1 /* 128 bit integer arithmetic.
2  *
3  * Not optimized for speed.
4  *
5  * Copyright: Copyright D Language Foundation 2022.
6  * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Authors:   Walter Bright
8  * Source:    $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/common/int128.d, root/_int128.d)
9  * Documentation: https://dlang.org/phobos/dmd_common_int128.html
10  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/common/int128.d
11  */
12 
13 module dmd.common.int128;
14 
15 nothrow:
16 @safe:
17 @nogc:
18 
19 alias I = long;
20 alias U = ulong;
21 enum Ubits = uint(U.sizeof * 8);
22 
23 align(16) struct Cent
24 {
25     U lo;      // low 64 bits
26     U hi;      // high 64 bits
27 }
28 
29 enum One = Cent(1);
30 enum Zero = Cent();
31 enum MinusOne = neg(One);
32 
33 /*****************************
34  * Test against 0
35  * Params:
36  *      c = Cent to test
37  * Returns:
38  *      true if != 0
39  */
40 pure
41 bool tst(Cent c)
42 {
43     return c.hi || c.lo;
44 }
45 
46 
47 /*****************************
48  * Complement
49  * Params:
50  *      c = Cent to complement
51  * Returns:
52  *      complemented value
53  */
54 pure
55 Cent com(Cent c)
56 {
57     c.lo = ~c.lo;
58     c.hi = ~c.hi;
59     return c;
60 }
61 
62 /*****************************
63  * Negate
64  * Params:
65  *      c = Cent to negate
66  * Returns:
67  *      negated value
68  */
69 pure
70 Cent neg(Cent c)
71 {
72     if (c.lo == 0)
73         c.hi = -c.hi;
74     else
75     {
76         c.lo = -c.lo;
77         c.hi = ~c.hi;
78     }
79     return c;
80 }
81 
82 /*****************************
83  * Increment
84  * Params:
85  *      c = Cent to increment
86  * Returns:
87  *      incremented value
88  */
89 pure
90 Cent inc(Cent c)
91 {
92     return add(c, One);
93 }
94 
95 /*****************************
96  * Decrement
97  * Params:
98  *      c = Cent to decrement
99  * Returns:
100  *      incremented value
101  */
102 pure
103 Cent dec(Cent c)
104 {
105     return sub(c, One);
106 }
107 
108 /*****************************
109  * Shift left one bit
110  * Params:
111  *      c = Cent to shift
112  * Returns:
113  *      shifted value
114  */
115 pure
116 Cent shl1(Cent c)
117 {
118     c.hi = (c.hi << 1) | (cast(I)c.lo < 0);
119     c.lo <<= 1;
120     return c;
121 }
122 
123 /*****************************
124  * Unsigned shift right one bit
125  * Params:
126  *      c = Cent to shift
127  * Returns:
128  *      shifted value
129  */
130 pure
131 Cent shr1(Cent c)
132 {
133     c.lo = (c.lo >> 1) | ((c.hi & 1) << (Ubits - 1));
134     c.hi >>= 1;
135     return c;
136 }
137 
138 
139 /*****************************
140  * Arithmetic shift right one bit
141  * Params:
142  *      c = Cent to shift
143  * Returns:
144  *      shifted value
145  */
146 pure
147 Cent sar1(Cent c)
148 {
149     c.lo = (c.lo >> 1) | ((c.hi & 1) << (Ubits - 1));
150     c.hi = cast(I)c.hi >> 1;
151     return c;
152 }
153 
154 /*****************************
155  * Shift left n bits
156  * Params:
157  *      c = Cent to shift
158  *      n = number of bits to shift
159  * Returns:
160  *      shifted value
161  */
162 pure
163 Cent shl(Cent c, uint n)
164 {
165     if (n >= Ubits * 2)
166         return Zero;
167 
168     if (n >= Ubits)
169     {
170         c.hi = c.lo << (n - Ubits);
171         c.lo = 0;
172     }
173     else
174     {
175         c.hi = ((c.hi << n) | (c.lo >> (Ubits - n - 1) >> 1));
176         c.lo = c.lo << n;
177     }
178     return c;
179 }
180 
181 /*****************************
182  * Unsigned shift right n bits
183  * Params:
184  *      c = Cent to shift
185  *      n = number of bits to shift
186  * Returns:
187  *      shifted value
188  */
189 pure
190 Cent shr(Cent c, uint n)
191 {
192     if (n >= Ubits * 2)
193         return Zero;
194 
195     if (n >= Ubits)
196     {
197         c.lo = c.hi >> (n - Ubits);
198         c.hi = 0;
199     }
200     else
201     {
202         c.lo = ((c.lo >> n) | (c.hi << (Ubits - n - 1) << 1));
203         c.hi = c.hi >> n;
204     }
205     return c;
206 }
207 
208 /*****************************
209  * Arithmetic shift right n bits
210  * Params:
211  *      c = Cent to shift
212  *      n = number of bits to shift
213  * Returns:
214  *      shifted value
215  */
216 pure
217 Cent sar(Cent c, uint n)
218 {
219     const signmask = -(c.hi >> (Ubits - 1));
220     const signshift = (Ubits * 2) - n;
221     c = shr(c, n);
222 
223     // Sign extend all bits beyond the precision of Cent.
224     if (n >= Ubits * 2)
225     {
226         c.hi = signmask;
227         c.lo = signmask;
228     }
229     else if (signshift >= Ubits * 2)
230     {
231     }
232     else if (signshift >= Ubits)
233     {
234         c.hi &= ~(U.max << (signshift - Ubits));
235         c.hi |= signmask << (signshift - Ubits);
236     }
237     else
238     {
239         c.hi = signmask;
240         c.lo &= ~(U.max << signshift);
241         c.lo |= signmask << signshift;
242     }
243     return c;
244 }
245 
246 /*****************************
247  * Rotate left one bit
248  * Params:
249  *      c = Cent to rotate
250  * Returns:
251  *      rotated value
252  */
253 pure
254 Cent rol1(Cent c)
255 {
256     int carry = cast(I)c.hi < 0;
257 
258     c.hi = (c.hi << 1) | (cast(I)c.lo < 0);
259     c.lo = (c.lo << 1) | carry;
260     return c;
261 }
262 
263 /*****************************
264  * Rotate right one bit
265  * Params:
266  *      c = Cent to rotate
267  * Returns:
268  *      rotated value
269  */
270 pure
271 Cent ror1(Cent c)
272 {
273     int carry = c.lo & 1;
274     c.lo = (c.lo >> 1) | (cast(U)(c.hi & 1) << (Ubits - 1));
275     c.hi = (c.hi >> 1) | (cast(U)carry << (Ubits - 1));
276     return c;
277 }
278 
279 
280 /*****************************
281  * Rotate left n bits
282  * Params:
283  *      c = Cent to rotate
284  *      n = number of bits to rotate
285  * Returns:
286  *      rotated value
287  */
288 pure
289 Cent rol(Cent c, uint n)
290 {
291     n &= Ubits * 2 - 1;
292     Cent l = shl(c, n);
293     Cent r = shr(c, Ubits * 2 - n);
294     return or(l, r);
295 }
296 
297 /*****************************
298  * Rotate right n bits
299  * Params:
300  *      c = Cent to rotate
301  *      n = number of bits to rotate
302  * Returns:
303  *      rotated value
304  */
305 pure
306 Cent ror(Cent c, uint n)
307 {
308     n &= Ubits * 2 - 1;
309     Cent r = shr(c, n);
310     Cent l = shl(c, Ubits * 2 - n);
311     return or(r, l);
312 }
313 
314 /****************************
315  * And c1 & c2.
316  * Params:
317  *      c1 = operand 1
318  *      c2 = operand 2
319  * Returns:
320  *      c1 & c2
321  */
322 pure
323 Cent and(Cent c1, Cent c2)
324 {
325     return Cent(c1.lo & c2.lo, c1.hi & c2.hi);
326 }
327 
328 /****************************
329  * Or c1 | c2.
330  * Params:
331  *      c1 = operand 1
332  *      c2 = operand 2
333  * Returns:
334  *      c1 | c2
335  */
336 pure
337 Cent or(Cent c1, Cent c2)
338 {
339     return Cent(c1.lo | c2.lo, c1.hi | c2.hi);
340 }
341 
342 /****************************
343  * Xor c1 ^ c2.
344  * Params:
345  *      c1 = operand 1
346  *      c2 = operand 2
347  * Returns:
348  *      c1 ^ c2
349  */
350 pure
351 Cent xor(Cent c1, Cent c2)
352 {
353     return Cent(c1.lo ^ c2.lo, c1.hi ^ c2.hi);
354 }
355 
356 /****************************
357  * Add c1 to c2.
358  * Params:
359  *      c1 = operand 1
360  *      c2 = operand 2
361  * Returns:
362  *      c1 + c2
363  */
364 pure
365 Cent add(Cent c1, Cent c2)
366 {
367     U r = cast(U)(c1.lo + c2.lo);
368     return Cent(r, cast(U)(c1.hi + c2.hi + (r < c1.lo)));
369 }
370 
371 /****************************
372  * Subtract c2 from c1.
373  * Params:
374  *      c1 = operand 1
375  *      c2 = operand 2
376  * Returns:
377  *      c1 - c2
378  */
379 pure
380 Cent sub(Cent c1, Cent c2)
381 {
382     return add(c1, neg(c2));
383 }
384 
385 /****************************
386  * Multiply c1 * c2.
387  * Params:
388  *      c1 = operand 1
389  *      c2 = operand 2
390  * Returns:
391  *      c1 * c2
392  */
393 pure
394 Cent mul(Cent c1, Cent c2)
395 {
396     enum mulmask = (1UL << (Ubits / 2)) - 1;
397     enum mulshift = Ubits / 2;
398 
399     // This algorithm splits the operands into 4 words, then computes and sums
400     // the partial products of each part.
401     const c2l0 = c2.lo & mulmask;
402     const c2l1 = c2.lo >> mulshift;
403     const c2h0 = c2.hi & mulmask;
404     const c2h1 = c2.hi >> mulshift;
405 
406     const c1l0 = c1.lo & mulmask;
407     U r0 = c1l0 * c2l0;
408     U r1 = c1l0 * c2l1 + (r0 >> mulshift);
409     U r2 = c1l0 * c2h0 + (r1 >> mulshift);
410     U r3 = c1l0 * c2h1 + (r2 >> mulshift);
411 
412     const c1l1 = c1.lo >> mulshift;
413     r1 = c1l1 * c2l0 + (r1 & mulmask);
414     r2 = c1l1 * c2l1 + (r2 & mulmask) + (r1 >> mulshift);
415     r3 = c1l1 * c2h0 + (r3 & mulmask) + (r2 >> mulshift);
416 
417     const c1h0 = c1.hi & mulmask;
418     r2 = c1h0 * c2l0 + (r2 & mulmask);
419     r3 = c1h0 * c2l1 + (r3 & mulmask) + (r2 >> mulshift);
420 
421     const c1h1 = c1.hi >> mulshift;
422     r3 = c1h1 * c2l0 + (r3 & mulmask);
423 
424     return Cent((r0 & mulmask) + (r1 & mulmask) * (mulmask + 1),
425                 (r2 & mulmask) + (r3 & mulmask) * (mulmask + 1));
426 
427 }
428 
429 
430 /****************************
431  * Unsigned divide c1 / c2.
432  * Params:
433  *      c1 = dividend
434  *      c2 = divisor
435  * Returns:
436  *      quotient c1 / c2
437  */
438 pure
439 Cent udiv(Cent c1, Cent c2)
440 {
441     Cent modulus;
442     return udivmod(c1, c2, modulus);
443 }
444 
445 /****************************
446  * Unsigned divide c1 / c2. The remainder after division is stored to modulus.
447  * Params:
448  *      c1 = dividend
449  *      c2 = divisor
450  *      modulus = set to c1 % c2
451  * Returns:
452  *      quotient c1 / c2
453  */
454 pure
455 Cent udivmod(Cent c1, Cent c2, out Cent modulus)
456 {
457     //printf("udiv c1(%llx,%llx) c2(%llx,%llx)\n", c1.lo, c1.hi, c2.lo, c2.hi);
458     // Based on "Unsigned Doubleword Division" in Hacker's Delight
459     import core.bitop;
460 
461     // Divides a 128-bit dividend by a 64-bit divisor.
462     // The result must fit in 64 bits.
463     static U udivmod128_64(Cent c1, U c2, out U modulus)
464     {
465         // We work in base 2^^32
466         enum base = 1UL << 32;
467         enum divmask = (1UL << (Ubits / 2)) - 1;
468         enum divshift = Ubits / 2;
469 
470         // Check for overflow and divide by 0
471         if (c1.hi >= c2)
472         {
473             modulus = 0UL;
474             return ~0UL;
475         }
476 
477         // Computes [num1 num0] / den
478         static uint udiv96_64(U num1, uint num0, U den)
479         {
480             // Extract both digits of the denominator
481             const den1 = cast(uint)(den >> divshift);
482             const den0 = cast(uint)(den & divmask);
483             // Estimate ret as num1 / den1, and then correct it
484             U ret = num1 / den1;
485             const t2 = (num1 % den1) * base + num0;
486             const t1 = ret * den0;
487             if (t1 > t2)
488                 ret -= (t1 - t2 > den) ? 2 : 1;
489             return cast(uint)ret;
490         }
491 
492         // Determine the normalization factor. We multiply c2 by this, so that its leading
493         // digit is at least half base. In binary this means just shifting left by the number
494         // of leading zeros, so that there's a 1 in the MSB.
495         // We also shift number by the same amount. This cannot overflow because c1.hi < c2.
496         const shift = (Ubits - 1) - bsr(c2);
497         c2 <<= shift;
498         U num2 = c1.hi;
499         num2 <<= shift;
500         num2 |= (c1.lo >> (-shift & 63)) & (-cast(I)shift >> 63);
501         c1.lo <<= shift;
502 
503         // Extract the low digits of the numerator (after normalizing)
504         const num1 = cast(uint)(c1.lo >> divshift);
505         const num0 = cast(uint)(c1.lo & divmask);
506 
507         // Compute q1 = [num2 num1] / c2
508         const q1 = udiv96_64(num2, num1, c2);
509         // Compute the true (partial) remainder
510         const rem = num2 * base + num1 - q1 * c2;
511         // Compute q0 = [rem num0] / c2
512         const q0 = udiv96_64(rem, num0, c2);
513 
514         modulus = (rem * base + num0 - q0 * c2) >> shift;
515         return (cast(U)q1 << divshift) | q0;
516     }
517 
518     // Special cases
519     if (!tst(c2))
520     {
521         // Divide by zero
522         modulus = Zero;
523         return com(modulus);
524     }
525     if (c1.hi == 0 && c2.hi == 0)
526     {
527         // Single precision divide
528         modulus = Cent(c1.lo % c2.lo);
529         return Cent(c1.lo / c2.lo);
530     }
531     if (c1.hi == 0)
532     {
533         // Numerator is smaller than the divisor
534         modulus = c1;
535         return Zero;
536     }
537     if (c2.hi == 0)
538     {
539         // Divisor is a 64-bit value, so we just need one 128/64 division.
540         // If c1 / c2 would overflow, break c1 up into two halves.
541         const q1 = (c1.hi < c2.lo) ? 0 : (c1.hi / c2.lo);
542         if (q1)
543             c1.hi = c1.hi % c2.lo;
544         U rem;
545         const q0 = udivmod128_64(c1, c2.lo, rem);
546         modulus = Cent(rem);
547         return Cent(q0, q1);
548     }
549 
550     // Full cent precision division.
551     // Here c2 >= 2^^64
552     // We know that c2.hi != 0, so count leading zeros is OK
553     // We have 0 <= shift <= 63
554     const shift = (Ubits - 1) - bsr(c2.hi);
555 
556     // Normalize the divisor so its MSB is 1
557     // v1 = (c2 << shift) >> 64
558     U v1 = shl(c2, shift).hi;
559 
560     // To ensure no overflow.
561     Cent u1 = shr1(c1);
562 
563     // Get quotient from divide unsigned operation.
564     U rem_ignored;
565     const q1 = udivmod128_64(u1, v1, rem_ignored);
566 
567     // Undo normalization and division of c1 by 2.
568     Cent quotient = shr(shl(Cent(q1), shift), 63);
569 
570     // Make quotient correct or too small by 1
571     if (tst(quotient))
572         quotient = dec(quotient);
573 
574     // Now quotient is correct.
575     // Compute rem = c1 - (quotient * c2);
576     Cent rem = sub(c1, mul(quotient, c2));
577 
578     // Check if remainder is larger than the divisor
579     if (uge(rem, c2))
580     {
581         // Increment quotient
582         quotient = inc(quotient);
583         // Subtract c2 from remainder
584         rem = sub(rem, c2);
585     }
586     modulus = rem;
587     //printf("quotient "); print(quotient);
588     //printf("modulus  "); print(modulus);
589     return quotient;
590 }
591 
592 
593 /****************************
594  * Signed divide c1 / c2.
595  * Params:
596  *      c1 = dividend
597  *      c2 = divisor
598  * Returns:
599  *      quotient c1 / c2
600  */
601 pure
602 Cent div(Cent c1, Cent c2)
603 {
604     Cent modulus;
605     return divmod(c1, c2, modulus);
606 }
607 
608 /****************************
609  * Signed divide c1 / c2. The remainder after division is stored to modulus.
610  * Params:
611  *      c1 = dividend
612  *      c2 = divisor
613  *      modulus = set to c1 % c2
614  * Returns:
615  *      quotient c1 / c2
616  */
617 pure
618 Cent divmod(Cent c1, Cent c2, out Cent modulus)
619 {
620     /* Muck about with the signs so we can use the unsigned divide
621      */
622     if (cast(I)c1.hi < 0)
623     {
624         if (cast(I)c2.hi < 0)
625         {
626             Cent r = udivmod(neg(c1), neg(c2), modulus);
627             modulus = neg(modulus);
628             return r;
629         }
630         Cent r = neg(udivmod(neg(c1), c2, modulus));
631         modulus = neg(modulus);
632         return r;
633     }
634     else if (cast(I)c2.hi < 0)
635     {
636         return neg(udivmod(c1, neg(c2), modulus));
637     }
638     else
639         return udivmod(c1, c2, modulus);
640 }
641 
642 /****************************
643  * If c1 > c2 unsigned
644  * Params:
645  *      c1 = operand 1
646  *      c2 = operand 2
647  * Returns:
648  *      true if c1 > c2
649  */
650 pure
651 bool ugt(Cent c1, Cent c2)
652 {
653     return (c1.hi == c2.hi) ? (c1.lo > c2.lo) : (c1.hi > c2.hi);
654 }
655 
656 /****************************
657  * If c1 >= c2 unsigned
658  * Params:
659  *      c1 = operand 1
660  *      c2 = operand 2
661  * Returns:
662  *      true if c1 >= c2
663  */
664 pure
665 bool uge(Cent c1, Cent c2)
666 {
667     return !ugt(c2, c1);
668 }
669 
670 /****************************
671  * If c1 < c2 unsigned
672  * Params:
673  *      c1 = operand 1
674  *      c2 = operand 2
675  * Returns:
676  *      true if c1 < c2
677  */
678 pure
679 bool ult(Cent c1, Cent c2)
680 {
681     return ugt(c2, c1);
682 }
683 
684 /****************************
685  * If c1 <= c2 unsigned
686  * Params:
687  *      c1 = operand 1
688  *      c2 = operand 2
689  * Returns:
690  *      true if c1 <= c2
691  */
692 pure
693 bool ule(Cent c1, Cent c2)
694 {
695     return !ugt(c1, c2);
696 }
697 
698 /****************************
699  * If c1 > c2 signed
700  * Params:
701  *      c1 = operand 1
702  *      c2 = operand 2
703  * Returns:
704  *      true if c1 > c2
705  */
706 pure
707 bool gt(Cent c1, Cent c2)
708 {
709     return (c1.hi == c2.hi)
710         ? (c1.lo > c2.lo)
711         : (cast(I)c1.hi > cast(I)c2.hi);
712 }
713 
714 /****************************
715  * If c1 >= c2 signed
716  * Params:
717  *      c1 = operand 1
718  *      c2 = operand 2
719  * Returns:
720  *      true if c1 >= c2
721  */
722 pure
723 bool ge(Cent c1, Cent c2)
724 {
725     return !gt(c2, c1);
726 }
727 
728 /****************************
729  * If c1 < c2 signed
730  * Params:
731  *      c1 = operand 1
732  *      c2 = operand 2
733  * Returns:
734  *      true if c1 < c2
735  */
736 pure
737 bool lt(Cent c1, Cent c2)
738 {
739     return gt(c2, c1);
740 }
741 
742 /****************************
743  * If c1 <= c2 signed
744  * Params:
745  *      c1 = operand 1
746  *      c2 = operand 2
747  * Returns:
748  *      true if c1 <= c2
749  */
750 pure
751 bool le(Cent c1, Cent c2)
752 {
753     return !gt(c1, c2);
754 }
755 
756 /*******************************************************/
757 
758 version (unittest)
759 {
760     version (none)
761     {
762         import core.stdc.stdio;
763 
764         @trusted
765         void print(Cent c)
766         {
767             printf("%lld, %lld\n", cast(ulong)c.lo, cast(ulong)c.hi);
768             printf("x%llx, x%llx\n", cast(ulong)c.lo, cast(ulong)c.hi);
769         }
770     }
771 }
772 
773 unittest
774 {
775     const C0 = Zero;
776     const C1 = One;
777     const C2 = Cent(2);
778     const C3 = Cent(3);
779     const C5 = Cent(5);
780     const C10 = Cent(10);
781     const C20 = Cent(20);
782     const C30 = Cent(30);
783     const C100 = Cent(100);
784 
785     const Cm1 =  neg(One);
786     const Cm3 =  neg(C3);
787     const Cm10 = neg(C10);
788 
789     const C3_1 = Cent(1,3);
790     const C3_2 = Cent(2,3);
791     const C4_8  = Cent(8, 4);
792     const C5_0  = Cent(0, 5);
793     const C7_1 = Cent(1,7);
794     const C7_9 = Cent(9,7);
795     const C9_3 = Cent(3,9);
796     const C10_0 = Cent(0,10);
797     const C10_1 = Cent(1,10);
798     const C10_3 = Cent(3,10);
799     const C11_3 = Cent(3,11);
800     const C20_0 = Cent(0,20);
801     const C90_30 = Cent(30,90);
802 
803     const Cm10_0 = inc(com(C10_0)); // Cent(0, -10);
804     const Cm10_1 = inc(com(C10_1)); // Cent(-1, -11);
805     const Cm10_3 = inc(com(C10_3)); // Cent(-3, -11);
806     const Cm20_0 = inc(com(C20_0)); // Cent(0, -20);
807 
808     enum Cs_3 = Cent(3, I.min);
809 
810     const Cbig_1 = Cent(0xa3ccac1832952398, 0xc3ac542864f652f8);
811     const Cbig_2 = Cent(0x5267b85f8a42fc20, 0);
812     const Cbig_3 = Cent(0xf0000000ffffffff, 0);
813 
814     /************************/
815 
816     assert( ugt(C1, C0) );
817     assert( ult(C1, C2) );
818     assert( uge(C1, C0) );
819     assert( ule(C1, C2) );
820 
821     assert( !ugt(C0, C1) );
822     assert( !ult(C2, C1) );
823     assert( !uge(C0, C1) );
824     assert( !ule(C2, C1) );
825 
826     assert( !ugt(C1, C1) );
827     assert( !ult(C1, C1) );
828     assert( uge(C1, C1) );
829     assert( ule(C2, C2) );
830 
831     assert( ugt(C10_3, C10_1) );
832     assert( ugt(C11_3, C10_3) );
833     assert( !ugt(C9_3, C10_3) );
834     assert( !ugt(C9_3, C9_3) );
835 
836     assert( gt(C2, C1) );
837     assert( !gt(C1, C2) );
838     assert( !gt(C1, C1) );
839     assert( gt(C0, Cm1) );
840     assert( gt(Cm1, neg(C10)));
841     assert( !gt(Cm1, Cm1) );
842     assert( !gt(Cm1, C0) );
843 
844     assert( !lt(C2, C1) );
845     assert( !le(C2, C1) );
846     assert( ge(C2, C1) );
847 
848     assert(neg(C10_0) == Cm10_0);
849     assert(neg(C10_1) == Cm10_1);
850     assert(neg(C10_3) == Cm10_3);
851 
852     assert(add(C7_1,C3_2) == C10_3);
853     assert(sub(C1,C2) == Cm1);
854 
855     assert(inc(C3_1) == C3_2);
856     assert(dec(C3_2) == C3_1);
857 
858     assert(shl(C10,0) == C10);
859     assert(shl(C10,Ubits) == C10_0);
860     assert(shl(C10,1) == C20);
861     assert(shl(C10,Ubits * 2) == C0);
862     assert(shr(C10_0,0) == C10_0);
863     assert(shr(C10_0,Ubits) == C10);
864     assert(shr(C10_0,Ubits - 1) == C20);
865     assert(shr(C10_0,Ubits + 1) == C5);
866     assert(shr(C10_0,Ubits * 2) == C0);
867     assert(sar(C10_0,0) == C10_0);
868     assert(sar(C10_0,Ubits) == C10);
869     assert(sar(C10_0,Ubits - 1) == C20);
870     assert(sar(C10_0,Ubits + 1) == C5);
871     assert(sar(C10_0,Ubits * 2) == C0);
872     assert(sar(Cm1,Ubits * 2) == Cm1);
873 
874     assert(shl1(C10) == C20);
875     assert(shr1(C10_0) == C5_0);
876     assert(sar1(C10_0) == C5_0);
877     assert(sar1(Cm1) == Cm1);
878 
879     Cent modulus;
880 
881     assert(udiv(C10,C2) == C5);
882     assert(udivmod(C10,C2, modulus) ==  C5);   assert(modulus == C0);
883     assert(udivmod(C10,C3, modulus) ==  C3);   assert(modulus == C1);
884     assert(udivmod(C10,C0, modulus) == Cm1);   assert(modulus == C0);
885     assert(udivmod(C2,C90_30, modulus) == C0); assert(modulus == C2);
886     assert(udiv(mul(C90_30, C2), C2) == C90_30);
887     assert(udiv(mul(C90_30, C2), C90_30) == C2);
888 
889     assert(div(C10,C3) == C3);
890     assert(divmod( C10,  C3, modulus) ==  C3); assert(modulus ==  C1);
891     assert(divmod(Cm10,  C3, modulus) == Cm3); assert(modulus == Cm1);
892     assert(divmod( C10, Cm3, modulus) == Cm3); assert(modulus ==  C1);
893     assert(divmod(Cm10, Cm3, modulus) ==  C3); assert(modulus == Cm1);
894     assert(divmod(C2, C90_30, modulus) == C0); assert(modulus == C2);
895     assert(div(mul(C90_30, C2), C2) == C90_30);
896     assert(div(mul(C90_30, C2), C90_30) == C2);
897 
898     assert(divmod(Cbig_1, Cbig_2, modulus) == Cent(0x4496aa309d4d4a2f, U.max));
899     assert(modulus == Cent(0xd83203d0fdc799b8, U.max));
900     assert(udivmod(Cbig_1, Cbig_2, modulus) == Cent(0x5fe0e9bace2bedad, 2));
901     assert(modulus == Cent(0x2c923125a68721f8, 0));
902     assert(div(Cbig_1, Cbig_3) == Cent(0xbfa6c02b5aff8b86, U.max));
903     assert(udiv(Cbig_1, Cbig_3) == Cent(0xd0b7d13b48cb350f, 0));
904 
905     assert(mul(Cm10, C1) == Cm10);
906     assert(mul(C1, Cm10) == Cm10);
907     assert(mul(C9_3, C10) == C90_30);
908     assert(mul(Cs_3, C10) == C30);
909     assert(mul(Cm10, Cm10) == C100);
910     assert(mul(C20_0, Cm1) == Cm20_0);
911 
912     assert( or(C4_8, C3_1) == C7_9);
913     assert(and(C4_8, C7_9) == C4_8);
914     assert(xor(C4_8, C7_9) == C3_1);
915 
916     assert(rol(Cm1,  1) == Cm1);
917     assert(ror(Cm1, 45) == Cm1);
918     assert(rol(ror(C7_9, 5), 5) == C7_9);
919     assert(rol(C7_9, 1) == rol1(C7_9));
920     assert(ror(C7_9, 1) == ror1(C7_9));
921 }