Merge pull request #3324 from dheaton-arm/implement-shuffle
Implement `Shuffle` for the interpreter
This commit is contained in:
12
cranelift/filetests/filetests/runtests/simd-shuffle.clif
Normal file
12
cranelift/filetests/filetests/runtests/simd-shuffle.clif
Normal 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]
|
||||||
@@ -76,6 +76,16 @@ where
|
|||||||
.as_slice();
|
.as_slice();
|
||||||
DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"))
|
DataValue::V128(buffer.try_into().expect("a 16-byte data buffer"))
|
||||||
}
|
}
|
||||||
|
InstructionData::Shuffle { mask, .. } => {
|
||||||
|
let mask = state
|
||||||
|
.get_current_function()
|
||||||
|
.dfg
|
||||||
|
.immediates
|
||||||
|
.get(mask)
|
||||||
|
.unwrap()
|
||||||
|
.as_slice();
|
||||||
|
DataValue::V128(mask.try_into().expect("a 16-byte vector mask"))
|
||||||
|
}
|
||||||
_ => inst.imm_value().unwrap(),
|
_ => inst.imm_value().unwrap(),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@@ -794,7 +804,20 @@ where
|
|||||||
arg(0)?,
|
arg(0)?,
|
||||||
ValueConversionKind::RoundNearestEven(ctrl_ty),
|
ValueConversionKind::RoundNearestEven(ctrl_ty),
|
||||||
)?),
|
)?),
|
||||||
Opcode::Shuffle => unimplemented!("Shuffle"),
|
Opcode::Shuffle => {
|
||||||
|
let mask = imm().into_array()?;
|
||||||
|
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)?)
|
||||||
|
}
|
||||||
Opcode::Swizzle => {
|
Opcode::Swizzle => {
|
||||||
let x = Value::into_array(&arg(0)?)?;
|
let x = Value::into_array(&arg(0)?)?;
|
||||||
let s = Value::into_array(&arg(1)?)?;
|
let s = Value::into_array(&arg(1)?)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user