Add x86 implementation of SIMD swizzle instruction

This commit is contained in:
Andrew Brown
2020-03-06 11:29:21 -08:00
parent 4a0f53464a
commit fa7481a681
4 changed files with 85 additions and 1 deletions

View File

@@ -338,7 +338,9 @@ fn define_simd(shared: &mut SharedDefinitions, x86_instructions: &InstructionGro
let splat = insts.by_name("splat");
let shuffle = insts.by_name("shuffle");
let sshr = insts.by_name("sshr");
let swizzle = insts.by_name("swizzle");
let trueif = insts.by_name("trueif");
let uadd_sat = insts.by_name("uadd_sat");
let umax = insts.by_name("umax");
let umin = insts.by_name("umin");
let ushr_imm = insts.by_name("ushr_imm");
@@ -375,6 +377,7 @@ fn define_simd(shared: &mut SharedDefinitions, x86_instructions: &InstructionGro
let uimm8_one = Literal::constant(&imm.uimm8, 0x01);
let u128_zeroes = constant(vec![0x00; 16]);
let u128_ones = constant(vec![0xff; 16]);
let u128_seventies = constant(vec![0x70; 16]);
let a = var("a");
let b = var("b");
let c = var("c");
@@ -459,6 +462,21 @@ fn define_simd(shared: &mut SharedDefinitions, x86_instructions: &InstructionGro
);
}
// SIMD swizzle; the following inefficient implementation is due to the Wasm SIMD spec requiring
// mask indexes greater than 15 to have the same semantics as a 0 index. For the spec discussion,
// see https://github.com/WebAssembly/simd/issues/93.
{
let swizzle = swizzle.bind(vector(I8, sse_vector_size));
narrow.legalize(
def!(a = swizzle(x, y)),
vec![
def!(b = vconst(u128_seventies)),
def!(c = uadd_sat(y, b)),
def!(a = x86_pshufb(x, c)),
],
);
}
// SIMD bnot
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
let bnot = bnot.bind(vector(ty, sse_vector_size));