From b2926b6b2a884b8f283b3756122fe9513b1ac8ae Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Sun, 6 Apr 2025 23:09:34 -0700 Subject: [PATCH] detail optimize switch compares (#21163) --- compiler/src/dmd/backend/x86/cod3.d | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/compiler/src/dmd/backend/x86/cod3.d b/compiler/src/dmd/backend/x86/cod3.d index 42ed8f1f39..3ccea8eb6e 100644 --- a/compiler/src/dmd/backend/x86/cod3.d +++ b/compiler/src/dmd/backend/x86/cod3.d @@ -1598,18 +1598,28 @@ struct CaseVal * Generate comparison of [reg2,reg] with val */ @trusted -private void cmpval(CGstate cg, ref CodeBuilder cdb, targ_llong val, uint sz, reg_t reg, reg_t reg2, reg_t sreg) +private void cmpval(CGstate cg, ref CodeBuilder cdb, ulong val, uint sz, reg_t reg, reg_t reg2, reg_t sreg) { if (cg.AArch64) { - // TODO AArch64 use CMP https://www.scs.stanford.edu/~zyedidia/arm64/cmp_subs_addsub_imm.html assert(sreg == NOREG); - regm_t retregs = cg.allregs & ~mask(reg); - sreg = allocreg(cdb,retregs,TYint); - movregconst(cdb,sreg,val,sz == 8 ? 64 : 0); - getregsNoSave(retregs); - assert(reg2 == NOREG); - cdb.gen1(INSTR.cmp_shift(sz == 8, reg, 0, 0, sreg)); // CMP sreg,reg + if (val <= 0xFFF || val >= 0x1000 && val <= 0xFFF000) + { + ubyte sh = val >= 0x1000; + uint imm12 = cast(uint)(sh ? val >> 12 : val); + assert((imm12 & ~0xFFF) == 0); + // https://www.scs.stanford.edu/~zyedidia/arm64/cmp_subs_addsub_imm.html + cdb.gen1(INSTR.cmp_imm(sz == 8, sh, imm12, reg)); // CMP reg,#imm12{, shift} + } + else + { + regm_t retregs = cg.allregs & ~mask(reg); + sreg = allocreg(cdb,retregs,TYint); + movregconst(cdb,sreg,val,sz == 8 ? 64 : 0); + getregsNoSave(retregs); + assert(reg2 == NOREG); + cdb.gen1(INSTR.cmp_shift(sz == 8, reg, 0, 0, sreg)); // CMP sreg,reg + } } else if (I64 && sz == 8) {