diff --git a/filetests/isa/riscv/abi-e.cton b/filetests/isa/riscv/abi-e.cton new file mode 100644 index 0000000000..f770a3558f --- /dev/null +++ b/filetests/isa/riscv/abi-e.cton @@ -0,0 +1,14 @@ +; Test the legalization of function signatures for RV32E. +test legalizer +isa riscv enable_e + +; regex: V=v\d+ + +function f() { + ; Spilling into the stack args after %x15 since %16 and up are not + ; available in RV32E. + sig0 = signature(i64, i64, i64, i64) -> i64 + ; check: sig0 = signature(i32 [%x10], i32 [%x11], i32 [%x12], i32 [%x13], i32 [%x14], i32 [%x15], i32 [0], i32 [4]) -> i32 [%x10], i32 [%x11] +ebb0: + return +} diff --git a/lib/cretonne/meta/isa/riscv/settings.py b/lib/cretonne/meta/isa/riscv/settings.py index e6fe230f89..c8b88db55e 100644 --- a/lib/cretonne/meta/isa/riscv/settings.py +++ b/lib/cretonne/meta/isa/riscv/settings.py @@ -18,6 +18,9 @@ enable_m = BoolSetting( "Enable the use of 'M' instructions if available", default=True) +enable_e = BoolSetting( + "Enable the 'RV32E' instruction set with only 16 registers") + use_m = And(supports_m, enable_m) use_a = And(supports_a, shared.enable_atomics) use_f = And(supports_f, shared.enable_float) diff --git a/lib/cretonne/src/isa/riscv/abi.rs b/lib/cretonne/src/isa/riscv/abi.rs index f13e6d2801..0df3806529 100644 --- a/lib/cretonne/src/isa/riscv/abi.rs +++ b/lib/cretonne/src/isa/riscv/abi.rs @@ -8,24 +8,27 @@ 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; +use super::registers::{GPR, FPR}; +use super::settings; struct Args { pointer_bits: u16, pointer_bytes: u32, pointer_type: Type, regs: u32, + reg_limit: u32, offset: u32, } impl Args { - fn new(bits: u16) -> Args { + fn new(bits: u16, enable_e: bool) -> Args { Args { pointer_bits: bits, pointer_bytes: bits as u32 / 8, pointer_type: Type::int(bits).unwrap(), regs: 0, + reg_limit: if enable_e { 6 } else { 8 }, offset: 0, } } @@ -62,7 +65,7 @@ impl ArgAssigner for Args { } } - if self.regs < 8 { + if self.regs < self.reg_limit { // Assign to a register. let reg = if ty.is_float() { FPR.unit(10 + self.regs as usize) @@ -81,13 +84,16 @@ impl ArgAssigner for Args { } /// Legalize `sig` for RISC-V. -pub fn legalize_signature(sig: &mut Signature, flags: &shared_settings::Flags, current: bool) { +pub fn legalize_signature(sig: &mut Signature, + flags: &shared_settings::Flags, + isa_flags: &settings::Flags, + current: bool) { let bits = if flags.is_64bit() { 64 } else { 32 }; - let mut args = Args::new(bits); + let mut args = Args::new(bits, isa_flags.enable_e()); legalize_args(&mut sig.argument_types, &mut args); - let mut rets = Args::new(bits); + let mut rets = Args::new(bits, isa_flags.enable_e()); legalize_args(&mut sig.return_types, &mut rets); if current { diff --git a/lib/cretonne/src/isa/riscv/mod.rs b/lib/cretonne/src/isa/riscv/mod.rs index 60b795156a..fe267ae870 100644 --- a/lib/cretonne/src/isa/riscv/mod.rs +++ b/lib/cretonne/src/isa/riscv/mod.rs @@ -79,8 +79,7 @@ impl TargetIsa for Isa { } fn legalize_signature(&self, sig: &mut Signature, current: bool) { - // We can pass in `self.isa_flags` too, if we need it. - abi::legalize_signature(sig, &self.shared_flags, current) + abi::legalize_signature(sig, &self.shared_flags, &self.isa_flags, current) } fn regclass_for_abi_type(&self, ty: Type) -> RegClass { diff --git a/lib/cretonne/src/isa/riscv/settings.rs b/lib/cretonne/src/isa/riscv/settings.rs index c070612d08..aa66d75fd9 100644 --- a/lib/cretonne/src/isa/riscv/settings.rs +++ b/lib/cretonne/src/isa/riscv/settings.rs @@ -24,7 +24,8 @@ mod tests { supports_a = false\n\ supports_f = false\n\ supports_d = false\n\ - enable_m = true\n"); + enable_m = true\n\ + enable_e = false\n"); // Predicates are not part of the Display output. assert_eq!(f.full_float(), false); }