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