Skip to content

Commit 0410029

Browse files
koachantstellar
authored andcommitted
[SPARC] Support reserving arbitrary general purpose registers (llvm#74927)
This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. (cherry picked from commit c2f9885)
1 parent 444e559 commit 0410029

14 files changed

+428
-2
lines changed

Diff for: clang/include/clang/Driver/Options.td

+12
Original file line numberDiff line numberDiff line change
@@ -5815,6 +5815,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group<m_sparc_Features_Group>;
58155815
def mno_vis3 : Flag<["-"], "mno-vis3">, Group<m_sparc_Features_Group>;
58165816
def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group<m_sparc_Features_Group>;
58175817
def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group<m_sparc_Features_Group>;
5818+
foreach i = 1 ... 7 in
5819+
def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group<m_sparc_Features_Group>,
5820+
HelpText<"Reserve the G"#i#" register (SPARC only)">;
5821+
foreach i = 0 ... 5 in
5822+
def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group<m_sparc_Features_Group>,
5823+
HelpText<"Reserve the O"#i#" register (SPARC only)">;
5824+
foreach i = 0 ... 7 in
5825+
def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group<m_sparc_Features_Group>,
5826+
HelpText<"Reserve the L"#i#" register (SPARC only)">;
5827+
foreach i = 0 ... 5 in
5828+
def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group<m_sparc_Features_Group>,
5829+
HelpText<"Reserve the I"#i#" register (SPARC only)">;
58185830
} // let Flags = [TargetSpecific]
58195831

58205832
// M68k features flags

Diff for: clang/lib/Driver/ToolChains/Arch/Sparc.cpp

+81
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,85 @@ void sparc::getSparcTargetFeatures(const Driver &D, const ArgList &Args,
178178
else
179179
Features.push_back("-hard-quad-float");
180180
}
181+
182+
if (Args.hasArg(options::OPT_ffixed_g1))
183+
Features.push_back("+reserve-g1");
184+
185+
if (Args.hasArg(options::OPT_ffixed_g2))
186+
Features.push_back("+reserve-g2");
187+
188+
if (Args.hasArg(options::OPT_ffixed_g3))
189+
Features.push_back("+reserve-g3");
190+
191+
if (Args.hasArg(options::OPT_ffixed_g4))
192+
Features.push_back("+reserve-g4");
193+
194+
if (Args.hasArg(options::OPT_ffixed_g5))
195+
Features.push_back("+reserve-g5");
196+
197+
if (Args.hasArg(options::OPT_ffixed_g6))
198+
Features.push_back("+reserve-g6");
199+
200+
if (Args.hasArg(options::OPT_ffixed_g7))
201+
Features.push_back("+reserve-g7");
202+
203+
if (Args.hasArg(options::OPT_ffixed_o0))
204+
Features.push_back("+reserve-o0");
205+
206+
if (Args.hasArg(options::OPT_ffixed_o1))
207+
Features.push_back("+reserve-o1");
208+
209+
if (Args.hasArg(options::OPT_ffixed_o2))
210+
Features.push_back("+reserve-o2");
211+
212+
if (Args.hasArg(options::OPT_ffixed_o3))
213+
Features.push_back("+reserve-o3");
214+
215+
if (Args.hasArg(options::OPT_ffixed_o4))
216+
Features.push_back("+reserve-o4");
217+
218+
if (Args.hasArg(options::OPT_ffixed_o5))
219+
Features.push_back("+reserve-o5");
220+
221+
if (Args.hasArg(options::OPT_ffixed_l0))
222+
Features.push_back("+reserve-l0");
223+
224+
if (Args.hasArg(options::OPT_ffixed_l1))
225+
Features.push_back("+reserve-l1");
226+
227+
if (Args.hasArg(options::OPT_ffixed_l2))
228+
Features.push_back("+reserve-l2");
229+
230+
if (Args.hasArg(options::OPT_ffixed_l3))
231+
Features.push_back("+reserve-l3");
232+
233+
if (Args.hasArg(options::OPT_ffixed_l4))
234+
Features.push_back("+reserve-l4");
235+
236+
if (Args.hasArg(options::OPT_ffixed_l5))
237+
Features.push_back("+reserve-l5");
238+
239+
if (Args.hasArg(options::OPT_ffixed_l6))
240+
Features.push_back("+reserve-l6");
241+
242+
if (Args.hasArg(options::OPT_ffixed_l7))
243+
Features.push_back("+reserve-l7");
244+
245+
if (Args.hasArg(options::OPT_ffixed_i0))
246+
Features.push_back("+reserve-i0");
247+
248+
if (Args.hasArg(options::OPT_ffixed_i1))
249+
Features.push_back("+reserve-i1");
250+
251+
if (Args.hasArg(options::OPT_ffixed_i2))
252+
Features.push_back("+reserve-i2");
253+
254+
if (Args.hasArg(options::OPT_ffixed_i3))
255+
Features.push_back("+reserve-i3");
256+
257+
if (Args.hasArg(options::OPT_ffixed_i4))
258+
Features.push_back("+reserve-i4");
259+
260+
if (Args.hasArg(options::OPT_ffixed_i5))
261+
Features.push_back("+reserve-i5");
181262
}

