Skip to content

Commit 1ceb104

Browse files
committed
On ARM, use relocation_model to detect whether r9 should be reserved
The previous approach of checking for the reserve-r9 target feature didn't actually work because LLVM only sets this feature very late when initializing the per-function subtarget.
1 parent 2e8a766 commit 1ceb104

File tree

9 files changed

+67
-47
lines changed

9 files changed

+67
-47
lines changed

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6666
for (abi_name, abi_span) in &asm.clobber_abis {
6767
match asm::InlineAsmClobberAbi::parse(
6868
asm_arch,
69+
self.sess.relocation_model(),
6970
&self.sess.target_features,
7071
&self.sess.target,
7172
*abi_name,
@@ -134,6 +135,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
134135
asm::InlineAsmRegOrRegClass::Reg(if let Some(asm_arch) = asm_arch {
135136
asm::InlineAsmReg::parse(
136137
asm_arch,
138+
sess.relocation_model(),
137139
&sess.target_features,
138140
&sess.target,
139141
is_clobber,

compiler/rustc_codegen_cranelift/src/inline_asm.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,12 @@ struct InlineAssemblyGenerator<'a, 'tcx> {
182182
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
183183
fn allocate_registers(&mut self) {
184184
let sess = self.tcx.sess;
185-
let map = allocatable_registers(self.arch, &sess.target_features, &sess.target);
185+
let map = allocatable_registers(
186+
self.arch,
187+
sess.relocation_model(),
188+
&sess.target_features,
189+
&sess.target,
190+
);
186191
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
187192
let mut regs = vec![None; self.operands.len()];
188193

@@ -315,6 +320,7 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
315320
// Allocate stack slots for saving clobbered registers
316321
let abi_clobber = InlineAsmClobberAbi::parse(
317322
self.arch,
323+
self.tcx.sess.relocation_model(),
318324
&self.tcx.sess.target_features,
319325
&self.tcx.sess.target,
320326
sym::C,

compiler/rustc_codegen_ssa/src/target_features.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
3636
// #[target_feature].
3737
("thumb-mode", Some(sym::arm_target_feature)),
3838
("thumb2", Some(sym::arm_target_feature)),
39-
("reserve-r9", Some(sym::arm_target_feature)),
4039
];
4140

4241
const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[

compiler/rustc_span/src/symbol.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,6 @@ symbols! {
11221122
repr_packed,
11231123
repr_simd,
11241124
repr_transparent,
1125-
reserved_r9: "reserved-r9",
11261125
residual,
11271126
result,
11281127
rhs,

compiler/rustc_target/src/asm/aarch64.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{InlineAsmArch, InlineAsmType};
2-
use crate::spec::Target;
2+
use crate::spec::{Target, RelocModel};
33
use rustc_data_structures::stable_set::FxHashSet;
44
use rustc_macros::HashStable_Generic;
55
use rustc_span::Symbol;
@@ -75,6 +75,7 @@ impl AArch64InlineAsmRegClass {
7575

7676
pub fn reserved_x18(
7777
_arch: InlineAsmArch,
78+
_reloc_model: RelocModel,
7879
_target_features: &FxHashSet<Symbol>,
7980
target: &Target,
8081
_is_clobber: bool,

compiler/rustc_target/src/asm/arm.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{InlineAsmArch, InlineAsmType};
2-
use crate::spec::Target;
2+
use crate::spec::{RelocModel, Target};
33
use rustc_data_structures::stable_set::FxHashSet;
44
use rustc_macros::HashStable_Generic;
55
use rustc_span::{sym, Symbol};
@@ -67,11 +67,12 @@ fn frame_pointer_is_r7(target_features: &FxHashSet<Symbol>, target: &Target) ->
6767

6868
fn frame_pointer_r11(
6969
arch: InlineAsmArch,
70+
reloc_model: RelocModel,
7071
target_features: &FxHashSet<Symbol>,
7172
target: &Target,
7273
is_clobber: bool,
7374
) -> Result<(), &'static str> {
74-
not_thumb1(arch, target_features, target, is_clobber)?;
75+
not_thumb1(arch, reloc_model, target_features, target, is_clobber)?;
7576

7677
if !frame_pointer_is_r7(target_features, target) {
7778
Err("the frame pointer (r11) cannot be used as an operand for inline asm")
@@ -82,6 +83,7 @@ fn frame_pointer_r11(
8283

8384
fn frame_pointer_r7(
8485
_arch: InlineAsmArch,
86+
_reloc_model: RelocModel,
8587
target_features: &FxHashSet<Symbol>,
8688
target: &Target,
8789
_is_clobber: bool,
@@ -95,6 +97,7 @@ fn frame_pointer_r7(
9597

9698
fn not_thumb1(
9799
_arch: InlineAsmArch,
100+
_reloc_model: RelocModel,
98101
target_features: &FxHashSet<Symbol>,
99102
_target: &Target,
100103
is_clobber: bool,
@@ -111,18 +114,18 @@ fn not_thumb1(
111114

112115
fn reserved_r9(
113116
arch: InlineAsmArch,
117+
reloc_model: RelocModel,
114118
target_features: &FxHashSet<Symbol>,
115119
target: &Target,
116120
is_clobber: bool,
117121
) -> Result<(), &'static str> {
118-
not_thumb1(arch, target_features, target, is_clobber)?;
122+
not_thumb1(arch, reloc_model, target_features, target, is_clobber)?;
119123

120-
// We detect this using the reserved-r9 feature instead of using the target
121-
// because the relocation model can be changed with compiler options.
122-
if target_features.contains(&sym::reserved_r9) {
123-
Err("the RWPI static base register (r9) cannot be used as an operand for inline asm")
124-
} else {
125-
Ok(())
124+
match reloc_model {
125+
RelocModel::Rwpi | RelocModel::RopiRwpi => {
126+
Err("the RWPI static base register (r9) cannot be used as an operand for inline asm")
127+
}
128+
_ => Ok(()),
126129
}
127130
}
128131

compiler/rustc_target/src/asm/mod.rs

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::abi::Size;
21
use crate::spec::Target;
2+
use crate::{abi::Size, spec::RelocModel};
33
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
44
use rustc_macros::HashStable_Generic;
55
use rustc_span::Symbol;
@@ -81,6 +81,7 @@ macro_rules! def_regs {
8181

8282
pub fn parse(
8383
_arch: super::InlineAsmArch,
84+
_reloc_model: crate::spec::RelocModel,
8485
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
8586
_target: &crate::spec::Target,
8687
_is_clobber: bool,
@@ -89,7 +90,7 @@ macro_rules! def_regs {
8990
match name {
9091
$(
9192
$($alias)|* | $reg_name => {
92-
$($filter(_arch, _target_features, _target, _is_clobber)?;)?
93+
$($filter(_arch, _reloc_model, _target_features, _target, _is_clobber)?;)?
9394
Ok(Self::$reg)
9495
}
9596
)*
@@ -103,6 +104,7 @@ macro_rules! def_regs {
103104

104105
pub(super) fn fill_reg_map(
105106
_arch: super::InlineAsmArch,
107+
_reloc_model: crate::spec::RelocModel,
106108
_target_features: &rustc_data_structures::fx::FxHashSet<Symbol>,
107109
_target: &crate::spec::Target,
108110
_map: &mut rustc_data_structures::fx::FxHashMap<
@@ -113,7 +115,7 @@ macro_rules! def_regs {
113115
#[allow(unused_imports)]
114116
use super::{InlineAsmReg, InlineAsmRegClass};
115117
$(
116-
if $($filter(_arch, _target_features, _target, false).is_ok() &&)? true {
118+
if $($filter(_arch, _reloc_model, _target_features, _target, false).is_ok() &&)? true {
117119
if let Some(set) = _map.get_mut(&InlineAsmRegClass::$arch($arch_regclass::$class)) {
118120
set.insert(InlineAsmReg::$arch($arch_reg::$reg));
119121
}
@@ -297,6 +299,7 @@ impl InlineAsmReg {
297299

298300
pub fn parse(
299301
arch: InlineAsmArch,
302+
reloc_model: RelocModel,
300303
target_features: &FxHashSet<Symbol>,
301304
target: &Target,
302305
is_clobber: bool,
@@ -307,75 +310,75 @@ impl InlineAsmReg {
307310
let name = name.as_str();
308311
Ok(match arch {
309312
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
310-
Self::X86(X86InlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
313+
Self::X86(X86InlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?)
311314
}
312315
InlineAsmArch::Arm => {
313-
Self::Arm(ArmInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
316+
Self::Arm(ArmInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?)
314317
}
315318
InlineAsmArch::AArch64 => Self::AArch64(AArch64InlineAsmReg::parse(
316319
arch,
317-
target_features,
320+
reloc_model,target_features,
318321
target,
319322
is_clobber,
320323
name,
321324
)?),
322325
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => Self::RiscV(
323-
RiscVInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
326+
RiscVInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?,
324327
),
325328
InlineAsmArch::Nvptx64 => Self::Nvptx(NvptxInlineAsmReg::parse(
326329
arch,
327-
target_features,
330+
reloc_model,target_features,
328331
target,
329332
is_clobber,
330333
name,
331334
)?),
332335
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => Self::PowerPC(
333-
PowerPCInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?,
336+
PowerPCInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?,
334337
),
335338
InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(
336339
arch,
337-
target_features,
340+
reloc_model,target_features,
338341
target,
339342
is_clobber,
340343
name,
341344
)?),
342345
InlineAsmArch::Mips | InlineAsmArch::Mips64 => Self::Mips(MipsInlineAsmReg::parse(
343346
arch,
344-
target_features,
347+
reloc_model,target_features,
345348
target,
346349
is_clobber,
347350
name,
348351
)?),
349352
InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(
350353
arch,
351-
target_features,
354+
reloc_model,target_features,
352355
target,
353356
is_clobber,
354357
name,
355358
)?),
356359
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(
357360
arch,
358-
target_features,
361+
reloc_model,target_features,
359362
target,
360363
is_clobber,
361364
name,
362365
)?),
363366
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => Self::Wasm(WasmInlineAsmReg::parse(
364367
arch,
365-
target_features,
368+
reloc_model,target_features,
366369
target,
367370
is_clobber,
368371
name,
369372
)?),
370373
InlineAsmArch::Bpf => {
371-
Self::Bpf(BpfInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
374+
Self::Bpf(BpfInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?)
372375
}
373376
InlineAsmArch::Avr => {
374-
Self::Avr(AvrInlineAsmReg::parse(arch, target_features, target, is_clobber, name)?)
377+
Self::Avr(AvrInlineAsmReg::parse(arch, reloc_model,target_features, target, is_clobber, name)?)
375378
}
376379
InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(
377380
arch,
378-
target_features,
381+
reloc_model,target_features,
379382
target,
380383
is_clobber,
381384
name,
@@ -749,78 +752,79 @@ impl fmt::Display for InlineAsmType {
749752
// falling back to an external assembler.
750753
pub fn allocatable_registers(
751754
arch: InlineAsmArch,
755+
reloc_model: RelocModel,
752756
target_features: &FxHashSet<Symbol>,
753757
target: &crate::spec::Target,
754758
) -> FxHashMap<InlineAsmRegClass, FxHashSet<InlineAsmReg>> {
755759
match arch {
756760
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
757761
let mut map = x86::regclass_map();
758-
x86::fill_reg_map(arch, target_features, target, &mut map);
762+
x86::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
759763
map
760764
}
761765
InlineAsmArch::Arm => {
762766
let mut map = arm::regclass_map();
763-
arm::fill_reg_map(arch, target_features, target, &mut map);
767+
arm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
764768
map
765769
}
766770
InlineAsmArch::AArch64 => {
767771
let mut map = aarch64::regclass_map();
768-
aarch64::fill_reg_map(arch, target_features, target, &mut map);
772+
aarch64::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
769773
map
770774
}
771775
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
772776
let mut map = riscv::regclass_map();
773-
riscv::fill_reg_map(arch, target_features, target, &mut map);
777+
riscv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
774778
map
775779
}
776780
InlineAsmArch::Nvptx64 => {
777781
let mut map = nvptx::regclass_map();
778-
nvptx::fill_reg_map(arch, target_features, target, &mut map);
782+
nvptx::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
779783
map
780784
}
781785
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
782786
let mut map = powerpc::regclass_map();
783-
powerpc::fill_reg_map(arch, target_features, target, &mut map);
787+
powerpc::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
784788
map
785789
}
786790
InlineAsmArch::Hexagon => {
787791
let mut map = hexagon::regclass_map();
788-
hexagon::fill_reg_map(arch, target_features, target, &mut map);
792+
hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
789793
map
790794
}
791795
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
792796
let mut map = mips::regclass_map();
793-
mips::fill_reg_map(arch, target_features, target, &mut map);
797+
mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
794798
map
795799
}
796800
InlineAsmArch::S390x => {
797801
let mut map = s390x::regclass_map();
798-
s390x::fill_reg_map(arch, target_features, target, &mut map);
802+
s390x::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
799803
map
800804
}
801805
InlineAsmArch::SpirV => {
802806
let mut map = spirv::regclass_map();
803-
spirv::fill_reg_map(arch, target_features, target, &mut map);
807+
spirv::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
804808
map
805809
}
806810
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
807811
let mut map = wasm::regclass_map();
808-
wasm::fill_reg_map(arch, target_features, target, &mut map);
812+
wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
809813
map
810814
}
811815
InlineAsmArch::Bpf => {
812816
let mut map = bpf::regclass_map();
813-
bpf::fill_reg_map(arch, target_features, target, &mut map);
817+
bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
814818
map
815819
}
816820
InlineAsmArch::Avr => {
817821
let mut map = avr::regclass_map();
818-
avr::fill_reg_map(arch, target_features, target, &mut map);
822+
avr::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
819823
map
820824
}
821825
InlineAsmArch::Msp430 => {
822826
let mut map = msp430::regclass_map();
823-
msp430::fill_reg_map(arch, target_features, target, &mut map);
827+
msp430::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
824828
map
825829
}
826830
}
@@ -853,6 +857,7 @@ impl InlineAsmClobberAbi {
853857
/// clobber ABIs for the target.
854858
pub fn parse(
855859
arch: InlineAsmArch,
860+
reloc_model: RelocModel,
856861
target_features: &FxHashSet<Symbol>,
857862
target: &Target,
858863
name: Symbol,
@@ -878,7 +883,7 @@ impl InlineAsmClobberAbi {
878883
},
879884
InlineAsmArch::AArch64 => match name {
880885
"C" | "system" | "efiapi" => {
881-
Ok(if aarch64::reserved_x18(arch, target_features, target, true).is_err() {
886+
Ok(if aarch64::reserved_x18(arch, reloc_model, target_features, target, true).is_err() {
882887
InlineAsmClobberAbi::AArch64NoX18
883888
} else {
884889
InlineAsmClobberAbi::AArch64

compiler/rustc_target/src/asm/riscv.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{InlineAsmArch, InlineAsmType};
2-
use crate::spec::Target;
2+
use crate::spec::{Target, RelocModel};
33
use rustc_data_structures::stable_set::FxHashSet;
44
use rustc_macros::HashStable_Generic;
55
use rustc_span::{sym, Symbol};
@@ -54,6 +54,7 @@ impl RiscVInlineAsmRegClass {
5454

5555
fn not_e(
5656
_arch: InlineAsmArch,
57+
_reloc_model: RelocModel,
5758
target_features: &FxHashSet<Symbol>,
5859
_target: &Target,
5960
_is_clobber: bool,

0 commit comments

Comments
 (0)