Skip to content

Commit 01e70a0

Browse files
authored
add cdpair() for AArch64 (dlang#21466)
1 parent 75e87ab commit 01e70a0

5 files changed

Lines changed: 60 additions & 9 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ void loadea(ref CodeBuilder cdb,elem* e,ref code cs,uint op,reg_t reg,targ_size_
470470
debug
471471
if (debugw)
472472
printf("loadea: e=%p cs=%p op=x%x reg=%s offset=%lld keepmsk=%s desmsk=%s\n",
473-
e, &cs, op, regstring[reg], cast(ulong)offset, regm_str(keepmsk), regm_str(desmsk));
473+
e, &cs, op, regm_str(mask(reg)), cast(ulong)offset, regm_str(keepmsk), regm_str(desmsk));
474474
assert(e);
475475
cs.Iflags = 0;
476476
cs.Iop = op;
@@ -2466,9 +2466,9 @@ void loaddata(ref CodeBuilder cdb, elem* e, ref regm_t outretregs)
24662466
}
24672467
else if (sz <= 2 * REGSIZE)
24682468
{
2469-
reg = findregmsw(forregs);
2469+
reg = findreg(forregs & INSTR.MSW);
24702470
loadea(cdb, e, cs, 0x8B, reg, REGSIZE, forregs, 0); // MOV reg,data+2
2471-
reg = findreglsw(forregs);
2471+
reg = findreg(forregs & INSTR.LSW);
24722472
loadea(cdb, e, cs, 0x8B, reg, 0, forregs, 0); // MOV reg,data
24732473
}
24742474
else if (sz >= 8)

compiler/src/dmd/backend/arm/cod2.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ Extend tyToExtend(tym_t ty)
209209
case 1: extend = UXTB; break;
210210
case 2: extend = UXTH; break;
211211
case 4: extend = UXTW; break;
212+
case 16: // in case TYucent for OPpair/OPrpair
212213
case 8: extend = LSL; break;
213214
default:
214215
assert(0);

compiler/src/dmd/backend/arm/cod4.d

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,7 +1899,7 @@ void cdlngsht(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
18991899
codelem(cgstate,cdb,e.E1,retregs,false);
19001900
bool isOff = e.Eoper == OPoffset;
19011901
if (isOff || e.Eoper == OP128_64)
1902-
retregs &= mLSW; // want LSW only
1902+
retregs &= INSTR.LSW; // want LSW only
19031903
}
19041904
}
19051905

@@ -2012,7 +2012,48 @@ void cdpopcnt(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
20122012
fixresult(cdb,e,retregs,pretregs);
20132013
}
20142014

2015-
// cdpair
2015+
/*******************************************
2016+
* Generate code for OPpair, OPrpair.
2017+
*/
2018+
@trusted
2019+
void cdpair(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
2020+
{
2021+
assert(pretregs);
2022+
2023+
//printf("cdpair(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
2024+
//elem_print(e);
2025+
2026+
regm_t retregs = pretregs;
2027+
2028+
regm_t regs1;
2029+
regm_t regs2;
2030+
2031+
retregs &= cgstate.allregs | INSTR.FLOATREGS;
2032+
if (!retregs)
2033+
retregs = cgstate.allregs | INSTR.FLOATREGS;
2034+
regs1 = retregs & INSTR.LSW;
2035+
regs2 = retregs & INSTR.MSW;
2036+
2037+
if (e.Eoper == OPrpair)
2038+
{
2039+
// swap
2040+
regs1 ^= regs2;
2041+
regs2 ^= regs1;
2042+
regs1 ^= regs2;
2043+
}
2044+
//printf("1: regs1 = %s, regs2 = %s\n", regm_str(regs1), regm_str(regs2));
2045+
2046+
codelem(cgstate,cdb,e.E1, regs1, false);
2047+
scodelem(cgstate,cdb,e.E2, regs2, regs1, false);
2048+
2049+
if (e.E1.Ecount)
2050+
getregs(cdb,regs1);
2051+
if (e.E2.Ecount)
2052+
getregs(cdb,regs2);
2053+
2054+
fixresult(cdb,e,regs1 | regs2,pretregs);
2055+
}
2056+
20162057
// cdcmpxchg
20172058
// cdprefetch
20182059
// opAssLoadReg

compiler/src/dmd/backend/arm/instr.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ struct INSTR
4545
enum FLOATREGS = 0x01FF_FFFF_0000_0000;
4646
static assert((FLOATREGS & (1UL << 57 /*REGMAX*/)) == 0);
4747

48+
/* most and least significant register masks
49+
*/
50+
enum LSW = 0x5555_5555_5555_5555;
51+
enum MSW = LSW << 1;
52+
4853
enum uint nop = 0xD503201F;
4954

5055
alias reg_t = ubyte;

compiler/src/dmd/backend/x86/cod4.d

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4658,10 +4658,14 @@ void cdpair(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
46584658
return;
46594659
}
46604660

4661-
assert(!cg.AArch64);
4662-
//printf("\ncdpair(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
4663-
//WRTYxx(e.Ety);printf("\n");
4664-
//printf("Ecount = %d\n", e.Ecount);
4661+
if (cg.AArch64)
4662+
{
4663+
import dmd.backend.arm.cod4 : cdpair;
4664+
return cdpair(cg, cdb, e, pretregs);
4665+
}
4666+
4667+
//printf("cdpair(e = %p, pretregs = %s)\n", e, regm_str(pretregs));
4668+
//elem_print(e);
46654669

46664670
regm_t retregs = pretregs;
46674671
if (retregs == mPSW && tycomplex(e.Ety) && config.inline8087)

0 commit comments

Comments
 (0)