Diff for: clang/test/Driver/sparc-fixed-register.c

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// RUN: %clang --target=sparc-none-gnu -ffixed-g1 -### %s 2> %t
2+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G1 < %t %s
3+
// CHECK-FIXED-G1: "-target-feature" "+reserve-g1"
4+
5+
// RUN: %clang --target=sparc-none-gnu -ffixed-g2 -### %s 2> %t
6+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G2 < %t %s
7+
// CHECK-FIXED-G2: "-target-feature" "+reserve-g2"
8+
9+
// RUN: %clang --target=sparc-none-gnu -ffixed-g3 -### %s 2> %t
10+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G3 < %t %s
11+
// CHECK-FIXED-G3: "-target-feature" "+reserve-g3"
12+
13+
// RUN: %clang --target=sparc-none-gnu -ffixed-g4 -### %s 2> %t
14+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G4 < %t %s
15+
// CHECK-FIXED-G4: "-target-feature" "+reserve-g4"
16+
17+
// RUN: %clang --target=sparc-none-gnu -ffixed-g5 -### %s 2> %t
18+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G5 < %t %s
19+
// CHECK-FIXED-G5: "-target-feature" "+reserve-g5"
20+
21+
// RUN: %clang --target=sparc-none-gnu -ffixed-g6 -### %s 2> %t
22+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G6 < %t %s
23+
// CHECK-FIXED-G6: "-target-feature" "+reserve-g6"
24+
25+
// RUN: %clang --target=sparc-none-gnu -ffixed-g7 -### %s 2> %t
26+
// RUN: FileCheck --check-prefix=CHECK-FIXED-G7 < %t %s
27+
// CHECK-FIXED-G7: "-target-feature" "+reserve-g7"
28+
29+
// RUN: %clang --target=sparc-none-gnu -ffixed-o0 -### %s 2> %t
30+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O0 < %t %s
31+
// CHECK-FIXED-O0: "-target-feature" "+reserve-o0"
32+
33+
// RUN: %clang --target=sparc-none-gnu -ffixed-o1 -### %s 2> %t
34+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O1 < %t %s
35+
// CHECK-FIXED-O1: "-target-feature" "+reserve-o1"
36+
37+
// RUN: %clang --target=sparc-none-gnu -ffixed-o2 -### %s 2> %t
38+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O2 < %t %s
39+
// CHECK-FIXED-O2: "-target-feature" "+reserve-o2"
40+
41+
// RUN: %clang --target=sparc-none-gnu -ffixed-o3 -### %s 2> %t
42+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O3 < %t %s
43+
// CHECK-FIXED-O3: "-target-feature" "+reserve-o3"
44+
45+
// RUN: %clang --target=sparc-none-gnu -ffixed-o4 -### %s 2> %t
46+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O4 < %t %s
47+
// CHECK-FIXED-O4: "-target-feature" "+reserve-o4"
48+
49+
// RUN: %clang --target=sparc-none-gnu -ffixed-o5 -### %s 2> %t
50+
// RUN: FileCheck --check-prefix=CHECK-FIXED-O5 < %t %s
51+
// CHECK-FIXED-O5: "-target-feature" "+reserve-o5"
52+
53+
// RUN: %clang --target=sparc-none-gnu -ffixed-l0 -### %s 2> %t
54+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L0 < %t %s
55+
// CHECK-FIXED-L0: "-target-feature" "+reserve-l0"
56+
57+
// RUN: %clang --target=sparc-none-gnu -ffixed-l1 -### %s 2> %t
58+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L1 < %t %s
59+
// CHECK-FIXED-L1: "-target-feature" "+reserve-l1"
60+
61+
// RUN: %clang --target=sparc-none-gnu -ffixed-l2 -### %s 2> %t
62+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L2 < %t %s
63+
// CHECK-FIXED-L2: "-target-feature" "+reserve-l2"
64+
65+
// RUN: %clang --target=sparc-none-gnu -ffixed-l3 -### %s 2> %t
66+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L3 < %t %s
67+
// CHECK-FIXED-L3: "-target-feature" "+reserve-l3"
68+
69+
// RUN: %clang --target=sparc-none-gnu -ffixed-l4 -### %s 2> %t
70+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L4 < %t %s
71+
// CHECK-FIXED-L4: "-target-feature" "+reserve-l4"
72+
73+
// RUN: %clang --target=sparc-none-gnu -ffixed-l5 -### %s 2> %t
74+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L5 < %t %s
75+
// CHECK-FIXED-L5: "-target-feature" "+reserve-l5"
76+
77+
// RUN: %clang --target=sparc-none-gnu -ffixed-l6 -### %s 2> %t
78+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L6 < %t %s
79+
// CHECK-FIXED-L6: "-target-feature" "+reserve-l6"
80+
81+
// RUN: %clang --target=sparc-none-gnu -ffixed-l7 -### %s 2> %t
82+
// RUN: FileCheck --check-prefix=CHECK-FIXED-L7 < %t %s
83+
// CHECK-FIXED-L7: "-target-feature" "+reserve-l7"
84+
85+
// RUN: %clang --target=sparc-none-gnu -ffixed-i0 -### %s 2> %t
86+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I0 < %t %s
87+
// CHECK-FIXED-I0: "-target-feature" "+reserve-i0"
88+
89+
// RUN: %clang --target=sparc-none-gnu -ffixed-i1 -### %s 2> %t
90+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I1 < %t %s
91+
// CHECK-FIXED-I1: "-target-feature" "+reserve-i1"
92+
93+
// RUN: %clang --target=sparc-none-gnu -ffixed-i2 -### %s 2> %t
94+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I2 < %t %s
95+
// CHECK-FIXED-I2: "-target-feature" "+reserve-i2"
96+
97+
// RUN: %clang --target=sparc-none-gnu -ffixed-i3 -### %s 2> %t
98+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I3 < %t %s
99+
// CHECK-FIXED-I3: "-target-feature" "+reserve-i3"
100+
101+
// RUN: %clang --target=sparc-none-gnu -ffixed-i4 -### %s 2> %t
102+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I4 < %t %s
103+
// CHECK-FIXED-I4: "-target-feature" "+reserve-i4"
104+
105+
// RUN: %clang --target=sparc-none-gnu -ffixed-i5 -### %s 2> %t
106+
// RUN: FileCheck --check-prefix=CHECK-FIXED-I5 < %t %s
107+
// CHECK-FIXED-I5: "-target-feature" "+reserve-i5"
108+
109+
// Test multiple of reserve-* options together.
110+
// RUN: %clang --target=sparc-none-gnu \
111+
// RUN: -ffixed-g1 \
112+
// RUN: -ffixed-o2 \
113+
// RUN: -ffixed-l3 \
114+
// RUN: -ffixed-i4 \
115+
// RUN: -### %s 2> %t
116+
// RUN: FileCheck \
117+
// RUN: --check-prefix=CHECK-FIXED-G1 \
118+
// RUN: --check-prefix=CHECK-FIXED-O2 \
119+
// RUN: --check-prefix=CHECK-FIXED-L3 \
120+
// RUN: --check-prefix=CHECK-FIXED-I4 \
121+
// RUN: < %t %s
122+
123+
// Test all reserve-* options together.
124+
// RUN: %clang --target=sparc-none-gnu \
125+
// RUN: -ffixed-g1 \
126+
// RUN: -ffixed-g2 \
127+
// RUN: -ffixed-g3 \
128+
// RUN: -ffixed-g4 \
129+
// RUN: -ffixed-g5 \
130+
// RUN: -ffixed-g6 \
131+
// RUN: -ffixed-g7 \
132+
// RUN: -ffixed-o0 \
133+
// RUN: -ffixed-o1 \
134+
// RUN: -ffixed-o2 \
135+
// RUN: -ffixed-o3 \
136+
// RUN: -ffixed-o4 \
137+
// RUN: -ffixed-o5 \
138+
// RUN: -ffixed-l0 \
139+
// RUN: -ffixed-l1 \
140+
// RUN: -ffixed-l2 \
141+
// RUN: -ffixed-l3 \
142+
// RUN: -ffixed-l4 \
143+
// RUN: -ffixed-l5 \
144+
// RUN: -ffixed-l6 \
145+
// RUN: -ffixed-l7 \
146+
// RUN: -ffixed-i0 \
147+
// RUN: -ffixed-i1 \
148+
// RUN: -ffixed-i2 \
149+
// RUN: -ffixed-i3 \
150+
// RUN: -ffixed-i4 \
151+
// RUN: -ffixed-i5 \
152+
// RUN: -### %s 2> %t
153+
// RUN: FileCheck \
154+
// RUN: --check-prefix=CHECK-FIXED-G1 \
155+
// RUN: --check-prefix=CHECK-FIXED-G2 \
156+
// RUN: --check-prefix=CHECK-FIXED-G3 \
157+
// RUN: --check-prefix=CHECK-FIXED-G4 \
158+
// RUN: --check-prefix=CHECK-FIXED-G5 \
159+
// RUN: --check-prefix=CHECK-FIXED-G6 \
160+
// RUN: --check-prefix=CHECK-FIXED-G7 \
161+
// RUN: --check-prefix=CHECK-FIXED-O0 \
162+
// RUN: --check-prefix=CHECK-FIXED-O1 \
163+
// RUN: --check-prefix=CHECK-FIXED-O2 \
164+
// RUN: --check-prefix=CHECK-FIXED-O3 \
165+
// RUN: --check-prefix=CHECK-FIXED-O4 \
166+
// RUN: --check-prefix=CHECK-FIXED-O5 \
167+
// RUN: --check-prefix=CHECK-FIXED-L0 \
168+
// RUN: --check-prefix=CHECK-FIXED-L1 \
169+
// RUN: --check-prefix=CHECK-FIXED-L2 \
170+
// RUN: --check-prefix=CHECK-FIXED-L3 \
171+
// RUN: --check-prefix=CHECK-FIXED-L4 \
172+
// RUN: --check-prefix=CHECK-FIXED-L5 \
173+
// RUN: --check-prefix=CHECK-FIXED-L6 \
174+
// RUN: --check-prefix=CHECK-FIXED-L7 \
175+
// RUN: --check-prefix=CHECK-FIXED-I0 \
176+
// RUN: --check-prefix=CHECK-FIXED-I1 \
177+
// RUN: --check-prefix=CHECK-FIXED-I2 \
178+
// RUN: --check-prefix=CHECK-FIXED-I3 \
179+
// RUN: --check-prefix=CHECK-FIXED-I4 \
180+
// RUN: --check-prefix=CHECK-FIXED-I5 \
181+
// RUN: < %t %s

