Add a TargetIsa::allocatable_registers() method.
This gives the target ISA a chance to reserve registers like the stack pointer or hard-wired 0 registers like %x0 on RISC-V.
This commit is contained in:
@@ -6,8 +6,9 @@
|
||||
//! This doesn't support the soft-float ABI at the moment.
|
||||
|
||||
use abi::{ArgAction, ValueConversion, ArgAssigner, legalize_args};
|
||||
use ir::{Signature, Type, ArgumentType, ArgumentLoc, ArgumentExtension, ArgumentPurpose};
|
||||
use ir::{self, Type, ArgumentType, ArgumentLoc, ArgumentExtension, ArgumentPurpose};
|
||||
use isa::RegClass;
|
||||
use regalloc::AllocatableSet;
|
||||
use settings as shared_settings;
|
||||
use super::registers::{GPR, FPR};
|
||||
use super::settings;
|
||||
@@ -84,7 +85,7 @@ impl ArgAssigner for Args {
|
||||
}
|
||||
|
||||
/// Legalize `sig` for RISC-V.
|
||||
pub fn legalize_signature(sig: &mut Signature,
|
||||
pub fn legalize_signature(sig: &mut ir::Signature,
|
||||
flags: &shared_settings::Flags,
|
||||
isa_flags: &settings::Flags,
|
||||
current: bool) {
|
||||
@@ -114,3 +115,22 @@ pub fn legalize_signature(sig: &mut Signature,
|
||||
pub fn regclass_for_abi_type(ty: Type) -> RegClass {
|
||||
if ty.is_float() { FPR } else { GPR }
|
||||
}
|
||||
|
||||
pub fn allocatable_registers(_func: &ir::Function, isa_flags: &settings::Flags) -> AllocatableSet {
|
||||
let mut regs = AllocatableSet::new();
|
||||
regs.take(GPR, GPR.unit(0)); // Hard-wired 0.
|
||||
// %x1 is the link register which is available for allocation.
|
||||
regs.take(GPR, GPR.unit(2)); // Stack pointer.
|
||||
regs.take(GPR, GPR.unit(3)); // Global pointer.
|
||||
regs.take(GPR, GPR.unit(4)); // Thread pointer.
|
||||
// TODO: %x8 is the frame pointer. Reserve it?
|
||||
|
||||
// Remove %x16 and up for RV32E.
|
||||
if isa_flags.enable_e() {
|
||||
for u in 16..32 {
|
||||
regs.take(GPR, GPR.unit(u));
|
||||
}
|
||||
}
|
||||
|
||||
regs
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ use binemit::CodeSink;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Encoding, Legalize};
|
||||
use ir::{Function, Inst, InstructionData, DataFlowGraph, Signature, Type};
|
||||
use ir;
|
||||
use regalloc;
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Isa {
|
||||
@@ -61,9 +62,9 @@ impl TargetIsa for Isa {
|
||||
}
|
||||
|
||||
fn encode(&self,
|
||||
_dfg: &DataFlowGraph,
|
||||
inst: &InstructionData,
|
||||
ctrl_typevar: Type)
|
||||
_dfg: &ir::DataFlowGraph,
|
||||
inst: &ir::InstructionData,
|
||||
ctrl_typevar: ir::Type)
|
||||
-> Result<Encoding, Legalize> {
|
||||
lookup_enclist(ctrl_typevar,
|
||||
inst.opcode(),
|
||||
@@ -78,15 +79,19 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut Signature, current: bool) {
|
||||
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
||||
abi::legalize_signature(sig, &self.shared_flags, &self.isa_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: Type) -> RegClass {
|
||||
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &Function, inst: Inst, sink: &mut CodeSink) {
|
||||
fn allocatable_registers(&self, func: &ir::Function) -> regalloc::AllocatableSet {
|
||||
abi::allocatable_registers(func, &self.isa_flags)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user