diff --git a/cranelift/codegen/Cargo.toml b/cranelift/codegen/Cargo.toml index 4397568e5a..984d696373 100644 --- a/cranelift/codegen/Cargo.toml +++ b/cranelift/codegen/Cargo.toml @@ -63,7 +63,6 @@ unwind = ["gimli"] # If no ISA targets are explicitly enabled, the ISA target for the host machine is enabled. x86 = [] arm64 = [] -riscv = [] s390x = [] arm32 = [] # Work-in-progress codegen backend for ARM. @@ -75,7 +74,6 @@ experimental_x64 = [] all-arch = [ "x86", "arm64", - "riscv", "s390x" ] diff --git a/cranelift/codegen/meta/src/isa/mod.rs b/cranelift/codegen/meta/src/isa/mod.rs index 34032842c2..9465e63b26 100644 --- a/cranelift/codegen/meta/src/isa/mod.rs +++ b/cranelift/codegen/meta/src/isa/mod.rs @@ -5,14 +5,12 @@ use std::fmt; mod arm32; mod arm64; -mod riscv; mod s390x; pub(crate) mod x86; /// Represents known ISA target. #[derive(PartialEq, Copy, Clone)] pub enum Isa { - Riscv, X86, Arm32, Arm64, @@ -31,7 +29,6 @@ impl Isa { /// Creates isa target from arch. pub fn from_arch(arch: &str) -> Option { match arch { - "riscv" => Some(Isa::Riscv), "aarch64" => Some(Isa::Arm64), "s390x" => Some(Isa::S390x), x if ["x86_64", "i386", "i586", "i686"].contains(&x) => Some(Isa::X86), @@ -42,7 +39,7 @@ impl Isa { /// Returns all supported isa targets. pub fn all() -> &'static [Isa] { - &[Isa::Riscv, Isa::X86, Isa::Arm32, Isa::Arm64, Isa::S390x] + &[Isa::X86, Isa::Arm32, Isa::Arm64, Isa::S390x] } } @@ -50,7 +47,6 @@ impl fmt::Display for Isa { // These names should be kept in sync with the crate features. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Isa::Riscv => write!(f, "riscv"), Isa::X86 => write!(f, "x86"), Isa::Arm32 => write!(f, "arm32"), Isa::Arm64 => write!(f, "arm64"), @@ -62,7 +58,6 @@ impl fmt::Display for Isa { pub(crate) fn define(isas: &[Isa], shared_defs: &mut SharedDefinitions) -> Vec { isas.iter() .map(|isa| match isa { - Isa::Riscv => riscv::define(shared_defs), Isa::X86 => x86::define(shared_defs), Isa::Arm32 => arm32::define(shared_defs), Isa::Arm64 => arm64::define(shared_defs), diff --git a/cranelift/codegen/meta/src/isa/riscv/encodings.rs b/cranelift/codegen/meta/src/isa/riscv/encodings.rs deleted file mode 100644 index c255ddb483..0000000000 --- a/cranelift/codegen/meta/src/isa/riscv/encodings.rs +++ /dev/null @@ -1,431 +0,0 @@ -use crate::cdsl::ast::{Apply, Expr, Literal, VarPool}; -use crate::cdsl::encodings::{Encoding, EncodingBuilder}; -use crate::cdsl::instructions::{ - Bindable, BoundInstruction, InstSpec, InstructionPredicateNode, InstructionPredicateRegistry, -}; -use crate::cdsl::recipes::{EncodingRecipeNumber, Recipes}; -use crate::cdsl::settings::SettingGroup; - -use crate::shared::types::Bool::B1; -use crate::shared::types::Float::{F32, F64}; -use crate::shared::types::Int::{I16, I32, I64, I8}; -use crate::shared::types::Reference::{R32, R64}; -use crate::shared::Definitions as SharedDefinitions; - -use super::recipes::RecipeGroup; - -pub(crate) struct PerCpuModeEncodings<'defs> { - pub inst_pred_reg: InstructionPredicateRegistry, - pub enc32: Vec, - pub enc64: Vec, - recipes: &'defs Recipes, -} - -impl<'defs> PerCpuModeEncodings<'defs> { - fn new(recipes: &'defs Recipes) -> Self { - Self { - inst_pred_reg: InstructionPredicateRegistry::new(), - enc32: Vec::new(), - enc64: Vec::new(), - recipes, - } - } - fn enc( - &self, - inst: impl Into, - recipe: EncodingRecipeNumber, - bits: u16, - ) -> EncodingBuilder { - EncodingBuilder::new(inst.into(), recipe, bits) - } - fn add32(&mut self, encoding: EncodingBuilder) { - self.enc32 - .push(encoding.build(self.recipes, &mut self.inst_pred_reg)); - } - fn add64(&mut self, encoding: EncodingBuilder) { - self.enc64 - .push(encoding.build(self.recipes, &mut self.inst_pred_reg)); - } -} - -// The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit instructions have 11 as -// the two low bits, with bits 6:2 determining the base opcode. -// -// Encbits for the 32-bit recipes are opcode[6:2] | (funct3 << 5) | ... -// The functions below encode the encbits. - -fn load_bits(funct3: u16) -> u16 { - assert!(funct3 <= 0b111); - funct3 << 5 -} - -fn store_bits(funct3: u16) -> u16 { - assert!(funct3 <= 0b111); - 0b01000 | (funct3 << 5) -} - -fn branch_bits(funct3: u16) -> u16 { - assert!(funct3 <= 0b111); - 0b11000 | (funct3 << 5) -} - -fn jalr_bits() -> u16 { - // This was previously accepting an argument funct3 of 3 bits and used the following formula: - //0b11001 | (funct3 << 5) - 0b11001 -} - -fn jal_bits() -> u16 { - 0b11011 -} - -fn opimm_bits(funct3: u16, funct7: u16) -> u16 { - assert!(funct3 <= 0b111); - 0b00100 | (funct3 << 5) | (funct7 << 8) -} - -fn opimm32_bits(funct3: u16, funct7: u16) -> u16 { - assert!(funct3 <= 0b111); - 0b00110 | (funct3 << 5) | (funct7 << 8) -} - -fn op_bits(funct3: u16, funct7: u16) -> u16 { - assert!(funct3 <= 0b111); - assert!(funct7 <= 0b111_1111); - 0b01100 | (funct3 << 5) | (funct7 << 8) -} - -fn op32_bits(funct3: u16, funct7: u16) -> u16 { - assert!(funct3 <= 0b111); - assert!(funct7 <= 0b111_1111); - 0b01110 | (funct3 << 5) | (funct7 << 8) -} - -fn lui_bits() -> u16 { - 0b01101 -} - -pub(crate) fn define<'defs>( - shared_defs: &'defs SharedDefinitions, - isa_settings: &SettingGroup, - recipes: &'defs RecipeGroup, -) -> PerCpuModeEncodings<'defs> { - // Instructions shorthands. - let shared = &shared_defs.instructions; - - let band = shared.by_name("band"); - let band_imm = shared.by_name("band_imm"); - let bor = shared.by_name("bor"); - let bor_imm = shared.by_name("bor_imm"); - let br_icmp = shared.by_name("br_icmp"); - let brz = shared.by_name("brz"); - let brnz = shared.by_name("brnz"); - let bxor = shared.by_name("bxor"); - let bxor_imm = shared.by_name("bxor_imm"); - let call = shared.by_name("call"); - let call_indirect = shared.by_name("call_indirect"); - let copy = shared.by_name("copy"); - let copy_nop = shared.by_name("copy_nop"); - let copy_to_ssa = shared.by_name("copy_to_ssa"); - let fill = shared.by_name("fill"); - let fill_nop = shared.by_name("fill_nop"); - let iadd = shared.by_name("iadd"); - let iadd_imm = shared.by_name("iadd_imm"); - let iconst = shared.by_name("iconst"); - let icmp = shared.by_name("icmp"); - let icmp_imm = shared.by_name("icmp_imm"); - let imul = shared.by_name("imul"); - let ishl = shared.by_name("ishl"); - let ishl_imm = shared.by_name("ishl_imm"); - let isub = shared.by_name("isub"); - let jump = shared.by_name("jump"); - let regmove = shared.by_name("regmove"); - let spill = shared.by_name("spill"); - let sshr = shared.by_name("sshr"); - let sshr_imm = shared.by_name("sshr_imm"); - let ushr = shared.by_name("ushr"); - let ushr_imm = shared.by_name("ushr_imm"); - let return_ = shared.by_name("return"); - - // Recipes shorthands, prefixed with r_. - let r_copytossa = recipes.by_name("copytossa"); - let r_fillnull = recipes.by_name("fillnull"); - let r_icall = recipes.by_name("Icall"); - let r_icopy = recipes.by_name("Icopy"); - let r_ii = recipes.by_name("Ii"); - let r_iicmp = recipes.by_name("Iicmp"); - let r_iret = recipes.by_name("Iret"); - let r_irmov = recipes.by_name("Irmov"); - let r_iz = recipes.by_name("Iz"); - let r_gp_sp = recipes.by_name("GPsp"); - let r_gp_fi = recipes.by_name("GPfi"); - let r_r = recipes.by_name("R"); - let r_ricmp = recipes.by_name("Ricmp"); - let r_rshamt = recipes.by_name("Rshamt"); - let r_sb = recipes.by_name("SB"); - let r_sb_zero = recipes.by_name("SBzero"); - let r_stacknull = recipes.by_name("stacknull"); - let r_u = recipes.by_name("U"); - let r_uj = recipes.by_name("UJ"); - let r_uj_call = recipes.by_name("UJcall"); - - // Predicates shorthands. - let use_m = isa_settings.predicate_by_name("use_m"); - - // Definitions. - let mut e = PerCpuModeEncodings::new(&recipes.recipes); - - // Basic arithmetic binary instructions are encoded in an R-type instruction. - for &(inst, inst_imm, f3, f7) in &[ - (iadd, Some(iadd_imm), 0b000, 0b000_0000), - (isub, None, 0b000, 0b010_0000), - (bxor, Some(bxor_imm), 0b100, 0b000_0000), - (bor, Some(bor_imm), 0b110, 0b000_0000), - (band, Some(band_imm), 0b111, 0b000_0000), - ] { - e.add32(e.enc(inst.bind(I32), r_r, op_bits(f3, f7))); - e.add64(e.enc(inst.bind(I64), r_r, op_bits(f3, f7))); - - // Immediate versions for add/xor/or/and. - if let Some(inst_imm) = inst_imm { - e.add32(e.enc(inst_imm.bind(I32), r_ii, opimm_bits(f3, 0))); - e.add64(e.enc(inst_imm.bind(I64), r_ii, opimm_bits(f3, 0))); - } - } - - // 32-bit ops in RV64. - e.add64(e.enc(iadd.bind(I32), r_r, op32_bits(0b000, 0b000_0000))); - e.add64(e.enc(isub.bind(I32), r_r, op32_bits(0b000, 0b010_0000))); - // There are no andiw/oriw/xoriw variations. - e.add64(e.enc(iadd_imm.bind(I32), r_ii, opimm32_bits(0b000, 0))); - - // Use iadd_imm with %x0 to materialize constants. - e.add32(e.enc(iconst.bind(I32), r_iz, opimm_bits(0b0, 0))); - e.add64(e.enc(iconst.bind(I32), r_iz, opimm_bits(0b0, 0))); - e.add64(e.enc(iconst.bind(I64), r_iz, opimm_bits(0b0, 0))); - - // Dynamic shifts have the same masking semantics as the clif base instructions. - for &(inst, inst_imm, f3, f7) in &[ - (ishl, ishl_imm, 0b1, 0b0), - (ushr, ushr_imm, 0b101, 0b0), - (sshr, sshr_imm, 0b101, 0b10_0000), - ] { - e.add32(e.enc(inst.bind(I32).bind(I32), r_r, op_bits(f3, f7))); - e.add64(e.enc(inst.bind(I64).bind(I64), r_r, op_bits(f3, f7))); - e.add64(e.enc(inst.bind(I32).bind(I32), r_r, op32_bits(f3, f7))); - // Allow i32 shift amounts in 64-bit shifts. - e.add64(e.enc(inst.bind(I64).bind(I32), r_r, op_bits(f3, f7))); - e.add64(e.enc(inst.bind(I32).bind(I64), r_r, op32_bits(f3, f7))); - - // Immediate shifts. - e.add32(e.enc(inst_imm.bind(I32), r_rshamt, opimm_bits(f3, f7))); - e.add64(e.enc(inst_imm.bind(I64), r_rshamt, opimm_bits(f3, f7))); - e.add64(e.enc(inst_imm.bind(I32), r_rshamt, opimm32_bits(f3, f7))); - } - - // Signed and unsigned integer 'less than'. There are no 'w' variants for comparing 32-bit - // numbers in RV64. - { - let mut var_pool = VarPool::new(); - - // Helper that creates an instruction predicate for an instruction in the icmp family. - let mut icmp_instp = |bound_inst: &BoundInstruction, - intcc_field: &'static str| - -> InstructionPredicateNode { - let x = var_pool.create("x"); - let y = var_pool.create("y"); - let cc = Literal::enumerator_for(&shared_defs.imm.intcc, intcc_field); - Apply::new( - bound_inst.clone().into(), - vec![Expr::Literal(cc), Expr::Var(x), Expr::Var(y)], - ) - .inst_predicate(&var_pool) - .unwrap() - }; - - let icmp_i32 = icmp.bind(I32); - let icmp_i64 = icmp.bind(I64); - e.add32( - e.enc(icmp_i32.clone(), r_ricmp, op_bits(0b010, 0b000_0000)) - .inst_predicate(icmp_instp(&icmp_i32, "slt")), - ); - e.add64( - e.enc(icmp_i64.clone(), r_ricmp, op_bits(0b010, 0b000_0000)) - .inst_predicate(icmp_instp(&icmp_i64, "slt")), - ); - - e.add32( - e.enc(icmp_i32.clone(), r_ricmp, op_bits(0b011, 0b000_0000)) - .inst_predicate(icmp_instp(&icmp_i32, "ult")), - ); - e.add64( - e.enc(icmp_i64.clone(), r_ricmp, op_bits(0b011, 0b000_0000)) - .inst_predicate(icmp_instp(&icmp_i64, "ult")), - ); - - // Immediate variants. - let icmp_i32 = icmp_imm.bind(I32); - let icmp_i64 = icmp_imm.bind(I64); - e.add32( - e.enc(icmp_i32.clone(), r_iicmp, opimm_bits(0b010, 0)) - .inst_predicate(icmp_instp(&icmp_i32, "slt")), - ); - e.add64( - e.enc(icmp_i64.clone(), r_iicmp, opimm_bits(0b010, 0)) - .inst_predicate(icmp_instp(&icmp_i64, "slt")), - ); - - e.add32( - e.enc(icmp_i32.clone(), r_iicmp, opimm_bits(0b011, 0)) - .inst_predicate(icmp_instp(&icmp_i32, "ult")), - ); - e.add64( - e.enc(icmp_i64.clone(), r_iicmp, opimm_bits(0b011, 0)) - .inst_predicate(icmp_instp(&icmp_i64, "ult")), - ); - } - - // Integer constants with the low 12 bits clear are materialized by lui. - e.add32(e.enc(iconst.bind(I32), r_u, lui_bits())); - e.add64(e.enc(iconst.bind(I32), r_u, lui_bits())); - e.add64(e.enc(iconst.bind(I64), r_u, lui_bits())); - - // "M" Standard Extension for Integer Multiplication and Division. - // Gated by the `use_m` flag. - e.add32( - e.enc(imul.bind(I32), r_r, op_bits(0b000, 0b0000_0001)) - .isa_predicate(use_m), - ); - e.add64( - e.enc(imul.bind(I64), r_r, op_bits(0b000, 0b0000_0001)) - .isa_predicate(use_m), - ); - e.add64( - e.enc(imul.bind(I32), r_r, op32_bits(0b000, 0b0000_0001)) - .isa_predicate(use_m), - ); - - // Control flow. - - // Unconditional branches. - e.add32(e.enc(jump, r_uj, jal_bits())); - e.add64(e.enc(jump, r_uj, jal_bits())); - e.add32(e.enc(call, r_uj_call, jal_bits())); - e.add64(e.enc(call, r_uj_call, jal_bits())); - - // Conditional branches. - { - let mut var_pool = VarPool::new(); - - // Helper that creates an instruction predicate for an instruction in the icmp family. - let mut br_icmp_instp = |bound_inst: &BoundInstruction, - intcc_field: &'static str| - -> InstructionPredicateNode { - let x = var_pool.create("x"); - let y = var_pool.create("y"); - let dest = var_pool.create("dest"); - let args = var_pool.create("args"); - let cc = Literal::enumerator_for(&shared_defs.imm.intcc, intcc_field); - Apply::new( - bound_inst.clone().into(), - vec![ - Expr::Literal(cc), - Expr::Var(x), - Expr::Var(y), - Expr::Var(dest), - Expr::Var(args), - ], - ) - .inst_predicate(&var_pool) - .unwrap() - }; - - let br_icmp_i32 = br_icmp.bind(I32); - let br_icmp_i64 = br_icmp.bind(I64); - for &(cond, f3) in &[ - ("eq", 0b000), - ("ne", 0b001), - ("slt", 0b100), - ("sge", 0b101), - ("ult", 0b110), - ("uge", 0b111), - ] { - e.add32( - e.enc(br_icmp_i32.clone(), r_sb, branch_bits(f3)) - .inst_predicate(br_icmp_instp(&br_icmp_i32, cond)), - ); - e.add64( - e.enc(br_icmp_i64.clone(), r_sb, branch_bits(f3)) - .inst_predicate(br_icmp_instp(&br_icmp_i64, cond)), - ); - } - } - - for &(inst, f3) in &[(brz, 0b000), (brnz, 0b001)] { - e.add32(e.enc(inst.bind(I32), r_sb_zero, branch_bits(f3))); - e.add64(e.enc(inst.bind(I64), r_sb_zero, branch_bits(f3))); - e.add32(e.enc(inst.bind(B1), r_sb_zero, branch_bits(f3))); - e.add64(e.enc(inst.bind(B1), r_sb_zero, branch_bits(f3))); - } - - // Returns are a special case of jalr_bits using %x1 to hold the return address. - // The return address is provided by a special-purpose `link` return value that - // is added by legalize_signature(). - e.add32(e.enc(return_, r_iret, jalr_bits())); - e.add64(e.enc(return_, r_iret, jalr_bits())); - e.add32(e.enc(call_indirect.bind(I32), r_icall, jalr_bits())); - e.add64(e.enc(call_indirect.bind(I64), r_icall, jalr_bits())); - - // Spill and fill. - e.add32(e.enc(spill.bind(I32), r_gp_sp, store_bits(0b010))); - e.add64(e.enc(spill.bind(I32), r_gp_sp, store_bits(0b010))); - e.add64(e.enc(spill.bind(I64), r_gp_sp, store_bits(0b011))); - e.add32(e.enc(fill.bind(I32), r_gp_fi, load_bits(0b010))); - e.add64(e.enc(fill.bind(I32), r_gp_fi, load_bits(0b010))); - e.add64(e.enc(fill.bind(I64), r_gp_fi, load_bits(0b011))); - - // No-op fills, created by late-stage redundant-fill removal. - for &ty in &[I64, I32] { - e.add64(e.enc(fill_nop.bind(ty), r_fillnull, 0)); - e.add32(e.enc(fill_nop.bind(ty), r_fillnull, 0)); - } - e.add64(e.enc(fill_nop.bind(B1), r_fillnull, 0)); - e.add32(e.enc(fill_nop.bind(B1), r_fillnull, 0)); - - // Register copies. - e.add32(e.enc(copy.bind(I32), r_icopy, opimm_bits(0b000, 0))); - e.add64(e.enc(copy.bind(I64), r_icopy, opimm_bits(0b000, 0))); - e.add64(e.enc(copy.bind(I32), r_icopy, opimm32_bits(0b000, 0))); - - e.add32(e.enc(regmove.bind(I32), r_irmov, opimm_bits(0b000, 0))); - e.add64(e.enc(regmove.bind(I64), r_irmov, opimm_bits(0b000, 0))); - e.add64(e.enc(regmove.bind(I32), r_irmov, opimm32_bits(0b000, 0))); - - e.add32(e.enc(copy.bind(B1), r_icopy, opimm_bits(0b000, 0))); - e.add64(e.enc(copy.bind(B1), r_icopy, opimm_bits(0b000, 0))); - e.add32(e.enc(regmove.bind(B1), r_irmov, opimm_bits(0b000, 0))); - e.add64(e.enc(regmove.bind(B1), r_irmov, opimm_bits(0b000, 0))); - - // Stack-slot-to-the-same-stack-slot copy, which is guaranteed to turn - // into a no-op. - // The same encoding is generated for both the 64- and 32-bit architectures. - for &ty in &[I64, I32, I16, I8] { - e.add32(e.enc(copy_nop.bind(ty), r_stacknull, 0)); - e.add64(e.enc(copy_nop.bind(ty), r_stacknull, 0)); - } - for &ty in &[F64, F32] { - e.add32(e.enc(copy_nop.bind(ty), r_stacknull, 0)); - e.add64(e.enc(copy_nop.bind(ty), r_stacknull, 0)); - } - - // Copy-to-SSA - e.add32(e.enc(copy_to_ssa.bind(I32), r_copytossa, opimm_bits(0b000, 0))); - e.add64(e.enc(copy_to_ssa.bind(I64), r_copytossa, opimm_bits(0b000, 0))); - e.add64(e.enc(copy_to_ssa.bind(I32), r_copytossa, opimm32_bits(0b000, 0))); - e.add32(e.enc(copy_to_ssa.bind(B1), r_copytossa, opimm_bits(0b000, 0))); - e.add64(e.enc(copy_to_ssa.bind(B1), r_copytossa, opimm_bits(0b000, 0))); - e.add32(e.enc(copy_to_ssa.bind(R32), r_copytossa, opimm_bits(0b000, 0))); - e.add64(e.enc(copy_to_ssa.bind(R64), r_copytossa, opimm_bits(0b000, 0))); - - e -} diff --git a/cranelift/codegen/meta/src/isa/riscv/mod.rs b/cranelift/codegen/meta/src/isa/riscv/mod.rs deleted file mode 100644 index 868ac17cfe..0000000000 --- a/cranelift/codegen/meta/src/isa/riscv/mod.rs +++ /dev/null @@ -1,136 +0,0 @@ -use crate::cdsl::cpu_modes::CpuMode; -use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder}; -use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder}; - -use crate::shared::types::Float::{F32, F64}; -use crate::shared::types::Int::{I32, I64}; -use crate::shared::Definitions as SharedDefinitions; - -mod encodings; -mod recipes; - -fn define_settings(shared: &SettingGroup) -> SettingGroup { - let mut setting = SettingGroupBuilder::new("riscv"); - - let supports_m = setting.add_bool( - "supports_m", - "CPU supports the 'M' extension (mul/div)", - "", - false, - ); - let supports_a = setting.add_bool( - "supports_a", - "CPU supports the 'A' extension (atomics)", - "", - false, - ); - let supports_f = setting.add_bool( - "supports_f", - "CPU supports the 'F' extension (float)", - "", - false, - ); - let supports_d = setting.add_bool( - "supports_d", - "CPU supports the 'D' extension (double)", - "", - false, - ); - - let enable_m = setting.add_bool( - "enable_m", - "Enable the use of 'M' instructions if available", - "", - true, - ); - - setting.add_bool( - "enable_e", - "Enable the 'RV32E' instruction set with only 16 registers", - "", - false, - ); - - let shared_enable_atomics = shared.get_bool("enable_atomics"); - let shared_enable_float = shared.get_bool("enable_float"); - let shared_enable_simd = shared.get_bool("enable_simd"); - - setting.add_predicate("use_m", predicate!(supports_m && enable_m)); - setting.add_predicate("use_a", predicate!(supports_a && shared_enable_atomics)); - setting.add_predicate("use_f", predicate!(supports_f && shared_enable_float)); - setting.add_predicate("use_d", predicate!(supports_d && shared_enable_float)); - setting.add_predicate( - "full_float", - predicate!(shared_enable_simd && supports_f && supports_d), - ); - - setting.build() -} - -fn define_registers() -> IsaRegs { - let mut regs = IsaRegsBuilder::new(); - - let builder = RegBankBuilder::new("IntRegs", "x") - .units(32) - .track_pressure(true); - let int_regs = regs.add_bank(builder); - - let builder = RegBankBuilder::new("FloatRegs", "f") - .units(32) - .track_pressure(true); - let float_regs = regs.add_bank(builder); - - let builder = RegClassBuilder::new_toplevel("GPR", int_regs); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("FPR", float_regs); - regs.add_class(builder); - - regs.build() -} - -pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa { - let settings = define_settings(&shared_defs.settings); - let regs = define_registers(); - - // CPU modes for 32-bit and 64-bit operation. - let mut rv_32 = CpuMode::new("RV32"); - let mut rv_64 = CpuMode::new("RV64"); - - let expand = shared_defs.transform_groups.by_name("expand"); - let narrow_no_flags = shared_defs.transform_groups.by_name("narrow_no_flags"); - - rv_32.legalize_monomorphic(expand); - rv_32.legalize_default(narrow_no_flags); - rv_32.legalize_type(I32, expand); - rv_32.legalize_type(F32, expand); - rv_32.legalize_type(F64, expand); - - rv_64.legalize_monomorphic(expand); - rv_64.legalize_default(narrow_no_flags); - rv_64.legalize_type(I32, expand); - rv_64.legalize_type(I64, expand); - rv_64.legalize_type(F32, expand); - rv_64.legalize_type(F64, expand); - - let recipes = recipes::define(shared_defs, ®s); - - let encodings = encodings::define(shared_defs, &settings, &recipes); - rv_32.set_encodings(encodings.enc32); - rv_64.set_encodings(encodings.enc64); - let encodings_predicates = encodings.inst_pred_reg.extract(); - - let recipes = recipes.collect(); - - let cpu_modes = vec![rv_32, rv_64]; - - TargetIsa::new( - "riscv", - settings, - regs, - recipes, - cpu_modes, - encodings_predicates, - ) -} diff --git a/cranelift/codegen/meta/src/isa/riscv/recipes.rs b/cranelift/codegen/meta/src/isa/riscv/recipes.rs deleted file mode 100644 index dc879dcecb..0000000000 --- a/cranelift/codegen/meta/src/isa/riscv/recipes.rs +++ /dev/null @@ -1,280 +0,0 @@ -use std::collections::HashMap; - -use crate::cdsl::instructions::InstructionPredicate; -use crate::cdsl::recipes::{EncodingRecipeBuilder, EncodingRecipeNumber, Recipes, Stack}; -use crate::cdsl::regs::IsaRegs; -use crate::shared::Definitions as SharedDefinitions; - -/// An helper to create recipes and use them when defining the RISCV encodings. -pub(crate) struct RecipeGroup { - /// The actualy list of recipes explicitly created in this file. - pub recipes: Recipes, - - /// Provides fast lookup from a name to an encoding recipe. - name_to_recipe: HashMap, -} - -impl RecipeGroup { - fn new() -> Self { - Self { - recipes: Recipes::new(), - name_to_recipe: HashMap::new(), - } - } - - fn push(&mut self, builder: EncodingRecipeBuilder) { - assert!( - self.name_to_recipe.get(&builder.name).is_none(), - "riscv recipe '{}' created twice", - builder.name - ); - let name = builder.name.clone(); - let number = self.recipes.push(builder.build()); - self.name_to_recipe.insert(name, number); - } - - pub fn by_name(&self, name: &str) -> EncodingRecipeNumber { - *self - .name_to_recipe - .get(name) - .unwrap_or_else(|| panic!("unknown riscv recipe name {}", name)) - } - - pub fn collect(self) -> Recipes { - self.recipes - } -} - -pub(crate) fn define(shared_defs: &SharedDefinitions, regs: &IsaRegs) -> RecipeGroup { - let formats = &shared_defs.formats; - - // Register classes shorthands. - let gpr = regs.class_by_name("GPR"); - - // Definitions. - let mut recipes = RecipeGroup::new(); - - // R-type 32-bit instructions: These are mostly binary arithmetic instructions. - // The encbits are `opcode[6:2] | (funct3 << 5) | (funct7 << 8) - recipes.push( - EncodingRecipeBuilder::new("R", &formats.binary, 4) - .operands_in(vec![gpr, gpr]) - .operands_out(vec![gpr]) - .emit("put_r(bits, in_reg0, in_reg1, out_reg0, sink);"), - ); - - // R-type with an immediate shift amount instead of rs2. - recipes.push( - EncodingRecipeBuilder::new("Rshamt", &formats.binary_imm64, 4) - .operands_in(vec![gpr]) - .operands_out(vec![gpr]) - .emit("put_rshamt(bits, in_reg0, imm.into(), out_reg0, sink);"), - ); - - // R-type encoding of an integer comparison. - recipes.push( - EncodingRecipeBuilder::new("Ricmp", &formats.int_compare, 4) - .operands_in(vec![gpr, gpr]) - .operands_out(vec![gpr]) - .emit("put_r(bits, in_reg0, in_reg1, out_reg0, sink);"), - ); - - recipes.push( - EncodingRecipeBuilder::new("Ii", &formats.binary_imm64, 4) - .operands_in(vec![gpr]) - .operands_out(vec![gpr]) - .inst_predicate(InstructionPredicate::new_is_signed_int( - &*formats.binary_imm64, - "imm", - 12, - 0, - )) - .emit("put_i(bits, in_reg0, imm.into(), out_reg0, sink);"), - ); - - // I-type instruction with a hardcoded %x0 rs1. - recipes.push( - EncodingRecipeBuilder::new("Iz", &formats.unary_imm, 4) - .operands_out(vec![gpr]) - .inst_predicate(InstructionPredicate::new_is_signed_int( - &formats.unary_imm, - "imm", - 12, - 0, - )) - .emit("put_i(bits, 0, imm.into(), out_reg0, sink);"), - ); - - // I-type encoding of an integer comparison. - recipes.push( - EncodingRecipeBuilder::new("Iicmp", &formats.int_compare_imm, 4) - .operands_in(vec![gpr]) - .operands_out(vec![gpr]) - .inst_predicate(InstructionPredicate::new_is_signed_int( - &formats.int_compare_imm, - "imm", - 12, - 0, - )) - .emit("put_i(bits, in_reg0, imm.into(), out_reg0, sink);"), - ); - - // I-type encoding for `jalr` as a return instruction. We won't use the immediate offset. The - // variable return values are not encoded. - recipes.push( - EncodingRecipeBuilder::new("Iret", &formats.multiary, 4).emit( - r#" - // Return instructions are always a jalr to %x1. - // The return address is provided as a special-purpose link argument. - put_i( - bits, - 1, // rs1 = %x1 - 0, // no offset. - 0, // rd = %x0: no address written. - sink, - ); - "#, - ), - ); - - // I-type encoding for `jalr` as a call_indirect. - recipes.push( - EncodingRecipeBuilder::new("Icall", &formats.call_indirect, 4) - .operands_in(vec![gpr]) - .emit( - r#" - // call_indirect instructions are jalr with rd=%x1. - put_i( - bits, - in_reg0, - 0, // no offset. - 1, // rd = %x1: link register. - sink, - ); - "#, - ), - ); - - // Copy of a GPR is implemented as addi x, 0. - recipes.push( - EncodingRecipeBuilder::new("Icopy", &formats.unary, 4) - .operands_in(vec![gpr]) - .operands_out(vec![gpr]) - .emit("put_i(bits, in_reg0, 0, out_reg0, sink);"), - ); - - // Same for a GPR regmove. - recipes.push( - EncodingRecipeBuilder::new("Irmov", &formats.reg_move, 4) - .operands_in(vec![gpr]) - .emit("put_i(bits, src, 0, dst, sink);"), - ); - - // Same for copy-to-SSA -- GPR regmove. - recipes.push( - EncodingRecipeBuilder::new("copytossa", &formats.copy_to_ssa, 4) - // No operands_in to mention, because a source register is specified directly. - .operands_out(vec![gpr]) - .emit("put_i(bits, src, 0, out_reg0, sink);"), - ); - - // U-type instructions have a 20-bit immediate that targets bits 12-31. - recipes.push( - EncodingRecipeBuilder::new("U", &formats.unary_imm, 4) - .operands_out(vec![gpr]) - .inst_predicate(InstructionPredicate::new_is_signed_int( - &formats.unary_imm, - "imm", - 32, - 12, - )) - .emit("put_u(bits, imm.into(), out_reg0, sink);"), - ); - - // UJ-type unconditional branch instructions. - recipes.push( - EncodingRecipeBuilder::new("UJ", &formats.jump, 4) - .branch_range((0, 21)) - .emit( - r#" - let dest = i64::from(func.offsets[destination]); - let disp = dest - i64::from(sink.offset()); - put_uj(bits, disp, 0, sink); - "#, - ), - ); - - recipes.push(EncodingRecipeBuilder::new("UJcall", &formats.call, 4).emit( - r#" - sink.reloc_external(func.srclocs[inst], - Reloc::RiscvCall, - &func.dfg.ext_funcs[func_ref].name, - 0); - // rd=%x1 is the standard link register. - put_uj(bits, 0, 1, sink); - "#, - )); - - // SB-type branch instructions. - recipes.push( - EncodingRecipeBuilder::new("SB", &formats.branch_icmp, 4) - .operands_in(vec![gpr, gpr]) - .branch_range((0, 13)) - .emit( - r#" - let dest = i64::from(func.offsets[destination]); - let disp = dest - i64::from(sink.offset()); - put_sb(bits, disp, in_reg0, in_reg1, sink); - "#, - ), - ); - - // SB-type branch instruction with rs2 fixed to zero. - recipes.push( - EncodingRecipeBuilder::new("SBzero", &formats.branch, 4) - .operands_in(vec![gpr]) - .branch_range((0, 13)) - .emit( - r#" - let dest = i64::from(func.offsets[destination]); - let disp = dest - i64::from(sink.offset()); - put_sb(bits, disp, in_reg0, 0, sink); - "#, - ), - ); - - // Spill of a GPR. - recipes.push( - EncodingRecipeBuilder::new("GPsp", &formats.unary, 4) - .operands_in(vec![gpr]) - .operands_out(vec![Stack::new(gpr)]) - .emit("unimplemented!();"), - ); - - // Fill of a GPR. - recipes.push( - EncodingRecipeBuilder::new("GPfi", &formats.unary, 4) - .operands_in(vec![Stack::new(gpr)]) - .operands_out(vec![gpr]) - .emit("unimplemented!();"), - ); - - // Stack-slot to same stack-slot copy, which is guaranteed to turn into a no-op. - recipes.push( - EncodingRecipeBuilder::new("stacknull", &formats.unary, 0) - .operands_in(vec![Stack::new(gpr)]) - .operands_out(vec![Stack::new(gpr)]) - .emit(""), - ); - - // No-op fills, created by late-stage redundant-fill removal. - recipes.push( - EncodingRecipeBuilder::new("fillnull", &formats.unary, 0) - .operands_in(vec![Stack::new(gpr)]) - .operands_out(vec![gpr]) - .clobbers_flags(false) - .emit(""), - ); - - recipes -} diff --git a/cranelift/codegen/meta/src/lib.rs b/cranelift/codegen/meta/src/lib.rs index 29a545aad6..88f7ed6b09 100644 --- a/cranelift/codegen/meta/src/lib.rs +++ b/cranelift/codegen/meta/src/lib.rs @@ -119,7 +119,7 @@ pub fn generate( isa::Isa::S390x => { // s390x doesn't have platform-specific settings. } - isa::Isa::Arm32 | isa::Isa::Riscv => todo!(), + isa::Isa::Arm32 => todo!(), } } diff --git a/cranelift/codegen/src/binemit/mod.rs b/cranelift/codegen/src/binemit/mod.rs index 62602d5a88..8861d92ce2 100644 --- a/cranelift/codegen/src/binemit/mod.rs +++ b/cranelift/codegen/src/binemit/mod.rs @@ -58,8 +58,6 @@ pub enum Reloc { /// value is sign-extended, multiplied by 4, and added to the PC of /// the call instruction to form the destination address. Arm64Call, - /// RISC-V call target - RiscvCall, /// s390x PC-relative 4-byte offset S390xPCRel32Dbl, @@ -93,7 +91,7 @@ impl fmt::Display for Reloc { Self::X86CallPCRel4 => write!(f, "CallPCRel4"), Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), - Self::Arm32Call | Self::Arm64Call | Self::RiscvCall => write!(f, "Call"), + Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), diff --git a/cranelift/codegen/src/isa/legacy/mod.rs b/cranelift/codegen/src/isa/legacy/mod.rs deleted file mode 100644 index 15900b9509..0000000000 --- a/cranelift/codegen/src/isa/legacy/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Legacy ("old-style") backends that will be removed in the future. - -#[cfg(feature = "riscv")] -pub(crate) mod riscv; diff --git a/cranelift/codegen/src/isa/legacy/riscv/abi.rs b/cranelift/codegen/src/isa/legacy/riscv/abi.rs deleted file mode 100644 index 44c5f36afe..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/abi.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! RISC-V ABI implementation. -//! -//! This module implements the RISC-V calling convention through the primary `legalize_signature()` -//! entry point. -//! -//! This doesn't support the soft-float ABI at the moment. - -use super::registers::{FPR, GPR}; -use super::settings; -use crate::abi::{legalize_args, ArgAction, ArgAssigner, ValueConversion}; -use crate::ir::{self, AbiParam, ArgumentExtension, ArgumentLoc, ArgumentPurpose, Type}; -use crate::isa::RegClass; -use crate::regalloc::RegisterSet; -use alloc::borrow::Cow; -use core::i32; -use target_lexicon::Triple; - -struct Args { - pointer_bits: u8, - pointer_bytes: u8, - pointer_type: Type, - regs: u32, - reg_limit: u32, - offset: u32, -} - -impl Args { - fn new(bits: u8, enable_e: bool) -> Self { - Self { - pointer_bits: bits, - pointer_bytes: bits / 8, - pointer_type: Type::int(u16::from(bits)).unwrap(), - regs: 0, - reg_limit: if enable_e { 6 } else { 8 }, - offset: 0, - } - } -} - -impl ArgAssigner for Args { - fn assign(&mut self, arg: &AbiParam) -> ArgAction { - fn align(value: u32, to: u32) -> u32 { - (value + to - 1) & !(to - 1) - } - - let ty = arg.value_type; - - // Check for a legal type. - // RISC-V doesn't have SIMD at all, so break all vectors down. - if ty.is_vector() { - return ValueConversion::VectorSplit.into(); - } - - // Large integers and booleans are broken down to fit in a register. - 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 * 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() < u16::from(self.pointer_bits) { - match arg.extension { - ArgumentExtension::None => {} - ArgumentExtension::Uext => return ValueConversion::Uext(self.pointer_type).into(), - ArgumentExtension::Sext => return ValueConversion::Sext(self.pointer_type).into(), - } - } - - if self.regs < self.reg_limit { - // Assign to a register. - let reg = if ty.is_float() { - FPR.unit(10 + self.regs as usize) - } else { - GPR.unit(10 + self.regs as usize) - }; - self.regs += 1; - ArgumentLoc::Reg(reg).into() - } else { - // Assign a stack location. - let loc = ArgumentLoc::Stack(self.offset as i32); - self.offset += u32::from(self.pointer_bytes); - debug_assert!(self.offset <= i32::MAX as u32); - loc.into() - } - } -} - -/// Legalize `sig` for RISC-V. -pub fn legalize_signature( - sig: &mut Cow, - triple: &Triple, - isa_flags: &settings::Flags, - current: bool, -) { - let bits = triple.pointer_width().unwrap().bits(); - - let mut args = Args::new(bits, isa_flags.enable_e()); - if let Some(new_params) = legalize_args(&sig.params, &mut args) { - sig.to_mut().params = new_params; - } - - let mut rets = Args::new(bits, isa_flags.enable_e()); - if let Some(new_returns) = legalize_args(&sig.returns, &mut rets) { - sig.to_mut().returns = new_returns; - } - - if current { - let ptr = Type::int(u16::from(bits)).unwrap(); - - // Add the link register as an argument and return value. - // - // The `jalr` instruction implementing a return can technically accept the return address - // in any register, but a micro-architecture with a return address predictor will only - // recognize it as a return if the address is in `x1`. - let link = AbiParam::special_reg(ptr, ArgumentPurpose::Link, GPR.unit(1)); - sig.to_mut().params.push(link); - sig.to_mut().returns.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 - } -} - -pub fn allocatable_registers(_func: &ir::Function, isa_flags: &settings::Flags) -> RegisterSet { - let mut regs = RegisterSet::new(); - regs.take(GPR, GPR.unit(0)); // Hard-wired 0. - // %x1 is the link register which is available for allocation. - regs.take(GPR, GPR.unit(2)); // Stack pointer. - regs.take(GPR, GPR.unit(3)); // Global pointer. - regs.take(GPR, GPR.unit(4)); // Thread pointer. - // TODO: %x8 is the frame pointer. Reserve it? - - // Remove %x16 and up for RV32E. - if isa_flags.enable_e() { - for u in 16..32 { - regs.take(GPR, GPR.unit(u)); - } - } - - regs -} diff --git a/cranelift/codegen/src/isa/legacy/riscv/binemit.rs b/cranelift/codegen/src/isa/legacy/riscv/binemit.rs deleted file mode 100644 index a1d2b82e12..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/binemit.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! Emitting binary RISC-V machine code. - -use crate::binemit::{bad_encoding, CodeSink, Reloc}; -use crate::ir::{Function, Inst, InstructionData}; -use crate::isa::{RegUnit, StackBaseMask, StackRef, TargetIsa}; -use crate::predicates::is_signed_int; -use crate::regalloc::RegDiversions; -use core::u32; - -include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs")); - -/// R-type instructions. -/// -/// 31 24 19 14 11 6 -/// funct7 rs2 rs1 funct3 rd opcode -/// 25 20 15 12 7 0 -/// -/// Encoding bits: `opcode[6:2] | (funct3 << 5) | (funct7 << 8)`. -fn put_r(bits: u16, rs1: RegUnit, rs2: RegUnit, rd: RegUnit, sink: &mut CS) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let funct3 = (bits >> 5) & 0x7; - let funct7 = (bits >> 8) & 0x7f; - let rs1 = u32::from(rs1) & 0x1f; - let rs2 = u32::from(rs2) & 0x1f; - let rd = u32::from(rd) & 0x1f; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= rd << 7; - i |= funct3 << 12; - i |= rs1 << 15; - i |= rs2 << 20; - i |= funct7 << 25; - - sink.put4(i); -} - -/// R-type instructions with a shift amount instead of rs2. -/// -/// 31 25 19 14 11 6 -/// funct7 shamt rs1 funct3 rd opcode -/// 25 20 15 12 7 0 -/// -/// Both funct7 and shamt contribute to bit 25. In RV64, shamt uses it for shifts > 31. -/// -/// Encoding bits: `opcode[6:2] | (funct3 << 5) | (funct7 << 8)`. -fn put_rshamt( - bits: u16, - rs1: RegUnit, - shamt: i64, - rd: RegUnit, - sink: &mut CS, -) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let funct3 = (bits >> 5) & 0x7; - let funct7 = (bits >> 8) & 0x7f; - let rs1 = u32::from(rs1) & 0x1f; - let shamt = shamt as u32 & 0x3f; - let rd = u32::from(rd) & 0x1f; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= rd << 7; - i |= funct3 << 12; - i |= rs1 << 15; - i |= shamt << 20; - i |= funct7 << 25; - - sink.put4(i); -} - -/// I-type instructions. -/// -/// 31 19 14 11 6 -/// imm rs1 funct3 rd opcode -/// 20 15 12 7 0 -/// -/// Encoding bits: `opcode[6:2] | (funct3 << 5)` -fn put_i(bits: u16, rs1: RegUnit, imm: i64, rd: RegUnit, sink: &mut CS) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let funct3 = (bits >> 5) & 0x7; - let rs1 = u32::from(rs1) & 0x1f; - let rd = u32::from(rd) & 0x1f; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= rd << 7; - i |= funct3 << 12; - i |= rs1 << 15; - i |= (imm << 20) as u32; - - sink.put4(i); -} - -/// U-type instructions. -/// -/// 31 11 6 -/// imm rd opcode -/// 12 7 0 -/// -/// Encoding bits: `opcode[6:2] | (funct3 << 5)` -fn put_u(bits: u16, imm: i64, rd: RegUnit, sink: &mut CS) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let rd = u32::from(rd) & 0x1f; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= rd << 7; - i |= imm as u32 & 0xfffff000; - - sink.put4(i); -} - -/// SB-type branch instructions. -/// -/// 31 24 19 14 11 6 -/// imm rs2 rs1 funct3 imm opcode -/// 25 20 15 12 7 0 -/// -/// Encoding bits: `opcode[6:2] | (funct3 << 5)` -fn put_sb(bits: u16, imm: i64, rs1: RegUnit, rs2: RegUnit, sink: &mut CS) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let funct3 = (bits >> 5) & 0x7; - let rs1 = u32::from(rs1) & 0x1f; - let rs2 = u32::from(rs2) & 0x1f; - - debug_assert!(is_signed_int(imm, 13, 1), "SB out of range {:#x}", imm); - let imm = imm as u32; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= funct3 << 12; - i |= rs1 << 15; - i |= rs2 << 20; - - // The displacement is completely hashed up. - i |= ((imm >> 11) & 0x1) << 7; - i |= ((imm >> 1) & 0xf) << 8; - i |= ((imm >> 5) & 0x3f) << 25; - i |= ((imm >> 12) & 0x1) << 31; - - sink.put4(i); -} - -/// UJ-type jump instructions. -/// -/// 31 11 6 -/// imm rd opcode -/// 12 7 0 -/// -/// Encoding bits: `opcode[6:2]` -fn put_uj(bits: u16, imm: i64, rd: RegUnit, sink: &mut CS) { - let bits = u32::from(bits); - let opcode5 = bits & 0x1f; - let rd = u32::from(rd) & 0x1f; - - debug_assert!(is_signed_int(imm, 21, 1), "UJ out of range {:#x}", imm); - let imm = imm as u32; - - // 0-6: opcode - let mut i = 0x3; - i |= opcode5 << 2; - i |= rd << 7; - - // The displacement is completely hashed up. - i |= imm & 0xff000; - i |= ((imm >> 11) & 0x1) << 20; - i |= ((imm >> 1) & 0x3ff) << 21; - i |= ((imm >> 20) & 0x1) << 31; - - sink.put4(i); -} diff --git a/cranelift/codegen/src/isa/legacy/riscv/enc_tables.rs b/cranelift/codegen/src/isa/legacy/riscv/enc_tables.rs deleted file mode 100644 index 76184ad727..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/enc_tables.rs +++ /dev/null @@ -1,18 +0,0 @@ -//! Encoding tables for RISC-V. - -use super::registers::*; -use crate::ir; -use crate::isa; -use crate::isa::constraints::*; -use crate::isa::enc_tables::*; -use crate::isa::encoding::{base_size, RecipeSizing}; -use crate::predicates; - -// Include the generated encoding tables: -// - `LEVEL1_RV32` -// - `LEVEL1_RV64` -// - `LEVEL2` -// - `ENCLIST` -// - `INFO` -include!(concat!(env!("OUT_DIR"), "/encoding-riscv.rs")); -include!(concat!(env!("OUT_DIR"), "/legalize-riscv.rs")); diff --git a/cranelift/codegen/src/isa/legacy/riscv/mod.rs b/cranelift/codegen/src/isa/legacy/riscv/mod.rs deleted file mode 100644 index 2c1ebf1c85..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/mod.rs +++ /dev/null @@ -1,304 +0,0 @@ -//! RISC-V Instruction Set Architecture. - -mod abi; -mod binemit; -mod enc_tables; -mod registers; -pub mod settings; - -use super::super::settings as shared_settings; -#[cfg(feature = "testing_hooks")] -use crate::binemit::CodeSink; -use crate::binemit::{emit_function, MemoryCodeSink}; -use crate::ir; -use crate::isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings}; -use crate::isa::Builder as IsaBuilder; -use crate::isa::{EncInfo, RegClass, RegInfo, TargetIsa}; -use crate::regalloc; -use alloc::{borrow::Cow, boxed::Box, vec::Vec}; -use core::any::Any; -use core::fmt; -use core::hash::{Hash, Hasher}; -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], -} - -/// Get an ISA builder for creating RISC-V targets. -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 { - 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, - }) -} - -impl TargetIsa for Isa { - fn name(&self) -> &'static str { - "riscv" - } - - fn triple(&self) -> &Triple { - &self.triple - } - - fn flags(&self) -> &shared_settings::Flags { - &self.shared_flags - } - - fn isa_flags(&self) -> Vec { - self.isa_flags.iter().collect() - } - - fn hash_all_flags(&self, mut hasher: &mut dyn Hasher) { - self.shared_flags.hash(&mut hasher); - self.isa_flags.hash(&mut hasher); - } - - fn register_info(&self) -> RegInfo { - registers::INFO.clone() - } - - fn encoding_info(&self) -> EncInfo { - enc_tables::INFO.clone() - } - - fn legal_encodings<'a>( - &'a self, - func: &'a ir::Function, - inst: &'a ir::InstructionData, - ctrl_typevar: ir::Type, - ) -> Encodings<'a> { - lookup_enclist( - ctrl_typevar, - inst, - func, - self.cpumode, - &enc_tables::LEVEL2[..], - &enc_tables::ENCLISTS[..], - &enc_tables::LEGALIZE_ACTIONS[..], - &enc_tables::RECIPE_PREDICATES[..], - &enc_tables::INST_PREDICATES[..], - self.isa_flags.predicate_view(), - ) - } - - fn legalize_signature(&self, sig: &mut Cow, current: bool) { - abi::legalize_signature(sig, &self.triple, &self.isa_flags, current) - } - - fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass { - abi::regclass_for_abi_type(ty) - } - - fn allocatable_registers(&self, func: &ir::Function) -> regalloc::RegisterSet { - abi::allocatable_registers(func, &self.isa_flags) - } - - #[cfg(feature = "testing_hooks")] - fn emit_inst( - &self, - func: &ir::Function, - inst: ir::Inst, - divert: &mut regalloc::RegDiversions, - sink: &mut dyn CodeSink, - ) { - binemit::emit_inst(func, inst, divert, sink, self) - } - - fn emit_function_to_memory(&self, func: &ir::Function, sink: &mut MemoryCodeSink) { - emit_function(func, binemit::emit_inst, sink, self) - } - - fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC { - unimplemented!() - } - - fn unsigned_sub_overflow_condition(&self) -> ir::condcodes::IntCC { - unimplemented!() - } - - fn as_any(&self) -> &dyn Any { - self as &dyn Any - } -} - -#[cfg(test)] -mod tests { - use crate::ir::{immediates, types}; - use crate::ir::{Function, InstructionData, Opcode}; - use crate::isa; - use crate::settings::{self, Configurable}; - use alloc::string::{String, ToString}; - use core::str::FromStr; - use target_lexicon::triple; - - fn encstr(isa: &dyn isa::TargetIsa, enc: Result) -> String { - match enc { - Ok(e) => isa.encoding_info().display(e).to_string(), - Err(_) => "no encoding".to_string(), - } - } - - #[test] - fn test_64bitenc() { - let shared_builder = settings::builder(); - let shared_flags = settings::Flags::new(shared_builder); - let isa = isa::lookup(triple!("riscv64")) - .unwrap() - .finish(shared_flags); - - let mut func = Function::new(); - let block = func.dfg.make_block(); - let arg64 = func.dfg.append_block_param(block, types::I64); - let arg32 = func.dfg.append_block_param(block, types::I32); - - // Try to encode iadd_imm.i64 v1, -10. - let inst64 = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg64, - imm: immediates::Imm64::new(-10), - }; - - // ADDI is I/0b00100 - assert_eq!( - encstr(&*isa, isa.encode(&func, &inst64, types::I64)), - "Ii#04" - ); - - // Try to encode iadd_imm.i64 v1, -10000. - let inst64_large = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg64, - imm: immediates::Imm64::new(-10000), - }; - - // Immediate is out of range for ADDI. - assert!(isa.encode(&func, &inst64_large, types::I64).is_err()); - - // Create an iadd_imm.i32 which is encodable in RV64. - let inst32 = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg32, - imm: immediates::Imm64::new(10), - }; - - // ADDIW is I/0b00110 - assert_eq!( - encstr(&*isa, isa.encode(&func, &inst32, types::I32)), - "Ii#06" - ); - } - - // Same as above, but for RV32. - #[test] - fn test_32bitenc() { - let shared_builder = settings::builder(); - let shared_flags = settings::Flags::new(shared_builder); - let isa = isa::lookup(triple!("riscv32")) - .unwrap() - .finish(shared_flags); - - let mut func = Function::new(); - let block = func.dfg.make_block(); - let arg64 = func.dfg.append_block_param(block, types::I64); - let arg32 = func.dfg.append_block_param(block, types::I32); - - // Try to encode iadd_imm.i64 v1, -10. - let inst64 = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg64, - imm: immediates::Imm64::new(-10), - }; - - // In 32-bit mode, an i64 bit add should be narrowed. - assert!(isa.encode(&func, &inst64, types::I64).is_err()); - - // Try to encode iadd_imm.i64 v1, -10000. - let inst64_large = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg64, - imm: immediates::Imm64::new(-10000), - }; - - // In 32-bit mode, an i64 bit add should be narrowed. - assert!(isa.encode(&func, &inst64_large, types::I64).is_err()); - - // Create an iadd_imm.i32 which is encodable in RV32. - let inst32 = InstructionData::BinaryImm64 { - opcode: Opcode::IaddImm, - arg: arg32, - imm: immediates::Imm64::new(10), - }; - - // ADDI is I/0b00100 - assert_eq!( - encstr(&*isa, isa.encode(&func, &inst32, types::I32)), - "Ii#04" - ); - - // Create an imul.i32 which is encodable in RV32, but only when use_m is true. - let mul32 = InstructionData::Binary { - opcode: Opcode::Imul, - args: [arg32, arg32], - }; - - assert!(isa.encode(&func, &mul32, types::I32).is_err()); - } - - #[test] - fn test_rv32m() { - 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(triple!("riscv32")).unwrap(); - isa_builder.enable("supports_m").unwrap(); - - let isa = isa_builder.finish(shared_flags); - - let mut func = Function::new(); - let block = func.dfg.make_block(); - let arg32 = func.dfg.append_block_param(block, types::I32); - - // Create an imul.i32 which is encodable in RV32M. - let mul32 = InstructionData::Binary { - opcode: Opcode::Imul, - args: [arg32, arg32], - }; - assert_eq!( - encstr(&*isa, isa.encode(&func, &mul32, types::I32)), - "R#10c" - ); - } -} - -impl fmt::Display for Isa { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}\n{}", self.shared_flags, self.isa_flags) - } -} diff --git a/cranelift/codegen/src/isa/legacy/riscv/registers.rs b/cranelift/codegen/src/isa/legacy/riscv/registers.rs deleted file mode 100644 index 9043b7f65f..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/registers.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! RISC-V register descriptions. - -use crate::isa::registers::{RegBank, RegClass, RegClassData, RegInfo, RegUnit}; - -include!(concat!(env!("OUT_DIR"), "/registers-riscv.rs")); - -#[cfg(test)] -mod tests { - use super::{FPR, GPR, INFO}; - use crate::isa::RegUnit; - use alloc::string::{String, ToString}; - - #[test] - fn unit_encodings() { - assert_eq!(INFO.parse_regunit("x0"), Some(0)); - assert_eq!(INFO.parse_regunit("x31"), Some(31)); - assert_eq!(INFO.parse_regunit("f0"), Some(32)); - assert_eq!(INFO.parse_regunit("f31"), Some(63)); - - assert_eq!(INFO.parse_regunit("x32"), None); - assert_eq!(INFO.parse_regunit("f32"), None); - } - - #[test] - fn unit_names() { - fn uname(ru: RegUnit) -> String { - INFO.display_regunit(ru).to_string() - } - - assert_eq!(uname(0), "%x0"); - assert_eq!(uname(1), "%x1"); - assert_eq!(uname(31), "%x31"); - assert_eq!(uname(32), "%f0"); - assert_eq!(uname(33), "%f1"); - assert_eq!(uname(63), "%f31"); - assert_eq!(uname(64), "%INVALID64"); - } - - #[test] - fn classes() { - assert!(GPR.contains(GPR.unit(0))); - assert!(GPR.contains(GPR.unit(31))); - assert!(!FPR.contains(GPR.unit(0))); - assert!(!FPR.contains(GPR.unit(31))); - assert!(!GPR.contains(FPR.unit(0))); - assert!(!GPR.contains(FPR.unit(31))); - assert!(FPR.contains(FPR.unit(0))); - assert!(FPR.contains(FPR.unit(31))); - } -} diff --git a/cranelift/codegen/src/isa/legacy/riscv/settings.rs b/cranelift/codegen/src/isa/legacy/riscv/settings.rs deleted file mode 100644 index 3da9f491fd..0000000000 --- a/cranelift/codegen/src/isa/legacy/riscv/settings.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! RISC-V Settings. - -use crate::settings::{self, detail, Builder, Value}; -use core::fmt; - -// Include code generated by `cranelift-codegen/meta/src/gen_settings.rs`. This file contains a -// public `Flags` struct with an impl for all of the settings defined in -// `cranelift-codegen/meta/src/isa/riscv/mod.rs`. -include!(concat!(env!("OUT_DIR"), "/settings-riscv.rs")); - -#[cfg(test)] -mod tests { - use super::{builder, Flags}; - use crate::settings::{self, Configurable}; - use alloc::string::ToString; - - #[test] - fn display_default() { - let shared = settings::Flags::new(settings::builder()); - let b = builder(); - let f = Flags::new(&shared, b); - assert_eq!( - f.to_string(), - "[riscv]\n\ - supports_m = false\n\ - supports_a = false\n\ - supports_f = false\n\ - supports_d = false\n\ - enable_m = true\n\ - enable_e = false\n" - ); - // Predicates are not part of the Display output. - assert_eq!(f.full_float(), false); - } - - #[test] - fn predicates() { - let mut sb = settings::builder(); - sb.set("enable_simd", "true").unwrap(); - let shared = settings::Flags::new(sb); - let mut b = builder(); - b.enable("supports_f").unwrap(); - b.enable("supports_d").unwrap(); - let f = Flags::new(&shared, b); - assert_eq!(f.full_float(), true); - - let mut sb = settings::builder(); - sb.set("enable_simd", "false").unwrap(); - let shared = settings::Flags::new(sb); - let mut b = builder(); - b.enable("supports_f").unwrap(); - b.enable("supports_d").unwrap(); - let f = Flags::new(&shared, b); - assert_eq!(f.full_float(), false); - } -} diff --git a/cranelift/codegen/src/isa/mod.rs b/cranelift/codegen/src/isa/mod.rs index 92edfd744f..069324f040 100644 --- a/cranelift/codegen/src/isa/mod.rs +++ b/cranelift/codegen/src/isa/mod.rs @@ -84,12 +84,6 @@ pub(crate) mod aarch64; #[cfg(feature = "s390x")] mod s390x; -#[cfg(feature = "riscv")] -mod legacy; - -#[cfg(feature = "riscv")] -use legacy::riscv; - pub mod unwind; mod call_conv; @@ -121,9 +115,6 @@ macro_rules! isa_builder { /// by `variant` if available. pub fn lookup_variant(triple: Triple) -> Result { match triple.architecture { - Architecture::Riscv32 { .. } | Architecture::Riscv64 { .. } => { - isa_builder!(riscv, (feature = "riscv"), triple) - } Architecture::X86_64 => { isa_builder!(x64, (feature = "x86"), triple) } diff --git a/cranelift/codegen/src/legalizer/mod.rs b/cranelift/codegen/src/legalizer/mod.rs index ee89ee35f0..0ba70915a1 100644 --- a/cranelift/codegen/src/legalizer/mod.rs +++ b/cranelift/codegen/src/legalizer/mod.rs @@ -13,19 +13,12 @@ //! The legalizer does not deal with register allocation constraints. These constraints are derived //! from the encoding recipes, and solved later by the register allocator. -#[cfg(any(feature = "x86", feature = "riscv"))] -use crate::bitset::BitSet; use crate::cursor::{Cursor, FuncCursor}; use crate::flowgraph::ControlFlowGraph; use crate::ir::types::{I32, I64}; use crate::ir::{self, InstBuilder, MemFlags}; use crate::isa::TargetIsa; -#[cfg(feature = "riscv")] -use crate::predicates; -#[cfg(feature = "riscv")] -use alloc::vec::Vec; - use crate::timing; use alloc::collections::BTreeSet; @@ -37,8 +30,6 @@ mod libcall; mod split; mod table; -#[cfg(any(feature = "x86", feature = "riscv"))] -use self::call::expand_call; use self::globalvalue::expand_global_value; use self::heap::expand_heap_addr; pub(crate) use self::libcall::expand_as_libcall; diff --git a/cranelift/filetests/filetests/isa/riscv/abi-e.clif b/cranelift/filetests/filetests/isa/riscv/abi-e.clif deleted file mode 100644 index fcd762ee81..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/abi-e.clif +++ /dev/null @@ -1,14 +0,0 @@ -; Test the legalization of function signatures for RV32E. -test legalizer -target riscv32 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 = (i64, i64, i64, i64) -> i64 system_v - ; check: sig0 = (i32 [%x10], i32 [%x11], i32 [%x12], i32 [%x13], i32 [%x14], i32 [%x15], i32 [0], i32 [4]) -> i32 [%x10], i32 [%x11] system_v -block0: - return -} diff --git a/cranelift/filetests/filetests/isa/riscv/abi.clif b/cranelift/filetests/filetests/isa/riscv/abi.clif deleted file mode 100644 index d9469f490e..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/abi.clif +++ /dev/null @@ -1,32 +0,0 @@ -; Test the legalization of function signatures. -test legalizer -target riscv32 - -; regex: V=v\d+ - -function %f() { - sig0 = (i32) -> i32 system_v - ; check: sig0 = (i32 [%x10]) -> i32 [%x10] system_v - - sig1 = (i64) -> b1 system_v - ; check: sig1 = (i32 [%x10], i32 [%x11]) -> b1 [%x10] system_v - - ; The i64 argument must go in an even-odd register pair. - sig2 = (f32, i64) -> f64 system_v - ; check: sig2 = (f32 [%f10], i32 [%x12], i32 [%x13]) -> f64 [%f10] system_v - - ; Spilling into the stack args. - sig3 = (f64, f64, f64, f64, f64, f64, f64, i64) -> f64 system_v - ; check: sig3 = (f64 [%f10], f64 [%f11], f64 [%f12], f64 [%f13], f64 [%f14], f64 [%f15], f64 [%f16], i32 [0], i32 [4]) -> f64 [%f10] system_v - - ; Splitting vectors. - sig4 = (i32x4) system_v - ; check: sig4 = (i32 [%x10], i32 [%x11], i32 [%x12], i32 [%x13]) system_v - - ; Splitting vectors, then splitting ints. - sig5 = (i64x4) system_v - ; check: sig5 = (i32 [%x10], i32 [%x11], i32 [%x12], i32 [%x13], i32 [%x14], i32 [%x15], i32 [%x16], i32 [%x17]) system_v - -block0: - return -} diff --git a/cranelift/filetests/filetests/isa/riscv/binary32.clif b/cranelift/filetests/filetests/isa/riscv/binary32.clif deleted file mode 100644 index 5a69c4289b..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/binary32.clif +++ /dev/null @@ -1,189 +0,0 @@ -; Binary emission of 32-bit code. -test binemit -target riscv32 - -function %RV32I(i32 link [%x1]) -> i32 link [%x1] { - sig0 = () - fn0 = %foo() - -block0(v9999: i32): - [-,%x10] v1 = iconst.i32 1 - [-,%x21] v2 = iconst.i32 2 - - ; Integer Register-Register Operations. - ; add - [-,%x7] v10 = iadd v1, v2 ; bin: 015503b3 - [-,%x16] v11 = iadd v2, v1 ; bin: 00aa8833 - ; sub - [-,%x7] v12 = isub v1, v2 ; bin: 415503b3 - [-,%x16] v13 = isub v2, v1 ; bin: 40aa8833 - ; and - [-,%x7] v20 = band v1, v2 ; bin: 015573b3 - [-,%x16] v21 = band v2, v1 ; bin: 00aaf833 - ; or - [-,%x7] v22 = bor v1, v2 ; bin: 015563b3 - [-,%x16] v23 = bor v2, v1 ; bin: 00aae833 - ; xor - [-,%x7] v24 = bxor v1, v2 ; bin: 015543b3 - [-,%x16] v25 = bxor v2, v1 ; bin: 00aac833 - ; sll - [-,%x7] v30 = ishl v1, v2 ; bin: 015513b3 - [-,%x16] v31 = ishl v2, v1 ; bin: 00aa9833 - ; srl - [-,%x7] v32 = ushr v1, v2 ; bin: 015553b3 - [-,%x16] v33 = ushr v2, v1 ; bin: 00aad833 - ; sra - [-,%x7] v34 = sshr v1, v2 ; bin: 415553b3 - [-,%x16] v35 = sshr v2, v1 ; bin: 40aad833 - ; slt - [-,%x7] v42 = icmp slt v1, v2 ; bin: 015523b3 - [-,%x16] v43 = icmp slt v2, v1 ; bin: 00aaa833 - ; sltu - [-,%x7] v44 = icmp ult v1, v2 ; bin: 015533b3 - [-,%x16] v45 = icmp ult v2, v1 ; bin: 00aab833 - - ; Integer Register-Immediate Instructions - - ; addi - [-,%x7] v100 = iadd_imm v1, 1000 ; bin: 3e850393 - [-,%x16] v101 = iadd_imm v2, -905 ; bin: c77a8813 - ; andi - [-,%x7] v110 = band_imm v1, 1000 ; bin: 3e857393 - [-,%x16] v111 = band_imm v2, -905 ; bin: c77af813 - ; ori - [-,%x7] v112 = bor_imm v1, 1000 ; bin: 3e856393 - [-,%x16] v113 = bor_imm v2, -905 ; bin: c77ae813 - ; xori - [-,%x7] v114 = bxor_imm v1, 1000 ; bin: 3e854393 - [-,%x16] v115 = bxor_imm v2, -905 ; bin: c77ac813 - - ; slli - [-,%x7] v120 = ishl_imm v1, 31 ; bin: 01f51393 - [-,%x16] v121 = ishl_imm v2, 8 ; bin: 008a9813 - ; srli - [-,%x7] v122 = ushr_imm v1, 31 ; bin: 01f55393 - [-,%x16] v123 = ushr_imm v2, 8 ; bin: 008ad813 - ; srai - [-,%x7] v124 = sshr_imm v1, 31 ; bin: 41f55393 - [-,%x16] v125 = sshr_imm v2, 8 ; bin: 408ad813 - - ; slti - [-,%x7] v130 = icmp_imm slt v1, 1000 ; bin: 3e852393 - [-,%x16] v131 = icmp_imm slt v2, -905 ; bin: c77aa813 - ; sltiu - [-,%x7] v132 = icmp_imm ult v1, 1000 ; bin: 3e853393 - [-,%x16] v133 = icmp_imm ult v2, -905 ; bin: c77ab813 - - ; lui - [-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7 - [-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837 - ; addi - [-,%x7] v142 = iconst.i32 1000 ; bin: 3e800393 - [-,%x16] v143 = iconst.i32 -905 ; bin: c7700813 - - ; Copies alias to iadd_imm. - [-,%x7] v150 = copy v1 ; bin: 00050393 - [-,%x16] v151 = copy v2 ; bin: 000a8813 - - ; Control Transfer Instructions - - ; jal %x1, fn0 - call fn0() ; bin: Call(%foo) 000000ef - - ; jalr %x1, %x10 - call_indirect sig0, v1() ; bin: 000500e7 - call_indirect sig0, v2() ; bin: 000a80e7 - - brz v1, block3 - fallthrough block4 - -block4: - brnz v1, block1 - fallthrough block5 - -block5: - ; jalr %x0, %x1, 0 - return v9999 ; bin: 00008067 - -block1: - ; beq 0x000 - br_icmp eq v1, v2, block1 ; bin: 01550063 - fallthrough block100 - -block100: - ; bne 0xffc - br_icmp ne v1, v2, block1 ; bin: ff551ee3 - fallthrough block101 - -block101: - ; blt 0xff8 - br_icmp slt v1, v2, block1 ; bin: ff554ce3 - fallthrough block102 - -block102: - ; bge 0xff4 - br_icmp sge v1, v2, block1 ; bin: ff555ae3 - fallthrough block103 - -block103: - ; bltu 0xff0 - br_icmp ult v1, v2, block1 ; bin: ff5568e3 - fallthrough block104 - -block104: - ; bgeu 0xfec - br_icmp uge v1, v2, block1 ; bin: ff5576e3 - fallthrough block105 - -block105: - - ; Forward branches. - fallthrough block106 - -block106: - ; beq 0x018 - br_icmp eq v2, v1, block2 ; bin: 00aa8c63 - fallthrough block107 - -block107: - ; bne 0x014 - br_icmp ne v2, v1, block2 ; bin: 00aa9a63 - fallthrough block108 - -block108: - ; blt 0x010 - br_icmp slt v2, v1, block2 ; bin: 00aac863 - fallthrough block109 - -block109: - ; bge 0x00c - br_icmp sge v2, v1, block2 ; bin: 00aad663 - fallthrough block110 - -block110: - ; bltu 0x008 - br_icmp ult v2, v1, block2 ; bin: 00aae463 - fallthrough block111 - -block111: - ; bgeu 0x004 - br_icmp uge v2, v1, block2 ; bin: 00aaf263 - - fallthrough block2 - -block2: - ; jal %x0, 0x00000 - jump block2 ; bin: 0000006f - -block3: - ; beq x, %x0 - brz v1, block3 ; bin: 00050063 - fallthrough block6 - -block6: - ; bne x, %x0 - brnz v1, block3 ; bin: fe051ee3 - - ; jal %x0, 0x1ffff4 - jump block2 ; bin: ff5ff06f -} diff --git a/cranelift/filetests/filetests/isa/riscv/encoding.clif b/cranelift/filetests/filetests/isa/riscv/encoding.clif deleted file mode 100644 index b8c991f52e..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/encoding.clif +++ /dev/null @@ -1,21 +0,0 @@ -test legalizer -target riscv32 supports_m=1 - -function %int32(i32, i32) { -block0(v1: i32, v2: i32): - v10 = iadd v1, v2 - ; check: [R#0c] - ; sameln: v10 = iadd - - v11 = isub v1, v2 - ; check: [R#200c] - ; sameln: v11 = isub - - v12 = imul v1, v2 - ; check: [R#10c] - ; sameln: v12 = imul - - return - ; check: [Iret#19] - ; sameln: return -} diff --git a/cranelift/filetests/filetests/isa/riscv/expand-i32.clif b/cranelift/filetests/filetests/isa/riscv/expand-i32.clif deleted file mode 100644 index ee62bc093f..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/expand-i32.clif +++ /dev/null @@ -1,37 +0,0 @@ -; Test the legalization of i32 instructions that don't have RISC-V versions. -test legalizer - -target riscv32 supports_m=1 - -target riscv64 supports_m=1 - -; regex: V=v\d+ - -function %carry_out(i32, i32) -> i32, b1 { -block0(v1: i32, v2: i32): - v3, v4 = iadd_cout v1, v2 - return v3, v4 -} -; check: v3 = iadd v1, v2 -; check: v4 = icmp ult v3, v1 -; check: return v3, v4 - -; Expanding illegal immediate constants. -; Note that at some point we'll probably expand the iconst as well. -function %large_imm(i32) -> i32 { -block0(v0: i32): - v1 = iadd_imm v0, 1000000000 - return v1 -} -; check: $(cst=$V) = iconst.i32 0x3b9a_ca00 -; check: v1 = iadd v0, $cst -; check: return v1 - -function %bitclear(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = band_not v0, v1 - ; check: iconst.i32 -1 - ; check: bxor - ; check: band - return v2 -} diff --git a/cranelift/filetests/filetests/isa/riscv/legalize-abi.clif b/cranelift/filetests/filetests/isa/riscv/legalize-abi.clif deleted file mode 100644 index 5ea4cd002e..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/legalize-abi.clif +++ /dev/null @@ -1,134 +0,0 @@ -; Test legalizer's handling of ABI boundaries. -test legalizer -target riscv32 - -; regex: V=v\d+ -; regex: SS=ss\d+ -; regex: WS=\s+ - -function %int_split_args(i64) -> i64 { -block0(v0: i64): - ; check: block0($(v0l=$V): i32, $(v0h=$V): i32, $(link=$V): i32): - ; check: v0 = iconcat $v0l, $v0h - v1 = iadd_imm v0, 1 - ; check: $(v1l=$V), $(v1h=$V) = isplit v1 - ; check: return $v1l, $v1h, $link - return v1 -} - -function %split_call_arg(i32) { - fn1 = %foo(i64) - fn2 = %foo(i32, i64) -block0(v0: i32): - v1 = uextend.i64 v0 - call fn1(v1) - ; check: $(v1h=$V) = iconst.i32 0 - ; check: call fn1(v0, $v1h) - call fn2(v0, v1) - ; check: call fn2(v0, $V, $V) - return -} - -function %split_ret_val() { - fn1 = %foo() -> i64 -block0: - v1 = call fn1() - ; check: block0($(link=$V): i32): - ; nextln: $(v1l=$V), $(v1h=$V) = call fn1() - ; check: v1 = iconcat $v1l, $v1h - jump block1(v1) - ; check: jump block1(v1) - -block1(v10: i64): - jump block1(v10) -} - -; First return value is fine, second one is expanded. -function %split_ret_val2() { - fn1 = %foo() -> i32, i64 -block0: - v1, v2 = call fn1() - ; check: block0($(link=$V): i32): - ; nextln: v1, $(v2l=$V), $(v2h=$V) = call fn1() - ; check: v2 = iconcat $v2l, $v2h - jump block1(v1, v2) - ; check: jump block1(v1, v2) - -block1(v9: i32, v10: i64): - jump block1(v9, v10) -} - -function %int_ext(i8, i8 sext, i8 uext) -> i8 uext { -block0(v1: i8, v2: i8, v3: i8): - ; check: block0(v1: i8, $(v2x=$V): i32, $(v3x=$V): i32, $(link=$V): i32): - ; check: v2 = ireduce.i8 $v2x - ; check: v3 = ireduce.i8 $v3x - ; check: $(v1x=$V) = uextend.i32 v1 - ; check: return $v1x, $link - return v1 -} - -; Function produces single return value, still need to copy. -function %ext_ret_val() { - fn1 = %foo() -> i8 sext -block0: - v1 = call fn1() - ; check: block0($V: i32): - ; nextln: $(rv=$V) = call fn1() - ; check: v1 = ireduce.i8 $rv - jump block1(v1) - ; check: jump block1(v1) - -block1(v10: i8): - jump block1(v10) -} - -function %vector_split_args(i64x4) -> i64x4 { -block0(v0: i64x4): - ; check: block0($(v0al=$V): i32, $(v0ah=$V): i32, $(v0bl=$V): i32, $(v0bh=$V): i32, $(v0cl=$V): i32, $(v0ch=$V): i32, $(v0dl=$V): i32, $(v0dh=$V): i32, $(link=$V): i32): - ; check: $(v0a=$V) = iconcat $v0al, $v0ah - ; check: $(v0b=$V) = iconcat $v0bl, $v0bh - ; check: $(v0ab=$V) = vconcat $v0a, $v0b - ; check: $(v0c=$V) = iconcat $v0cl, $v0ch - ; check: $(v0d=$V) = iconcat $v0dl, $v0dh - ; check: $(v0cd=$V) = vconcat $v0c, $v0d - ; check: v0 = vconcat $v0ab, $v0cd - v1 = bxor v0, v0 - ; check: $(v1ab=$V), $(v1cd=$V) = vsplit v1 - ; check: $(v1a=$V), $(v1b=$V) = vsplit $v1ab - ; check: $(v1al=$V), $(v1ah=$V) = isplit $v1a - ; check: $(v1bl=$V), $(v1bh=$V) = isplit $v1b - ; check: $(v1c=$V), $(v1d=$V) = vsplit $v1cd - ; check: $(v1cl=$V), $(v1ch=$V) = isplit $v1c - ; check: $(v1dl=$V), $(v1dh=$V) = isplit $v1d - ; check: return $v1al, $v1ah, $v1bl, $v1bh, $v1cl, $v1ch, $v1dl, $v1dh, $link - return v1 -} - -function %indirect(i32) { - sig1 = () system_v -block0(v0: i32): - call_indirect sig1, v0() - return -} - -; The first argument to call_indirect doesn't get altered. -function %indirect_arg(i32, f32x2) { - sig1 = (f32x2) system_v -block0(v0: i32, v1: f32x2): - call_indirect sig1, v0(v1) - ; check: call_indirect sig1, v0($V, $V) - return -} - -; Call a function that takes arguments on the stack. -function %stack_args(i32) { - ; check: $(ss0=$SS) = outgoing_arg 4 - fn1 = %foo(i64, i64, i64, i64, i32) -block0(v0: i32): - v1 = iconst.i64 1 - call fn1(v1, v1, v1, v1, v0) - ; check: [GPsp#48,$ss0]$WS $(v0s=$V) = spill v0 - ; check: call fn1($(=.*), $v0s) - return -} diff --git a/cranelift/filetests/filetests/isa/riscv/legalize-i64.clif b/cranelift/filetests/filetests/isa/riscv/legalize-i64.clif deleted file mode 100644 index 11b31218be..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/legalize-i64.clif +++ /dev/null @@ -1,64 +0,0 @@ -; Test the legalization of i64 arithmetic instructions. -test legalizer -target riscv32 supports_m=1 - -; regex: V=v\d+ - -function %bitwise_and(i64, i64) -> i64 { -block0(v1: i64, v2: i64): - v3 = band v1, v2 - return v3 -} -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): -; check: [R#ec -; sameln: $(v3l=$V) = band $v1l, $v2l -; check: [R#ec -; sameln: $(v3h=$V) = band $v1h, $v2h -; check: v3 = iconcat $v3l, $v3h -; check: return $v3l, $v3h, $link - -function %bitwise_or(i64, i64) -> i64 { -block0(v1: i64, v2: i64): - v3 = bor v1, v2 - return v3 -} -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): -; check: [R#cc -; sameln: $(v3l=$V) = bor $v1l, $v2l -; check: [R#cc -; sameln: $(v3h=$V) = bor $v1h, $v2h -; check: v3 = iconcat $v3l, $v3h -; check: return $v3l, $v3h, $link - -function %bitwise_xor(i64, i64) -> i64 { -block0(v1: i64, v2: i64): - v3 = bxor v1, v2 - return v3 -} -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): -; check: [R#8c -; sameln: $(v3l=$V) = bxor $v1l, $v2l -; check: [R#8c -; sameln: $(v3h=$V) = bxor $v1h, $v2h -; check: v3 = iconcat $v3l, $v3h -; check: return $v3l, $v3h, $link - -function %arith_add(i64, i64) -> i64 { -; Legalizing iadd.i64 requires two steps: -; 1. Narrow to iadd_cout.i32, then -; 2. Expand iadd_cout.i32 since RISC-V has no carry flag. -block0(v1: i64, v2: i64): - v3 = iadd v1, v2 - return v3 -} -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): -; check: [R#0c -; sameln: $(v3l=$V) = iadd $v1l, $v2l -; check: $(c=$V) = icmp ult $v3l, $v1l -; check: [R#0c -; sameln: $(v3h1=$V) = iadd $v1h, $v2h -; check: $(c_int=$V) = bint.i32 $c -; check: [R#0c -; sameln: $(v3h=$V) = iadd $v3h1, $c_int -; check: v3 = iconcat $v3l, $v3h -; check: return $v3l, $v3h, $link diff --git a/cranelift/filetests/filetests/isa/riscv/legalize-icmp_imm-i64.clif b/cranelift/filetests/filetests/isa/riscv/legalize-icmp_imm-i64.clif deleted file mode 100644 index d7250cb3af..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/legalize-icmp_imm-i64.clif +++ /dev/null @@ -1,55 +0,0 @@ -test legalizer -target riscv32 - -; regex: V=v\d+ - -function %icmp_imm_eq(i64) -> b1 { -block0(v0: i64): - v1 = icmp_imm eq v0, 0x20202020_10101010 - return v1 -} -; check: block0($(v0l=$V): i32, $(v0h=$V): i32, $(link=$V): i32): -; nextln: $(v2l=$V) -> $(v0l) -; nextln: $(v2h=$V) -> $(v0h) -; nextln: v0 = iconcat $(v0l), $(v0h) -; nextln: $(imm_low=$V) = iconst.i32 0x1010_1010 -; nextln: $(imm_high=$V) = iconst.i32 0x2020_2020 -; nextln: $(v3=$V) = icmp eq $(v2l), $(imm_low) -; nextln: $(v4=$V) = icmp eq $(v2h), $(imm_high) -; nextln: v1 = band $(v3), $(v4) -; nextln: return v1, $(link) - -function %icmp_imm_ne(i64) -> b1 { -block0(v0: i64): - v1 = icmp_imm ne v0, 0x33333333_44444444 - return v1 -} -; check: block0($(v0l=$V): i32, $(v0h=$V): i32, $(link=$V): i32): -; nextln: $(v2l=$V) -> $(v0l) -; nextln: $(v2h=$V) -> $(v0h) -; nextln: v0 = iconcat $(v0l), $(v0h) -; nextln: $(imm_low=$V) = iconst.i32 0x4444_4444 -; nextln: $(imm_high=$V) = iconst.i32 0x3333_3333 -; nextln: $(v3=$V) = icmp ne $(v2l), $(imm_low) -; nextln: $(v4=$V) = icmp ne $(v2h), $(imm_high) -; nextln: v1 = bor $(v3), $(v4) -; nextln: return v1, $(link) - -function %icmp_imm_sge(i64) -> b1 { -block0(v0: i64): - v1 = icmp_imm sge v0, 0x01020304_05060708 - return v1 -} -; check: block0($(v0l=$V): i32, $(v0h=$V): i32, $(link=$V): i32): -; nextln: $(v2l=$V) -> $(v0l) -; nextln: $(v2h=$V) -> $(v0h) -; nextln: v0 = iconcat $(v0l), $(v0h) -; nextln: $(imm_low=$V) = iconst.i32 0x0506_0708 -; nextln: $(imm_high=$V) = iconst.i32 0x0102_0304 -; nextln: $(v3=$V) = icmp sgt $(v2h), $(imm_high) -; nextln: $(v4=$V) = icmp slt $(v2h), $(imm_high) -; nextln: $(v5=$V) = icmp uge $(v2l), $(imm_low) -; nextln: $(v6=$V) = bnot $v4 -; nextln: $(v7=$V) = band $v6, $v5 -; nextln: v1 = bor $(v3), $(v7) -; nextln: return v1, $(link) diff --git a/cranelift/filetests/filetests/isa/riscv/parse-encoding.clif b/cranelift/filetests/filetests/isa/riscv/parse-encoding.clif deleted file mode 100644 index 21cd828b8a..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/parse-encoding.clif +++ /dev/null @@ -1,36 +0,0 @@ -; Test the parser's support for encoding annotations. -test legalizer -target riscv32 - -function %parse_encoding(i32 [%x5]) -> i32 [%x10] { - ; check: function %parse_encoding(i32 [%x5], i32 link [%x1]) -> i32 [%x10], i32 link [%x1] fast { - - sig0 = (i32 [%x10]) -> i32 [%x10] system_v - ; check: sig0 = (i32 [%x10]) -> i32 [%x10] system_v - - sig1 = (i32 [%x10], i32 [%x11]) -> b1 [%x10] system_v - ; check: sig1 = (i32 [%x10], i32 [%x11]) -> b1 [%x10] system_v - - sig2 = (f32 [%f10], i32 [%x12], i32 [%x13]) -> f64 [%f10] system_v - ; check: sig2 = (f32 [%f10], i32 [%x12], i32 [%x13]) -> f64 [%f10] system_v - - ; Arguments on stack where not necessary - sig3 = (f64 [%f10], i32 [0], i32 [4]) -> f64 [%f10] system_v - ; check: sig3 = (f64 [%f10], i32 [0], i32 [4]) -> f64 [%f10] system_v - - ; Stack argument before register argument - sig4 = (f32 [72], i32 [%x10]) system_v - ; check: sig4 = (f32 [72], i32 [%x10]) system_v - - ; Return value on stack - sig5 = () -> f32 [0] system_v - ; check: sig5 = () -> f32 [0] system_v - - ; function + signature - fn0 = %bar(i32 [%x10]) -> b1 [%x10] system_v - ; check: sig6 = (i32 [%x10]) -> b1 [%x10] system_v - ; nextln: fn0 = %bar sig6 - -block0(v0: i32): - return v0 -} diff --git a/cranelift/filetests/filetests/isa/riscv/regmove.clif b/cranelift/filetests/filetests/isa/riscv/regmove.clif deleted file mode 100644 index f1509e8178..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/regmove.clif +++ /dev/null @@ -1,15 +0,0 @@ -; Test tracking of register moves. -test binemit -target riscv32 - -function %regmoves(i32 link [%x1]) -> i32 link [%x1] { -block0(v9999: i32): - [-,%x10] v1 = iconst.i32 1 - [-,%x7] v2 = iadd_imm v1, 1000 ; bin: 3e850393 - regmove v1, %x10 -> %x11 ; bin: 00050593 - [-,%x7] v3 = iadd_imm v1, 1000 ; bin: 3e858393 - regmove v1, %x11 -> %x10 ; bin: 00058513 - [-,%x7] v4 = iadd_imm v1, 1000 ; bin: 3e850393 - - return v9999 -} diff --git a/cranelift/filetests/filetests/isa/riscv/split-args.clif b/cranelift/filetests/filetests/isa/riscv/split-args.clif deleted file mode 100644 index 9f4b3e9268..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/split-args.clif +++ /dev/null @@ -1,55 +0,0 @@ -; Test the legalization of block arguments that are split. -test legalizer -target riscv32 - -; regex: V=v\d+ - -function %simple(i64, i64) -> i64 { -block0(v1: i64, v2: i64): -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): - jump block1(v1) - ; check: jump block1($v1l, $v1h) - -block1(v3: i64): -; check: block1($(v3l=$V): i32, $(v3h=$V): i32): - v4 = band v3, v2 - ; check: $(v4l=$V) = band $v3l, $v2l - ; check: $(v4h=$V) = band $v3h, $v2h - return v4 - ; check: return $v4l, $v4h, $link -} - -function %multi(i64) -> i64 { -block1(v1: i64): -; check: block1($(v1l=$V): i32, $(v1h=$V): i32, $(link=$V): i32): - jump block2(v1, v1) - ; check: jump block2($v1l, $v1l, $v1h, $v1h) - -block2(v2: i64, v3: i64): -; check: block2($(v2l=$V): i32, $(v3l=$V): i32, $(v2h=$V): i32, $(v3h=$V): i32): - jump block3(v2) - ; check: jump block3($v2l, $v2h) - -block3(v4: i64): -; check: block3($(v4l=$V): i32, $(v4h=$V): i32): - v5 = band v4, v3 - ; check: $(v5l=$V) = band $v4l, $v3l - ; check: $(v5h=$V) = band $v4h, $v3h - return v5 - ; check: return $v5l, $v5h, $link -} - -function %loop(i64, i64) -> i64 { -block0(v1: i64, v2: i64): -; check: block0($(v1l=$V): i32, $(v1h=$V): i32, $(v2l=$V): i32, $(v2h=$V): i32, $(link=$V): i32): - jump block1(v1) - ; check: jump block1($v1l, $v1h) - -block1(v3: i64): -; check: block1($(v3l=$V): i32, $(v3h=$V): i32): - v4 = band v3, v2 - ; check: $(v4l=$V) = band $v3l, $v2l - ; check: $(v4h=$V) = band $v3h, $v2h - jump block1(v4) - ; check: jump block1($v4l, $v4h) -} diff --git a/cranelift/filetests/filetests/isa/riscv/verify-encoding.clif b/cranelift/filetests/filetests/isa/riscv/verify-encoding.clif deleted file mode 100644 index 1d29b86da9..0000000000 --- a/cranelift/filetests/filetests/isa/riscv/verify-encoding.clif +++ /dev/null @@ -1,21 +0,0 @@ -test verifier -target riscv32 - -function %RV32I(i32 link [%x1]) -> i32 link [%x1] { - fn0 = %foo() - -block0(v9999: i32): - ; iconst.i32 needs legalizing, so it should throw a - [R#0,-] v1 = iconst.i32 0xf0f0f0f0f0 ; error: Instruction failed to re-encode - [Iret#19] return v9999 -} - -function %RV32I(i32 link [%x1]) -> i32 link [%x1] { - fn0 = %foo() - -block0(v9999: i32): - v1 = iconst.i32 1 - v2 = iconst.i32 2 - [R#0,-] v3 = iadd v1, v2 ; error: encoding R#00 should be R#0c - [Iret#19] return v9999 -} diff --git a/cranelift/filetests/filetests/parser/instruction_encoding.clif b/cranelift/filetests/filetests/parser/instruction_encoding.clif deleted file mode 100644 index 5386808482..0000000000 --- a/cranelift/filetests/filetests/parser/instruction_encoding.clif +++ /dev/null @@ -1,24 +0,0 @@ -test cat - -target riscv32 - -; regex: WS=[ \t]* - -function %foo(i32, i32) { -block1(v0: i32 [%x8], v1: i32): - [-,-] v2 = iadd v0, v1 - [-] trap heap_oob - [R#1234, %x5, %x11] v6, v7 = iadd_ifcout v2, v0 - [Rshamt#beef, %x25] v8 = ishl_imm v6, 2 -@55 v9 = iadd v8, v7 -@a5 [Iret#5] return v0, v8 -} -; sameln: function %foo(i32, i32) fast { -; nextln: block1(v0: i32 [%x8], v1: i32): -; nextln: [-,-]$WS v2 = iadd v0, v1 -; nextln: [-]$WS trap heap_oob -; nextln: [R#1234,%x5,%x11]$WS v6, v7 = iadd_ifcout v2, v0 -; nextln: [Rshamt#beef,%x25]$WS v8 = ishl_imm v6, 2 -; nextln: @0055 [-,-]$WS v9 = iadd v8, v7 -; nextln: @00a5 [Iret#05]$WS return v0, v8 -; nextln: } diff --git a/cranelift/filetests/src/function_runner.rs b/cranelift/filetests/src/function_runner.rs index 6a7fb5a282..58a321adba 100644 --- a/cranelift/filetests/src/function_runner.rs +++ b/cranelift/filetests/src/function_runner.rs @@ -3,7 +3,7 @@ use core::mem; use cranelift_codegen::binemit::{NullRelocSink, NullStackMapSink, NullTrapSink}; use cranelift_codegen::data_value::DataValue; use cranelift_codegen::ir::{condcodes::IntCC, Function, InstBuilder, Signature}; -use cranelift_codegen::isa::{BackendVariant, TargetIsa}; +use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::{ir, settings, CodegenError, Context}; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_native::builder_with_options; diff --git a/cranelift/src/disasm.rs b/cranelift/src/disasm.rs index da593f8679..cd3b8f66df 100644 --- a/cranelift/src/disasm.rs +++ b/cranelift/src/disasm.rs @@ -111,28 +111,6 @@ cfg_if! { fn get_disassembler(isa: &dyn TargetIsa) -> Result { let cs = match isa.triple().architecture { - Architecture::Riscv32(_) => { - let mut cs = Capstone::new() - .riscv() - .mode(arch::riscv::ArchMode::RiscV32) - .extra_mode(std::iter::once(arch::riscv::ArchExtraMode::RiscVC)) - .build() - .map_err(map_caperr)?; - // See the comment of AArch64 below - cs.set_skipdata(true).map_err(map_caperr)?; - cs - } - Architecture::Riscv64(_) => { - let mut cs = Capstone::new() - .riscv() - .mode(arch::riscv::ArchMode::RiscV64) - .extra_mode(std::iter::once(arch::riscv::ArchExtraMode::RiscVC)) - .build() - .map_err(map_caperr)?; - // See the comment of AArch64 below - cs.set_skipdata(true).map_err(map_caperr)?; - cs - } Architecture::X86_32(_) => Capstone::new() .x86() .mode(arch::x86::ArchMode::Mode32) diff --git a/cranelift/wasm/Cargo.toml b/cranelift/wasm/Cargo.toml index 31e84a517d..cd45a4faac 100644 --- a/cranelift/wasm/Cargo.toml +++ b/cranelift/wasm/Cargo.toml @@ -26,8 +26,7 @@ smallvec = "1.6.1" [dev-dependencies] wat = "1.0.37" target-lexicon = "0.12" -# Enable the riscv feature for cranelift-codegen, as some tests require it -cranelift-codegen = { path = "../codegen", version = "0.77.0", default-features = false, features = ["riscv"] } +cranelift-codegen = { path = "../codegen", version = "0.77.0", default-features = false } [features] default = ["std"] diff --git a/cranelift/wasm/tests/wasm_testsuite.rs b/cranelift/wasm/tests/wasm_testsuite.rs index a2e0f7db7c..a5200c3d71 100644 --- a/cranelift/wasm/tests/wasm_testsuite.rs +++ b/cranelift/wasm/tests/wasm_testsuite.rs @@ -1,12 +1,11 @@ -use cranelift_codegen::isa; +use cranelift_codegen::isa::{CallConv, TargetFrontendConfig}; use cranelift_codegen::print_errors::pretty_verifier_error; use cranelift_codegen::settings::{self, Flags}; use cranelift_codegen::verifier; use cranelift_wasm::{translate_module, DummyEnvironment, FuncIndex, ReturnMode}; use std::fs; use std::path::Path; -use std::str::FromStr; -use target_lexicon::triple; +use target_lexicon::PointerWidth; #[test] fn testsuite() { @@ -52,11 +51,15 @@ fn use_name_section() { ) .unwrap(); - let flags = Flags::new(settings::builder()); - let triple = triple!("riscv64"); - let isa = isa::lookup(triple).unwrap().finish(flags.clone()); let return_mode = ReturnMode::NormalReturns; - let mut dummy_environ = DummyEnvironment::new(isa.frontend_config(), return_mode, false); + let mut dummy_environ = DummyEnvironment::new( + TargetFrontendConfig { + default_call_conv: CallConv::SystemV, + pointer_width: PointerWidth::U32, + }, + return_mode, + false, + ); translate_module(data.as_ref(), &mut dummy_environ).unwrap(); @@ -82,15 +85,20 @@ fn read_module(path: &Path) -> Vec { } fn handle_module(data: Vec, flags: &Flags, return_mode: ReturnMode) { - let triple = triple!("riscv64"); - let isa = isa::lookup(triple).unwrap().finish(flags.clone()); - let mut dummy_environ = DummyEnvironment::new(isa.frontend_config(), return_mode, false); + let mut dummy_environ = DummyEnvironment::new( + TargetFrontendConfig { + default_call_conv: CallConv::SystemV, + pointer_width: PointerWidth::U64, + }, + return_mode, + false, + ); translate_module(&data, &mut dummy_environ).unwrap(); for func in dummy_environ.info.function_bodies.values() { - verifier::verify_function(func, &*isa) - .map_err(|errors| panic!("{}", pretty_verifier_error(func, Some(&*isa), None, errors))) + verifier::verify_function(func, flags) + .map_err(|errors| panic!("{}", pretty_verifier_error(func, None, None, errors))) .unwrap(); } } @@ -168,10 +176,14 @@ fn reachability_is_correct() { for (return_mode, wat, expected_reachability) in tests { println!("testing wat:\n{}", wat); - let flags = Flags::new(settings::builder()); - let triple = triple!("riscv64"); - let isa = isa::lookup(triple).unwrap().finish(flags.clone()); - let mut env = DummyEnvironment::new(isa.frontend_config(), return_mode, false); + let mut env = DummyEnvironment::new( + TargetFrontendConfig { + default_call_conv: CallConv::SystemV, + pointer_width: PointerWidth::U64, + }, + return_mode, + false, + ); env.test_expected_reachability(expected_reachability); let data = wat::parse_str(wat).unwrap(); translate_module(data.as_ref(), &mut env).unwrap();