Skip to content

Commit f3df9ef

Browse files
n8sh9il
authored andcommitted
Restore non-LDC X86_64 assembly code in extMul
Was previously removed: #106 Changing the return type of the helper function from a struct to ulong[2] was the key to make the Windows 64 version stop crashing. Also updated the unit test to verify that the multiplication has the correct result.
1 parent a65fb47 commit f3df9ef

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

source/mir/utility.d

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,22 @@ ExtMulResult!U extMul(U)(in U a, in U b) @nogc nothrow pure @safe
554554
return ExtMulResult!U(r[0], r[1]);
555555
}
556556
}
557+
else
558+
version(D_InlineAsm_X86_64)
559+
{
560+
static if (is(U == ulong))
561+
{
562+
version(Windows)
563+
{
564+
ulong[2] r = extMul_X86_64(a, b);
565+
return ExtMulResult!ulong(r[0], r[1]);
566+
}
567+
else
568+
{
569+
return extMul_X86_64(a, b);
570+
}
571+
}
572+
}
557573
}
558574

559575
U al = cast(H)a;
@@ -581,4 +597,52 @@ unittest
581597
immutable b = 0x54_c3_2f_e8_cc_a5_97_10;
582598
enum c = extMul(a, b); // Compile time algorithm
583599
assert(extMul(a, b) == c); // Fast runtime algorihtm
600+
static assert(c.high == 0x30_da_d1_42_95_4a_50_78);
601+
static assert(c.low == 0x27_9b_4b_b4_9e_fe_0f_60);
602+
}
603+
604+
version(D_InlineAsm_X86_64)
605+
{
606+
version(Windows)
607+
private ulong[2] extMul_X86_64()(ulong a, ulong b)
608+
{
609+
asm @safe pure nothrow @nogc
610+
{
611+
naked;
612+
mov RAX, RCX;
613+
mul RDX;
614+
ret;
615+
}
616+
}
617+
else
618+
private ExtMulResult!ulong extMul_X86_64()(ulong a, ulong b)
619+
{
620+
asm @safe pure nothrow @nogc
621+
{
622+
naked;
623+
mov RAX, RDI;
624+
mul RSI;
625+
ret;
626+
}
627+
}
628+
}
629+
630+
version(LDC) {} else version(D_InlineAsm_X86_64)
631+
@nogc nothrow pure @safe unittest
632+
{
633+
immutable a = 0x93_8d_28_00_0f_50_a5_56;
634+
immutable b = 0x54_c3_2f_e8_cc_a5_97_10;
635+
636+
version(Windows)
637+
{
638+
immutable ulong[2] r = extMul_X86_64(a, b);
639+
immutable ExtMulResult!ulong c = ExtMulResult!ulong(r[0], r[1]);
640+
}
641+
else
642+
{
643+
immutable ExtMulResult!ulong c = extMul_X86_64(a, b);
644+
}
645+
646+
assert(c.high == 0x30_da_d1_42_95_4a_50_78);
647+
assert(c.low == 0x27_9b_4b_b4_9e_fe_0f_60);
584648
}

0 commit comments

Comments
 (0)