register.hpp revision 0:a61af66fc99e
1/*
2 * Copyright 2000-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25// Use AbstractRegister as shortcut
26class AbstractRegisterImpl;
27typedef AbstractRegisterImpl* AbstractRegister;
28
29
30// The super class for platform specific registers. Instead of using value objects,
31// registers are implemented as pointers. Subclassing is used so all registers can
32// use the debugging suport below. No virtual functions are used for efficiency.
33// They are canonicalized; i.e., registers are equal if their pointers are equal,
34// and vice versa. A concrete implementation may just map the register onto 'this'.
35
36class AbstractRegisterImpl {
37 protected:
38  int value() const                              { return (int)(intx)this; }
39};
40
41
42//
43// Macros for use in defining Register instances.  We'd like to be
44// able to simply define const instances of the RegisterImpl* for each
45// of the registers needed on a system in a header file.  However many
46// compilers don't handle this very well and end up producing a
47// private definition in every file which includes the header file.
48// Along with the static constructors necessary for initialization it
49// can consume a significant amount of space in the result library.
50//
51// The following macros allow us to declare the instance in a .hpp and
52// produce an enumeration value which has the same number.  Then in a
53// .cpp the the register instance can be defined using the enumeration
54// value.  This avoids the use of static constructors and multiple
55// definitions per .cpp.  In addition #defines for the register can be
56// produced so that the constant registers can be inlined.  These
57// macros should not be used inside other macros, because you may get
58// multiple evaluations of the macros which can give bad results.
59//
60// Here are some example uses and expansions.  Note that the macro
61// invocation is terminated with a ;.
62//
63// CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
64//
65// extern const Register G0 ;
66// enum { G0_RegisterEnumValue = 0 } ;
67//
68// REGISTER_DECLARATION(Register, Gmethod, G5);
69//
70// extern const Register Gmethod ;
71// enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
72//
73// REGISTER_DEFINITION(Register, G0);
74//
75// const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
76//
77
78#define AS_REGISTER(type,name)         ((type)name##_##type##EnumValue)
79
80#define CONSTANT_REGISTER_DECLARATION(type, name, value) \
81extern const type name;                                  \
82enum { name##_##type##EnumValue = (value) }
83
84#define REGISTER_DECLARATION(type, name, value) \
85extern const type name;                         \
86enum { name##_##type##EnumValue = value##_##type##EnumValue }
87
88#define REGISTER_DEFINITION(type, name) \
89const type name = ((type)name##_##type##EnumValue)
90
91
92
93// Debugging support
94
95inline void assert_different_registers(
96  AbstractRegister a,
97  AbstractRegister b
98) {
99  assert(
100    a != b,
101    "registers must be different"
102  );
103}
104
105
106inline void assert_different_registers(
107  AbstractRegister a,
108  AbstractRegister b,
109  AbstractRegister c
110) {
111  assert(
112    a != b && a != c
113           && b != c,
114    "registers must be different"
115  );
116}
117
118
119inline void assert_different_registers(
120  AbstractRegister a,
121  AbstractRegister b,
122  AbstractRegister c,
123  AbstractRegister d
124) {
125  assert(
126    a != b && a != c && a != d
127           && b != c && b != d
128                     && c != d,
129    "registers must be different"
130  );
131}
132
133
134inline void assert_different_registers(
135  AbstractRegister a,
136  AbstractRegister b,
137  AbstractRegister c,
138  AbstractRegister d,
139  AbstractRegister e
140) {
141  assert(
142    a != b && a != c && a != d && a != e
143           && b != c && b != d && b != e
144                     && c != d && c != e
145                               && d != e,
146    "registers must be different"
147  );
148}
149
150
151inline void assert_different_registers(
152  AbstractRegister a,
153  AbstractRegister b,
154  AbstractRegister c,
155  AbstractRegister d,
156  AbstractRegister e,
157  AbstractRegister f
158) {
159  assert(
160    a != b && a != c && a != d && a != e && a != f
161           && b != c && b != d && b != e && b != f
162                     && c != d && c != e && c != f
163                               && d != e && d != f
164                                         && e != f,
165    "registers must be different"
166  );
167}
168
169
170inline void assert_different_registers(
171  AbstractRegister a,
172  AbstractRegister b,
173  AbstractRegister c,
174  AbstractRegister d,
175  AbstractRegister e,
176  AbstractRegister f,
177  AbstractRegister g
178) {
179  assert(
180    a != b && a != c && a != d && a != e && a != f && a != g
181           && b != c && b != d && b != e && b != f && b != g
182                     && c != d && c != e && c != f && c != g
183                               && d != e && d != f && d != g
184                                         && e != f && e != g
185                                                   && f != g,
186    "registers must be different"
187  );
188}
189
190
191inline void assert_different_registers(
192  AbstractRegister a,
193  AbstractRegister b,
194  AbstractRegister c,
195  AbstractRegister d,
196  AbstractRegister e,
197  AbstractRegister f,
198  AbstractRegister g,
199  AbstractRegister h
200) {
201  assert(
202    a != b && a != c && a != d && a != e && a != f && a != g && a != h
203           && b != c && b != d && b != e && b != f && b != g && b != h
204                     && c != d && c != e && c != f && c != g && c != h
205                               && d != e && d != f && d != g && d != h
206                                         && e != f && e != g && e != h
207                                                   && f != g && f != h
208                                                             && g != h,
209    "registers must be different"
210  );
211}
212