1 // Low-level arithmetic: operations on 16-bit and 32-bit words
8 // Determines the sign of a 16-bit number.
10 // > wert: eine 16-Bit-Zahl
11 // < sint16 ergebnis: 0 falls wert>=0, -1 falls wert<0.
12 inline sint16 sign_of (sint16 wert)
14 #if defined(__sparc64__)
15 return (sint64)wert >> 63;
16 #elif defined(__sparc__) || defined(__arm__)
17 return (sint32)wert >> 31;
19 return (wert >= 0 ? 0 : -1);
23 // Determines the sign of a 32-bit number.
25 // > wert: eine 32-Bit-Zahl
26 // < sint32 ergebnis: 0 falls wert>=0, -1 falls wert<0.
27 inline sint32 sign_of (sint32 wert)
29 #if defined(__sparc64__)
30 return (sint64)wert >> 63;
31 #elif defined(__sparc__) || defined(__arm__)
34 return (wert >= 0 ? 0 : -1);
38 #ifdef HAVE_FAST_LONGLONG
40 // Determines the sign of a 64-bit number.
42 // > wert: eine 64-Bit-Zahl
43 // < sint64 ergebnis: 0 falls wert>=0, -1 falls wert<0.
44 inline sint64 sign_of (sint64 wert)
49 #endif /* HAVE_FAST_LONGLONG */
52 // High-Word einer 32-Bit-Zahl bestimmen
54 inline uint16 high16 (uint32 wert)
59 // Low-Word einer 32-Bit-Zahl bestimmen
61 inline uint16 low16 (uint32 wert)
66 // Eine 32-Bit-Zahl aus ihrem High-Word und ihrem Low-Word bestimmen:
67 // highlow32(uint16 high, uint16 low)
68 inline uint32 highlow32 (uint16 high, uint16 low)
70 return ((uint32)high << 16) | (uint32)low;
73 // Eine 32-Bit-Zahl aus ihrem High-Word und ihrem Low-Word 0 bestimmen:
74 // highlow32_0(uint16 high)
75 inline uint32 highlow32_0 (uint16 high)
77 return (uint32)high << 16;
80 // High-Word einer 64-Bit-Zahl bestimmen
82 inline uint32 high32 (uint64 wert)
87 // Low-Word einer 64-Bit-Zahl bestimmen
89 inline uint32 low32 (uint64 wert)
94 // Eine 64-Bit-Zahl aus ihrem High-Word und ihrem Low-Word bestimmen:
95 // highlow64(uint32 high, uint32 low)
96 inline uint64 highlow64 (uint32 high, uint32 low)
98 return ((uint64)high << 32) | (uint64)low;
101 // Eine 64-Bit-Zahl aus ihrem High-Word und ihrem Low-Word 0 bestimmen:
102 // highlow64_0(uint32 high)
103 inline uint64 highlow64_0 (uint32 high)
105 return (uint64)high << 32;
109 // Multipliziert zwei 16-Bit-Zahlen miteinander und liefert eine 32-Bit-Zahl:
111 // > arg1, arg2 : zwei 16-Bit-Zahlen
112 // < ergebnis: eine 32-Bit-Zahl
113 #if defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
114 // Ist das schneller als mulu16_ ??
115 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
117 union { double f; uint32 i[2]; } __fi;
118 __fi.f = (double)(sint32)arg1 * (double)(sint32)arg2
119 + (double)(4503599627370496.0L); // + 2^52, zum Normalisieren
120 return __fi.i[1]; // untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !)
122 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
123 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
125 register uint64 _prod;
126 __asm__("umul %1,%2,%0"
128 : "r" (arg1), "r" (arg2)
132 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
133 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
138 : "=d" /* %dx */ (_hi), "=a" /* %ax */ (_lo)
139 : "rm" (arg1), "1" /* %eax */ (arg2)
141 return highlow32(_hi,_lo);
143 #elif (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
144 extern "C" uint32 mulu16_ (uint16 arg1, uint16 arg2);
145 #define mulu16 mulu16_ // extern in Assembler
147 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
153 // Multipliziert zwei 24-Bit-Zahlen zusammen und liefert eine 48-Bit-Zahl.
154 // mulu24(arg1,arg2,hi=,lo=);
155 // > arg1, arg2 : zwei 24-Bit-Zahlen
156 // < 2^32*hi+lo : eine 48-Bit-Zahl
157 #if defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
158 #define mulu24(x,y,hi_zuweisung,lo_zuweisung) \
159 { var uint32 _x = (x); \
160 var uint32 _y = (y); \
161 var union { double f; uint32 i[2]; uint16 s[4]; } __fi; \
162 __fi.f = (double)(sint32)(_x)*(double)(sint32)(_y) \
163 + (double)(4503599627370496.0L); /* + 2^52, zum Normalisieren */\
164 unused (hi_zuweisung __fi.s[1]); /* mittlere 16 Bit herausholen, (benutzt CL_CPU_BIG_ENDIAN_P !) */\
165 lo_zuweisung __fi.i[1]; /* untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !) */\
168 #define mulu24 mulu32
171 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 32-Bit-Zahl:
172 // mulu32_unchecked(arg1,arg2)
173 // > arg1, arg2 : zwei 32-Bit-Zahlen
174 // < ergebnis : eine 32-Bit-Zahl
175 // Es wird vorausgesetzt, daß arg1*arg2 < 2^32.
176 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
177 inline uint32 mulu32_unchecked (uint32 arg1, uint32 arg2)
179 register uint64 _prod;
180 __asm__("umul %1,%2,%0"
182 : "r" (arg1), "r" (arg2)
186 #elif defined(__sparc__) && !defined(NO_ASM)
187 extern "C" uint32 mulu32_unchecked (uint32 x, uint32 y); // extern in Assembler
189 // Wir können dafür auch die Bibliotheksroutine des C-Compilers nehmen:
190 inline uint32 mulu32_unchecked (uint32 arg1, uint32 arg2)
196 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 64-Bit-Zahl:
197 // mulu32(arg1,arg2,hi=,lo=);
198 // > arg1, arg2 : zwei 32-Bit-Zahlen
199 // < 2^32*hi+lo : eine 64-Bit-Zahl
200 extern "C" uint32 mulu32_ (uint32 arg1, uint32 arg2); // -> Low-Teil
202 // Workaround MSVC compiler bug: extern "C" results in wrong symbols, when
203 // declared inside a namespace!
204 } extern "C" uint32 mulu32_high; namespace cln { // -> High-Teil
206 extern "C" uint32 mulu32_high; // -> High-Teil
208 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
209 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
210 ({ var uint32 _x = (x); \
211 var uint32 _y = (y); \
214 __asm__("mulul %3,%0:%1" : "=d" (_hi), "=d"(_lo) : "1" (_x), "dm" (_y) ); \
215 unused (hi_zuweisung _hi); \
218 #elif defined(__GNUC__) && defined(__m68k__)
219 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
220 ({ var uint32 _x = (x); \
221 var uint32 _y = (y); \
222 var uint16 _x1 = high16(_x); \
223 var uint16 _x0 = low16(_x); \
224 var uint16 _y1 = high16(_y); \
225 var uint16 _y0 = low16(_y); \
226 var uint32 _hi = mulu16(_x1,_y1); /* obere Portion */ \
227 var uint32 _lo = mulu16(_x0,_y0); /* untere Portion */ \
228 {var uint32 _mid = mulu16(_x0,_y1); /* 1. mittlere Portion */ \
229 _hi += high16(_mid); _mid = highlow32_0(low16(_mid)); \
230 _lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
232 {var uint32 _mid = mulu16(_x1,_y0); /* 2. mittlere Portion */ \
233 _hi += high16(_mid); _mid = highlow32_0(low16(_mid)); \
234 _lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
236 unused (hi_zuweisung _hi); \
239 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
240 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
241 ({ var register uint64 _prod; \
242 __asm__("umul %1,%2,%0" \
244 : "r" ((uint32)(x)), "r" ((uint32)(y)) \
246 unused (hi_zuweisung (uint32)(_prod>>32)); \
247 lo_zuweisung (uint32)(_prod); \
249 #elif defined(__GNUC__) && defined(__sparc__) && !defined(NO_ASM)
250 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
251 ({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
252 {var register uint32 _hi __asm__("%g1"); \
253 unused (hi_zuweisung _hi); \
255 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
256 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
257 ({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */ \
258 {var register uint32 _hi __asm__("%r1"/*"%a2"*/); \
259 unused (hi_zuweisung _hi); \
261 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
262 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
263 ({ var register uint32 _hi; \
264 var register uint32 _lo; \
266 : "=d" /* %edx */ (_hi), "=a" /* %eax */ (_lo) \
267 : "g" ((uint32)(x)), "1" /* %eax */ ((uint32)(y)) \
269 unused (hi_zuweisung _hi); lo_zuweisung _lo; \
271 #elif defined(__GNUC__) && defined(__mips__) && !defined(NO_ASM)
272 #if __mips_isa_rev >= 6
273 #define MULTU_HI_LO "mulu %1,%3,%2 ; muhu %0,%3,%2"
275 #define MULTU_HI_LO "multu %3,%2 ; mfhi %0 ; mflo %1"
277 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
278 ({ var register uint32 _hi; \
279 var register uint32 _lo; \
280 __asm__(MULTU_HI_LO \
281 : "=r" (_hi), "=r" (_lo) \
282 : "r" ((uint32)(x)), "r" ((uint32)(y)) \
284 unused (hi_zuweisung _hi); lo_zuweisung _lo; \
286 #elif defined(__GNUC__) && !defined(__arm__)
287 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
288 ({ var register uint64 _prod = (uint64)(uint32)(x) * (uint64)(uint32)(y); \
289 unused (hi_zuweisung (uint32)(_prod>>32)); \
290 lo_zuweisung (uint32)(_prod); \
292 #elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
293 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
294 { var register uint32 _hi; \
295 var register uint32 _lo; \
296 _lo = mulu32_(x,y), _hi = mulu32_high_(); \
297 unused (hi_zuweisung _hi); lo_zuweisung _lo; \
299 extern "C" uint32 mulu32_high_ (void);
300 #pragma aux mulu32_ = 0xF7 0xE2 /* mull %edx */ parm [eax] [edx] value [eax] modify [eax edx];
301 #pragma aux mulu32_high_ = /* */ value [edx] modify [];
303 #define mulu32(x,y,hi_zuweisung,lo_zuweisung) \
304 { lo_zuweisung mulu32_(x,y); unused (hi_zuweisung mulu32_high); }
305 #if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__x86_64__) || defined(__mips__) || defined(__hppa__)) && !defined(NO_ASM)
306 // mulu32_ extern in Assembler
307 #if defined(__sparc__) || defined(__sparc64__)
308 extern "C" uint32 _get_g1 (void);
309 #define mulu32_high (_get_g1()) // Rückgabe im Register %g1
310 #elif !defined(__hppa__)
311 #define NEED_VAR_mulu32_high
314 #define NEED_FUNCTION_mulu32_
318 #ifdef HAVE_FAST_LONGLONG
320 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 64-Bit-Zahl:
321 // mulu32_w(arg1,arg2)
322 // > arg1, arg2 : zwei 32-Bit-Zahlen
323 // < result : eine 64-Bit-Zahl
324 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
325 // Prefer the umul instruction over the mulx instruction (overkill).
326 #define mulu32_w(x,y) \
327 ({ var register uint64 _prod; \
328 __asm__("umul %1,%2,%0" \
330 : "r" ((uint32)(x)), "r" ((uint32)(y)) \
334 #elif defined(__GNUC__)
335 #define mulu32_w(x,y) ((uint64)(uint32)(x) * (uint64)(uint32)(y))
337 extern "C" uint64 mulu32_w (uint32 arg1, uint32 arg2);
338 #define NEED_FUNCTION_mulu32_w
341 // Multipliziert zwei 64-Bit-Zahlen miteinander und liefert eine 128-Bit-Zahl:
342 // mulu64(arg1,arg2,hi=,lo=);
343 // > arg1, arg2 : zwei 64-Bit-Zahlen
344 // < 2^64*hi+lo : eine 128-Bit-Zahl
345 extern "C" uint64 mulu64_ (uint64 arg1, uint64 arg2); // -> Low-Teil
347 // Workaround MSVC compiler bug.
348 } extern "C" uint64 mulu64_high; namespace cln { // -> High-Teil
350 extern "C" uint64 mulu64_high; // -> High-Teil
352 #if defined(__GNUC__) && defined(__alpha__) && !defined(NO_ASM)
353 #define mulu64(x,y,hi_zuweisung,lo_zuweisung) \
354 ({ var register uint64 _x = (x); \
355 var register uint64 _y = (y); \
356 var register uint64 _hi; \
357 var register uint64 _lo; \
358 __asm__("mulq %1,%2,%0" \
360 : "r" (_x), "r" (_y) \
362 __asm__("umulh %1,%2,%0" \
364 : "r" (_x), "r" (_y) \
366 unused (hi_zuweisung _hi); \
369 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
370 #define mulu64(x,y,hi_zuweisung,lo_zuweisung) \
371 ({ lo_zuweisung mulu64_(x,y); /* extern in Assembler */ \
372 {var register uint64 _hi __asm__("%g2"); \
373 unused (hi_zuweisung _hi); \
375 #elif defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
376 #define mulu64(x,y,hi_zuweisung,lo_zuweisung) \
377 ({ var register uint64 _hi; \
378 var register uint64 _lo; \
380 : "=d" /* %rdx */ (_hi), "=a" /* %rax */ (_lo) \
381 : "rm" ((uint64)(x)), "1" /* %rax */ ((uint64)(y)) \
383 unused (hi_zuweisung _hi); lo_zuweisung _lo; \
385 #elif defined(__GNUC__) && defined(__ia64__) && !defined(NO_ASM)
386 #define mulu64(x,y,hi_zuweisung,lo_zuweisung) \
387 ({ var register uint64 _x = (x); \
388 var register uint64 _y = (y); \
389 var register uint64 _hi; \
390 __asm__("xma.hu %0 = %1, %2, f0" \
392 : "f" ((uint64)(_x)), "f" ((uint64)(_y)) \
394 unused (hi_zuweisung _hi); lo_zuweisung ((uint64)(_x)*(uint64)(_y)); \
397 #define mulu64(x,y,hi_zuweisung,lo_zuweisung) \
398 { lo_zuweisung mulu64_(x,y); unused (hi_zuweisung mulu64_high); }
399 #if defined(__sparc64__) && !defined(NO_ASM)
400 // mulu64_ extern in Assembler
401 extern "C" uint64 _get_g2 (void);
402 #define mulu64_high (_get_g2()) // Rückgabe im Register %g2
404 #define NEED_FUNCTION_mulu64_
408 #endif /* HAVE_FAST_LONGLONG */
411 // Dividiert eine 16-Bit-Zahl durch eine 16-Bit-Zahl und
412 // liefert einen 16-Bit-Quotienten und einen 16-Bit-Rest.
413 // divu_1616_1616(x,y,q=,r=);
414 // > uint16 x: Zähler
415 // > uint16 y: Nenner
416 // < uint16 q: floor(x/y)
417 // < uint16 r: x mod y
419 #define divu_1616_1616(x,y,q_zuweisung,r_zuweisung) \
420 { var uint16 __x = (x); \
421 var uint16 __y = (y); \
422 q_zuweisung floor(__x,__y); \
423 r_zuweisung (__x % __y); \
426 // Dividiert eine 32-Bit-Zahl durch eine 16-Bit-Zahl und
427 // liefert einen 16-Bit-Quotienten und einen 16-Bit-Rest.
428 // divu_3216_1616(x,y,q=,r=);
429 // > uint32 x: Zähler
430 // > uint16 y: Nenner
431 // > Es sei bekannt, daß 0 <= x < 2^16*y .
432 // < uint16 q: floor(x/y)
433 // < uint16 r: x mod y
435 #if defined(__sparc__)
436 extern "C" uint32 divu_3216_1616_ (uint32 x, uint16 y); // -> Quotient q, Rest r
438 extern "C" uint16 divu_3216_1616_ (uint32 x, uint16 y); // -> Quotient q
440 // Workaround MSVC compiler bug.
441 } extern "C" uint16 divu_16_rest; namespace cln { // -> Rest r
443 extern "C" uint16 divu_16_rest; // -> Rest r
446 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
447 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
448 ({var uint32 __x = (x); \
449 var uint16 __y = (y); \
452 __asm__ __volatile__ ( \
453 "wr %%g0,%%g0,%%y\n\t" \
454 "udiv %2,%3,%0\n\t" \
455 "umul %0,%3,%1\n\t" \
457 : "=&r" (__q), "=&r" (__r) \
458 : "r" (__x), "r" (__y)); \
459 unused (q_zuweisung (uint16)__q); \
460 r_zuweisung (uint16)__r; \
462 #elif defined(__GNUC__) && (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
463 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
464 ({ var uint32 __qr = divu_3216_1616_(x,y); /* extern in Assembler */\
465 unused (q_zuweisung low16(__qr)); \
466 r_zuweisung high16(__qr); \
468 #elif defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
469 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
470 ({var uint32 __x = (x); \
471 var uint16 __y = (y); \
473 __asm__ __volatile__ (" \
475 " : "=d" (__qr) : "0" (__x), "dm" (__y)); \
476 unused (q_zuweisung low16(__qr)); \
477 r_zuweisung high16(__qr); \
479 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
480 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
481 ({var uint32 __x = (x); \
482 var uint16 __y = (y); \
486 : "=a" /* %ax */ (__q), "=d" /* %dx */ (__r) \
487 : "1" /* %dx */ ((uint16)(high16(__x))), "0" /* %ax */ ((uint16)(low16(__x))), "rm" (__y) \
489 unused (q_zuweisung __q); \
492 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
493 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
494 { var uint32 __q = divu_3216_1616_(x,y); /* extern in Assembler */ \
495 var register uint32 __r __asm__("%r1"/*"%a2"*/); \
496 unused (q_zuweisung __q); r_zuweisung __r; \
498 #elif defined(__GNUC__) && !defined(__arm__)
499 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
500 ({var uint32 __x = (x); \
501 var uint16 __y = (y); \
502 var uint16 __q = floor(__x,__y); \
503 unused (q_zuweisung __q); \
504 r_zuweisung (__x - __q * __y); \
506 #elif (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
507 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
508 { var uint32 __qr = divu_3216_1616_(x,y); /* extern in Assembler */ \
509 unused (q_zuweisung low16(__qr)); \
510 r_zuweisung high16(__qr); \
512 #elif defined(__arm__) && !defined(NO_ASM)
513 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
514 { unused (q_zuweisung divu_3216_1616_(x,y)); /* extern in Assembler */ \
515 r_zuweisung divu_16_rest; \
517 #define NEED_VAR_divu_16_rest
519 #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung) \
520 { unused (q_zuweisung divu_3216_1616_(x,y)); r_zuweisung divu_16_rest; }
521 #define NEED_FUNCTION_divu_3216_1616_
524 // Dividiert eine 32-Bit-Zahl durch eine 16-Bit-Zahl und
525 // liefert einen 32-Bit-Quotienten und einen 16-Bit-Rest.
526 // divu_3216_3216(x,y,q=,r=);
527 // > uint32 x: Zähler
528 // > uint16 y: Nenner
529 // Es sei bekannt, daß y>0.
530 // < uint32 q: floor(x/y)
531 // < uint16 r: x mod y
533 extern "C" uint32 divu_3216_3216_ (uint32 x, uint16 y); // -> Quotient q
535 // Workaround MSVC compiler bug.
536 } extern "C" uint16 divu_16_rest; namespace cln { // -> Rest r
538 extern "C" uint16 divu_16_rest; // -> Rest r
540 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
541 #define divu_3216_3216(x,y,q_zuweisung,r_zuweisung) \
542 ({var uint32 __x = (x); \
543 var uint16 __y = (y); \
546 __asm__ __volatile__ ( \
547 "wr %%g0,%%g0,%%y\n\t" \
548 "udiv %2,%3,%0\n\t" \
549 "umul %0,%3,%1\n\t" \
551 : "=&r" (__q), "=&r" (__r) \
552 : "r" (__x), "r" (__y)); \
553 q_zuweisung (uint32)__q; \
554 r_zuweisung (uint16)__r; \
556 #elif defined(__sparc__) || defined(__sparc64__) || defined(__i386__) || defined(__x86_64__)
557 #define divu_3216_3216 divu_3232_3232
559 // Methode: (beta = 2^16)
560 // x = x1*beta+x0 schreiben.
561 // Division mit Rest: x1 = q1*y + r1, wobei 0 <= x1 < beta <= beta*y.
562 // Also 0 <= q1 < beta, 0 <= r1 < y.
563 // Division mit Rest: (r1*beta+x0) = q0*y + r0, wobei 0 <= r1*beta+x0 < beta*y.
564 // Also 0 <= q0 < beta, 0 <= r0 < y
565 // und x = x1*beta+x0 = (q1*beta+q0)*y + r0.
566 // Setze q := q1*beta+q0 und r := r0.
567 #define divu_3216_3216(x,y,q_zuweisung,r_zuweisung) \
568 { var uint32 _x = (x); \
569 var uint16 _y = (y); \
573 divu_3216_1616(high16(_x),_y, _q1 = , _r1 = ); \
574 divu_3216_1616(highlow32(_r1,low16(_x)),_y, _q0 = , r_zuweisung); \
575 q_zuweisung highlow32(_q1,_q0); \
579 // Dividiert eine 32-Bit-Zahl durch eine 32-Bit-Zahl und
580 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
581 // divu_3232_3232(x,y,q=,r=);
582 // > uint32 x: Zähler
583 // > uint32 y: Nenner
584 // Es sei bekannt, daß y>0.
585 // < uint32 q: floor(x/y)
586 // < uint32 r: x mod y
588 extern "C" uint32 divu_3232_3232_ (uint32 x, uint32 y); // -> Quotient q
590 // Workaround MSVC compiler bug.
591 } extern "C" uint32 divu_32_rest; namespace cln { // -> Rest r
593 extern "C" uint32 divu_32_rest; // -> Rest r
595 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
596 #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung) \
597 ({var uint32 __x = (x); \
598 var uint32 __y = (y); \
601 __asm__ __volatile__ ( \
602 "wr %%g0,%%g0,%%y\n\t" \
603 "udiv %2,%3,%0\n\t" \
604 "umul %0,%3,%1\n\t" \
606 : "=&r" (__q), "=&r" (__r) \
607 : "r" (__x), "r" (__y)); \
608 q_zuweisung (uint32)__q; \
609 r_zuweisung (uint32)__r; \
611 #define divu_3232_3232_(x,y) divu_6432_3232_(0,x,y)
612 #elif defined(__sparc__) || defined(__sparc64__) || defined(__i386__) || defined(__x86_64__)
613 #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung) \
614 divu_6432_3232(0,x,y,q_zuweisung,r_zuweisung)
615 #define divu_3232_3232_(x,y) divu_6432_3232_(0,x,y)
617 // Methode: (beta = 2^n = 2^16, n = 16)
618 // Falls y < beta, handelt es sich um eine 32-durch-16-Bit-Division.
620 // Quotient q = floor(x/y) < beta (da 0 <= x < beta^2, y >= beta).
621 // y habe genau n+k Bits (1 <= k <= n), d.h. 2^(n+k-1) <= y < 2^(n+k).
622 // Schreibe x = 2^k*x1 + x0 mit x1 := floor(x/2^k)
623 // und y = 2^k*y1 + y0 mit y1 := floor(y/2^k)
624 // und bilde den Näherungs-Quotienten floor(x1/y1)
625 // oder (noch besser) floor(x1/(y1+1)).
626 // Wegen 0 <= x1 < 2^(2n) und 0 < 2^(n-1) <= y1 < 2^n
627 // und x1/(y1+1) <= x/y < x1/(y1+1) + 2
628 // (denn x1/(y1+1) = (x1*2^k)/((y1+1)*2^k) <= (x1*2^k)/y <= x/y
629 // und x/y - x1/(y1+1) = (x+x*y1-x1*y)/(y*(y1+1))
630 // = (x+x0*y1-x1*y0)/(y*(y1+1)) <= (x+x0*y1)/(y*(y1+1))
631 // <= x/(y*(y1+1)) + x0/y
632 // <= 2^(2n)/(2^(n+k-1)*(2^(n-1)+1)) + 2^k/2^(n+k-1)
633 // = 2^(n-k+1)/(2^(n-1)+1) + 2^(1-n) <= 2^n/(2^(n-1)+1) + 2^(1-n) < 2 )
634 // gilt floor(x1/(y1+1)) <= floor(x/y) <= floor(x1/(y1+1)) + 2 .
635 // Man bildet also q:=floor(x1/(y1+1)) (ein Shift um n Bit oder
636 // eine (2n)-durch-n-Bit-Division, mit Ergebnis q <= floor(x/y) < beta)
637 // und x-q*y und muß hiervon noch höchstens 2 mal y abziehen und q
638 // incrementieren, um den Quotienten q = floor(x/y) und den Rest
639 // x-floor(x/y)*y der Division zu bekommen.
640 #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung) \
641 { var uint32 _x = (x); \
642 var uint32 _y = (y); \
643 if (_y <= (uint32)(bit(16)-1)) \
647 divu_3216_1616(high16(_x),_y, _q1 = , _r1 = ); \
648 divu_3216_1616(highlow32(_r1,low16(_x)),_y, _q0 = , r_zuweisung); \
649 q_zuweisung highlow32(_q1,_q0); \
652 { var uint32 _x1 = _x; /* x1 := x */ \
653 var uint32 _y1 = _y; /* y1 := y */ \
655 do { _x1 = floor(_x1,2); _y1 = floor(_y1,2); } /* k erhöhen */\
656 until (_y1 <= (uint32)(bit(16)-1)); /* bis y1 < beta */ \
657 { var uint16 _y2 = low16(_y1)+1; /* y1+1 bilden */ \
659 { _q = high16(_x1); } /* y1+1=beta -> ein Shift */ \
661 { divu_3216_1616(_x1,_y2,_q=,); } /* Division von x1 durch y1+1 */\
663 /* _q = q = floor(x1/(y1+1)) */ \
664 /* x-q*y bilden (eine 16-mal-32-Bit-Multiplikation ohne Überlauf): */\
665 _x -= highlow32_0(mulu16(_q,high16(_y))); /* q * high16(y) * beta */\
666 /* gefahrlos, da q*high16(y) <= q*y/beta <= x/beta < beta */ \
667 _x -= mulu16(_q,low16(_y)); /* q * low16(y) */ \
668 /* gefahrlos, da q*high16(y)*beta + q*low16(y) = q*y <= x */ \
669 /* Noch höchstens 2 mal y abziehen: */ \
671 { _q += 1; _x -= _y; \
673 { _q += 1; _x -= _y; } \
676 q_zuweisung (uint32)(_q); \
678 #define NEED_FUNCTION_divu_3232_3232_
681 // Dividiert eine 64-Bit-Zahl durch eine 32-Bit-Zahl und
682 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
683 // divu_6432_3232(xhi,xlo,y,q=,r=);
684 // > uint32 xhi,xlo: x = 2^32*xhi+xlo = Zähler
685 // > uint32 y: Nenner
686 // > Es sei bekannt, daß 0 <= x < 2^32*y .
687 // < uint32 q: floor(x/y)
688 // < uint32 r: x mod y
690 extern "C" uint32 divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y); // -> Quotient q
692 // Workaround MSVC compiler bug.
693 } extern "C" uint32 divu_32_rest; namespace cln { // -> Rest r
695 extern "C" uint32 divu_32_rest; // -> Rest r
697 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
698 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
699 ({var uint32 __xhi = (xhi); \
700 var uint32 __xlo = (xlo); \
701 var uint32 __y = (y); \
704 __asm__ __volatile__ (" \
706 " : "=d" (__q), "=d" (__r) : "1" (__xhi), "0" (__xlo), "dm" (__y)); \
707 unused (q_zuweisung __q); \
710 #define divu_6432_3232_(xhi,xlo,y) \
711 ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
712 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
713 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
714 ({var uint32 __xhi = (xhi); \
715 var uint32 __xlo = (xlo); \
716 var uint32 __y = (y); \
719 __asm__ __volatile__ ( \
720 "wr %2,%%g0,%%y\n\t" \
721 "udiv %3,%4,%0\n\t" \
722 "umul %0,%4,%1\n\t" \
724 : "=&r" (__q), "=&r" (__r) \
725 : "r" (__xhi), "r" (__xlo), "r" (__y)); \
726 unused (q_zuweisung (uint32)__q); \
727 r_zuweisung (uint32)__r; \
729 #elif defined(__GNUC__) && (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
730 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
731 ({ var uint32 _q = divu_6432_3232_(xhi,xlo,y); /* extern in Assembler */\
732 var register uint32 _r __asm__("%g1"); \
733 unused (q_zuweisung _q); r_zuweisung _r; \
735 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
736 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
737 ({ var uint32 _q = divu_6432_3232_(xhi,xlo,y); /* extern in Assembler */\
738 var register uint32 _r __asm__("%r1"/*"%a2"*/); \
739 unused (q_zuweisung _q); r_zuweisung _r; \
741 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(NO_ASM)
742 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
743 ({var uint32 __xhi = (xhi); \
744 var uint32 __xlo = (xlo); \
745 var uint32 __y = (y); \
748 __asm__ __volatile__ ( \
750 : "=a" /* %eax */ (__q), "=d" /* %edx */ (__r) \
751 : "1" /* %edx */ (__xhi), "0" /* %eax */ (__xlo), "rm" (__y) \
753 unused (q_zuweisung __q); \
756 #define divu_6432_3232_(xhi,xlo,y) \
757 ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
758 #elif defined(__GNUC__) && !defined(__arm__)
759 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
760 ({var uint32 __xhi = (xhi); \
761 var uint32 __xlo = (xlo); \
762 var uint64 __x = ((uint64)__xhi << 32) | (uint64)__xlo; \
763 var uint32 __y = (y); \
764 var uint32 __q = floor(__x,(uint64)__y); \
765 unused (q_zuweisung __q); r_zuweisung __xlo - __q * __y; \
767 #define divu_6432_3232_(xhi,xlo,y) \
768 ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
769 #elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
770 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
771 { var uint32 __xhi = (xhi); \
772 var uint32 __xlo = (xlo); \
773 var uint32 __y = (y); \
776 __q = divu_6432_3232_(__xhi,__xlo,__y); __r = divu_6432_3232_rest(); \
777 unused (q_zuweisung __q); \
780 extern "C" uint32 divu_6432_3232_rest (void);
781 #pragma aux divu_6432_3232_ = 0xF7 0xF1 /* divl %ecx */ parm [edx] [eax] [ecx] value [eax] modify [eax edx];
782 #pragma aux divu_6432_3232_rest = /* */ value [edx] modify [];
784 #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
785 { unused (q_zuweisung divu_6432_3232_(xhi,xlo,y)); r_zuweisung divu_32_rest; }
786 #if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__x86_64__) || defined(__hppa__)) && !defined(NO_ASM)
787 // divu_6432_3232_ extern in Assembler
788 #if defined(__sparc__) || defined(__sparc64__)
789 extern "C" uint32 _get_g1 (void);
790 #define divu_32_rest (_get_g1()) // Rückgabe im Register %g1
792 #define NEED_VAR_divu_32_rest
795 #define NEED_FUNCTION_divu_6432_3232_
799 #ifdef HAVE_FAST_LONGLONG
801 // Dividiert eine 64-Bit-Zahl durch eine 32-Bit-Zahl und
802 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
803 // divu_6432_3232_w(x,y,q=,r=);
804 // > uint64 x: Zähler
805 // > uint32 y: Nenner
806 // > Es sei bekannt, daß 0 <= x < 2^32*y .
807 // < uint32 q: floor(x/y)
808 // < uint32 r: x mod y
810 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
811 // Prefer the udiv and umul instructions over the udivx and mulx instructions
813 #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung) \
814 ({var uint64 __x = (x); \
815 var uint32 __xhi = high32(__x); \
816 var uint32 __xlo = low32(__x); \
817 var uint32 __y = (y); \
820 __asm__ __volatile__ ( \
821 "wr %2,%%g0,%%y\n\t" \
822 "udiv %3,%4,%0\n\t" \
823 "umul %0,%4,%1\n\t" \
825 : "=&r" (__q), "=&r" (__r) \
826 : "r" (__xhi), "r" (__xlo), "r" (__y)); \
827 q_zuweisung (uint32)__q; \
828 r_zuweisung (uint32)__r; \
830 #elif defined(__GNUC__) && (defined(__alpha__) || defined(__ia64__) || defined(__mips64__) || defined(__sparc64__))
831 // On __alpha__, computing the remainder by multiplication is just two
832 // instructions, compared to the __remqu (libc) function call for the %
834 // On __ia64__, computing the remainder by multiplication is just four
835 // instructions, compared to the __umoddi3 (libgcc) function call for the %
837 // On __mips64__, computing the remainder by multiplication is just two
838 // instructions, compared to the __umoddi3 (libgcc) function call for the %
840 // On __sparc64__, computing the remainder by multiplication uses a 32-bit
841 // multiplication instruction, compared to a 64-bit multiplication when the %
843 #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung) \
844 ({var uint64 __x = (x); \
845 var uint32 __y = (y); \
846 var uint32 __q = floor(__x,(uint64)__y); \
847 q_zuweisung __q; r_zuweisung (uint32)__x - __q * __y; \
849 #elif defined(__GNUC__) && defined(__x86_64__)
850 // On __x86_64__, gcc 4.0 performs both quotient and remainder computation
851 // in a single instruction.
852 #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung) \
853 ({var uint64 __x = (x); \
854 var uint32 __y = (y); \
855 var uint32 __q = floor(__x,(uint64)__y); \
856 q_zuweisung __q; r_zuweisung __x % (uint64)__y; \
859 #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung) \
860 { var uint64 __x = (x); \
861 divu_6432_3232(high32(__x),low32(__x),(y),q_zuweisung,r_zuweisung); \
865 // Dividiert eine 64-Bit-Zahl durch eine 32-Bit-Zahl und
866 // liefert einen 64-Bit-Quotienten und einen 32-Bit-Rest.
867 // divu_6432_6432(x,y,q=,r=);
868 // > uint64 x: Zähler
869 // > uint32 y: Nenner
870 // > Es sei bekannt, daß y>0.
871 // < uint64 q: floor(x/y)
872 // < uint32 r: x mod y
874 #if defined(__GNUC__) && (defined(__alpha__) || defined(__ia64__) || defined(__mips64__) || defined(__sparc64__))
875 // On __alpha__, computing the remainder by multiplication is just two
876 // instructions, compared to the __remqu (libc) function call for the %
878 // On __ia64__, computing the remainder by multiplication is just four
879 // instructions, compared to the __umoddi3 (libgcc) function call for the %
881 // On __mips64__, computing the remainder by multiplication is just two
882 // instructions, compared to the __umoddi3 (libgcc) function call for the %
884 // On __sparc64__, computing the remainder by multiplication uses a 32-bit
885 // multiplication instruction, compared to a 64-bit multiplication when the %
887 #define divu_6432_6432(x,y,q_zuweisung,r_zuweisung) \
888 ({var uint64 _x = (x); \
889 var uint32 _y = (y); \
891 q_zuweisung _q = floor(_x,(uint64)_y); \
892 r_zuweisung low32(_x) - low32(_q) * _y; \
894 #elif defined(__GNUC__) && defined(__x86_64__)
895 // On __x86_64__, gcc 4.0 performs both quotient and remainder computation
896 // in a single instruction.
897 #define divu_6432_6432(x,y,q_zuweisung,r_zuweisung) \
898 ({var uint64 _x = (x); \
899 var uint32 _y = (y); \
900 q_zuweisung floor(_x,(uint64)_y); \
901 r_zuweisung _x % (uint64)_y; \
904 // Methode: (beta = 2^32)
905 // x = x1*beta+x0 schreiben.
906 // Division mit Rest: x1 = q1*y + r1, wobei 0 <= x1 < beta <= beta*y.
907 // Also 0 <= q1 < beta, 0 <= r1 < y.
908 // Division mit Rest: (r1*beta+x0) = q0*y + r0, wobei 0 <= r1*beta+x0 < beta*y.
909 // Also 0 <= q0 < beta, 0 <= r0 < y
910 // und x = x1*beta+x0 = (q1*beta+q0)*y + r0.
911 // Setze q := q1*beta+q0 und r := r0.
912 #if defined(__GNUC__)
913 #define divu_6432_6432(x,y,q_zuweisung,r_zuweisung) \
914 ({var uint64 _x = (x); \
915 var uint32 _y = (y); \
919 divu_6432_3232(0,high32(_x),_y, _q1 = , _r1 = ); \
920 divu_6432_3232(_r1,low32(_x),_y, _q0 = , r_zuweisung); \
921 q_zuweisung highlow64(_q1,_q0); \
924 #define divu_6432_6432(x,y,q_zuweisung,r_zuweisung) \
925 {var uint64 _x = (x); \
926 var uint32 _y = (y); \
930 divu_6432_3232(0,high32(_x),_y, _q1 = , _r1 = ); \
931 divu_6432_3232(_r1,low32(_x),_y, _q0 = , r_zuweisung); \
932 q_zuweisung highlow64(_q1,_q0); \
937 // Dividiert eine 64-Bit-Zahl durch eine 64-Bit-Zahl und
938 // liefert einen 64-Bit-Quotienten und einen 64-Bit-Rest.
939 // divu_6464_6464(x,y,q=,r=);
940 // > uint64 x: Zähler
941 // > uint64 y: Nenner
942 // > Es sei bekannt, daß y>0.
943 // < uint64 q: floor(x/y)
944 // < uint64 r: x mod y
946 #if defined(__GNUC__) && (defined(__alpha__) || defined(__ia64__) || defined(__mips64__) || defined(__sparc64__))
947 // On __alpha__, computing the remainder by multiplication is just two
948 // instructions, compared to the __remqu (libc) function call for the %
950 // On __ia64__, computing the remainder by multiplication is just four
951 // instructions, compared to the __umoddi3 (libgcc) function call for the %
953 // On __mips64__, computing the remainder by multiplication is just two
954 // instructions, compared to the __umoddi3 (libgcc) function call for the %
956 // On __sparc64__, it doesn't matter.
957 #define divu_6464_6464(x,y,q_zuweisung,r_zuweisung) \
958 ({var uint64 _x = (x); \
959 var uint64 _y = (y); \
961 q_zuweisung _q = floor(_x,_y); \
962 r_zuweisung _x - _q * _y; \
964 #elif defined(__GNUC__) && (defined(__sparc64__) || defined(__x86_64__))
965 // On __sparc64__, it doesn't matter.
966 // On __x86_64__, gcc 4.0 performs both quotient and remainder computation
967 // in a single instruction.
968 #define divu_6464_6464(x,y,q_zuweisung,r_zuweisung) \
969 ({var uint64 _x = (x); \
970 var uint64 _y = (y); \
971 q_zuweisung floor(_x,_y); \
972 r_zuweisung _x % _y; \
975 // For unknown CPUs, we don't know whether gcc's __udivdi3 function plus a
976 // multiplication is slower or faster than our own divu_6464_6464_ routine.
977 // Anyway, call our own routine.
978 extern "C" uint64 divu_6464_6464_ (uint64 x, uint64 y); // -> Quotient q
980 // Workaround MSVC compiler bug.
981 } extern "C" uint64 divu_64_rest; namespace cln { // -> Rest r
983 extern "C" uint64 divu_64_rest; // -> Rest r
985 #define divu_6464_6464(x,y,q_zuweisung,r_zuweisung) \
986 { q_zuweisung divu_6464_6464_(x,y); r_zuweisung divu_64_rest; }
987 #define NEED_VAR_divu_64_rest
988 #define NEED_FUNCTION_divu_6464_6464_
991 // Dividiert eine 128-Bit-Zahl durch eine 64-Bit-Zahl und
992 // liefert einen 64-Bit-Quotienten und einen 64-Bit-Rest.
993 // divu_12864_6464(xhi,xlo,y,q=,r=);
994 // > uint64 xhi,xlo: x = 2^64*xhi+xlo = Zähler
995 // > uint64 y: Nenner
996 // > Es sei bekannt, daß 0 <= x < 2^64*y .
997 // < uint64 q: floor(x/y)
998 // < uint64 r: x mod y
1000 extern "C" uint64 divu_12864_6464_ (uint64 xhi, uint64 xlo, uint64 y); // -> Quotient q
1002 // Workaround MSVC compiler bug.
1003 } extern "C" uint64 divu_64_rest; namespace cln { // -> Rest r
1005 extern "C" uint64 divu_64_rest; // -> Rest r
1007 #if defined(__GNUC__) && defined(__x86_64__) && !defined(NO_ASM)
1008 #define divu_12864_6464(xhi,xlo,y,q_zuweisung,r_zuweisung) \
1009 ({var uint64 __xhi = (xhi); \
1010 var uint64 __xlo = (xlo); \
1011 var uint64 __y = (y); \
1014 __asm__ __volatile__ ( \
1016 : "=a" /* %rax */ (__q), "=d" /* %rdx */ (__r) \
1017 : "1" /* %rdx */ (__xhi), "0" /* %rax */ (__xlo), "rm" (__y) \
1022 #define divu_12864_64364_(xhi,xlo,y) \
1023 ({var uint64 ___q; divu_12864_6464(xhi,xlo,y,___q=,); ___q; })
1025 #define divu_12864_6464(xhi,xlo,y,q_zuweisung,r_zuweisung) \
1026 { q_zuweisung divu_12864_6464_(xhi,xlo,y); r_zuweisung divu_64_rest; }
1027 #define NEED_VAR_divu_64_rest
1028 #define NEED_FUNCTION_divu_12864_6464_
1031 #endif /* HAVE_FAST_LONGLONG */
1034 // Zieht die Ganzzahl-Wurzel aus einer 32-Bit-Zahl und
1035 // liefert eine 16-Bit-Wurzel und einen Rest.
1036 // isqrt_32_16(x,y=,sqrtp=);
1037 // > uint32 x: Radikand, >= 2^30, < 2^32
1038 // < uint16 y: floor(sqrt(x)), >= 2^15, < 2^16
1039 // < boolean sqrtp: /=0, falls x=y^2
1041 // y := 2^16 als Anfangswert,
1042 // y := floor((y + floor(x/y))/2) als nächster Wert,
1043 // solange z := floor(x/y) < y, setze y := floor((y+z)/2).
1044 // y ist fertig; x=y^2 genau dann, wenn z=y und die letzte Division aufging.
1046 // 1. Die Folge der y ist streng monoton fallend.
1047 // 2. Stets gilt y >= floor(sqrt(x)) (denn für alle y>0 ist
1048 // y + x/y >= 2*sqrt(x) und daher floor((y + floor(x/y))/2) =
1049 // floor(y/2 + x/(2*y)) >= floor(sqrt(x)) ).
1050 // 3. Am Schluß gilt x >= y^2.
1052 #define isqrt_32_16(x,y_zuweisung,sqrtp_zuweisung) \
1053 { var uint32 _x = (x); \
1054 var uint16 _x1 = high16(_x); \
1055 var uint16 _y = floor(_x1,2) | bit(16-1); \
1059 if (_x1 >= _y) /* Division _x/_y ergäbe Überlauf -> _z > _y */\
1060 { unused (sqrtp_zuweisung FALSE); break; } \
1061 divu_3216_1616(_x,_y, _z=,_r=); /* Dividiere _x/_y */ \
1063 { unused (sqrtp_zuweisung (_z == _y) && (_r == 0)); break; } \
1064 _y = floor((uint16)(_z+_y),2) | bit(16-1); /* _y muß >= 2^15 bleiben */\
1069 // Zieht die Ganzzahl-Wurzel aus einer 64-Bit-Zahl und
1070 // liefert eine 32-Bit-Wurzel und einen Rest.
1071 // isqrt_64_32(xhi,xlo,y=,sqrtp=);
1072 // > uint32 xhi,xlo: Radikand x = 2^32*xhi+xlo, >= 2^62, < 2^64
1073 // < uint32 y: floor(sqrt(x)), >= 2^31, < 2^32
1074 // < boolean sqrtp: /=0, falls x=y^2
1075 #if defined(__sparc__) || defined(__sparc64__) || defined(__m68k__) || defined(__hppa__)
1077 // y := 2^32 als Anfangswert,
1078 // y := floor((y + floor(x/y))/2) als nächster Wert,
1079 // solange z := floor(x/y) < y, setze y := floor((y+z)/2).
1080 // y ist fertig; x=y^2 genau dann, wenn z=y und die letzte Division aufging.
1082 // 1. Die Folge der y ist streng monoton fallend.
1083 // 2. Stets gilt y >= floor(sqrt(x)) (denn für alle y>0 ist
1084 // y + x/y >= 2*sqrt(x) und daher floor((y + floor(x/y))/2) =
1085 // floor(y/2 + x/(2*y)) >= floor(sqrt(x)) ).
1086 // 3. Am Schluß gilt x >= y^2.
1088 #define isqrt_64_32(xhi,xlo,y_zuweisung,sqrtp_zuweisung) \
1089 { var uint32 _xhi = (xhi); \
1090 var uint32 _xlo = (xlo); \
1091 var uint32 _y = floor(_xhi,2) | bit(32-1); \
1095 if (_xhi >= _y) /* Division _x/_y ergäbe Überlauf -> _z > _y */\
1096 { sqrtp_zuweisung FALSE; break; } \
1097 divu_6432_3232(_xhi,_xlo,_y, _z=,_rest=); /* Dividiere _x/_y */\
1099 { sqrtp_zuweisung (_z == _y) && (_rest == 0); break; } \
1100 _y = floor(_z+_y,2) | bit(32-1); /* _y muß >= 2^31 bleiben */ \
1106 // Wie bei UDS_sqrt mit n=2.
1107 // y = 2^16*yhi + ylo ansetzen.
1109 // yhi = floor(y/2^16) = floor(floor(sqrt(x))/2^16)
1110 // = floor(sqrt(x)/2^16) = floor(sqrt(x/2^32)) = isqrt(xhi)
1111 // sein. Es folgt yhi >= 2^15.
1112 // Danach sucht man das größte ylo >=0 mit
1113 // x - 2^32*yhi^2 >= 2*2^16*yhi*ylo + ylo^2.
1114 // Dazu setzen wir xhi*2^32+xlo := x - 2^32*yhi^2
1115 // (also xhi := xhi - yhi^2, das ist >=0, <=2*yhi).
1116 // Die Schätzung für die zweite Ziffer
1117 // ylo' := min(2^16-1,floor((xhi*2^32+xlo)/(2*2^16*yhi)))
1118 // erfüllt ylo'-1 <= ylo <= ylo', ist also um höchstens 1 zu groß.
1119 // (Beweis: Rechte Ungleichung klar, da ylo < 2^16 und
1120 // xhi*2^32+xlo >= 2*2^16*yhi*ylo + ylo^2 >= 2*2^16*yhi*ylo
1121 // ==> (xhi*2^32+xlo)/(2*2^16*yhi) >= ylo gelten muß.
1122 // Linke Ungleichung: Falls floor(...)>=2^16, ist
1123 // xhi*2^32+xlo >= 2*2^16*2^16*yhi >= 2*2^16*yhi*(2^16-1) + 2^32
1124 // >= 2*2^16*yhi*(2^16-1) + (2^16-1)^2
1125 // und xhi*2^32+xlo < 2*2^16*2^16*yhi + (2^16)^2, also
1126 // ylo = 2^16-1 = ylo'.
1127 // Sonst ist ylo' = floor((xhi*2^32+xlo)/(2*2^16*yhi)), also
1128 // xhi*2^32+xlo >= 2*2^16*yhi*ylo' >= 2*2^16*yhi*(ylo'-1) + 2^32
1129 // >= 2*2^16*yhi*(ylo'-1) + (ylo'-1)^2,
1130 // also ylo >= ylo'-1 nach Definition von ylo.)
1131 #define isqrt_64_32(xhi,xlo,y_zuweisung,sqrtp_zuweisung) \
1132 { var uint32 _xhi = (xhi); \
1133 var uint32 _xlo = (xlo); \
1136 /* erste Ziffer berechnen: */ \
1137 isqrt_32_16(_xhi,_yhi=,); /* yhi := isqrt(xhi) */ \
1138 _xhi -= mulu16(_yhi,_yhi); /* jetzt 0 <= xhi <= 2*yhi */ \
1139 /* x = 2^32*yhi^2 + 2^32*xhi + xlo */ \
1140 /* Schätzung für die zweite Ziffer berechnen: */ \
1141 /* ylo := min(2^16-1,floor((xhi*2^32+xlo)/(2*2^16*yhi))) bilden: */\
1142 {var uint32 _z = (_xhi << 15) | (_xlo >> 17); /* < 2^15*(2*yhi+1) */\
1143 var uint32 _r = highlow32_0(_yhi); \
1145 { _ylo = bit(16)-1; _r = _z - _r + (uint32)_yhi; } \
1147 { divu_3216_1616(_z,_yhi, _ylo=,_r=); } \
1148 /* x = 2^32*yhi^2 + 2*2^16*yhi*ylo + 2^17*r + (xlo mod 2^17), */ \
1149 /* 0 <= r < yhi + 2^15 */ \
1150 _xlo = (_r << 17) | (_xlo & (bit(17)-1)); \
1151 /* x = 2^32*yhi^2 + 2*2^16*yhi*ylo + 2^32*floor(r/2^15) + xlo */ \
1152 _z = mulu16(_ylo,_ylo); /* z = ylo^2 */ \
1153 /* Versuche vom Rest 2^32*floor(r/2^15) + xlo z zu subtrahieren. */\
1154 /* Falls Rest >= z (d.h. r>=2^15 oder xlo>=z), ist ylo fertig, */ \
1155 /* und es gilt x=y^2 genau dann, wenn r<2^15 und xlo=z. */ \
1156 /* Sonst (d.h. r<2^15 und xlo<z), muß man ylo erniedrigen. Dazu */\
1157 /* setzt man ylo := ylo-1, z := z-(2*ylo+1), */ \
1158 /* Rest := Rest + 2^17*yhi = xlo + 2^17*yhi >= 2^32 > z, also x>y^2. */\
1161 { _ylo -= 1; unused (sqrtp_zuweisung FALSE); } \
1163 { unused (sqrtp_zuweisung (_xlo == _z)); } \
1166 { unused (sqrtp_zuweisung FALSE); } \
1167 y_zuweisung highlow32(_yhi,_ylo); \
1171 #ifdef HAVE_FAST_LONGLONG
1173 // Zieht die Ganzzahl-Wurzel aus einer 128-Bit-Zahl und
1174 // liefert eine 64-Bit-Wurzel und einen Rest.
1175 // isqrt_128_64(xhi,xlo,y=,sqrtp=);
1176 // > uint64 xhi,xlo: Radikand x = 2^64*xhi+xlo, >= 2^126, < 2^128
1177 // < uint64 y: floor(sqrt(x)), >= 2^63, < 2^64
1178 // < boolean sqrtp: /=0, falls x=y^2
1180 // Wie bei UDS_sqrt mit n=2.
1181 // y = 2^32*yhi + ylo ansetzen.
1183 // yhi = floor(y/2^32) = floor(floor(sqrt(x))/2^32)
1184 // = floor(sqrt(x)/2^32) = floor(sqrt(x/2^64)) = isqrt(xhi)
1185 // sein. Es folgt yhi >= 2^31.
1186 // Danach sucht man das größte ylo >=0 mit
1187 // x - 2^64*yhi^2 >= 2*2^32*yhi*ylo + ylo^2.
1188 // Dazu setzen wir xhi*2^64+xlo := x - 2^64*yhi^2
1189 // (also xhi := xhi - yhi^2, das ist >=0, <=2*yhi).
1190 // Die Schätzung für die zweite Ziffer
1191 // ylo' := min(2^32-1,floor((xhi*2^64+xlo)/(2*2^32*yhi)))
1192 // erfüllt ylo'-1 <= ylo <= ylo', ist also um höchstens 1 zu groß.
1193 // (Beweis: Rechte Ungleichung klar, da ylo < 2^32 und
1194 // xhi*2^64+xlo >= 2*2^32*yhi*ylo + ylo^2 >= 2*2^32*yhi*ylo
1195 // ==> (xhi*2^64+xlo)/(2*2^32*yhi) >= ylo gelten muß.
1196 // Linke Ungleichung: Falls floor(...)>=2^32, ist
1197 // xhi*2^64+xlo >= 2*2^32*2^32*yhi >= 2*2^32*yhi*(2^32-1) + 2^64
1198 // >= 2*2^32*yhi*(2^32-1) + (2^32-1)^2
1199 // und xhi*2^64+xlo < 2*2^32*2^32*yhi + (2^32)^2, also
1200 // ylo = 2^32-1 = ylo'.
1201 // Sonst ist ylo' = floor((xhi*2^64+xlo)/(2*2^32*yhi)), also
1202 // xhi*2^64+xlo >= 2*2^32*yhi*ylo' >= 2*2^32*yhi*(ylo'-1) + 2^64
1203 // >= 2*2^32*yhi*(ylo'-1) + (ylo'-1)^2,
1204 // also ylo >= ylo'-1 nach Definition von ylo.)
1205 #define isqrt_128_64(x_hi,x_lo,y_zuweisung,sqrtp_zuweisung) \
1206 { var uint64 xhi = (x_hi); \
1207 var uint64 xlo = (x_lo); \
1210 /* erste Ziffer berechnen: */ \
1211 isqrt_64_32(high32(xhi),low32(xhi),yhi=,); /* yhi := isqrt(xhi) */\
1212 xhi -= mulu32_w(yhi,yhi); /* jetzt 0 <= xhi <= 2*yhi */ \
1213 /* x = 2^64*yhi^2 + 2^64*xhi + xlo */ \
1214 /* Schätzung für die zweite Ziffer berechnen: */ \
1215 /* ylo := min(2^32-1,floor((xhi*2^64+xlo)/(2*2^32*yhi))) bilden: */\
1216 {var uint64 z = (xhi << 31) | (xlo >> 33); /* < 2^31*(2*yhi+1) */ \
1217 var uint64 r = highlow64_0(yhi); \
1219 { ylo = bit(32)-1; r = z - r + (uint64)yhi; } \
1221 { divu_6432_3232_w(z,yhi, ylo=,r=); } \
1222 /* x = 2^64*yhi^2 + 2*2^32*yhi*ylo + 2^33*r + (xlo mod 2^33), */ \
1223 /* 0 <= r < yhi + 2^31 */ \
1224 xlo = (r << 33) | (xlo & (bit(33)-1)); \
1225 /* x = 2^64*yhi^2 + 2*2^32*yhi*ylo + 2^64*floor(r/2^31) + xlo */ \
1226 z = mulu32_w(ylo,ylo); /* z = ylo^2 */ \
1227 /* Versuche vom Rest 2^64*floor(r/2^31) + xlo z zu subtrahieren. */\
1228 /* Falls Rest >= z (d.h. r>=2^31 oder xlo>=z), ist ylo fertig, */ \
1229 /* und es gilt x=y^2 genau dann, wenn r<2^31 und xlo=z. */ \
1230 /* Sonst (d.h. r<2^31 und xlo<z), muß man ylo erniedrigen. Dazu */\
1231 /* setzt man ylo := ylo-1, z := z-(2*ylo+1), */ \
1232 /* Rest := Rest + 2^33*yhi = xlo + 2^33*yhi >= 2^64 > z, also x>y^2. */\
1235 { ylo -= 1; sqrtp_zuweisung FALSE; } \
1237 { sqrtp_zuweisung (xlo == z); } \
1240 { sqrtp_zuweisung FALSE; } \
1241 y_zuweisung highlow64(yhi,ylo); \
1244 #endif /* HAVE_FAST_LONGLONG */
1246 // Zieht die Ganzzahl-Wurzel aus einer 32-Bit-Zahl und
1247 // liefert eine 16-Bit-Wurzel.
1249 // > uintL x : Radikand, >=0, <2^32
1250 // < uintL ergebnis : Wurzel, >=0, <2^16
1251 extern uintL isqrt (uintL x);
1253 // Extracts integer root of a 64-bit number and returns a 32-bit number.
1255 // > uintQ x : radicand, >=0, <2^64
1256 // < uintL result : square root, >=0, <2^32
1257 extern uintL isqrt (uintQ x);
1259 // Sorry for this. We need an isqrt function taking uintC arguments but we
1260 // cannot use overloading since this would lead to ambiguities with any of the
1261 // two signatures above.
1262 inline uintL isqrtC (uintC x)
1265 return isqrt((uintL)x);
1267 return isqrt((uintQ)x);
1272 // Zieht die Ganzzahl-Wurzel aus einer 64-Bit-Zahl und
1273 // liefert eine 32-Bit-Wurzel.
1275 // > uintL2 x = x1*2^32+x0 : Radikand, >=0, <2^64
1276 // < uintL ergebnis : Wurzel, >=0, <2^32
1277 extern uintL isqrt (uintL x1, uintL x0);
1280 // Bits einer 8-Bit-Zahl zählen:
1281 // integerlength8(digit,size=);
1282 // setzt size auf die höchste in digit vorkommende Bitnummer.
1283 // > digit: ein uint8 >0
1284 // < size: >0, <=8, mit 2^(size-1) <= digit < 2^size
1285 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1286 #define integerlength8(digit,size_zuweisung) \
1287 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1288 __asm__("bfffo %1{#0:#8},%0" : "=d" (_zero_counter) : "dm" ((uint8)(digit)) ); \
1289 size_zuweisung (8-_zero_counter); \
1291 #elif defined(__sparc__) && !defined(__sparc64__)
1292 #define integerlength8(digit,size_zuweisung) \
1293 integerlength32((uint32)(digit),size_zuweisung) // siehe unten
1294 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1295 #define integerlength8(digit,size_zuweisung) \
1296 integerlength16((uint16)(digit),size_zuweisung)
1298 #define integerlength8(digit,size_zuweisung) \
1299 { var uintC _bitsize = 1; \
1300 var uintL _x8 = (uint8)(digit); \
1301 /* _x8 hat höchstens 8 Bits. */\
1302 if (_x8 >= bit(4)) { _x8 = _x8>>4; _bitsize += 4; } \
1303 /* _x8 hat höchstens 4 Bits. */\
1304 if (_x8 >= bit(2)) { _x8 = _x8>>2; _bitsize += 2; } \
1305 /* _x8 hat höchstens 2 Bits. */\
1306 if (_x8 >= bit(1)) { /* _x8 = _x8>>1; */ _bitsize += 1; } \
1307 /* _x8 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein. */\
1308 size_zuweisung _bitsize; \
1312 // Bits einer 16-Bit-Zahl zählen:
1313 // integerlength16(digit,size=);
1314 // setzt size auf die höchste in digit vorkommende Bitnummer.
1315 // > digit: ein uint16 >0
1316 // < size: >0, <=16, mit 2^(size-1) <= digit < 2^size
1317 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1318 #define integerlength16(digit,size_zuweisung) \
1319 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1320 __asm__("bfffo %1{#0:#16},%0" : "=d" (_zero_counter) : "dm" ((uint16)(digit)) ); \
1321 size_zuweisung (16-_zero_counter); \
1323 #elif defined(__sparc__) && !defined(__sparc64__)
1324 #define integerlength16(digit,size_zuweisung) \
1325 integerlength32((uint32)(digit),size_zuweisung) // siehe unten
1326 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1327 #define integerlength16(digit,size_zuweisung) \
1328 { var uintW _one_position; /* Position der führenden 1 */\
1329 __asm__("bsrw %1,%0" : "=r" (_one_position) : "r" ((uint16)(digit)) ); \
1330 size_zuweisung (1+_one_position); \
1332 // Die weiteren kommen von gcc/longlong.h :
1333 #elif defined(__GNUC__) && defined(__ibm032__) && !defined(NO_ASM) // RT/ROMP
1334 #define integerlength16(digit,size_zuweisung) \
1335 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1336 __asm__("clz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1337 size_zuweisung (16-_zero_counter); \
1340 #define integerlength16(digit,size_zuweisung) \
1341 { var uintC _bitsize = 1; \
1342 var uintWL _x16 = (uint16)(digit); \
1343 /* _x16 hat höchstens 16 Bits. */\
1344 if (_x16 >= bit(8)) { _x16 = _x16>>8; _bitsize += 8; } \
1345 /* _x16 hat höchstens 8 Bits. */\
1346 if (_x16 >= bit(4)) { _x16 = _x16>>4; _bitsize += 4; } \
1347 /* _x16 hat höchstens 4 Bits. */\
1348 if (_x16 >= bit(2)) { _x16 = _x16>>2; _bitsize += 2; } \
1349 /* _x16 hat höchstens 2 Bits. */\
1350 if (_x16 >= bit(1)) { /* _x16 = _x16>>1; */ _bitsize += 1; } \
1351 /* _x16 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein. */\
1352 size_zuweisung _bitsize; \
1356 // Bits einer 32-Bit-Zahl zählen:
1357 // integerlength32(digit,size=);
1358 // setzt size auf die höchste in digit vorkommende Bitnummer.
1359 // > digit: ein uint32 >0
1360 // < size: >0, <=32, mit 2^(size-1) <= digit < 2^size
1361 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1362 #define integerlength32(digit,size_zuweisung) \
1363 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1364 __asm__("bfffo %1{#0:#32},%0" : "=d" (_zero_counter) : "dm" ((uint32)(digit)) ); \
1365 size_zuweisung (32-_zero_counter); \
1367 #elif defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
1368 #define integerlength32(digit,size_zuweisung) \
1369 {var union { double f; uint32 i[2]; } __fi; \
1370 const int df_mant_len = 52; /* mantissa bits (excl. hidden bit) */\
1371 const int df_exp_mid = 1022; /* exponent bias */ \
1372 /* Bilde 2^52 + digit: */\
1373 __fi.i[0] = (uint32)(df_mant_len+1+df_exp_mid) << (df_mant_len-32); /* Vorzeichen 0, Exponent 53 */\
1374 __fi.i[1] = (digit); /* untere 32 Bits setzen (benutzt CL_CPU_BIG_ENDIAN_P !) */\
1375 /* subtrahiere 2^52: */\
1376 __fi.f = __fi.f - (double)(4503599627370496.0L); \
1377 /* Hole davon den Exponenten: */\
1378 size_zuweisung ((__fi.i[0] >> (df_mant_len-32)) - df_exp_mid); \
1380 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1381 #define integerlength32(digit,size_zuweisung) \
1382 { var uintL _one_position; /* Position der führenden 1 */\
1383 __asm__("bsrl %1,%0" : "=r" (_one_position) : "rm" ((uint32)(digit)) ); \
1384 size_zuweisung (1+_one_position); \
1386 #elif defined(__hppa__) && !defined(NO_ASM)
1387 #define integerlength32(digit,size_zuweisung) \
1388 size_zuweisung length32(digit);
1389 extern "C" uintL length32 (uintL digit); // extern in Assembler
1390 // Die weiteren kommen von gcc/longlong.h :
1391 #elif defined(__GNUC__) && (defined(__a29k__) || defined(___AM29K__)) && !defined(NO_ASM)
1392 #define integerlength32(digit,size_zuweisung) \
1393 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1394 __asm__("clz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1395 size_zuweisung (32-_zero_counter); \
1397 #elif defined(__GNUC__) && defined(__gmicro__) && !defined(NO_ASM)
1398 #define integerlength32(digit,size_zuweisung) \
1399 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1400 __asm__("bsch/1 %1,%0" : "=g" (_zero_counter) : "g" ((uint32)(digit)) ); \
1401 size_zuweisung (32-_zero_counter); \
1403 #elif defined(__GNUC__) && defined(__rs6000__) && !defined(NO_ASM)
1405 // old assembler syntax
1406 #define integerlength32(digit,size_zuweisung) \
1407 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1408 __asm__("cntlz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1409 size_zuweisung (32-_zero_counter); \
1412 // new assembler syntax
1413 #define integerlength32(digit,size_zuweisung) \
1414 { var uintL _zero_counter; /* zählt die führenden Nullbits in digit */\
1415 __asm__("cntlzw %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1416 size_zuweisung (32-_zero_counter); \
1419 #elif defined(__GNUC__) && defined(__m88k__) && !defined(NO_ASM)
1420 #define integerlength32(digit,size_zuweisung) \
1421 { var uintL _one_position; /* Position der führenden 1 */\
1422 __asm__("ff1 %0,%1" : "=r" (_one_position) : "r" ((uint32)(digit)) ); \
1423 size_zuweisung (1+_one_position); \
1425 #elif defined(__GNUC__) && defined(__ibm032__) && !defined(NO_ASM) // RT/ROMP
1426 #define integerlength32(digit,size_zuweisung) \
1427 { var uintL _x32 = (uint32)(digit); \
1428 if (_x32 >= bit(16)) \
1429 { integerlength16(_x32>>16,size_zuweisung 16 + ); } \
1431 { integerlength16(_x32,size_zuweisung); } \
1434 #define integerlength32(digit,size_zuweisung) \
1435 { var uintC _bitsize = 1; \
1436 var uintL _x32 = (uint32)(digit); \
1437 /* _x32 hat höchstens 32 Bits. */\
1438 if (_x32 >= bit(16)) { _x32 = _x32>>16; _bitsize += 16; } \
1439 /* _x32 hat höchstens 16 Bits. */\
1440 if (_x32 >= bit(8)) { _x32 = _x32>>8; _bitsize += 8; } \
1441 /* _x32 hat höchstens 8 Bits. */\
1442 if (_x32 >= bit(4)) { _x32 = _x32>>4; _bitsize += 4; } \
1443 /* _x32 hat höchstens 4 Bits. */\
1444 if (_x32 >= bit(2)) { _x32 = _x32>>2; _bitsize += 2; } \
1445 /* _x32 hat höchstens 2 Bits. */\
1446 if (_x32 >= bit(1)) { /* _x32 = _x32>>1; */ _bitsize += 1; } \
1447 /* _x32 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein. */\
1448 size_zuweisung _bitsize; \
1450 #define GENERIC_INTEGERLENGTH32
1453 // Bits einer 64-Bit-Zahl zählen:
1454 // integerlength64(digit,size=);
1455 // setzt size auf die höchste in digit vorkommende Bitnummer.
1456 // > digit: ein uint64 >0
1457 // < size: >0, <=64, mit 2^(size-1) <= digit < 2^size
1458 #ifdef GENERIC_INTEGERLENGTH32
1459 #define integerlength64(digit,size_zuweisung) \
1460 { var uintC _bitsize = 1; \
1461 var uint64 _x64 = (uint64)(digit); \
1462 /* _x64 hat höchstens 64 Bits. */\
1463 if (_x64 >= bit(32)) { _x64 = _x64>>32; _bitsize += 32; } \
1464 /* _x64 hat höchstens 32 Bits. */\
1465 if (_x64 >= bit(16)) { _x64 = _x64>>16; _bitsize += 16; } \
1466 /* _x64 hat höchstens 16 Bits. */\
1467 if (_x64 >= bit(8)) { _x64 = _x64>>8; _bitsize += 8; } \
1468 /* _x64 hat höchstens 8 Bits. */\
1469 if (_x64 >= bit(4)) { _x64 = _x64>>4; _bitsize += 4; } \
1470 /* _x64 hat höchstens 4 Bits. */\
1471 if (_x64 >= bit(2)) { _x64 = _x64>>2; _bitsize += 2; } \
1472 /* _x64 hat höchstens 2 Bits. */\
1473 if (_x64 >= bit(1)) { /* _x64 = _x64>>1; */ _bitsize += 1; } \
1474 /* _x64 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein. */\
1475 size_zuweisung _bitsize; \
1478 #define integerlength64(digit,size_zuweisung) \
1479 { var uint64 _x64 = (digit); \
1480 var uintC _bitsize64 = 0; \
1481 var uint32 _x32_from_integerlength64; \
1482 if (_x64 >= (1ULL << 32)) { \
1483 _x32_from_integerlength64 = _x64>>32; _bitsize64 += 32; \
1485 _x32_from_integerlength64 = _x64; \
1487 integerlength32(_x32_from_integerlength64, size_zuweisung _bitsize64 + ); \
1491 // Bits einer uintC-Zahl zählen:
1492 // integerlengthC(digit,size=);
1493 // setzt size auf die höchste in digit vorkommende Bitnummer.
1494 // > digit: ein uintC >0
1495 // < size: >0, <=intCsize, mit 2^(size-1) <= digit < 2^size
1497 #define integerlengthC integerlength32
1500 #define integerlengthC integerlength64
1503 // Hintere Nullbits eines 32-Bit-Wortes zählen:
1504 // ord2_32(digit,count=);
1505 // setzt size auf die kleinste in digit vorkommende Bitnummer.
1506 // > digit: ein uint32 >0
1507 // < count: >=0, <32, mit 2^count | digit, digit/2^count ungerade
1508 #if defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1509 #define ord2_32(digit,count_zuweisung) \
1510 { var uintL _one_position; /* Position der letzten 1 */\
1511 __asm__("bsfl %1,%0" : "=r" (_one_position) : "rm" ((uint32)(digit)) ); \
1512 count_zuweisung _one_position; \
1515 #elif defined(__sparc__) && !defined(__sparc64__)
1516 #define ord2_32(digit,count_zuweisung) \
1517 { var uint32 n = (digit); \
1521 n = n - (n<<16); /* or n = n ^ (n<<16); or n = n &~ (n<<16); */ \
1522 /* static const char ord2_tab [64] = {-1,0,1,12,2,6,-1,13,3,-1,7,-1,-1,-1,-1,14,10,4,-1,-1,8,-1,-1,25,-1,-1,-1,-1,-1,21,27,15,31,11,5,-1,-1,-1,-1,-1,9,-1,-1,24,-1,-1,20,26,30,-1,-1,-1,-1,23,-1,19,29,-1,22,18,28,17,16,-1}; */ \
1523 /* count_zuweisung ord2_tab[n>>26]; */ \
1524 count_zuweisung "\377\000\001\014\002\006\377\015\003\377\007\377\377\377\377\016\012\004\377\377\010\377\377\031\377\377\377\377\377\025\033\017\037\013\005\377\377\377\377\377\011\377\377\030\377\377\024\032\036\377\377\377\377\027\377\023\035\377\026\022\034\021\020"[n>>26]; \
1528 // Sei n = ord2(x). Dann ist logxor(x,x-1) = 2^n + (2^n-1) = 2^(n+1)-1.
1529 // Also (ord2 x) = (1- (integer-length (logxor x (1- x)))) .
1530 #define ord2_32(digit,count_zuweisung) \
1531 { var uint32 _digit = (digit) ^ ((digit) - 1); \
1532 integerlength32(_digit,count_zuweisung -1 + ) \
1536 // Hintere Nullbits eines 64-Bit-Wortes zählen:
1537 // ord2_64(digit,count=);
1538 // setzt size auf die kleinste in digit vorkommende Bitnummer.
1539 // > digit: ein uint64 >0
1540 // < count: >=0, <64, mit 2^count | digit, digit/2^count ungerade
1541 // Sei n = ord2(x). Dann ist logxor(x,x-1) = 2^n + (2^n-1) = 2^(n+1)-1.
1542 // Also (ord2 x) = (1- (integer-length (logxor x (1- x)))) .
1543 #define ord2_64(digit,count_zuweisung) \
1544 { var uint64 _digit = (digit) ^ ((digit) - 1); \
1545 integerlength64(_digit,count_zuweisung -1 + ) \
1549 // Bits eines Wortes zählen.
1551 // > xNN: ein uintNN
1552 // < xNN: Anzahl der darin gesetzten Bits
1553 // Bits von x8 zählen: (Input x8, Output x8)
1554 #define logcount_8() \
1555 ( /* x8 besteht aus 8 1-Bit-Zählern (0,1). */\
1556 x8 = (x8 & 0x55U) + ((x8 & 0xAAU) >> 1), \
1557 /* x8 besteht aus 4 2-Bit-Zählern (0,1,2). */\
1558 x8 = (x8 & 0x33U) + ((x8 & 0xCCU) >> 2), \
1559 /* x8 besteht aus 2 4-Bit-Zählern (0,1,2,3,4). */\
1560 x8 = (x8 & 0x0FU) + (x8 >> 4) \
1561 /* x8 besteht aus 1 8-Bit-Zähler (0,...,8). */\
1563 // Bits von x16 zählen: (Input x16, Output x16)
1564 #define logcount_16() \
1565 ( /* x16 besteht aus 16 1-Bit-Zählern (0,1). */\
1566 x16 = (x16 & 0x5555U) + ((x16 & 0xAAAAU) >> 1), \
1567 /* x16 besteht aus 8 2-Bit-Zählern (0,1,2). */\
1568 x16 = (x16 & 0x3333U) + ((x16 & 0xCCCCU) >> 2), \
1569 /* x16 besteht aus 4 4-Bit-Zählern (0,1,2,3,4). */\
1570 x16 = (x16 & 0x0F0FU) + ((x16 & 0xF0F0U) >> 4), \
1571 /* x16 besteht aus 2 8-Bit-Zählern (0,...,8). */\
1572 x16 = (x16 & 0x00FFU) + (x16 >> 8) \
1573 /* x16 besteht aus 1 16-Bit-Zähler (0,...,16). */\
1575 // Bits von x32 zählen: (Input x32, Output x32)
1576 #define logcount_32() \
1577 ( /* x32 besteht aus 32 1-Bit-Zählern (0,1). */\
1578 x32 = (x32 & 0x55555555UL) + ((x32 & 0xAAAAAAAAUL) >> 1), \
1579 /* x32 besteht aus 16 2-Bit-Zählern (0,1,2). */\
1580 x32 = (x32 & 0x33333333UL) + ((x32 & 0xCCCCCCCCUL) >> 2), \
1581 /* x32 besteht aus 8 4-Bit-Zählern (0,1,2,3,4). */\
1582 x32 = high16(x32)+low16(x32), \
1583 /* x32 besteht aus 4 4-Bit-Zählern (0,...,8). */\
1584 x32 = (x32 & 0x0F0FU) + ((x32 & 0xF0F0U) >> 4), \
1585 /* x32 besteht aus 2 8-Bit-Zählern (0,...,16). */\
1586 x32 = (x32 & 0x00FFU) + (x32 >> 8) \
1587 /* x32 besteht aus 1 16-Bit-Zähler (0,...,32). */\
1589 // Bits von x64 zählen: (Input x64, Output x64)
1590 #define logcount_64() \
1591 ( /* x64 besteht aus 64 1-Bit-Zählern (0,1). */\
1592 x64 = (x64 & 0x5555555555555555ULL) + ((x64 & 0xAAAAAAAAAAAAAAAAULL) >> 1),\
1593 /* x64 besteht aus 32 2-Bit-Zählern (0,1,2). */\
1594 x64 = (x64 & 0x3333333333333333ULL) + ((x64 & 0xCCCCCCCCCCCCCCCCULL) >> 2),\
1595 /* x64 besteht aus 16 4-Bit-Zählern (0,1,2,3,4). */\
1596 x64 = (uint32)(x64 + (x64 >> 32)), \
1597 /* x64 besteht aus 8 4-Bit-Zählern (0,...,8). */\
1598 x64 = (x64 & 0x0F0F0F0FUL) + ((x64 & 0xF0F0F0F0UL) >> 4), \
1599 /* x64 besteht aus 4 8-Bit-Zählern (0,...,16). */\
1600 x64 = (x64 & 0x00FF00FFU) + ((x64 & 0xFF00FF00U) >> 8), \
1601 /* x64 besteht aus 2 16-Bit-Zählern (0,...,32). */\
1602 x64 = (x64 & 0x0000FFFFU) + (x64 >> 16) \
1603 /* x64 besteht aus 1 16-Bit-Zähler (0,...,64). */\
1608 #endif /* _CL_LOW_H */