riscv64: Move is_null/is_invalid to ISLE (#5874)

* riscv64: Move `is_null`/`is_invalid` to ISLE

* riscv64: Fix `is_invalid` codegen

* Implement review suggestions

Thanks!

Co-authored-by: Jamey Sharp <jamey@minilop.net>

---------

Co-authored-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
Afonso Bordado
2023-02-25 12:48:44 +00:00
committed by GitHub
parent 67e2e57b02
commit 36e92add6f
10 changed files with 33 additions and 116 deletions

View File

@@ -1639,23 +1639,6 @@ impl IntSelectOP {
}
}
impl ReferenceCheckOP {
pub(crate) fn op_name(self) -> &'static str {
match self {
ReferenceCheckOP::IsNull => "is_null",
ReferenceCheckOP::IsInvalid => "is_invalid",
}
}
#[inline]
pub(crate) fn from_ir_op(op: crate::ir::Opcode) -> Self {
match op {
crate::ir::Opcode::IsInvalid => Self::IsInvalid,
crate::ir::Opcode::IsNull => Self::IsNull,
_ => unreachable!(),
}
}
}
#[derive(Clone, Copy)]
pub enum CsrAddress {
Fcsr = 0x3,

View File

@@ -680,57 +680,6 @@ impl MachInstEmit for Inst {
.for_each(|inst| inst.emit(&[], sink, emit_info, state));
}
}
&Inst::ReferenceCheck { rd, op, x } => {
let x = allocs.next(x);
let rd = allocs.next_writable(rd);
let mut insts = SmallInstVec::new();
match op {
ReferenceCheckOP::IsNull => {
insts.push(Inst::CondBr {
taken: BranchTarget::ResolvedOffset(Inst::INSTRUCTION_SIZE * 3),
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::Equal,
rs1: zero_reg(),
rs2: x,
},
});
// here is false
insts.push(Inst::load_imm12(rd, Imm12::FALSE));
insts.push(Inst::Jal {
dest: BranchTarget::ResolvedOffset(Inst::INSTRUCTION_SIZE * 2),
});
// here is true
insts.push(Inst::load_imm12(rd, Imm12::TRUE));
}
ReferenceCheckOP::IsInvalid => {
// todo:: right now just check if it is null
// null is a valid reference??????
insts.push(Inst::CondBr {
taken: BranchTarget::ResolvedOffset(Inst::INSTRUCTION_SIZE * 3),
not_taken: BranchTarget::zero(),
kind: IntegerCompare {
kind: IntCC::Equal,
rs1: zero_reg(),
rs2: x,
},
});
// here is false
insts.push(Inst::load_imm12(rd, Imm12::FALSE));
insts.push(Inst::Jal {
dest: BranchTarget::ResolvedOffset(Inst::INSTRUCTION_SIZE * 2),
});
// here is true
insts.push(Inst::load_imm12(rd, Imm12::TRUE));
}
}
insts
.into_iter()
.for_each(|i| i.emit(&[], sink, emit_info, state));
}
&Inst::Args { .. } => {
// Nothing: this is a pseudoinstruction that serves
// only to constrain registers at a certain point.

View File

@@ -51,8 +51,7 @@ pub(crate) type VecWritableReg = Vec<Writable<Reg>>;
use crate::isa::riscv64::lower::isle::generated_code::MInst;
pub use crate::isa::riscv64::lower::isle::generated_code::{
AluOPRRI, AluOPRRR, AtomicOP, CsrOP, FClassResult, FFlagsException, FenceFm, FloatRoundOP,
FloatSelectOP, FpuOPRR, FpuOPRRR, FpuOPRRRR, IntSelectOP, LoadOP, MInst as Inst,
ReferenceCheckOP, StoreOP, FRM,
FloatSelectOP, FpuOPRR, FpuOPRRR, FpuOPRRRR, IntSelectOP, LoadOP, MInst as Inst, StoreOP, FRM,
};
type BoxCallInfo = Box<CallInfo>;
@@ -471,10 +470,6 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
collector.reg_early_def(d.clone());
}
}
&Inst::ReferenceCheck { rd, x, .. } => {
collector.reg_use(x);
collector.reg_def(rd);
}
&Inst::AtomicCas {
offset,
t0,
@@ -1185,12 +1180,6 @@ impl Inst {
imm.bits
)
}
&Inst::ReferenceCheck { rd, op, x } => {
let x = format_reg(x, allocs);
let rd = format_reg(rd.to_reg(), allocs);
format!("{} {},{}", op.op_name(), rd, x)
}
&Inst::Jalr { rd, base, offset } => {
let base = format_reg(base, allocs);
let rd = format_reg(rd.to_reg(), allocs);
@@ -1344,6 +1333,9 @@ impl Inst {
(AluOPRRI::Xori, _, imm12) if imm12.as_i16() == -1 => {
return format!("not {},{}", rd, rs_s);
}
(AluOPRRI::SltiU, _, imm12) if imm12.as_i16() == 1 => {
return format!("seqz {},{}", rd, rs_s);
}
(alu_op, _, _) if alu_op.option_funct12().is_some() => {
format!("{} {},{}", alu_op.op_name(), rd, rs_s)
}