Skip to content

Commit fcbec02

Browse files
committed
[AArch64] Support reserving arbitrary general purpose registers
This is a follow up to D48580 and D48581 which allows reserving arbitrary general purpose registers with the exception of registers with special purpose (X8, X16-X18, X29, X30) and registers used by LLVM (X0, X19). This change also generalizes some of the existing logic to rely entirely on values generated from tablegen. Differential Revision: https://reviews.llvm.org/D56305 llvm-svn: 353957
1 parent 122e813 commit fcbec02

File tree

10 files changed

+290
-62
lines changed

10 files changed

+290
-62
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
21342134
def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
21352135
Group<m_aarch64_Features_Group>,
21362136
HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
2137-
foreach i = {1-7,18,20} in
2137+
foreach i = {1-7,9-15,18,20-28} in
21382138
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_aarch64_Features_Group>,
21392139
HelpText<"Reserve the "#i#" register (AArch64 only)">;
21402140

clang/lib/Driver/ToolChains/Arch/AArch64.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,54 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
334334
if (Args.hasArg(options::OPT_ffixed_x7))
335335
Features.push_back("+reserve-x7");
336336

337+
if (Args.hasArg(options::OPT_ffixed_x9))
338+
Features.push_back("+reserve-x9");
339+
340+
if (Args.hasArg(options::OPT_ffixed_x10))
341+
Features.push_back("+reserve-x10");
342+
343+
if (Args.hasArg(options::OPT_ffixed_x11))
344+
Features.push_back("+reserve-x11");
345+
346+
if (Args.hasArg(options::OPT_ffixed_x12))
347+
Features.push_back("+reserve-x12");
348+
349+
if (Args.hasArg(options::OPT_ffixed_x13))
350+
Features.push_back("+reserve-x13");
351+
352+
if (Args.hasArg(options::OPT_ffixed_x14))
353+
Features.push_back("+reserve-x14");
354+
355+
if (Args.hasArg(options::OPT_ffixed_x15))
356+
Features.push_back("+reserve-x15");
357+
337358
if (Args.hasArg(options::OPT_ffixed_x18))
338359
Features.push_back("+reserve-x18");
339360

340361
if (Args.hasArg(options::OPT_ffixed_x20))
341362
Features.push_back("+reserve-x20");
342363

364+
if (Args.hasArg(options::OPT_ffixed_x21))
365+
Features.push_back("+reserve-x21");
366+
367+
if (Args.hasArg(options::OPT_ffixed_x22))
368+
Features.push_back("+reserve-x22");
369+
370+
if (Args.hasArg(options::OPT_ffixed_x23))
371+
Features.push_back("+reserve-x23");
372+
373+
if (Args.hasArg(options::OPT_ffixed_x24))
374+
Features.push_back("+reserve-x24");
375+
376+
if (Args.hasArg(options::OPT_ffixed_x26))
377+
Features.push_back("+reserve-x26");
378+
379+
if (Args.hasArg(options::OPT_ffixed_x27))
380+
Features.push_back("+reserve-x27");
381+
382+
if (Args.hasArg(options::OPT_ffixed_x28))
383+
Features.push_back("+reserve-x28");
384+
343385
if (Args.hasArg(options::OPT_fcall_saved_x8))
344386
Features.push_back("+call-saved-x8");
345387

clang/test/Driver/aarch64-fixed-x-register.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@
2626
// RUN: FileCheck --check-prefix=CHECK-FIXED-X7 < %t %s
2727
// CHECK-FIXED-X7: "-target-feature" "+reserve-x7"
2828

