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).
This commit is contained in:
@@ -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::<Reg>::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,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Inst>) {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
}
|
||||
} 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<Inst>) {
|
||||
// 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<Inst>) {
|
||||
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>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Inst::Imm_R {
|
||||
dst_is_64,
|
||||
simm64,
|
||||
@@ -482,6 +489,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
// 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>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Inst>) {
|
||||
}
|
||||
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<Inst>) {
|
||||
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>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Inst>) {
|
||||
}
|
||||
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<Inst>) {
|
||||
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>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Inst::Ret {} => sink.put1(0xC3),
|
||||
|
||||
Inst::JmpKnown { dest } => {
|
||||
@@ -895,6 +914,7 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
|
||||
sink.put1(0xE9);
|
||||
sink.put4(disp);
|
||||
}
|
||||
|
||||
Inst::JmpCondSymm {
|
||||
cc,
|
||||
taken,
|
||||
@@ -935,9 +955,10 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
|
||||
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<Inst>) {
|
||||
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>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Inst>) {
|
||||
} => {
|
||||
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<Inst>) {
|
||||
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<Inst>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => panic!("x64_emit: unhandled: {} ", inst.show_rru(None)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
));
|
||||
|
||||
@@ -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<Reg>,
|
||||
},
|
||||
|
||||
@@ -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<Reg> },
|
||||
@@ -122,7 +122,7 @@ pub(crate) enum Inst {
|
||||
|
||||
/// callq (reg mem)
|
||||
CallUnknown {
|
||||
dest: RM,
|
||||
dest: RegMem,
|
||||
//uses: Set<Reg>,
|
||||
//defs: Set<Writable<Reg>>,
|
||||
},
|
||||
@@ -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<Reg>,
|
||||
},
|
||||
|
||||
/// mov (64 32) reg reg
|
||||
XMM_R_R {
|
||||
op: SSE_Op,
|
||||
op: SseOpcode,
|
||||
src: Reg,
|
||||
dst: Writable<Reg>,
|
||||
},
|
||||
@@ -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<Reg>) -> Self {
|
||||
pub(crate) fn alu_rmi_r(
|
||||
is_64: bool,
|
||||
op: AluRmiROpcode,
|
||||
src: RegMemImm,
|
||||
dst: Writable<Reg>,
|
||||
) -> 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<Reg>) -> Inst {
|
||||
pub(crate) fn xmm_r_r(op: SseOpcode, src: Reg, dst: Writable<Reg>) -> 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<Reg>) -> Self {
|
||||
pub(crate) fn xmm_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> 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<RUM: RegUsageMapper>(m: &RUM, r: &mut Writable<Reg>) {
|
||||
impl Addr {
|
||||
fn map_uses<RUM: RegUsageMapper>(&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<RUM: RegUsageMapper>(&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<RUM: RegUsageMapper>(&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<Reg>, src_reg: Reg, _ty: Type) -> Inst {
|
||||
fn gen_move(dst_reg: Writable<Reg>, 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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user