Add x86 legalization for SIMD bnot
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
use crate::cdsl::ast::{var, ExprBuilder, Literal};
|
use crate::cdsl::ast::{constant, var, ExprBuilder, Literal};
|
||||||
use crate::cdsl::instructions::{vector, Bindable, InstructionGroup};
|
use crate::cdsl::instructions::{vector, Bindable, InstructionGroup};
|
||||||
use crate::cdsl::types::ValueType;
|
use crate::cdsl::types::{LaneType, ValueType};
|
||||||
use crate::cdsl::xform::TransformGroupBuilder;
|
use crate::cdsl::xform::TransformGroupBuilder;
|
||||||
use crate::shared::types::Float::F64;
|
use crate::shared::types::Float::F64;
|
||||||
use crate::shared::types::Int::{I32, I64};
|
use crate::shared::types::Int::{I32, I64};
|
||||||
@@ -21,6 +21,8 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
let insts = &shared.instructions;
|
let insts = &shared.instructions;
|
||||||
let band = insts.by_name("band");
|
let band = insts.by_name("band");
|
||||||
let bor = insts.by_name("bor");
|
let bor = insts.by_name("bor");
|
||||||
|
let bnot = insts.by_name("bnot");
|
||||||
|
let bxor = insts.by_name("bxor");
|
||||||
let clz = insts.by_name("clz");
|
let clz = insts.by_name("clz");
|
||||||
let ctz = insts.by_name("ctz");
|
let ctz = insts.by_name("ctz");
|
||||||
let extractlane = insts.by_name("extractlane");
|
let extractlane = insts.by_name("extractlane");
|
||||||
@@ -52,6 +54,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
let umulhi = insts.by_name("umulhi");
|
let umulhi = insts.by_name("umulhi");
|
||||||
let ushr_imm = insts.by_name("ushr_imm");
|
let ushr_imm = insts.by_name("ushr_imm");
|
||||||
let urem = insts.by_name("urem");
|
let urem = insts.by_name("urem");
|
||||||
|
let vconst = insts.by_name("vconst");
|
||||||
|
|
||||||
let x86_bsf = x86_instructions.by_name("x86_bsf");
|
let x86_bsf = x86_instructions.by_name("x86_bsf");
|
||||||
let x86_bsr = x86_instructions.by_name("x86_bsr");
|
let x86_bsr = x86_instructions.by_name("x86_bsr");
|
||||||
@@ -319,6 +322,7 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
|
|
||||||
// SIMD vector size: eventually multiple vector sizes may be supported but for now only SSE-sized vectors are available
|
// SIMD vector size: eventually multiple vector sizes may be supported but for now only SSE-sized vectors are available
|
||||||
let sse_vector_size: u64 = 128;
|
let sse_vector_size: u64 = 128;
|
||||||
|
let allowed_simd_type = |t: &LaneType| t.lane_bits() >= 8 && t.lane_bits() < 128;
|
||||||
|
|
||||||
// SIMD splat: 8-bits
|
// SIMD splat: 8-bits
|
||||||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
||||||
@@ -381,6 +385,16 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SIMD bnot
|
||||||
|
let ones = constant(vec![0xff; 16]);
|
||||||
|
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
|
let bnot = bnot.bind(vector(ty, sse_vector_size));
|
||||||
|
narrow.legalize(
|
||||||
|
def!(y = bnot(x)),
|
||||||
|
vec![def!(a = vconst(ones)), def!(y = bxor(a, x))],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
narrow.custom_legalize(shuffle, "convert_shuffle");
|
narrow.custom_legalize(shuffle, "convert_shuffle");
|
||||||
narrow.custom_legalize(extractlane, "convert_extractlane");
|
narrow.custom_legalize(extractlane, "convert_extractlane");
|
||||||
narrow.custom_legalize(insertlane, "convert_insertlane");
|
narrow.custom_legalize(insertlane, "convert_insertlane");
|
||||||
|
|||||||
@@ -302,17 +302,17 @@ impl FromStr for Uimm32 {
|
|||||||
pub struct V128Imm(pub [u8; 16]);
|
pub struct V128Imm(pub [u8; 16]);
|
||||||
|
|
||||||
impl V128Imm {
|
impl V128Imm {
|
||||||
/// Iterate over the bytes in the constant
|
/// Iterate over the bytes in the constant.
|
||||||
pub fn bytes(&self) -> impl Iterator<Item = &u8> {
|
pub fn bytes(&self) -> impl Iterator<Item = &u8> {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the immediate into a vector
|
/// Convert the immediate into a vector.
|
||||||
pub fn to_vec(self) -> Vec<u8> {
|
pub fn to_vec(self) -> Vec<u8> {
|
||||||
self.0.to_vec()
|
self.0.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the immediate into a slice
|
/// Convert the immediate into a slice.
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
&self.0[..]
|
&self.0[..]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
test legalizer
|
||||||
|
set enable_simd
|
||||||
|
target x86_64 skylake
|
||||||
|
|
||||||
|
function %bnot_b32x4(b32x4) -> b32x4 {
|
||||||
|
ebb0(v0: b32x4):
|
||||||
|
v1 = bnot v0
|
||||||
|
; check: v2 = vconst.b32x4 0xffffffffffffffffffffffffffffffff
|
||||||
|
; nextln: v1 = bxor v2, v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
test rodata
|
||||||
|
set enable_simd
|
||||||
|
target x86_64 skylake
|
||||||
|
|
||||||
|
function %bnot_b32x4(b32x4) -> b32x4 {
|
||||||
|
ebb0(v0: b32x4):
|
||||||
|
v1 = bnot v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
|
||||||
|
; sameln: [FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF, FF]
|
||||||
Reference in New Issue
Block a user