x64: Migrate brff and I128 branching instructions to ISLE (#4599)
https://github.com/bytecodealliance/wasmtime/pull/4599
This commit is contained in:
@@ -701,12 +701,6 @@ pub enum AluRmiROpcode {
|
||||
Xor,
|
||||
/// The signless, non-extending (N x N -> N, for N in {32,64}) variant.
|
||||
Mul,
|
||||
/// 8-bit form of And. Handled separately as we don't have full 8-bit op
|
||||
/// support (we just use wider instructions). Used only with some sequences
|
||||
/// with SETcc.
|
||||
And8,
|
||||
/// 8-bit form of Or.
|
||||
Or8,
|
||||
}
|
||||
|
||||
impl fmt::Debug for AluRmiROpcode {
|
||||
@@ -720,8 +714,6 @@ impl fmt::Debug for AluRmiROpcode {
|
||||
AluRmiROpcode::Or => "or",
|
||||
AluRmiROpcode::Xor => "xor",
|
||||
AluRmiROpcode::Mul => "imul",
|
||||
AluRmiROpcode::And8 => "and",
|
||||
AluRmiROpcode::Or8 => "or",
|
||||
};
|
||||
write!(fmt, "{}", name)
|
||||
}
|
||||
@@ -733,16 +725,6 @@ impl fmt::Display for AluRmiROpcode {
|
||||
}
|
||||
}
|
||||
|
||||
impl AluRmiROpcode {
|
||||
/// Is this a special-cased 8-bit ALU op?
|
||||
pub fn is_8bit(self) -> bool {
|
||||
match self {
|
||||
AluRmiROpcode::And8 | AluRmiROpcode::Or8 => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub enum UnaryRmROpcode {
|
||||
/// Bit-scan reverse.
|
||||
@@ -1704,32 +1686,6 @@ impl CC {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_floatcc(floatcc: FloatCC) -> Self {
|
||||
match floatcc {
|
||||
FloatCC::Ordered => CC::NP,
|
||||
FloatCC::Unordered => CC::P,
|
||||
// Alias for NE
|
||||
FloatCC::OrderedNotEqual => CC::NZ,
|
||||
// Alias for E
|
||||
FloatCC::UnorderedOrEqual => CC::Z,
|
||||
// Alias for A
|
||||
FloatCC::GreaterThan => CC::NBE,
|
||||
// Alias for AE
|
||||
FloatCC::GreaterThanOrEqual => CC::NB,
|
||||
FloatCC::UnorderedOrLessThan => CC::B,
|
||||
FloatCC::UnorderedOrLessThanOrEqual => CC::BE,
|
||||
FloatCC::Equal
|
||||
| FloatCC::NotEqual
|
||||
| FloatCC::LessThan
|
||||
| FloatCC::LessThanOrEqual
|
||||
| FloatCC::UnorderedOrGreaterThan
|
||||
| FloatCC::UnorderedOrGreaterThanOrEqual => panic!(
|
||||
"{:?} can't be lowered to a CC code; treat as special case.",
|
||||
floatcc
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_enc(self) -> u8 {
|
||||
self as u8
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ pub(crate) fn emit(
|
||||
(reg_g, src2)
|
||||
};
|
||||
|
||||
let mut rex = RexFlags::from(*size);
|
||||
let rex = RexFlags::from(*size);
|
||||
if *op == AluRmiROpcode::Mul {
|
||||
// We kinda freeloaded Mul into RMI_R_Op, but it doesn't fit the usual pattern, so
|
||||
// we have to special-case it.
|
||||
@@ -191,26 +191,19 @@ pub(crate) fn emit(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let (opcode_r, opcode_m, subopcode_i, is_8bit) = match op {
|
||||
AluRmiROpcode::Add => (0x01, 0x03, 0, false),
|
||||
AluRmiROpcode::Adc => (0x11, 0x03, 0, false),
|
||||
AluRmiROpcode::Sub => (0x29, 0x2B, 5, false),
|
||||
AluRmiROpcode::Sbb => (0x19, 0x2B, 5, false),
|
||||
AluRmiROpcode::And => (0x21, 0x23, 4, false),
|
||||
AluRmiROpcode::Or => (0x09, 0x0B, 1, false),
|
||||
AluRmiROpcode::Xor => (0x31, 0x33, 6, false),
|
||||
AluRmiROpcode::And8 => (0x20, 0x22, 4, true),
|
||||
AluRmiROpcode::Or8 => (0x08, 0x0A, 1, true),
|
||||
let (opcode_r, opcode_m, subopcode_i) = match op {
|
||||
AluRmiROpcode::Add => (0x01, 0x03, 0),
|
||||
AluRmiROpcode::Adc => (0x11, 0x03, 0),
|
||||
AluRmiROpcode::Sub => (0x29, 0x2B, 5),
|
||||
AluRmiROpcode::Sbb => (0x19, 0x2B, 5),
|
||||
AluRmiROpcode::And => (0x21, 0x23, 4),
|
||||
AluRmiROpcode::Or => (0x09, 0x0B, 1),
|
||||
AluRmiROpcode::Xor => (0x31, 0x33, 6),
|
||||
AluRmiROpcode::Mul => panic!("unreachable"),
|
||||
};
|
||||
assert!(!(is_8bit && *size == OperandSize::Size64));
|
||||
|
||||
match src2 {
|
||||
RegMemImm::Reg { reg: reg_e } => {
|
||||
if is_8bit {
|
||||
rex.always_emit_if_8bit_needed(reg_e);
|
||||
rex.always_emit_if_8bit_needed(reg_g);
|
||||
}
|
||||
// GCC/llvm use the swapped operand encoding (viz., the R/RM vs RM/R
|
||||
// duality). Do this too, so as to be able to compare generated machine
|
||||
// code easily.
|
||||
@@ -227,9 +220,6 @@ pub(crate) fn emit(
|
||||
|
||||
RegMemImm::Mem { addr } => {
|
||||
let amode = addr.finalize(state, sink);
|
||||
if is_8bit {
|
||||
rex.always_emit_if_8bit_needed(reg_g);
|
||||
}
|
||||
// Here we revert to the "normal" G-E ordering.
|
||||
emit_std_reg_mem(
|
||||
sink,
|
||||
@@ -245,7 +235,6 @@ pub(crate) fn emit(
|
||||
}
|
||||
|
||||
RegMemImm::Imm { simm32 } => {
|
||||
assert!(!is_8bit);
|
||||
let use_imm8 = low8_will_sign_extend_to_32(simm32);
|
||||
let opcode = if use_imm8 { 0x83 } else { 0x81 };
|
||||
// And also here we use the "normal" G-E ordering.
|
||||
|
||||
@@ -1258,86 +1258,6 @@ fn test_x64_emit() {
|
||||
"4C09FA",
|
||||
"orq %rdx, %r15, %rdx",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::And8,
|
||||
RegMemImm::reg(r15),
|
||||
w_rdx,
|
||||
),
|
||||
"4420FA",
|
||||
"andb %dl, %r15b, %dl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::And8,
|
||||
RegMemImm::reg(rax),
|
||||
w_rsi,
|
||||
),
|
||||
"4020C6",
|
||||
"andb %sil, %al, %sil",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::And8,
|
||||
RegMemImm::reg(rax),
|
||||
w_rbx,
|
||||
),
|
||||
"20C3",
|
||||
"andb %bl, %al, %bl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::And8,
|
||||
RegMemImm::mem(Amode::imm_reg(0, rax)),
|
||||
w_rbx,
|
||||
),
|
||||
"2218",
|
||||
"andb %bl, 0(%rax), %bl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::Or8,
|
||||
RegMemImm::reg(r15),
|
||||
w_rdx,
|
||||
),
|
||||
"4408FA",
|
||||
"orb %dl, %r15b, %dl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::Or8,
|
||||
RegMemImm::reg(rax),
|
||||
w_rsi,
|
||||
),
|
||||
"4008C6",
|
||||
"orb %sil, %al, %sil",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::Or8,
|
||||
RegMemImm::reg(rax),
|
||||
w_rbx,
|
||||
),
|
||||
"08C3",
|
||||
"orb %bl, %al, %bl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size32,
|
||||
AluRmiROpcode::Or8,
|
||||
RegMemImm::mem(Amode::imm_reg(0, rax)),
|
||||
w_rbx,
|
||||
),
|
||||
"0A18",
|
||||
"orb %bl, 0(%rax), %bl",
|
||||
));
|
||||
insns.push((
|
||||
Inst::alu_rmi_r(
|
||||
OperandSize::Size64,
|
||||
|
||||
@@ -729,10 +729,6 @@ impl Inst {
|
||||
Inst::JmpKnown { dst }
|
||||
}
|
||||
|
||||
pub(crate) fn jmp_if(cc: CC, taken: MachLabel) -> Inst {
|
||||
Inst::JmpIf { cc, taken }
|
||||
}
|
||||
|
||||
pub(crate) fn jmp_cond(cc: CC, taken: MachLabel, not_taken: MachLabel) -> Inst {
|
||||
Inst::JmpCond {
|
||||
cc,
|
||||
@@ -892,23 +888,15 @@ impl PrettyPrint for Inst {
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn suffix_lqb(size: OperandSize, is_8: bool) -> String {
|
||||
match (size, is_8) {
|
||||
(_, true) => "b",
|
||||
(OperandSize::Size32, false) => "l",
|
||||
(OperandSize::Size64, false) => "q",
|
||||
fn suffix_lqb(size: OperandSize) -> String {
|
||||
match size {
|
||||
OperandSize::Size32 => "l",
|
||||
OperandSize::Size64 => "q",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn size_lqb(size: OperandSize, is_8: bool) -> u8 {
|
||||
if is_8 {
|
||||
return 1;
|
||||
}
|
||||
size.to_bytes()
|
||||
}
|
||||
|
||||
fn suffix_bwlq(size: OperandSize) -> String {
|
||||
match size {
|
||||
OperandSize::Size8 => "b".to_string(),
|
||||
@@ -922,11 +910,10 @@ impl PrettyPrint for Inst {
|
||||
Inst::Nop { len } => format!("{} len={}", ljustify("nop".to_string()), len),
|
||||
|
||||
Inst::AluRmiR { size, op, dst, .. } if self.produces_const() => {
|
||||
let dst =
|
||||
pretty_print_reg(dst.to_reg().to_reg(), size_lqb(*size, op.is_8bit()), allocs);
|
||||
let dst = pretty_print_reg(dst.to_reg().to_reg(), size.to_bytes(), allocs);
|
||||
format!(
|
||||
"{} {}, {}, {}",
|
||||
ljustify2(op.to_string(), suffix_lqb(*size, op.is_8bit())),
|
||||
ljustify2(op.to_string(), suffix_lqb(*size)),
|
||||
dst,
|
||||
dst,
|
||||
dst
|
||||
@@ -939,13 +926,13 @@ impl PrettyPrint for Inst {
|
||||
src2,
|
||||
dst,
|
||||
} => {
|
||||
let size_bytes = size_lqb(*size, op.is_8bit());
|
||||
let size_bytes = size.to_bytes();
|
||||
let src1 = pretty_print_reg(src1.to_reg(), size_bytes, allocs);
|
||||
let dst = pretty_print_reg(dst.to_reg().to_reg(), size_bytes, allocs);
|
||||
let src2 = src2.pretty_print(size_bytes, allocs);
|
||||
format!(
|
||||
"{} {}, {}, {}",
|
||||
ljustify2(op.to_string(), suffix_lqb(*size, op.is_8bit())),
|
||||
ljustify2(op.to_string(), suffix_lqb(*size)),
|
||||
src1,
|
||||
src2,
|
||||
dst
|
||||
@@ -957,12 +944,12 @@ impl PrettyPrint for Inst {
|
||||
src1_dst,
|
||||
src2,
|
||||
} => {
|
||||
let size_bytes = size_lqb(*size, op.is_8bit());
|
||||
let size_bytes = size.to_bytes();
|
||||
let src2 = pretty_print_reg(src2.to_reg(), size_bytes, allocs);
|
||||
let src1_dst = src1_dst.pretty_print(size_bytes, allocs);
|
||||
format!(
|
||||
"{} {}, {}",
|
||||
ljustify2(op.to_string(), suffix_lqb(*size, op.is_8bit())),
|
||||
ljustify2(op.to_string(), suffix_lqb(*size)),
|
||||
src2,
|
||||
src1_dst,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user