register.hpp revision 7877:cc8363b030d5
1/*
2 * Copyright (c) 2000, 2014, 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/top.hpp"
29
30// Use AbstractRegister as shortcut
31class AbstractRegisterImpl;
32typedef AbstractRegisterImpl* AbstractRegister;
33
34
35// The super class for platform specific registers. Instead of using value objects,
36// registers are implemented as pointers. Subclassing is used so all registers can
37// use the debugging suport below. No virtual functions are used for efficiency.
38// They are canonicalized; i.e., registers are equal if their pointers are equal,
39// and vice versa. A concrete implementation may just map the register onto 'this'.
40
41class AbstractRegisterImpl {
42 protected:
43  int value() const                              { return (int)(intx)this; }
44};
45
46
47//
48// Macros for use in defining Register instances.  We'd like to be
49// able to simply define const instances of the RegisterImpl* for each
50// of the registers needed on a system in a header file.  However many
51// compilers don't handle this very well and end up producing a
52// private definition in every file which includes the header file.
53// Along with the static constructors necessary for initialization it
54// can consume a significant amount of space in the result library.
55//
56// The following macros allow us to declare the instance in a .hpp and
57// produce an enumeration value which has the same number.  Then in a
58// .cpp the the register instance can be defined using the enumeration
59// value.  This avoids the use of static constructors and multiple
60// definitions per .cpp.  In addition #defines for the register can be
61// produced so that the constant registers can be inlined.  These
62// macros should not be used inside other macros, because you may get
63// multiple evaluations of the macros which can give bad results.
64//
65// Here are some example uses and expansions.  Note that the macro
66// invocation is terminated with a ;.
67//
68// CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
69//
70// extern const Register G0 ;
71// enum { G0_RegisterEnumValue = 0 } ;
72//
73// REGISTER_DECLARATION(Register, Gmethod, G5);
74//
75// extern const Register Gmethod ;
76// enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
77//
78// REGISTER_DEFINITION(Register, G0);
79//
80// const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
81//
82
83#define AS_REGISTER(type,name)         ((type)name##_##type##EnumValue)
84
85#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
86extern const type name;                                  \
87enum { name##_##type##EnumValue = (value) }
88
89#define REGISTER_DECLARATION(type, name, value) \
90extern const type name;                         \
91enum { name##_##type##EnumValue = value##_##type##EnumValue }
92
93#define REGISTER_DEFINITION(type, name) \
94const type name = ((type)name##_##type##EnumValue)
95
96#ifdef TARGET_ARCH_x86
97# include "register_x86.hpp"
98#endif
99#ifdef TARGET_ARCH_sparc
100# include "register_sparc.hpp"
101#endif
102#ifdef TARGET_ARCH_zero
103# include "register_zero.hpp"
104#endif
105#ifdef TARGET_ARCH_arm
106# include "register_arm.hpp"
107#endif
108#ifdef TARGET_ARCH_ppc
109# include "register_ppc.hpp"
110#endif
111#ifdef TARGET_ARCH_aarch64
112# include "register_aarch64.hpp"
113#endif
114
115
116// Debugging support
117
118inline void assert_different_registers(
119  AbstractRegister a,
120  AbstractRegister b
121) {
122  assert(
123    a != b,
124    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "",
125                p2i(a), p2i(b))
126  );
127}
128
129
130inline void assert_different_registers(
131  AbstractRegister a,
132  AbstractRegister b,
133  AbstractRegister c
134) {
135  assert(
136    a != b && a != c
137           && b != c,
138    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
139                ", c=" INTPTR_FORMAT "",
140                p2i(a), p2i(b), p2i(c))
141  );
142}
143
144
145inline void assert_different_registers(
146  AbstractRegister a,
147  AbstractRegister b,
148  AbstractRegister c,
149  AbstractRegister d
150) {
151  assert(
152    a != b && a != c && a != d
153           && b != c && b != d
154                     && c != d,
155    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
156                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
157                p2i(a), p2i(b), p2i(c), p2i(d))
158  );
159}
160
161
162inline void assert_different_registers(
163  AbstractRegister a,
164  AbstractRegister b,
165  AbstractRegister c,
166  AbstractRegister d,
167  AbstractRegister e
168) {
169  assert(
170    a != b && a != c && a != d && a != e
171           && b != c && b != d && b != e
172                     && c != d && c != e
173                               && d != e,
174    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
175                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
176                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e))
177  );
178}
179
180
181inline void assert_different_registers(
182  AbstractRegister a,
183  AbstractRegister b,
184  AbstractRegister c,
185  AbstractRegister d,
186  AbstractRegister e,
187  AbstractRegister f
188) {
189  assert(
190    a != b && a != c && a != d && a != e && a != f
191           && b != c && b != d && b != e && b != f
192                     && c != d && c != e && c != f
193                               && d != e && d != f
194                                         && e != f,
195    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
196                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
197                ", f=" INTPTR_FORMAT "",
198                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f))
199  );
200}
201
202
203inline void assert_different_registers(
204  AbstractRegister a,
205  AbstractRegister b,
206  AbstractRegister c,
207  AbstractRegister d,
208  AbstractRegister e,
209  AbstractRegister f,
210  AbstractRegister g
211) {
212  assert(
213    a != b && a != c && a != d && a != e && a != f && a != g
214           && b != c && b != d && b != e && b != f && b != g
215                     && c != d && c != e && c != f && c != g
216                               && d != e && d != f && d != g
217                                         && e != f && e != g
218                                                   && f != g,
219    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
220                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
221                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
222                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g))
223  );
224}
225
226
227inline void assert_different_registers(
228  AbstractRegister a,
229  AbstractRegister b,
230  AbstractRegister c,
231  AbstractRegister d,
232  AbstractRegister e,
233  AbstractRegister f,
234  AbstractRegister g,
235  AbstractRegister h
236) {
237  assert(
238    a != b && a != c && a != d && a != e && a != f && a != g && a != h
239           && b != c && b != d && b != e && b != f && b != g && b != h
240                     && c != d && c != e && c != f && c != g && c != h
241                               && d != e && d != f && d != g && d != h
242                                         && e != f && e != g && e != h
243                                                   && f != g && f != h
244                                                             && g != h,
245    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
246                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
247                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
248                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h))
249  );
250}
251
252
253inline void assert_different_registers(
254  AbstractRegister a,
255  AbstractRegister b,
256  AbstractRegister c,
257  AbstractRegister d,
258  AbstractRegister e,
259  AbstractRegister f,
260  AbstractRegister g,
261  AbstractRegister h,
262  AbstractRegister i
263) {
264  assert(
265    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
266           && b != c && b != d && b != e && b != f && b != g && b != h && b != i
267                     && c != d && c != e && c != f && c != g && c != h && c != i
268                               && d != e && d != f && d != g && d != h && d != i
269                                         && e != f && e != g && e != h && e != i
270                                                   && f != g && f != h && f != i
271                                                             && g != h && g != i
272                                                                       && h != i,
273    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
274                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
275                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
276                ", i=" INTPTR_FORMAT "",
277                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i))
278  );
279}
280
281inline void assert_different_registers(
282  AbstractRegister a,
283  AbstractRegister b,
284  AbstractRegister c,
285  AbstractRegister d,
286  AbstractRegister e,
287  AbstractRegister f,
288  AbstractRegister g,
289  AbstractRegister h,
290  AbstractRegister i,
291  AbstractRegister j
292) {
293  assert(
294    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j
295           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j
296                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j
297                               && d != e && d != f && d != g && d != h && d != i && d != j
298                                         && e != f && e != g && e != h && e != i && e != j
299                                                   && f != g && f != h && f != i && f != j
300                                                             && g != h && g != i && g != j
301                                                                       && h != i && h != j
302                                                                                 && i != j,
303    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
304                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
305                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
306                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
307                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j))
308  );
309}
310
311inline void assert_different_registers(
312  AbstractRegister a,
313  AbstractRegister b,
314  AbstractRegister c,
315  AbstractRegister d,
316  AbstractRegister e,
317  AbstractRegister f,
318  AbstractRegister g,
319  AbstractRegister h,
320  AbstractRegister i,
321  AbstractRegister j,
322  AbstractRegister k
323) {
324  assert(
325    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k
326           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k
327                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k
328                               && d != e && d != f && d != g && d != h && d != i && d != j && d !=k
329                                         && e != f && e != g && e != h && e != i && e != j && e !=k
330                                                   && f != g && f != h && f != i && f != j && f !=k
331                                                             && g != h && g != i && g != j && g !=k
332                                                                       && h != i && h != j && h !=k
333                                                                                 && i != j && i !=k
334                                                                                           && j !=k,
335    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
336                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
337                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
338                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
339                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k))
340  );
341}
342
343inline void assert_different_registers(
344  AbstractRegister a,
345  AbstractRegister b,
346  AbstractRegister c,
347  AbstractRegister d,
348  AbstractRegister e,
349  AbstractRegister f,
350  AbstractRegister g,
351  AbstractRegister h,
352  AbstractRegister i,
353  AbstractRegister j,
354  AbstractRegister k,
355  AbstractRegister l
356) {
357  assert(
358    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l
359           && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l
360                     && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l
361                               && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l
362                                         && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l
363                                                   && f != g && f != h && f != i && f != j && f !=k && f !=l
364                                                             && g != h && g != i && g != j && g !=k && g !=l
365                                                                       && h != i && h != j && h !=k && h !=l
366                                                                                 && i != j && i !=k && i !=l
367                                                                                           && j !=k && j !=l
368                                                                                                    && k !=l,
369    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
370                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
371                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
372                ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
373                ", l=" INTPTR_FORMAT "",
374                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l))
375  );
376}
377
378#endif // SHARE_VM_ASM_REGISTER_HPP
379