Skip to content

Commit b2926b6

Browse files
authored
detail optimize switch compares (dlang#21163)
1 parent a03aa27 commit b2926b6

File tree

1 file changed

+18
-8
lines changed
  • compiler/src/dmd/backend/x86

1 file changed

+18
-8
lines changed

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,18 +1598,28 @@ struct CaseVal
15981598
* Generate comparison of [reg2,reg] with val
15991599
*/
16001600
@trusted
1601-
private void cmpval(CGstate cg, ref CodeBuilder cdb, targ_llong val, uint sz, reg_t reg, reg_t reg2, reg_t sreg)
1601+
private void cmpval(CGstate cg, ref CodeBuilder cdb, ulong val, uint sz, reg_t reg, reg_t reg2, reg_t sreg)
16021602
{
16031603
if (cg.AArch64)
16041604
{
1605-
// TODO AArch64 use CMP https://www.scs.stanford.edu/~zyedidia/arm64/cmp_subs_addsub_imm.html
16061605
assert(sreg == NOREG);
1607-
regm_t retregs = cg.allregs & ~mask(reg);
1608-
sreg = allocreg(cdb,retregs,TYint);
1609-
movregconst(cdb,sreg,val,sz == 8 ? 64 : 0);
1610-
getregsNoSave(retregs);
1611-
assert(reg2 == NOREG);
1612-
cdb.gen1(INSTR.cmp_shift(sz == 8, reg, 0, 0, sreg)); // CMP sreg,reg
1606+
if (val <= 0xFFF || val >= 0x1000 && val <= 0xFFF000)
1607+
{
1608+
ubyte sh = val >= 0x1000;
1609+
uint imm12 = cast(uint)(sh ? val >> 12 : val);
1610+
assert((imm12 & ~0xFFF) == 0);
1611+
// https://www.scs.stanford.edu/~zyedidia/arm64/cmp_subs_addsub_imm.html
1612+
cdb.gen1(INSTR.cmp_imm(sz == 8, sh, imm12, reg)); // CMP reg,#imm12{, shift}
1613+
}
1614+
else
1615+
{
1616+
regm_t retregs = cg.allregs & ~mask(reg);
1617+
sreg = allocreg(cdb,retregs,TYint);
1618+
movregconst(cdb,sreg,val,sz == 8 ? 64 : 0);
1619+
getregsNoSave(retregs);
1620+
assert(reg2 == NOREG);
1621+
cdb.gen1(INSTR.cmp_shift(sz == 8, reg, 0, 0, sreg)); // CMP sreg,reg
1622+
}
16131623
}
16141624
else if (I64 && sz == 8)
16151625
{

0 commit comments

Comments
 (0)