aarch64: Migrate ishl/ushr/sshr to ISLE (#3608)
* aarch64: Migrate ishl/ushr/sshr to ISLE This commit migrates the `ishl`, `ushr`, and `sshr` instructions to ISLE. These involve special cases for almost all types of integers (including vectors) and helper functions for the i128 lowerings since the i128 lowerings look to be used for other instructions as well. This doesn't delete the i128 lowerings in the Rust code just yet because they're still used by Rust lowerings, but they should be deletable in due time once those lowerings are translated to ISLE. * Use more descriptive names for i128 lowerings * Use a with_flags-lookalike for csel * Use existing `with_flags_*` * Coment backwards order * Update generated code
This commit is contained in:
@@ -89,15 +89,6 @@ pub(crate) enum ResultRegImmShift {
|
||||
ImmShift(ImmShift),
|
||||
}
|
||||
|
||||
impl ResultRegImmShift {
|
||||
pub fn unwrap_reg(self) -> Reg {
|
||||
match self {
|
||||
ResultRegImmShift::Reg(r) => r,
|
||||
_ => panic!("Unwrapped ResultRegImmShift, expected reg, got: {:?}", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// Lowering: convert instruction inputs to forms that we can use.
|
||||
|
||||
@@ -518,28 +509,6 @@ pub(crate) fn alu_inst_imm12(op: ALUOp, rd: Writable<Reg>, rn: Reg, rm: ResultRS
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn alu_inst_immshift(
|
||||
op: ALUOp,
|
||||
rd: Writable<Reg>,
|
||||
rn: Reg,
|
||||
rm: ResultRegImmShift,
|
||||
) -> Inst {
|
||||
match rm {
|
||||
ResultRegImmShift::ImmShift(immshift) => Inst::AluRRImmShift {
|
||||
alu_op: op,
|
||||
rd,
|
||||
rn,
|
||||
immshift,
|
||||
},
|
||||
ResultRegImmShift::Reg(rm) => Inst::AluRRR {
|
||||
alu_op: op,
|
||||
rd,
|
||||
rn,
|
||||
rm,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// Lowering: addressing mode support. Takes instruction directly, rather
|
||||
// than an `InsnInput`, to do more introspection.
|
||||
@@ -1516,43 +1485,6 @@ pub(crate) fn materialize_bool_result<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lower_shift_amt<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
amt_input: InsnInput,
|
||||
dst_ty: Type,
|
||||
tmp_reg: Writable<Reg>,
|
||||
) -> ResultRegImmShift {
|
||||
let amt_ty = ctx.input_ty(amt_input.insn, amt_input.input);
|
||||
|
||||
match (dst_ty, amt_ty) {
|
||||
// When shifting for amounts larger than the size of the type, the CLIF shift
|
||||
// instructions implement a "wrapping" behaviour, such that an i8 << 8 is
|
||||
// equivalent to i8 << 0
|
||||
//
|
||||
// On i32 and i64 types this matches what the aarch64 spec does, but on smaller
|
||||
// types (i16, i8) we need to do this manually, so we wrap the shift amount
|
||||
// with an AND instruction
|
||||
(I16 | I8, _) => {
|
||||
// We can ignore the top half of the shift amount register if the type is I128
|
||||
let amt_reg = put_input_in_regs(ctx, amt_input).regs()[0];
|
||||
let mask = (ty_bits(dst_ty) - 1) as u64;
|
||||
ctx.emit(Inst::AluRRImmLogic {
|
||||
alu_op: ALUOp::And32,
|
||||
rd: tmp_reg,
|
||||
rn: amt_reg,
|
||||
imml: ImmLogic::maybe_from_u64(mask, I32).unwrap(),
|
||||
});
|
||||
ResultRegImmShift::Reg(tmp_reg.to_reg())
|
||||
}
|
||||
// TODO: We can use immlogic for i128 types here
|
||||
(I128, _) | (_, I128) => {
|
||||
// For I128 shifts, we need a register without immlogic
|
||||
ResultRegImmShift::Reg(put_input_in_regs(ctx, amt_input).regs()[0])
|
||||
}
|
||||
_ => put_input_in_reg_immshift(ctx, amt_input, ty_bits(dst_ty)),
|
||||
}
|
||||
}
|
||||
|
||||
/// This is target-word-size dependent. And it excludes booleans and reftypes.
|
||||
pub(crate) fn is_valid_atomic_transaction_ty(ty: Type) -> bool {
|
||||
match ty {
|
||||
|
||||
Reference in New Issue
Block a user