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:
Jakob Stoklund Olesen
2017-04-26 10:11:50 -07:00
parent d078c546e5
commit e67f5e210f
9 changed files with 114 additions and 8 deletions

View 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),
}
}
}

View File

@@ -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)
}

View 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 }
}

View File

@@ -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)
}

View 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 }
}

View File

@@ -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)
}

View File

@@ -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.
///

View File

@@ -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 }
}

View File

@@ -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)
}