зеркало из https://github.com/github/ruby.git
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] ```
This commit is contained in:
Родитель
9228ae97c5
Коммит
e74d82f674
|
@ -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 {
|
||||
|
@ -171,6 +178,13 @@ mod tests {
|
|||
assert_eq!(0x38400020, result);
|
||||
}
|
||||
|
||||
#[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);
|
||||
|
|
|
@ -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) {
|
||||
|
@ -1309,6 +1325,12 @@ mod tests {
|
|||
check_bytes("6ac54078", |cb| ldrh_post(cb, W10, A64Opnd::new_mem(64, X11, 12)));
|
||||
}
|
||||
|
||||
#[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)));
|
||||
|
|
Загрузка…
Ссылка в новой задаче