register.hpp revision 6412:53a41e7cbe05
1208737Sjmallett/*
2208737Sjmallett * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
3208737Sjmallett * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4208737Sjmallett *
5208737Sjmallett * This code is free software; you can redistribute it and/or modify it
6208737Sjmallett * under the terms of the GNU General Public License version 2 only, as
7208737Sjmallett * published by the Free Software Foundation.
8208737Sjmallett *
9208737Sjmallett * This code is distributed in the hope that it will be useful, but WITHOUT
10208737Sjmallett * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11208737Sjmallett * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12208737Sjmallett * version 2 for more details (a copy is included in the LICENSE file that
13208737Sjmallett * accompanied this code).
14208737Sjmallett *
15208737Sjmallett * You should have received a copy of the GNU General Public License version
16208737Sjmallett * 2 along with this work; if not, write to the Free Software Foundation,
17208737Sjmallett * 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
112
113// Debugging support
114
115inline void assert_different_registers(
116  AbstractRegister a,
117  AbstractRegister b
118) {
119  assert(
120    a != b,
121    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "",
122                p2i(a), p2i(b))
123  );
124}
125
126
127inline void assert_different_registers(
128  AbstractRegister a,
129  AbstractRegister b,
130  AbstractRegister c
131) {
132  assert(
133    a != b && a != c
134           && b != c,
135    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
136                ", c=" INTPTR_FORMAT "",
137                p2i(a), p2i(b), p2i(c))
138  );
139}
140
141
142inline void assert_different_registers(
143  AbstractRegister a,
144  AbstractRegister b,
145  AbstractRegister c,
146  AbstractRegister d
147) {
148  assert(
149    a != b && a != c && a != d
150           && b != c && b != d
151                     && c != d,
152    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
153                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
154                p2i(a), p2i(b), p2i(c), p2i(d))
155  );
156}
157
158
159inline void assert_different_registers(
160  AbstractRegister a,
161  AbstractRegister b,
162  AbstractRegister c,
163  AbstractRegister d,
164  AbstractRegister e
165) {
166  assert(
167    a != b && a != c && a != d && a != e
168           && b != c && b != d && b != e
169                     && c != d && c != e
170                               && d != e,
171    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
172                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
173                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e))
174  );
175}
176
177
178inline void assert_different_registers(
179  AbstractRegister a,
180  AbstractRegister b,
181  AbstractRegister c,
182  AbstractRegister d,
183  AbstractRegister e,
184  AbstractRegister f
185) {
186  assert(
187    a != b && a != c && a != d && a != e && a != f
188           && b != c && b != d && b != e && b != f
189                     && c != d && c != e && c != f
190                               && d != e && d != f
191                                         && e != f,
192    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
193                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
194                ", f=" INTPTR_FORMAT "",
195                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f))
196  );
197}
198
199
200inline void assert_different_registers(
201  AbstractRegister a,
202  AbstractRegister b,
203  AbstractRegister c,
204  AbstractRegister d,
205  AbstractRegister e,
206  AbstractRegister f,
207  AbstractRegister g
208) {
209  assert(
210    a != b && a != c && a != d && a != e && a != f && a != g
211           && b != c && b != d && b != e && b != f && b != g
212                     && c != d && c != e && c != f && c != g
213                               && d != e && d != f && d != g
214                                         && e != f && e != g
215                                                   && f != g,
216    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
217                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
218                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
219                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g))
220  );
221}
222
223
224inline void assert_different_registers(
225  AbstractRegister a,
226  AbstractRegister b,
227  AbstractRegister c,
228  AbstractRegister d,
229  AbstractRegister e,
230  AbstractRegister f,
231  AbstractRegister g,
232  AbstractRegister h
233) {
234  assert(
235    a != b && a != c && a != d && a != e && a != f && a != g && a != h
236           && b != c && b != d && b != e && b != f && b != g && b != h
237                     && c != d && c != e && c != f && c != g && c != h
238                               && d != e && d != f && d != g && d != h
239                                         && e != f && e != g && e != h
240                                                   && f != g && f != h
241                                                             && g != h,
242    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
243                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
244                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
245                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h))
246  );
247}
248
249
250inline void assert_different_registers(
251  AbstractRegister a,
252  AbstractRegister b,
253  AbstractRegister c,
254  AbstractRegister d,
255  AbstractRegister e,
256  AbstractRegister f,
257  AbstractRegister g,
258  AbstractRegister h,
259  AbstractRegister i
260) {
261  assert(
262    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
263           && b != c && b != d && b != e && b != f && b != g && b != h && b != i
264                     && c != d && c != e && c != f && c != g && c != h && c != i
265                               && d != e && d != f && d != g && d != h && d != i
266                                         && e != f && e != g && e != h && e != i
267                                                   && f != g && f != h && f != i
268                                                             && g != h && g != i
269                                                                       && h != i,
270    err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
271                ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
272                ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
273                ", i=" INTPTR_FORMAT "",
274                p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i))
275  );
276}
277
278#endif // SHARE_VM_ASM_REGISTER_HPP
279