Skip to content

Commit afbe0d7

Browse files
committed
update extMul
1 parent 1a0f5a5 commit afbe0d7

File tree

1 file changed

+55
-47
lines changed

1 file changed

+55
-47
lines changed

source/mir/utility.d

Lines changed: 55 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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

570578
unittest

0 commit comments

Comments
 (0)