cranelift: Align Scalar and SIMD shift semantics (#4520)
* cranelift: Reorganize test suite Group some SIMD operations by instruction. * cranelift: Deduplicate some shift tests Also, new tests with the mod behaviour * aarch64: Lower shifts with mod behaviour * x64: Lower shifts with mod behaviour * wasmtime: Don't mask SIMD shifts
This commit is contained in:
@@ -1630,29 +1630,23 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
Operator::I8x16Shl | Operator::I16x8Shl | Operator::I32x4Shl | Operator::I64x2Shl => {
|
||||
let (a, b) = state.pop2();
|
||||
let bitcast_a = optionally_bitcast_vector(a, type_of(op), builder);
|
||||
let bitwidth = i64::from(type_of(op).lane_bits());
|
||||
// The spec expects to shift with `b mod lanewidth`; so, e.g., for 16 bit lane-width
|
||||
// we do `b AND 15`; this means fewer instructions than `iconst + urem`.
|
||||
let b_mod_bitwidth = builder.ins().band_imm(b, bitwidth - 1);
|
||||
state.push1(builder.ins().ishl(bitcast_a, b_mod_bitwidth))
|
||||
// The spec expects to shift with `b mod lanewidth`; This is directly compatible
|
||||
// with cranelift's instruction.
|
||||
state.push1(builder.ins().ishl(bitcast_a, b))
|
||||
}
|
||||
Operator::I8x16ShrU | Operator::I16x8ShrU | Operator::I32x4ShrU | Operator::I64x2ShrU => {
|
||||
let (a, b) = state.pop2();
|
||||
let bitcast_a = optionally_bitcast_vector(a, type_of(op), builder);
|
||||
let bitwidth = i64::from(type_of(op).lane_bits());
|
||||
// The spec expects to shift with `b mod lanewidth`; so, e.g., for 16 bit lane-width
|
||||
// we do `b AND 15`; this means fewer instructions than `iconst + urem`.
|
||||
let b_mod_bitwidth = builder.ins().band_imm(b, bitwidth - 1);
|
||||
state.push1(builder.ins().ushr(bitcast_a, b_mod_bitwidth))
|
||||
// The spec expects to shift with `b mod lanewidth`; This is directly compatible
|
||||
// with cranelift's instruction.
|
||||
state.push1(builder.ins().ushr(bitcast_a, b))
|
||||
}
|
||||
Operator::I8x16ShrS | Operator::I16x8ShrS | Operator::I32x4ShrS | Operator::I64x2ShrS => {
|
||||
let (a, b) = state.pop2();
|
||||
let bitcast_a = optionally_bitcast_vector(a, type_of(op), builder);
|
||||
let bitwidth = i64::from(type_of(op).lane_bits());
|
||||
// The spec expects to shift with `b mod lanewidth`; so, e.g., for 16 bit lane-width
|
||||
// we do `b AND 15`; this means fewer instructions than `iconst + urem`.
|
||||
let b_mod_bitwidth = builder.ins().band_imm(b, bitwidth - 1);
|
||||
state.push1(builder.ins().sshr(bitcast_a, b_mod_bitwidth))
|
||||
// The spec expects to shift with `b mod lanewidth`; This is directly compatible
|
||||
// with cranelift's instruction.
|
||||
state.push1(builder.ins().sshr(bitcast_a, b))
|
||||
}
|
||||
Operator::V128Bitselect => {
|
||||
let (a, b, c) = state.pop3();
|
||||
|
||||
Reference in New Issue
Block a user