YJIT: implement imul instruction encoding in x86 assembler (#8191)

This commit is contained in:
Maxime Chevalier-Boisvert 2023-08-09 13:12:21 -04:00 коммит произвёл GitHub
Родитель a41c617e41
Коммит c9b30f9d76
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 34 добавлений и 0 удалений

Просмотреть файл

@ -805,6 +805,31 @@ pub fn cqo(cb: &mut CodeBlock) {
cb.write_bytes(&[0x48, 0x99]);
}
/// imul - signed integer multiply
pub fn imul(cb: &mut CodeBlock, opnd0: X86Opnd, opnd1: X86Opnd) {
assert!(opnd0.num_bits() == 64);
assert!(opnd1.num_bits() == 64);
assert!(matches!(opnd0, X86Opnd::Reg(_) | X86Opnd::Mem(_)));
assert!(matches!(opnd1, X86Opnd::Reg(_) | X86Opnd::Mem(_)));
match (opnd0, opnd1) {
(X86Opnd::Reg(_), X86Opnd::Reg(_) | X86Opnd::Mem(_)) => {
//REX.W + 0F AF /rIMUL r64, r/m64
// Quadword register := Quadword register * r/m64.
write_rm(cb, false, true, opnd0, opnd1, None, &[0x0F, 0xAF]);
}
// Flip the operands to handle this case. This instruction has weird encoding restrictions.
(X86Opnd::Mem(_), X86Opnd::Reg(_)) => {
//REX.W + 0F AF /rIMUL r64, r/m64
// Quadword register := Quadword register * r/m64.
write_rm(cb, false, true, opnd1, opnd0, None, &[0x0F, 0xAF]);
}
_ => unreachable!()
}
}
/// Interrupt 3 - trap to debugger
pub fn int3(cb: &mut CodeBlock) {
cb.write_byte(0xcc);

Просмотреть файл

@ -105,6 +105,15 @@ fn test_cqo() {
check_bytes("4899", |cb| cqo(cb));
}
#[test]
fn test_imul() {
check_bytes("480fafc3", |cb| imul(cb, RAX, RBX));
check_bytes("480faf10", |cb| imul(cb, RDX, mem_opnd(64, RAX, 0)));
// Operands flipped for encoding since multiplication is commutative
check_bytes("480faf10", |cb| imul(cb, mem_opnd(64, RAX, 0), RDX));
}
#[test]
fn test_jge_label() {
check_bytes("0f8dfaffffff", |cb| {