Add a TargetIsa::regclass_for_abi_type() function.
The legalize_signature() function will return ArgumentLoc::Reg arguments that contain a register unit. However, the register also needs to be able to associate a register class with the argument values to fully track the used registers. When values are defined by instructions, the register class is part for the operand constraints for the instruction. For values defined on ABI boundaries like function arguments and return values from a call, the register class is provided by the new regclass_for_abi_type() function. Provide implementations of this function in abi modules of all the targets, even those that don't have a legalize_signature() implementation yet. Since we're adding abi modules to all targets, move the legalize_signature() stubs in there and make the function mandatory in TargetIsa. All targets will eventually need this function.
This commit is contained in:
27
lib/cretonne/src/isa/arm32/abi.rs
Normal file
27
lib/cretonne/src/isa/arm32/abi.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
//! ARM ABI implementation.
|
||||
|
||||
use ir;
|
||||
use isa::RegClass;
|
||||
use settings as shared_settings;
|
||||
use super::registers::{S, D, Q, GPR};
|
||||
|
||||
/// Legalize `sig`.
|
||||
pub fn legalize_signature(_sig: &mut ir::Signature,
|
||||
_flags: &shared_settings::Flags,
|
||||
_current: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Get register class for a type appearing in a legalized signature.
|
||||
pub fn regclass_for_abi_type(ty: ir::Type) -> RegClass {
|
||||
if ty.is_int() {
|
||||
GPR
|
||||
} else {
|
||||
match ty.bits() {
|
||||
32 => S,
|
||||
64 => D,
|
||||
128 => Q,
|
||||
_ => panic!("Unexpected {} ABI type for arm32", ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//! ARM 32-bit Instruction Set Architecture.
|
||||
|
||||
pub mod settings;
|
||||
mod abi;
|
||||
mod binemit;
|
||||
mod enc_tables;
|
||||
mod registers;
|
||||
@@ -9,7 +10,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -77,6 +78,14 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
||||
abi::legalize_signature(sig, &self.shared_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
18
lib/cretonne/src/isa/arm64/abi.rs
Normal file
18
lib/cretonne/src/isa/arm64/abi.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
//! ARM 64 ABI implementation.
|
||||
|
||||
use ir;
|
||||
use isa::RegClass;
|
||||
use settings as shared_settings;
|
||||
use super::registers::{GPR, FPR};
|
||||
|
||||
/// Legalize `sig`.
|
||||
pub fn legalize_signature(_sig: &mut ir::Signature,
|
||||
_flags: &shared_settings::Flags,
|
||||
_current: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Get register class for a type appearing in a legalized signature.
|
||||
pub fn regclass_for_abi_type(ty: ir::Type) -> RegClass {
|
||||
if ty.is_int() { GPR } else { FPR }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//! ARM 64-bit Instruction Set Architecture.
|
||||
|
||||
pub mod settings;
|
||||
mod abi;
|
||||
mod binemit;
|
||||
mod enc_tables;
|
||||
mod registers;
|
||||
@@ -9,7 +10,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -70,6 +71,14 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
||||
abi::legalize_signature(sig, &self.shared_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
18
lib/cretonne/src/isa/intel/abi.rs
Normal file
18
lib/cretonne/src/isa/intel/abi.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
//! Intel ABI implementation.
|
||||
|
||||
use ir;
|
||||
use isa::RegClass;
|
||||
use settings as shared_settings;
|
||||
use super::registers::{GPR, FPR};
|
||||
|
||||
/// Legalize `sig`.
|
||||
pub fn legalize_signature(_sig: &mut ir::Signature,
|
||||
_flags: &shared_settings::Flags,
|
||||
_current: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
/// Get register class for a type appearing in a legalized signature.
|
||||
pub fn regclass_for_abi_type(ty: ir::Type) -> RegClass {
|
||||
if ty.is_int() { GPR } else { FPR }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Intel Instruction Set Architectures.
|
||||
|
||||
pub mod settings;
|
||||
mod abi;
|
||||
mod binemit;
|
||||
mod enc_tables;
|
||||
mod registers;
|
||||
@@ -9,7 +10,7 @@ use binemit::CodeSink;
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, RegInfo, EncInfo, Encoding, Legalize};
|
||||
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Encoding, Legalize};
|
||||
use ir;
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -77,6 +78,14 @@ impl TargetIsa for Isa {
|
||||
})
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
||||
abi::legalize_signature(sig, &self.shared_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ pub trait TargetIsa {
|
||||
/// The legalizer will adapt argument and return values as necessary at all ABI boundaries.
|
||||
///
|
||||
/// When this function is called to legalize the signature of the function currently begin
|
||||
/// compiler, `_current` is true. The legalized signature can then also contain special purpose
|
||||
/// compiler, `current` is true. The legalized signature can then also contain special purpose
|
||||
/// arguments and return values such as:
|
||||
///
|
||||
/// - A `link` argument representing the link registers on RISC architectures that don't push
|
||||
@@ -183,9 +183,15 @@ pub trait TargetIsa {
|
||||
/// Arguments and return values for the caller's frame pointer and other callee-saved registers
|
||||
/// should not be added by this function. These arguments are not added until after register
|
||||
/// allocation.
|
||||
fn legalize_signature(&self, _sig: &mut Signature, _current: bool) {
|
||||
unimplemented!()
|
||||
}
|
||||
fn legalize_signature(&self, sig: &mut Signature, current: bool);
|
||||
|
||||
/// Get the register class that should be used to represent an ABI argument or return value of
|
||||
/// type `ty`. This should be the top-level register class that contains the argument
|
||||
/// registers.
|
||||
///
|
||||
/// This function can assume that it will only be asked to provide register classes for types
|
||||
/// that `legalize_signature()` produces in `ArgumentLoc::Reg` entries.
|
||||
fn regclass_for_abi_type(&self, ty: Type) -> RegClass;
|
||||
|
||||
/// Emit binary machine code for a single instruction into the `sink` trait object.
|
||||
///
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
use abi::{ArgAction, ValueConversion, ArgAssigner, legalize_args};
|
||||
use ir::{Signature, Type, ArgumentType, ArgumentLoc, ArgumentExtension, ArgumentPurpose};
|
||||
use isa::RegClass;
|
||||
use isa::riscv::registers::{GPR, FPR};
|
||||
use settings as shared_settings;
|
||||
|
||||
@@ -102,3 +103,8 @@ pub fn legalize_signature(sig: &mut Signature, flags: &shared_settings::Flags, c
|
||||
sig.return_types.push(link);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get register class for a type appearing in a legalized signature.
|
||||
pub fn regclass_for_abi_type(ty: Type) -> RegClass {
|
||||
if ty.is_float() { FPR } else { GPR }
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use super::super::settings as shared_settings;
|
||||
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, EncInfo, Encoding, Legalize};
|
||||
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Encoding, Legalize};
|
||||
use ir::{Function, Inst, InstructionData, DataFlowGraph, Signature, Type};
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -83,6 +83,10 @@ impl TargetIsa for Isa {
|
||||
abi::legalize_signature(sig, &self.shared_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: Type) -> RegClass {
|
||||
abi::regclass_for_abi_type(ty)
|
||||
}
|
||||
|
||||
fn emit_inst(&self, func: &Function, inst: Inst, sink: &mut CodeSink) {
|
||||
binemit::emit_inst(func, inst, sink)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user