@@ -506,65 +506,73 @@ ExtMulResult!U extMul(U)(in U a, in U b) @nogc nothrow pure @safe
506506
507507 enum hbc = H.sizeof * 8 ;
508508
509- if (! __ctfe )
509+ static if (is (U == ulong ) && __traits(compiles, ucent .init) )
510510 {
511- version (LDC )
511+ auto ret = ucent (a) * b;
512+ return typeof (return )(cast (ulong ) ret, cast (ulong )(ret >>> 64 ));
513+ }
514+ else
515+ {
516+ if (! __ctfe)
512517 {
513- // LLVM IR by n8sh
514- pragma (inline, true );
515- static if (is (U == ulong ))
518+ version (LDC )
516519 {
517- auto r = inlineIR! (`
518- %a = zext i64 %0 to i128
519- %b = zext i64 %1 to i128
520- %m = mul i128 %a, %b
521- %n = lshr i128 %m, 64
522- %h = trunc i128 %n to i64
523- %l = trunc i128 %m to i64
524- %agg1 = insertvalue [2 x i64] undef, i64 %l, 0
525- %agg2 = insertvalue [2 x i64] %agg1, i64 %h, 1
526- ret [2 x i64] %agg2` , ulong [2 ])(a, b);
520+ // LLVM IR by n8sh
521+ pragma (inline, true );
522+ static if (is (U == ulong ))
523+ {
524+ auto r = inlineIR! (`
525+ %a = zext i64 %0 to i128
526+ %b = zext i64 %1 to i128
527+ %m = mul i128 %a, %b
528+ %n = lshr i128 %m, 64
529+ %h = trunc i128 %n to i64
530+ %l = trunc i128 %m to i64
531+ %agg1 = insertvalue [2 x i64] undef, i64 %l, 0
532+ %agg2 = insertvalue [2 x i64] %agg1, i64 %h, 1
533+ ret [2 x i64] %agg2` , ulong [2 ])(a, b);
534+ }
535+ else
536+ {
537+ auto r = inlineIR! (`
538+ %a = zext i128 %0 to i256
539+ %b = zext i128 %1 to i256
540+ %m = mul i256 %a, %b
541+ %n = lshr i256 %m, 128
542+ %h = trunc i256 %n to i128
543+ %l = trunc i256 %m to i128
544+ %agg1 = insertvalue [2 x i128] undef, i128 %l, 0
545+ %agg2 = insertvalue [2 x i128] %agg1, i128 %h, 1
546+ ret [2 x i128] %agg2` , ucent [2 ])(a, b);
547+ }
548+ return ExtMulResult! U(r[0 ], r[1 ]);
527549 }
528550 else
551+ version (D_InlineAsm_X86_64 )
529552 {
530- auto r = inlineIR! (`
531- %a = zext i128 %0 to i256
532- %b = zext i128 %1 to i256
533- %m = mul i256 %a, %b
534- %n = lshr i256 %m, 128
535- %h = trunc i256 %n to i128
536- %l = trunc i256 %m to i128
537- %agg1 = insertvalue [2 x i128] undef, i128 %l, 0
538- %agg2 = insertvalue [2 x i128] %agg1, i128 %h, 1
539- ret [2 x i128] %agg2` , ucent [2 ])(a, b);
540- }
541- return ExtMulResult! U(r[0 ], r[1 ]);
542- }
543- else
544- version (D_InlineAsm_X86_64 )
545- {
546- static if (is (U == ulong ))
547- {
548- return extMul_X86_64 (a, b);
553+ static if (is (U == ulong ) && ! is (ucent ))
554+ {
555+ return extMul_X86_64 (a, b);
556+ }
549557 }
550558 }
551- }
552559
553- U al = cast (H)a;
554- U ah = a >>> hbc;
555- U bl = cast (H)b;
556- U bh = b >>> hbc;
560+ U al = cast (H)a;
561+ U ah = a >>> hbc;
562+ U bl = cast (H)b;
563+ U bh = b >>> hbc;
557564
558- U p0 = al * bl;
559- U p1 = al * bh;
560- U p2 = ah * bl;
561- U p3 = ah * bh;
565+ U p0 = al * bl;
566+ U p1 = al * bh;
567+ U p2 = ah * bl;
568+ U p3 = ah * bh;
562569
563- H cy = cast (H)(((p0 >>> hbc) + cast (H)p1 + cast (H)p2) >>> hbc);
564- U lo = p0 + (p1 << hbc) + (p2 << hbc);
565- U hi = p3 + (p1 >>> hbc) + (p2 >>> hbc) + cy;
570+ H cy = cast (H)(((p0 >>> hbc) + cast (H)p1 + cast (H)p2) >>> hbc);
571+ U lo = p0 + (p1 << hbc) + (p2 << hbc);
572+ U hi = p3 + (p1 >>> hbc) + (p2 >>> hbc) + cy;
566573
567- return typeof (return )(lo, hi);
574+ return typeof (return )(lo, hi);
575+ }
568576}
569577
570578unittest
0 commit comments