Index: clang/docs/ClangCommandLineReference.rst =================================================================== --- clang/docs/ClangCommandLineReference.rst +++ clang/docs/ClangCommandLineReference.rst @@ -2296,6 +2296,10 @@ Reserve the x18 register (AArch64 only) +.. option:: -ffixed-x20 + +Reserve the x20 register (AArch64 only) + .. option:: -mfix-cortex-a53-835769, -mno-fix-cortex-a53-835769 Workaround Cortex-A53 erratum 835769 (AArch64 only) Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2002,6 +2002,8 @@ HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">; def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group, HelpText<"Reserve the x18 register (AArch64 only)">; +def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group, + HelpText<"Reserve the x20 register (AArch64 only)">; def msimd128 : Flag<["-"], "msimd128">, Group; def mno_simd128 : Flag<["-"], "mno-simd128">, Group; Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -198,6 +198,9 @@ if (Args.hasArg(options::OPT_ffixed_x18)) Features.push_back("+reserve-x18"); + if (Args.hasArg(options::OPT_ffixed_x20)) + Features.push_back("+reserve-x20"); + if (Args.hasArg(options::OPT_mno_neg_immediates)) Features.push_back("+no-neg-immediates"); } Index: clang/test/Driver/aarch64-fixed-x20.c =================================================================== --- /dev/null +++ clang/test/Driver/aarch64-fixed-x20.c @@ -0,0 +1,4 @@ +// RUN: %clang -target aarch64-none-gnu -ffixed-x20 -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-FIXED-X20 < %t %s + +// CHECK-FIXED-X20: "-target-feature" "+reserve-x20" Index: llvm/lib/Target/AArch64/AArch64.td =================================================================== --- llvm/lib/Target/AArch64/AArch64.td +++ llvm/lib/Target/AArch64/AArch64.td @@ -76,6 +76,10 @@ "Reserve X18, making it unavailable " "as a GPR">; +def FeatureReserveX20 : SubtargetFeature<"reserve-x20", "ReserveX20", "true", + "Reserve X20, making it unavailable " + "as a GPR">; + def FeatureUseAA : SubtargetFeature<"use-aa", "UseAA", "true", "Use alias analysis during codegen">; Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -4930,9 +4930,13 @@ .Case("sp", AArch64::SP) .Case("x18", AArch64::X18) .Case("w18", AArch64::W18) + .Case("x20", AArch64::X20) + .Case("w20", AArch64::W20) .Default(0); - if ((Reg == AArch64::X18 || Reg == AArch64::W18) && - !Subtarget->isX18Reserved()) + if (((Reg == AArch64::X18 || Reg == AArch64::W18) && + !Subtarget->isX18Reserved()) || + ((Reg == AArch64::X20 || Reg == AArch64::W20) && + !Subtarget->isX20Reserved())) Reg = 0; if (Reg) return Reg; Index: llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -137,6 +137,9 @@ if (MF.getSubtarget().isX18Reserved()) markSuperRegs(Reserved, AArch64::W18); // Platform register + if (MF.getSubtarget().isX20Reserved()) + markSuperRegs(Reserved, AArch64::W20); // Platform register + if (hasBasePointer(MF)) markSuperRegs(Reserved, AArch64::W19); @@ -159,12 +162,15 @@ case AArch64::X18: case AArch64::W18: return MF.getSubtarget().isX18Reserved(); + case AArch64::X19: + case AArch64::W19: + return hasBasePointer(MF); + case AArch64::X20: + case AArch64::W20: + return MF.getSubtarget().isX20Reserved(); case AArch64::FP: case AArch64::W29: return TFI->hasFP(MF) || TT.isOSDarwin(); - case AArch64::W19: - case AArch64::X19: - return hasBasePointer(MF); } return false; @@ -432,6 +438,8 @@ - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP - MF.getSubtarget() .isX18Reserved() // X18 reserved as platform register + - MF.getSubtarget() + .isX20Reserved() // X20 reserved as platform register - hasBasePointer(MF); // X19 case AArch64::FPR8RegClassID: case AArch64::FPR16RegClassID: Index: llvm/lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- llvm/lib/Target/AArch64/AArch64Subtarget.h +++ llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -131,6 +131,9 @@ // ReserveX18 - X18 is not available as a general purpose register. bool ReserveX18; + // ReserveX20 - X20 is not available as a general purpose register. + bool ReserveX20 = false; + bool IsLittle; /// TargetTriple - What processor and OS we're targeting. @@ -216,6 +219,7 @@ } bool isX18Reserved() const { return ReserveX18; } + bool isX20Reserved() const { return ReserveX20; } bool hasFPARMv8() const { return HasFPARMv8; } bool hasNEON() const { return HasNEON; } bool hasCrypto() const { return HasCrypto; } Index: llvm/test/CodeGen/AArch64/arm64-platform-reg.ll =================================================================== --- llvm/test/CodeGen/AArch64/arm64-platform-reg.ll +++ llvm/test/CodeGen/AArch64/arm64-platform-reg.ll @@ -1,8 +1,10 @@ -; RUN: llc -mtriple=arm64-apple-ios -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18 -; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=arm64-apple-ios -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X20 +; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x18,+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 --check-prefix=CHECK-RESERVE-X20 ; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s -; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18 -; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 +; RUN: llc -mtriple=aarch64-windows -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; x18 is reserved as a platform register on Darwin but not on other ; systems. Create loads of register pressure and make sure this is respected. @@ -19,11 +21,13 @@ ; CHECK: ldr x18 ; CHECK: str x18 -; CHECK-RESERVE-X18-NOT: ldr fp +; CHECK-RESERVE-NOT: ldr fp ; CHECK-RESERVE-X18-NOT: ldr x18 -; CHECK-RESERVE-X18: Spill -; CHECK-RESERVE-X18-NOT: ldr fp +; CHECK-RESERVE-X20-NOT: ldr x20 +; CHECK-RESERVE: Spill +; CHECK-RESERVE-NOT: ldr fp ; CHECK-RESERVE-X18-NOT: ldr x18 -; CHECK-RESERVE-X18: ret +; CHECK-RESERVE-X20-NOT: ldr x20 +; CHECK-RESERVE: ret ret void }