Port Fence, IsNull/IsInvalid & Debugtrap to ISLE (AArch64) (#4548)
Ported the existing implementation of the following Opcodes for AArch64 to ISLE: - `Fence` - `IsNull` - `IsInvalid` - `Debugtrap` Copyright (c) 2022 Arm Limited
This commit is contained in:
@@ -1567,6 +1567,27 @@
|
||||
(MInst.AluRRR (ALUOp.SubS) (operand_size ty) dst src1 src2)
|
||||
dst)))
|
||||
|
||||
;; Helper for materializing a boolean value into a register from
|
||||
;; flags.
|
||||
(decl materialize_bool_result (u8 Cond) ConsumesFlags)
|
||||
(rule (materialize_bool_result 1 cond)
|
||||
(let ((dst WritableReg (temp_writable_reg $I64)))
|
||||
(ConsumesFlags.ConsumesFlagsReturnsReg
|
||||
(MInst.CSet dst cond)
|
||||
dst)))
|
||||
|
||||
(rule -1 (materialize_bool_result _ty_bits cond)
|
||||
(let ((dst WritableReg (temp_writable_reg $I64)))
|
||||
(ConsumesFlags.ConsumesFlagsReturnsReg
|
||||
(MInst.CSetm dst cond)
|
||||
dst)))
|
||||
|
||||
(decl cmn_imm (OperandSize Reg Imm12) ProducesFlags)
|
||||
(rule (cmn_imm size src1 src2)
|
||||
(ProducesFlags.ProducesFlagsSideEffect
|
||||
(MInst.AluRRImm12 (ALUOp.AddS) size (writable_zero_reg)
|
||||
src1 src2)))
|
||||
|
||||
(decl cmp_imm (OperandSize Reg Imm12) ProducesFlags)
|
||||
(rule (cmp_imm size src1 src2)
|
||||
(ProducesFlags.ProducesFlagsSideEffect
|
||||
|
||||
@@ -1699,3 +1699,29 @@
|
||||
(let ((low_half Reg (uqxtn x (lane_size ty)))
|
||||
(result Reg (uqxtn2 low_half y (lane_size ty))))
|
||||
result))
|
||||
|
||||
;;;; Rules for `Fence` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (fence))
|
||||
(let ((_ Unit (emit (MInst.Fence))))
|
||||
(output_none)))
|
||||
|
||||
;;;; Rules for `IsNull` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type out_ty (is_null x @ (value_type ty))))
|
||||
(with_flags (cmp_imm (operand_size ty) x (u8_into_imm12 0))
|
||||
(materialize_bool_result
|
||||
(ty_bits out_ty) (Cond.Eq))))
|
||||
|
||||
;;;; Rules for `IsInvalid` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type out_ty (is_invalid x @ (value_type ty))))
|
||||
(with_flags (cmn_imm (operand_size ty) x (u8_into_imm12 1))
|
||||
(materialize_bool_result
|
||||
(ty_bits out_ty) (Cond.Eq))))
|
||||
|
||||
;;;; Rules for `Debugtrap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (debugtrap))
|
||||
(let ((_ Unit (emit (MInst.Brk))))
|
||||
(output_none)))
|
||||
|
||||
@@ -254,9 +254,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
|
||||
Opcode::AtomicStore => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Fence => {
|
||||
ctx.emit(Inst::Fence {});
|
||||
}
|
||||
Opcode::Fence => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::StackLoad
|
||||
| Opcode::StackStore
|
||||
@@ -399,34 +397,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
materialize_bool_result(ctx, insn, rd, cond);
|
||||
}
|
||||
|
||||
Opcode::IsNull | Opcode::IsInvalid => {
|
||||
// Null references are represented by the constant value 0; invalid references are
|
||||
// represented by the constant value -1. See `define_reftypes()` in
|
||||
// `meta/src/isa/x86/encodings.rs` to confirm.
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let rn = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let ty = ctx.input_ty(insn, 0);
|
||||
let (alu_op, const_value) = match op {
|
||||
Opcode::IsNull => {
|
||||
// cmp rn, #0
|
||||
(ALUOp::SubS, 0)
|
||||
}
|
||||
Opcode::IsInvalid => {
|
||||
// cmn rn, #1
|
||||
(ALUOp::AddS, 1)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let const_value = ResultRSEImm12::Imm12(Imm12::maybe_from_u64(const_value).unwrap());
|
||||
ctx.emit(alu_inst_imm12(
|
||||
alu_op,
|
||||
ty,
|
||||
writable_zero_reg(),
|
||||
rn,
|
||||
const_value,
|
||||
));
|
||||
materialize_bool_result(ctx, insn, rd, Cond::Eq);
|
||||
}
|
||||
Opcode::IsNull | Opcode::IsInvalid => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Copy => {
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
@@ -546,9 +517,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
Opcode::Debugtrap => {
|
||||
ctx.emit(Inst::Brk);
|
||||
}
|
||||
Opcode::Debugtrap => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trap | Opcode::ResumableTrap => implemented_in_isle(ctx),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user