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 inline void assert_different_registers( 279 AbstractRegister a, 280 AbstractRegister b, 281 AbstractRegister c, 282 AbstractRegister d, 283 AbstractRegister e, 284 AbstractRegister f, 285 AbstractRegister g, 286 AbstractRegister h, 287 AbstractRegister i, 288 AbstractRegister j 289 ) { 290 assert( 291 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j 292 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j 293 && c != d && c != e && c != f && c != g && c != h && c != i && c != j 294 && d != e && d != f && d != g && d != h && d != i && d != j 295 && e != f && e != g && e != h && e != i && e != j 296 && f != g && f != h && f != i && f != j 297 && g != h && g != i && g != j 298 && h != i && h != j 299 && i != j, 300 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 301 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 302 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 303 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "", 304 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)) 305 ); 306 } 307 308 inline void assert_different_registers( 309 AbstractRegister a, 310 AbstractRegister b, 311 AbstractRegister c, 312 AbstractRegister d, 313 AbstractRegister e, 314 AbstractRegister f, 315 AbstractRegister g, 316 AbstractRegister h, 317 AbstractRegister i, 318 AbstractRegister j, 319 AbstractRegister k 320 ) { 321 assert( 322 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k 323 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k 324 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k 325 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k 326 && e != f && e != g && e != h && e != i && e != j && e !=k 327 && f != g && f != h && f != i && f != j && f !=k 328 && g != h && g != i && g != j && g !=k 329 && h != i && h != j && h !=k 330 && i != j && i !=k 331 && j !=k, 332 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 333 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 334 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 335 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "", 336 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)) 337 ); 338 } 339 340 inline void assert_different_registers( 341 AbstractRegister a, 342 AbstractRegister b, 343 AbstractRegister c, 344 AbstractRegister d, 345 AbstractRegister e, 346 AbstractRegister f, 347 AbstractRegister g, 348 AbstractRegister h, 349 AbstractRegister i, 350 AbstractRegister j, 351 AbstractRegister k, 352 AbstractRegister l 353 ) { 354 assert( 355 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l 356 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l 357 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l 358 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l 359 && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l 360 && f != g && f != h && f != i && f != j && f !=k && f !=l 361 && g != h && g != i && g != j && g !=k && g !=l 362 && h != i && h != j && h !=k && h !=l 363 && i != j && i !=k && i !=l 364 && j !=k && j !=l 365 && k !=l, 366 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 367 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 368 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 369 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT 370 ", l=" INTPTR_FORMAT "", 371 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)) 372 ); 373 } 374 375 #endif // SHARE_VM_ASM_REGISTER_HPP