1/*
2 * Copyright (c) 2000, 2016, 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_VM_ASM_REGISTER_HPP
26#define SHARE_VM_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_VM_ASM_REGISTER_HPP
362