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 31 class AbstractRegisterImpl; 32 typedef 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 41 class 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) \ 86 extern const type name; \ 87 enum { name##_##type##EnumValue = (value) } 88 89 #define REGISTER_DECLARATION(type, name, value) \ 90 extern const type name; \ 91 enum { name##_##type##EnumValue = value##_##type##EnumValue } 92 93 #define REGISTER_DEFINITION(type, name) \ 94 const 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 115 inline 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 127 inline 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 142 inline 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 159 inline 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 178 inline 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 200 inline 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 224 inline 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 250 inline 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