Implements vcode lowering for f32.copysign.

This patch implements the required but not already available
x64 instructions for copysign as well as the actual lowering sequence
and tests for the newly implemented x64 instructions.
Those instructions include:

andps,
andnps,
movaps,
movd,
orps,

The lowering sequence is based on the lowering for f32.copysign
in the current cranelift backend. movd does not have a test yet
due to some logic needed express a 32-bit register as a source
for xmm_rm_r instructions. This code also begins some
rethinking/refactoring of how the sse move instuctions
are written and so also includes new emit cases that will replace
current ones that match a different enum used to describe sse moves.
This commit is contained in:
Johnnie Birch
2020-06-06 15:32:36 -07:00
parent 1ea2f47d9c
commit f2f7706265
5 changed files with 197 additions and 39 deletions

View File

@@ -151,6 +151,18 @@ pub(crate) enum Inst {
/// jmpq (reg mem)
JmpUnknown { target: RegMem },
/// mov between XMM registers (32 64) (reg addr) reg
/// XMM_MOV_RM_R differs from XMM_RM_R in that the dst
/// register of XMM_MOV_RM_R is not used in the computation
/// of the instruction dst value and so does not have to
/// be a previously valid value. This is characteristic of
/// mov instructions.
XMM_MOV_RM_R {
op: SseOpcode,
src: RegMem,
dst: Writable<Reg>,
},
/// (add sub and or xor mul adc? sbb?) (32 64) (reg addr imm) reg
XMM_RM_R {
op: SseOpcode,
@@ -220,9 +232,14 @@ impl Inst {
Inst::XMM_R_R { op, src, dst }
}
pub(crate) fn xmm_mov_rm_r(op: SseOpcode, src: RegMem, dst: Writable<Reg>) -> Inst {
debug_assert!(dst.to_reg().get_class() == RegClass::V128);
Inst::XMM_MOV_RM_R { op, src, dst }
}
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 }
Inst::XMM_RM_R { op, src, dst }
}
pub(crate) fn movzx_m_r(extMode: ExtMode, addr: Addr, dst: Writable<Reg>) -> Inst {
@@ -371,6 +388,12 @@ impl ShowWithRRU for Inst {
src.show_rru_sized(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!(
"{} {}, {}",
ljustify(op.to_string()),
src.show_rru_sized(mb_rru, op.src_size()),
show_ireg_sized(dst.to_reg(), mb_rru, 8),
),
Inst::XMM_RM_R { op, src, dst } => format!(
"{} {}, {}",
ljustify(op.to_string()),
@@ -532,7 +555,11 @@ fn x64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
src.get_regs_as_uses(collector);
collector.add_mod(*dst);
}
Inst::XMM_RM_R { op: _, src, dst } => {
Inst::XMM_MOV_RM_R { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_def(*dst);
}
Inst::XMM_RM_R { src, dst, .. } => {
src.get_regs_as_uses(collector);
collector.add_mod(*dst);
}
@@ -699,6 +726,14 @@ fn x64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
src.map_uses(mapper);
map_mod(mapper, dst);
}
Inst::XMM_MOV_RM_R {
op: _,
ref mut src,
ref mut dst,
} => {
src.map_uses(mapper);
map_def(mapper, dst);
}
Inst::XMM_RM_R {
op: _,
ref mut src,
@@ -817,7 +852,9 @@ 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 == SseOpcode::Movss || *op == SseOpcode::Movsd =>
if *op == SseOpcode::Movss
|| *op == SseOpcode::Movsd
|| *op == SseOpcode::Movaps =>
{
Some((*dst, *src))
}