29+
// RUN: %clang -target aarch64-none-gnu -ffixed-x9 -### %s 2> %t
30+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X9 < %t %s
31+
// CHECK-FIXED-X9: "-target-feature" "+reserve-x9"
32+
33+
// RUN: %clang -target aarch64-none-gnu -ffixed-x10 -### %s 2> %t
34+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X10 < %t %s
35+
// CHECK-FIXED-X10: "-target-feature" "+reserve-x10"
36+
37+
// RUN: %clang -target aarch64-none-gnu -ffixed-x11 -### %s 2> %t
38+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X11 < %t %s
39+
// CHECK-FIXED-X11: "-target-feature" "+reserve-x11"
40+
41+
// RUN: %clang -target aarch64-none-gnu -ffixed-x12 -### %s 2> %t
42+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X12 < %t %s
43+
// CHECK-FIXED-X12: "-target-feature" "+reserve-x12"
44+
45+
// RUN: %clang -target aarch64-none-gnu -ffixed-x13 -### %s 2> %t
46+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X13 < %t %s
47+
// CHECK-FIXED-X13: "-target-feature" "+reserve-x13"
48+
49+
// RUN: %clang -target aarch64-none-gnu -ffixed-x14 -### %s 2> %t
50+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X14 < %t %s
51+
// CHECK-FIXED-X14: "-target-feature" "+reserve-x14"
52+
53+
// RUN: %clang -target aarch64-none-gnu -ffixed-x15 -### %s 2> %t
54+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X15 < %t %s
55+
// CHECK-FIXED-X15: "-target-feature" "+reserve-x15"
56+
2957
// RUN: %clang -target aarch64-none-gnu -ffixed-x18 -### %s 2> %t
3058
// RUN: FileCheck --check-prefix=CHECK-FIXED-X18 < %t %s
3159
// CHECK-FIXED-X18: "-target-feature" "+reserve-x18"
@@ -34,6 +62,38 @@
3462
// RUN: FileCheck --check-prefix=CHECK-FIXED-X20 < %t %s
3563
// CHECK-FIXED-X20: "-target-feature" "+reserve-x20"
3664

65+
// RUN: %clang -target aarch64-none-gnu -ffixed-x21 -### %s 2> %t
66+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X21 < %t %s
67+
// CHECK-FIXED-X21: "-target-feature" "+reserve-x21"
68+
69+
// RUN: %clang -target aarch64-none-gnu -ffixed-x22 -### %s 2> %t
70+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X22 < %t %s
71+
// CHECK-FIXED-X22: "-target-feature" "+reserve-x22"
72+
73+
// RUN: %clang -target aarch64-none-gnu -ffixed-x23 -### %s 2> %t
74+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X23 < %t %s
75+
// CHECK-FIXED-X23: "-target-feature" "+reserve-x23"
76+
77+
// RUN: %clang -target aarch64-none-gnu -ffixed-x24 -### %s 2> %t
78+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X24 < %t %s
79+
// CHECK-FIXED-X24: "-target-feature" "+reserve-x24"
80+
81+
// RUN: %clang -target aarch64-none-gnu -ffixed-x25 -### %s 2> %t
82+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X25 < %t %s
83+
// CHECK-FIXED-X25: "-target-feature" "+reserve-x25"
84+
85+
// RUN: %clang -target aarch64-none-gnu -ffixed-x26 -### %s 2> %t
86+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X26 < %t %s
87+
// CHECK-FIXED-X26: "-target-feature" "+reserve-x26"
88+
89+
// RUN: %clang -target aarch64-none-gnu -ffixed-x27 -### %s 2> %t
90+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X27 < %t %s
91+
// CHECK-FIXED-X27: "-target-feature" "+reserve-x27"
92+
93+
// RUN: %clang -target aarch64-none-gnu -ffixed-x28 -### %s 2> %t
94+
// RUN: FileCheck --check-prefix=CHECK-FIXED-X28 < %t %s
95+
// CHECK-FIXED-X28: "-target-feature" "+reserve-x28"
96+
3797
// Test multiple of reserve-x# options together.
3898
// RUN: %clang -target aarch64-none-gnu \
3999
// RUN: -ffixed-x1 \
@@ -55,8 +115,23 @@
55115
// RUN: -ffixed-x5 \
56116
// RUN: -ffixed-x6 \
57117
// RUN: -ffixed-x7 \
118+
// RUN: -ffixed-x9 \
119+
// RUN: -ffixed-x10 \
120+
// RUN: -ffixed-x11 \
121+
// RUN: -ffixed-x12 \
122+
// RUN: -ffixed-x13 \
123+
// RUN: -ffixed-x14 \
124+
// RUN: -ffixed-x15 \
58125
// RUN: -ffixed-x18 \
59126
// RUN: -ffixed-x20 \
127+
// RUN: -ffixed-x21 \
128+
// RUN: -ffixed-x22 \
129+
// RUN: -ffixed-x23 \
130+
// RUN: -ffixed-x24 \
131+
// RUN: -ffixed-x25 \
132+
// RUN: -ffixed-x26 \
133+
// RUN: -ffixed-x27 \
134+
// RUN: -ffixed-x28 \
60135
// RUN: -### %s 2> %t
61136
// RUN: FileCheck \
62137
// RUN: --check-prefix=CHECK-FIXED-X1 \
@@ -66,6 +141,21 @@
66141
// RUN: --check-prefix=CHECK-FIXED-X5 \
67142
// RUN: --check-prefix=CHECK-FIXED-X6 \
68143
// RUN: --check-prefix=CHECK-FIXED-X7 \
144+
// RUN: --check-prefix=CHECK-FIXED-X9 \
145+
// RUN: --check-prefix=CHECK-FIXED-X10 \
146+
// RUN: --check-prefix=CHECK-FIXED-X11 \
147+
// RUN: --check-prefix=CHECK-FIXED-X12 \
148+
// RUN: --check-prefix=CHECK-FIXED-X13 \
149+
// RUN: --check-prefix=CHECK-FIXED-X14 \
150+
// RUN: --check-prefix=CHECK-FIXED-X15 \
69151
// RUN: --check-prefix=CHECK-FIXED-X18 \
70152
// RUN: --check-prefix=CHECK-FIXED-X20 \
153+
// RUN: --check-prefix=CHECK-FIXED-X21 \
154+
// RUN: --check-prefix=CHECK-FIXED-X22 \
155+
// RUN: --check-prefix=CHECK-FIXED-X23 \
156+
// RUN: --check-prefix=CHECK-FIXED-X24 \
157+
// RUN: --check-prefix=CHECK-FIXED-X25 \
158+
// RUN: --check-prefix=CHECK-FIXED-X26 \
159+
// RUN: --check-prefix=CHECK-FIXED-X27 \
160+
// RUN: --check-prefix=CHECK-FIXED-X28 \
71161
// RUN: < %t %s

