Skip to content

Commit

Permalink
write_rm_multi implementation for uimm (ruby#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Feb 11, 2022
1 parent 6def931 commit a5443b8
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
27 changes: 26 additions & 1 deletion yjit/src/asm/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ fn write_rm(cb: &mut CodeBlock, sz_pref: bool, rex_w: bool, r_opnd: X86Opnd, rm_

// Add the operand-size prefix, if needed
if sz_pref {
cb.write_byte(0x66)
cb.write_byte(0x66);
}

// Add the REX prefix, if needed
Expand Down Expand Up @@ -822,6 +822,7 @@ fn write_rm_multi(cb: &mut CodeBlock, op_mem_reg8: u8, op_mem_reg_pref: u8, op_r
X86Opnd::Reg(reg) => assert!(reg.num_bits == opnd_size),
X86Opnd::Mem(mem) => assert!(mem.num_bits == opnd_size),
X86Opnd::Imm(imm) => assert!(imm.num_bits <= opnd_size),
X86Opnd::UImm(uimm) => assert!(uimm.num_bits <= opnd_size),
_ => ()
};

Expand Down Expand Up @@ -867,6 +868,30 @@ fn write_rm_multi(cb: &mut CodeBlock, op_mem_reg8: u8, op_mem_reg_pref: u8, op_r
panic!("immediate value too large");
}
},
// R/M + UImm
(_, X86Opnd::UImm(uimm)) => {
let num_bits = sig_imm_size(uimm.value.try_into().unwrap());

if num_bits <= 8 {
// 8-bit immediate

if opnd_size == 8 {
write_rm(cb, false, false, X86Opnd::None, opnd0, op_ext_imm, 1, &[op_mem_imm8]);
} else {
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, op_ext_imm, 1, &[op_mem_imm_sml]);
}

cb.write_int(uimm.value, 8);
} else if num_bits <= 32 {
// 32-bit immediate

assert!(num_bits <= opnd_size);
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, op_ext_imm, 1, &[op_mem_imm_lrg]);
cb.write_int(uimm.value, if opnd_size > 32 { 32 } else { opnd_size.into() });
} else {
panic!("immediate value too large");
}
},
_ => unreachable!()
};
}
Expand Down
19 changes: 19 additions & 0 deletions yjit/src/asm/x86_64/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ fn test_add() {
check_bytes("81c1ff000000", |cb| add(cb, ECX, imm_opnd(255)));
}

#[test]
fn test_add_unsigned() {
// ADD r/m8, imm8
check_bytes("4180c001", |cb| add(cb, R8B, uimm_opnd(1)));
check_bytes("4180c07f", |cb| add(cb, R8B, imm_opnd(i8::MAX.try_into().unwrap())));

// ADD r/m16, imm16
check_bytes("664183c001", |cb| add(cb, R8W, uimm_opnd(1)));
check_bytes("664181c0ff7f", |cb| add(cb, R8W, uimm_opnd(i16::MAX.try_into().unwrap())));

// ADD r/m32, imm32
check_bytes("4183c001", |cb| add(cb, R8D, uimm_opnd(1)));
check_bytes("4181c0ffffff7f", |cb| add(cb, R8D, uimm_opnd(i32::MAX.try_into().unwrap())));

// ADD r/m64, imm32
check_bytes("4983c001", |cb| add(cb, R8, uimm_opnd(1)));
check_bytes("4981c0ffffff7f", |cb| add(cb, R8, uimm_opnd(i32::MAX.try_into().unwrap())));
}

#[test]
fn test_and() {
check_bytes("4421e5", |cb| and(cb, EBP, R12D));
Expand Down

0 comments on commit a5443b8

Please sign in to comment.