1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26: #if defined(__x86_64__)
27: #define __HAVE_FAST_MULU64__
28: static always_inline void mulu64 (uint64_t *plow, uint64_t *phigh,
29: uint64_t a, uint64_t b)
30: {
31: __asm__ ("mul %0\n\t"
32: : "=d" (*phigh), "=a" (*plow)
33: : "a" (a), "0" (b));
34: }
35: #define __HAVE_FAST_MULS64__
36: static always_inline void muls64 (uint64_t *plow, uint64_t *phigh,
37: int64_t a, int64_t b)
38: {
39: __asm__ ("imul %0\n\t"
40: : "=d" (*phigh), "=a" (*plow)
41: : "a" (a), "0" (b));
42: }
43: #else
44: void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
45: void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
46: #endif
47:
48:
49:
50:
51:
52:
53:
54: static always_inline int clz32(uint32_t val)
55: {
56: int cnt = 0;
57:
58: if (!(val & 0xFFFF0000U)) {
59: cnt += 16;
60: val <<= 16;
61: }
62: if (!(val & 0xFF000000U)) {
63: cnt += 8;
64: val <<= 8;
65: }
66: if (!(val & 0xF0000000U)) {
67: cnt += 4;
68: val <<= 4;
69: }
70: if (!(val & 0xC0000000U)) {
71: cnt += 2;
72: val <<= 2;
73: }
74: if (!(val & 0x80000000U)) {
75: cnt++;
76: val <<= 1;
77: }
78: if (!(val & 0x80000000U)) {
79: cnt++;
80: }
81: return cnt;
82: }
83:
84: static always_inline int clo32(uint32_t val)
85: {
86: return clz32(~val);
87: }
88:
89: static always_inline int clz64(uint64_t val)
90: {
91: int cnt = 0;
92:
93: if (!(val >> 32)) {
94: cnt += 32;
95: } else {
96: val >>= 32;
97: }
98:
99: return cnt + clz32(val);
100: }
101:
102: static always_inline int clo64(uint64_t val)
103: {
104: return clz64(~val);
105: }
106:
107: static always_inline int ctz32 (uint32_t val)
108: {
109: int cnt;
110:
111: cnt = 0;
112: if (!(val & 0x0000FFFFUL)) {
113: cnt += 16;
114: val >>= 16;
115: }
116: if (!(val & 0x000000FFUL)) {
117: cnt += 8;
118: val >>= 8;
119: }
120: if (!(val & 0x0000000FUL)) {
121: cnt += 4;
122: val >>= 4;
123: }
124: if (!(val & 0x00000003UL)) {
125: cnt += 2;
126: val >>= 2;
127: }
128: if (!(val & 0x00000001UL)) {
129: cnt++;
130: val >>= 1;
131: }
132: if (!(val & 0x00000001UL)) {
133: cnt++;
134: }
135:
136: return cnt;
137: }
138:
139: static always_inline int cto32 (uint32_t val)
140: {
141: return ctz32(~val);
142: }
143:
144: static always_inline int ctz64 (uint64_t val)
145: {
146: int cnt;
147:
148: cnt = 0;
149: if (!((uint32_t)val)) {
150: cnt += 32;
151: val >>= 32;
152: }
153:
154: return cnt + ctz32(val);
155: }
156:
157: static always_inline int cto64 (uint64_t val)
158: {
159: return ctz64(~val);
160: }
161:
162: static always_inline int ctpop8 (uint8_t val)
163: {
164: val = (val & 0x55) + ((val >> 1) & 0x55);
165: val = (val & 0x33) + ((val >> 2) & 0x33);
166: val = (val & 0x0f) + ((val >> 4) & 0x0f);
167:
168: return val;
169: }
170:
171: static always_inline int ctpop16 (uint16_t val)
172: {
173: val = (val & 0x5555) + ((val >> 1) & 0x5555);
174: val = (val & 0x3333) + ((val >> 2) & 0x3333);
175: val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
176: val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
177:
178: return val;
179: }
180:
181: static always_inline int ctpop32 (uint32_t val)
182: {
183: val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
184: val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
185: val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
186: val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
187: val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
188:
189: return val;
190: }
191:
192: static always_inline int ctpop64 (uint64_t val)
193: {
194: val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
195: val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
196: val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
197: val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
198: val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
199: val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
200:
201: return val;
202: }