1# libdivide C API 2 3Note that all of libdivide's public API functions are declared as ```static inline``` 4for performance reasons, however ```static inline``` is omitted in the code sections 5below in order to increase readability. 6 7## Generate libdivide divider 8 9```C 10/* Generate a libdivide divider */ 11struct libdivide_s16_t libdivide_s16_gen(int16_t d); 12struct libdivide_u16_t libdivide_u16_gen(uint16_t d); 13struct libdivide_s32_t libdivide_s32_gen(int32_t d); 14struct libdivide_u32_t libdivide_u32_gen(uint32_t d); 15struct libdivide_s64_t libdivide_s64_gen(int64_t d); 16struct libdivide_u64_t libdivide_u64_gen(uint64_t d); 17 18/* Generate a branchfree libdivide divider */ 19struct libdivide_s16_branchfree_t libdivide_s16_branchfree_gen(int16_t d); 20struct libdivide_u16_branchfree_t libdivide_u16_branchfree_gen(uint16_t d); 21struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d); 22struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d); 23struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d); 24struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d); 25``` 26 27## libdivide division 28 29```C 30/* libdivide division */ 31int16_t libdivide_s16_do(int16_t numer, const struct libdivide_s16_t *denom); 32uint16_t libdivide_u16_do(uint16_t numer, const struct libdivide_u16_t *denom); 33int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom); 34uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom); 35int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom); 36uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom); 37 38/* libdivide branchfree division */ 39int16_t libdivide_s16_branchfree_do(int16_t numer, const struct libdivide_s16_branchfree_t *denom); 40uint16_t libdivide_u16_branchfree_do(uint16_t numer, const struct libdivide_u16_branchfree_t *denom); 41int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom); 42uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom); 43int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom); 44uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom); 45``` 46 47## libdivide NEON vector division 48 49```C 50/* libdivide NEON division */ 51uint32x4_t libdivide_u32_do_vec128(uint32x4_t numers, const struct libdivide_u32_t *denom); 52int32x4_t libdivide_s32_do_vec128(int32x4_t numers, const struct libdivide_s32_t *denom); 53uint64x2_t libdivide_u64_do_vec128(uint64x2_t numers, const struct libdivide_u64_t *denom); 54int64x2_t libdivide_s64_do_vec128(int64x2_t numers, const struct libdivide_s64_t *denom); 55 56/* libdivide NEON branchfree division */ 57uint32x4_t libdivide_u32_branchfree_do_vec128(uint32x4_t numers, const struct libdivide_u32_branchfree_t *denom); 58int32x4_t libdivide_s32_branchfree_do_vec128(int32x4_t numers, const struct libdivide_s32_branchfree_t *denom); 59uint64x2_t libdivide_u64_branchfree_do_vec128(uint2x4_t numers, const struct libdivide_u64_branchfree_t *denom); 60int64x2_t libdivide_s64_branchfree_do_vec128(int64x2_t numers, const struct libdivide_s64_branchfree_t *denom); 61``` 62 63You need to define ```LIBDIVIDE_NEON``` to enable NEON vector division. 64 65## libdivide SSE2 vector division 66 67```C 68/* libdivide SSE2 division */ 69__m128i libdivide_u32_do_vec128(__m128i numers, const struct libdivide_u32_t *denom); 70__m128i libdivide_s32_do_vec128(__m128i numers, const struct libdivide_s32_t *denom); 71__m128i libdivide_u64_do_vec128(__m128i numers, const struct libdivide_u64_t *denom); 72__m128i libdivide_s64_do_vec128(__m128i numers, const struct libdivide_s64_t *denom); 73 74/* libdivide SSE2 branchfree division */ 75__m128i libdivide_u32_branchfree_do_vec128(__m128i numers, const struct libdivide_u32_branchfree_t *denom); 76__m128i libdivide_s32_branchfree_do_vec128(__m128i numers, const struct libdivide_s32_branchfree_t *denom); 77__m128i libdivide_u64_branchfree_do_vec128(__m128i numers, const struct libdivide_u64_branchfree_t *denom); 78__m128i libdivide_s64_branchfree_do_vec128(__m128i numers, const struct libdivide_s64_branchfree_t *denom); 79``` 80 81You need to define ```LIBDIVIDE_SSE2``` to enable SSE2 vector division. 82 83## libdivide AVX2 vector division 84 85```C 86/* libdivide AVX2 division */ 87__m256i libdivide_u32_do_vec256(__m256i numers, const struct libdivide_u32_t *denom); 88__m256i libdivide_s32_do_vec256(__m256i numers, const struct libdivide_s32_t *denom); 89__m256i libdivide_u64_do_vec256(__m256i numers, const struct libdivide_u64_t *denom); 90__m256i libdivide_s64_do_vec256(__m256i numers, const struct libdivide_s64_t *denom); 91 92/* libdivide AVX2 branchfree division */ 93__m256i libdivide_u32_branchfree_do_vec256(__m256i numers, const struct libdivide_u32_branchfree_t *denom); 94__m256i libdivide_s32_branchfree_do_vec256(__m256i numers, const struct libdivide_s32_branchfree_t *denom); 95__m256i libdivide_u64_branchfree_do_vec256(__m256i numers, const struct libdivide_u64_branchfree_t *denom); 96__m256i libdivide_s64_branchfree_do_vec256(__m256i numers, const struct libdivide_s64_branchfree_t *denom); 97``` 98 99You need to define ```LIBDIVIDE_AVX2``` to enable AVX2 vector division. 100 101## libdivide AVX512 vector division 102 103```C 104/* libdivide AVX512 division */ 105__m512i libdivide_u32_do_vec512(__m512i numers, const struct libdivide_u32_t *denom); 106__m512i libdivide_s32_do_vec512(__m512i numers, const struct libdivide_s32_t *denom); 107__m512i libdivide_u64_do_vec512(__m512i numers, const struct libdivide_u64_t *denom); 108__m512i libdivide_s64_do_vec512(__m512i numers, const struct libdivide_s64_t *denom); 109 110/* libdivide AVX512 branchfree division */ 111__m512i libdivide_u32_branchfree_do_vec512(__m512i numers, const struct libdivide_u32_branchfree_t *denom); 112__m512i libdivide_s32_branchfree_do_vec512(__m512i numers, const struct libdivide_s32_branchfree_t *denom); 113__m512i libdivide_u64_branchfree_do_vec512(__m512i numers, const struct libdivide_u64_branchfree_t *denom); 114__m512i libdivide_s64_branchfree_do_vec512(__m512i numers, const struct libdivide_s64_branchfree_t *denom); 115``` 116 117You need to define ```LIBDIVIDE_AVX512``` to enable AVX512 vector division. 118 119## Recover divider 120 121```C 122/* Recover the original divider */ 123int16_t libdivide_s16_recover(const struct libdivide_s16_t *denom); 124uint16_t libdivide_u16_recover(const struct libdivide_u16_t *denom); 125int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom); 126uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom); 127int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom); 128uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom); 129 130/* Recover the original divider */ 131int16_t libdivide_s16_branchfree_recover(const struct libdivide_s16_branchfree_t *denom); 132uint16_t libdivide_u16_branchfree_recover(const struct libdivide_u16_branchfree_t *denom); 133int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom); 134uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom); 135int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom); 136uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom); 137``` 138