Implement Shuffle for the interpreter

Implemented `Shuffle` for the Cranelift interpreter, to shuffle two SIMD
vectors together based on an immediate mask of 16 bytes.

Copyright (c) 2021, Arm Limited
This commit is contained in:
dheaton-arm
2021-09-06 11:50:21 +01:00
parent 164835ecf5
commit bca3cb32ef
2 changed files with 36 additions and 1 deletions

View File

@@ -0,0 +1,12 @@
test interpret
test run
target aarch64
set enable_simd
target x86_64
function %shuffle_i8x16(i8x16, i8x16) -> i8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = shuffle v0, v1, [3 0 31 26 100 6 12 11 23 13 24 4 2 15 17 5]
return v2
}
; run: %shuffle_i8x16([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16], [17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32]) == [4 1 32 27 0 7 13 12 24 14 25 5 3 16 18 6]

View File

@@ -776,7 +776,30 @@ where
arg(0)?,
ValueConversionKind::RoundNearestEven(ctrl_ty),
)?),
Opcode::Shuffle => unimplemented!("Shuffle"),
Opcode::Shuffle => {
if let InstructionData::Shuffle { mask, .. } = inst {
let mask = state
.get_current_function()
.dfg
.immediates
.get(mask)
.unwrap()
.as_slice();
let a = Value::into_array(&arg(0)?)?;
let b = Value::into_array(&arg(1)?)?;
let mut new = [0u8; 16];
for i in 0..mask.len() {
if (mask[i] as usize) < a.len() {
new[i] = a[mask[i] as usize];
} else if (mask[i] as usize - a.len()) < b.len() {
new[i] = b[mask[i] as usize - a.len()];
} // else leave as 0.
}
assign(Value::vector(new, ctrl_ty)?)
} else {
unreachable!();
}
}
Opcode::Swizzle => {
let x = Value::into_array(&arg(0)?)?;
let s = Value::into_array(&arg(1)?)?;