Use the target-lexicon crate.
This switches from a custom list of architectures to use the target-lexicon crate. - "set is_64bit=1; isa x86" is replaced with "target x86_64", and similar for other architectures, and the `is_64bit` flag is removed entirely. - The `is_compressed` flag is removed too; it's no longer being used to control REX prefixes on x86-64, ARM and Thumb are separate architectures in target-lexicon, and we can figure out how to select RISC-V compressed encodings when we're ready.
This commit is contained in:
@@ -11,12 +11,12 @@ use abi::{legalize_args, ArgAction, ArgAssigner, ValueConversion};
|
||||
use ir::{self, AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, Type};
|
||||
use isa::RegClass;
|
||||
use regalloc::RegisterSet;
|
||||
use settings as shared_settings;
|
||||
use std::i32;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
struct Args {
|
||||
pointer_bits: u16,
|
||||
pointer_bytes: u32,
|
||||
pointer_bits: u8,
|
||||
pointer_bytes: u8,
|
||||
pointer_type: Type,
|
||||
regs: u32,
|
||||
reg_limit: u32,
|
||||
@@ -24,11 +24,11 @@ struct Args {
|
||||
}
|
||||
|
||||
impl Args {
|
||||
fn new(bits: u16, enable_e: bool) -> Self {
|
||||
fn new(bits: u8, enable_e: bool) -> Self {
|
||||
Self {
|
||||
pointer_bits: bits,
|
||||
pointer_bytes: u32::from(bits) / 8,
|
||||
pointer_type: Type::int(bits).unwrap(),
|
||||
pointer_bytes: bits / 8,
|
||||
pointer_type: Type::int(u16::from(bits)).unwrap(),
|
||||
regs: 0,
|
||||
reg_limit: if enable_e { 6 } else { 8 },
|
||||
offset: 0,
|
||||
@@ -51,15 +51,15 @@ impl ArgAssigner for Args {
|
||||
}
|
||||
|
||||
// Large integers and booleans are broken down to fit in a register.
|
||||
if !ty.is_float() && ty.bits() > self.pointer_bits {
|
||||
if !ty.is_float() && ty.bits() > u16::from(self.pointer_bits) {
|
||||
// Align registers and stack to a multiple of two pointers.
|
||||
self.regs = align(self.regs, 2);
|
||||
self.offset = align(self.offset, 2 * self.pointer_bytes);
|
||||
self.offset = align(self.offset, 2 * u32::from(self.pointer_bytes));
|
||||
return ValueConversion::IntSplit.into();
|
||||
}
|
||||
|
||||
// Small integers are extended to the size of a pointer register.
|
||||
if ty.is_int() && ty.bits() < self.pointer_bits {
|
||||
if ty.is_int() && ty.bits() < u16::from(self.pointer_bits) {
|
||||
match arg.extension {
|
||||
ArgumentExtension::None => {}
|
||||
ArgumentExtension::Uext => return ValueConversion::Uext(self.pointer_type).into(),
|
||||
@@ -79,7 +79,7 @@ impl ArgAssigner for Args {
|
||||
} else {
|
||||
// Assign a stack location.
|
||||
let loc = ArgumentLoc::Stack(self.offset as i32);
|
||||
self.offset += self.pointer_bytes;
|
||||
self.offset += u32::from(self.pointer_bytes);
|
||||
debug_assert!(self.offset <= i32::MAX as u32);
|
||||
loc.into()
|
||||
}
|
||||
@@ -89,11 +89,11 @@ impl ArgAssigner for Args {
|
||||
/// Legalize `sig` for RISC-V.
|
||||
pub fn legalize_signature(
|
||||
sig: &mut ir::Signature,
|
||||
flags: &shared_settings::Flags,
|
||||
triple: &Triple,
|
||||
isa_flags: &settings::Flags,
|
||||
current: bool,
|
||||
) {
|
||||
let bits = if flags.is_64bit() { 64 } else { 32 };
|
||||
let bits = triple.pointer_width().unwrap().bits();
|
||||
|
||||
let mut args = Args::new(bits, isa_flags.enable_e());
|
||||
legalize_args(&mut sig.params, &mut args);
|
||||
@@ -102,7 +102,7 @@ pub fn legalize_signature(
|
||||
legalize_args(&mut sig.returns, &mut rets);
|
||||
|
||||
if current {
|
||||
let ptr = Type::int(bits).unwrap();
|
||||
let ptr = Type::int(u16::from(bits)).unwrap();
|
||||
|
||||
// Add the link register as an argument and return value.
|
||||
//
|
||||
|
||||
@@ -15,32 +15,37 @@ use isa::{EncInfo, RegClass, RegInfo, TargetIsa};
|
||||
use regalloc;
|
||||
use std::boxed::Box;
|
||||
use std::fmt;
|
||||
use target_lexicon::{PointerWidth, Triple};
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Isa {
|
||||
triple: Triple,
|
||||
shared_flags: shared_settings::Flags,
|
||||
isa_flags: settings::Flags,
|
||||
cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
|
||||
}
|
||||
|
||||
/// Get an ISA builder for creating RISC-V targets.
|
||||
pub fn isa_builder() -> IsaBuilder {
|
||||
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
||||
IsaBuilder {
|
||||
triple,
|
||||
setup: settings::builder(),
|
||||
constructor: isa_constructor,
|
||||
}
|
||||
}
|
||||
|
||||
fn isa_constructor(
|
||||
triple: Triple,
|
||||
shared_flags: shared_settings::Flags,
|
||||
builder: shared_settings::Builder,
|
||||
) -> Box<TargetIsa> {
|
||||
let level1 = if shared_flags.is_64bit() {
|
||||
&enc_tables::LEVEL1_RV64[..]
|
||||
} else {
|
||||
&enc_tables::LEVEL1_RV32[..]
|
||||
let level1 = match triple.pointer_width().unwrap() {
|
||||
PointerWidth::U16 => panic!("16-bit RISC-V unrecognized"),
|
||||
PointerWidth::U32 => &enc_tables::LEVEL1_RV32[..],
|
||||
PointerWidth::U64 => &enc_tables::LEVEL1_RV64[..],
|
||||
};
|
||||
Box::new(Isa {
|
||||
triple,
|
||||
isa_flags: settings::Flags::new(&shared_flags, builder),
|
||||
shared_flags,
|
||||
cpumode: level1,
|
||||
@@ -52,6 +57,10 @@ impl TargetIsa for Isa {
|
||||
"riscv"
|
||||
}
|
||||
|
||||
fn triple(&self) -> &Triple {
|
||||
&self.triple
|
||||
}
|
||||
|
||||
fn flags(&self) -> &shared_settings::Flags {
|
||||
&self.shared_flags
|
||||
}
|
||||
@@ -85,7 +94,7 @@ impl TargetIsa for Isa {
|
||||
}
|
||||
|
||||
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
||||
abi::legalize_signature(sig, &self.shared_flags, &self.isa_flags, current)
|
||||
abi::legalize_signature(sig, &self.triple, &self.isa_flags, current)
|
||||
}
|
||||
|
||||
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
||||
@@ -117,7 +126,9 @@ mod tests {
|
||||
use ir::{Function, InstructionData, Opcode};
|
||||
use isa;
|
||||
use settings::{self, Configurable};
|
||||
use std::str::FromStr;
|
||||
use std::string::{String, ToString};
|
||||
use target_lexicon;
|
||||
|
||||
fn encstr(isa: &isa::TargetIsa, enc: Result<isa::Encoding, isa::Legalize>) -> String {
|
||||
match enc {
|
||||
@@ -128,10 +139,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_64bitenc() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.enable("is_64bit").unwrap();
|
||||
let shared_builder = settings::builder();
|
||||
let shared_flags = settings::Flags::new(shared_builder);
|
||||
let isa = isa::lookup("riscv").unwrap().finish(shared_flags);
|
||||
let isa = isa::lookup(triple!("riscv64"))
|
||||
.unwrap()
|
||||
.finish(shared_flags);
|
||||
|
||||
let mut func = Function::new();
|
||||
let ebb = func.dfg.make_ebb();
|
||||
@@ -178,10 +190,11 @@ mod tests {
|
||||
// Same as above, but for RV32.
|
||||
#[test]
|
||||
fn test_32bitenc() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.set("is_64bit", "false").unwrap();
|
||||
let shared_builder = settings::builder();
|
||||
let shared_flags = settings::Flags::new(shared_builder);
|
||||
let isa = isa::lookup("riscv").unwrap().finish(shared_flags);
|
||||
let isa = isa::lookup(triple!("riscv32"))
|
||||
.unwrap()
|
||||
.finish(shared_flags);
|
||||
|
||||
let mut func = Function::new();
|
||||
let ebb = func.dfg.make_ebb();
|
||||
@@ -232,13 +245,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_rv32m() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.set("is_64bit", "false").unwrap();
|
||||
let shared_builder = settings::builder();
|
||||
let shared_flags = settings::Flags::new(shared_builder);
|
||||
|
||||
// Set the supports_m stting which in turn enables the use_m predicate that unlocks
|
||||
// encodings for imul.
|
||||
let mut isa_builder = isa::lookup("riscv").unwrap();
|
||||
let mut isa_builder = isa::lookup(triple!("riscv32")).unwrap();
|
||||
isa_builder.enable("supports_m").unwrap();
|
||||
|
||||
let isa = isa_builder.finish(shared_flags);
|
||||
|
||||
Reference in New Issue
Block a user