Mon, 09 Aug 2010 17:51:56 -0700
Merge
duke@435 | 1 | /* |
trims@1907 | 2 | * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
duke@435 | 25 | // Use AbstractRegister as shortcut |
duke@435 | 26 | class AbstractRegisterImpl; |
duke@435 | 27 | typedef AbstractRegisterImpl* AbstractRegister; |
duke@435 | 28 | |
duke@435 | 29 | |
duke@435 | 30 | // The super class for platform specific registers. Instead of using value objects, |
duke@435 | 31 | // registers are implemented as pointers. Subclassing is used so all registers can |
duke@435 | 32 | // use the debugging suport below. No virtual functions are used for efficiency. |
duke@435 | 33 | // They are canonicalized; i.e., registers are equal if their pointers are equal, |
duke@435 | 34 | // and vice versa. A concrete implementation may just map the register onto 'this'. |
duke@435 | 35 | |
duke@435 | 36 | class AbstractRegisterImpl { |
duke@435 | 37 | protected: |
duke@435 | 38 | int value() const { return (int)(intx)this; } |
duke@435 | 39 | }; |
duke@435 | 40 | |
duke@435 | 41 | |
duke@435 | 42 | // |
duke@435 | 43 | // Macros for use in defining Register instances. We'd like to be |
duke@435 | 44 | // able to simply define const instances of the RegisterImpl* for each |
duke@435 | 45 | // of the registers needed on a system in a header file. However many |
duke@435 | 46 | // compilers don't handle this very well and end up producing a |
duke@435 | 47 | // private definition in every file which includes the header file. |
duke@435 | 48 | // Along with the static constructors necessary for initialization it |
duke@435 | 49 | // can consume a significant amount of space in the result library. |
duke@435 | 50 | // |
duke@435 | 51 | // The following macros allow us to declare the instance in a .hpp and |
duke@435 | 52 | // produce an enumeration value which has the same number. Then in a |
duke@435 | 53 | // .cpp the the register instance can be defined using the enumeration |
duke@435 | 54 | // value. This avoids the use of static constructors and multiple |
duke@435 | 55 | // definitions per .cpp. In addition #defines for the register can be |
duke@435 | 56 | // produced so that the constant registers can be inlined. These |
duke@435 | 57 | // macros should not be used inside other macros, because you may get |
duke@435 | 58 | // multiple evaluations of the macros which can give bad results. |
duke@435 | 59 | // |
duke@435 | 60 | // Here are some example uses and expansions. Note that the macro |
duke@435 | 61 | // invocation is terminated with a ;. |
duke@435 | 62 | // |
duke@435 | 63 | // CONSTANT_REGISTER_DECLARATION(Register, G0, 0); |
duke@435 | 64 | // |
duke@435 | 65 | // extern const Register G0 ; |
duke@435 | 66 | // enum { G0_RegisterEnumValue = 0 } ; |
duke@435 | 67 | // |
duke@435 | 68 | // REGISTER_DECLARATION(Register, Gmethod, G5); |
duke@435 | 69 | // |
duke@435 | 70 | // extern const Register Gmethod ; |
duke@435 | 71 | // enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ; |
duke@435 | 72 | // |
duke@435 | 73 | // REGISTER_DEFINITION(Register, G0); |
duke@435 | 74 | // |
duke@435 | 75 | // const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ; |
duke@435 | 76 | // |
duke@435 | 77 | |
duke@435 | 78 | #define AS_REGISTER(type,name) ((type)name##_##type##EnumValue) |
duke@435 | 79 | |
duke@435 | 80 | #define CONSTANT_REGISTER_DECLARATION(type, name, value) \ |
duke@435 | 81 | extern const type name; \ |
duke@435 | 82 | enum { name##_##type##EnumValue = (value) } |
duke@435 | 83 | |
duke@435 | 84 | #define REGISTER_DECLARATION(type, name, value) \ |
duke@435 | 85 | extern const type name; \ |
duke@435 | 86 | enum { name##_##type##EnumValue = value##_##type##EnumValue } |
duke@435 | 87 | |
duke@435 | 88 | #define REGISTER_DEFINITION(type, name) \ |
duke@435 | 89 | const type name = ((type)name##_##type##EnumValue) |
duke@435 | 90 | |
duke@435 | 91 | |
duke@435 | 92 | |
duke@435 | 93 | // Debugging support |
duke@435 | 94 | |
duke@435 | 95 | inline void assert_different_registers( |
duke@435 | 96 | AbstractRegister a, |
duke@435 | 97 | AbstractRegister b |
duke@435 | 98 | ) { |
duke@435 | 99 | assert( |
duke@435 | 100 | a != b, |
duke@435 | 101 | "registers must be different" |
duke@435 | 102 | ); |
duke@435 | 103 | } |
duke@435 | 104 | |
duke@435 | 105 | |
duke@435 | 106 | inline void assert_different_registers( |
duke@435 | 107 | AbstractRegister a, |
duke@435 | 108 | AbstractRegister b, |
duke@435 | 109 | AbstractRegister c |
duke@435 | 110 | ) { |
duke@435 | 111 | assert( |
duke@435 | 112 | a != b && a != c |
duke@435 | 113 | && b != c, |
duke@435 | 114 | "registers must be different" |
duke@435 | 115 | ); |
duke@435 | 116 | } |
duke@435 | 117 | |
duke@435 | 118 | |
duke@435 | 119 | inline void assert_different_registers( |
duke@435 | 120 | AbstractRegister a, |
duke@435 | 121 | AbstractRegister b, |
duke@435 | 122 | AbstractRegister c, |
duke@435 | 123 | AbstractRegister d |
duke@435 | 124 | ) { |
duke@435 | 125 | assert( |
duke@435 | 126 | a != b && a != c && a != d |
duke@435 | 127 | && b != c && b != d |
duke@435 | 128 | && c != d, |
duke@435 | 129 | "registers must be different" |
duke@435 | 130 | ); |
duke@435 | 131 | } |
duke@435 | 132 | |
duke@435 | 133 | |
duke@435 | 134 | inline void assert_different_registers( |
duke@435 | 135 | AbstractRegister a, |
duke@435 | 136 | AbstractRegister b, |
duke@435 | 137 | AbstractRegister c, |
duke@435 | 138 | AbstractRegister d, |
duke@435 | 139 | AbstractRegister e |
duke@435 | 140 | ) { |
duke@435 | 141 | assert( |
duke@435 | 142 | a != b && a != c && a != d && a != e |
duke@435 | 143 | && b != c && b != d && b != e |
duke@435 | 144 | && c != d && c != e |
duke@435 | 145 | && d != e, |
duke@435 | 146 | "registers must be different" |
duke@435 | 147 | ); |
duke@435 | 148 | } |
duke@435 | 149 | |
duke@435 | 150 | |
duke@435 | 151 | inline void assert_different_registers( |
duke@435 | 152 | AbstractRegister a, |
duke@435 | 153 | AbstractRegister b, |
duke@435 | 154 | AbstractRegister c, |
duke@435 | 155 | AbstractRegister d, |
duke@435 | 156 | AbstractRegister e, |
duke@435 | 157 | AbstractRegister f |
duke@435 | 158 | ) { |
duke@435 | 159 | assert( |
duke@435 | 160 | a != b && a != c && a != d && a != e && a != f |
duke@435 | 161 | && b != c && b != d && b != e && b != f |
duke@435 | 162 | && c != d && c != e && c != f |
duke@435 | 163 | && d != e && d != f |
duke@435 | 164 | && e != f, |
duke@435 | 165 | "registers must be different" |
duke@435 | 166 | ); |
duke@435 | 167 | } |
duke@435 | 168 | |
duke@435 | 169 | |
duke@435 | 170 | inline void assert_different_registers( |
duke@435 | 171 | AbstractRegister a, |
duke@435 | 172 | AbstractRegister b, |
duke@435 | 173 | AbstractRegister c, |
duke@435 | 174 | AbstractRegister d, |
duke@435 | 175 | AbstractRegister e, |
duke@435 | 176 | AbstractRegister f, |
duke@435 | 177 | AbstractRegister g |
duke@435 | 178 | ) { |
duke@435 | 179 | assert( |
duke@435 | 180 | a != b && a != c && a != d && a != e && a != f && a != g |
duke@435 | 181 | && b != c && b != d && b != e && b != f && b != g |
duke@435 | 182 | && c != d && c != e && c != f && c != g |
duke@435 | 183 | && d != e && d != f && d != g |
duke@435 | 184 | && e != f && e != g |
duke@435 | 185 | && f != g, |
duke@435 | 186 | "registers must be different" |
duke@435 | 187 | ); |
duke@435 | 188 | } |
duke@435 | 189 | |
duke@435 | 190 | |
duke@435 | 191 | inline void assert_different_registers( |
duke@435 | 192 | AbstractRegister a, |
duke@435 | 193 | AbstractRegister b, |
duke@435 | 194 | AbstractRegister c, |
duke@435 | 195 | AbstractRegister d, |
duke@435 | 196 | AbstractRegister e, |
duke@435 | 197 | AbstractRegister f, |
duke@435 | 198 | AbstractRegister g, |
duke@435 | 199 | AbstractRegister h |
duke@435 | 200 | ) { |
duke@435 | 201 | assert( |
duke@435 | 202 | a != b && a != c && a != d && a != e && a != f && a != g && a != h |
duke@435 | 203 | && b != c && b != d && b != e && b != f && b != g && b != h |
duke@435 | 204 | && c != d && c != e && c != f && c != g && c != h |
duke@435 | 205 | && d != e && d != f && d != g && d != h |
duke@435 | 206 | && e != f && e != g && e != h |
duke@435 | 207 | && f != g && f != h |
duke@435 | 208 | && g != h, |
duke@435 | 209 | "registers must be different" |
duke@435 | 210 | ); |
duke@435 | 211 | } |