Add x86 legalization for SIMD ineg

This commit is contained in:
Andrew Brown
2019-09-18 10:50:01 -07:00
parent ca1df499a0
commit ba393afd4d
5 changed files with 77 additions and 4 deletions

View File

@@ -36,6 +36,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
let iadd = insts.by_name("iadd");
let iconst = insts.by_name("iconst");
let imul = insts.by_name("imul");
let ineg = insts.by_name("ineg");
let insertlane = insts.by_name("insertlane");
let isub = insts.by_name("isub");
let popcnt = insts.by_name("popcnt");
@@ -385,6 +386,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
narrow.custom_legalize(shuffle, "convert_shuffle");
narrow.custom_legalize(extractlane, "convert_extractlane");
narrow.custom_legalize(insertlane, "convert_insertlane");
narrow.custom_legalize(ineg, "convert_ineg");
narrow.build_and_add_to(&mut shared.transform_groups);
}

View File

@@ -1704,6 +1704,17 @@ pub(crate) fn define(
.operands_out(vec![a]),
);
ig.push(
Inst::new(
"ineg",
r#"
Integer negation: `a := -x \pmod{2^B}`.
"#,
)
.operands_in(vec![x])
.operands_out(vec![a]),
);
ig.push(
Inst::new(
"imul",

View File

@@ -5,6 +5,7 @@ use crate::bitset::BitSet;
use crate::cursor::{Cursor, FuncCursor};
use crate::flowgraph::ControlFlowGraph;
use crate::ir::condcodes::{FloatCC, IntCC};
use crate::ir::immediates::V128Imm;
use crate::ir::types::*;
use crate::ir::{self, Function, Inst, InstBuilder};
use crate::isa::constraints::*;
@@ -1090,3 +1091,27 @@ fn convert_insertlane(
}
}
}
/// For SIMD negation, convert an `ineg` to a `vconst + isub`.
fn convert_ineg(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
_isa: &dyn TargetIsa,
) {
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
if let ir::InstructionData::Unary {
opcode: ir::Opcode::Ineg,
arg,
} = pos.func.dfg[inst]
{
let value_type = pos.func.dfg.value_type(arg);
if value_type.is_vector() && value_type.lane_type().is_int() {
let zero_immediate = pos.func.dfg.constants.insert(V128Imm::from(0).to_vec());
let zero_value = pos.ins().vconst(value_type, zero_immediate); // this should be legalized to a PXOR
pos.func.dfg.replace(inst).isub(zero_value, arg);
}
}
}