cranelift: Use GPR newtypes extensively in x64 lowering (#3798)

We already defined the `Gpr` newtype and used it in a few places, and we already
defined the `Xmm` newtype and used it extensively. This finishes the transition
to using the newtypes extensively in lowering by making use of `Gpr` in more
places.

Fixes #3685
This commit is contained in:
Nick Fitzgerald
2022-02-14 12:54:41 -08:00
committed by GitHub
parent 84b9c7bb8a
commit dc86e7a6dc
9 changed files with 1804 additions and 1482 deletions

View File

@@ -133,9 +133,9 @@ impl Inst {
Self::AluRmiR {
size,
op,
src1: dst.to_reg(),
src2: src,
dst,
src1: Gpr::new(dst.to_reg()).unwrap(),
src2: GprMemImm::new(src).unwrap(),
dst: WritableGpr::from_writable_reg(dst).unwrap(),
}
}
@@ -174,10 +174,10 @@ impl Inst {
Inst::Div {
size,
signed,
divisor,
dividend: regs::rax(),
dst_quotient: Writable::from_reg(regs::rax()),
dst_remainder: Writable::from_reg(regs::rdx()),
divisor: GprMem::new(divisor).unwrap(),
dividend: Gpr::new(regs::rax()).unwrap(),
dst_quotient: WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()),
dst_remainder: Writable::from_reg(Gpr::new(regs::rdx()).unwrap()),
}
}
@@ -191,10 +191,10 @@ impl Inst {
Inst::MulHi {
size,
signed,
src1: regs::rax(),
src2: rhs,
dst_lo: Writable::from_reg(regs::rax()),
dst_hi: Writable::from_reg(regs::rdx()),
src1: Gpr::new(regs::rax()).unwrap(),
src2: GprMem::new(rhs).unwrap(),
dst_lo: WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()),
dst_hi: WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()),
}
}
@@ -211,19 +211,19 @@ impl Inst {
Inst::CheckedDivOrRemSeq {
kind,
size,
divisor,
dividend: regs::rax(),
dst_quotient: Writable::from_reg(regs::rax()),
dst_remainder: Writable::from_reg(regs::rdx()),
tmp,
divisor: WritableGpr::from_writable_reg(divisor).unwrap(),
dividend: Gpr::new(regs::rax()).unwrap(),
dst_quotient: Writable::from_reg(Gpr::new(regs::rax()).unwrap()),
dst_remainder: Writable::from_reg(Gpr::new(regs::rdx()).unwrap()),
tmp: tmp.map(|tmp| WritableGpr::from_writable_reg(tmp).unwrap()),
}
}
pub(crate) fn sign_extend_data(size: OperandSize) -> Inst {
Inst::SignExtendData {
size,
src: regs::rax(),
dst: Writable::from_reg(regs::rdx()),
src: Gpr::new(regs::rax()).unwrap(),
dst: Writable::from_reg(Gpr::new(regs::rdx()).unwrap()),
}
}
@@ -239,7 +239,7 @@ impl Inst {
Inst::Imm {
dst_size,
simm64,
dst,
dst: WritableGpr::from_writable_reg(dst).unwrap(),
}
}
@@ -247,6 +247,8 @@ impl Inst {
debug_assert!(size.is_one_of(&[OperandSize::Size32, OperandSize::Size64]));
debug_assert!(src.get_class() == RegClass::I64);
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
let src = Gpr::new(src).unwrap();
let dst = WritableGpr::from_writable_reg(dst).unwrap();
Inst::MovRR { size, src, dst }
}
@@ -360,7 +362,7 @@ impl Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::V128);
Inst::GprToXmm {
op,
src,
src: GprMem::new(src).unwrap(),
dst: WritableXmm::from_writable_reg(dst).unwrap(),
src_size,
}
@@ -369,6 +371,8 @@ impl Inst {
pub(crate) fn xmm_cmp_rm_r(op: SseOpcode, src: RegMem, dst: Reg) -> Inst {
src.assert_regclass_is(RegClass::V128);
debug_assert!(dst.get_class() == RegClass::V128);
let src = XmmMem::new(src).unwrap();
let dst = Xmm::new(dst).unwrap();
Inst::XmmCmpRmR { op, src, dst }
}
@@ -457,8 +461,8 @@ impl Inst {
Inst::XmmMinMaxSeq {
size,
is_min,
lhs,
rhs_dst,
lhs: Xmm::new(lhs).unwrap(),
rhs_dst: WritableXmm::from_writable_reg(rhs_dst).unwrap(),
}
}
@@ -483,6 +487,8 @@ impl Inst {
pub(crate) fn movzx_rm_r(ext_mode: ExtMode, src: RegMem, dst: Writable<Reg>) -> Inst {
src.assert_regclass_is(RegClass::I64);
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
let src = GprMem::new(src).unwrap();
let dst = WritableGpr::from_writable_reg(dst).unwrap();
Inst::MovzxRmR { ext_mode, src, dst }
}
@@ -500,6 +506,8 @@ impl Inst {
pub(crate) fn movsx_rm_r(ext_mode: ExtMode, src: RegMem, dst: Writable<Reg>) -> Inst {
src.assert_regclass_is(RegClass::I64);
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
let src = GprMem::new(src).unwrap();
let dst = WritableGpr::from_writable_reg(dst).unwrap();
Inst::MovsxRmR { ext_mode, src, dst }
}
@@ -507,7 +515,7 @@ impl Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
Inst::Mov64MR {
src: src.into(),
dst,
dst: WritableGpr::from_writable_reg(dst).unwrap(),
}
}
@@ -524,7 +532,7 @@ impl Inst {
debug_assert!(src.get_class() == RegClass::I64);
Inst::MovRM {
size,
src,
src: Gpr::new(src).unwrap(),
dst: dst.into(),
}
}
@@ -552,12 +560,13 @@ impl Inst {
Inst::ShiftR {
size,
kind,
src: dst.to_reg(),
num_bits: match num_bits {
src: Gpr::new(dst.to_reg()).unwrap(),
num_bits: Imm8Gpr::new(match num_bits {
Some(imm) => Imm8Reg::Imm8 { imm },
None => Imm8Reg::Reg { reg: regs::rcx() },
},
dst,
})
.unwrap(),
dst: WritableGpr::from_writable_reg(dst).unwrap(),
}
}
@@ -568,8 +577,8 @@ impl Inst {
debug_assert_eq!(dst.get_class(), RegClass::I64);
Inst::CmpRmiR {
size,
src,
dst,
src: GprMemImm::new(src).unwrap(),
dst: Gpr::new(dst).unwrap(),
opcode: CmpOpcode::Cmp,
}
}
@@ -580,8 +589,8 @@ impl Inst {
debug_assert_eq!(dst.get_class(), RegClass::I64);
Inst::CmpRmiR {
size,
src,
dst,
src: GprMemImm::new(src).unwrap(),
dst: Gpr::new(dst).unwrap(),
opcode: CmpOpcode::Test,
}
}
@@ -594,6 +603,7 @@ impl Inst {
pub(crate) fn setcc(cc: CC, dst: Writable<Reg>) -> Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
let dst = WritableGpr::from_writable_reg(dst).unwrap();
Inst::Setcc { cc, dst }
}
@@ -607,9 +617,9 @@ impl Inst {
Inst::Cmove {
size,
cc,
consequent: src,
alternative: dst.to_reg(),
dst,
consequent: GprMem::new(src).unwrap(),
alternative: Gpr::new(dst.to_reg()).unwrap(),
dst: WritableGpr::from_writable_reg(dst).unwrap(),
}
}
@@ -617,16 +627,20 @@ impl Inst {
debug_assert!(size.is_one_of(&[OperandSize::Size32, OperandSize::Size64]));
src.assert_regclass_is(RegClass::V128);
debug_assert!(dst.to_reg().get_class() == RegClass::V128);
let src = XmmMem::new(src).unwrap();
let dst = WritableXmm::from_writable_reg(dst).unwrap();
Inst::XmmCmove { size, cc, src, dst }
}
pub(crate) fn push64(src: RegMemImm) -> Inst {
src.assert_regclass_is(RegClass::I64);
let src = GprMemImm::new(src).unwrap();
Inst::Push64 { src }
}
pub(crate) fn pop64(dst: Writable<Reg>) -> Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
let dst = WritableGpr::from_writable_reg(dst).unwrap();
Inst::Pop64 { dst }
}
@@ -780,7 +794,7 @@ impl Inst {
fn produces_const(&self) -> bool {
match self {
Self::AluRmiR { op, src2, dst, .. } => {
src2.to_reg() == Some(dst.to_reg())
src2.clone().to_reg_mem_imm().to_reg() == Some(dst.to_reg().to_reg())
&& (*op == AluRmiROpcode::Xor || *op == AluRmiROpcode::Sub)
}
@@ -838,7 +852,11 @@ impl Inst {
Inst::AluRmiR { src1, dst, .. } => {
if *src1 != dst.to_reg() {
debug_assert!(src1.is_virtual());
insts.push(Self::gen_move(*dst, *src1, types::I64));
insts.push(Self::gen_move(
dst.to_writable_reg(),
src1.to_reg(),
types::I64,
));
*src1 = dst.to_reg();
}
insts.push(self);
@@ -883,7 +901,11 @@ impl Inst {
} => {
if *alternative != dst.to_reg() {
debug_assert!(alternative.is_virtual());
insts.push(Self::mov_r_r(*size, *alternative, *dst));
insts.push(Self::mov_r_r(
*size,
alternative.to_reg(),
dst.to_writable_reg(),
));
*alternative = dst.to_reg();
}
insts.push(self);
@@ -916,22 +938,30 @@ impl Inst {
debug_assert!(dividend.is_virtual());
insts.push(Self::gen_move(
Writable::from_reg(regs::rax()),
*dividend,
dividend.to_reg(),
types::I64,
));
*dividend = regs::rax();
*dividend = Gpr::new(regs::rax()).unwrap();
}
let mut quotient_mov = None;
if dst_quotient.to_reg() != regs::rax() {
debug_assert!(dst_quotient.to_reg().is_virtual());
quotient_mov = Some(Self::gen_move(*dst_quotient, regs::rax(), types::I64));
*dst_quotient = Writable::from_reg(regs::rax());
quotient_mov = Some(Self::gen_move(
dst_quotient.to_writable_reg(),
regs::rax(),
types::I64,
));
*dst_quotient = Writable::from_reg(Gpr::new(regs::rax()).unwrap());
}
let mut remainder_mov = None;
if dst_remainder.to_reg() != regs::rdx() {
debug_assert!(dst_remainder.to_reg().is_virtual());
remainder_mov = Some(Self::gen_move(*dst_remainder, regs::rdx(), types::I64));
*dst_remainder = Writable::from_reg(regs::rdx());
remainder_mov = Some(Self::gen_move(
dst_remainder.to_writable_reg(),
regs::rdx(),
types::I64,
));
*dst_remainder = Writable::from_reg(Gpr::new(regs::rdx()).unwrap());
}
insts.push(self);
insts.extend(quotient_mov);
@@ -947,22 +977,30 @@ impl Inst {
debug_assert!(src1.is_virtual());
insts.push(Self::gen_move(
Writable::from_reg(regs::rax()),
*src1,
src1.to_reg(),
types::I64,
));
*src1 = regs::rax();
*src1 = Gpr::new(regs::rax()).unwrap();
}
let mut dst_lo_mov = None;
if dst_lo.to_reg() != regs::rax() {
debug_assert!(dst_lo.to_reg().is_virtual());
dst_lo_mov = Some(Self::gen_move(*dst_lo, regs::rax(), types::I64));
*dst_lo = Writable::from_reg(regs::rax());
dst_lo_mov = Some(Self::gen_move(
dst_lo.to_writable_reg(),
regs::rax(),
types::I64,
));
*dst_lo = Writable::from_reg(Gpr::new(regs::rax()).unwrap());
}
let mut dst_hi_mov = None;
if dst_hi.to_reg() != regs::rdx() {
debug_assert!(dst_hi.to_reg().is_virtual());
dst_hi_mov = Some(Self::gen_move(*dst_hi, regs::rdx(), types::I64));
*dst_hi = Writable::from_reg(regs::rdx());
dst_hi_mov = Some(Self::gen_move(
dst_hi.to_writable_reg(),
regs::rdx(),
types::I64,
));
*dst_hi = Writable::from_reg(Gpr::new(regs::rdx()).unwrap());
}
insts.push(self);
insts.extend(dst_lo_mov);
@@ -973,16 +1011,20 @@ impl Inst {
debug_assert!(src.is_virtual());
insts.push(Self::gen_move(
Writable::from_reg(regs::rax()),
*src,
src.to_reg(),
types::I64,
));
*src = regs::rax();
*src = Gpr::new(regs::rax()).unwrap();
}
let mut dst_mov = None;
if dst.to_reg() != regs::rax() {
debug_assert!(dst.to_reg().is_virtual());
dst_mov = Some(Self::gen_move(*dst, dst.to_reg(), types::I64));
*dst = Writable::from_reg(regs::rax());
dst_mov = Some(Self::gen_move(
dst.to_writable_reg(),
dst.to_reg().to_reg(),
types::I64,
));
*dst = Writable::from_reg(Gpr::new(regs::rax()).unwrap());
}
insts.push(self);
insts.extend(dst_mov);
@@ -992,18 +1034,22 @@ impl Inst {
} => {
if *src != dst.to_reg() {
debug_assert!(src.is_virtual());
insts.push(Self::gen_move(*dst, *src, types::I64));
insts.push(Self::gen_move(
dst.to_writable_reg(),
src.to_reg(),
types::I64,
));
*src = dst.to_reg();
}
if let Imm8Reg::Reg { reg } = num_bits {
if *reg != regs::rcx() {
if let Imm8Reg::Reg { reg } = num_bits.clone().to_imm8_reg() {
if reg != regs::rcx() {
debug_assert!(reg.is_virtual());
insts.push(Self::gen_move(
Writable::from_reg(regs::rcx()),
*reg,
reg,
types::I64,
));
*reg = regs::rcx();
*num_bits = Imm8Gpr::new(Imm8Reg::Reg { reg: regs::rcx() }).unwrap();
}
}
insts.push(self);
@@ -1146,7 +1192,7 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify2(op.to_string(), suffix_lqb(*size, op.is_8bit())),
src2.show_rru_sized(mb_rru, size_lqb(*size, op.is_8bit())),
show_ireg_sized(dst.to_reg(), mb_rru, size_lqb(*size, op.is_8bit())),
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size_lqb(*size, op.is_8bit())),
),
Inst::UnaryRmR { src, dst, op, size } => format!(
@@ -1208,7 +1254,7 @@ impl PrettyPrint for Inst {
DivOrRemKind::SignedRem => "srem",
DivOrRemKind::UnsignedRem => "urem",
},
show_ireg_sized(divisor.to_reg(), mb_rru, size.to_bytes()),
show_ireg_sized(divisor.to_reg().to_reg(), mb_rru, size.to_bytes()),
),
Inst::SignExtendData { size, .. } => match size {
@@ -1276,8 +1322,8 @@ impl PrettyPrint for Inst {
},
format!("f{}", size.to_bits())
),
show_ireg_sized(*lhs, mb_rru, 8),
show_ireg_sized(rhs_dst.to_reg(), mb_rru, 8),
show_ireg_sized(lhs.to_reg(), mb_rru, 8),
show_ireg_sized(rhs_dst.to_reg().to_reg(), mb_rru, 8),
),
Inst::XmmRmRImm {
@@ -1342,7 +1388,7 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify(op.to_string()),
src.show_rru_sized(mb_rru, 8),
show_ireg_sized(*dst, mb_rru, 8),
show_ireg_sized(dst.to_reg(), mb_rru, 8),
),
Inst::CvtUint64ToFloatSeq {
@@ -1405,14 +1451,14 @@ impl PrettyPrint for Inst {
"{} ${}, {}",
ljustify("movabsq".to_string()),
*simm64 as i64,
show_ireg_sized(dst.to_reg(), mb_rru, 8)
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, 8)
)
} else {
format!(
"{} ${}, {}",
ljustify("movl".to_string()),
(*simm64 as u32) as i32,
show_ireg_sized(dst.to_reg(), mb_rru, 4)
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, 4)
)
}
}
@@ -1420,8 +1466,8 @@ impl PrettyPrint for Inst {
Inst::MovRR { size, src, dst } => format!(
"{} {}, {}",
ljustify2("mov".to_string(), suffix_lq(*size)),
show_ireg_sized(*src, mb_rru, size.to_bytes()),
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
show_ireg_sized(src.to_reg(), mb_rru, size.to_bytes()),
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size.to_bytes())
),
Inst::MovzxRmR {
@@ -1432,14 +1478,14 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify("movl".to_string()),
src.show_rru_sized(mb_rru, ext_mode.src_size()),
show_ireg_sized(dst.to_reg(), mb_rru, 4)
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, 4)
)
} else {
format!(
"{} {}, {}",
ljustify2("movz".to_string(), ext_mode.to_string()),
src.show_rru_sized(mb_rru, ext_mode.src_size()),
show_ireg_sized(dst.to_reg(), mb_rru, ext_mode.dst_size())
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, ext_mode.dst_size())
)
}
}
@@ -1464,13 +1510,13 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify2("movs".to_string(), ext_mode.to_string()),
src.show_rru_sized(mb_rru, ext_mode.src_size()),
show_ireg_sized(dst.to_reg(), mb_rru, ext_mode.dst_size())
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, ext_mode.dst_size())
),
Inst::MovRM { size, src, dst, .. } => format!(
"{} {}, {}",
ljustify2("mov".to_string(), suffix_bwlq(*size)),
show_ireg_sized(*src, mb_rru, size.to_bytes()),
show_ireg_sized(src.to_reg(), mb_rru, size.to_bytes()),
dst.show_rru(mb_rru)
),
@@ -1480,19 +1526,19 @@ impl PrettyPrint for Inst {
num_bits,
dst,
..
} => match num_bits {
} => match num_bits.clone().to_imm8_reg() {
Imm8Reg::Reg { reg } => format!(
"{} {}, {}",
ljustify2(kind.to_string(), suffix_bwlq(*size)),
show_ireg_sized(*reg, mb_rru, 1),
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
show_ireg_sized(reg, mb_rru, 1),
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size.to_bytes())
),
Imm8Reg::Imm8 { imm: num_bits } => format!(
"{} ${}, {}",
ljustify2(kind.to_string(), suffix_bwlq(*size)),
num_bits,
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size.to_bytes())
),
},
@@ -1519,14 +1565,14 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify2(op.to_string(), suffix_bwlq(*size)),
src.show_rru_sized(mb_rru, size.to_bytes()),
show_ireg_sized(*dst, mb_rru, size.to_bytes())
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
)
}
Inst::Setcc { cc, dst } => format!(
"{} {}",
ljustify2("set".to_string(), cc.to_string()),
show_ireg_sized(dst.to_reg(), mb_rru, 1)
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, 1)
),
Inst::Cmove {
@@ -1539,7 +1585,7 @@ impl PrettyPrint for Inst {
"{} {}, {}",
ljustify(format!("cmov{}{}", cc.to_string(), suffix_bwlq(*size))),
src.show_rru_sized(mb_rru, size.to_bytes()),
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size.to_bytes())
),
Inst::XmmCmove { size, cc, src, dst } => {
@@ -1552,7 +1598,7 @@ impl PrettyPrint for Inst {
"ss"
},
src.show_rru_sized(mb_rru, size.to_bytes()),
show_ireg_sized(dst.to_reg(), mb_rru, size.to_bytes())
show_ireg_sized(dst.to_reg().to_reg(), mb_rru, size.to_bytes())
)
}
@@ -1693,10 +1739,10 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
debug_assert_eq!(*src1, dst.to_reg());
if inst.produces_const() {
// No need to account for src2, since src2 == dst.
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
} else {
src2.get_regs_as_uses(collector);
collector.add_mod(*dst);
collector.add_mod(dst.to_writable_reg());
}
}
Inst::Not { src, dst, .. } => {
@@ -1760,9 +1806,9 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
// the rdx register *before* the instruction, which is not too bad.
collector.add_mod(Writable::from_reg(regs::rax()));
collector.add_mod(Writable::from_reg(regs::rdx()));
collector.add_mod(*divisor);
collector.add_mod(divisor.to_writable_reg());
if let Some(tmp) = tmp {
collector.add_def(*tmp);
collector.add_def(tmp.to_writable_reg());
}
}
Inst::SignExtendData { size, src, dst } => {
@@ -1852,8 +1898,8 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
Inst::XmmUninitializedValue { dst } => collector.add_def(dst.to_writable_reg()),
Inst::XmmLoadConst { dst, .. } => collector.add_def(*dst),
Inst::XmmMinMaxSeq { lhs, rhs_dst, .. } => {
collector.add_use(*lhs);
collector.add_mod(*rhs_dst);
collector.add_use(lhs.to_reg());
collector.add_mod(rhs_dst.to_writable_reg());
}
Inst::XmmRmiReg {
src1, src2, dst, ..
@@ -1868,14 +1914,14 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
}
Inst::XmmCmpRmR { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_use(*dst);
collector.add_use(dst.to_reg());
}
Inst::Imm { dst, .. } => {
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
}
Inst::MovRR { src, dst, .. } => {
collector.add_use(*src);
collector.add_def(*dst);
collector.add_use(src.to_reg());
collector.add_def(dst.to_writable_reg());
}
Inst::XmmToGpr { src, dst, .. } => {
collector.add_use(src.to_reg());
@@ -1918,11 +1964,11 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
}
Inst::MovzxRmR { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
}
Inst::Mov64MR { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_def(*dst)
collector.add_def(dst.to_writable_reg())
}
Inst::LoadEffectiveAddress { addr: src, dst } => {
src.get_regs_as_uses(collector);
@@ -1930,41 +1976,44 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
}
Inst::MovsxRmR { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
}
Inst::MovRM { src, dst, .. } => {
collector.add_use(*src);
collector.add_use(src.to_reg());
dst.get_regs_as_uses(collector);
}
Inst::ShiftR { num_bits, dst, .. } => {
if let Imm8Reg::Reg { reg } = num_bits {
debug_assert_eq!(*reg, regs::rcx());
if let Imm8Reg::Reg { reg } = num_bits.clone().to_imm8_reg() {
debug_assert_eq!(reg, regs::rcx());
collector.add_use(regs::rcx());
}
collector.add_mod(*dst);
collector.add_mod(dst.to_writable_reg());
}
Inst::CmpRmiR { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_use(*dst); // yes, really `add_use`
collector.add_use(dst.to_reg()); // yes, really `add_use`
}
Inst::Setcc { dst, .. } => {
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
}
Inst::Cmove {
consequent: src,
dst,
..
}
| Inst::XmmCmove { src, dst, .. } => {
} => {
src.get_regs_as_uses(collector);
collector.add_mod(*dst);
collector.add_mod(dst.to_writable_reg());
}
Inst::XmmCmove { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_mod(dst.to_writable_reg());
}
Inst::Push64 { src } => {
src.get_regs_as_uses(collector);
collector.add_mod(Writable::from_reg(regs::rsp()));
}
Inst::Pop64 { dst } => {
collector.add_def(*dst);
collector.add_def(dst.to_writable_reg());
}
Inst::CallKnown {
@@ -2149,11 +2198,11 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
debug_assert_eq!(*src1, dst.to_reg());
if produces_const {
src2.map_as_def(mapper);
mapper.map_def(dst);
dst.map_def(mapper);
*src1 = dst.to_reg();
} else {
src2.map_uses(mapper);
mapper.map_mod(dst);
dst.map_mod(mapper);
*src1 = dst.to_reg();
}
}
@@ -2165,9 +2214,9 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
Inst::Div { divisor, .. } => divisor.map_uses(mapper),
Inst::MulHi { src2, .. } => src2.map_uses(mapper),
Inst::CheckedDivOrRemSeq { divisor, tmp, .. } => {
mapper.map_mod(divisor);
divisor.map_mod(mapper);
if let Some(tmp) = tmp {
mapper.map_def(tmp)
tmp.map_def(mapper)
}
}
Inst::SignExtendData { .. } => {}
@@ -2275,8 +2324,8 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
ref mut rhs_dst,
..
} => {
mapper.map_use(lhs);
mapper.map_mod(rhs_dst);
lhs.map_use(mapper);
rhs_dst.map_mod(mapper);
}
Inst::XmmMovRM {
ref mut src,
@@ -2292,16 +2341,16 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_use(dst);
dst.map_use(mapper);
}
Inst::Imm { ref mut dst, .. } => mapper.map_def(dst),
Inst::Imm { ref mut dst, .. } => dst.map_def(mapper),
Inst::MovRR {
ref mut src,
ref mut dst,
..
} => {
mapper.map_use(src);
mapper.map_def(dst);
src.map_use(mapper);
dst.map_def(mapper);
}
Inst::XmmToGpr {
ref mut src,
@@ -2356,11 +2405,11 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_def(dst);
dst.map_def(mapper);
}
Inst::Mov64MR { src, dst, .. } => {
src.map_uses(mapper);
mapper.map_def(dst);
dst.map_def(mapper);
}
Inst::LoadEffectiveAddress { addr: src, dst } => {
src.map_uses(mapper);
@@ -2372,14 +2421,14 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_def(dst);
dst.map_def(mapper);
}
Inst::MovRM {
ref mut src,
ref mut dst,
..
} => {
mapper.map_use(src);
src.map_use(mapper);
dst.map_uses(mapper);
}
Inst::ShiftR {
@@ -2388,7 +2437,7 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
debug_assert_eq!(*src, dst.to_reg());
mapper.map_mod(dst);
dst.map_mod(mapper);
*src = dst.to_reg();
}
Inst::CmpRmiR {
@@ -2397,9 +2446,9 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_use(dst);
dst.map_use(mapper);
}
Inst::Setcc { ref mut dst, .. } => mapper.map_def(dst),
Inst::Setcc { ref mut dst, .. } => dst.map_def(mapper),
Inst::Cmove {
consequent: ref mut src,
ref mut dst,
@@ -2407,7 +2456,7 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_mod(dst);
dst.map_mod(mapper);
*alternative = dst.to_reg();
}
Inst::XmmCmove {
@@ -2416,11 +2465,11 @@ pub(crate) fn x64_map_regs<RM: RegMapper>(inst: &mut Inst, mapper: &RM) {
..
} => {
src.map_uses(mapper);
mapper.map_mod(dst);
dst.map_mod(mapper);
}
Inst::Push64 { ref mut src } => src.map_uses(mapper),
Inst::Pop64 { ref mut dst } => {
mapper.map_def(dst);
dst.map_def(mapper);
}
Inst::CallKnown {
@@ -2520,7 +2569,7 @@ impl MachInst for Inst {
// conceivably use `movl %reg, %reg` to zero out the top 32 bits of
// %reg.
Self::MovRR { size, src, dst, .. } if *size == OperandSize::Size64 => {
Some((*dst, *src))
Some((dst.to_writable_reg(), src.to_reg()))
}
// Note as well that MOVS[S|D] when used in the `XmmUnaryRmR` context are pure moves of
// scalar floating-point values (and annotate `dst` as `def`s to the register allocator)
@@ -2578,12 +2627,15 @@ impl MachInst for Inst {
size: OperandSize::Size8,
src,
dst: SyntheticAmode::NominalSPOffset { simm32 },
} => Some(MachInstStackOpInfo::StoreNomSPOff(*src, *simm32 as i64)),
} => Some(MachInstStackOpInfo::StoreNomSPOff(
src.to_reg(),
*simm32 as i64,
)),
Self::Mov64MR {
src: SyntheticAmode::NominalSPOffset { simm32 },
dst,
} => Some(MachInstStackOpInfo::LoadNomSPOff(
dst.to_reg(),
dst.to_reg().to_reg(),
*simm32 as i64,
)),
_ => None,