Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 31ec2e8

Browse files
ibuclawdlang-bot
authored andcommitted
core.int128: Match Cent layout on BigEndian targets
1 parent 0367eeb commit 31ec2e8

File tree

1 file changed

+87
-64
lines changed

1 file changed

+87
-64
lines changed

src/core/int128.d

Lines changed: 87 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,21 @@ else private enum Cent_alignment = (size_t.sizeof * 2);
2323

2424
align(Cent_alignment) struct Cent
2525
{
26-
U lo; // low 64 bits
27-
U hi; // high 64 bits
26+
version (LittleEndian)
27+
{
28+
U lo; // low 64 bits
29+
U hi; // high 64 bits
30+
}
31+
else
32+
{
33+
U hi; // high 64 bits
34+
U lo; // low 64 bits
35+
}
2836
}
2937

30-
enum One = Cent(1);
31-
enum Zero = Cent();
32-
enum MinusOne = neg(One);
38+
enum Cent One = { lo:1 };
39+
enum Cent Zero = { lo:0 };
40+
enum Cent MinusOne = neg(One);
3341

3442
/*****************************
3543
* Test against 0
@@ -323,7 +331,8 @@ Cent ror(Cent c, uint n)
323331
pure
324332
Cent and(Cent c1, Cent c2)
325333
{
326-
return Cent(c1.lo & c2.lo, c1.hi & c2.hi);
334+
const Cent ret = { lo:c1.lo & c2.lo, hi:c1.hi & c2.hi };
335+
return ret;
327336
}
328337

329338
/****************************
@@ -337,7 +346,8 @@ Cent and(Cent c1, Cent c2)
337346
pure
338347
Cent or(Cent c1, Cent c2)
339348
{
340-
return Cent(c1.lo | c2.lo, c1.hi | c2.hi);
349+
const Cent ret = { lo:c1.lo | c2.lo, hi:c1.hi | c2.hi };
350+
return ret;
341351
}
342352

343353
/****************************
@@ -351,7 +361,8 @@ Cent or(Cent c1, Cent c2)
351361
pure
352362
Cent xor(Cent c1, Cent c2)
353363
{
354-
return Cent(c1.lo ^ c2.lo, c1.hi ^ c2.hi);
364+
const Cent ret = { lo:c1.lo ^ c2.lo, hi:c1.hi ^ c2.hi };
365+
return ret;
355366
}
356367

357368
/****************************
@@ -366,7 +377,8 @@ pure
366377
Cent add(Cent c1, Cent c2)
367378
{
368379
U r = cast(U)(c1.lo + c2.lo);
369-
return Cent(r, cast(U)(c1.hi + c2.hi + (r < c1.lo)));
380+
const Cent ret = { lo:r, hi:cast(U)(c1.hi + c2.hi + (r < c1.lo)) };
381+
return ret;
370382
}
371383

372384
/****************************
@@ -422,9 +434,9 @@ Cent mul(Cent c1, Cent c2)
422434
const c1h1 = c1.hi >> mulshift;
423435
r3 = c1h1 * c2l0 + (r3 & mulmask);
424436

425-
return Cent((r0 & mulmask) + (r1 & mulmask) * (mulmask + 1),
426-
(r2 & mulmask) + (r3 & mulmask) * (mulmask + 1));
427-
437+
const Cent ret = { lo:(r0 & mulmask) + (r1 & mulmask) * (mulmask + 1),
438+
hi:(r2 & mulmask) + (r3 & mulmask) * (mulmask + 1) };
439+
return ret;
428440
}
429441

430442

@@ -526,8 +538,10 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
526538
if (c1.hi == 0 && c2.hi == 0)
527539
{
528540
// Single precision divide
529-
modulus = Cent(c1.lo % c2.lo);
530-
return Cent(c1.lo / c2.lo);
541+
const Cent rem = { lo:c1.lo % c2.lo };
542+
modulus = rem;
543+
const Cent ret = { lo:c1.lo / c2.lo };
544+
return ret;
531545
}
532546
if (c1.hi == 0)
533547
{
@@ -542,10 +556,11 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
542556
const q1 = (c1.hi < c2.lo) ? 0 : (c1.hi / c2.lo);
543557
if (q1)
544558
c1.hi = c1.hi % c2.lo;
545-
U rem;
546-
const q0 = udivmod128_64(c1, c2.lo, rem);
547-
modulus = Cent(rem);
548-
return Cent(q0, q1);
559+
Cent rem;
560+
const q0 = udivmod128_64(c1, c2.lo, rem.lo);
561+
modulus = rem;
562+
const Cent ret = { lo:q0, hi:q1 };
563+
return ret;
549564
}
550565

551566
// Full cent precision division.
@@ -563,10 +578,10 @@ Cent udivmod(Cent c1, Cent c2, out Cent modulus)
563578

564579
// Get quotient from divide unsigned operation.
565580
U rem_ignored;
566-
const q1 = udivmod128_64(u1, v1, rem_ignored);
581+
const Cent q1 = { lo:udivmod128_64(u1, v1, rem_ignored) };
567582

568583
// Undo normalization and division of c1 by 2.
569-
Cent quotient = shr(shl(Cent(q1), shift), 63);
584+
Cent quotient = shr(shl(q1, shift), 63);
570585

571586
// Make quotient correct or too small by 1
572587
if (tst(quotient))
@@ -773,44 +788,44 @@ version (unittest)
773788

774789
unittest
775790
{
776-
const C0 = Zero;
777-
const C1 = One;
778-
const C2 = Cent(2);
779-
const C3 = Cent(3);
780-
const C5 = Cent(5);
781-
const C10 = Cent(10);
782-
const C20 = Cent(20);
783-
const C30 = Cent(30);
784-
const C100 = Cent(100);
785-
786-
const Cm1 = neg(One);
787-
const Cm3 = neg(C3);
788-
const Cm10 = neg(C10);
789-
790-
const C3_1 = Cent(1,3);
791-
const C3_2 = Cent(2,3);
792-
const C4_8 = Cent(8, 4);
793-
const C5_0 = Cent(0, 5);
794-
const C7_1 = Cent(1,7);
795-
const C7_9 = Cent(9,7);
796-
const C9_3 = Cent(3,9);
797-
const C10_0 = Cent(0,10);
798-
const C10_1 = Cent(1,10);
799-
const C10_3 = Cent(3,10);
800-
const C11_3 = Cent(3,11);
801-
const C20_0 = Cent(0,20);
802-
const C90_30 = Cent(30,90);
803-
804-
const Cm10_0 = inc(com(C10_0)); // Cent(0, -10);
805-
const Cm10_1 = inc(com(C10_1)); // Cent(-1, -11);
806-
const Cm10_3 = inc(com(C10_3)); // Cent(-3, -11);
807-
const Cm20_0 = inc(com(C20_0)); // Cent(0, -20);
808-
809-
enum Cs_3 = Cent(3, I.min);
810-
811-
const Cbig_1 = Cent(0xa3ccac1832952398, 0xc3ac542864f652f8);
812-
const Cbig_2 = Cent(0x5267b85f8a42fc20, 0);
813-
const Cbig_3 = Cent(0xf0000000ffffffff, 0);
791+
const Cent C0 = Zero;
792+
const Cent C1 = One;
793+
const Cent C2 = { lo:2 };
794+
const Cent C3 = { lo:3 };
795+
const Cent C5 = { lo:5 };
796+
const Cent C10 = { lo:10 };
797+
const Cent C20 = { lo:20 };
798+
const Cent C30 = { lo:30 };
799+
const Cent C100 = { lo:100 };
800+
801+
const Cent Cm1 = neg(One);
802+
const Cent Cm3 = neg(C3);
803+
const Cent Cm10 = neg(C10);
804+
805+
const Cent C3_1 = { lo:1, hi:3 };
806+
const Cent C3_2 = { lo:2, hi:3 };
807+
const Cent C4_8 = { lo:8, hi:4 };
808+
const Cent C5_0 = { lo:0, hi:5 };
809+
const Cent C7_1 = { lo:1, hi:7 };
810+
const Cent C7_9 = { lo:9, hi:7 };
811+
const Cent C9_3 = { lo:3, hi:9 };
812+
const Cent C10_0 = { lo:0, hi:10 };
813+
const Cent C10_1 = { lo:1, hi:10 };
814+
const Cent C10_3 = { lo:3, hi:10 };
815+
const Cent C11_3 = { lo:3, hi:11 };
816+
const Cent C20_0 = { lo:0, hi:20 };
817+
const Cent C90_30 = { lo:30, hi:90 };
818+
819+
const Cent Cm10_0 = inc(com(C10_0)); // Cent(lo=0, hi=-10);
820+
const Cent Cm10_1 = inc(com(C10_1)); // Cent(lo=-1, hi=-11);
821+
const Cent Cm10_3 = inc(com(C10_3)); // Cent(lo=-3, hi=-11);
822+
const Cent Cm20_0 = inc(com(C20_0)); // Cent(lo=0, hi=-20);
823+
824+
enum Cent Cs_3 = { lo:3, hi:I.min };
825+
826+
const Cent Cbig_1 = { lo:0xa3ccac1832952398, hi:0xc3ac542864f652f8 };
827+
const Cent Cbig_2 = { lo:0x5267b85f8a42fc20, hi:0 };
828+
const Cent Cbig_3 = { lo:0xf0000000ffffffff, hi:0 };
814829

815830
/************************/
816831

