]> www.ginac.de Git - cln.git/blob - src/base/cl_low.h
- added some missing `&& !defined(NO_ASM)' in Sparc-#if's.
[cln.git] / src / base / cl_low.h
1 // Low-level arithmetic: operations on 16-bit and 32-bit words
2
3 #ifndef _CL_LOW_H
4 #define _CL_LOW_H
5
6 namespace cln {
7
8 // Determines the sign of a 16-bit number.
9 // sign_of(wert)
10 // > wert: eine 16-Bit-Zahl
11 // < sint16 ergebnis: 0 falls wert>=0, -1 falls wert<0.
12 inline sint16 sign_of (sint16 wert)
13 {
14 #if defined(__sparc64__)
15         return (sint64)wert >> 63;
16 #elif defined(__sparc__) || defined(__arm__)
17         return (sint32)wert >> 31;
18 #else
19         return (wert >= 0 ? 0 : -1);
20 #endif
21 }
22
23 // Determines the sign of a 32-bit number.
24 // sign_of(wert)
25 // > wert: eine 32-Bit-Zahl
26 // < sint32 ergebnis: 0 falls wert>=0, -1 falls wert<0.
27 inline sint32 sign_of (sint32 wert)
28 {
29 #if defined(__sparc64__)
30         return (sint64)wert >> 63;
31 #elif defined(__sparc__) || defined(__arm__)
32         return wert >> 31;
33 #else
34         return (wert >= 0 ? 0 : -1);
35 #endif
36 }
37
38 #ifdef HAVE_FAST_LONGLONG
39
40 // Determines the sign of a 64-bit number.
41 // sign_of(wert)
42 // > wert: eine 64-Bit-Zahl
43 // < sint64 ergebnis: 0 falls wert>=0, -1 falls wert<0.
44 inline sint64 sign_of (sint64 wert)
45 {
46         return wert >> 63;
47 }
48
49 #endif /* HAVE_FAST_LONGLONG */
50
51
52 // High-Word einer 32-Bit-Zahl bestimmen
53 // high16(wert)
54 inline uint16 high16 (uint32 wert)
55 {
56         return wert >> 16;
57 }
58
59 // Low-Word einer 32-Bit-Zahl bestimmen
60 // low16(wert)
61 inline uint16 low16 (uint32 wert)
62 {
63         return (uint16)wert;
64 }
65
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)
69 {
70         return ((uint32)high << 16) | (uint32)low;
71 }
72
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)
76 {
77         return (uint32)high << 16;
78 }
79
80 #ifdef HAVE_FAST_LONGLONG
81
82 // High-Word einer 64-Bit-Zahl bestimmen
83 // high32(wert)
84 inline uint32 high32 (uint64 wert)
85 {
86         return wert >> 32;
87 }
88
89 // Low-Word einer 64-Bit-Zahl bestimmen
90 // low32(wert)
91 inline uint32 low32 (uint64 wert)
92 {
93         return (uint32)wert;
94 }
95
96 // Eine 64-Bit-Zahl aus ihrem High-Word und ihrem Low-Word bestimmen:
97 // highlow64(uint32 high, uint32 low)
98 inline uint64 highlow64 (uint32 high, uint32 low)
99 {
100         return ((uint64)high << 32) | (uint64)low;
101 }
102
103 // Eine 64-Bit-Zahl aus ihrem High-Word und ihrem Low-Word 0 bestimmen:
104 // highlow64_0(uint32 high)
105 inline uint64 highlow64_0 (uint32 high)
106 {
107         return (uint64)high << 32;
108 }
109
110 #endif /* HAVE_FAST_LONGLONG */
111
112
113 // Multipliziert zwei 16-Bit-Zahlen miteinander und liefert eine 32-Bit-Zahl:
114 // mulu16(arg1,arg2)
115 // > arg1, arg2 : zwei 16-Bit-Zahlen
116 // < ergebnis: eine 32-Bit-Zahl
117 #if defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
118 // Ist das schneller als mulu16_ ??
119 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
120 {
121         union { double f; uint32 i[2]; } __fi;
122         __fi.f = (double)(sint32)arg1 * (double)(sint32)arg2
123                  + (double)(4503599627370496.0L); // + 2^52, zum Normalisieren
124         return __fi.i[1]; // untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !)
125 }
126 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
127 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
128 {
129         register uint64 _prod;
130         __asm__("umul %1,%2,%0"
131                 : "=r" (_prod)
132                 : "r" (arg1), "r" (arg2)
133                );
134         return _prod;
135 }
136 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
137 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
138 {
139         register uint16 _hi;
140         register uint16 _lo;
141         __asm__("mulw %2"
142                 : "=d" /* %dx */ (_hi), "=a" /* %ax */ (_lo)
143                 : "rm" (arg1), "1" /* %eax */ (arg2)
144                );
145         return highlow32(_hi,_lo);
146 }
147 #elif defined(__sparc__) || defined(__sparc64__)
148   extern "C" uint32 mulu16_ (uint16 arg1, uint16 arg2);
149   #define mulu16  mulu16_  // extern in Assembler
150 #else
151 inline uint32 mulu16 (uint16 arg1, uint16 arg2)
152 {
153         return arg1 * arg2;
154 }
155 #endif
156
157 // Multipliziert zwei 24-Bit-Zahlen zusammen und liefert eine 48-Bit-Zahl.
158 // mulu24(arg1,arg2,hi=,lo=);
159 // > arg1, arg2 : zwei 24-Bit-Zahlen
160 // < 2^32*hi+lo : eine 48-Bit-Zahl
161 #if defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
162   #define mulu24(x,y,hi_zuweisung,lo_zuweisung)  \
163     { var uint32 _x = (x);                                      \
164       var uint32 _y = (y);                                      \
165       var union { double f; uint32 i[2]; uint16 s[4]; } __fi;   \
166       __fi.f = (double)(sint32)(_x)*(double)(sint32)(_y)        \
167                + (double)(4503599627370496.0L); /* + 2^52, zum Normalisieren */\
168       hi_zuweisung __fi.s[1]; /* mittlere 16 Bit herausholen, (benutzt CL_CPU_BIG_ENDIAN_P !) */\
169       lo_zuweisung __fi.i[1]; /* untere 32 Bit herausholen (benutzt CL_CPU_BIG_ENDIAN_P !)    */\
170     }
171 #else
172   #define mulu24  mulu32
173 #endif
174
175 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 32-Bit-Zahl:
176 // mulu32_unchecked(arg1,arg2)
177 // > arg1, arg2 : zwei 32-Bit-Zahlen
178 // < ergebnis : eine 32-Bit-Zahl
179 // Es wird vorausgesetzt, daß arg1*arg2 < 2^32.
180 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
181 inline uint32 mulu32_unchecked (uint32 arg1, uint32 arg2)
182 {
183         register uint64 _prod;
184         __asm__("umul %1,%2,%0"
185                 : "=r" (_prod)
186                 : "r" (arg1), "r" (arg2)
187                );
188         return _prod;
189 }
190 #elif defined(__sparc__) && !defined(NO_ASM)
191   extern "C" uint32 mulu32_unchecked (uint32 x, uint32 y); // extern in Assembler
192 #else
193   // Wir können dafür auch die Bibliotheksroutine des C-Compilers nehmen:
194   inline uint32 mulu32_unchecked (uint32 arg1, uint32 arg2)
195   {
196         return arg1 * arg2;
197   }
198 #endif
199
200 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 64-Bit-Zahl:
201 // mulu32(arg1,arg2,hi=,lo=);
202 // > arg1, arg2 : zwei 32-Bit-Zahlen
203 // < 2^32*hi+lo : eine 64-Bit-Zahl
204   extern "C" uint32 mulu32_ (uint32 arg1, uint32 arg2); // -> Low-Teil
205   extern "C" uint32 mulu32_high;                        // -> High-Teil
206 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
207   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
208     ({ var uint32 _x = (x); \
209        var uint32 _y = (y); \
210        var uint32 _hi;      \
211        var uint32 _lo;      \
212        __asm__("mulul %3,%0:%1" : "=d" (_hi), "=d"(_lo) : "1" (_x), "dm" (_y) ); \
213        hi_zuweisung _hi;    \
214        lo_zuweisung _lo;    \
215      })
216 #elif defined(__GNUC__) && defined(__m68k__)
217   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
218     ({ var uint32 _x = (x);                                             \
219        var uint32 _y = (y);                                             \
220        var uint16 _x1 = high16(_x);                                     \
221        var uint16 _x0 = low16(_x);                                      \
222        var uint16 _y1 = high16(_y);                                     \
223        var uint16 _y0 = low16(_y);                                      \
224        var uint32 _hi = mulu16(_x1,_y1); /* obere Portion */            \
225        var uint32 _lo = mulu16(_x0,_y0); /* untere Portion */           \
226        {var uint32 _mid = mulu16(_x0,_y1); /* 1. mittlere Portion */    \
227         _hi += high16(_mid); _mid = highlow32_0(low16(_mid));           \
228         _lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
229        }                                                                \
230        {var uint32 _mid = mulu16(_x1,_y0); /* 2. mittlere Portion */    \
231         _hi += high16(_mid); _mid = highlow32_0(low16(_mid));           \
232         _lo += _mid; if (_lo < _mid) { _hi += 1; } /* 64-Bit-Addition */\
233        }                                                                \
234        hi_zuweisung _hi;                                                \
235        lo_zuweisung _lo;                                                \
236      })
237 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
238   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
239     ({ var register uint64 _hi;                                 \
240        var register uint64 _lo;                                 \
241        __asm__("umul %2,%3,%1\n\trd %y,%0"                      \
242                : "=r" (_hi), "=r" (_lo)                         \
243                : "r" ((uint32)(x)), "r" ((uint32)(y))           \
244               );                                                \
245        hi_zuweisung (uint32)_hi; lo_zuweisung (uint32)_lo;      \
246      })
247 #elif defined(__GNUC__) && defined(__sparc__) && !defined(NO_ASM)
248   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
249     ({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */     \
250       {var register uint32 _hi __asm__("%g1");                  \
251        hi_zuweisung _hi;                                        \
252      }})
253 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
254   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
255     ({ lo_zuweisung mulu32_(x,y); /* extern in Assembler */     \
256       {var register uint32 _hi __asm__("%r1"/*"%a2"*/);         \
257        hi_zuweisung _hi;                                        \
258      }})
259 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
260   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
261     ({ var register uint32 _hi;                                  \
262        var register uint32 _lo;                                  \
263        __asm__("mull %2"                                         \
264                : "=d" /* %edx */ (_hi), "=a" /* %eax */ (_lo)    \
265                : "g" ((uint32)(x)), "1" /* %eax */ ((uint32)(y)) \
266               );                                                 \
267        hi_zuweisung _hi; lo_zuweisung _lo;                       \
268      })
269 #elif defined(__GNUC__) && defined(__mips__) && !defined(NO_ASM)
270   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
271     ({ var register uint32 _hi;                       \
272        var register uint32 _lo;                       \
273        __asm__("multu %3,%2 ; mfhi %0 ; mflo %1"      \
274                : "=r" (_hi), "=r" (_lo)               \
275                : "r" ((uint32)(x)), "r" ((uint32)(y)) \
276               );                                      \
277        hi_zuweisung _hi; lo_zuweisung _lo;            \
278      })
279 #elif defined(__GNUC__) && defined(HAVE_LONGLONG) && !defined(__arm__)
280   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
281     ({ var register uint64 _prod = (uint64)(uint32)(x) * (uint64)(uint32)(y); \
282        hi_zuweisung (uint32)(_prod>>32);                                      \
283        lo_zuweisung (uint32)(_prod);                                          \
284      })
285 #elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
286   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
287     { var register uint32 _hi;                  \
288       var register uint32 _lo;                  \
289       _lo = mulu32_(x,y), _hi = mulu32_high_(); \
290       hi_zuweisung _hi; lo_zuweisung _lo;       \
291     }
292   extern "C" uint32 mulu32_high_ (void);
293   #pragma aux mulu32_ = 0xF7 0xE2 /* mull %edx */ parm [eax] [edx] value [eax] modify [eax edx];
294   #pragma aux mulu32_high_ = /* */ value [edx] modify [];
295 #else
296   #define mulu32(x,y,hi_zuweisung,lo_zuweisung)  \
297     { lo_zuweisung mulu32_(x,y); hi_zuweisung mulu32_high; }
298   #if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__mips__) || defined(__hppa__)) && !defined(NO_ASM)
299     // mulu32_ extern in Assembler
300     #if defined(__sparc__) || defined(__sparc64__)
301       extern "C" uint32 _get_g1 (void);
302       #define mulu32_high  (_get_g1()) // Rückgabe im Register %g1
303     #elif !defined(__hppa__)
304       #define NEED_VAR_mulu32_high
305     #endif
306   #else
307     #define NEED_FUNCTION_mulu32_
308   #endif
309 #endif
310
311 #ifdef HAVE_FAST_LONGLONG
312
313 // Multipliziert zwei 32-Bit-Zahlen miteinander und liefert eine 64-Bit-Zahl:
314 // mulu32_w(arg1,arg2)
315 // > arg1, arg2 : zwei 32-Bit-Zahlen
316 // < result : eine 64-Bit-Zahl
317 #if defined(__GNUC__)
318   #define mulu32_w(x,y)  ((uint64)(uint32)(x) * (uint64)(uint32)(y))
319 #else
320   extern "C" uint64 mulu32_w (uint32 arg1, uint32 arg2);
321   #define NEED_FUNCTION_mulu32_w
322 #endif
323
324 // Multipliziert zwei 64-Bit-Zahlen miteinander und liefert eine 128-Bit-Zahl:
325 // mulu64(arg1,arg2,hi=,lo=);
326 // > arg1, arg2 : zwei 64-Bit-Zahlen
327 // < 2^64*hi+lo : eine 128-Bit-Zahl
328   extern "C" uint64 mulu64_ (uint64 arg1, uint64 arg2); // -> Low-Teil
329   extern "C" uint64 mulu64_high;                        // -> High-Teil
330 #if defined(__GNUC__) && defined(__alpha__) && !defined(NO_ASM)
331   #define mulu64(x,y,hi_zuweisung,lo_zuweisung)  \
332     ({ var register uint64 _x = (x);    \
333        var register uint64 _y = (y);    \
334        var register uint64 _hi;         \
335        var register uint64 _lo;         \
336        __asm__("mulq %1,%2,%0"          \
337                : "=r" (_lo)             \
338                : "r" (_x), "r" (_y)     \
339               );                        \
340        __asm__("umulh %1,%2,%0"         \
341                : "=r" (_hi)             \
342                : "r" (_x), "r" (_y)     \
343               );                        \
344        hi_zuweisung _hi;                \
345        lo_zuweisung _lo;                \
346      })
347 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
348   #define mulu64(x,y,hi_zuweisung,lo_zuweisung)  \
349     ({ lo_zuweisung mulu64_(x,y); /* extern in Assembler */     \
350       {var register uint64 _hi __asm__("%g2");                  \
351        hi_zuweisung _hi;                                        \
352      }})
353 #else
354   #define mulu64(x,y,hi_zuweisung,lo_zuweisung)  \
355     { lo_zuweisung mulu64_(x,y); hi_zuweisung mulu64_high; }
356   #if defined(__sparc64__)
357     // mulu64_ extern in Assembler
358     #if defined(__sparc64__)
359       extern "C" uint64 _get_g2 (void);
360       #define mulu64_high  (_get_g2()) // Rückgabe im Register %g2
361     #else
362       #define NEED_VAR_mulu64_high
363     #endif
364   #else
365     #define NEED_FUNCTION_mulu64_
366   #endif
367 #endif
368
369 #endif /* HAVE_FAST_LONGLONG */
370
371
372 // Dividiert eine 16-Bit-Zahl durch eine 16-Bit-Zahl und
373 // liefert einen 16-Bit-Quotienten und einen 16-Bit-Rest.
374 // divu_1616_1616(x,y,q=,r=);
375 // > uint16 x: Zähler
376 // > uint16 y: Nenner
377 // < uint16 q: floor(x/y)
378 // < uint16 r: x mod y
379 // < x = q*y+r
380   #define divu_1616_1616(x,y,q_zuweisung,r_zuweisung)  \
381     { var uint16 __x = (x);                                     \
382       var uint16 __y = (y);                                     \
383       q_zuweisung floor(__x,__y);                               \
384       r_zuweisung (__x % __y);                                  \
385     }
386
387 // Dividiert eine 32-Bit-Zahl durch eine 16-Bit-Zahl und
388 // liefert einen 16-Bit-Quotienten und einen 16-Bit-Rest.
389 // divu_3216_1616(x,y,q=,r=);
390 // > uint32 x: Zähler
391 // > uint16 y: Nenner
392 // > Es sei bekannt, daß 0 <= x < 2^16*y .
393 // < uint16 q: floor(x/y)
394 // < uint16 r: x mod y
395 // < x = q*y+r
396 #if defined(__sparc__)
397   extern "C" uint32 divu_3216_1616_ (uint32 x, uint16 y); // -> Quotient q, Rest r
398 #else
399   extern "C" uint16 divu_3216_1616_ (uint32 x, uint16 y); // -> Quotient q
400   extern "C" uint16 divu_16_rest;                         // -> Rest r
401 #endif
402 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
403   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
404     ({var uint32 __x = (x);        \
405       var uint16 __y = (y);        \
406       var uint64 __q;              \
407       var uint64 __r;              \
408       __asm__ __volatile__ (       \
409         "wr %%g0,%%g0,%%y\n\t"     \
410         "udiv %2,%3,%0\n\t"        \
411         "umul %0,%3,%1"            \
412         "sub %2,%1,%1"             \
413         : "=&r" (__q), "=&r" (__r) \
414         : "r" (__x), "r" (__y));   \
415       q_zuweisung (uint16)__q;     \
416       r_zuweisung (uint16)__r;     \
417      })
418 #elif defined(__GNUC__) && (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
419   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
420     ({ var uint32 __qr = divu_3216_1616_(x,y); /* extern in Assembler */\
421        q_zuweisung low16(__qr);                                         \
422        r_zuweisung high16(__qr);                                        \
423      })
424 #elif defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
425   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
426     ({var uint32 __x = (x);                                             \
427       var uint16 __y = (y);                                             \
428       var uint32 __qr;                                                  \
429       __asm__ __volatile__ ("                                           \
430         divu %2,%0                                                      \
431         " : "=d" (__qr) : "0" (__x), "dm" (__y));                       \
432       q_zuweisung low16(__qr);                                          \
433       r_zuweisung high16(__qr);                                         \
434      })
435 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
436   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
437     ({var uint32 __x = (x);                                             \
438       var uint16 __y = (y);                                             \
439       var uint16 __q;                                                   \
440       var uint16 __r;                                                   \
441       __asm__("divw %4"                                                 \
442               : "=a" /* %ax */ (__q), "=d" /* %dx */ (__r)              \
443               : "1" /* %dx */ ((uint16)(high16(__x))), "0" /* %ax */ ((uint16)(low16(__x))), "rm" (__y) \
444              );                                                         \
445       q_zuweisung __q;                                                  \
446       r_zuweisung __r;                                                  \
447      })
448 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
449   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
450     { var uint32 _q = divu_3216_1616_(x,y); /* extern in Assembler */   \
451       var register uint32 _r __asm__("%r1"/*"%a2"*/);                   \
452       q_zuweisung _q; r_zuweisung _r;                                   \
453     }
454 #elif defined(__GNUC__) && !defined(__arm__)
455   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
456     ({var uint32 __x = (x);                                             \
457       var uint16 __y = (y);                                             \
458       var uint16 __q = floor(__x,__y);                                  \
459       q_zuweisung __q;                                                  \
460       r_zuweisung (__x - __q * __y);                                    \
461      })
462 #elif (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       q_zuweisung low16(__qr);                                          \
466       r_zuweisung high16(__qr);                                         \
467     }
468 #elif defined(__arm__) && !defined(NO_ASM)
469   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
470     { q_zuweisung divu_3216_1616_(x,y); /* extern in Assembler */       \
471       r_zuweisung divu_16_rest;                                         \
472     }
473   #define NEED_VAR_divu_16_rest
474 #else
475   #define divu_3216_1616(x,y,q_zuweisung,r_zuweisung)  \
476     { q_zuweisung divu_3216_1616_(x,y); r_zuweisung divu_16_rest; }
477   #define NEED_FUNCTION_divu_3216_1616_
478 #endif
479
480 // Dividiert eine 32-Bit-Zahl durch eine 16-Bit-Zahl und
481 // liefert einen 32-Bit-Quotienten und einen 16-Bit-Rest.
482 // divu_3216_3216(x,y,q=,r=);
483 // > uint32 x: Zähler
484 // > uint16 y: Nenner
485 // Es sei bekannt, daß y>0.
486 // < uint32 q: floor(x/y)
487 // < uint16 r: x mod y
488 // < x = q*y+r
489   extern "C" uint32 divu_3216_3216_ (uint32 x, uint16 y); // -> Quotient q
490   extern "C" uint16 divu_16_rest;                         // -> Rest r
491 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
492   #define divu_3216_3216(x,y,q_zuweisung,r_zuweisung)  \
493     ({var uint32 __x = (x);        \
494       var uint16 __y = (y);        \
495       var uint64 __q;              \
496       var uint64 __r;              \
497       __asm__ __volatile__ (       \
498         "wr %%g0,%%g0,%%y\n\t"     \
499         "udiv %2,%3,%0\n\t"        \
500         "umul %0,%3,%1"            \
501         "sub %2,%1,%1"             \
502         : "=&r" (__q), "=&r" (__r) \
503         : "r" (__x), "r" (__y));   \
504       q_zuweisung (uint32)__q;     \
505       r_zuweisung (uint16)__r;     \
506      })
507 #elif defined(__sparc__) || defined(__sparc64__) || defined(__i386__)
508   #define divu_3216_3216  divu_3232_3232
509 #else
510   // Methode: (beta = 2^16)
511   // x = x1*beta+x0 schreiben.
512   // Division mit Rest: x1 = q1*y + r1, wobei 0 <= x1 < beta <= beta*y.
513   // Also 0 <= q1 < beta, 0 <= r1 < y.
514   // Division mit Rest: (r1*beta+x0) = q0*y + r0, wobei 0 <= r1*beta+x0 < beta*y.
515   // Also 0 <= q0 < beta, 0 <= r0 < y
516   // und x = x1*beta+x0 = (q1*beta+q0)*y + r0.
517   // Setze q := q1*beta+q0 und r := r0.
518   #define divu_3216_3216(x,y,q_zuweisung,r_zuweisung)  \
519     { var uint32 _x = (x);                                              \
520       var uint16 _y = (y);                                              \
521       var uint16 _q1;                                                   \
522       var uint16 _q0;                                                   \
523       var uint16 _r1;                                                   \
524       divu_3216_1616(high16(_x),_y, _q1 = , _r1 = );                    \
525       divu_3216_1616(highlow32(_r1,low16(_x)),_y, _q0 = , r_zuweisung); \
526       q_zuweisung highlow32(_q1,_q0);                                   \
527     }
528 #endif
529
530 // Dividiert eine 32-Bit-Zahl durch eine 32-Bit-Zahl und
531 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
532 // divu_3232_3232(x,y,q=,r=);
533 // > uint32 x: Zähler
534 // > uint32 y: Nenner
535 // Es sei bekannt, daß y>0.
536 // < uint32 q: floor(x/y)
537 // < uint32 r: x mod y
538 // < x = q*y+r
539   extern "C" uint32 divu_3232_3232_ (uint32 x, uint32 y); // -> Quotient q
540   extern "C" uint32 divu_32_rest;                         // -> Rest r
541 #if defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
542   #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung)  \
543     ({var uint32 __x = (x);        \
544       var uint32 __y = (y);        \
545       var uint64 __q;              \
546       var uint64 __r;              \
547       __asm__ __volatile__ (       \
548         "wr %%g0,%%g0,%%y\n\t"     \
549         "udiv %2,%3,%0\n\t"        \
550         "umul %0,%3,%1"            \
551         "sub %2,%1,%1"             \
552         : "=&r" (__q), "=&r" (__r) \
553         : "r" (__x), "r" (__y));   \
554       q_zuweisung (uint32)__q;     \
555       r_zuweisung (uint32)__r;     \
556      })
557 #elif defined(__sparc__) || defined(__sparc64__) || defined(__i386__)
558   #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung)  \
559     divu_6432_3232(0,x,y,q_zuweisung,r_zuweisung)
560   #define divu_3232_3232_(x,y) divu_6432_3232_(0,x,y)
561 #else
562   // Methode: (beta = 2^n = 2^16, n = 16)
563   // Falls y < beta, handelt es sich um eine 32-durch-16-Bit-Division.
564   // Falls y >= beta:
565   // Quotient  q = floor(x/y) < beta  (da 0 <= x < beta^2, y >= beta).
566   // y habe genau n+k Bits (1 <= k <= n), d.h. 2^(n+k-1) <= y < 2^(n+k).
567   // Schreibe  x = 2^k*x1 + x0  mit  x1 := floor(x/2^k)
568   // und       y = 2^k*y1 + y0  mit  y1 := floor(y/2^k)
569   // und bilde den Näherungs-Quotienten floor(x1/y1)
570   // oder (noch besser) floor(x1/(y1+1)).
571   // Wegen 0 <= x1 < 2^(2n) und 0 < 2^(n-1) <= y1 < 2^n
572   // und  x1/(y1+1) <= x/y < x1/(y1+1) + 2
573   // (denn x1/(y1+1) = (x1*2^k)/((y1+1)*2^k) <= (x1*2^k)/y <= x/y
574   // und x/y - x1/(y1+1) = (x+x*y1-x1*y)/(y*(y1+1))
575   // = (x+x0*y1-x1*y0)/(y*(y1+1)) <= (x+x0*y1)/(y*(y1+1))
576   // <= x/(y*(y1+1)) + x0/y
577   // <= 2^(2n)/(2^(n+k-1)*(2^(n-1)+1)) + 2^k/2^(n+k-1)
578   // = 2^(n-k+1)/(2^(n-1)+1) + 2^(1-n) <= 2^n/(2^(n-1)+1) + 2^(1-n) < 2 )
579   // gilt  floor(x1/(y1+1)) <= floor(x/y) <= floor(x1/(y1+1)) + 2  .
580   // Man bildet also  q:=floor(x1/(y1+1))  (ein Shift um n Bit oder
581   // eine (2n)-durch-n-Bit-Division, mit Ergebnis q <= floor(x/y) < beta)
582   // und x-q*y und muß hiervon noch höchstens 2 mal y abziehen und q
583   // incrementieren, um den Quotienten  q = floor(x/y)  und den Rest
584   // x-floor(x/y)*y  der Division zu bekommen.
585   #define divu_3232_3232(x,y,q_zuweisung,r_zuweisung)  \
586     { var uint32 _x = (x);                                              \
587       var uint32 _y = (y);                                              \
588       if (_y <= (uint32)(bit(16)-1))                                    \
589         { var uint16 _q1;                                               \
590           var uint16 _q0;                                               \
591           var uint16 _r1;                                               \
592           divu_3216_1616(high16(_x),_y, _q1 = , _r1 = );                \
593           divu_3216_1616(highlow32(_r1,low16(_x)),_y, _q0 = , r_zuweisung); \
594           q_zuweisung highlow32(_q1,_q0);                               \
595         }                                                               \
596         else                                                            \
597         { var uint32 _x1 = _x; /* x1 := x */                            \
598           var uint32 _y1 = _y; /* y1 := y */                            \
599           var uint16 _q;                                                \
600           do { _x1 = floor(_x1,2); _y1 = floor(_y1,2); } /* k erhöhen */\
601              until (_y1 <= (uint32)(bit(16)-1)); /* bis y1 < beta */    \
602           { var uint16 _y2 = low16(_y1)+1; /* y1+1 bilden */            \
603             if (_y2==0)                                                 \
604               { _q = high16(_x1); } /* y1+1=beta -> ein Shift */        \
605               else                                                      \
606               { divu_3216_1616(_x1,_y2,_q=,); } /* Division von x1 durch y1+1 */\
607           }                                                             \
608           /* _q = q = floor(x1/(y1+1)) */                               \
609           /* x-q*y bilden (eine 16-mal-32-Bit-Multiplikation ohne Überlauf): */\
610           _x -= highlow32_0(mulu16(_q,high16(_y))); /* q * high16(y) * beta */\
611           /* gefahrlos, da q*high16(y) <= q*y/beta <= x/beta < beta */  \
612           _x -= mulu16(_q,low16(_y)); /* q * low16(y) */                \
613           /* gefahrlos, da q*high16(y)*beta + q*low16(y) = q*y <= x */  \
614           /* Noch höchstens 2 mal y abziehen: */                        \
615           if (_x >= _y)                                                 \
616             { _q += 1; _x -= _y;                                        \
617               if (_x >= _y)                                             \
618                 { _q += 1; _x -= _y; }                                  \
619             }                                                           \
620           r_zuweisung _x;                                               \
621           q_zuweisung (uint32)(_q);                                     \
622     }   }
623   #define NEED_FUNCTION_divu_3232_3232_
624 #endif
625
626 // Dividiert eine 64-Bit-Zahl durch eine 32-Bit-Zahl und
627 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
628 // divu_6432_3232(xhi,xlo,y,q=,r=);
629 // > uint32 xhi,xlo: x = 2^32*xhi+xlo = Zähler
630 // > uint32 y: Nenner
631 // > Es sei bekannt, daß 0 <= x < 2^32*y .
632 // < uint32 q: floor(x/y)
633 // < uint32 r: x mod y
634 // < x = q*y+r
635   extern "C" uint32 divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y); // -> Quotient q
636   extern "C" uint32 divu_32_rest;                                       // -> Rest r
637 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
638   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
639     ({var uint32 __xhi = (xhi);                                         \
640       var uint32 __xlo = (xlo);                                         \
641       var uint32 __y = (y);                                             \
642       var uint32 __q;                                                   \
643       var uint32 __r;                                                   \
644       __asm__ __volatile__ ("                                           \
645         divul %4,%1:%0                                                  \
646         " : "=d" (__q), "=d" (__r) : "1" (__xhi), "0" (__xlo), "dm" (__y)); \
647       q_zuweisung __q;                                                  \
648       r_zuweisung __r;                                                  \
649      })
650   #define divu_6432_3232_(xhi,xlo,y) \
651     ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
652 #elif defined(__GNUC__) && defined(__sparc64__) && !defined(NO_ASM)
653   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
654     ({var uint32 __xhi = (xhi);    \
655       var uint32 __xlo = (xlo);    \
656       var uint32 __y = (y);        \
657       var uint64 __q;              \
658       var uint64 __r;              \
659       __asm__ __volatile__ (       \
660         "wr %2,%%g0,%%y\n\t"       \
661         "udiv %3,%4,%0\n\t"        \
662         "umul %0,%4,%1"            \
663         "sub %3,%1,%1"             \
664         : "=&r" (__q), "=&r" (__r) \
665         : "r" (__xhi), "r" (__xlo), "r" (__y)); \
666       q_zuweisung (uint32)__q;     \
667       r_zuweisung (uint32)__r;     \
668      })
669 #elif defined(__GNUC__) && (defined(__sparc__) || defined(__sparc64__)) && !defined(NO_ASM)
670   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
671     ({ var uint32 _q = divu_6432_3232_(xhi,xlo,y); /* extern in Assembler */\
672        var register uint32 _r __asm__("%g1");                               \
673        q_zuweisung _q; r_zuweisung _r;                                      \
674      })
675 #elif defined(__GNUC__) && defined(__arm__) && 0 // see comment cl_asm_arm.cc
676   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
677     ({ var uint32 _q = divu_6432_3232_(xhi,xlo,y); /* extern in Assembler */\
678        var register uint32 _r __asm__("%r1"/*"%a2"*/);                      \
679        q_zuweisung _q; r_zuweisung _r;                                      \
680      })
681 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
682   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
683     ({var uint32 __xhi = (xhi);                                         \
684       var uint32 __xlo = (xlo);                                         \
685       var uint32 __y = (y);                                             \
686       var uint32 __q;                                                   \
687       var uint32 __r;                                                   \
688       __asm__ __volatile__ (                                            \
689          "divl %4"                                                      \
690          : "=a" /* %eax */ (__q), "=d" /* %edx */ (__r)                 \
691          : "1" /* %edx */ (__xhi), "0" /* %eax */ (__xlo), "rm" (__y)   \
692          );                                                             \
693       q_zuweisung __q;                                                  \
694       r_zuweisung __r;                                                  \
695      })
696   #define divu_6432_3232_(xhi,xlo,y) \
697     ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
698 #elif defined(__GNUC__) && defined(HAVE_LONGLONG) && !defined(__arm__)
699   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung) \
700     ({var uint32 __xhi = (xhi);                                         \
701       var uint32 __xlo = (xlo);                                         \
702       var uint64 __x = ((uint64)__xhi << 32) | (uint64)__xlo;           \
703       var uint32 __y = (y);                                             \
704       var uint32 __q = floor(__x,(uint64)__y);                          \
705       q_zuweisung __q; r_zuweisung __xlo - __q * __y;                   \
706      })
707   #define divu_6432_3232_(xhi,xlo,y) \
708     ({var uint32 ___q; divu_6432_3232(xhi,xlo,y,___q=,); ___q; })
709 #elif defined(WATCOM) && defined(__i386__) && !defined(NO_ASM)
710   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
711     { var uint32 __xhi = (xhi);                                         \
712       var uint32 __xlo = (xlo);                                         \
713       var uint32 __y = (y);                                             \
714       var uint32 __q;                                                   \
715       var uint32 __r;                                                   \
716       __q = divu_6432_3232_(__xhi,__xlo,__y); __r = divu_6432_3232_rest(); \
717       q_zuweisung __q;                                                  \
718       r_zuweisung __r;                                                  \
719     }
720   extern "C" uint32 divu_6432_3232_rest (void);
721   #pragma aux divu_6432_3232_ = 0xF7 0xF1 /* divl %ecx */ parm [edx] [eax] [ecx] value [eax] modify [eax edx];
722   #pragma aux divu_6432_3232_rest = /* */ value [edx] modify [];
723 #else
724   #define divu_6432_3232(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
725     { q_zuweisung divu_6432_3232_(xhi,xlo,y); r_zuweisung divu_32_rest; }
726   #if (defined(__m68k__) || defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || (defined(__i386__) && !defined(WATCOM) && !defined(MICROSOFT)) || defined(__hppa__)) && !defined(NO_ASM)
727     // divu_6432_3232_ extern in Assembler
728     #if defined(__sparc__) || defined(__sparc64__)
729       extern "C" uint32 _get_g1 (void);
730       #define divu_32_rest  (_get_g1()) // Rückgabe im Register %g1
731     #else
732       #define NEED_VAR_divu_32_rest
733     #endif
734   #else
735     #define NEED_FUNCTION_divu_6432_3232_
736   #endif
737 #endif
738
739 #ifdef HAVE_FAST_LONGLONG
740
741 // Dividiert eine 64-Bit-Zahl durch eine 32-Bit-Zahl und
742 // liefert einen 32-Bit-Quotienten und einen 32-Bit-Rest.
743 // divu_6432_3232_w(x,y,q=,r=);
744 // > uint64 x: Zähler
745 // > uint32 y: Nenner
746 // > Es sei bekannt, daß 0 <= x < 2^32*y .
747 // < uint32 q: floor(x/y)
748 // < uint32 r: x mod y
749 // < x = q*y+r
750 #if defined(__GNUC__)
751   #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung)  \
752     ({var uint64 __x = (x);                                             \
753       var uint32 __y = (y);                                             \
754       var uint32 __q = floor(__x,(uint64)__y);                          \
755       q_zuweisung __q; r_zuweisung (uint32)__x - __q * __y;             \
756      })
757 #else
758   #define divu_6432_3232_w(x,y,q_zuweisung,r_zuweisung)  \
759     { var uint64 __x = (x);                                               \
760       divu_6432_3232(high32(__x),low32(__x),(y),q_zuweisung,r_zuweisung); \
761     }
762 #endif
763
764 // Dividiert eine 64-Bit-Zahl durch eine 64-Bit-Zahl und
765 // liefert einen 64-Bit-Quotienten und einen 64-Bit-Rest.
766 // divu_6464_6464(x,y,q=,r=);
767 // > uint64 x: Zähler
768 // > uint64 y: Nenner
769 // Es sei bekannt, daß y>0.
770 // < uint64 q: floor(x/y)
771 // < uint64 r: x mod y
772 // < x = q*y+r
773 #if defined(__alpha__) || 1
774   #define divu_6464_6464(x,y,q_zuweisung,r_zuweisung)  \
775     { var uint64 __x = (x);     \
776       var uint64 __y = (y);     \
777       q_zuweisung (__x / __y);  \
778       r_zuweisung (__x % __y);  \
779     }
780 #endif
781
782 // Dividiert eine 128-Bit-Zahl durch eine 64-Bit-Zahl und
783 // liefert einen 64-Bit-Quotienten und einen 64-Bit-Rest.
784 // divu_12864_6464(xhi,xlo,y,q=,r=);
785 // > uint64 xhi,xlo: x = 2^64*xhi+xlo = Zähler
786 // > uint64 y: Nenner
787 // > Es sei bekannt, daß 0 <= x < 2^64*y .
788 // < uint64 q: floor(x/y)
789 // < uint64 r: x mod y
790 // < x = q*y+r
791   extern "C" uint64 divu_12864_6464_ (uint64 xhi, uint64 xlo, uint64 y); // -> Quotient q
792   extern "C" uint64 divu_64_rest;                                        // -> Rest r
793   #define divu_12864_6464(xhi,xlo,y,q_zuweisung,r_zuweisung)  \
794     { q_zuweisung divu_12864_6464_(xhi,xlo,y); r_zuweisung divu_64_rest; }
795   #define NEED_FUNCTION_divu_12864_6464_
796
797 #endif /* HAVE_FAST_LONGLONG */
798
799
800 // Zieht die Ganzzahl-Wurzel aus einer 32-Bit-Zahl und
801 // liefert eine 16-Bit-Wurzel und einen Rest.
802 // isqrt_32_16(x,y=,sqrtp=);
803 // > uint32 x: Radikand, >= 2^30, < 2^32
804 // < uint16 y: floor(sqrt(x)), >= 2^15, < 2^16
805 // < boolean sqrtp: /=0, falls x=y^2
806   // Methode:
807   // y := 2^16 als Anfangswert,
808   // y := floor((y + floor(x/y))/2) als nächster Wert,
809   // solange z := floor(x/y) < y, setze y := floor((y+z)/2).
810   // y ist fertig; x=y^2 genau dann, wenn z=y und die letzte Division aufging.
811   // (Beweis:
812   //  1. Die Folge der y ist streng monoton fallend.
813   //  2. Stets gilt y >= floor(sqrt(x)) (denn für alle y>0 ist
814   //     y + x/y >= 2*sqrt(x) und daher  floor((y + floor(x/y))/2) =
815   //     floor(y/2 + x/(2*y)) >= floor(sqrt(x)) ).
816   //  3. Am Schluß gilt x >= y^2.
817   // )
818   #define isqrt_32_16(x,y_zuweisung,sqrtp_zuweisung)  \
819     { var uint32 _x = (x);                                              \
820       var uint16 _x1 = high16(_x);                                      \
821       var uint16 _y = floor(_x1,2) | bit(16-1);                         \
822       loop                                                              \
823         { var uint16 _z;                                                \
824           var uint16 _r;                                                \
825           if (_x1 >= _y) /* Division _x/_y ergäbe Überlauf -> _z > _y */\
826             { unused (sqrtp_zuweisung FALSE); break; }                  \
827           divu_3216_1616(_x,_y, _z=,_r=); /* Dividiere _x/_y */         \
828           if (_z >= _y)                                                 \
829             { unused (sqrtp_zuweisung (_z == _y) && (_r == 0)); break; } \
830           _y = floor((uint16)(_z+_y),2) | bit(16-1); /* _y muß >= 2^15 bleiben */\
831         }                                                               \
832       y_zuweisung _y;                                                   \
833     }
834
835 // Zieht die Ganzzahl-Wurzel aus einer 64-Bit-Zahl und
836 // liefert eine 32-Bit-Wurzel und einen Rest.
837 // isqrt_64_32(xhi,xlo,y=,sqrtp=);
838 // > uint32 xhi,xlo: Radikand x = 2^32*xhi+xlo, >= 2^62, < 2^64
839 // < uint32 y: floor(sqrt(x)), >= 2^31, < 2^32
840 // < boolean sqrtp: /=0, falls x=y^2
841 #if defined(__sparc__) || defined(__sparc64__) || defined(__m68k__) || defined(__hppa__)
842   // Methode:
843   // y := 2^32 als Anfangswert,
844   // y := floor((y + floor(x/y))/2) als nächster Wert,
845   // solange z := floor(x/y) < y, setze y := floor((y+z)/2).
846   // y ist fertig; x=y^2 genau dann, wenn z=y und die letzte Division aufging.
847   // (Beweis:
848   //  1. Die Folge der y ist streng monoton fallend.
849   //  2. Stets gilt y >= floor(sqrt(x)) (denn für alle y>0 ist
850   //     y + x/y >= 2*sqrt(x) und daher  floor((y + floor(x/y))/2) =
851   //     floor(y/2 + x/(2*y)) >= floor(sqrt(x)) ).
852   //  3. Am Schluß gilt x >= y^2.
853   // )
854   #define isqrt_64_32(xhi,xlo,y_zuweisung,sqrtp_zuweisung)  \
855     { var uint32 _xhi = (xhi);                                          \
856       var uint32 _xlo = (xlo);                                          \
857       var uint32 _y = floor(_xhi,2) | bit(32-1);                        \
858       loop                                                              \
859         { var uint32 _z;                                                \
860           var uint32 _rest;                                             \
861           if (_xhi >= _y) /* Division _x/_y ergäbe Überlauf -> _z > _y */\
862             { sqrtp_zuweisung FALSE; break; }                           \
863           divu_6432_3232(_xhi,_xlo,_y, _z=,_rest=); /* Dividiere _x/_y */\
864           if (_z >= _y)                                                 \
865             { sqrtp_zuweisung (_z == _y) && (_rest == 0); break; }      \
866           _y = floor(_z+_y,2) | bit(32-1); /* _y muß >= 2^31 bleiben */ \
867         }                                                               \
868       y_zuweisung _y;                                                   \
869     }
870 #else
871   // Methode:
872   // Wie bei UDS_sqrt mit n=2.
873   // y = 2^16*yhi + ylo ansetzen.
874   // Dann muß
875   //   yhi = floor(y/2^16) = floor(floor(sqrt(x))/2^16)
876   //       = floor(sqrt(x)/2^16) = floor(sqrt(x/2^32)) = isqrt(xhi)
877   // sein. Es folgt yhi >= 2^15.
878   // Danach sucht man das größte ylo >=0 mit
879   // x - 2^32*yhi^2 >= 2*2^16*yhi*ylo + ylo^2.
880   // Dazu setzen wir  xhi*2^32+xlo := x - 2^32*yhi^2
881   // (also xhi := xhi - yhi^2, das ist >=0, <=2*yhi).
882   // Die Schätzung für die zweite Ziffer
883   //     ylo' := min(2^16-1,floor((xhi*2^32+xlo)/(2*2^16*yhi)))
884   // erfüllt ylo'-1 <= ylo <= ylo', ist also um höchstens 1 zu groß.
885   // (Beweis: Rechte Ungleichung klar, da  ylo < 2^16  und
886   //   xhi*2^32+xlo >= 2*2^16*yhi*ylo + ylo^2 >= 2*2^16*yhi*ylo
887   //   ==> (xhi*2^32+xlo)/(2*2^16*yhi) >= ylo  gelten muß.
888   //   Linke Ungleichung: Falls floor(...)>=2^16, ist
889   //   xhi*2^32+xlo >= 2*2^16*2^16*yhi >= 2*2^16*yhi*(2^16-1) + 2^32
890   //                >= 2*2^16*yhi*(2^16-1) + (2^16-1)^2
891   //   und xhi*2^32+xlo < 2*2^16*2^16*yhi + (2^16)^2, also
892   //   ylo = 2^16-1 = ylo'.
893   //   Sonst ist ylo' = floor((xhi*2^32+xlo)/(2*2^16*yhi)), also
894   //   xhi*2^32+xlo >= 2*2^16*yhi*ylo' >= 2*2^16*yhi*(ylo'-1) + 2^32
895   //                >= 2*2^16*yhi*(ylo'-1) + (ylo'-1)^2,
896   //   also ylo >= ylo'-1 nach Definition von ylo.)
897   #define isqrt_64_32(xhi,xlo,y_zuweisung,sqrtp_zuweisung)  \
898     { var uint32 _xhi = (xhi);                                          \
899       var uint32 _xlo = (xlo);                                          \
900       var uint16 _yhi;                                                  \
901       var uint16 _ylo;                                                  \
902       /* erste Ziffer berechnen: */                                     \
903       isqrt_32_16(_xhi,_yhi=,); /* yhi := isqrt(xhi) */                 \
904       _xhi -= mulu16(_yhi,_yhi); /* jetzt 0 <= xhi <= 2*yhi */          \
905       /* x = 2^32*yhi^2 + 2^32*xhi + xlo */                             \
906       /* Schätzung für die zweite Ziffer berechnen: */                  \
907       /* ylo := min(2^16-1,floor((xhi*2^32+xlo)/(2*2^16*yhi))) bilden: */\
908      {var uint32 _z = (_xhi << 15) | (_xlo >> 17); /* < 2^15*(2*yhi+1) */\
909       var uint32 _r = highlow32_0(_yhi);                                \
910       if (_z >= _r)                                                     \
911         { _ylo = bit(16)-1; _r = _z - _r + (uint32)_yhi; }              \
912         else                                                            \
913         { divu_3216_1616(_z,_yhi, _ylo=,_r=); }                         \
914       /* x = 2^32*yhi^2 + 2*2^16*yhi*ylo + 2^17*r + (xlo mod 2^17), */  \
915       /* 0 <= r < yhi + 2^15 */                                         \
916       _xlo = (_r << 17) | (_xlo & (bit(17)-1));                         \
917       /* x = 2^32*yhi^2 + 2*2^16*yhi*ylo + 2^32*floor(r/2^15) + xlo */  \
918       _z = mulu16(_ylo,_ylo); /* z = ylo^2 */                           \
919       /* Versuche vom Rest 2^32*floor(r/2^15) + xlo  z zu subtrahieren. */\
920       /* Falls Rest >= z (d.h. r>=2^15 oder xlo>=z), ist ylo fertig, */ \
921       /* und es gilt x=y^2 genau dann, wenn r<2^15 und xlo=z. */        \
922       /* Sonst (d.h. r<2^15 und xlo<z), muß man ylo erniedrigen. Dazu */\
923       /* setzt man  ylo := ylo-1, z := z-(2*ylo+1), */                  \
924       /* Rest := Rest + 2^17*yhi = xlo + 2^17*yhi >= 2^32 > z, also x>y^2. */\
925       if (_r < bit(15))                                                 \
926         { if (_xlo < _z)                                                \
927             { _ylo -= 1; sqrtp_zuweisung FALSE; }                       \
928             else                                                        \
929             { sqrtp_zuweisung (_xlo == _z); }                           \
930         }                                                               \
931         else                                                            \
932         { sqrtp_zuweisung FALSE; }                                      \
933       y_zuweisung highlow32(_yhi,_ylo);                                 \
934     }}
935 #endif
936
937 #ifdef HAVE_FAST_LONGLONG
938
939 // Zieht die Ganzzahl-Wurzel aus einer 128-Bit-Zahl und
940 // liefert eine 64-Bit-Wurzel und einen Rest.
941 // isqrt_128_64(xhi,xlo,y=,sqrtp=);
942 // > uint64 xhi,xlo: Radikand x = 2^64*xhi+xlo, >= 2^126, < 2^128
943 // < uint64 y: floor(sqrt(x)), >= 2^63, < 2^64
944 // < boolean sqrtp: /=0, falls x=y^2
945   // Methode:
946   // Wie bei UDS_sqrt mit n=2.
947   // y = 2^32*yhi + ylo ansetzen.
948   // Dann muß
949   //   yhi = floor(y/2^32) = floor(floor(sqrt(x))/2^32)
950   //       = floor(sqrt(x)/2^32) = floor(sqrt(x/2^64)) = isqrt(xhi)
951   // sein. Es folgt yhi >= 2^31.
952   // Danach sucht man das größte ylo >=0 mit
953   // x - 2^64*yhi^2 >= 2*2^32*yhi*ylo + ylo^2.
954   // Dazu setzen wir  xhi*2^64+xlo := x - 2^64*yhi^2
955   // (also xhi := xhi - yhi^2, das ist >=0, <=2*yhi).
956   // Die Schätzung für die zweite Ziffer
957   //     ylo' := min(2^32-1,floor((xhi*2^64+xlo)/(2*2^32*yhi)))
958   // erfüllt ylo'-1 <= ylo <= ylo', ist also um höchstens 1 zu groß.
959   // (Beweis: Rechte Ungleichung klar, da  ylo < 2^32  und
960   //   xhi*2^64+xlo >= 2*2^32*yhi*ylo + ylo^2 >= 2*2^32*yhi*ylo
961   //   ==> (xhi*2^64+xlo)/(2*2^32*yhi) >= ylo  gelten muß.
962   //   Linke Ungleichung: Falls floor(...)>=2^32, ist
963   //   xhi*2^64+xlo >= 2*2^32*2^32*yhi >= 2*2^32*yhi*(2^32-1) + 2^64
964   //                >= 2*2^32*yhi*(2^32-1) + (2^32-1)^2
965   //   und xhi*2^64+xlo < 2*2^32*2^32*yhi + (2^32)^2, also
966   //   ylo = 2^32-1 = ylo'.
967   //   Sonst ist ylo' = floor((xhi*2^64+xlo)/(2*2^32*yhi)), also
968   //   xhi*2^64+xlo >= 2*2^32*yhi*ylo' >= 2*2^32*yhi*(ylo'-1) + 2^64
969   //                >= 2*2^32*yhi*(ylo'-1) + (ylo'-1)^2,
970   //   also ylo >= ylo'-1 nach Definition von ylo.)
971   #define isqrt_128_64(x_hi,x_lo,y_zuweisung,sqrtp_zuweisung)  \
972     { var uint64 xhi = (x_hi);                                          \
973       var uint64 xlo = (x_lo);                                          \
974       var uint32 yhi;                                                   \
975       var uint32 ylo;                                                   \
976       /* erste Ziffer berechnen: */                                     \
977       isqrt_64_32(high32(xhi),low32(xhi),yhi=,); /* yhi := isqrt(xhi) */\
978       xhi -= mulu32_w(yhi,yhi); /* jetzt 0 <= xhi <= 2*yhi */           \
979       /* x = 2^64*yhi^2 + 2^64*xhi + xlo */                             \
980       /* Schätzung für die zweite Ziffer berechnen: */                  \
981       /* ylo := min(2^32-1,floor((xhi*2^64+xlo)/(2*2^32*yhi))) bilden: */\
982      {var uint64 z = (xhi << 31) | (xlo >> 33); /* < 2^31*(2*yhi+1) */  \
983       var uint64 r = highlow64_0(yhi);                                  \
984       if (z >= r)                                                       \
985         { ylo = bit(32)-1; r = z - r + (uint64)yhi; }                   \
986         else                                                            \
987         { divu_6432_3232_w(z,yhi, ylo=,r=); }                           \
988       /* x = 2^64*yhi^2 + 2*2^32*yhi*ylo + 2^33*r + (xlo mod 2^33), */  \
989       /* 0 <= r < yhi + 2^31 */                                         \
990       xlo = (r << 33) | (xlo & (bit(33)-1));                            \
991       /* x = 2^64*yhi^2 + 2*2^32*yhi*ylo + 2^64*floor(r/2^31) + xlo */  \
992       z = mulu32_w(ylo,ylo); /* z = ylo^2 */                            \
993       /* Versuche vom Rest 2^64*floor(r/2^31) + xlo  z zu subtrahieren. */\
994       /* Falls Rest >= z (d.h. r>=2^31 oder xlo>=z), ist ylo fertig, */ \
995       /* und es gilt x=y^2 genau dann, wenn r<2^31 und xlo=z. */        \
996       /* Sonst (d.h. r<2^31 und xlo<z), muß man ylo erniedrigen. Dazu */\
997       /* setzt man  ylo := ylo-1, z := z-(2*ylo+1), */                  \
998       /* Rest := Rest + 2^33*yhi = xlo + 2^33*yhi >= 2^64 > z, also x>y^2. */\
999       if (r < bit(31))                                                  \
1000         { if (xlo < z)                                                  \
1001             { ylo -= 1; sqrtp_zuweisung FALSE; }                        \
1002             else                                                        \
1003             { sqrtp_zuweisung (xlo == z); }                             \
1004         }                                                               \
1005         else                                                            \
1006         { sqrtp_zuweisung FALSE; }                                      \
1007       y_zuweisung highlow64(yhi,ylo);                                   \
1008     }}
1009
1010 #endif /* HAVE_FAST_LONGLONG */
1011
1012 // Zieht die Ganzzahl-Wurzel aus einer 32-Bit-Zahl und
1013 // liefert eine 16-Bit-Wurzel.
1014 // isqrt(x)
1015 // > uintL x : Radikand, >=0, <2^32
1016 // < uintL ergebnis : Wurzel, >=0, <2^16
1017   extern uintL isqrt (uintL x);
1018
1019 // Zieht die Ganzzahl-Wurzel aus einer 64-Bit-Zahl und
1020 // liefert eine 32-Bit-Wurzel.
1021 // isqrt(x1,x0)
1022 // > uintL2 x = x1*2^32+x0 : Radikand, >=0, <2^64
1023 // < uintL ergebnis : Wurzel, >=0, <2^32
1024   extern uintL isqrt (uintL x1, uintL x0);
1025
1026
1027 // Bits einer 8-Bit-Zahl zählen:
1028 // integerlength8(digit,size=);
1029 // setzt size auf die höchste in digit vorkommende Bitnummer.
1030 // > digit: ein uint8 >0
1031 // < size: >0, <=8, mit 2^(size-1) <= digit < 2^size
1032 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1033   #define integerlength8(digit,size_zuweisung)  \
1034     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit            */\
1035       __asm__("bfffo %1{#0:#8},%0" : "=d" (_zero_counter) : "dm" ((uint8)(digit)) ); \
1036       size_zuweisung (8-_zero_counter);                                              \
1037     }
1038 #elif defined(__sparc__) && !defined(__sparc64__)
1039   #define integerlength8(digit,size_zuweisung)  \
1040     integerlength32((uint32)(digit),size_zuweisung) // siehe unten
1041 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1042   #define integerlength8(digit,size_zuweisung)  \
1043     integerlength16((uint16)(digit),size_zuweisung)
1044 #else
1045   #define integerlength8(digit,size_zuweisung)  \
1046     { var uintC _bitsize = 1;                                   \
1047       var uintL _x8 = (uint8)(digit);                           \
1048       /* _x8 hat höchstens 8 Bits.                             */\
1049       if (_x8 >= bit(4)) { _x8 = _x8>>4; _bitsize += 4; }               \
1050       /* _x8 hat höchstens 4 Bits.                             */\
1051       if (_x8 >= bit(2)) { _x8 = _x8>>2; _bitsize += 2; }               \
1052       /* _x8 hat höchstens 2 Bits.                             */\
1053       if (_x8 >= bit(1)) { /* _x8 = _x8>>1; */ _bitsize += 1; } \
1054       /* _x8 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein. */\
1055       size_zuweisung _bitsize;                                  \
1056     }
1057 #endif
1058
1059 // Bits einer 16-Bit-Zahl zählen:
1060 // integerlength16(digit,size=);
1061 // setzt size auf die höchste in digit vorkommende Bitnummer.
1062 // > digit: ein uint16 >0
1063 // < size: >0, <=16, mit 2^(size-1) <= digit < 2^size
1064 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1065   #define integerlength16(digit,size_zuweisung)  \
1066     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit              */\
1067       __asm__("bfffo %1{#0:#16},%0" : "=d" (_zero_counter) : "dm" ((uint16)(digit)) ); \
1068       size_zuweisung (16-_zero_counter);                                               \
1069     }
1070 #elif defined(__sparc__) && !defined(__sparc64__)
1071   #define integerlength16(digit,size_zuweisung)  \
1072     integerlength32((uint32)(digit),size_zuweisung) // siehe unten
1073 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1074   #define integerlength16(digit,size_zuweisung)  \
1075     { var uintW _one_position; /* Position der führenden 1                 */\
1076       __asm__("bsrw %1,%0" : "=r" (_one_position) : "r" ((uint16)(digit)) ); \
1077       size_zuweisung (1+_one_position);                                      \
1078     }
1079 // Die weiteren kommen von gcc/longlong.h :
1080 #elif defined(__GNUC__) && defined(__ibm032__) && !defined(NO_ASM) // RT/ROMP
1081   #define integerlength16(digit,size_zuweisung)  \
1082     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit   */\
1083       __asm__("clz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1084       size_zuweisung (16-_zero_counter);                                    \
1085     }
1086 #else
1087   #define integerlength16(digit,size_zuweisung)  \
1088     { var uintC _bitsize = 1;                                           \
1089       var uintWL _x16 = (uint16)(digit);                                        \
1090       /* _x16 hat höchstens 16 Bits.                                   */\
1091       if (_x16 >= bit(8)) { _x16 = _x16>>8; _bitsize += 8; }            \
1092       /* _x16 hat höchstens 8 Bits.                                    */\
1093       if (_x16 >= bit(4)) { _x16 = _x16>>4; _bitsize += 4; }            \
1094       /* _x16 hat höchstens 4 Bits.                                    */\
1095       if (_x16 >= bit(2)) { _x16 = _x16>>2; _bitsize += 2; }            \
1096       /* _x16 hat höchstens 2 Bits.                                    */\
1097       if (_x16 >= bit(1)) { /* _x16 = _x16>>1; */ _bitsize += 1; }              \
1098       /* _x16 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein.        */\
1099       size_zuweisung _bitsize;                                          \
1100     }
1101 #endif
1102
1103 // Bits einer 32-Bit-Zahl zählen:
1104 // integerlength32(digit,size=);
1105 // setzt size auf die höchste in digit vorkommende Bitnummer.
1106 // > digit: ein uint32 >0
1107 // < size: >0, <=32, mit 2^(size-1) <= digit < 2^size
1108 #if defined(__GNUC__) && defined(__m68k__) && !defined(NO_ASM)
1109   #define integerlength32(digit,size_zuweisung)  \
1110     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit              */\
1111       __asm__("bfffo %1{#0:#32},%0" : "=d" (_zero_counter) : "dm" ((uint32)(digit)) ); \
1112       size_zuweisung (32-_zero_counter);                                               \
1113     }
1114 #elif defined(__sparc__) && !defined(__sparc64__) && defined(FAST_DOUBLE)
1115   #define integerlength32(digit,size_zuweisung)  \
1116     {var union { double f; uint32 i[2]; } __fi;                         \
1117      const int df_mant_len = 52;  /* mantissa bits (excl. hidden bit) */\
1118      const int df_exp_mid = 1022; /* exponent bias */                   \
1119      /* Bilde 2^52 + digit:                                           */\
1120      __fi.i[0] = (uint32)(df_mant_len+1+df_exp_mid) << (df_mant_len-32); /* Vorzeichen 0, Exponent 53 */\
1121      __fi.i[1] = (digit); /* untere 32 Bits setzen (benutzt CL_CPU_BIG_ENDIAN_P !) */\
1122      /* subtrahiere 2^52:                                             */\
1123      __fi.f = __fi.f - (double)(4503599627370496.0L);                   \
1124      /* Hole davon den Exponenten:                                    */\
1125      size_zuweisung ((__fi.i[0] >> (df_mant_len-32)) - df_exp_mid);     \
1126     }
1127 #elif defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1128   #define integerlength32(digit,size_zuweisung)  \
1129     { var uintL _one_position; /* Position der führenden 1                  */\
1130       __asm__("bsrl %1,%0" : "=r" (_one_position) : "rm" ((uint32)(digit)) ); \
1131       size_zuweisung (1+_one_position);                                       \
1132     }
1133 #elif defined(__hppa__) && !defined(NO_ASM)
1134   #define integerlength32(digit,size_zuweisung)  \
1135     size_zuweisung length32(digit);
1136   extern "C" uintL length32 (uintL digit); // extern in Assembler
1137 // Die weiteren kommen von gcc/longlong.h :
1138 #elif defined(__GNUC__) && (defined(__a29k__) || defined(___AM29K__)) && !defined(NO_ASM)
1139   #define integerlength32(digit,size_zuweisung)  \
1140     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit   */\
1141       __asm__("clz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1142       size_zuweisung (32-_zero_counter);                                    \
1143     }
1144 #elif defined(__GNUC__) && defined(__gmicro__) && !defined(NO_ASM)
1145   #define integerlength32(digit,size_zuweisung)  \
1146     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit      */\
1147       __asm__("bsch/1 %1,%0" : "=g" (_zero_counter) : "g" ((uint32)(digit)) ); \
1148       size_zuweisung (32-_zero_counter);                                       \
1149     }
1150 #elif defined(__GNUC__) && defined(__rs6000__) && !defined(NO_ASM)
1151  #ifdef _AIX
1152   // old assembler syntax
1153   #define integerlength32(digit,size_zuweisung)  \
1154     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit     */\
1155       __asm__("cntlz %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1156       size_zuweisung (32-_zero_counter);                                      \
1157     }
1158  #else
1159   // new assembler syntax
1160   #define integerlength32(digit,size_zuweisung)  \
1161     { var uintL _zero_counter; /* zählt die führenden Nullbits in digit      */\
1162       __asm__("cntlzw %0,%1" : "=r" (_zero_counter) : "r" ((uint32)(digit)) ); \
1163       size_zuweisung (32-_zero_counter);                                       \
1164     }
1165  #endif
1166 #elif defined(__GNUC__) && defined(__m88k__) && !defined(NO_ASM)
1167   #define integerlength32(digit,size_zuweisung)  \
1168     { var uintL _one_position; /* Position der führenden 1                */\
1169       __asm__("ff1 %0,%1" : "=r" (_one_position) : "r" ((uint32)(digit)) ); \
1170       size_zuweisung (1+_one_position);                                     \
1171     }
1172 #elif defined(__GNUC__) && defined(__ibm032__) && !defined(NO_ASM) // RT/ROMP
1173   #define integerlength32(digit,size_zuweisung)  \
1174     { var uintL _x32 = (uint32)(digit);                         \
1175       if (_x32 >= bit(16))                                      \
1176         { integerlength16(_x32>>16,size_zuweisung 16 + ); }     \
1177         else                                                    \
1178         { integerlength16(_x32,size_zuweisung); }               \
1179     }
1180 #else
1181   #define integerlength32(digit,size_zuweisung)  \
1182     { var uintC _bitsize = 1;                                           \
1183       var uintL _x32 = (uint32)(digit);                                 \
1184       /* _x32 hat höchstens 32 Bits.                                   */\
1185       if (_x32 >= bit(16)) { _x32 = _x32>>16; _bitsize += 16; }         \
1186       /* _x32 hat höchstens 16 Bits.                                   */\
1187       if (_x32 >= bit(8)) { _x32 = _x32>>8; _bitsize += 8; }            \
1188       /* _x32 hat höchstens 8 Bits.                                    */\
1189       if (_x32 >= bit(4)) { _x32 = _x32>>4; _bitsize += 4; }            \
1190       /* _x32 hat höchstens 4 Bits.                                    */\
1191       if (_x32 >= bit(2)) { _x32 = _x32>>2; _bitsize += 2; }            \
1192       /* _x32 hat höchstens 2 Bits.                                    */\
1193       if (_x32 >= bit(1)) { /* _x32 = _x32>>1; */ _bitsize += 1; }              \
1194       /* _x32 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein.        */\
1195       size_zuweisung _bitsize;                                          \
1196     }
1197 #endif
1198
1199 // Bits einer 64-Bit-Zahl zählen:
1200 // integerlength64(digit,size=);
1201 // setzt size auf die höchste in digit vorkommende Bitnummer.
1202 // > digit: ein uint64 >0
1203 // < size: >0, <=64, mit 2^(size-1) <= digit < 2^size
1204   #define integerlength64(digit,size_zuweisung)  \
1205     { var uintC _bitsize = 1;                                           \
1206       var uint64 _x64 = (uint64)(digit);                                        \
1207       /* _x64 hat höchstens 64 Bits.                                   */\
1208       if (_x64 >= bit(32)) { _x64 = _x64>>32; _bitsize += 32; }         \
1209       /* _x64 hat höchstens 32 Bits.                                   */\
1210       if (_x64 >= bit(16)) { _x64 = _x64>>16; _bitsize += 16; }         \
1211       /* _x64 hat höchstens 16 Bits.                                   */\
1212       if (_x64 >= bit(8)) { _x64 = _x64>>8; _bitsize += 8; }            \
1213       /* _x64 hat höchstens 8 Bits.                                    */\
1214       if (_x64 >= bit(4)) { _x64 = _x64>>4; _bitsize += 4; }            \
1215       /* _x64 hat höchstens 4 Bits.                                    */\
1216       if (_x64 >= bit(2)) { _x64 = _x64>>2; _bitsize += 2; }            \
1217       /* _x64 hat höchstens 2 Bits.                                    */\
1218       if (_x64 >= bit(1)) { /* _x64 = _x64>>1; */ _bitsize += 1; }              \
1219       /* _x64 hat höchstens 1 Bit. Dieses Bit muß gesetzt sein.        */\
1220       size_zuweisung _bitsize;                                          \
1221     }
1222
1223 // Hintere Nullbits eines 32-Bit-Wortes zählen:
1224 // ord2_32(digit,count=);
1225 // setzt size auf die kleinste in digit vorkommende Bitnummer.
1226 // > digit: ein uint32 >0
1227 // < count: >=0, <32, mit 2^count | digit, digit/2^count ungerade
1228   #if defined(__GNUC__) && defined(__i386__) && !defined(NO_ASM)
1229     #define ord2_32(digit,count_zuweisung)  \
1230       { var uintL _one_position; /* Position der letzten 1                    */\
1231         __asm__("bsfl %1,%0" : "=r" (_one_position) : "rm" ((uint32)(digit)) ); \
1232         count_zuweisung _one_position;                                          \
1233       }
1234     #define FAST_ORD2
1235   #elif defined(__sparc__) && !defined(__sparc64__)
1236     #define ord2_32(digit,count_zuweisung)  \
1237     { var uint32 n = (digit);                                             \
1238       n = n | -n;                                                         \
1239       n = (n<<4) + n;                                                     \
1240       n = (n<<6) + n;                                                     \
1241       n = n - (n<<16); /* or  n = n ^ (n<<16);  or  n = n &~ (n<<16);  */ \
1242       /* 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}; */ \
1243       /* count_zuweisung ord2_tab[n>>26];                              */ \
1244       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]; \
1245     }
1246     #define FAST_ORD2
1247   #else
1248     // Sei n = ord2(x). Dann ist logxor(x,x-1) = 2^n + (2^n-1) = 2^(n+1)-1.
1249     // Also  (ord2 x) = (1- (integer-length (logxor x (1- x)))) .
1250     #define ord2_32(digit,count_zuweisung)  \
1251       { var uint32 _digit = digit ^ (digit - 1);        \
1252         integerlength32(_digit,count_zuweisung -1 + )   \
1253       }
1254   #endif
1255
1256
1257 // Bits eines Wortes zählen.
1258 // logcount_NN();
1259 // > xNN: ein uintNN
1260 // < xNN: Anzahl der darin gesetzten Bits
1261   // Bits von x8 zählen: (Input x8, Output x8)
1262   #define logcount_8()  \
1263     ( /* x8 besteht aus 8 1-Bit-Zählern (0,1).        */\
1264       x8 = (x8 & 0x55U) + ((x8 & 0xAAU) >> 1),          \
1265       /* x8 besteht aus 4 2-Bit-Zählern (0,1,2).      */\
1266       x8 = (x8 & 0x33U) + ((x8 & 0xCCU) >> 2),          \
1267       /* x8 besteht aus 2 4-Bit-Zählern (0,1,2,3,4).  */\
1268       x8 = (x8 & 0x0FU) + (x8 >> 4)                     \
1269       /* x8 besteht aus 1 8-Bit-Zähler (0,...,8).     */\
1270     )
1271   // Bits von x16 zählen: (Input x16, Output x16)
1272   #define logcount_16()  \
1273     ( /* x16 besteht aus 16 1-Bit-Zählern (0,1).      */\
1274       x16 = (x16 & 0x5555U) + ((x16 & 0xAAAAU) >> 1),   \
1275       /* x16 besteht aus 8 2-Bit-Zählern (0,1,2).     */\
1276       x16 = (x16 & 0x3333U) + ((x16 & 0xCCCCU) >> 2),   \
1277       /* x16 besteht aus 4 4-Bit-Zählern (0,1,2,3,4). */\
1278       x16 = (x16 & 0x0F0FU) + ((x16 & 0xF0F0U) >> 4),   \
1279       /* x16 besteht aus 2 8-Bit-Zählern (0,...,8).   */\
1280       x16 = (x16 & 0x00FFU) + (x16 >> 8)                \
1281       /* x16 besteht aus 1 16-Bit-Zähler (0,...,16).  */\
1282     )
1283   // Bits von x32 zählen: (Input x32, Output x32)
1284   #define logcount_32()  \
1285     ( /* x32 besteht aus 32 1-Bit-Zählern (0,1).              */\
1286       x32 = (x32 & 0x55555555UL) + ((x32 & 0xAAAAAAAAUL) >> 1), \
1287       /* x32 besteht aus 16 2-Bit-Zählern (0,1,2).            */\
1288       x32 = (x32 & 0x33333333UL) + ((x32 & 0xCCCCCCCCUL) >> 2), \
1289       /* x32 besteht aus 8 4-Bit-Zählern (0,1,2,3,4).         */\
1290       x32 = high16(x32)+low16(x32),                             \
1291       /* x32 besteht aus 4 4-Bit-Zählern (0,...,8).           */\
1292       x32 = (x32 & 0x0F0FU) + ((x32 & 0xF0F0U) >> 4),           \
1293       /* x32 besteht aus 2 8-Bit-Zählern (0,...,16).          */\
1294       x32 = (x32 & 0x00FFU) + (x32 >> 8)                        \
1295       /* x32 besteht aus 1 16-Bit-Zähler (0,...,32).          */\
1296     )
1297   // Bits von x64 zählen: (Input x64, Output x64)
1298   #define logcount_64()  \
1299     ( /* x64 besteht aus 64 1-Bit-Zählern (0,1).                             */\
1300       x64 = (x64 & 0x5555555555555555ULL) + ((x64 & 0xAAAAAAAAAAAAAAAAULL) >> 1),\
1301       /* x64 besteht aus 32 2-Bit-Zählern (0,1,2).                           */\
1302       x64 = (x64 & 0x3333333333333333ULL) + ((x64 & 0xCCCCCCCCCCCCCCCCULL) >> 2),\
1303       /* x64 besteht aus 16 4-Bit-Zählern (0,1,2,3,4).                       */\
1304       x64 = (uint32)(x64 + (x64 >> 32)),                                       \
1305       /* x64 besteht aus 8 4-Bit-Zählern (0,...,8).                          */\
1306       x64 = (x64 & 0x0F0F0F0FUL) + ((x64 & 0xF0F0F0F0UL) >> 4),                \
1307       /* x64 besteht aus 4 8-Bit-Zählern (0,...,16).                         */\
1308       x64 = (x64 & 0x00FF00FFU) + ((x64 & 0xFF00FF00U) >> 8),                  \
1309       /* x64 besteht aus 2 16-Bit-Zählern (0,...,32).                        */\
1310       x64 = (x64 & 0x0000FFFFU) + (x64 >> 16)                                  \
1311       /* x64 besteht aus 1 16-Bit-Zähler (0,...,64).                         */\
1312     )
1313
1314 }  // namespace cln
1315
1316 #endif /* _CL_LOW_H */