diff --git a/lib/cretonne/src/isa/arm32/abi.rs b/lib/cretonne/src/isa/arm32/abi.rs new file mode 100644 index 0000000000..c4e0ffc2ee --- /dev/null +++ b/lib/cretonne/src/isa/arm32/abi.rs @@ -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), + } + } +} diff --git a/lib/cretonne/src/isa/arm32/mod.rs b/lib/cretonne/src/isa/arm32/mod.rs index b76ffa32cb..735fcd4b2c 100644 --- a/lib/cretonne/src/isa/arm32/mod.rs +++ b/lib/cretonne/src/isa/arm32/mod.rs @@ -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) } diff --git a/lib/cretonne/src/isa/arm64/abi.rs b/lib/cretonne/src/isa/arm64/abi.rs new file mode 100644 index 0000000000..8c2e9ed7d6 --- /dev/null +++ b/lib/cretonne/src/isa/arm64/abi.rs @@ -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 } +} diff --git a/lib/cretonne/src/isa/arm64/mod.rs b/lib/cretonne/src/isa/arm64/mod.rs index 2499028919..91a8a50f4e 100644 --- a/lib/cretonne/src/isa/arm64/mod.rs +++ b/lib/cretonne/src/isa/arm64/mod.rs @@ -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) } diff --git a/lib/cretonne/src/isa/intel/abi.rs b/lib/cretonne/src/isa/intel/abi.rs new file mode 100644 index 0000000000..437925cd40 --- /dev/null +++ b/lib/cretonne/src/isa/intel/abi.rs @@ -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 } +} diff --git a/lib/cretonne/src/isa/intel/mod.rs b/lib/cretonne/src/isa/intel/mod.rs index 60ce3a795d..768150eb50 100644 --- a/lib/cretonne/src/isa/intel/mod.rs +++ b/lib/cretonne/src/isa/intel/mod.rs @@ -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) } diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index e951ad31de..bd9e0caf9a 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -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. /// diff --git a/lib/cretonne/src/isa/riscv/abi.rs b/lib/cretonne/src/isa/riscv/abi.rs index 453a9c7be8..f13e6d2801 100644 --- a/lib/cretonne/src/isa/riscv/abi.rs +++ b/lib/cretonne/src/isa/riscv/abi.rs @@ -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 } +} diff --git a/lib/cretonne/src/isa/riscv/mod.rs b/lib/cretonne/src/isa/riscv/mod.rs index ac5057103c..60b795156a 100644 --- a/lib/cretonne/src/isa/riscv/mod.rs +++ b/lib/cretonne/src/isa/riscv/mod.rs @@ -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) }