diff --git a/cranelift/filetests/filetests/runtests/simd-swidenhigh.clif b/cranelift/filetests/filetests/runtests/simd-swidenhigh.clif new file mode 100644 index 0000000000..47d4229c61 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-swidenhigh.clif @@ -0,0 +1,26 @@ +test interpret +test run +target aarch64 +set enable_simd +target x86_64 + +function %swidenhigh_i8x16(i8x16) -> i16x8 { +block0(v0: i8x16): + v1 = swiden_high v0 + return v1 +} +; run: %swidenhigh_i8x16([1 -2 3 -4 5 -6 7 -8 9 -10 11 -12 13 -14 15 -16]) == [9 -10 11 -12 13 -14 15 -16] + +function %swidenhigh_i16x8(i16x8) -> i32x4 { +block0(v0: i16x8): + v1 = swiden_high v0 + return v1 +} +; run: %swidenhigh_i16x8([1 -2 3 -4 5 -6 7 -8]) == [5 -6 7 -8] + +function %swidenhigh_i32x4(i32x4) -> i64x2 { +block0(v0: i32x4): + v1 = swiden_high v0 + return v1 +} +; run: %swidenhigh_i32x4([1 -2 3 -4]) == [3 -4] diff --git a/cranelift/filetests/filetests/runtests/simd-swidenlow.clif b/cranelift/filetests/filetests/runtests/simd-swidenlow.clif new file mode 100644 index 0000000000..997734702b --- /dev/null +++ b/cranelift/filetests/filetests/runtests/simd-swidenlow.clif @@ -0,0 +1,26 @@ +test interpret +test run +target aarch64 +set enable_simd +target x86_64 + +function %swidenlow_i8x16(i8x16) -> i16x8 { +block0(v0: i8x16): + v1 = swiden_low v0 + return v1 +} +; run: %swidenlow_i8x16([1 -2 3 -4 5 -6 7 -8 9 -10 11 -12 13 -14 15 -16]) == [1 -2 3 -4 5 -6 7 -8] + +function %swidenlow_i16x8(i16x8) -> i32x4 { +block0(v0: i16x8): + v1 = swiden_low v0 + return v1 +} +; run: %swidenlow_i16x8([1 -2 3 -4 5 -6 7 -8]) == [1 -2 3 -4] + +function %swidenlow_i32x4(i32x4) -> i64x2 { +block0(v0: i32x4): + v1 = swiden_low v0 + return v1 +} +; run: %swidenlow_i32x4([1 -2 3 -4]) == [1 -2] diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index 6b3eb59ff8..4a013868e9 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -840,8 +840,28 @@ where V::bool(true, types::B1)?, |acc, lane| acc.and(lane), )?), - Opcode::SwidenLow => unimplemented!("SwidenLow"), - Opcode::SwidenHigh => unimplemented!("SwidenHigh"), + Opcode::SwidenLow => { + let new_type = ctrl_ty.merge_lanes().unwrap(); + let mut new_vec = SimdVec::new(); + let mut arg0 = extractlanes(&arg(0)?, ctrl_ty.lane_type())?; + arg0.truncate(new_type.lane_count() as usize); + for lane in arg0 { + let lane = lane.convert(ValueConversionKind::SignExtend(new_type.lane_type()))?; + new_vec.push(lane); + } + assign(vectorizelanes(&new_vec, new_type)?) + } + Opcode::SwidenHigh => { + let new_type = ctrl_ty.merge_lanes().unwrap(); + let mut new_vec = SimdVec::new(); + let mut arg0 = extractlanes(&arg(0)?, ctrl_ty.lane_type())?; + arg0.drain(0..new_type.lane_count() as usize); + for lane in arg0 { + let lane = lane.convert(ValueConversionKind::SignExtend(new_type.lane_type()))?; + new_vec.push(lane); + } + assign(vectorizelanes(&new_vec, new_type)?) + } Opcode::UwidenLow => { let new_type = ctrl_ty.merge_lanes().unwrap(); let new_vec = extractlanes(&arg(0)?, ctrl_ty.lane_type())? diff --git a/cranelift/interpreter/src/value.rs b/cranelift/interpreter/src/value.rs index bd4cd93445..768ccfe8e2 100644 --- a/cranelift/interpreter/src/value.rs +++ b/cranelift/interpreter/src/value.rs @@ -301,14 +301,14 @@ impl Value for DataValue { let extracted = (self.into_int()? & shifted_mask) >> shift_amt; Self::from_integer(extracted, ty)? } - ValueConversionKind::SignExtend(ty) => match (self.ty(), ty) { - (types::I8, types::I16) => unimplemented!(), - (types::I8, types::I32) => unimplemented!(), - (types::I8, types::I64) => unimplemented!(), - (types::I16, types::I32) => unimplemented!(), - (types::I16, types::I64) => unimplemented!(), - (types::I32, types::I64) => unimplemented!(), - _ => unimplemented!("conversion: {} -> {:?}", self.ty(), kind), + ValueConversionKind::SignExtend(ty) => match (self, ty) { + (DataValue::I8(n), types::I16) => DataValue::I16(n as i16), + (DataValue::I8(n), types::I32) => DataValue::I32(n as i32), + (DataValue::I8(n), types::I64) => DataValue::I64(n as i64), + (DataValue::I16(n), types::I32) => DataValue::I32(n as i32), + (DataValue::I16(n), types::I64) => DataValue::I64(n as i64), + (DataValue::I32(n), types::I64) => DataValue::I64(n as i64), + (dv, _) => unimplemented!("conversion: {} -> {:?}", dv.ty(), kind), }, ValueConversionKind::ZeroExtend(ty) => match (self, ty) { (DataValue::U8(n), types::I16) => DataValue::U16(n as u16),