From bca3cb32ef9e37c62b4e282917a0d57c4e8a5362 Mon Sep 17 00:00:00 2001 From: dheaton-arm Date: Mon, 6 Sep 2021 11:50:21 +0100 Subject: [PATCH 1/2] 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 --- .../filetests/runtests/simd-shuffle.clif | 12 +++++++++ cranelift/interpreter/src/step.rs | 25 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 cranelift/filetests/filetests/runtests/simd-shuffle.clif diff --git a/cranelift/filetests/filetests/runtests/simd-shuffle.clif b/cranelift/filetests/filetests/runtests/simd-shuffle.clif new file mode 100644 index 0000000000..d4151953e6 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-shuffle.clif @@ -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] diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index ce53528c20..638db5937c 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -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)?)?; From 4a4f940facf98d172243805c25ce4456fc39b8bd Mon Sep 17 00:00:00 2001 From: dheaton-arm Date: Fri, 10 Sep 2021 12:36:33 +0100 Subject: [PATCH 2/2] Move immediate value retrieval to `imm` Copyright (c) 2021, Arm Limited --- cranelift/interpreter/src/step.rs | 42 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 638db5937c..bfba030176 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -76,6 +76,16 @@ where .as_slice(); 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(), }) }; @@ -777,28 +787,18 @@ where ValueConversionKind::RoundNearestEven(ctrl_ty), )?), 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!(); + 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 => { let x = Value::into_array(&arg(0)?)?;