@@ -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