[simd] Implement load*_lane and store*_lane
The Wasm SIMD specification has added new instructions that allow inserting to the lane of a vector from a memory location, and conversely, extracting from a lane of a vector to a memory location. The simplest implementation lowers these instructions, `load[8|16|32|64]_lane` and `store[8|16|32|64]_lane`, to a sequence of either `load + insertlane` or `extractlane + store` (in CLIF). With the new backend's pattern matching, we expect these CLIF sequences to compile as a single machine instruction (at least in x64).
This commit is contained in:
18
build.rs
18
build.rs
@@ -192,14 +192,6 @@ fn experimental_x64_should_panic(testsuite: &str, testname: &str, strategy: &str
|
||||
("simd", "simd_i32x4_trunc_sat_f64x2") => return true,
|
||||
("simd", "simd_i64x2_extmul_i32x4") => return true,
|
||||
("simd", "simd_int_to_int_extend") => return true,
|
||||
("simd", "simd_load16_lane") => return true,
|
||||
("simd", "simd_load32_lane") => return true,
|
||||
("simd", "simd_load64_lane") => return true,
|
||||
("simd", "simd_load8_lane") => return true,
|
||||
("simd", "simd_store16_lane") => return true,
|
||||
("simd", "simd_store32_lane") => return true,
|
||||
("simd", "simd_store64_lane") => return true,
|
||||
("simd", "simd_store8_lane") => return true,
|
||||
("simd", _) => return false,
|
||||
_ => {}
|
||||
}
|
||||
@@ -234,15 +226,7 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
|
||||
| ("simd", "simd_i32x4_extmul_i16x8")
|
||||
| ("simd", "simd_i32x4_trunc_sat_f64x2")
|
||||
| ("simd", "simd_i64x2_extmul_i32x4")
|
||||
| ("simd", "simd_int_to_int_extend")
|
||||
| ("simd", "simd_load16_lane")
|
||||
| ("simd", "simd_load32_lane")
|
||||
| ("simd", "simd_load64_lane")
|
||||
| ("simd", "simd_load8_lane")
|
||||
| ("simd", "simd_store16_lane")
|
||||
| ("simd", "simd_store32_lane")
|
||||
| ("simd", "simd_store64_lane")
|
||||
| ("simd", "simd_store8_lane") => return true,
|
||||
| ("simd", "simd_int_to_int_extend") => return true,
|
||||
|
||||
// These are only implemented on x64.
|
||||
("simd", "simd_i64x2_arith2") | ("simd", "simd_boolean") => {
|
||||
|
||||
@@ -1466,6 +1466,30 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
let as_vector = builder.ins().scalar_to_vector(type_of(op), state.pop1());
|
||||
state.push1(as_vector)
|
||||
}
|
||||
Operator::V128Load8Lane { memarg, lane }
|
||||
| Operator::V128Load16Lane { memarg, lane }
|
||||
| Operator::V128Load32Lane { memarg, lane }
|
||||
| Operator::V128Load64Lane { memarg, lane } => {
|
||||
let vector = pop1_with_bitcast(state, type_of(op), builder);
|
||||
translate_load(
|
||||
memarg,
|
||||
ir::Opcode::Load,
|
||||
type_of(op).lane_type(),
|
||||
builder,
|
||||
state,
|
||||
environ,
|
||||
)?;
|
||||
let replacement = state.pop1();
|
||||
state.push1(builder.ins().insertlane(vector, replacement, *lane))
|
||||
}
|
||||
Operator::V128Store8Lane { memarg, lane }
|
||||
| Operator::V128Store16Lane { memarg, lane }
|
||||
| Operator::V128Store32Lane { memarg, lane }
|
||||
| Operator::V128Store64Lane { memarg, lane } => {
|
||||
let vector = pop1_with_bitcast(state, type_of(op), builder);
|
||||
state.push1(builder.ins().extractlane(vector, lane.clone()));
|
||||
translate_store(memarg, ir::Opcode::Store, builder, state, environ)?;
|
||||
}
|
||||
Operator::I8x16ExtractLaneS { lane } | Operator::I16x8ExtractLaneS { lane } => {
|
||||
let vector = pop1_with_bitcast(state, type_of(op), builder);
|
||||
let extracted = builder.ins().extractlane(vector, lane.clone());
|
||||
@@ -1837,14 +1861,6 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
| Operator::I64x2ExtendHighI32x4S
|
||||
| Operator::I64x2ExtendLowI32x4U
|
||||
| Operator::I64x2ExtendHighI32x4U
|
||||
| Operator::V128Load8Lane { .. }
|
||||
| Operator::V128Load16Lane { .. }
|
||||
| Operator::V128Load32Lane { .. }
|
||||
| Operator::V128Load64Lane { .. }
|
||||
| Operator::V128Store8Lane { .. }
|
||||
| Operator::V128Store16Lane { .. }
|
||||
| Operator::V128Store32Lane { .. }
|
||||
| Operator::V128Store64Lane { .. }
|
||||
| Operator::I16x8Q15MulrSatS
|
||||
| Operator::I16x8ExtMulLowI8x16S
|
||||
| Operator::I16x8ExtMulHighI8x16S
|
||||
@@ -2541,6 +2557,8 @@ fn type_of(operator: &Operator) -> Type {
|
||||
Operator::I8x16Shuffle { .. }
|
||||
| Operator::I8x16Splat
|
||||
| Operator::V128Load8Splat { .. }
|
||||
| Operator::V128Load8Lane { .. }
|
||||
| Operator::V128Store8Lane { .. }
|
||||
| Operator::I8x16ExtractLaneS { .. }
|
||||
| Operator::I8x16ExtractLaneU { .. }
|
||||
| Operator::I8x16ReplaceLane { .. }
|
||||
@@ -2575,6 +2593,8 @@ fn type_of(operator: &Operator) -> Type {
|
||||
|
||||
Operator::I16x8Splat
|
||||
| Operator::V128Load16Splat { .. }
|
||||
| Operator::V128Load16Lane { .. }
|
||||
| Operator::V128Store16Lane { .. }
|
||||
| Operator::I16x8ExtractLaneS { .. }
|
||||
| Operator::I16x8ExtractLaneU { .. }
|
||||
| Operator::I16x8ReplaceLane { .. }
|
||||
@@ -2610,6 +2630,8 @@ fn type_of(operator: &Operator) -> Type {
|
||||
|
||||
Operator::I32x4Splat
|
||||
| Operator::V128Load32Splat { .. }
|
||||
| Operator::V128Load32Lane { .. }
|
||||
| Operator::V128Store32Lane { .. }
|
||||
| Operator::I32x4ExtractLane { .. }
|
||||
| Operator::I32x4ReplaceLane { .. }
|
||||
| Operator::I32x4Eq
|
||||
@@ -2642,6 +2664,8 @@ fn type_of(operator: &Operator) -> Type {
|
||||
|
||||
Operator::I64x2Splat
|
||||
| Operator::V128Load64Splat { .. }
|
||||
| Operator::V128Load64Lane { .. }
|
||||
| Operator::V128Store64Lane { .. }
|
||||
| Operator::I64x2ExtractLane { .. }
|
||||
| Operator::I64x2ReplaceLane { .. }
|
||||
| Operator::I64x2Eq
|
||||
|
||||
Reference in New Issue
Block a user