From 908f300dd7878f6bcd0f5479c2db680067aec3d8 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 11 Nov 2021 12:42:38 +0000 Subject: [PATCH] Remove the reg_thumb register class for asm! on ARM Also restricts r8-r14 from being used on Thumb1 targets as per #90736. --- compiler/rustc_codegen_gcc/src/asm.rs | 7 +--- compiler/rustc_codegen_llvm/src/asm.rs | 7 +--- .../rustc_codegen_ssa/src/target_features.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 - compiler/rustc_target/src/asm/arm.rs | 37 ++++++++++++------- .../unstable-book/src/library-features/asm.md | 6 +-- src/test/assembly/asm/arm-modifiers.rs | 6 --- src/test/assembly/asm/arm-types.rs | 30 --------------- 8 files changed, 30 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 7481b5db755e7..10edcf36955da 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -568,7 +568,6 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => unimplemented!(), InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => unimplemented!(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(), - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => unimplemented!(), @@ -628,8 +627,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { unimplemented!() } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(), + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg)=> cx.type_i32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) @@ -737,8 +735,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => { unimplemented!() } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => unimplemented!(), + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => unimplemented!(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => unimplemented!(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 90d3c0fb2f173..f3c3a17490811 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -632,7 +632,6 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>) unreachable!("clobber-only") } InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r", - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => "l", InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t", @@ -703,8 +702,7 @@ fn modifier_to_llvm( InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { unreachable!("clobber-only") } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => None, + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None, InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None, InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) @@ -785,8 +783,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => { unreachable!("clobber-only") } - InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) - | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg_thumb) => cx.type_i32(), + InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(), InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index b4420df5df417..ba72e3cfafce2 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -35,6 +35,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ // since it should be enabled per-function using #[instruction_set], not // #[target_feature]. ("thumb-mode", Some(sym::arm_target_feature)), + ("thumb2", 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 a4280047c7068..2a7af9cf67ae3 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1057,7 +1057,6 @@ symbols! { reg_nonzero, reg_pair, reg_ptr, - reg_thumb, reg_upper, register_attr, register_tool, diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 4c323fc35d643..4eeb7fcc71bce 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -6,7 +6,6 @@ use std::fmt; def_reg_class! { Arm ArmInlineAsmRegClass { reg, - reg_thumb, sreg, sreg_low16, dreg, @@ -47,7 +46,7 @@ impl ArmInlineAsmRegClass { _arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option<&'static str>)] { match self { - Self::reg | Self::reg_thumb => types! { _: I8, I16, I32, F32; }, + Self::reg => types! { _: I8, I16, I32, F32; }, Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; }, Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! { "vfp2": I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2); @@ -88,20 +87,32 @@ fn frame_pointer_r7( } } +fn not_thumb1( + _arch: InlineAsmArch, + mut has_feature: impl FnMut(&str) -> bool, + _target: &Target, +) -> Result<(), &'static str> { + if has_feature("thumb-mode") && !has_feature("thumb2") { + Err("high registers (r8+) cannot be used in Thumb-1 code") + } else { + Ok(()) + } +} + def_regs! { Arm ArmInlineAsmReg ArmInlineAsmRegClass { - r0: reg, reg_thumb = ["r0", "a1"], - r1: reg, reg_thumb = ["r1", "a2"], - r2: reg, reg_thumb = ["r2", "a3"], - r3: reg, reg_thumb = ["r3", "a4"], - r4: reg, reg_thumb = ["r4", "v1"], - r5: reg, reg_thumb = ["r5", "v2"], - r7: reg, reg_thumb = ["r7", "v4"] % frame_pointer_r7, - r8: reg = ["r8", "v5"], - r10: reg = ["r10", "sl"], + r0: reg = ["r0", "a1"], + r1: reg = ["r1", "a2"], + r2: reg = ["r2", "a3"], + r3: reg = ["r3", "a4"], + r4: reg = ["r4", "v1"], + r5: reg = ["r5", "v2"], + r7: reg = ["r7", "v4"] % frame_pointer_r7, + r8: reg = ["r8", "v5"] % not_thumb1, + r10: reg = ["r10", "sl"] % not_thumb1, r11: reg = ["r11", "fp"] % frame_pointer_r11, - r12: reg = ["r12", "ip"], - r14: reg = ["r14", "lr"], + r12: reg = ["r12", "ip"] % not_thumb1, + r14: reg = ["r14", "lr"] % not_thumb1, s0: sreg, sreg_low16 = ["s0"], s1: sreg, sreg_low16 = ["s1"], s2: sreg, sreg_low16 = ["s2"], diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md index dffa3a8b80f0f..59987cccde673 100644 --- a/src/doc/unstable-book/src/library-features/asm.md +++ b/src/doc/unstable-book/src/library-features/asm.md @@ -564,12 +564,8 @@ Here is the list of currently supported register classes: | AArch64 | `vreg` | `v[0-31]` | `w` | | AArch64 | `vreg_low16` | `v[0-15]` | `x` | | AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers | -| ARM (ARM) | `reg` | `r[0-12]`, `r14` | `r` | -| ARM (Thumb2) | `reg` | `r[0-12]`, `r14` | `r` | +| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` | | ARM (Thumb1) | `reg` | `r[0-7]` | `r` | -| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` | -| ARM (Thumb2) | `reg_thumb` | `r[0-7]` | `l` | -| ARM (Thumb1) | `reg_thumb` | `r[0-7]` | `l` | | ARM | `sreg` | `s[0-31]` | `t` | | ARM | `sreg_low16` | `s[0-15]` | `x` | | ARM | `dreg` | `d[0-31]` | `w` | diff --git a/src/test/assembly/asm/arm-modifiers.rs b/src/test/assembly/asm/arm-modifiers.rs index a6985a3bf5c6b..88ffeaecfecb6 100644 --- a/src/test/assembly/asm/arm-modifiers.rs +++ b/src/test/assembly/asm/arm-modifiers.rs @@ -59,12 +59,6 @@ macro_rules! check { // CHECK: @NO_APP check!(reg "" reg i32 "mov"); -// CHECK-LABEL: reg_thumb: -// CHECK: @APP -// CHECK: mov r0, r0 -// CHECK: @NO_APP -check!(reg_thumb "" reg_thumb i32 "mov"); - // CHECK-LABEL: sreg: // CHECK: @APP // CHECK: vmov.f32 s0, s0 diff --git a/src/test/assembly/asm/arm-types.rs b/src/test/assembly/asm/arm-types.rs index 0c57b1fc4782d..5ac1af6afd67d 100644 --- a/src/test/assembly/asm/arm-types.rs +++ b/src/test/assembly/asm/arm-types.rs @@ -163,36 +163,6 @@ check!(reg_f32 f32 reg "mov"); // CHECK: @NO_APP check!(reg_ptr ptr reg "mov"); -// CHECK-LABEL: reg_thumb_i8: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_thumb_i8 i8 reg_thumb "mov"); - -// CHECK-LABEL: reg_thumb_i16: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_thumb_i16 i16 reg_thumb "mov"); - -// CHECK-LABEL: reg_thumb_i32: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_thumb_i32 i32 reg_thumb "mov"); - -// CHECK-LABEL: reg_thumb_f32: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_thumb_f32 f32 reg_thumb "mov"); - -// CHECK-LABEL: reg_thumb_ptr: -// CHECK: @APP -// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}} -// CHECK: @NO_APP -check!(reg_thumb_ptr ptr reg_thumb "mov"); - // CHECK-LABEL: sreg_i32: // CHECK: @APP // CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}