Avoid reusing a register during constant loading (#5379)
Avoid reusing a register when loading a constant, allocating a temporary instead.
This commit is contained in:
@@ -53,11 +53,16 @@ impl LoadConstant {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn load_constant(self, rd: Writable<Reg>) -> SmallInstVec<Inst> {
|
||||
pub(crate) fn load_constant<F: FnMut(Type) -> Writable<Reg>>(
|
||||
self,
|
||||
rd: Writable<Reg>,
|
||||
alloc_tmp: &mut F,
|
||||
) -> SmallInstVec<Inst> {
|
||||
let mut insts = SmallInstVec::new();
|
||||
// get current pc.
|
||||
let pc = alloc_tmp(I64);
|
||||
insts.push(Inst::Auipc {
|
||||
rd,
|
||||
rd: pc,
|
||||
imm: Imm20 { bits: 0 },
|
||||
});
|
||||
// load
|
||||
@@ -65,7 +70,7 @@ impl LoadConstant {
|
||||
rd,
|
||||
op: self.load_op(),
|
||||
flags: MemFlags::new(),
|
||||
from: AMode::RegOffset(rd.to_reg(), 12, self.load_ty()),
|
||||
from: AMode::RegOffset(pc.to_reg(), 12, self.load_ty()),
|
||||
});
|
||||
let data = self.to_le_bytes();
|
||||
// jump over.
|
||||
@@ -78,10 +83,10 @@ impl LoadConstant {
|
||||
|
||||
// load and perform an extra add.
|
||||
pub(crate) fn load_constant_and_add(self, rd: Writable<Reg>, rs: Reg) -> SmallInstVec<Inst> {
|
||||
let mut insts = self.load_constant(rd);
|
||||
let mut insts = self.load_constant(rd, &mut |_| rd);
|
||||
insts.push(Inst::AluRRR {
|
||||
alu_op: AluOPRRR::Add,
|
||||
rd: rd,
|
||||
rd,
|
||||
rs1: rd.to_reg(),
|
||||
rs2: rs,
|
||||
});
|
||||
|
||||
@@ -235,7 +235,7 @@ impl Inst {
|
||||
alloc_tmp: &mut F,
|
||||
) -> SmallInstVec<Inst> {
|
||||
let insts = Inst::load_const_imm(rd, value, alloc_tmp);
|
||||
insts.unwrap_or(LoadConstant::U32(value as u32).load_constant(rd))
|
||||
insts.unwrap_or(LoadConstant::U32(value as u32).load_constant(rd, alloc_tmp))
|
||||
}
|
||||
|
||||
pub fn load_constant_u64<F: FnMut(Type) -> Writable<Reg>>(
|
||||
@@ -244,7 +244,7 @@ impl Inst {
|
||||
alloc_tmp: &mut F,
|
||||
) -> SmallInstVec<Inst> {
|
||||
let insts = Inst::load_const_imm(rd, value, alloc_tmp);
|
||||
insts.unwrap_or(LoadConstant::U64(value).load_constant(rd))
|
||||
insts.unwrap_or(LoadConstant::U64(value).load_constant(rd, alloc_tmp))
|
||||
}
|
||||
|
||||
pub(crate) fn construct_auipc_and_jalr(
|
||||
|
||||
Reference in New Issue
Block a user