Merge pull request #3317 from dheaton-arm/implement-swiden

Implement `SwidenLow` and `SwidenHigh` for the interpreter
This commit is contained in:
Chris Fallin
2021-09-14 08:57:57 -07:00
committed by GitHub
4 changed files with 82 additions and 25 deletions

View File

@@ -863,24 +863,29 @@ where
V::bool(true, types::B1)?,
|acc, lane| acc.and(lane),
)?),
Opcode::SwidenLow => unimplemented!("SwidenLow"),
Opcode::SwidenHigh => unimplemented!("SwidenHigh"),
Opcode::UwidenLow => {
Opcode::SwidenLow | Opcode::SwidenHigh | Opcode::UwidenLow | Opcode::UwidenHigh => {
let new_type = ctrl_ty.merge_lanes().unwrap();
let new_vec = extractlanes(&arg(0)?, ctrl_ty.lane_type())?
.into_iter()
.take(new_type.lane_count() as usize)
.map(|lane| lane.convert(ValueConversionKind::ZeroExtend(new_type.lane_type())))
.collect::<ValueResult<Vec<_>>>()?;
assign(vectorizelanes(&new_vec, new_type)?)
}
Opcode::UwidenHigh => {
let new_type = ctrl_ty.merge_lanes().unwrap();
let new_vec = extractlanes(&arg(0)?, ctrl_ty.lane_type())?
.into_iter()
.skip(new_type.lane_count() as usize)
.map(|lane| lane.convert(ValueConversionKind::ZeroExtend(new_type.lane_type())))
.collect::<ValueResult<Vec<_>>>()?;
let conv_type = match inst.opcode() {
Opcode::SwidenLow | Opcode::SwidenHigh => {
ValueConversionKind::SignExtend(new_type.lane_type())
}
Opcode::UwidenLow | Opcode::UwidenHigh => {
ValueConversionKind::ZeroExtend(new_type.lane_type())
}
_ => unreachable!(),
};
let vec_iter = extractlanes(&arg(0)?, ctrl_ty.lane_type())?.into_iter();
let new_vec = match inst.opcode() {
Opcode::SwidenLow | Opcode::UwidenLow => vec_iter
.take(new_type.lane_count() as usize)
.map(|lane| lane.convert(conv_type.clone()))
.collect::<ValueResult<Vec<_>>>()?,
Opcode::SwidenHigh | Opcode::UwidenHigh => vec_iter
.skip(new_type.lane_count() as usize)
.map(|lane| lane.convert(conv_type.clone()))
.collect::<ValueResult<Vec<_>>>()?,
_ => unreachable!(),
};
assign(vectorizelanes(&new_vec, new_type)?)
}
Opcode::FcvtToUint => unimplemented!("FcvtToUint"),

View File

@@ -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),