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 #ifdef TARGET_ARCH_aarch64 112 # include "register_aarch64.hpp" 113 #endif 114 115 116 // Debugging support 117 118 inline void assert_different_registers( 119 AbstractRegister a, 120 AbstractRegister b 121 ) { 122 assert( 123 a != b, 124 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", 125 p2i(a), p2i(b)) 126 ); 127 } 128 129 130 inline void assert_different_registers( 131 AbstractRegister a, 132 AbstractRegister b, 133 AbstractRegister c 134 ) { 135 assert( 136 a != b && a != c 137 && b != c, 138 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 139 ", c=" INTPTR_FORMAT "", 140 p2i(a), p2i(b), p2i(c)) 141 ); 142 } 143 144 145 inline void assert_different_registers( 146 AbstractRegister a, 147 AbstractRegister b, 148 AbstractRegister c, 149 AbstractRegister d 150 ) { 151 assert( 152 a != b && a != c && a != d 153 && b != c && b != d 154 && c != d, 155 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 156 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", 157 p2i(a), p2i(b), p2i(c), p2i(d)) 158 ); 159 } 160 161 162 inline void assert_different_registers( 163 AbstractRegister a, 164 AbstractRegister b, 165 AbstractRegister c, 166 AbstractRegister d, 167 AbstractRegister e 168 ) { 169 assert( 170 a != b && a != c && a != d && a != e 171 && b != c && b != d && b != e 172 && c != d && c != e 173 && d != e, 174 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 175 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", 176 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)) 177 ); 178 } 179 180 181 inline void assert_different_registers( 182 AbstractRegister a, 183 AbstractRegister b, 184 AbstractRegister c, 185 AbstractRegister d, 186 AbstractRegister e, 187 AbstractRegister f 188 ) { 189 assert( 190 a != b && a != c && a != d && a != e && a != f 191 && b != c && b != d && b != e && b != f 192 && c != d && c != e && c != f 193 && d != e && d != f 194 && e != f, 195 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 196 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 197 ", f=" INTPTR_FORMAT "", 198 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)) 199 ); 200 } 201 202 203 inline void assert_different_registers( 204 AbstractRegister a, 205 AbstractRegister b, 206 AbstractRegister c, 207 AbstractRegister d, 208 AbstractRegister e, 209 AbstractRegister f, 210 AbstractRegister g 211 ) { 212 assert( 213 a != b && a != c && a != d && a != e && a != f && a != g 214 && b != c && b != d && b != e && b != f && b != g 215 && c != d && c != e && c != f && c != g 216 && d != e && d != f && d != g 217 && e != f && e != g 218 && f != g, 219 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 220 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 221 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", 222 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)) 223 ); 224 } 225 226 227 inline void assert_different_registers( 228 AbstractRegister a, 229 AbstractRegister b, 230 AbstractRegister c, 231 AbstractRegister d, 232 AbstractRegister e, 233 AbstractRegister f, 234 AbstractRegister g, 235 AbstractRegister h 236 ) { 237 assert( 238 a != b && a != c && a != d && a != e && a != f && a != g && a != h 239 && b != c && b != d && b != e && b != f && b != g && b != h 240 && c != d && c != e && c != f && c != g && c != h 241 && d != e && d != f && d != g && d != h 242 && e != f && e != g && e != h 243 && f != g && f != h 244 && g != h, 245 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 246 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 247 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", 248 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)) 249 ); 250 } 251 252 253 inline void assert_different_registers( 254 AbstractRegister a, 255 AbstractRegister b, 256 AbstractRegister c, 257 AbstractRegister d, 258 AbstractRegister e, 259 AbstractRegister f, 260 AbstractRegister g, 261 AbstractRegister h, 262 AbstractRegister i 263 ) { 264 assert( 265 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i 266 && b != c && b != d && b != e && b != f && b != g && b != h && b != i 267 && c != d && c != e && c != f && c != g && c != h && c != i 268 && d != e && d != f && d != g && d != h && d != i 269 && e != f && e != g && e != h && e != i 270 && f != g && f != h && f != i 271 && g != h && g != i 272 && h != i, 273 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 274 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 275 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 276 ", i=" INTPTR_FORMAT "", 277 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)) 278 ); 279 } 280 281 inline void assert_different_registers( 282 AbstractRegister a, 283 AbstractRegister b, 284 AbstractRegister c, 285 AbstractRegister d, 286 AbstractRegister e, 287 AbstractRegister f, 288 AbstractRegister g, 289 AbstractRegister h, 290 AbstractRegister i, 291 AbstractRegister j 292 ) { 293 assert( 294 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j 295 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j 296 && c != d && c != e && c != f && c != g && c != h && c != i && c != j 297 && d != e && d != f && d != g && d != h && d != i && d != j 298 && e != f && e != g && e != h && e != i && e != j 299 && f != g && f != h && f != i && f != j 300 && g != h && g != i && g != j 301 && h != i && h != j 302 && i != j, 303 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 304 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 305 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 306 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "", 307 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)) 308 ); 309 } 310 311 inline void assert_different_registers( 312 AbstractRegister a, 313 AbstractRegister b, 314 AbstractRegister c, 315 AbstractRegister d, 316 AbstractRegister e, 317 AbstractRegister f, 318 AbstractRegister g, 319 AbstractRegister h, 320 AbstractRegister i, 321 AbstractRegister j, 322 AbstractRegister k 323 ) { 324 assert( 325 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k 326 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k 327 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k 328 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k 329 && e != f && e != g && e != h && e != i && e != j && e !=k 330 && f != g && f != h && f != i && f != j && f !=k 331 && g != h && g != i && g != j && g !=k 332 && h != i && h != j && h !=k 333 && i != j && i !=k 334 && j !=k, 335 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 336 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 337 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 338 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "", 339 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)) 340 ); 341 } 342 343 inline void assert_different_registers( 344 AbstractRegister a, 345 AbstractRegister b, 346 AbstractRegister c, 347 AbstractRegister d, 348 AbstractRegister e, 349 AbstractRegister f, 350 AbstractRegister g, 351 AbstractRegister h, 352 AbstractRegister i, 353 AbstractRegister j, 354 AbstractRegister k, 355 AbstractRegister l 356 ) { 357 assert( 358 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l 359 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l 360 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l 361 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l 362 && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l 363 && f != g && f != h && f != i && f != j && f !=k && f !=l 364 && g != h && g != i && g != j && g !=k && g !=l 365 && h != i && h != j && h !=k && h !=l 366 && i != j && i !=k && i !=l 367 && j !=k && j !=l 368 && k !=l, 369 err_msg_res("registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 370 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 371 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 372 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT 373 ", l=" INTPTR_FORMAT "", 374 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)) 375 ); 376 } 377 378 #endif // SHARE_VM_ASM_REGISTER_HPP