llvm/lib/Target/AArch64/AArch64.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def FeatureStrictAlign : SubtargetFeature<"strict-align",
126126
"Disallow all unaligned memory "
127127
"access">;
128128

129-
foreach i = {1-7,18,20} in
129+
foreach i = {1-7,9-15,18,20-28} in
130130
def FeatureReserveX#i : SubtargetFeature<"reserve-x"#i, "ReserveXRegister["#i#"]", "true",
131131
"Reserve X"#i#", making it unavailable "
132132
"as a GPR">;

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5211,50 +5211,20 @@ SDValue AArch64TargetLowering::LowerSPONENTRY(SDValue Op,
52115211
return DAG.getFrameIndex(FI, VT);
52125212
}
52135213

5214+
#define GET_REGISTER_MATCHER
5215+
#include "AArch64GenAsmMatcher.inc"
5216+
52145217
// FIXME? Maybe this could be a TableGen attribute on some registers and
52155218
// this table could be generated automatically from RegInfo.
52165219
unsigned AArch64TargetLowering::getRegisterByName(const char* RegName, EVT VT,
52175220
SelectionDAG &DAG) const {
5218-
unsigned Reg = StringSwitch<unsigned>(RegName)
5219-
.Case("sp", AArch64::SP)
5220-
.Case("x1", AArch64::X1)
5221-
.Case("w1", AArch64::W1)
5222-
.Case("x2", AArch64::X2)
5223-
.Case("w2", AArch64::W2)
5224-
.Case("x3", AArch64::X3)
5225-
.Case("w3", AArch64::W3)
5226-
.Case("x4", AArch64::X4)
5227-
.Case("w4", AArch64::W4)
5228-
.Case("x5", AArch64::X5)
5229-
.Case("w5", AArch64::W5)
5230-
.Case("x6", AArch64::X6)
5231-
.Case("w6", AArch64::W6)
5232-
.Case("x7", AArch64::X7)
5233-
.Case("w7", AArch64::W7)
5234-
.Case("x18", AArch64::X18)
5235-
.Case("w18", AArch64::W18)
5236-
.Case("x20", AArch64::X20)
5237-
.Case("w20", AArch64::W20)
5238-
.Default(0);
5239-
if (((Reg == AArch64::X1 || Reg == AArch64::W1) &&
5240-
!Subtarget->isXRegisterReserved(1)) ||
5241-
((Reg == AArch64::X2 || Reg == AArch64::W2) &&
5242-
!Subtarget->isXRegisterReserved(2)) ||
5243-
((Reg == AArch64::X3 || Reg == AArch64::W3) &&
5244-
!Subtarget->isXRegisterReserved(3)) ||
5245-
((Reg == AArch64::X4 || Reg == AArch64::W4) &&
5246-
!Subtarget->isXRegisterReserved(4)) ||
5247-
((Reg == AArch64::X5 || Reg == AArch64::W5) &&
5248-
!Subtarget->isXRegisterReserved(5)) ||
5249-
((Reg == AArch64::X6 || Reg == AArch64::W6) &&
5250-
!Subtarget->isXRegisterReserved(6)) ||
5251-
((Reg == AArch64::X7 || Reg == AArch64::W7) &&
5252-
!Subtarget->isXRegisterReserved(7)) ||
5253-
((Reg == AArch64::X18 || Reg == AArch64::W18) &&
5254-
!Subtarget->isXRegisterReserved(18)) ||
5255-
((Reg == AArch64::X20 || Reg == AArch64::W20) &&
5256-
!Subtarget->isXRegisterReserved(20)))
5257-
Reg = 0;
5221+
unsigned Reg = MatchRegisterName(RegName);
5222+
if (AArch64::X1 <= Reg && Reg <= AArch64::X28) {
5223+
const MCRegisterInfo *MRI = Subtarget->getRegisterInfo();
5224+
unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false);
5225+
if (!Subtarget->isXRegisterReserved(DwarfRegNum))
5226+
Reg = 0;
5227+
}
52585228
if (Reg)
52595229
return Reg;
52605230
report_fatal_error(Twine("Invalid register name \""

llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,13 @@ const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass(
242242
case AArch64::GPR32RegClassID:
243243
case AArch64::GPR32spRegClassID:
244244
case AArch64::GPR32sponlyRegClassID:
245+
case AArch64::GPR32argRegClassID:
245246
case AArch64::GPR32allRegClassID:
246247
case AArch64::GPR64commonRegClassID:
247248
case AArch64::GPR64RegClassID:
248249
case AArch64::GPR64spRegClassID:
249250
case AArch64::GPR64sponlyRegClassID:
251+
case AArch64::GPR64argRegClassID:
250252
case AArch64::GPR64allRegClassID:
251253
case AArch64::GPR64noipRegClassID:
252254
case AArch64::GPR64common_and_GPR64noipRegClassID:

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,8 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
216216
}
217217

218218
bool AArch64RegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const {
219-
// FIXME: Get the list of argument registers from TableGen.
220-
static const MCPhysReg GPRArgRegs[] = { AArch64::X0, AArch64::X1, AArch64::X2,
221-
AArch64::X3, AArch64::X4, AArch64::X5,
222-
AArch64::X6, AArch64::X7 };
223-
return std::any_of(std::begin(GPRArgRegs), std::end(GPRArgRegs),
219+
return std::any_of(std::begin(*AArch64::GPR64argRegClass.MC),
220+
std::end(*AArch64::GPR64argRegClass.MC),
224221
[this, &MF](MCPhysReg r){return isReservedReg(MF, r);});
225222
}
226223

llvm/lib/Target/AArch64/AArch64RegisterInfo.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ def GPR64z : RegisterOperand<GPR64> {
187187
let GIZeroRegister = XZR;
188188
}
189189

190+
// GPR argument registers.
191+
def GPR32arg : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 0, 7)>;
192+
def GPR64arg : RegisterClass<"AArch64", [i64], 64, (sequence "X%u", 0, 7)>;
193+
190194
// GPR register classes which include WZR/XZR AND SP/WSP. This is not a
191195
// constraint used by any instructions, it is used as a common super-class.
192196
def GPR32all : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WZR, WSP)>;

0 commit comments

Comments
 (0)