Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite fixresult() for AArch64 #20940

Merged
merged 1 commit into from
Mar 3, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 19 additions & 64 deletions compiler/src/dmd/backend/arm/cod1.d
Original file line number Diff line number Diff line change
Expand Up @@ -1213,6 +1213,11 @@
/******************************
* Given the result of an expression is in retregs,
* generate necessary code to return result in outretregs.
* Params:
* cdb = code sink
* e = expression in retregs
* retregs = expression result is in retregs
* outretregs = registers we want the result in, updated
*/
@trusted
void fixresult(ref CodeBuilder cdb, elem* e, regm_t retregs, ref regm_t outretregs)
Expand All @@ -1221,8 +1226,7 @@
if (outretregs == 0) return; // if don't want result
assert(e && retregs); // need something to work with
regm_t forccs = outretregs & mPSW;
//regm_t forregs = outretregs & (mST01 | mST0 | mBP | ALLREGS | mES | mSTACK | XMMREGS);
regm_t forregs = outretregs & cgstate.allregs;
regm_t forregs = outretregs & (cgstate.allregs | INSTR.FLOATREGS);

Check warning on line 1229 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1229

Added line #L1229 was not covered by tests
tym_t tym = tybasic(e.Ety);

if (tym == TYstruct)
Expand All @@ -1237,85 +1241,36 @@
}
int sz = _tysize[tym];

reg_t reg,rreg;
if ((retregs & forregs) == retregs) // if already in right registers
outretregs = retregs;
else if (forregs) // if return the result in registers
{
bool opsflag = false;
rreg = allocreg(cdb, outretregs, tym); // allocate return regs
if (0 && retregs & XMMREGS) // TODO AArch64
{
reg = findreg(retregs & XMMREGS);
if (mask(rreg) & XMMREGS)
genmovreg(cdb, rreg, reg, tym);
else
{
// MOVSD floatreg, XMM?
cdb.genxmmreg(xmmstore(tym), reg, 0, tym);
// MOV rreg,floatreg
cdb.genfltreg(0x8B,rreg,0);
if (sz == 8)
{
if (I32)
{
rreg = findregmsw(outretregs);
cdb.genfltreg(0x8B, rreg,4);
}
else
code_orrex(cdb.last(),REX_W);
}
}
}
/+ TODO AArch64
else if (forregs & XMMREGS)
if (tyfloating(tym))

Check warning on line 1249 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1249

Added line #L1249 was not covered by tests
{
reg = findreg(retregs & (mBP | ALLREGS));
switch (sz)
{
case 4:
cdb.gen2(LODD, modregxrmx(3, rreg - XMM0, reg)); // MOVD xmm,reg
break;

case 8:
if (I32)
{
cdb.genfltreg(0x89, reg, 0);
reg = findregmsw(retregs);
cdb.genfltreg(0x89, reg, 4);
cdb.genxmmreg(xmmload(tym), rreg, 0, tym); // MOVQ xmm,mem
}
else
{
cdb.gen2(LODD /* [sic!] */, modregxrmx(3, rreg - XMM0, reg));
code_orrex(cdb.last(), REX_W); // MOVQ xmm,reg
}
break;

default:
assert(false);
}
assert(retregs & INSTR.FLOATREGS);
reg_t Vn = findreg(retregs);
reg_t Vd = allocreg(cdb, outretregs, tym); // allocate return regs
uint ftype = INSTR.szToFtype(sz);
cdb.gen1(INSTR.fmov(ftype,Vd,Vn)); // FMOV Vd,Vn

Check warning on line 1255 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1251-L1255

Added lines #L1251 - L1255 were not covered by tests
}
+/
else if (sz > REGSIZE)
{
reg_t msreg = findregmsw(retregs);
reg_t lsreg = findreglsw(retregs);

allocreg(cdb, outretregs, tym); // allocate return regs

Check warning on line 1262 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1262

Added line #L1262 was not covered by tests
reg_t msrreg = findregmsw(outretregs);
reg_t lsrreg = findreglsw(outretregs);

genmovreg(cdb, msrreg, msreg); // MOV msrreg,msreg
genmovreg(cdb, lsrreg, lsreg); // MOV lsrreg,lsreg
cdb.gen1(INSTR.mov_register(sz == 8,msreg,msrreg)); // MOV msrreg,msreg
cdb.gen1(INSTR.mov_register(sz == 8,lsreg,lsrreg)); // MOV lsrreg,lsreg

Check warning on line 1267 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1266-L1267

Added lines #L1266 - L1267 were not covered by tests
}
else
{
assert(!(retregs & XMMREGS));
assert(!(forregs & XMMREGS));
reg = findreg(retregs & cgstate.allregs);
if (sz <= 4)
genmovreg(cdb, rreg, reg, TYint); // only move 32 bits, and zero the top 32 bits
else
genmovreg(cdb, rreg, reg); // MOV rreg,reg
reg_t reg = findreg(retregs & cgstate.allregs);
reg_t rreg = allocreg(cdb, outretregs, tym); // allocate return regs
cdb.gen1(INSTR.mov_register(sz == 8,reg,rreg)); // MOV rreg,reg

Check warning on line 1273 in compiler/src/dmd/backend/arm/cod1.d

View check run for this annotation

Codecov / codecov/patch

compiler/src/dmd/backend/arm/cod1.d#L1271-L1273

Added lines #L1271 - L1273 were not covered by tests
}
cssave(e,retregs | outretregs,opsflag);
// Commented out due to Bugzilla 8840
Expand Down
Loading