Remove xmm_r_r inst data structure and cases after related refactoring

Removes unneeded data structure that was holding instructions for
xmm based move instructions. These instructions can should be categorized
as rm not just r. This change is intended to simplify organization and
cases when lowering.
This commit is contained in:
Johnnie Birch
2020-06-06 16:20:08 -07:00
committed by Benjamin Bouvier
parent f2f7706265
commit 2d364f75bd
6 changed files with 23 additions and 83 deletions

View File

@@ -280,7 +280,11 @@ impl ABIBody for X64ABIBody {
return Inst::mov_r_r(/*is64=*/ true, from_reg.to_reg(), to_reg); return Inst::mov_r_r(/*is64=*/ true, from_reg.to_reg(), to_reg);
} else if from_reg.get_class() == RegClass::V128 { } else if from_reg.get_class() == RegClass::V128 {
// TODO: How to support Movss. Should is64 always be true? // TODO: How to support Movss. Should is64 always be true?
return Inst::xmm_r_r(SseOpcode::Movsd, from_reg.to_reg(), to_reg); return Inst::xmm_mov_rm_r(
SseOpcode::Movsd,
RegMem::reg(from_reg.to_reg()),
to_reg,
);
} }
unimplemented!("moving from non-int arg to vreg {:?}", from_reg.get_class()); unimplemented!("moving from non-int arg to vreg {:?}", from_reg.get_class());
} }
@@ -316,9 +320,9 @@ impl ABIBody for X64ABIBody {
Writable::<Reg>::from_reg(to_reg.to_reg()), Writable::<Reg>::from_reg(to_reg.to_reg()),
)) ))
} else if to_reg.get_class() == RegClass::V128 { } else if to_reg.get_class() == RegClass::V128 {
ret.push(Inst::xmm_r_r( ret.push(Inst::xmm_mov_rm_r(
SseOpcode::Movsd, SseOpcode::Movsd,
from_reg.to_reg(), RegMem::reg(from_reg.to_reg()),
Writable::<Reg>::from_reg(to_reg.to_reg()), Writable::<Reg>::from_reg(to_reg.to_reg()),
)) ))
} else { } else {

View File

@@ -302,7 +302,7 @@ impl SseOpcode {
} }
} }
/// Returns src register operand size for an instruction /// Returns the src operand size for an instruction
pub(crate) fn src_size(&self) -> u8 { pub(crate) fn src_size(&self) -> u8 {
match self { match self {
SseOpcode::Movd => 4, SseOpcode::Movd => 4,

View File

@@ -1025,32 +1025,6 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
} }
} }
Inst::XMM_R_R { op, src, dst } => {
let opcode = match op {
SseOpcode::Movss => 0x0F10,
SseOpcode::Movsd => 0x0F10,
SseOpcode::Movd => 0x0F6E,
_ => unimplemented!("XMM_R_R opcode"),
};
let prefix = match op {
SseOpcode::Movss => LegacyPrefix::_F3,
SseOpcode::Movsd => LegacyPrefix::_F2,
SseOpcode::Movd => LegacyPrefix::_66,
_ => unimplemented!("XMM_R_R opcode"),
};
emit_std_reg_reg(
sink,
prefix,
opcode,
2,
dst.to_reg(),
*src,
RexFlags::clear_w(),
);
}
Inst::XMM_MOV_RM_R { Inst::XMM_MOV_RM_R {
op, op,
src: src_e, src: src_e,

View File

@@ -2408,21 +2408,6 @@ fn test_x64_emit() {
"movsd %xmm14, %xmm3", "movsd %xmm14, %xmm3",
)); ));
// ========================================================
// XMM_R_R
insns.push((
Inst::xmm_r_r(SseOpcode::Movss, xmm3, w_xmm2),
"F30F10D3",
"movss %xmm3, %xmm2",
));
insns.push((
Inst::xmm_r_r(SseOpcode::Movsd, xmm4, w_xmm3),
"F20F10DC",
"movsd %xmm4, %xmm3",
));
// ======================================================== // ========================================================
// Actually run the tests! // Actually run the tests!
let flags = settings::Flags::new(settings::builder()); let flags = settings::Flags::new(settings::builder());

View File

@@ -169,13 +169,6 @@ pub(crate) enum Inst {
src: RegMem, src: RegMem,
dst: Writable<Reg>, dst: Writable<Reg>,
}, },
/// mov (64 32) reg reg
XMM_R_R {
op: SseOpcode,
src: Reg,
dst: Writable<Reg>,
},
} }
// Handy constructors for Insts. // Handy constructors for Insts.
@@ -226,12 +219,6 @@ impl Inst {
Inst::Mov_R_R { is_64, src, dst } Inst::Mov_R_R { is_64, src, dst }
} }
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_mov_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> Inst { pub(crate) fn xmm_mov_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::V128); debug_assert!(dst.to_reg().get_class() == RegClass::V128);
Inst::XMM_MOV_RM_R { op, src, dst } Inst::XMM_MOV_RM_R { op, src, dst }
@@ -427,12 +414,6 @@ impl ShowWithRRU for Inst {
show_ireg_sized(*src, mb_rru, sizeLQ(*is_64)), show_ireg_sized(*src, mb_rru, sizeLQ(*is_64)),
show_ireg_sized(dst.to_reg(), mb_rru, sizeLQ(*is_64)) show_ireg_sized(dst.to_reg(), mb_rru, sizeLQ(*is_64))
), ),
Inst::XMM_R_R { op, src, dst } => format!(
"{} {}, {}",
ljustify(op.to_string()),
show_ireg_sized(*src, mb_rru, 8),
show_ireg_sized(dst.to_reg(), mb_rru, 8)
),
Inst::MovZX_M_R { extMode, addr, dst } => { Inst::MovZX_M_R { extMode, addr, dst } => {
if *extMode == ExtMode::LQ { if *extMode == ExtMode::LQ {
format!( format!(
@@ -574,10 +555,6 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
collector.add_use(*src); collector.add_use(*src);
collector.add_def(*dst); collector.add_def(*dst);
} }
Inst::XMM_R_R { op: _, src, dst } => {
collector.add_use(*src);
collector.add_def(*dst);
}
Inst::MovZX_M_R { Inst::MovZX_M_R {
extMode: _, extMode: _,
addr, addr,
@@ -755,14 +732,6 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
map_use(mapper, src); map_use(mapper, src);
map_def(mapper, dst); map_def(mapper, dst);
} }
Inst::XMM_R_R {
op: _,
ref mut src,
ref mut dst,
} => {
map_use(mapper, src);
map_def(mapper, dst);
}
Inst::MovZX_M_R { Inst::MovZX_M_R {
extMode: _, extMode: _,
ref mut addr, ref mut addr,
@@ -851,12 +820,16 @@ impl MachInst for Inst {
// %reg. // %reg.
match self { match self {
Self::Mov_R_R { is_64, src, dst } if *is_64 => Some((*dst, *src)), Self::Mov_R_R { is_64, src, dst } if *is_64 => Some((*dst, *src)),
Self::XMM_R_R { op, src, dst } Self::XMM_MOV_RM_R { op, src, dst }
if *op == SseOpcode::Movss if *op == SseOpcode::Movss
|| *op == SseOpcode::Movsd || *op == SseOpcode::Movsd
|| *op == SseOpcode::Movaps => || *op == SseOpcode::Movaps =>
{ {
Some((*dst, *src)) if let RegMem::Reg { reg } = src {
Some((*dst, *reg))
} else {
None
}
} }
_ => None, _ => None,
} }
@@ -893,11 +866,11 @@ impl MachInst for Inst {
match rc_dst { match rc_dst {
RegClass::I64 => Inst::mov_r_r(true, src_reg, dst_reg), RegClass::I64 => Inst::mov_r_r(true, src_reg, dst_reg),
RegClass::V128 => match ty { RegClass::V128 => match ty {
F32 => Inst::xmm_r_r(SseOpcode::Movss, src_reg, dst_reg), F32 => Inst::xmm_mov_rm_r(SseOpcode::Movss, RegMem::reg(src_reg), dst_reg),
F64 => Inst::xmm_r_r(SseOpcode::Movsd, src_reg, dst_reg), F64 => Inst::xmm_mov_rm_r(SseOpcode::Movsd, RegMem::reg(src_reg), dst_reg),
_ => panic!("unexpected V128 type in gen_move"), _ => panic!("unexpected V128 type in gen_move"),
}, },
_ => panic!("gen_move(x64): unhandled gen_move"), _ => panic!("gen_move(x64): unhandled regclass"),
} }
} }

View File

@@ -189,7 +189,11 @@ fn lower_insn_to_regs<'a>(ctx: Ctx<'a>, inst: IRInst) {
if src_reg.get_class() == RegClass::I64 { if src_reg.get_class() == RegClass::I64 {
ctx.emit(Inst::mov_r_r(true, src_reg, retval_reg)); ctx.emit(Inst::mov_r_r(true, src_reg, retval_reg));
} else if src_reg.get_class() == RegClass::V128 { } else if src_reg.get_class() == RegClass::V128 {
ctx.emit(Inst::xmm_r_r(SseOpcode::Movsd, src_reg, retval_reg)); ctx.emit(Inst::xmm_mov_rm_r(
SseOpcode::Movsd,
RegMem::reg(src_reg),
retval_reg,
));
} }
} }
// N.B.: the Ret itself is generated by the ABI. // N.B.: the Ret itself is generated by the ABI.
@@ -209,7 +213,7 @@ fn lower_insn_to_regs<'a>(ctx: Ctx<'a>, inst: IRInst) {
// TODO Fmax, Fmin. // TODO Fmax, Fmin.
_ => unimplemented!(), _ => unimplemented!(),
}; };
ctx.emit(Inst::xmm_r_r(SseOpcode::Movss, lhs, dst)); ctx.emit(Inst::xmm_mov_rm_r(SseOpcode::Movss, RegMem::reg(lhs), dst));
ctx.emit(Inst::xmm_rm_r(sse_op, RegMem::reg(rhs), dst)); ctx.emit(Inst::xmm_rm_r(sse_op, RegMem::reg(rhs), dst));
} else { } else {
unimplemented!("unimplemented lowering for opcode {:?}", op); unimplemented!("unimplemented lowering for opcode {:?}", op);