Cast types back to expected in macros
Also neatened `popcnt` a little following feedback. Copyright (c) 2021, Arm Limited
This commit is contained in:
@@ -669,36 +669,25 @@ where
|
|||||||
Opcode::UshrImm => binary(Value::ushr, arg(0)?, imm_as_ctrl_ty()?)?,
|
Opcode::UshrImm => binary(Value::ushr, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||||
Opcode::SshrImm => binary(Value::ishr, arg(0)?, imm_as_ctrl_ty()?)?,
|
Opcode::SshrImm => binary(Value::ishr, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||||
Opcode::Bitrev => assign(Value::reverse_bits(arg(0)?)?),
|
Opcode::Bitrev => assign(Value::reverse_bits(arg(0)?)?),
|
||||||
// For `Clz`, `Cls`, `Ctz`, and `Popcnt`, the underlying Rust function
|
Opcode::Clz => assign(arg(0)?.leading_zeros()?),
|
||||||
// always returns `u32` (and therefore a `Value` of type `U32`), so this
|
|
||||||
// is switched back to the correct type by recreating the `Value`.
|
|
||||||
Opcode::Clz => assign(Value::int(
|
|
||||||
Value::leading_zeros(arg(0)?)?.into_int()?,
|
|
||||||
ctrl_ty,
|
|
||||||
)?),
|
|
||||||
Opcode::Cls => {
|
Opcode::Cls => {
|
||||||
let count = if Value::lt(&arg(0)?, &Value::int(0, ctrl_ty)?)? {
|
let count = if Value::lt(&arg(0)?, &Value::int(0, ctrl_ty)?)? {
|
||||||
Value::int(Value::leading_ones(arg(0)?)?.into_int()?, ctrl_ty)?
|
arg(0)?.leading_ones()?
|
||||||
} else {
|
} else {
|
||||||
Value::int(Value::leading_zeros(arg(0)?)?.into_int()?, ctrl_ty)?
|
arg(0)?.leading_zeros()?
|
||||||
};
|
};
|
||||||
assign(Value::sub(count, Value::int(1, ctrl_ty)?)?)
|
assign(Value::sub(count, Value::int(1, ctrl_ty)?)?)
|
||||||
}
|
}
|
||||||
Opcode::Ctz => assign(Value::int(
|
Opcode::Ctz => assign(arg(0)?.trailing_zeros()?),
|
||||||
Value::trailing_zeros(arg(0)?)?.into_int()?,
|
|
||||||
ctrl_ty,
|
|
||||||
)?),
|
|
||||||
Opcode::Popcnt => {
|
Opcode::Popcnt => {
|
||||||
let count = if arg(0)?.ty().is_int() {
|
let count = if arg(0)?.ty().is_int() {
|
||||||
Value::int(Value::count_ones(arg(0)?)?.into_int()?, ctrl_ty)?
|
arg(0)?.count_ones()?
|
||||||
} else {
|
} else {
|
||||||
let lanes = extractlanes(&arg(0)?, ctrl_ty.lane_type())?;
|
let lanes = extractlanes(&arg(0)?, ctrl_ty.lane_type())?
|
||||||
let mut new_vec = SimdVec::new();
|
.into_iter()
|
||||||
for i in lanes {
|
.map(|lane| lane.count_ones().unwrap())
|
||||||
let c: V = Value::count_ones(i)?;
|
.collect::<SimdVec<V>>();
|
||||||
new_vec.push(c);
|
vectorizelanes(&lanes, ctrl_ty)?
|
||||||
}
|
|
||||||
vectorizelanes(&new_vec, ctrl_ty)?
|
|
||||||
};
|
};
|
||||||
assign(count)
|
assign(count)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,10 +139,10 @@ pub enum ValueConversionKind {
|
|||||||
|
|
||||||
/// Helper for creating match expressions over [DataValue].
|
/// Helper for creating match expressions over [DataValue].
|
||||||
macro_rules! unary_match {
|
macro_rules! unary_match {
|
||||||
( $op:ident($arg1:expr); [ $( $data_value_ty:ident ),* ]; $return_value_ty:ident ) => {
|
( $op:ident($arg1:expr); [ $( $data_value_ty:ident ),* ]; [ $( $return_value_ty:ident ),* ] ) => {
|
||||||
match $arg1 {
|
match $arg1 {
|
||||||
$( DataValue::$data_value_ty(a) => {
|
$( DataValue::$data_value_ty(a) => {
|
||||||
Ok(DataValue::$return_value_ty(a.$op()))
|
Ok(DataValue::$data_value_ty($return_value_ty::try_from(a.$op()).unwrap()))
|
||||||
} )*
|
} )*
|
||||||
_ => unimplemented!()
|
_ => unimplemented!()
|
||||||
}
|
}
|
||||||
@@ -461,19 +461,19 @@ impl Value for DataValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn count_ones(self) -> ValueResult<Self> {
|
fn count_ones(self) -> ValueResult<Self> {
|
||||||
unary_match!(count_ones(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; U32)
|
unary_match!(count_ones(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn leading_ones(self) -> ValueResult<Self> {
|
fn leading_ones(self) -> ValueResult<Self> {
|
||||||
unary_match!(leading_ones(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; U32)
|
unary_match!(leading_ones(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn leading_zeros(self) -> ValueResult<Self> {
|
fn leading_zeros(self) -> ValueResult<Self> {
|
||||||
unary_match!(leading_zeros(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; U32)
|
unary_match!(leading_zeros(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trailing_zeros(self) -> ValueResult<Self> {
|
fn trailing_zeros(self) -> ValueResult<Self> {
|
||||||
unary_match!(trailing_zeros(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; U32)
|
unary_match!(trailing_zeros(&self); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128]; [i8, i16, i32, i64, i128, u8, u16, u32, u64, u128])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse_bits(self) -> ValueResult<Self> {
|
fn reverse_bits(self) -> ValueResult<Self> {
|
||||||
|
|||||||
Reference in New Issue
Block a user