diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 0211d7b336736..d7c27059aaea2 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -66,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { for (abi_name, abi_span) in &asm.clobber_abis { match asm::InlineAsmClobberAbi::parse( asm_arch, + self.sess.relocation_model(), &self.sess.target_features, &self.sess.target, *abi_name, @@ -134,6 +135,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch { asm::InlineAsmReg::parse( asm_arch, + sess.relocation_model(), &sess.target_features, &sess.target, is_clobber, diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index c242c75ed18ff..10c2f06faf3ee 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -182,7 +182,12 @@ struct InlineAssemblyGenerator<'a, 'tcx> { impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { let sess = self.tcx.sess; - let map = allocatable_registers(self.arch, &sess.target_features, &sess.target); + let map = allocatable_registers( + self.arch, + sess.relocation_model(), + &sess.target_features, + &sess.target, + ); let mut allocated = FxHashMap::<_, (bool, bool)>::default(); let mut regs = vec![None; self.operands.len()]; @@ -315,6 +320,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { // Allocate stack slots for saving clobbered registers let abi_clobber = InlineAsmClobberAbi::parse( self.arch, + self.tcx.sess.relocation_model(), &self.tcx.sess.target_features, &self.tcx.sess.target, sym::C, diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index f31b0ee592e9c..77166c89735e4 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -36,7 +36,6 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ // #[target_feature]. ("thumb-mode", Some(sym::arm_target_feature)), ("thumb2", Some(sym::arm_target_feature)), - ("reserve-r9", Some(sym::arm_target_feature)), ]; const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c746255e95e18..6767593bbc51a 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1122,7 +1122,6 @@ symbols! { repr_packed, repr_simd, repr_transparent, - reserved_r9: "reserved-r9", residual, result, rhs, diff --git a/compiler/rustc_target/src/asm/aarch64.rs b/compiler/rustc_target/src/asm/aarch64.rs index d184ad4e78ae5..b4a1b5e91430c 100644 --- a/compiler/rustc_target/src/asm/aarch64.rs +++ b/compiler/rustc_target/src/asm/aarch64.rs @@ -1,5 +1,5 @@ use super::{InlineAsmArch, InlineAsmType}; -use crate::spec::Target; +use crate::spec::{Target, RelocModel}; use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; @@ -75,6 +75,7 @@ impl AArch64InlineAsmRegClass { pub fn reserved_x18( _arch: InlineAsmArch, + _reloc_model: RelocModel, _target_features: &FxHashSet, target: &Target, _is_clobber: bool, diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index b2d5bb3736afd..88f2d3f80d2c3 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -1,5 +1,5 @@ use super::{InlineAsmArch, InlineAsmType}; -use crate::spec::Target; +use crate::spec::{RelocModel, Target}; use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; @@ -67,11 +67,12 @@ fn frame_pointer_is_r7(target_features: &FxHashSet, target: &Target) -> fn frame_pointer_r11( arch: InlineAsmArch, + reloc_model: RelocModel, target_features: &FxHashSet, target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { - not_thumb1(arch, target_features, target, is_clobber)?; + not_thumb1(arch, reloc_model, target_features, target, is_clobber)?; if !frame_pointer_is_r7(target_features, target) { Err("the frame pointer (r11) cannot be used as an operand for inline asm") @@ -82,6 +83,7 @@ fn frame_pointer_r11( fn frame_pointer_r7( _arch: InlineAsmArch, + _reloc_model: RelocModel, target_features: &FxHashSet, target: &Target, _is_clobber: bool, @@ -95,6 +97,7 @@ fn frame_pointer_r7( fn not_thumb1( _arch: InlineAsmArch, + _reloc_model: RelocModel, target_features: &FxHashSet, _target: &Target, is_clobber: bool, @@ -111,18 +114,18 @@ fn not_thumb1( fn reserved_r9( arch: InlineAsmArch, + reloc_model: RelocModel, target_features: &FxHashSet, target: &Target, is_clobber: bool, ) -> Result<(), &'static str> { - not_thumb1(arch, target_features, target, is_clobber)?; + not_thumb1(arch, reloc_model, target_features, target, is_clobber)?; - // We detect this using the reserved-r9 feature instead of using the target - // because the relocation model can be changed with compiler options. - if target_features.contains(&sym::reserved_r9) { - Err("the RWPI static base register (r9) cannot be used as an operand for inline asm") - } else { - Ok(()) + match reloc_model { + RelocModel::Rwpi | RelocModel::RopiRwpi => { + Err("the RWPI static base register (r9) cannot be used as an operand for inline asm") + } + _ => Ok(()), } } diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index fd95b0338a6e1..1bf4747a97050 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -1,5 +1,5 @@ -use crate::abi::Size; use crate::spec::Target; +use crate::{abi::Size, spec::RelocModel}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; @@ -81,6 +81,7 @@ macro_rules! def_regs { pub fn parse( _arch: super::InlineAsmArch, + _reloc_model: crate::spec::RelocModel, _target_features: &rustc_data_structures::fx::FxHashSet, _target: &crate::spec::Target, _is_clobber: bool, @@ -89,7 +90,7 @@ macro_rules! def_regs { match name { $( $($alias)|* | $reg_name => { - $($filter(_arch, _target_features, _target, _is_clobber)?;)? + $($filter(_arch, _reloc_model, _target_features, _target, _is_clobber)?;)? Ok(Self::$reg) } )* @@ -103,6 +104,7 @@ macro_rules! def_regs { pub(super) fn fill_reg_map( _arch: super::InlineAsmArch, + _reloc_model: crate::spec::RelocModel, _target_features: &rustc_data_structures::fx::FxHashSet, _target: &crate::spec::Target, _map: &mut rustc_data_structures::fx::FxHashMap< @@ -113,7 +115,7 @@ macro_rules! def_regs { #[allow(unused_imports)] use super::{InlineAsmReg, InlineAsmRegClass}; $( - if $($filter(_arch, _target_features, _target, false).is_ok() &&)? true { + if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)? true { if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) { set.insert(InlineAsmReg::$arch($arch_reg::$reg)); } @@ -297,6 +299,7 @@ impl InlineAsmReg { pub fn parse( arch: InlineAsmArch, + reloc_model: RelocModel, target_features: &FxHashSet, target: &Target, is_clobber: bool, @@ -307,75 +310,75 @@ impl InlineAsmReg { let name = name.as_str(); Ok(match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { - Self::X86(X86InlineAsmReg::parse(arch, target_features, target, is_clobber, name)?) + Self::X86(X86InlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?) } InlineAsmArch::Arm => { - Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?) + Self::Arm(ArmInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?) } InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => Self::RiscV( - RiscVInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?, + RiscVInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?, ), InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => Self::PowerPC( - PowerPCInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?, + PowerPCInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?, ), InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::Mips | InlineAsmArch::Mips64 => Self::Mips(MipsInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => Self::Wasm(WasmInlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, )?), InlineAsmArch::Bpf => { - Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?) + Self::Bpf(BpfInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?) } InlineAsmArch::Avr => { - Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?) + Self::Avr(AvrInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?) } InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse( arch, - target_features, + reloc_model,target_features, target, is_clobber, name, @@ -749,78 +752,79 @@ impl fmt::Display for InlineAsmType { // falling back to an external assembler. pub fn allocatable_registers( arch: InlineAsmArch, + reloc_model: RelocModel, target_features: &FxHashSet, target: &crate::spec::Target, ) -> FxHashMap> { match arch { InlineAsmArch::X86 | InlineAsmArch::X86_64 => { let mut map = x86::regclass_map(); - x86::fill_reg_map(arch, target_features, target, &mut map); + x86::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Arm => { let mut map = arm::regclass_map(); - arm::fill_reg_map(arch, target_features, target, &mut map); + arm::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::AArch64 => { let mut map = aarch64::regclass_map(); - aarch64::fill_reg_map(arch, target_features, target, &mut map); + aarch64::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { let mut map = riscv::regclass_map(); - riscv::fill_reg_map(arch, target_features, target, &mut map); + riscv::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Nvptx64 => { let mut map = nvptx::regclass_map(); - nvptx::fill_reg_map(arch, target_features, target, &mut map); + nvptx::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => { let mut map = powerpc::regclass_map(); - powerpc::fill_reg_map(arch, target_features, target, &mut map); + powerpc::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Hexagon => { let mut map = hexagon::regclass_map(); - hexagon::fill_reg_map(arch, target_features, target, &mut map); + hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { let mut map = mips::regclass_map(); - mips::fill_reg_map(arch, target_features, target, &mut map); + mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::S390x => { let mut map = s390x::regclass_map(); - s390x::fill_reg_map(arch, target_features, target, &mut map); + s390x::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::SpirV => { let mut map = spirv::regclass_map(); - spirv::fill_reg_map(arch, target_features, target, &mut map); + spirv::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => { let mut map = wasm::regclass_map(); - wasm::fill_reg_map(arch, target_features, target, &mut map); + wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Bpf => { let mut map = bpf::regclass_map(); - bpf::fill_reg_map(arch, target_features, target, &mut map); + bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Avr => { let mut map = avr::regclass_map(); - avr::fill_reg_map(arch, target_features, target, &mut map); + avr::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } InlineAsmArch::Msp430 => { let mut map = msp430::regclass_map(); - msp430::fill_reg_map(arch, target_features, target, &mut map); + msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } } @@ -853,6 +857,7 @@ impl InlineAsmClobberAbi { /// clobber ABIs for the target. pub fn parse( arch: InlineAsmArch, + reloc_model: RelocModel, target_features: &FxHashSet, target: &Target, name: Symbol, @@ -878,7 +883,7 @@ impl InlineAsmClobberAbi { }, InlineAsmArch::AArch64 => match name { "C" | "system" | "efiapi" => { - Ok(if aarch64::reserved_x18(arch, target_features, target, true).is_err() { + Ok(if aarch64::reserved_x18(arch, reloc_model, target_features, target, true).is_err() { InlineAsmClobberAbi::AArch64NoX18 } else { InlineAsmClobberAbi::AArch64 diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs index e145ba8a16e64..65ce69cb5c0cd 100644 --- a/compiler/rustc_target/src/asm/riscv.rs +++ b/compiler/rustc_target/src/asm/riscv.rs @@ -1,5 +1,5 @@ use super::{InlineAsmArch, InlineAsmType}; -use crate::spec::Target; +use crate::spec::{Target, RelocModel}; use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::{sym, Symbol}; @@ -54,6 +54,7 @@ impl RiscVInlineAsmRegClass { fn not_e( _arch: InlineAsmArch, + _reloc_model: RelocModel, target_features: &FxHashSet, _target: &Target, _is_clobber: bool, diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs index a8ee80ec4ea27..ac6f39f1c9559 100644 --- a/compiler/rustc_target/src/asm/x86.rs +++ b/compiler/rustc_target/src/asm/x86.rs @@ -1,5 +1,5 @@ use super::{InlineAsmArch, InlineAsmType}; -use crate::spec::Target; +use crate::spec::{Target, RelocModel}; use rustc_data_structures::stable_set::FxHashSet; use rustc_macros::HashStable_Generic; use rustc_span::Symbol; @@ -139,6 +139,7 @@ impl X86InlineAsmRegClass { fn x86_64_only( arch: InlineAsmArch, + _reloc_model: RelocModel, _target_features: &FxHashSet, _target: &Target, _is_clobber: bool, @@ -152,6 +153,7 @@ fn x86_64_only( fn high_byte( arch: InlineAsmArch, + _reloc_model: RelocModel, _target_features: &FxHashSet, _target: &Target, _is_clobber: bool, @@ -164,6 +166,7 @@ fn high_byte( fn rbx_reserved( arch: InlineAsmArch, + _reloc_model: RelocModel, _target_features: &FxHashSet, _target: &Target, _is_clobber: bool, @@ -179,6 +182,7 @@ fn rbx_reserved( fn esi_reserved( arch: InlineAsmArch, + _reloc_model: RelocModel, _target_features: &FxHashSet, _target: &Target, _is_clobber: bool,