1/*
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_ASM_REGISTER_HPP
26#define SHARE_ASM_REGISTER_HPP
27
28#include "utilities/debug.hpp"
29#include "utilities/globalDefinitions.hpp"
30#include "utilities/macros.hpp"
31
32// Use AbstractRegister as shortcut
33class AbstractRegisterImpl;
34typedef AbstractRegisterImpl* AbstractRegister;
35
36
37// The super class for platform specific registers. Instead of using value objects,
38// registers are implemented as pointers. Subclassing is used so all registers can
39// use the debugging suport below. No virtual functions are used for efficiency.
40// They are canonicalized; i.e., registers are equal if their pointers are equal,
41// and vice versa. A concrete implementation may just map the register onto 'this'.
42
43class AbstractRegisterImpl {
44 protected:
45 int value() const { return (int)(intx)this; }
46};
47
48
49//
50// Macros for use in defining Register instances. We'd like to be
51// able to simply define const instances of the RegisterImpl* for each
52// of the registers needed on a system in a header file. However many
53// compilers don't handle this very well and end up producing a
54// private definition in every file which includes the header file.
55// Along with the static constructors necessary for initialization it
56// can consume a significant amount of space in the result library.
57//
58// The following macros allow us to declare the instance in a .hpp and
59// produce an enumeration value which has the same number. Then in a
60// .cpp the the register instance can be defined using the enumeration
61// value. This avoids the use of static constructors and multiple
62// definitions per .cpp. In addition #defines for the register can be
63// produced so that the constant registers can be inlined. These
64// macros should not be used inside other macros, because you may get
65// multiple evaluations of the macros which can give bad results.
66//
67// Here are some example uses and expansions. Note that the macro
68// invocation is terminated with a ;.
69//
70// CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
71//
72// extern const Register G0 ;
73// enum { G0_RegisterEnumValue = 0 } ;
74//
75// REGISTER_DECLARATION(Register, Gmethod, G5);
76//
77// extern const Register Gmethod ;
78// enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
79//
80// REGISTER_DEFINITION(Register, G0);
81//
82// const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
83//
84
85#define AS_REGISTER(type,name) ((type)name##_##type##EnumValue)
86
87#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
88extern const type name; \
89enum { name##_##type##EnumValue = (value) }
90
91#define REGISTER_DECLARATION(type, name, value) \
92extern const type name; \
93enum { name##_##type##EnumValue = value##_##type##EnumValue }
94
95#define REGISTER_DEFINITION(type, name) \
96const type name = ((type)name##_##type##EnumValue)
97
98#include CPU_HEADER(register)
99
100// Debugging support
101
102inline void assert_different_registers(
103 AbstractRegister a,
104 AbstractRegister b
105) {
106 assert(
107 a != b,
108 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b)
109 );
110}
111
112
113inline void assert_different_registers(
114 AbstractRegister a,
115 AbstractRegister b,
116 AbstractRegister c
117) {
118 assert(
119 a != b && a != c
120 && b != c,
121 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
122 ", c=" INTPTR_FORMAT "",
123 p2i(a), p2i(b), p2i(c)
124 );
125}
126
127
128inline void assert_different_registers(
129 AbstractRegister a,
130 AbstractRegister b,
131 AbstractRegister c,
132 AbstractRegister d
133) {
134 assert(
135 a != b && a != c && a != d
136 && b != c && b != d
137 && c != d,
138 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
139 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
140 p2i(a), p2i(b), p2i(c), p2i(d)
141 );
142}
143
144
145inline void assert_different_registers(
146 AbstractRegister a,
147 AbstractRegister b,
148 AbstractRegister c,
149 AbstractRegister d,
150 AbstractRegister e
151) {
152 assert(
153 a != b && a != c && a != d && a != e
154 && b != c && b != d && b != e
155 && c != d && c != e
156 && d != e,
157 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
158 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
159 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)
160 );
161}
162
163
164inline void assert_different_registers(
165 AbstractRegister a,
166 AbstractRegister b,
167 AbstractRegister c,
168 AbstractRegister d,
169 AbstractRegister e,
170 AbstractRegister f
171) {
172 assert(
173 a != b && a != c && a != d && a != e && a != f
174 && b != c && b != d && b != e && b != f
175 && c != d && c != e && c != f
176 && d != e && d != f
177 && e != f,
178 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
179 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
180 ", f=" INTPTR_FORMAT "",
181 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)
182 );
183}
184
185
186inline void assert_different_registers(
187 AbstractRegister a,
188 AbstractRegister b,
189 AbstractRegister c,
190 AbstractRegister d,
191 AbstractRegister e,
192 AbstractRegister f,
193 AbstractRegister g
194) {
195 assert(
196 a != b && a != c && a != d && a != e && a != f && a != g
197 && b != c && b != d && b != e && b != f && b != g
198 && c != d && c != e && c != f && c != g
199 && d != e && d != f && d != g
200 && e != f && e != g
201 && f != g,
202 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
203 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
204 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
205 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)
206 );
207}
208
209
210inline void assert_different_registers(
211 AbstractRegister a,
212 AbstractRegister b,
213 AbstractRegister c,
214 AbstractRegister d,
215 AbstractRegister e,
216 AbstractRegister f,
217 AbstractRegister g,
218 AbstractRegister h
219) {
220 assert(
221 a != b && a != c && a != d && a != e && a != f && a != g && a != h
222 && b != c && b != d && b != e && b != f && b != g && b != h
223 && c != d && c != e && c != f && c != g && c != h
224 && d != e && d != f && d != g && d != h
225 && e != f && e != g && e != h
226 && f != g && f != h
227 && g != h,
228 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
229 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
230 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
231 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)
232 );
233}
234
235
236inline void assert_different_registers(
237 AbstractRegister a,
238 AbstractRegister b,
239 AbstractRegister c,
240 AbstractRegister d,
241 AbstractRegister e,
242 AbstractRegister f,
243 AbstractRegister g,
244 AbstractRegister h,
245 AbstractRegister i
246) {
247 assert(
248 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
249 && b != c && b != d && b != e && b != f && b != g && b != h && b != i
250 && c != d && c != e && c != f && c != g && c != h && c != i
251 && d != e && d != f && d != g && d != h && d != i
252 && e != f && e != g && e != h && e != i
253 && f != g && f != h && f != i
254 && g != h && g != i
255 && h != i,
256 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
257 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
258 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
259 ", i=" INTPTR_FORMAT "",
260 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)
261 );
262}
263
264inline void assert_different_registers(
265 AbstractRegister a,
266 AbstractRegister b,
267 AbstractRegister c,
268 AbstractRegister d,
269 AbstractRegister e,
270 AbstractRegister f,
271 AbstractRegister g,
272 AbstractRegister h,
273 AbstractRegister i,
274 AbstractRegister j
275) {
276 assert(
277 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j
278 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j
279 && c != d && c != e && c != f && c != g && c != h && c != i && c != j
280 && d != e && d != f && d != g && d != h && d != i && d != j
281 && e != f && e != g && e != h && e != i && e != j
282 && f != g && f != h && f != i && f != j
283 && g != h && g != i && g != j
284 && h != i && h != j
285 && i != j,
286 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
287 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
288 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
289 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
290 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)
291 );
292}
293
294inline void assert_different_registers(
295 AbstractRegister a,
296 AbstractRegister b,
297 AbstractRegister c,
298 AbstractRegister d,
299 AbstractRegister e,
300 AbstractRegister f,
301 AbstractRegister g,
302 AbstractRegister h,
303 AbstractRegister i,
304 AbstractRegister j,
305 AbstractRegister k
306) {
307 assert(
308 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k
309 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k
310 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k
311 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k
312 && e != f && e != g && e != h && e != i && e != j && e !=k
313 && f != g && f != h && f != i && f != j && f !=k
314 && g != h && g != i && g != j && g !=k
315 && h != i && h != j && h !=k
316 && i != j && i !=k
317 && j !=k,
318 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
319 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
320 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
321 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
322 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)
323 );
324}
325
326inline void assert_different_registers(
327 AbstractRegister a,
328 AbstractRegister b,
329 AbstractRegister c,
330 AbstractRegister d,
331 AbstractRegister e,
332 AbstractRegister f,
333 AbstractRegister g,
334 AbstractRegister h,
335 AbstractRegister i,
336 AbstractRegister j,
337 AbstractRegister k,
338 AbstractRegister l
339) {
340 assert(
341 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l
342 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l
343 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l
344 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l
345 && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l
346 && f != g && f != h && f != i && f != j && f !=k && f !=l
347 && g != h && g != i && g != j && g !=k && g !=l
348 && h != i && h != j && h !=k && h !=l
349 && i != j && i !=k && i !=l
350 && j !=k && j !=l
351 && k !=l,
352 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
353 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
354 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
355 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
356 ", l=" INTPTR_FORMAT "",
357 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)
358 );
359}
360
361#endif // SHARE_ASM_REGISTER_HPP
362