Skip to content

Commit

Permalink
YJIT: A64: Use ADDS/SUBS/CMP (immediate) when possible
Browse files Browse the repository at this point in the history
We were loading 1 into a register and then doing ADDS/SUBS previously.
That was particularly bad since those come up in fixnum operations.

```diff
   # integer left shift with rhs=1
-  mov x11, #1
-  subs x11, x1, x11
+  subs x11, x1, #1
   lsl x12, x11, #1
   asr x13, x12, #1
   cmp x13, x11
-  b.ne #0x106ab60f8
-  mov x11, #1
-  adds x12, x12, x11
+  b.ne #0x10903a0f8
+  adds x12, x12, #1
   mov x1, x12
```

Note that it's fine to cast between i64 and u64 since the bit pattern is
preserved, and the add/sub themselves don't care about the signedness of
the operands.

CMP is just another mnemonic for SUBS.
  • Loading branch information
XrXr committed Mar 28, 2024
1 parent f3c3574 commit 11e2f63
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
3 changes: 3 additions & 0 deletions yjit/src/asm/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ pub fn cmp(cb: &mut CodeBlock, rn: A64Opnd, rm: A64Opnd) {

DataReg::cmp(rn.reg_no, rm.reg_no, rn.num_bits).into()
},
(A64Opnd::Reg(rn), A64Opnd::Imm(imm12)) => {
DataImm::cmp(rn.reg_no, (imm12 as u64).try_into().unwrap(), rn.num_bits).into()
},
(A64Opnd::Reg(rn), A64Opnd::UImm(imm12)) => {
DataImm::cmp(rn.reg_no, imm12.try_into().unwrap(), rn.num_bits).into()
},
Expand Down
22 changes: 21 additions & 1 deletion yjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,11 @@ impl Assembler
match opnd {
Opnd::Reg(_) | Opnd::CArg(_) | Opnd::InsnOut { .. } => opnd,
Opnd::Mem(_) => split_load_operand(asm, opnd),
Opnd::Imm(_) => asm.load(opnd),
Opnd::Imm(imm) => if ShiftedImmediate::try_from(imm as u64).is_ok() {
opnd
} else {
asm.load(opnd)
}
Opnd::UImm(uimm) => {
if ShiftedImmediate::try_from(uimm).is_ok() {
opnd
Expand Down Expand Up @@ -1704,4 +1708,20 @@ mod tests {
0x8: csel x1, x11, x12, lt
"});
}

#[test]
fn test_add_with_immediate() {
let (mut asm, mut cb) = setup_asm();

let out = asm.add(Opnd::Reg(TEMP_REGS[1]), 1.into());
let out = asm.add(out, 1_usize.into());
asm.mov(Opnd::Reg(TEMP_REGS[0]), out);
asm.compile_with_num_regs(&mut cb, 2);

assert_disasm!(cb, "2b0500b16b0500b1e1030baa", {"
0x0: adds x11, x9, #1
0x4: adds x11, x11, #1
0x8: mov x1, x11
"});
}
}

0 comments on commit 11e2f63

Please sign in to comment.