Implement Swizzle and Splat for interpreter (#3268)
* Implement `Swizzle` and `Splat` for interpreter Implemented for the Cranelift interpreter: - `Swizzle` to shuffle an `i8x16` SIMD vector based on the indices specified in another vector of the same size. - `Splat` to create a SIMD vector with all lanes having the same value. Copyright (c) 2021, Arm Limited * Fix old x86 backend failing test Copyright (c) 2021, Arm Limited * Represent i16x8 and above as hex Copyright (c) 2021, Arm Limited
This commit is contained in:
33
cranelift/filetests/filetests/runtests/simd-splat.clif
Normal file
33
cranelift/filetests/filetests/runtests/simd-splat.clif
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
test interpret
|
||||||
|
test run
|
||||||
|
target aarch64
|
||||||
|
set enable_simd
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
function %splat_i8x16(i8) -> i8x16 {
|
||||||
|
block0(v0: i8):
|
||||||
|
v1 = splat.i8x16 v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
; run: %splat_i8x16(1) == [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
|
||||||
|
|
||||||
|
function %splat_i16x8(i16) -> i16x8 {
|
||||||
|
block0(v0: i16):
|
||||||
|
v1 = splat.i16x8 v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
; run: %splat_i16x8(512) == [512 512 512 512 512 512 512 512]
|
||||||
|
|
||||||
|
function %splat_i32x4(i32) -> i32x4 {
|
||||||
|
block0(v0: i32):
|
||||||
|
v1 = splat.i32x4 v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
; run: %splat_i32x4(2000000) == [2000000 2000000 2000000 2000000]
|
||||||
|
|
||||||
|
function %splat_i64x2(i64) -> i64x2 {
|
||||||
|
block0(v0: i64):
|
||||||
|
v1 = splat.i64x2 v0
|
||||||
|
return v1
|
||||||
|
}
|
||||||
|
; run: %splat_i64x2(5000000000) == [5000000000 5000000000]
|
||||||
33
cranelift/filetests/filetests/runtests/simd-swizzle.clif
Normal file
33
cranelift/filetests/filetests/runtests/simd-swizzle.clif
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
test interpret
|
||||||
|
test run
|
||||||
|
target aarch64
|
||||||
|
set enable_simd
|
||||||
|
target x86_64 machinst
|
||||||
|
|
||||||
|
function %swizzle_i8x16(i8x16, i8x16) -> i8x16 {
|
||||||
|
block0(v0: i8x16, v1: i8x16):
|
||||||
|
v2 = swizzle.i8x16 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
; run: %swizzle_i8x16([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == [1 10 16 2 7 14 8 12 11 9 0 13 5 3 4 6]
|
||||||
|
|
||||||
|
function %swizzle_i16x8(i8x16, i8x16) -> i16x8 {
|
||||||
|
block0(v0: i8x16, v1: i8x16):
|
||||||
|
v2 = swizzle.i16x8 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
; run: %swizzle_i16x8([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||||
|
|
||||||
|
function %swizzle_i32x4(i8x16, i8x16) -> i32x4 {
|
||||||
|
block0(v0: i8x16, v1: i8x16):
|
||||||
|
v2 = swizzle.i32x4 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
; run: %swizzle_i32x4([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||||
|
|
||||||
|
function %swizzle_i64x2(i8x16, i8x16) -> i64x2 {
|
||||||
|
block0(v0: i8x16, v1: i8x16):
|
||||||
|
v2 = swizzle.i64x2 v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
; run: %swizzle_i64x2([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [0 9 15 1 6 13 7 11 10 8 100 12 4 2 3 5]) == 0x060403050d00090b0c080e0702100a01
|
||||||
@@ -777,8 +777,24 @@ where
|
|||||||
ValueConversionKind::RoundNearestEven(ctrl_ty),
|
ValueConversionKind::RoundNearestEven(ctrl_ty),
|
||||||
)?),
|
)?),
|
||||||
Opcode::Shuffle => unimplemented!("Shuffle"),
|
Opcode::Shuffle => unimplemented!("Shuffle"),
|
||||||
Opcode::Swizzle => unimplemented!("Swizzle"),
|
Opcode::Swizzle => {
|
||||||
Opcode::Splat => unimplemented!("Splat"),
|
let x = Value::into_array(&arg(0)?)?;
|
||||||
|
let s = Value::into_array(&arg(1)?)?;
|
||||||
|
let mut new = [0u8; 16];
|
||||||
|
for i in 0..new.len() {
|
||||||
|
if (s[i] as usize) < new.len() {
|
||||||
|
new[i] = x[s[i] as usize];
|
||||||
|
} // else leave as 0
|
||||||
|
}
|
||||||
|
assign(Value::vector(new, ctrl_ty)?)
|
||||||
|
}
|
||||||
|
Opcode::Splat => {
|
||||||
|
let mut new_vector = SimdVec::new();
|
||||||
|
for _ in 0..ctrl_ty.lane_count() {
|
||||||
|
new_vector.push(arg(0)?.into_int()?);
|
||||||
|
}
|
||||||
|
assign(vectorizelanes(&new_vector, ctrl_ty)?)
|
||||||
|
}
|
||||||
Opcode::Insertlane => {
|
Opcode::Insertlane => {
|
||||||
let idx = imm().into_int()? as usize;
|
let idx = imm().into_int()? as usize;
|
||||||
let mut vector = extractlanes(&arg(0)?, ctrl_ty.lane_type())?;
|
let mut vector = extractlanes(&arg(0)?, ctrl_ty.lane_type())?;
|
||||||
|
|||||||
Reference in New Issue
Block a user