Merge pull request #3362 from dheaton-arm/implement-unarrow
Implement `Unarrow`, `Uunarrow`, and `Snarrow` for the interpreter
This commit is contained in:
@@ -772,19 +772,40 @@ where
|
||||
arg(0)?,
|
||||
ValueConversionKind::Exact(ctrl_ty),
|
||||
)?),
|
||||
Opcode::Snarrow => assign(Value::convert(
|
||||
arg(0)?,
|
||||
ValueConversionKind::Truncate(ctrl_ty),
|
||||
)?),
|
||||
Opcode::Snarrow | Opcode::Unarrow | Opcode::Uunarrow => {
|
||||
let arg0 = extractlanes(&arg(0)?, ctrl_ty.lane_type())?;
|
||||
let arg1 = extractlanes(&arg(1)?, ctrl_ty.lane_type())?;
|
||||
let new_type = ctrl_ty.split_lanes().unwrap();
|
||||
let (min, max) = new_type.bounds(inst.opcode() == Opcode::Snarrow);
|
||||
let mut min: V = Value::int(min as i128, ctrl_ty.lane_type())?;
|
||||
let mut max: V = Value::int(max as i128, ctrl_ty.lane_type())?;
|
||||
if inst.opcode() == Opcode::Uunarrow {
|
||||
min = min.convert(ValueConversionKind::ToUnsigned)?;
|
||||
max = max.convert(ValueConversionKind::ToUnsigned)?;
|
||||
}
|
||||
let narrow = |mut lane: V| -> ValueResult<V> {
|
||||
if inst.opcode() == Opcode::Uunarrow {
|
||||
lane = lane.convert(ValueConversionKind::ToUnsigned)?;
|
||||
}
|
||||
lane = Value::max(lane, min.clone())?;
|
||||
lane = Value::min(lane, max.clone())?;
|
||||
lane = lane.convert(ValueConversionKind::Truncate(new_type.lane_type()))?;
|
||||
if inst.opcode() == Opcode::Unarrow || inst.opcode() == Opcode::Uunarrow {
|
||||
lane = lane.convert(ValueConversionKind::ToUnsigned)?;
|
||||
}
|
||||
Ok(lane)
|
||||
};
|
||||
let new_vec = arg0
|
||||
.into_iter()
|
||||
.chain(arg1)
|
||||
.map(|lane| narrow(lane))
|
||||
.collect::<ValueResult<Vec<_>>>()?;
|
||||
assign(vectorizelanes(&new_vec, new_type)?)
|
||||
}
|
||||
Opcode::Sextend => assign(Value::convert(
|
||||
arg(0)?,
|
||||
ValueConversionKind::SignExtend(ctrl_ty),
|
||||
)?),
|
||||
Opcode::Unarrow => assign(Value::convert(
|
||||
arg(0)?,
|
||||
ValueConversionKind::Truncate(ctrl_ty),
|
||||
)?),
|
||||
Opcode::Uunarrow => unimplemented!("Uunarrow"),
|
||||
Opcode::Uextend => assign(Value::convert(
|
||||
arg(0)?,
|
||||
ValueConversionKind::ZeroExtend(ctrl_ty),
|
||||
|
||||
Reference in New Issue
Block a user