зеркало из https://github.com/github/ruby.git
YJIT: expand bitwise shift support in x86 assembler (#8174)
This commit is contained in:
Родитель
c4066af35e
Коммит
8d7861e3da
|
@ -1223,8 +1223,8 @@ pub fn ret(cb: &mut CodeBlock) {
|
||||||
cb.write_byte(0xC3);
|
cb.write_byte(0xC3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a single-operand shift instruction
|
// Encode a bitwise shift instruction
|
||||||
fn write_shift(cb: &mut CodeBlock, op_mem_one_pref: u8, _op_mem_cl_pref: u8, op_mem_imm_pref: u8, op_ext: Option<u8>, opnd0: X86Opnd, opnd1: X86Opnd) {
|
fn write_shift(cb: &mut CodeBlock, op_mem_one_pref: u8, op_mem_cl_pref: u8, op_mem_imm_pref: u8, op_ext: u8, opnd0: X86Opnd, opnd1: X86Opnd) {
|
||||||
assert!(matches!(opnd0, X86Opnd::Reg(_) | X86Opnd::Mem(_)));
|
assert!(matches!(opnd0, X86Opnd::Reg(_) | X86Opnd::Mem(_)));
|
||||||
|
|
||||||
// Check the size of opnd0
|
// Check the size of opnd0
|
||||||
|
@ -1234,16 +1234,26 @@ fn write_shift(cb: &mut CodeBlock, op_mem_one_pref: u8, _op_mem_cl_pref: u8, op_
|
||||||
let sz_pref = opnd_size == 16;
|
let sz_pref = opnd_size == 16;
|
||||||
let rex_w = opnd_size == 64;
|
let rex_w = opnd_size == 64;
|
||||||
|
|
||||||
if let X86Opnd::UImm(imm) = opnd1 {
|
match opnd1 {
|
||||||
if imm.value == 1 {
|
X86Opnd::UImm(imm) => {
|
||||||
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, op_ext, &[op_mem_one_pref]);
|
if imm.value == 1 {
|
||||||
} else {
|
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, Some(op_ext), &[op_mem_one_pref]);
|
||||||
assert!(imm.num_bits <= 8);
|
} else {
|
||||||
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, op_ext, &[op_mem_imm_pref]);
|
assert!(imm.num_bits <= 8);
|
||||||
cb.write_byte(imm.value as u8);
|
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, Some(op_ext), &[op_mem_imm_pref]);
|
||||||
|
cb.write_byte(imm.value as u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
X86Opnd::Reg(reg) => {
|
||||||
|
// We can only use CL/RCX as the shift amount
|
||||||
|
assert!(reg.reg_no == RCX_REG.reg_no);
|
||||||
|
write_rm(cb, sz_pref, rex_w, X86Opnd::None, opnd0, Some(op_ext), &[op_mem_cl_pref]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
unreachable!();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
unreachable!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1254,7 +1264,7 @@ pub fn sal(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
|
||||||
0xD1, // opMemOnePref,
|
0xD1, // opMemOnePref,
|
||||||
0xD3, // opMemClPref,
|
0xD3, // opMemClPref,
|
||||||
0xC1, // opMemImmPref,
|
0xC1, // opMemImmPref,
|
||||||
Some(0x04),
|
0x04,
|
||||||
opnd0,
|
opnd0,
|
||||||
opnd1
|
opnd1
|
||||||
);
|
);
|
||||||
|
@ -1267,7 +1277,7 @@ pub fn sar(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
|
||||||
0xD1, // opMemOnePref,
|
0xD1, // opMemOnePref,
|
||||||
0xD3, // opMemClPref,
|
0xD3, // opMemClPref,
|
||||||
0xC1, // opMemImmPref,
|
0xC1, // opMemImmPref,
|
||||||
Some(0x07),
|
0x07,
|
||||||
opnd0,
|
opnd0,
|
||||||
opnd1
|
opnd1
|
||||||
);
|
);
|
||||||
|
@ -1280,7 +1290,7 @@ pub fn shl(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
|
||||||
0xD1, // opMemOnePref,
|
0xD1, // opMemOnePref,
|
||||||
0xD3, // opMemClPref,
|
0xD3, // opMemClPref,
|
||||||
0xC1, // opMemImmPref,
|
0xC1, // opMemImmPref,
|
||||||
Some(0x04),
|
0x04,
|
||||||
opnd0,
|
opnd0,
|
||||||
opnd1
|
opnd1
|
||||||
);
|
);
|
||||||
|
@ -1293,7 +1303,7 @@ pub fn shr(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
|
||||||
0xD1, // opMemOnePref,
|
0xD1, // opMemOnePref,
|
||||||
0xD3, // opMemClPref,
|
0xD3, // opMemClPref,
|
||||||
0xC1, // opMemImmPref,
|
0xC1, // opMemImmPref,
|
||||||
Some(0x05),
|
0x05,
|
||||||
opnd0,
|
opnd0,
|
||||||
opnd1
|
opnd1
|
||||||
);
|
);
|
||||||
|
|
|
@ -340,6 +340,7 @@ fn test_sal() {
|
||||||
check_bytes("d1e1", |cb| sal(cb, ECX, uimm_opnd(1)));
|
check_bytes("d1e1", |cb| sal(cb, ECX, uimm_opnd(1)));
|
||||||
check_bytes("c1e505", |cb| sal(cb, EBP, uimm_opnd(5)));
|
check_bytes("c1e505", |cb| sal(cb, EBP, uimm_opnd(5)));
|
||||||
check_bytes("d1642444", |cb| sal(cb, mem_opnd(32, RSP, 68), uimm_opnd(1)));
|
check_bytes("d1642444", |cb| sal(cb, mem_opnd(32, RSP, 68), uimm_opnd(1)));
|
||||||
|
check_bytes("48d3e1", |cb| sal(cb, RCX, CL));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче