Add x64 lowering of Clif flt store instruction for new backend
Adds support for the clif flt store instruction.
This commit is contained in:
@@ -1027,7 +1027,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Inst::XMM_MOV_RM_R {
|
Inst::XMM_Mov_RM_R {
|
||||||
op,
|
op,
|
||||||
src: src_e,
|
src: src_e,
|
||||||
dst: reg_g,
|
dst: reg_g,
|
||||||
@@ -1082,7 +1082,17 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Inst::XMM_Mov_R_M { op, src, dst } => {
|
||||||
|
let rex = RexFlags::clear_w();
|
||||||
|
let (prefix, opcode) = match op {
|
||||||
|
SseOpcode::Movd => (LegacyPrefix::_66, 0x0F7E),
|
||||||
|
SseOpcode::Movss => (LegacyPrefix::_F3, 0x0F11),
|
||||||
|
_ => unimplemented!("Emit xmm mov r m"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let dst = &dst.finalize(state);
|
||||||
|
emit_std_reg_mem(sink, prefix, opcode, 2, *src, dst, rex);
|
||||||
|
}
|
||||||
Inst::Hlt => {
|
Inst::Hlt => {
|
||||||
sink.put1(0xcc);
|
sink.put1(0xcc);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2688,6 +2688,19 @@ fn test_x64_emit() {
|
|||||||
"440F56F9",
|
"440F56F9",
|
||||||
"orps %xmm1, %xmm15",
|
"orps %xmm1, %xmm15",
|
||||||
));
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::xmm_mov_r_m(SseOpcode::Movd, xmm0, Amode::imm_reg(321, rbx)),
|
||||||
|
"660F7E8341010000",
|
||||||
|
"movd %xmm0, 321(%rbx)",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::xmm_mov_r_m(SseOpcode::Movss, xmm15, Amode::imm_reg(128, r12)),
|
||||||
|
"F3450F11BC2480000000",
|
||||||
|
"movss %xmm15, 128(%r12)",
|
||||||
|
));
|
||||||
|
|
||||||
insns.push((
|
insns.push((
|
||||||
Inst::xmm_rm_r(SseOpcode::Orps, RegMem::reg(xmm5), w_xmm4),
|
Inst::xmm_rm_r(SseOpcode::Orps, RegMem::reg(xmm5), w_xmm4),
|
||||||
"0F56E5",
|
"0F56E5",
|
||||||
|
|||||||
@@ -135,16 +135,23 @@ pub enum Inst {
|
|||||||
dst: Writable<Reg>,
|
dst: Writable<Reg>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// mov between XMM registers (32 64) (reg addr) reg
|
/// mov between XMM registers (32 64) (reg addr) reg XMM_Mov_RM_R differs from XMM_RM_R in
|
||||||
/// XMM_MOV_RM_R differs from XMM_RM_R in that the dst register of XMM_MOV_RM_R is not used in
|
/// that the dst register of XMM_MOV_RM_R is not used in the computation of the instruction
|
||||||
/// the computation of the instruction dst value and so does not have to be a previously valid
|
/// dst value and so does not have to be a previously valid value. This is characteristic of
|
||||||
/// value. This is characteristic of mov instructions.
|
/// mov instructions.
|
||||||
XMM_MOV_RM_R {
|
XMM_Mov_RM_R {
|
||||||
op: SseOpcode,
|
op: SseOpcode,
|
||||||
src: RegMem,
|
src: RegMem,
|
||||||
dst: Writable<Reg>,
|
dst: Writable<Reg>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// mov reg addr (good for all memory stores from xmm registers)
|
||||||
|
XMM_Mov_R_M {
|
||||||
|
op: SseOpcode,
|
||||||
|
src: Reg,
|
||||||
|
dst: SyntheticAmode,
|
||||||
|
},
|
||||||
|
|
||||||
// =====================================
|
// =====================================
|
||||||
// Control flow instructions.
|
// Control flow instructions.
|
||||||
/// Direct call: call simm32.
|
/// Direct call: call simm32.
|
||||||
@@ -249,7 +256,7 @@ impl Inst {
|
|||||||
|
|
||||||
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 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn xmm_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> Self {
|
pub(crate) fn xmm_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> Self {
|
||||||
@@ -257,6 +264,15 @@ impl Inst {
|
|||||||
Inst::XMM_RM_R { op, src, dst }
|
Inst::XMM_RM_R { op, src, dst }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn xmm_mov_r_m(op: SseOpcode, src: Reg, dst: impl Into<SyntheticAmode>) -> Inst {
|
||||||
|
debug_assert!(src.get_class() == RegClass::V128);
|
||||||
|
Inst::XMM_Mov_R_M {
|
||||||
|
op,
|
||||||
|
src,
|
||||||
|
dst: dst.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn movzx_rm_r(ext_mode: ExtMode, src: RegMem, dst: Writable<Reg>) -> Inst {
|
pub(crate) fn movzx_rm_r(ext_mode: ExtMode, src: RegMem, dst: Writable<Reg>) -> Inst {
|
||||||
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
|
debug_assert!(dst.to_reg().get_class() == RegClass::I64);
|
||||||
Inst::MovZX_RM_R { ext_mode, src, dst }
|
Inst::MovZX_RM_R { ext_mode, src, dst }
|
||||||
@@ -453,12 +469,18 @@ impl ShowWithRRU for Inst {
|
|||||||
src.show_rru_sized(mb_rru, sizeLQ(*is_64)),
|
src.show_rru_sized(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_MOV_RM_R { op, src, dst } => format!(
|
Inst::XMM_Mov_RM_R { op, src, dst } => format!(
|
||||||
"{} {}, {}",
|
"{} {}, {}",
|
||||||
ljustify(op.to_string()),
|
ljustify(op.to_string()),
|
||||||
src.show_rru_sized(mb_rru, op.src_size()),
|
src.show_rru_sized(mb_rru, op.src_size()),
|
||||||
show_ireg_sized(dst.to_reg(), mb_rru, 8),
|
show_ireg_sized(dst.to_reg(), mb_rru, 8),
|
||||||
),
|
),
|
||||||
|
Inst::XMM_Mov_R_M { op, src, dst } => format!(
|
||||||
|
"{} {}, {}",
|
||||||
|
ljustify(op.to_string()),
|
||||||
|
show_ireg_sized(*src, mb_rru, 8),
|
||||||
|
dst.show_rru(mb_rru)
|
||||||
|
),
|
||||||
Inst::XMM_RM_R { op, src, dst } => format!(
|
Inst::XMM_RM_R { op, src, dst } => format!(
|
||||||
"{} {}, {}",
|
"{} {}, {}",
|
||||||
ljustify(op.to_string()),
|
ljustify(op.to_string()),
|
||||||
@@ -626,7 +648,7 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
|||||||
src.get_regs_as_uses(collector);
|
src.get_regs_as_uses(collector);
|
||||||
collector.add_mod(*dst);
|
collector.add_mod(*dst);
|
||||||
}
|
}
|
||||||
Inst::XMM_MOV_RM_R { src, dst, .. } => {
|
Inst::XMM_Mov_RM_R { src, dst, .. } => {
|
||||||
src.get_regs_as_uses(collector);
|
src.get_regs_as_uses(collector);
|
||||||
collector.add_def(*dst);
|
collector.add_def(*dst);
|
||||||
}
|
}
|
||||||
@@ -634,6 +656,10 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
|
|||||||
src.get_regs_as_uses(collector);
|
src.get_regs_as_uses(collector);
|
||||||
collector.add_mod(*dst);
|
collector.add_mod(*dst);
|
||||||
}
|
}
|
||||||
|
Inst::XMM_Mov_R_M { src, dst, .. } => {
|
||||||
|
collector.add_use(*src);
|
||||||
|
dst.get_regs_as_uses(collector);
|
||||||
|
}
|
||||||
Inst::Imm_R { dst, .. } => {
|
Inst::Imm_R { dst, .. } => {
|
||||||
collector.add_def(*dst);
|
collector.add_def(*dst);
|
||||||
}
|
}
|
||||||
@@ -791,22 +817,30 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
|
|||||||
src.map_uses(mapper);
|
src.map_uses(mapper);
|
||||||
map_mod(mapper, dst);
|
map_mod(mapper, dst);
|
||||||
}
|
}
|
||||||
Inst::XMM_MOV_RM_R {
|
Inst::XMM_Mov_RM_R {
|
||||||
op: _,
|
|
||||||
ref mut src,
|
ref mut src,
|
||||||
ref mut dst,
|
ref mut dst,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
src.map_uses(mapper);
|
src.map_uses(mapper);
|
||||||
map_def(mapper, dst);
|
map_def(mapper, dst);
|
||||||
}
|
}
|
||||||
Inst::XMM_RM_R {
|
Inst::XMM_RM_R {
|
||||||
op: _,
|
|
||||||
ref mut src,
|
ref mut src,
|
||||||
ref mut dst,
|
ref mut dst,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
src.map_uses(mapper);
|
src.map_uses(mapper);
|
||||||
map_mod(mapper, dst);
|
map_mod(mapper, dst);
|
||||||
}
|
}
|
||||||
|
Inst::XMM_Mov_R_M {
|
||||||
|
ref mut src,
|
||||||
|
ref mut dst,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
map_use(mapper, src);
|
||||||
|
dst.map_uses(mapper);
|
||||||
|
}
|
||||||
Inst::Imm_R {
|
Inst::Imm_R {
|
||||||
dst_is_64: _,
|
dst_is_64: _,
|
||||||
simm64: _,
|
simm64: _,
|
||||||
@@ -931,7 +965,7 @@ 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_MOV_RM_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 =>
|
||||||
|
|||||||
@@ -567,7 +567,10 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(ctx: &mut C, insn: IRInst) -> Codeg
|
|||||||
let src = input_to_reg(ctx, inputs[0]);
|
let src = input_to_reg(ctx, inputs[0]);
|
||||||
|
|
||||||
if is_float {
|
if is_float {
|
||||||
unimplemented!("FPU stores");
|
ctx.emit(match elem_ty {
|
||||||
|
F32 => Inst::xmm_mov_r_m(SseOpcode::Movss, src, addr),
|
||||||
|
_ => unimplemented!("FP store not 32-bit"),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
ctx.emit(Inst::mov_r_m(elem_ty.bytes() as u8, src, addr));
|
ctx.emit(Inst::mov_r_m(elem_ty.bytes() as u8, src, addr));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user