@@ -896,12 +911,20 @@ unittest
896911
assert(div(mul(C90_30, C2), C2) == C90_30);
897912
assert(div(mul(C90_30, C2), C90_30) == C2);
898913

899-
assert(divmod(Cbig_1, Cbig_2, modulus) == Cent(0x4496aa309d4d4a2f, U.max));
900-
assert(modulus == Cent(0xd83203d0fdc799b8, U.max));
901-
assert(udivmod(Cbig_1, Cbig_2, modulus) == Cent(0x5fe0e9bace2bedad, 2));
902-
assert(modulus == Cent(0x2c923125a68721f8, 0));
903-
assert(div(Cbig_1, Cbig_3) == Cent(0xbfa6c02b5aff8b86, U.max));
904-
assert(udiv(Cbig_1, Cbig_3) == Cent(0xd0b7d13b48cb350f, 0));
914+
const Cent Cb1divb2 = { lo:0x4496aa309d4d4a2f, hi:U.max };
915+
const Cent Cb1modb2 = { lo:0xd83203d0fdc799b8, hi:U.max };
916+
assert(divmod(Cbig_1, Cbig_2, modulus) == Cb1divb2);
917+
assert(modulus == Cb1modb2);
918+
919+
const Cent Cb1udivb2 = { lo:0x5fe0e9bace2bedad, hi:2 };
920+
const Cent Cb1umodb2 = { lo:0x2c923125a68721f8, hi:0 };
921+
assert(udivmod(Cbig_1, Cbig_2, modulus) == Cb1udivb2);
922+
assert(modulus == Cb1umodb2);
923+
924+
const Cent Cb1divb3 = { lo:0xbfa6c02b5aff8b86, hi:U.max };
925+
const Cent Cb1udivb3 = { lo:0xd0b7d13b48cb350f, hi:0 };
926+
assert(div(Cbig_1, Cbig_3) == Cb1divb3);
927+
assert(udiv(Cbig_1, Cbig_3) == Cb1udivb3);
905928

906929
assert(mul(Cm10, C1) == Cm10);
907930
assert(mul(C1, Cm10) == Cm10);

0 commit comments

Comments
 (0)