Index: clang/docs/ClangCommandLineReference.rst =================================================================== --- clang/docs/ClangCommandLineReference.rst +++ clang/docs/ClangCommandLineReference.rst @@ -2296,6 +2296,14 @@ Reserve the x18 register (AArch64 only) +.. option:: -ffixed-x19 + +Reserve the x19 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 @@ -1969,6 +1969,10 @@ 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_x19 : Flag<["-"], "ffixed-x19">, Group, + HelpText<"Reserve the x19 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,12 @@ if (Args.hasArg(options::OPT_ffixed_x18)) Features.push_back("+reserve-x18"); + if (Args.hasArg(options::OPT_ffixed_x19)) + Features.push_back("+reserve-x19"); + + 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-x19.c =================================================================== --- /dev/null +++ clang/test/Driver/aarch64-fixed-x19.c @@ -0,0 +1,4 @@ +// RUN: %clang -target aarch64-none-gnu -ffixed-x19 -### %s 2> %t +// RUN: FileCheck --check-prefix=CHECK-FIXED-X19 < %t %s + +// CHECK-FIXED-X19: "-target-feature" "+reserve-x19" 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,14 @@ "Reserve X18, making it unavailable " "as a GPR">; +def FeatureReserveX19 : SubtargetFeature<"reserve-x19", "ReserveX19", "true", + "Reserve X19, 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 @@ -4921,9 +4921,17 @@ .Case("sp", AArch64::SP) .Case("x18", AArch64::X18) .Case("w18", AArch64::W18) + .Case("x19", AArch64::X19) + .Case("w19", AArch64::W19) + .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::X19 || Reg == AArch64::W19) && + !Subtarget->isX19Reserved()) || + ((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,12 @@ if (MF.getSubtarget().isX18Reserved()) markSuperRegs(Reserved, AArch64::W18); // Platform register + if (MF.getSubtarget().isX19Reserved()) + markSuperRegs(Reserved, AArch64::W19); // Platform register + + if (MF.getSubtarget().isX20Reserved()) + markSuperRegs(Reserved, AArch64::W20); // Platform register + if (hasBasePointer(MF)) markSuperRegs(Reserved, AArch64::W19); @@ -159,12 +165,15 @@ case AArch64::X18: case AArch64::W18: return MF.getSubtarget().isX18Reserved(); + case AArch64::X19: + case AArch64::W19: + return MF.getSubtarget().isX19Reserved() || 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 +441,10 @@ - (TFI->hasFP(MF) || TT.isOSDarwin()) // FP - MF.getSubtarget() .isX18Reserved() // X18 reserved as platform register + - MF.getSubtarget() + .isX19Reserved() // X19 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,12 @@ // ReserveX18 - X18 is not available as a general purpose register. bool ReserveX18; + // ReserveX19 - X19 is not available as a general purpose register. + bool ReserveX19 = false; + + // 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 +222,8 @@ } bool isX18Reserved() const { return ReserveX18; } + bool isX19Reserved() const { return ReserveX19; } + 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,11 @@ -; 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-x19 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X19 +; 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-x19,+reserve-x20,+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X19 --check-prefix=CHECK-RESERVE-X20 --check-prefix=CHECK-RESERVE-X18 ; 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 +22,15 @@ ; 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-X19-NOT: ldr x19 +; 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-X19-NOT: ldr x19 +; CHECK-RESERVE-X20-NOT: ldr x20 +; CHECK-RESERVE: ret ret void }