From b2a07184040caf13025007f81067889182f4e929 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 11 Jun 2020 15:09:45 +0200 Subject: [PATCH] machinst x64: expand encoding names a bit; This avoids one, two, and three letter structures names, which makes the code easier to read (while a bit more verbose). --- cranelift/codegen/src/isa/x64/abi.rs | 16 +- cranelift/codegen/src/isa/x64/inst/args.rs | 419 +++++++++++------- cranelift/codegen/src/isa/x64/inst/emit.rs | 109 +++-- .../codegen/src/isa/x64/inst/emit_tests.rs | 344 +++++++++----- cranelift/codegen/src/isa/x64/inst/mod.rs | 68 +-- cranelift/codegen/src/isa/x64/lower.rs | 20 +- 6 files changed, 607 insertions(+), 369 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/abi.rs b/cranelift/codegen/src/isa/x64/abi.rs index 3ac4633ced..51fbddeacb 100644 --- a/cranelift/codegen/src/isa/x64/abi.rs +++ b/cranelift/codegen/src/isa/x64/abi.rs @@ -280,7 +280,7 @@ impl ABIBody for X64ABIBody { return Inst::mov_r_r(/*is64=*/ true, from_reg.to_reg(), to_reg); } else if from_reg.get_class() == RegClass::V128 { // TODO: How to support Movss. Should is64 always be true? - return Inst::xmm_r_r(SSE_Op::SSE2_Movsd, from_reg.to_reg(), to_reg); + return Inst::xmm_r_r(SseOpcode::Movsd, from_reg.to_reg(), to_reg); } unimplemented!("moving from non-int arg to vreg {:?}", from_reg.get_class()); } @@ -317,7 +317,7 @@ impl ABIBody for X64ABIBody { )) } else if to_reg.get_class() == RegClass::V128 { ret.push(Inst::xmm_r_r( - SSE_Op::SSE2_Movsd, + SseOpcode::Movsd, from_reg.to_reg(), Writable::::from_reg(to_reg.to_reg()), )) @@ -388,7 +388,7 @@ impl ABIBody for X64ABIBody { // The "traditional" pre-preamble // RSP before the call will be 0 % 16. So here, it is 8 % 16. - insts.push(Inst::push64(RMI::reg(r_rbp))); + insts.push(Inst::push64(RegMemImm::reg(r_rbp))); // RSP is now 0 % 16 insts.push(Inst::mov_r_r(true, r_rsp, w_rbp)); } @@ -401,7 +401,7 @@ impl ABIBody for X64ABIBody { let r_reg = reg.to_reg(); match r_reg.get_class() { RegClass::I64 => { - insts.push(Inst::push64(RMI::reg(r_reg.to_reg()))); + insts.push(Inst::push64(RegMemImm::reg(r_reg.to_reg()))); callee_saved_used += 8; } _ => unimplemented!(), @@ -434,8 +434,8 @@ impl ABIBody for X64ABIBody { if frame_size > 0 { insts.push(Inst::alu_rmi_r( true, - RMI_R_Op::Sub, - RMI::imm(frame_size as u32), + AluRmiROpcode::Sub, + RegMemImm::imm(frame_size as u32), w_rsp, )); } @@ -462,8 +462,8 @@ impl ABIBody for X64ABIBody { insts.push(Inst::alu_rmi_r( true, - RMI_R_Op::Add, - RMI::imm(frame_size as u32), + AluRmiROpcode::Add, + RegMemImm::imm(frame_size as u32), w_rsp, )); } diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs index 6f4b52156f..35f113a32a 100644 --- a/cranelift/codegen/src/isa/x64/inst/args.rs +++ b/cranelift/codegen/src/isa/x64/inst/args.rs @@ -13,10 +13,10 @@ use super::regs::show_ireg_sized; #[derive(Clone)] pub(crate) enum Addr { /// Immediate sign-extended and a Register. - IR { simm32: u32, base: Reg }, + ImmReg { simm32: u32, base: Reg }, /// sign-extend-32-to-64(Immediate) + Register1 + (Register2 << Shift) - IRRS { + ImmRegRegShift { simm32: u32, base: Reg, index: Reg, @@ -25,18 +25,16 @@ pub(crate) enum Addr { } impl Addr { - // Constructors. - pub(crate) fn imm_reg(simm32: u32, base: Reg) -> Self { debug_assert!(base.get_class() == RegClass::I64); - Self::IR { simm32, base } + Self::ImmReg { simm32, base } } pub(crate) fn imm_reg_reg_shift(simm32: u32, base: Reg, index: Reg, shift: u8) -> Self { debug_assert!(base.get_class() == RegClass::I64); debug_assert!(index.get_class() == RegClass::I64); debug_assert!(shift <= 3); - Addr::IRRS { + Self::ImmRegRegShift { simm32, base, index, @@ -47,10 +45,10 @@ impl Addr { /// Add the regs mentioned by `self` to `collector`. pub(crate) fn get_regs_as_uses(&self, collector: &mut RegUsageCollector) { match self { - Addr::IR { simm32: _, base } => { + Addr::ImmReg { simm32: _, base } => { collector.add_use(*base); } - Addr::IRRS { + Addr::ImmRegRegShift { simm32: _, base, index, @@ -66,8 +64,10 @@ impl Addr { impl ShowWithRRU for Addr { fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String { match self { - Addr::IR { simm32, base } => format!("{}({})", *simm32 as i32, base.show_rru(mb_rru)), - Addr::IRRS { + Addr::ImmReg { simm32, base } => { + format!("{}({})", *simm32 as i32, base.show_rru(mb_rru)) + } + Addr::ImmRegRegShift { simm32, base, index, @@ -88,46 +88,44 @@ impl ShowWithRRU for Addr { /// the lower 8 or 16 bits of `simm32` is relevant. In the 64-bit case, the value denoted by /// `simm32` is its sign-extension out to 64 bits. #[derive(Clone)] -pub(crate) enum RMI { - R { reg: Reg }, - M { addr: Addr }, - I { simm32: u32 }, +pub(crate) enum RegMemImm { + Reg { reg: Reg }, + Mem { addr: Addr }, + Imm { simm32: u32 }, } -impl RMI { - // Constructors - - pub(crate) fn reg(reg: Reg) -> RMI { +impl RegMemImm { + pub(crate) fn reg(reg: Reg) -> Self { debug_assert!(reg.get_class() == RegClass::I64); - RMI::R { reg } + Self::Reg { reg } } - pub(crate) fn mem(addr: Addr) -> RMI { - RMI::M { addr } + pub(crate) fn mem(addr: Addr) -> Self { + Self::Mem { addr } } - pub(crate) fn imm(simm32: u32) -> RMI { - RMI::I { simm32 } + pub(crate) fn imm(simm32: u32) -> Self { + Self::Imm { simm32 } } /// Add the regs mentioned by `self` to `collector`. pub(crate) fn get_regs_as_uses(&self, collector: &mut RegUsageCollector) { match self { - RMI::R { reg } => collector.add_use(*reg), - RMI::M { addr } => addr.get_regs_as_uses(collector), - RMI::I { simm32: _ } => {} + Self::Reg { reg } => collector.add_use(*reg), + Self::Mem { addr } => addr.get_regs_as_uses(collector), + Self::Imm { simm32: _ } => {} } } } -impl ShowWithRRU for RMI { +impl ShowWithRRU for RegMemImm { fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String { self.show_rru_sized(mb_rru, 8) } fn show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, size: u8) -> String { match self { - RMI::R { reg } => show_ireg_sized(*reg, mb_rru, size), - RMI::M { addr } => addr.show_rru(mb_rru), - RMI::I { simm32 } => format!("${}", *simm32 as i32), + Self::Reg { reg } => show_ireg_sized(*reg, mb_rru, size), + Self::Mem { addr } => addr.show_rru(mb_rru), + Self::Imm { simm32 } => format!("${}", *simm32 as i32), } } } @@ -135,48 +133,45 @@ impl ShowWithRRU for RMI { /// An operand which is either an integer Register or a value in Memory. This can denote an 8, 16, /// 32 or 64 bit value. #[derive(Clone)] -pub(crate) enum RM { - R { reg: Reg }, - M { addr: Addr }, +pub(crate) enum RegMem { + Reg { reg: Reg }, + Mem { addr: Addr }, } -impl RM { - // Constructors. - +impl RegMem { pub(crate) fn reg(reg: Reg) -> Self { debug_assert!(reg.get_class() == RegClass::I64 || reg.get_class() == RegClass::V128); - RM::R { reg } + Self::Reg { reg } } - pub(crate) fn mem(addr: Addr) -> Self { - RM::M { addr } + Self::Mem { addr } } /// Add the regs mentioned by `self` to `collector`. pub(crate) fn get_regs_as_uses(&self, collector: &mut RegUsageCollector) { match self { - RM::R { reg } => collector.add_use(*reg), - RM::M { addr } => addr.get_regs_as_uses(collector), + RegMem::Reg { reg } => collector.add_use(*reg), + RegMem::Mem { addr } => addr.get_regs_as_uses(collector), } } } -impl ShowWithRRU for RM { +impl ShowWithRRU for RegMem { fn show_rru(&self, mb_rru: Option<&RealRegUniverse>) -> String { self.show_rru_sized(mb_rru, 8) } fn show_rru_sized(&self, mb_rru: Option<&RealRegUniverse>, size: u8) -> String { match self { - RM::R { reg } => show_ireg_sized(*reg, mb_rru, size), - RM::M { addr } => addr.show_rru(mb_rru), + RegMem::Reg { reg } => show_ireg_sized(*reg, mb_rru, size), + RegMem::Mem { addr } => addr.show_rru(mb_rru), } } } /// Some basic ALU operations. TODO: maybe add Adc, Sbb. #[derive(Clone, PartialEq)] -pub enum RMI_R_Op { +pub enum AluRmiROpcode { Add, Sub, And, @@ -186,89 +181,185 @@ pub enum RMI_R_Op { Mul, } -impl RMI_R_Op { - pub(crate) fn to_string(&self) -> String { +impl fmt::Debug for AluRmiROpcode { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let name = match self { + AluRmiROpcode::Add => "add", + AluRmiROpcode::Sub => "sub", + AluRmiROpcode::And => "and", + AluRmiROpcode::Or => "or", + AluRmiROpcode::Xor => "xor", + AluRmiROpcode::Mul => "imul", + }; + write!(fmt, "{}", name) + } +} + +impl ToString for AluRmiROpcode { + fn to_string(&self) -> String { + format!("{:?}", self) + } +} + +pub(crate) enum InstructionSet { + SSE, + SSE2, + SSE41, +} + +/// Some scalar SSE operations requiring 2 operands r/m and r. +/// TODO: Below only includes scalar operations. To be seen if packed will be added here. +#[derive(Clone, PartialEq)] +pub enum SseOpcode { + Addss, + Addsd, + Comiss, + Comisd, + Cvtsd2ss, + Cvtsd2si, + Cvtsi2ss, + Cvtsi2sd, + Cvtss2si, + Cvtss2sd, + Cvttss2si, + Cvttsd2si, + Divss, + Divsd, + Maxss, + Maxsd, + Minss, + Minsd, + Movss, + Movsd, + Mulss, + Mulsd, + Rcpss, + Roundss, + Roundsd, + Rsqrtss, + Sqrtss, + Sqrtsd, + Subss, + Subsd, + Ucomiss, + Ucomisd, +} + +impl SseOpcode { + /// Which `InstructionSet` is the first supporting this opcode? + pub(crate) fn available_from(&self) -> InstructionSet { + use InstructionSet::*; match self { - RMI_R_Op::Add => "add".to_string(), - RMI_R_Op::Sub => "sub".to_string(), - RMI_R_Op::And => "and".to_string(), - RMI_R_Op::Or => "or".to_string(), - RMI_R_Op::Xor => "xor".to_string(), - RMI_R_Op::Mul => "imul".to_string(), + SseOpcode::Addss + | SseOpcode::Cvtsi2ss + | SseOpcode::Cvtss2si + | SseOpcode::Cvttss2si + | SseOpcode::Divss + | SseOpcode::Maxss + | SseOpcode::Minss + | SseOpcode::Movss + | SseOpcode::Mulss + | SseOpcode::Rcpss + | SseOpcode::Rsqrtss + | SseOpcode::Subss + | SseOpcode::Ucomiss + | SseOpcode::Sqrtss + | SseOpcode::Comiss => SSE, + + SseOpcode::Addsd + | SseOpcode::Cvtsd2ss + | SseOpcode::Cvtsd2si + | SseOpcode::Cvtsi2sd + | SseOpcode::Cvtss2sd + | SseOpcode::Cvttsd2si + | SseOpcode::Divsd + | SseOpcode::Maxsd + | SseOpcode::Minsd + | SseOpcode::Movsd + | SseOpcode::Mulsd + | SseOpcode::Sqrtsd + | SseOpcode::Subsd + | SseOpcode::Ucomisd + | SseOpcode::Comisd => SSE2, + + SseOpcode::Roundss | SseOpcode::Roundsd => SSE41, } } -} -impl fmt::Debug for RMI_R_Op { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.to_string()) - } -} - -/// Some scalar SSE operations requiring 2 operands r/m and r -/// Each instruction is prefixed with the SSE version that introduced -/// the particular instructions. -/// TODO: Below only includes scalar operations. To be seen if packed will -/// be added here. -#[derive(Clone, PartialEq)] -pub enum SSE_Op { - SSE_Addss, - SSE2_Addsd, - SSE_Comiss, - SSE2_Comisd, - SSE2_Cvtsd2ss, - SSE2_Cvtsd2si, - SSE_Cvtsi2ss, - SSE2_Cvtsi2sd, - SSE_Cvtss2si, - SSE2_Cvtss2sd, - SSE_Cvttss2si, - SSE2_Cvttsd2si, - SSE_Divss, - SSE2_Divsd, - SSE_Maxss, - SSE2_Maxsd, - SSE_Minss, - SSE2_Minsd, - SSE_Movss, - SSE2_Movsd, - SSE_Mulss, - SSE2_Mulsd, - SSE_Rcpss, - SSE41_Roundss, - SSE41_Roundsd, - SSE_Rsqrtss, - SSE_Sqrtss, - SSE2_Sqrtsd, - SSE_Subss, - SSE2_Subsd, - SSE_Ucomiss, - SSE2_Ucomisd, -} - -/// Some SSE operations requiring 3 operands i, r/m, and r -#[derive(Clone, PartialEq)] -pub enum SSE_RMI_Op { - SSE_Cmpss, - SSE2_Cmpsd, - SSE41_Insertps, -} - -impl SSE_Op { pub(crate) fn to_string(&self) -> String { match self { - SSE_Op::SSE_Addss => "addss".to_string(), - SSE_Op::SSE_Subss => "subss".to_string(), - SSE_Op::SSE_Movss => "movss".to_string(), - SSE_Op::SSE2_Movsd => "movsd".to_string(), + SseOpcode::Addss => "addss".to_string(), + SseOpcode::Subss => "subss".to_string(), + SseOpcode::Movss => "movss".to_string(), + SseOpcode::Movsd => "movsd".to_string(), _ => "unimplemented sse_op".to_string(), } } } -impl fmt::Debug for SSE_Op { +impl fmt::Debug for SseOpcode { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.to_string()) + let name = match self { + SseOpcode::Addss => "addss", + SseOpcode::Addsd => "addsd", + SseOpcode::Comiss => "comiss", + SseOpcode::Comisd => "comisd", + SseOpcode::Cvtsd2ss => "cvtsd2ss", + SseOpcode::Cvtsd2si => "cvtsd2si", + SseOpcode::Cvtsi2ss => "cvtsi2ss", + SseOpcode::Cvtsi2sd => "cvtsi2sd", + SseOpcode::Cvtss2si => "cvtss2si", + SseOpcode::Cvtss2sd => "cvtss2sd", + SseOpcode::Cvttss2si => "cvttss2si", + SseOpcode::Cvttsd2si => "cvttsd2si", + SseOpcode::Divss => "divss", + SseOpcode::Divsd => "divsd", + SseOpcode::Maxss => "maxss", + SseOpcode::Maxsd => "maxsd", + SseOpcode::Minss => "minss", + SseOpcode::Minsd => "minsd", + SseOpcode::Movss => "movss", + SseOpcode::Movsd => "movsd", + SseOpcode::Mulss => "mulss", + SseOpcode::Mulsd => "mulsd", + SseOpcode::Rcpss => "rcpss", + SseOpcode::Roundss => "roundss", + SseOpcode::Roundsd => "roundsd", + SseOpcode::Rsqrtss => "rsqrtss", + SseOpcode::Sqrtss => "srtqss", + SseOpcode::Sqrtsd => "sqrtsd", + SseOpcode::Subss => "subss", + SseOpcode::Subsd => "subsd", + SseOpcode::Ucomiss => "ucomiss", + SseOpcode::Ucomisd => "ucomisd", + }; + write!(fmt, "{}", name) + } +} + +impl ToString for SseOpcode { + fn to_string(&self) -> String { + format!("{:?}", self) + } +} + +/// Some SSE operations requiring 3 operands i, r/m, and r. +#[derive(Clone, PartialEq)] +pub enum SseRmiOpcode { + Cmpss, + Cmpsd, + Insertps, +} + +impl SseRmiOpcode { + /// Which `InstructionSet` is the first supporting this opcode? + pub(crate) fn available_from(&self) -> InstructionSet { + use InstructionSet::*; + match self { + SseRmiOpcode::Cmpss => SSE, + SseRmiOpcode::Cmpsd => SSE2, + SseRmiOpcode::Insertps => SSE41, + } } } @@ -289,30 +380,30 @@ pub enum ExtMode { } impl ExtMode { - pub(crate) fn to_string(&self) -> String { - match self { - ExtMode::BL => "bl".to_string(), - ExtMode::BQ => "bq".to_string(), - ExtMode::WL => "wl".to_string(), - ExtMode::WQ => "wq".to_string(), - ExtMode::LQ => "lq".to_string(), - } - } - pub(crate) fn dst_size(&self) -> u8 { match self { - ExtMode::BL => 4, - ExtMode::BQ => 8, - ExtMode::WL => 4, - ExtMode::WQ => 8, - ExtMode::LQ => 8, + ExtMode::BL | ExtMode::WL => 4, + ExtMode::BQ | ExtMode::WQ | ExtMode::LQ => 8, } } } impl fmt::Debug for ExtMode { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.to_string()) + let name = match self { + ExtMode::BL => "bl", + ExtMode::BQ => "bq", + ExtMode::WL => "wl", + ExtMode::WQ => "wq", + ExtMode::LQ => "lq", + }; + write!(fmt, "{}", name) + } +} + +impl ToString for ExtMode { + fn to_string(&self) -> String { + format!("{:?}", self) } } @@ -324,19 +415,20 @@ pub enum ShiftKind { RightS, } -impl ShiftKind { - pub(crate) fn to_string(&self) -> String { - match self { - ShiftKind::Left => "shl".to_string(), - ShiftKind::RightZ => "shr".to_string(), - ShiftKind::RightS => "sar".to_string(), - } +impl fmt::Debug for ShiftKind { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let name = match self { + ShiftKind::Left => "shl", + ShiftKind::RightZ => "shr", + ShiftKind::RightS => "sar", + }; + write!(fmt, "{}", name) } } -impl fmt::Debug for ShiftKind { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.to_string()) +impl ToString for ShiftKind { + fn to_string(&self) -> String { + format!("{:?}", self) } } @@ -382,25 +474,6 @@ pub enum CC { } impl CC { - pub(crate) fn to_string(&self) -> String { - match self { - CC::O => "o".to_string(), - CC::NO => "no".to_string(), - CC::B => "b".to_string(), - CC::NB => "nb".to_string(), - CC::Z => "z".to_string(), - CC::NZ => "nz".to_string(), - CC::BE => "be".to_string(), - CC::NBE => "nbe".to_string(), - CC::S => "s".to_string(), - CC::NS => "ns".to_string(), - CC::L => "l".to_string(), - CC::NL => "nl".to_string(), - CC::LE => "le".to_string(), - CC::NLE => "nle".to_string(), - } - } - pub(crate) fn invert(&self) -> CC { match self { CC::O => CC::NO, @@ -433,7 +506,29 @@ impl CC { impl fmt::Debug for CC { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}", self.to_string()) + let name = match self { + CC::O => "o", + CC::NO => "no", + CC::B => "b", + CC::NB => "nb", + CC::Z => "z", + CC::NZ => "nz", + CC::BE => "be", + CC::NBE => "nbe", + CC::S => "s", + CC::NS => "ns", + CC::L => "l", + CC::NL => "nl", + CC::LE => "le", + CC::NLE => "nle", + }; + write!(fmt, "{}", name) + } +} + +impl ToString for CC { + fn to_string(&self) -> String { + format!("{:?}", self) } } diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 77ed7fcb4e..681dec6ce7 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -106,8 +106,9 @@ fn emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( LegacyPrefix::PfxF3 => sink.put1(0xF3), LegacyPrefix::PfxNone => (), } + match memE { - Addr::IR { simm32, base: regE } => { + Addr::ImmReg { simm32, base: regE } => { // First, cook up the REX byte. This is easy. let encE = iregEnc(*regE); let w = if clearRexW { 0 } else { 1 }; @@ -157,11 +158,11 @@ fn emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( sink.put1(0x24); sink.put4(*simm32); } else { - unreachable!("emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE: IR"); + unreachable!("emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE: ImmReg"); } } - // Bizarrely, the IRRS case is much simpler. - Addr::IRRS { + + Addr::ImmRegRegShift { simm32, base: regBase, index: regIndex, @@ -193,7 +194,7 @@ fn emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( sink.put1(mkSIB(*shift, encIndex & 7, encBase & 7)); sink.put4(*simm32); } else { - panic!("emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE: IRRS"); + panic!("emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE: ImmRegRegShift"); } } } @@ -355,11 +356,11 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { dst: regG, } => { let flags = if *is_64 { F_NONE } else { F_CLEAR_REX_W }; - if *op == RMI_R_Op::Mul { + 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. match srcE { - RMI::R { reg: regE } => { + RegMemImm::Reg { reg: regE } => { emit_REX_OPCODES_MODRM_regG_regE( sink, LegacyPrefix::PfxNone, @@ -370,7 +371,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { flags, ); } - RMI::M { addr } => { + + RegMemImm::Mem { addr } => { emit_REX_OPCODES_MODRM_SIB_IMM_regG_memE( sink, LegacyPrefix::PfxNone, @@ -381,7 +383,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { flags, ); } - RMI::I { simm32 } => { + + RegMemImm::Imm { simm32 } => { let useImm8 = low8willSXto32(*simm32); let opcode = if useImm8 { 0x6B } else { 0x69 }; // Yes, really, regG twice. @@ -399,15 +402,16 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } else { let (opcode_R, opcode_M, subopcode_I) = match op { - RMI_R_Op::Add => (0x01, 0x03, 0), - RMI_R_Op::Sub => (0x29, 0x2B, 5), - RMI_R_Op::And => (0x21, 0x23, 4), - RMI_R_Op::Or => (0x09, 0x0B, 1), - RMI_R_Op::Xor => (0x31, 0x33, 6), - RMI_R_Op::Mul => panic!("unreachable"), + AluRmiROpcode::Add => (0x01, 0x03, 0), + AluRmiROpcode::Sub => (0x29, 0x2B, 5), + AluRmiROpcode::And => (0x21, 0x23, 4), + AluRmiROpcode::Or => (0x09, 0x0B, 1), + AluRmiROpcode::Xor => (0x31, 0x33, 6), + AluRmiROpcode::Mul => panic!("unreachable"), }; + match srcE { - RMI::R { reg: regE } => { + RegMemImm::Reg { reg: regE } => { // Note. The arguments .. regE .. regG .. sequence // here is the opposite of what is expected. I'm not // sure why this is. But I am fairly sure that the @@ -431,7 +435,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { // NB: if this is ever extended to handle byte size // ops, be sure to retain redundant REX prefixes. } - RMI::M { addr } => { + + RegMemImm::Mem { addr } => { // Whereas here we revert to the "normal" G-E ordering. emit_REX_OPCODES_MODRM_SIB_IMM_regG_memE( sink, @@ -443,7 +448,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { flags, ); } - RMI::I { simm32 } => { + + RegMemImm::Imm { simm32 } => { let useImm8 = low8willSXto32(*simm32); let opcode = if useImm8 { 0x83 } else { 0x81 }; // And also here we use the "normal" G-E ordering. @@ -462,6 +468,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + Inst::Imm_R { dst_is_64, simm64, @@ -482,6 +489,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { sink.put4(*simm64 as u32); } } + Inst::Mov_R_R { is_64, src, dst } => { let flags = if *is_64 { F_NONE } else { F_CLEAR_REX_W }; emit_REX_OPCODES_MODRM_regG_regE( @@ -494,6 +502,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { flags, ); } + Inst::MovZX_M_R { extMode, addr, dst } => { match extMode { ExtMode::BL => { @@ -749,7 +758,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { dst: regG, } => { let mut retainRedundantRex = 0; - let mut prefix = LegacyPrefix::PfxNone; + if *size == 1 { // Here, a redundant REX prefix changes the meaning of the // instruction. @@ -758,17 +767,21 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { retainRedundantRex = F_RETAIN_REDUNDANT_REX; } } + + let mut prefix = LegacyPrefix::PfxNone; if *size == 2 { prefix = LegacyPrefix::Pfx66; } + let mut flags = match size { 8 => F_NONE, 4 | 2 => F_CLEAR_REX_W, 1 => F_CLEAR_REX_W | retainRedundantRex, _ => panic!("x64::Inst::Cmp_RMI_R::emit: unreachable"), }; + match srcE { - RMI::R { reg: regE } => { + RegMemImm::Reg { reg: regE } => { let opcode = if *size == 1 { 0x38 } else { 0x39 }; if *size == 1 { // We also need to check whether the E register forces @@ -781,14 +794,16 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { // Same comment re swapped args as for Alu_RMI_R. emit_REX_OPCODES_MODRM_regG_regE(sink, prefix, opcode, 1, *regE, *regG, flags); } - RMI::M { addr } => { + + RegMemImm::Mem { addr } => { let opcode = if *size == 1 { 0x3A } else { 0x3B }; // Whereas here we revert to the "normal" G-E ordering. emit_REX_OPCODES_MODRM_SIB_IMM_regG_memE( sink, prefix, opcode, 1, *regG, addr, flags, ); } - RMI::I { simm32 } => { + + RegMemImm::Imm { simm32 } => { // FIXME JRS 2020Feb11: there are shorter encodings for // cmp $imm, rax/eax/ax/al. let useImm8 = low8willSXto32(*simm32); @@ -809,9 +824,10 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + Inst::Push64 { src } => { match src { - RMI::R { reg } => { + RegMemImm::Reg { reg } => { let encReg = iregEnc(*reg); let rex = 0x40 | ((encReg >> 3) & 1); if rex != 0x40 { @@ -819,7 +835,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } sink.put1(0x50 | (encReg & 7)); } - RMI::M { addr } => { + + RegMemImm::Mem { addr } => { emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( sink, LegacyPrefix::PfxNone, @@ -830,7 +847,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { F_CLEAR_REX_W, ); } - RMI::I { simm32 } => { + + RegMemImm::Imm { simm32 } => { if low8willSXto64(*simm32) { sink.put1(0x6A); sink.put1(*simm32 as u8); @@ -841,6 +859,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + Inst::Pop64 { dst } => { let encDst = iregEnc(dst.to_reg()); if encDst >= 8 { @@ -850,12 +869,10 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } sink.put1(0x58 + (encDst & 7)); } - // - // ** Inst::CallKnown - // + Inst::CallUnknown { dest } => { match dest { - RM::R { reg } => { + RegMem::Reg { reg } => { let regEnc = iregEnc(*reg); emit_REX_OPCODES_MODRM_encG_encE( sink, @@ -867,7 +884,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { F_CLEAR_REX_W, ); } - RM::M { addr } => { + + RegMem::Mem { addr } => { emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( sink, LegacyPrefix::PfxNone, @@ -880,6 +898,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + Inst::Ret {} => sink.put1(0xC3), Inst::JmpKnown { dest } => { @@ -895,6 +914,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { sink.put1(0xE9); sink.put4(disp); } + Inst::JmpCondSymm { cc, taken, @@ -935,9 +955,10 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { sink.put1(0xE9); sink.put4(nt_disp); } + Inst::JmpUnknown { target } => { match target { - RM::R { reg } => { + RegMem::Reg { reg } => { let regEnc = iregEnc(*reg); emit_REX_OPCODES_MODRM_encG_encE( sink, @@ -949,7 +970,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { F_CLEAR_REX_W, ); } - RM::M { addr } => { + + RegMem::Mem { addr } => { emit_REX_OPCODES_MODRM_SIB_IMM_encG_memE( sink, LegacyPrefix::PfxNone, @@ -962,20 +984,24 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + Inst::XMM_R_R { op, src, dst } => { let flags = F_CLEAR_REX_W; let opcode = match op { - SSE_Op::SSE_Movss => 0x0F10, - SSE_Op::SSE2_Movsd => 0x0F10, + SseOpcode::Movss => 0x0F10, + SseOpcode::Movsd => 0x0F10, _ => unimplemented!("XMM_R_R opcode"), }; + let prefix = match op { - SSE_Op::SSE_Movss => LegacyPrefix::PfxF3, - SSE_Op::SSE2_Movsd => LegacyPrefix::PfxF2, + SseOpcode::Movss => LegacyPrefix::PfxF3, + SseOpcode::Movsd => LegacyPrefix::PfxF2, _ => unimplemented!("XMM_R_R opcode"), }; + emit_REX_OPCODES_MODRM_regG_regE(sink, prefix, opcode, 2, dst.to_reg(), *src, flags); } + Inst::XMM_RM_R { op, src: srcE, @@ -983,12 +1009,13 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } => { let flags = F_CLEAR_REX_W; let opcode = match op { - SSE_Op::SSE_Addss => 0x0F58, - SSE_Op::SSE_Subss => 0x0F5C, + SseOpcode::Addss => 0x0F58, + SseOpcode::Subss => 0x0F5C, _ => unimplemented!("XMM_RM_R opcode"), }; + match srcE { - RM::R { reg: regE } => { + RegMem::Reg { reg: regE } => { emit_REX_OPCODES_MODRM_regG_regE( sink, LegacyPrefix::PfxF3, @@ -999,7 +1026,8 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { flags, ); } - RM::M { addr } => { + + RegMem::Mem { addr } => { emit_REX_OPCODES_MODRM_SIB_IMM_regG_memE( sink, LegacyPrefix::PfxF3, @@ -1012,6 +1040,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer) { } } } + _ => panic!("x64_emit: unhandled: {} ", inst.show_rru(None)), } } diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs index 6b54c7a1f2..e1a91633c1 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs @@ -882,184 +882,274 @@ fn test_x64_emit() { // // Alu_RMI_R insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Add, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Add, RegMemImm::reg(r15), w_rdx), "4C01FA", "addq %r15, %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::reg(rcx), w_r8), + Inst::alu_rmi_r(false, AluRmiROpcode::Add, RegMemImm::reg(rcx), w_r8), "4101C8", "addl %ecx, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::reg(rcx), w_rsi), + Inst::alu_rmi_r(false, AluRmiROpcode::Add, RegMemImm::reg(rcx), w_rsi), "01CE", "addl %ecx, %esi", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Add, RMI::mem(Addr::imm_reg(99, rdi)), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Add, + RegMemImm::mem(Addr::imm_reg(99, rdi)), + w_rdx, + ), "48035763", "addq 99(%rdi), %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::mem(Addr::imm_reg(99, rdi)), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::mem(Addr::imm_reg(99, rdi)), + w_r8, + ), "44034763", "addl 99(%rdi), %r8d", )); insns.push(( Inst::alu_rmi_r( false, - RMI_R_Op::Add, - RMI::mem(Addr::imm_reg(99, rdi)), + AluRmiROpcode::Add, + RegMemImm::mem(Addr::imm_reg(99, rdi)), w_rsi, ), "037763", "addl 99(%rdi), %esi", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Add, RMI::imm(-127i32 as u32), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Add, + RegMemImm::imm(-127i32 as u32), + w_rdx, + ), "4883C281", "addq $-127, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Add, RMI::imm(-129i32 as u32), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Add, + RegMemImm::imm(-129i32 as u32), + w_rdx, + ), "4881C27FFFFFFF", "addq $-129, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Add, RMI::imm(76543210), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Add, RegMemImm::imm(76543210), w_rdx), "4881C2EAF48F04", "addq $76543210, %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(-127i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::imm(-127i32 as u32), + w_r8, + ), "4183C081", "addl $-127, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(-129i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::imm(-129i32 as u32), + w_r8, + ), "4181C07FFFFFFF", "addl $-129, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(-76543210i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::imm(-76543210i32 as u32), + w_r8, + ), "4181C0160B70FB", "addl $-76543210, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(-127i32 as u32), w_rsi), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::imm(-127i32 as u32), + w_rsi, + ), "83C681", "addl $-127, %esi", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(-129i32 as u32), w_rsi), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Add, + RegMemImm::imm(-129i32 as u32), + w_rsi, + ), "81C67FFFFFFF", "addl $-129, %esi", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Add, RMI::imm(76543210), w_rsi), + Inst::alu_rmi_r(false, AluRmiROpcode::Add, RegMemImm::imm(76543210), w_rsi), "81C6EAF48F04", "addl $76543210, %esi", )); // This is pretty feeble insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Sub, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Sub, RegMemImm::reg(r15), w_rdx), "4C29FA", "subq %r15, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::And, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::And, RegMemImm::reg(r15), w_rdx), "4C21FA", "andq %r15, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Or, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Or, RegMemImm::reg(r15), w_rdx), "4C09FA", "orq %r15, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Xor, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Xor, RegMemImm::reg(r15), w_rdx), "4C31FA", "xorq %r15, %rdx", )); // Test all mul cases, though insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Mul, RMI::reg(r15), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Mul, RegMemImm::reg(r15), w_rdx), "490FAFD7", "imulq %r15, %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::reg(rcx), w_r8), + Inst::alu_rmi_r(false, AluRmiROpcode::Mul, RegMemImm::reg(rcx), w_r8), "440FAFC1", "imull %ecx, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::reg(rcx), w_rsi), + Inst::alu_rmi_r(false, AluRmiROpcode::Mul, RegMemImm::reg(rcx), w_rsi), "0FAFF1", "imull %ecx, %esi", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Mul, RMI::mem(Addr::imm_reg(99, rdi)), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Mul, + RegMemImm::mem(Addr::imm_reg(99, rdi)), + w_rdx, + ), "480FAF5763", "imulq 99(%rdi), %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::mem(Addr::imm_reg(99, rdi)), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::mem(Addr::imm_reg(99, rdi)), + w_r8, + ), "440FAF4763", "imull 99(%rdi), %r8d", )); insns.push(( Inst::alu_rmi_r( false, - RMI_R_Op::Mul, - RMI::mem(Addr::imm_reg(99, rdi)), + AluRmiROpcode::Mul, + RegMemImm::mem(Addr::imm_reg(99, rdi)), w_rsi, ), "0FAF7763", "imull 99(%rdi), %esi", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Mul, RMI::imm(-127i32 as u32), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Mul, + RegMemImm::imm(-127i32 as u32), + w_rdx, + ), "486BD281", "imulq $-127, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Mul, RMI::imm(-129i32 as u32), w_rdx), + Inst::alu_rmi_r( + true, + AluRmiROpcode::Mul, + RegMemImm::imm(-129i32 as u32), + w_rdx, + ), "4869D27FFFFFFF", "imulq $-129, %rdx", )); insns.push(( - Inst::alu_rmi_r(true, RMI_R_Op::Mul, RMI::imm(76543210), w_rdx), + Inst::alu_rmi_r(true, AluRmiROpcode::Mul, RegMemImm::imm(76543210), w_rdx), "4869D2EAF48F04", "imulq $76543210, %rdx", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(-127i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::imm(-127i32 as u32), + w_r8, + ), "456BC081", "imull $-127, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(-129i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::imm(-129i32 as u32), + w_r8, + ), "4569C07FFFFFFF", "imull $-129, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(-76543210i32 as u32), w_r8), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::imm(-76543210i32 as u32), + w_r8, + ), "4569C0160B70FB", "imull $-76543210, %r8d", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(-127i32 as u32), w_rsi), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::imm(-127i32 as u32), + w_rsi, + ), "6BF681", "imull $-127, %esi", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(-129i32 as u32), w_rsi), + Inst::alu_rmi_r( + false, + AluRmiROpcode::Mul, + RegMemImm::imm(-129i32 as u32), + w_rsi, + ), "69F67FFFFFFF", "imull $-129, %esi", )); insns.push(( - Inst::alu_rmi_r(false, RMI_R_Op::Mul, RMI::imm(76543210), w_rsi), + Inst::alu_rmi_r(false, AluRmiROpcode::Mul, RegMemImm::imm(76543210), w_rsi), "69F6EAF48F04", "imull $76543210, %esi", )); @@ -1837,314 +1927,318 @@ fn test_x64_emit() { // ======================================================== // CmpRMIR insns.push(( - Inst::cmp_rmi_r(8, RMI::reg(r15), rdx), + Inst::cmp_rmi_r(8, RegMemImm::reg(r15), rdx), "4C39FA", "cmpq %r15, %rdx", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::reg(rcx), r8), + Inst::cmp_rmi_r(8, RegMemImm::reg(rcx), r8), "4939C8", "cmpq %rcx, %r8", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::reg(rcx), rsi), + Inst::cmp_rmi_r(8, RegMemImm::reg(rcx), rsi), "4839CE", "cmpq %rcx, %rsi", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::mem(Addr::imm_reg(99, rdi)), rdx), + Inst::cmp_rmi_r(8, RegMemImm::mem(Addr::imm_reg(99, rdi)), rdx), "483B5763", "cmpq 99(%rdi), %rdx", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::mem(Addr::imm_reg(99, rdi)), r8), + Inst::cmp_rmi_r(8, RegMemImm::mem(Addr::imm_reg(99, rdi)), r8), "4C3B4763", "cmpq 99(%rdi), %r8", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::mem(Addr::imm_reg(99, rdi)), rsi), + Inst::cmp_rmi_r(8, RegMemImm::mem(Addr::imm_reg(99, rdi)), rsi), "483B7763", "cmpq 99(%rdi), %rsi", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::imm(76543210), rdx), + Inst::cmp_rmi_r(8, RegMemImm::imm(76543210), rdx), "4881FAEAF48F04", "cmpq $76543210, %rdx", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::imm(-76543210i32 as u32), r8), + Inst::cmp_rmi_r(8, RegMemImm::imm(-76543210i32 as u32), r8), "4981F8160B70FB", "cmpq $-76543210, %r8", )); insns.push(( - Inst::cmp_rmi_r(8, RMI::imm(76543210), rsi), + Inst::cmp_rmi_r(8, RegMemImm::imm(76543210), rsi), "4881FEEAF48F04", "cmpq $76543210, %rsi", )); // insns.push(( - Inst::cmp_rmi_r(4, RMI::reg(r15), rdx), + Inst::cmp_rmi_r(4, RegMemImm::reg(r15), rdx), "4439FA", "cmpl %r15d, %edx", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::reg(rcx), r8), + Inst::cmp_rmi_r(4, RegMemImm::reg(rcx), r8), "4139C8", "cmpl %ecx, %r8d", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::reg(rcx), rsi), + Inst::cmp_rmi_r(4, RegMemImm::reg(rcx), rsi), "39CE", "cmpl %ecx, %esi", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::mem(Addr::imm_reg(99, rdi)), rdx), + Inst::cmp_rmi_r(4, RegMemImm::mem(Addr::imm_reg(99, rdi)), rdx), "3B5763", "cmpl 99(%rdi), %edx", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::mem(Addr::imm_reg(99, rdi)), r8), + Inst::cmp_rmi_r(4, RegMemImm::mem(Addr::imm_reg(99, rdi)), r8), "443B4763", "cmpl 99(%rdi), %r8d", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::mem(Addr::imm_reg(99, rdi)), rsi), + Inst::cmp_rmi_r(4, RegMemImm::mem(Addr::imm_reg(99, rdi)), rsi), "3B7763", "cmpl 99(%rdi), %esi", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::imm(76543210), rdx), + Inst::cmp_rmi_r(4, RegMemImm::imm(76543210), rdx), "81FAEAF48F04", "cmpl $76543210, %edx", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::imm(-76543210i32 as u32), r8), + Inst::cmp_rmi_r(4, RegMemImm::imm(-76543210i32 as u32), r8), "4181F8160B70FB", "cmpl $-76543210, %r8d", )); insns.push(( - Inst::cmp_rmi_r(4, RMI::imm(76543210), rsi), + Inst::cmp_rmi_r(4, RegMemImm::imm(76543210), rsi), "81FEEAF48F04", "cmpl $76543210, %esi", )); // insns.push(( - Inst::cmp_rmi_r(2, RMI::reg(r15), rdx), + Inst::cmp_rmi_r(2, RegMemImm::reg(r15), rdx), "664439FA", "cmpw %r15w, %dx", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::reg(rcx), r8), + Inst::cmp_rmi_r(2, RegMemImm::reg(rcx), r8), "664139C8", "cmpw %cx, %r8w", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::reg(rcx), rsi), + Inst::cmp_rmi_r(2, RegMemImm::reg(rcx), rsi), "6639CE", "cmpw %cx, %si", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::mem(Addr::imm_reg(99, rdi)), rdx), + Inst::cmp_rmi_r(2, RegMemImm::mem(Addr::imm_reg(99, rdi)), rdx), "663B5763", "cmpw 99(%rdi), %dx", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::mem(Addr::imm_reg(99, rdi)), r8), + Inst::cmp_rmi_r(2, RegMemImm::mem(Addr::imm_reg(99, rdi)), r8), "66443B4763", "cmpw 99(%rdi), %r8w", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::mem(Addr::imm_reg(99, rdi)), rsi), + Inst::cmp_rmi_r(2, RegMemImm::mem(Addr::imm_reg(99, rdi)), rsi), "663B7763", "cmpw 99(%rdi), %si", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::imm(23210), rdx), + Inst::cmp_rmi_r(2, RegMemImm::imm(23210), rdx), "6681FAAA5A", "cmpw $23210, %dx", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::imm(-7654i32 as u32), r8), + Inst::cmp_rmi_r(2, RegMemImm::imm(-7654i32 as u32), r8), "664181F81AE2", "cmpw $-7654, %r8w", )); insns.push(( - Inst::cmp_rmi_r(2, RMI::imm(7654), rsi), + Inst::cmp_rmi_r(2, RegMemImm::imm(7654), rsi), "6681FEE61D", "cmpw $7654, %si", )); // insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r15), rdx), + Inst::cmp_rmi_r(1, RegMemImm::reg(r15), rdx), "4438FA", "cmpb %r15b, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), r8), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), r8), "4138C8", "cmpb %cl, %r8b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), rsi), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), rsi), "4038CE", "cmpb %cl, %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::mem(Addr::imm_reg(99, rdi)), rdx), + Inst::cmp_rmi_r(1, RegMemImm::mem(Addr::imm_reg(99, rdi)), rdx), "3A5763", "cmpb 99(%rdi), %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::mem(Addr::imm_reg(99, rdi)), r8), + Inst::cmp_rmi_r(1, RegMemImm::mem(Addr::imm_reg(99, rdi)), r8), "443A4763", "cmpb 99(%rdi), %r8b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::mem(Addr::imm_reg(99, rdi)), rsi), + Inst::cmp_rmi_r(1, RegMemImm::mem(Addr::imm_reg(99, rdi)), rsi), "403A7763", "cmpb 99(%rdi), %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::imm(70), rdx), + Inst::cmp_rmi_r(1, RegMemImm::imm(70), rdx), "80FA46", "cmpb $70, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::imm(-76i32 as u32), r8), + Inst::cmp_rmi_r(1, RegMemImm::imm(-76i32 as u32), r8), "4180F8B4", "cmpb $-76, %r8b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::imm(76), rsi), + Inst::cmp_rmi_r(1, RegMemImm::imm(76), rsi), "4080FE4C", "cmpb $76, %sil", )); // Extra byte-cases (paranoia!) for cmp_rmi_r for first operand = R insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rax), rbx), + Inst::cmp_rmi_r(1, RegMemImm::reg(rax), rbx), "38C3", "cmpb %al, %bl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rbx), rax), + Inst::cmp_rmi_r(1, RegMemImm::reg(rbx), rax), "38D8", "cmpb %bl, %al", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), rdx), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), rdx), "38CA", "cmpb %cl, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), rsi), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), rsi), "4038CE", "cmpb %cl, %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), r10), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), r10), "4138CA", "cmpb %cl, %r10b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rcx), r14), + Inst::cmp_rmi_r(1, RegMemImm::reg(rcx), r14), "4138CE", "cmpb %cl, %r14b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rbp), rdx), + Inst::cmp_rmi_r(1, RegMemImm::reg(rbp), rdx), "4038EA", "cmpb %bpl, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rbp), rsi), + Inst::cmp_rmi_r(1, RegMemImm::reg(rbp), rsi), "4038EE", "cmpb %bpl, %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rbp), r10), + Inst::cmp_rmi_r(1, RegMemImm::reg(rbp), r10), "4138EA", "cmpb %bpl, %r10b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(rbp), r14), + Inst::cmp_rmi_r(1, RegMemImm::reg(rbp), r14), "4138EE", "cmpb %bpl, %r14b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r9), rdx), + Inst::cmp_rmi_r(1, RegMemImm::reg(r9), rdx), "4438CA", "cmpb %r9b, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r9), rsi), + Inst::cmp_rmi_r(1, RegMemImm::reg(r9), rsi), "4438CE", "cmpb %r9b, %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r9), r10), + Inst::cmp_rmi_r(1, RegMemImm::reg(r9), r10), "4538CA", "cmpb %r9b, %r10b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r9), r14), + Inst::cmp_rmi_r(1, RegMemImm::reg(r9), r14), "4538CE", "cmpb %r9b, %r14b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r13), rdx), + Inst::cmp_rmi_r(1, RegMemImm::reg(r13), rdx), "4438EA", "cmpb %r13b, %dl", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r13), rsi), + Inst::cmp_rmi_r(1, RegMemImm::reg(r13), rsi), "4438EE", "cmpb %r13b, %sil", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r13), r10), + Inst::cmp_rmi_r(1, RegMemImm::reg(r13), r10), "4538EA", "cmpb %r13b, %r10b", )); insns.push(( - Inst::cmp_rmi_r(1, RMI::reg(r13), r14), + Inst::cmp_rmi_r(1, RegMemImm::reg(r13), r14), "4538EE", "cmpb %r13b, %r14b", )); // ======================================================== // Push64 - insns.push((Inst::push64(RMI::reg(rdi)), "57", "pushq %rdi")); - insns.push((Inst::push64(RMI::reg(r8)), "4150", "pushq %r8")); + insns.push((Inst::push64(RegMemImm::reg(rdi)), "57", "pushq %rdi")); + insns.push((Inst::push64(RegMemImm::reg(r8)), "4150", "pushq %r8")); insns.push(( - Inst::push64(RMI::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), + Inst::push64(RegMemImm::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), "FFB4CE41010000", "pushq 321(%rsi,%rcx,8)", )); insns.push(( - Inst::push64(RMI::mem(Addr::imm_reg_reg_shift(321, r9, rbx, 2))), + Inst::push64(RegMemImm::mem(Addr::imm_reg_reg_shift(321, r9, rbx, 2))), "41FFB49941010000", "pushq 321(%r9,%rbx,4)", )); - insns.push((Inst::push64(RMI::imm(0)), "6A00", "pushq $0")); - insns.push((Inst::push64(RMI::imm(127)), "6A7F", "pushq $127")); - insns.push((Inst::push64(RMI::imm(128)), "6880000000", "pushq $128")); + insns.push((Inst::push64(RegMemImm::imm(0)), "6A00", "pushq $0")); + insns.push((Inst::push64(RegMemImm::imm(127)), "6A7F", "pushq $127")); insns.push(( - Inst::push64(RMI::imm(0x31415927)), + Inst::push64(RegMemImm::imm(128)), + "6880000000", + "pushq $128", + )); + insns.push(( + Inst::push64(RegMemImm::imm(0x31415927)), "6827594131", "pushq $826366247", )); insns.push(( - Inst::push64(RMI::imm(-128i32 as u32)), + Inst::push64(RegMemImm::imm(-128i32 as u32)), "6A80", "pushq $-128", )); insns.push(( - Inst::push64(RMI::imm(-129i32 as u32)), + Inst::push64(RegMemImm::imm(-129i32 as u32)), "687FFFFFFF", "pushq $-129", )); insns.push(( - Inst::push64(RMI::imm(-0x75c4e8a1i32 as u32)), + Inst::push64(RegMemImm::imm(-0x75c4e8a1i32 as u32)), "685F173B8A", "pushq $-1975838881", )); @@ -2161,15 +2255,23 @@ fn test_x64_emit() { // ======================================================== // CallUnknown - insns.push((Inst::call_unknown(RM::reg(rbp)), "FFD5", "call *%rbp")); - insns.push((Inst::call_unknown(RM::reg(r11)), "41FFD3", "call *%r11")); insns.push(( - Inst::call_unknown(RM::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), + Inst::call_unknown(RegMem::reg(rbp)), + "FFD5", + "call *%rbp", + )); + insns.push(( + Inst::call_unknown(RegMem::reg(r11)), + "41FFD3", + "call *%r11", + )); + insns.push(( + Inst::call_unknown(RegMem::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), "FF94CE41010000", "call *321(%rsi,%rcx,8)", )); insns.push(( - Inst::call_unknown(RM::mem(Addr::imm_reg_reg_shift(321, r10, rdx, 2))), + Inst::call_unknown(RegMem::mem(Addr::imm_reg_reg_shift(321, r10, rdx, 2))), "41FF949241010000", "call *321(%r10,%rdx,4)", )); @@ -2192,15 +2294,19 @@ fn test_x64_emit() { // ======================================================== // JmpUnknown - insns.push((Inst::jmp_unknown(RM::reg(rbp)), "FFE5", "jmp *%rbp")); - insns.push((Inst::jmp_unknown(RM::reg(r11)), "41FFE3", "jmp *%r11")); + insns.push((Inst::jmp_unknown(RegMem::reg(rbp)), "FFE5", "jmp *%rbp")); insns.push(( - Inst::jmp_unknown(RM::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), + Inst::jmp_unknown(RegMem::reg(r11)), + "41FFE3", + "jmp *%r11", + )); + insns.push(( + Inst::jmp_unknown(RegMem::mem(Addr::imm_reg_reg_shift(321, rsi, rcx, 3))), "FFA4CE41010000", "jmp *321(%rsi,%rcx,8)", )); insns.push(( - Inst::jmp_unknown(RM::mem(Addr::imm_reg_reg_shift(321, r10, rdx, 2))), + Inst::jmp_unknown(RegMem::mem(Addr::imm_reg_reg_shift(321, r10, rdx, 2))), "41FFA49241010000", "jmp *321(%r10,%rdx,4)", )); @@ -2209,32 +2315,32 @@ fn test_x64_emit() { // XMM_RM_R insns.push(( - Inst::xmm_rm_r(SSE_Op::SSE_Addss, RM::reg(xmm1), w_xmm0), + Inst::xmm_rm_r(SseOpcode::Addss, RegMem::reg(xmm1), w_xmm0), "F30F58C1", "addss %xmm1, %xmm0", )); insns.push(( - Inst::xmm_rm_r(SSE_Op::SSE_Subss, RM::reg(xmm0), w_xmm1), + Inst::xmm_rm_r(SseOpcode::Subss, RegMem::reg(xmm0), w_xmm1), "F30F5CC8", "subss %xmm0, %xmm1", )); insns.push(( - Inst::xmm_rm_r(SSE_Op::SSE_Addss, RM::reg(xmm11), w_xmm13), + Inst::xmm_rm_r(SseOpcode::Addss, RegMem::reg(xmm11), w_xmm13), "F3450F58EB", "addss %xmm11, %xmm13", )); insns.push(( - Inst::xmm_rm_r(SSE_Op::SSE_Subss, RM::reg(xmm12), w_xmm1), + Inst::xmm_rm_r(SseOpcode::Subss, RegMem::reg(xmm12), w_xmm1), "F3410F5CCC", "subss %xmm12, %xmm1", )); insns.push(( Inst::xmm_rm_r( - SSE_Op::SSE_Addss, - RM::mem(Addr::imm_reg_reg_shift(123, r10, rdx, 2)), + SseOpcode::Addss, + RegMem::mem(Addr::imm_reg_reg_shift(123, r10, rdx, 2)), w_xmm0, ), "F3410F5844927B", @@ -2243,8 +2349,8 @@ fn test_x64_emit() { insns.push(( Inst::xmm_rm_r( - SSE_Op::SSE_Subss, - RM::mem(Addr::imm_reg_reg_shift(321, r10, rax, 3)), + SseOpcode::Subss, + RegMem::mem(Addr::imm_reg_reg_shift(321, r10, rax, 3)), w_xmm10, ), "F3450F5C94C241010000", @@ -2255,13 +2361,13 @@ fn test_x64_emit() { // XMM_R_R insns.push(( - Inst::xmm_r_r(SSE_Op::SSE_Movss, xmm3, w_xmm2), + Inst::xmm_r_r(SseOpcode::Movss, xmm3, w_xmm2), "F30F10D3", "movss %xmm3, %xmm2", )); insns.push(( - Inst::xmm_r_r(SSE_Op::SSE2_Movsd, xmm4, w_xmm3), + Inst::xmm_r_r(SseOpcode::Movsd, xmm4, w_xmm3), "F20F10DC", "movsd %xmm4, %xmm3", )); diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 0676380752..0852f30857 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -44,8 +44,8 @@ pub(crate) enum Inst { /// (add sub and or xor mul adc? sbb?) (32 64) (reg addr imm) reg Alu_RMI_R { is_64: bool, - op: RMI_R_Op, - src: RMI, + op: AluRmiROpcode, + src: RegMemImm, dst: Writable, }, @@ -103,12 +103,12 @@ pub(crate) enum Inst { /// cmp (b w l q) (reg addr imm) reg Cmp_RMI_R { size: u8, // 1, 2, 4 or 8 - src: RMI, + src: RegMemImm, dst: Reg, }, /// pushq (reg addr imm) - Push64 { src: RMI }, + Push64 { src: RegMemImm }, /// popq reg Pop64 { dst: Writable }, @@ -122,7 +122,7 @@ pub(crate) enum Inst { /// callq (reg mem) CallUnknown { - dest: RM, + dest: RegMem, //uses: Set, //defs: Set>, }, @@ -149,18 +149,18 @@ pub(crate) enum Inst { }, /// jmpq (reg mem) - JmpUnknown { target: RM }, + JmpUnknown { target: RegMem }, /// (add sub and or xor mul adc? sbb?) (32 64) (reg addr imm) reg XMM_RM_R { - op: SSE_Op, - src: RM, + op: SseOpcode, + src: RegMem, dst: Writable, }, /// mov (64 32) reg reg XMM_R_R { - op: SSE_Op, + op: SseOpcode, src: Reg, dst: Writable, }, @@ -181,7 +181,12 @@ impl Inst { Self::Nop { len } } - pub(crate) fn alu_rmi_r(is_64: bool, op: RMI_R_Op, src: RMI, dst: Writable) -> Self { + pub(crate) fn alu_rmi_r( + is_64: bool, + op: AluRmiROpcode, + src: RegMemImm, + dst: Writable, + ) -> Self { debug_assert!(dst.to_reg().get_class() == RegClass::I64); Self::Alu_RMI_R { is_64, @@ -209,13 +214,13 @@ impl Inst { Inst::Mov_R_R { is_64, src, dst } } - pub(crate) fn xmm_r_r(op: SSE_Op, src: Reg, dst: Writable) -> Inst { + pub(crate) fn xmm_r_r(op: SseOpcode, src: Reg, dst: Writable) -> Inst { debug_assert!(src.get_class() == RegClass::V128); debug_assert!(dst.to_reg().get_class() == RegClass::V128); Inst::XMM_R_R { op, src, dst } } - pub(crate) fn xmm_rm_r(op: SSE_Op, src: RM, dst: Writable) -> Self { + pub(crate) fn xmm_rm_r(op: SseOpcode, src: RegMem, dst: Writable) -> Self { debug_assert!(dst.to_reg().get_class() == RegClass::V128); Self::XMM_RM_R { op, src, dst } } @@ -267,7 +272,7 @@ impl Inst { pub(crate) fn cmp_rmi_r( size: u8, // 1, 2, 4 or 8 - src: RMI, + src: RegMemImm, dst: Reg, ) -> Inst { debug_assert!(size == 8 || size == 4 || size == 2 || size == 1); @@ -275,7 +280,7 @@ impl Inst { Inst::Cmp_RMI_R { size, src, dst } } - pub(crate) fn push64(src: RMI) -> Inst { + pub(crate) fn push64(src: RegMemImm) -> Inst { Inst::Push64 { src } } @@ -283,7 +288,7 @@ impl Inst { Inst::Pop64 { dst } } - pub(crate) fn call_unknown(dest: RM) -> Inst { + pub(crate) fn call_unknown(dest: RegMem) -> Inst { Inst::CallUnknown { dest } } @@ -307,7 +312,7 @@ impl Inst { } } - pub(crate) fn jmp_unknown(target: RM) -> Inst { + pub(crate) fn jmp_unknown(target: RegMem) -> Inst { Inst::JmpUnknown { target } } } @@ -645,11 +650,11 @@ fn map_mod(m: &RUM, r: &mut Writable) { impl Addr { fn map_uses(&mut self, map: &RUM) { match self { - Addr::IR { + Addr::ImmReg { simm32: _, ref mut base, } => map_use(map, base), - Addr::IRRS { + Addr::ImmRegRegShift { simm32: _, ref mut base, ref mut index, @@ -662,21 +667,21 @@ impl Addr { } } -impl RMI { +impl RegMemImm { fn map_uses(&mut self, map: &RUM) { match self { - RMI::R { ref mut reg } => map_use(map, reg), - RMI::M { ref mut addr } => addr.map_uses(map), - RMI::I { simm32: _ } => {} + RegMemImm::Reg { ref mut reg } => map_use(map, reg), + RegMemImm::Mem { ref mut addr } => addr.map_uses(map), + RegMemImm::Imm { simm32: _ } => {} } } } -impl RM { +impl RegMem { fn map_uses(&mut self, map: &RUM) { match self { - RM::R { ref mut reg } => map_use(map, reg), - RM::M { ref mut addr } => addr.map_uses(map), + RegMem::Reg { ref mut reg } => map_use(map, reg), + RegMem::Mem { ref mut addr } => addr.map_uses(map), } } } @@ -812,7 +817,7 @@ impl MachInst for Inst { match self { Self::Mov_R_R { is_64, src, dst } if *is_64 => Some((*dst, *src)), Self::XMM_R_R { op, src, dst } - if *op == SSE_Op::SSE_Movss || *op == SSE_Op::SSE2_Movsd => + if *op == SseOpcode::Movss || *op == SseOpcode::Movsd => { Some((*dst, *src)) } @@ -843,16 +848,19 @@ impl MachInst for Inst { } } - fn gen_move(dst_reg: Writable, src_reg: Reg, _ty: Type) -> Inst { + fn gen_move(dst_reg: Writable, src_reg: Reg, ty: Type) -> Inst { let rc_dst = dst_reg.to_reg().get_class(); let rc_src = src_reg.get_class(); // If this isn't true, we have gone way off the rails. debug_assert!(rc_dst == rc_src); match rc_dst { RegClass::I64 => Inst::mov_r_r(true, src_reg, dst_reg), - // TODO: How do you just move 32 bits? - RegClass::V128 => Inst::xmm_r_r(SSE_Op::SSE2_Movsd, src_reg, dst_reg), - _ => panic!("gen_move(x64): unhandled regclass"), + RegClass::V128 => match ty { + F32 => Inst::xmm_r_r(SseOpcode::Movss, src_reg, dst_reg), + F64 => Inst::xmm_r_r(SseOpcode::Movsd, src_reg, dst_reg), + _ => panic!("unexpected V128 type in gen_move"), + }, + _ => panic!("gen_move(x64): unhandled gen_move"), } } diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index f306d867b0..3dab71bfc6 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -145,12 +145,12 @@ fn lower_insn_to_regs<'a>(ctx: Ctx<'a>, iri: IRInst) { let regR = input_to_reg(ctx, iri, 1); let is64 = int_ty_is_64(ty.unwrap()); let how = if op == Opcode::Iadd { - RMI_R_Op::Add + AluRmiROpcode::Add } else { - RMI_R_Op::Sub + AluRmiROpcode::Sub }; ctx.emit(Inst::mov_r_r(true, regL, regD)); - ctx.emit(Inst::alu_rmi_r(is64, how, RMI::reg(regR), regD)); + ctx.emit(Inst::alu_rmi_r(is64, how, RegMemImm::reg(regR), regD)); } Opcode::Ishl | Opcode::Ushr | Opcode::Sshr => { @@ -205,7 +205,7 @@ fn lower_insn_to_regs<'a>(ctx: Ctx<'a>, iri: IRInst) { if src_reg.get_class() == RegClass::I64 { ctx.emit(Inst::mov_r_r(true, src_reg, retval_reg)); } else if src_reg.get_class() == RegClass::V128 { - ctx.emit(Inst::xmm_r_r(SSE_Op::SSE2_Movsd, src_reg, retval_reg)); + ctx.emit(Inst::xmm_r_r(SseOpcode::Movsd, src_reg, retval_reg)); } } // N.B.: the Ret itself is generated by the ABI. @@ -247,12 +247,12 @@ fn lower_insn_to_regs<'a>(ctx: Ctx<'a>, iri: IRInst) { let is64 = flt_ty_is_64(ty.unwrap()); if !is64 { let inst = if op == Opcode::Fadd { - SSE_Op::SSE_Addss + SseOpcode::Addss } else { - SSE_Op::SSE_Subss + SseOpcode::Subss }; - ctx.emit(Inst::xmm_r_r(SSE_Op::SSE_Movss, regL, regD)); - ctx.emit(Inst::xmm_rm_r(inst, RM::reg(regR), regD)); + ctx.emit(Inst::xmm_r_r(SseOpcode::Movss, regL, regD)); + ctx.emit(Inst::xmm_rm_r(inst, RegMem::reg(regR), regD)); } else { unimplemented!("unimplemented lowering for opcode {:?}", op); } @@ -317,7 +317,7 @@ impl LowerBackend for X64Backend { _ => unreachable!(), }; let sizeB = int_ty_to_sizeB(tyS); - ctx.emit(Inst::cmp_rmi_r(sizeB, RMI::imm(0), rS)); + ctx.emit(Inst::cmp_rmi_r(sizeB, RegMemImm::imm(0), rS)); ctx.emit(Inst::jmp_cond_symm(cc, taken, not_taken)); } else { unimplemented = true; @@ -331,7 +331,7 @@ impl LowerBackend for X64Backend { let cc = intCC_to_x64_CC(inst_condcode(ctx.data(branches[0]))); let sizeB = int_ty_to_sizeB(tyS); // FIXME verify rSR vs rSL ordering - ctx.emit(Inst::cmp_rmi_r(sizeB, RMI::reg(rSR), rSL)); + ctx.emit(Inst::cmp_rmi_r(sizeB, RegMemImm::reg(rSR), rSL)); ctx.emit(Inst::jmp_cond_symm(cc, taken, not_taken)); } else { unimplemented = true;