From cd99eee86b850ce2595908aaba77ac07f7a9016f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 26 Apr 2017 10:11:50 -0700 Subject: [PATCH] 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. --- lib/cretonne/src/isa/arm32/abi.rs | 27 +++++++++++++++++++++++++++ lib/cretonne/src/isa/arm32/mod.rs | 11 ++++++++++- lib/cretonne/src/isa/arm64/abi.rs | 18 ++++++++++++++++++ lib/cretonne/src/isa/arm64/mod.rs | 11 ++++++++++- lib/cretonne/src/isa/intel/abi.rs | 18 ++++++++++++++++++ lib/cretonne/src/isa/intel/mod.rs | 11 ++++++++++- lib/cretonne/src/isa/mod.rs | 14 ++++++++++---- lib/cretonne/src/isa/riscv/abi.rs | 6 ++++++ lib/cretonne/src/isa/riscv/mod.rs | 6 +++++- 9 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 lib/cretonne/src/isa/arm32/abi.rs create mode 100644 lib/cretonne/src/isa/arm64/abi.rs create mode 100644 lib/cretonne/src/isa/intel/abi.rs 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) }