Add SIMD bitselect instruction and x86 legalization
This new instructions matches the `bitselect` behavior described in the WASM SIMD spec (https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md#bitwise-select)
This commit is contained in:
@@ -20,7 +20,9 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
// List of instructions.
|
// List of instructions.
|
||||||
let insts = &shared.instructions;
|
let insts = &shared.instructions;
|
||||||
let band = insts.by_name("band");
|
let band = insts.by_name("band");
|
||||||
|
let band_not = insts.by_name("band_not");
|
||||||
let bitcast = insts.by_name("bitcast");
|
let bitcast = insts.by_name("bitcast");
|
||||||
|
let bitselect = insts.by_name("bitselect");
|
||||||
let bor = insts.by_name("bor");
|
let bor = insts.by_name("bor");
|
||||||
let bnot = insts.by_name("bnot");
|
let bnot = insts.by_name("bnot");
|
||||||
let bxor = insts.by_name("bxor");
|
let bxor = insts.by_name("bxor");
|
||||||
@@ -431,6 +433,19 @@ pub(crate) fn define(shared: &mut SharedDefinitions, x86_instructions: &Instruct
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SIMD select
|
||||||
|
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
|
let bitselect = bitselect.bind(vector(ty, sse_vector_size)); // must bind both x/y and c
|
||||||
|
narrow.legalize(
|
||||||
|
def!(d = bitselect(c, x, y)),
|
||||||
|
vec![
|
||||||
|
def!(a = band(x, c)),
|
||||||
|
def!(b = band_not(y, c)),
|
||||||
|
def!(d = bor(a, b)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
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");
|
||||||
|
|||||||
@@ -1199,6 +1199,22 @@ pub(crate) fn define(
|
|||||||
.operands_out(vec![a]),
|
.operands_out(vec![a]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let c = &operand_doc("c", Any, "Controlling value to test");
|
||||||
|
ig.push(
|
||||||
|
Inst::new(
|
||||||
|
"bitselect",
|
||||||
|
r#"
|
||||||
|
Conditional select of bits.
|
||||||
|
|
||||||
|
For each bit in `c`, this instruction selects the corresponding bit from `x` if the bit
|
||||||
|
in `c` is 1 and the corresponding bit from `y` if the bit in `c` is 0. See also:
|
||||||
|
`select`, `vselect`.
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.operands_in(vec![c, x, y])
|
||||||
|
.operands_out(vec![a]),
|
||||||
|
);
|
||||||
|
|
||||||
let x = &operand("x", Any);
|
let x = &operand("x", Any);
|
||||||
|
|
||||||
ig.push(
|
ig.push(
|
||||||
|
|||||||
@@ -31,3 +31,15 @@ ebb0:
|
|||||||
; nextln: v2 = x86_psra v1, v3
|
; nextln: v2 = x86_psra v1, v3
|
||||||
return v2
|
return v2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function %bitselect_i16x8() -> i16x8 {
|
||||||
|
ebb0:
|
||||||
|
v0 = vconst.i16x8 [0 0 0 0 0 0 0 0]
|
||||||
|
v1 = vconst.i16x8 [0 0 0 0 0 0 0 0]
|
||||||
|
v2 = vconst.i16x8 [0 0 0 0 0 0 0 0]
|
||||||
|
v3 = bitselect v0, v1, v2
|
||||||
|
; check: v4 = band v1, v0
|
||||||
|
; nextln: v5 = band_not v2, v0
|
||||||
|
; nextln: v3 = bor v4, v5
|
||||||
|
return v3
|
||||||
|
}
|
||||||
|
|||||||
@@ -105,3 +105,25 @@ ebb0:
|
|||||||
return v7
|
return v7
|
||||||
}
|
}
|
||||||
; run
|
; run
|
||||||
|
|
||||||
|
function %bitselect_i8x16() -> b1 {
|
||||||
|
ebb0:
|
||||||
|
v0 = vconst.i8x16 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255] ; the selector vector
|
||||||
|
v1 = vconst.i8x16 [127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42] ; for each 1-bit in v0 the bit of v1 is selected
|
||||||
|
v2 = vconst.i8x16 [42 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127] ; for each 0-bit in v0 the bit of v2 is selected
|
||||||
|
v3 = bitselect v0, v1, v2
|
||||||
|
|
||||||
|
v4 = extractlane v3, 0
|
||||||
|
v5 = icmp_imm eq v4, 42
|
||||||
|
|
||||||
|
v6 = extractlane v3, 1
|
||||||
|
v7 = icmp_imm eq v6, 0
|
||||||
|
|
||||||
|
v8 = extractlane v3, 15
|
||||||
|
v9 = icmp_imm eq v8, 42
|
||||||
|
|
||||||
|
v10 = band v5, v7
|
||||||
|
v11 = band v10, v9
|
||||||
|
return v11
|
||||||
|
}
|
||||||
|
; run
|
||||||
|
|||||||
Reference in New Issue
Block a user