Diff for: llvm/lib/Target/Sparc/Sparc.td

+14
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ def TuneSlowRDPC : SubtargetFeature<"slow-rdpc", "HasSlowRDPC", "true",
7272
//==== Features added predmoninantly for LEON subtarget support
7373
include "LeonFeatures.td"
7474

75+
//==== Register allocation tweaks needed by some low-level software
76+
foreach i = 1 ... 7 in
77+
def FeatureReserveG#i : SubtargetFeature<"reserve-g"#i, "ReserveRegister["#i#" + SP::G0]", "true",
78+
"Reserve G"#i#", making it unavailable as a GPR">;
79+
foreach i = 0 ... 5 in
80+
def FeatureReserveO#i : SubtargetFeature<"reserve-o"#i, "ReserveRegister["#i#" + SP::O0]", "true",
81+
"Reserve O"#i#", making it unavailable as a GPR">;
82+
foreach i = 0 ... 7 in
83+
def FeatureReserveL#i : SubtargetFeature<"reserve-l"#i, "ReserveRegister["#i#" + SP::L0]", "true",
84+
"Reserve L"#i#", making it unavailable as a GPR">;
85+
foreach i = 0 ... 5 in
86+
def FeatureReserveI#i : SubtargetFeature<"reserve-i"#i, "ReserveRegister["#i#" + SP::I0]", "true",
87+
"Reserve I"#i#", making it unavailable as a GPR">;
88+
7589
//===----------------------------------------------------------------------===//
7690
// Register File, Calling Conv, Instruction Descriptions
7791
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)