diff options
author | Aaron Patterson <[email protected]> | 2022-11-14 16:15:50 -0800 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2022-11-14 17:04:50 -0800 |
commit | e74d82f67447d10347b154d5e9b098397e80567c (patch) | |
tree | 5c4f325ac6969f54e6010dd83dc76c8df24672bb | |
parent | 9228ae97c5f4e27a3bd534d4b40c6f390cb8aaac (diff) |
Implement LDURH on Aarch64
When RUBY_DEBUG is enabled, shape ids are 16 bits. I would like to do
16 bit comparisons, so I need to load halfwords sometimes. This commit
adds LDURH so that I can load halfwords.
https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/LDURH--Load-Register-Halfword--unscaled--?lang=en
I verified the bytes using clang:
```
$ cat asmthing.s
.global _start
.align 2
_start:
ldurh w10, [x1]
ldurh w10, [x1, #123]
$ as asmthing.s -o asmthing.o && objdump --disassemble asmthing.o
asmthing.o: file format mach-o arm64
Disassembly of section __TEXT,__text:
0000000000000000 <ltmp0>:
0: 2a 00 40 78 ldurh w10, [x1]
4: 2a b0 47 78 ldurh w10, [x1, #123]
```
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6729
-rw-r--r-- | yjit/src/asm/arm64/inst/load_store.rs | 14 | ||||
-rw-r--r-- | yjit/src/asm/arm64/mod.rs | 22 |
2 files changed, 36 insertions, 0 deletions
diff --git a/yjit/src/asm/arm64/inst/load_store.rs b/yjit/src/asm/arm64/inst/load_store.rs index e877c6de77..d08398380a 100644 --- a/yjit/src/asm/arm64/inst/load_store.rs +++ b/yjit/src/asm/arm64/inst/load_store.rs @@ -3,6 +3,7 @@ use super::super::arg::truncate_imm; /// The size of the operands being operated on. enum Size { Size8 = 0b00, + Size16 = 0b01, Size32 = 0b10, Size64 = 0b11, } @@ -82,6 +83,12 @@ impl LoadStore { Self { rt, rn, idx: Index::None, imm9, opc: Opc::LDR, size: num_bits.into() } } + /// LDURH Load Register Halfword (unscaled) + /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/LDURH--Load-Register-Halfword--unscaled--?lang=en + pub fn ldurh(rt: u8, rn: u8, imm9: i16) -> Self { + Self { rt, rn, idx: Index::None, imm9, opc: Opc::LDR, size: Size::Size16 } + } + /// LDURB (load register, byte, unscaled) /// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/LDURB--Load-Register-Byte--unscaled--?lang=en pub fn ldurb(rt: u8, rn: u8, imm9: i16) -> Self { @@ -172,6 +179,13 @@ mod tests { } #[test] + fn test_ldurh() { + let inst = LoadStore::ldurh(0, 1, 0); + let result: u32 = inst.into(); + assert_eq!(0x78400020, result); + } + + #[test] fn test_ldur_with_imm() { let inst = LoadStore::ldur(0, 1, 123, 64); let result: u32 = inst.into(); diff --git a/yjit/src/asm/arm64/mod.rs b/yjit/src/asm/arm64/mod.rs index e5697e26fb..683711259e 100644 --- a/yjit/src/asm/arm64/mod.rs +++ b/yjit/src/asm/arm64/mod.rs @@ -536,6 +536,22 @@ pub fn ldur(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) { cb.write_bytes(&bytes); } +/// LDURH - load a byte from memory, zero-extend it, and write it to a register +pub fn ldurh(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) { + let bytes: [u8; 4] = match (rt, rn) { + (A64Opnd::Reg(rt), A64Opnd::Mem(rn)) => { + assert!(rt.num_bits == 32, "Rt should be a 32 bit register"); + assert!(rn.num_bits == 64, "Rn should be a 64 bit register"); + assert!(mem_disp_fits_bits(rn.disp), "Expected displacement to be 9 bits or less"); + + LoadStore::ldurh(rt.reg_no, rn.base_reg_no, rn.disp as i16).into() + }, + _ => panic!("Invalid operands for LDURH") + }; + + cb.write_bytes(&bytes); +} + /// LDURB - load a byte from memory, zero-extend it, and write it to a register pub fn ldurb(cb: &mut CodeBlock, rt: A64Opnd, rn: A64Opnd) { let bytes: [u8; 4] = match (rt, rn) { @@ -1310,6 +1326,12 @@ mod tests { } #[test] + fn test_ldurh_memory() { + check_bytes("2a004078", |cb| ldurh(cb, W10, A64Opnd::new_mem(64, X1, 0))); + check_bytes("2ab04778", |cb| ldurh(cb, W10, A64Opnd::new_mem(64, X1, 123))); + } + + #[test] fn test_ldur_memory() { check_bytes("20b047f8", |cb| ldur(cb, X0, A64Opnd::new_mem(64, X1, 123))); } |