cranelift: Fix shifts and implement rotates in interpreter (#4519)
* cranelift: Fix shifts and implement rotates in interpreter * x64: Implement `rotl`/`rotr` for some small type combinations
This commit is contained in:
@@ -153,6 +153,20 @@ where
|
||||
right: V|
|
||||
-> ValueResult<ControlFlow<V>> { Ok(assign(op(left, right)?)) };
|
||||
|
||||
// Same as `binary_unsigned`, but converts the values to their unsigned form before the
|
||||
// operation and back to signed form afterwards. Since Cranelift types have no notion of
|
||||
// signedness, this enables operations that depend on sign.
|
||||
let binary_unsigned =
|
||||
|op: fn(V, V) -> ValueResult<V>, left: V, right: V| -> ValueResult<ControlFlow<V>> {
|
||||
Ok(assign(
|
||||
op(
|
||||
left.convert(ValueConversionKind::ToUnsigned)?,
|
||||
right.convert(ValueConversionKind::ToUnsigned)?,
|
||||
)
|
||||
.and_then(|v| v.convert(ValueConversionKind::ToSigned))?,
|
||||
))
|
||||
};
|
||||
|
||||
// Similar to `binary` but converts select `ValueError`'s into trap `ControlFlow`'s
|
||||
let binary_can_trap = |op: fn(V, V) -> ValueResult<V>,
|
||||
left: V,
|
||||
@@ -690,10 +704,10 @@ where
|
||||
Opcode::RotlImm => binary(Value::rotl, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::RotrImm => binary(Value::rotr, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::Ishl => binary(Value::shl, arg(0)?, arg(1)?)?,
|
||||
Opcode::Ushr => binary(Value::ushr, arg(0)?, arg(1)?)?,
|
||||
Opcode::Ushr => binary_unsigned(Value::ushr, arg(0)?, arg(1)?)?,
|
||||
Opcode::Sshr => binary(Value::ishr, arg(0)?, arg(1)?)?,
|
||||
Opcode::IshlImm => binary(Value::shl, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::UshrImm => binary(Value::ushr, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::UshrImm => binary_unsigned(Value::ushr, 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::Clz => assign(arg(0)?.leading_zeros()?),
|
||||
|
||||
Reference in New Issue
Block a user