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