Skip to content

Commit aa94684

Browse files
Merge pull request #10247 from marler8997/8087stack
Fix issue 20089: Handle extra case in fixresult_complex87
2 parents 0f6c2e2 + c4b00f8 commit aa94684

3 files changed

Lines changed: 101 additions & 5 deletions

File tree

src/dmd/backend/cg87.d

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,6 +3646,20 @@ void fixresult_complex87(ref CodeBuilder cdb,elem *e,regm_t retregs,regm_t *pret
36463646
cdb.genf2(0xDD,modregrm(3,3,0)); // FPOP
36473647
pop87();
36483648
}
3649+
else if (tym == TYllong)
3650+
{
3651+
// passing cfloat through register for I64
3652+
assert(retregs & mST01, "this float expression is not implemented");
3653+
pop87();
3654+
cdb.genfltreg(ESC(MFfloat,1),BX,4); // FSTP floatreg
3655+
pop87();
3656+
cdb.genfltreg(ESC(MFfloat,1),BX,0); // FSTP floatreg+4
3657+
genfwait(cdb);
3658+
const reg = findreg(*pretregs);
3659+
getregs(cdb,reg);
3660+
cdb.genfltreg(LOD, reg, 0); // MOV ECX,floatreg
3661+
code_orrex(cdb.last(), REX_W); // extend to RCX
3662+
}
36493663
else if (tym == TYcfloat && *pretregs & (mAX|mDX) && retregs & mST01)
36503664
{
36513665
if (*pretregs & mPSW && !(retregs & mPSW))

src/dmd/backend/cod2.d

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,8 @@ void cdmul(ref CodeBuilder cdb,elem *e,regm_t *pretregs)
924924
config.fpxmmregs && oper != OPmod && tyxmmreg(tyml) &&
925925
!(*pretregs & mST0) &&
926926
!(ty == TYldouble || ty == TYildouble) && // watch out for shrinkLongDoubleConstantIfPossible()
927-
!tycomplex(ty) // SIMD code is not set up to deal with complex mul/div
927+
!tycomplex(ty) && // SIMD code is not set up to deal with complex mul/div
928+
!(ty == TYllong) // or passing to function through integer register
928929
)
929930
{
930931
orthxmm(cdb,e,pretregs);

test/runnable/test18772.d

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,94 @@
1-
float fun(cfloat z)
1+
float getreal_rcx(cfloat z)
22
{
33
return z.re;
44
}
5+
float getimag_rcx(cfloat z)
6+
{
7+
return z.im;
8+
}
59

6-
void main()
10+
float getreal_rdx(cfloat z, int)
11+
{
12+
return z.re;
13+
}
14+
float getimag_rdx(cfloat z, int)
15+
{
16+
return z.im;
17+
}
18+
19+
float getreal_r8(cfloat z, int, int)
20+
{
21+
return z.re;
22+
}
23+
float getimag_r8(cfloat z, int, int)
24+
{
25+
return z.im;
26+
}
27+
28+
float getreal_r9(cfloat z, int, int, int)
29+
{
30+
return z.re;
31+
}
32+
float getimag_r9(cfloat z, int, int, int)
33+
{
34+
return z.im;
35+
}
36+
37+
float getreal_stack(cfloat z, int, int, int, int)
38+
{
39+
return z.re;
40+
}
41+
float getimag_stack(cfloat z, int, int, int, int)
42+
{
43+
return z.im;
44+
}
45+
46+
void test18772()
747
{
848
cfloat[1] A;
949
float[1] B;
1050
int i = 0;
11-
version(D_LP64) {} else // disabled because of wrong codegen: https://issues.dlang.org/show_bug.cgi?id=20089
12-
double C = fun(A[i] * B[i]);
51+
A[0] = 2.0f + 4i;
52+
B[0] = 3.0f;
53+
assert(6.0 == getreal_rcx(A[i] * B[i]));
54+
assert(12.0 == getimag_rcx(A[i] * B[i]));
55+
56+
assert(6.0 == getreal_rdx(A[i] * B[i], 1));
57+
assert(12.0 == getimag_rdx(A[i] * B[i], 1));
58+
59+
assert(6.0 == getreal_r8(A[i] * B[i], 1, 2));
60+
assert(12.0 == getimag_r8(A[i] * B[i], 1, 2));
61+
62+
assert(6.0 == getreal_r9(A[i] * B[i], 1, 2, 3));
63+
assert(12.0 == getimag_r9(A[i] * B[i], 1, 2, 3));
64+
65+
assert(6.0 == getreal_stack(A[i] * B[i], 1, 2, 3, 4));
66+
assert(12.0 == getimag_stack(A[i] * B[i], 1, 2, 3, 4));
67+
}
68+
69+
void test(T)()
70+
{
71+
static auto getre0(T z)
72+
{
73+
return z.re;
74+
}
75+
static auto getim0(T z)
76+
{
77+
return z.im;
78+
}
79+
80+
T z = 3 + 4i;
81+
auto d = z.re;
82+
83+
assert(getre0(d * z) == d * 3);
84+
assert(getim0(d * z) == d * 4);
85+
}
86+
87+
void main()
88+
{
89+
test18772();
90+
91+
test!cfloat();
92+
test!cdouble();
93+
test!creal();
1394
}

0 commit comments

Comments
 (0)