mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
[AArch64] Support reserving x20 register
Register x20 is a callee-saved register which may be used for other purposes in certain contexts, for example to hold special variables within the kernel. This change adds support for reserving this register both to frontend and backend to make this register usable for these purposes. Differential Revision: https://reviews.llvm.org/D46552 llvm-svn: 334531
This commit is contained in:
parent
72d5015e27
commit
4239933fa7
@ -76,6 +76,10 @@ def FeatureReserveX18 : SubtargetFeature<"reserve-x18", "ReserveX18", "true",
|
||||
"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">;
|
||||
|
||||
|
@ -4930,9 +4930,13 @@ unsigned AArch64TargetLowering::getRegisterByName(const char* RegName, EVT VT,
|
||||
.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;
|
||||
|
@ -137,6 +137,9 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
if (MF.getSubtarget<AArch64Subtarget>().isX18Reserved())
|
||||
markSuperRegs(Reserved, AArch64::W18); // Platform register
|
||||
|
||||
if (MF.getSubtarget<AArch64Subtarget>().isX20Reserved())
|
||||
markSuperRegs(Reserved, AArch64::W20); // Platform register
|
||||
|
||||
if (hasBasePointer(MF))
|
||||
markSuperRegs(Reserved, AArch64::W19);
|
||||
|
||||
@ -159,12 +162,15 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
|
||||
case AArch64::X18:
|
||||
case AArch64::W18:
|
||||
return MF.getSubtarget<AArch64Subtarget>().isX18Reserved();
|
||||
case AArch64::X19:
|
||||
case AArch64::W19:
|
||||
return hasBasePointer(MF);
|
||||
case AArch64::X20:
|
||||
case AArch64::W20:
|
||||
return MF.getSubtarget<AArch64Subtarget>().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 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
|
||||
- (TFI->hasFP(MF) || TT.isOSDarwin()) // FP
|
||||
- MF.getSubtarget<AArch64Subtarget>()
|
||||
.isX18Reserved() // X18 reserved as platform register
|
||||
- MF.getSubtarget<AArch64Subtarget>()
|
||||
.isX20Reserved() // X20 reserved as platform register
|
||||
- hasBasePointer(MF); // X19
|
||||
case AArch64::FPR8RegClassID:
|
||||
case AArch64::FPR16RegClassID:
|
||||
|
@ -131,6 +131,9 @@ protected:
|
||||
// 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 @@ public:
|
||||
}
|
||||
|
||||
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; }
|
||||
|
@ -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 @@ define void @keep_live() {
|
||||
; 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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user