1 /* 2 * Copyright (c) 2000, 2016, 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/debug.hpp" 29 #include "utilities/globalDefinitions.hpp" 30 #include "utilities/macros.hpp" 31 32 // Use AbstractRegister as shortcut 33 class AbstractRegisterImpl; 34 typedef AbstractRegisterImpl* AbstractRegister; 35 36 37 // The super class for platform specific registers. Instead of using value objects, 38 // registers are implemented as pointers. Subclassing is used so all registers can 39 // use the debugging suport below. No virtual functions are used for efficiency. 40 // They are canonicalized; i.e., registers are equal if their pointers are equal, 41 // and vice versa. A concrete implementation may just map the register onto 'this'. 42 43 class AbstractRegisterImpl { 44 protected: 45 int value() const { return (int)(intx)this; } 46 }; 47 48 49 // 50 // Macros for use in defining Register instances. We'd like to be 51 // able to simply define const instances of the RegisterImpl* for each 52 // of the registers needed on a system in a header file. However many 53 // compilers don't handle this very well and end up producing a 54 // private definition in every file which includes the header file. 55 // Along with the static constructors necessary for initialization it 56 // can consume a significant amount of space in the result library. 57 // 58 // The following macros allow us to declare the instance in a .hpp and 59 // produce an enumeration value which has the same number. Then in a 60 // .cpp the the register instance can be defined using the enumeration 61 // value. This avoids the use of static constructors and multiple 62 // definitions per .cpp. In addition #defines for the register can be 63 // produced so that the constant registers can be inlined. These 64 // macros should not be used inside other macros, because you may get 65 // multiple evaluations of the macros which can give bad results. 66 // 67 // Here are some example uses and expansions. Note that the macro 68 // invocation is terminated with a ;. 69 // 70 // CONSTANT_REGISTER_DECLARATION(Register, G0, 0); 71 // 72 // extern const Register G0 ; 73 // enum { G0_RegisterEnumValue = 0 } ; 74 // 75 // REGISTER_DECLARATION(Register, Gmethod, G5); 76 // 77 // extern const Register Gmethod ; 78 // enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ; 79 // 80 // REGISTER_DEFINITION(Register, G0); 81 // 82 // const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ; 83 // 84 85 #define AS_REGISTER(type,name) ((type)name##_##type##EnumValue) 86 87 #define CONSTANT_REGISTER_DECLARATION(type, name, value) \ 88 extern const type name; \ 89 enum { name##_##type##EnumValue = (value) } 90 91 #define REGISTER_DECLARATION(type, name, value) \ 92 extern const type name; \ 93 enum { name##_##type##EnumValue = value##_##type##EnumValue } 94 95 #define REGISTER_DEFINITION(type, name) \ 96 const type name = ((type)name##_##type##EnumValue) 97 98 #include CPU_HEADER(register) 99 100 // Debugging support 101 102 inline void assert_different_registers( 103 AbstractRegister a, 104 AbstractRegister b 105 ) { 106 assert( 107 a != b, 108 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b) 109 ); 110 } 111 112 113 inline void assert_different_registers( 114 AbstractRegister a, 115 AbstractRegister b, 116 AbstractRegister c 117 ) { 118 assert( 119 a != b && a != c 120 && b != c, 121 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 122 ", c=" INTPTR_FORMAT "", 123 p2i(a), p2i(b), p2i(c) 124 ); 125 } 126 127 128 inline void assert_different_registers( 129 AbstractRegister a, 130 AbstractRegister b, 131 AbstractRegister c, 132 AbstractRegister d 133 ) { 134 assert( 135 a != b && a != c && a != d 136 && b != c && b != d 137 && c != d, 138 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 139 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "", 140 p2i(a), p2i(b), p2i(c), p2i(d) 141 ); 142 } 143 144 145 inline void assert_different_registers( 146 AbstractRegister a, 147 AbstractRegister b, 148 AbstractRegister c, 149 AbstractRegister d, 150 AbstractRegister e 151 ) { 152 assert( 153 a != b && a != c && a != d && a != e 154 && b != c && b != d && b != e 155 && c != d && c != e 156 && d != e, 157 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 158 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "", 159 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e) 160 ); 161 } 162 163 164 inline void assert_different_registers( 165 AbstractRegister a, 166 AbstractRegister b, 167 AbstractRegister c, 168 AbstractRegister d, 169 AbstractRegister e, 170 AbstractRegister f 171 ) { 172 assert( 173 a != b && a != c && a != d && a != e && a != f 174 && b != c && b != d && b != e && b != f 175 && c != d && c != e && c != f 176 && d != e && d != f 177 && e != f, 178 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 179 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 180 ", f=" INTPTR_FORMAT "", 181 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f) 182 ); 183 } 184 185 186 inline void assert_different_registers( 187 AbstractRegister a, 188 AbstractRegister b, 189 AbstractRegister c, 190 AbstractRegister d, 191 AbstractRegister e, 192 AbstractRegister f, 193 AbstractRegister g 194 ) { 195 assert( 196 a != b && a != c && a != d && a != e && a != f && a != g 197 && b != c && b != d && b != e && b != f && b != g 198 && c != d && c != e && c != f && c != g 199 && d != e && d != f && d != g 200 && e != f && e != g 201 && f != g, 202 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 203 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 204 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "", 205 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g) 206 ); 207 } 208 209 210 inline void assert_different_registers( 211 AbstractRegister a, 212 AbstractRegister b, 213 AbstractRegister c, 214 AbstractRegister d, 215 AbstractRegister e, 216 AbstractRegister f, 217 AbstractRegister g, 218 AbstractRegister h 219 ) { 220 assert( 221 a != b && a != c && a != d && a != e && a != f && a != g && a != h 222 && b != c && b != d && b != e && b != f && b != g && b != h 223 && c != d && c != e && c != f && c != g && c != h 224 && d != e && d != f && d != g && d != h 225 && e != f && e != g && e != h 226 && f != g && f != h 227 && g != h, 228 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 229 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 230 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "", 231 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h) 232 ); 233 } 234 235 236 inline void assert_different_registers( 237 AbstractRegister a, 238 AbstractRegister b, 239 AbstractRegister c, 240 AbstractRegister d, 241 AbstractRegister e, 242 AbstractRegister f, 243 AbstractRegister g, 244 AbstractRegister h, 245 AbstractRegister i 246 ) { 247 assert( 248 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i 249 && b != c && b != d && b != e && b != f && b != g && b != h && b != i 250 && c != d && c != e && c != f && c != g && c != h && c != i 251 && d != e && d != f && d != g && d != h && d != i 252 && e != f && e != g && e != h && e != i 253 && f != g && f != h && f != i 254 && g != h && g != i 255 && h != i, 256 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 257 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 258 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 259 ", i=" INTPTR_FORMAT "", 260 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i) 261 ); 262 } 263 264 inline void assert_different_registers( 265 AbstractRegister a, 266 AbstractRegister b, 267 AbstractRegister c, 268 AbstractRegister d, 269 AbstractRegister e, 270 AbstractRegister f, 271 AbstractRegister g, 272 AbstractRegister h, 273 AbstractRegister i, 274 AbstractRegister j 275 ) { 276 assert( 277 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j 278 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j 279 && c != d && c != e && c != f && c != g && c != h && c != i && c != j 280 && d != e && d != f && d != g && d != h && d != i && d != j 281 && e != f && e != g && e != h && e != i && e != j 282 && f != g && f != h && f != i && f != j 283 && g != h && g != i && g != j 284 && h != i && h != j 285 && i != j, 286 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 287 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 288 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 289 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "", 290 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j) 291 ); 292 } 293 294 inline void assert_different_registers( 295 AbstractRegister a, 296 AbstractRegister b, 297 AbstractRegister c, 298 AbstractRegister d, 299 AbstractRegister e, 300 AbstractRegister f, 301 AbstractRegister g, 302 AbstractRegister h, 303 AbstractRegister i, 304 AbstractRegister j, 305 AbstractRegister k 306 ) { 307 assert( 308 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k 309 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k 310 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k 311 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k 312 && e != f && e != g && e != h && e != i && e != j && e !=k 313 && f != g && f != h && f != i && f != j && f !=k 314 && g != h && g != i && g != j && g !=k 315 && h != i && h != j && h !=k 316 && i != j && i !=k 317 && j !=k, 318 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 319 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 320 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 321 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "", 322 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k) 323 ); 324 } 325 326 inline void assert_different_registers( 327 AbstractRegister a, 328 AbstractRegister b, 329 AbstractRegister c, 330 AbstractRegister d, 331 AbstractRegister e, 332 AbstractRegister f, 333 AbstractRegister g, 334 AbstractRegister h, 335 AbstractRegister i, 336 AbstractRegister j, 337 AbstractRegister k, 338 AbstractRegister l 339 ) { 340 assert( 341 a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l 342 && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l 343 && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l 344 && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l 345 && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l 346 && f != g && f != h && f != i && f != j && f !=k && f !=l 347 && g != h && g != i && g != j && g !=k && g !=l 348 && h != i && h != j && h !=k && h !=l 349 && i != j && i !=k && i !=l 350 && j !=k && j !=l 351 && k !=l, 352 "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT 353 ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT 354 ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT 355 ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT 356 ", l=" INTPTR_FORMAT "", 357 p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l) 358 ); 359 } 360 361 #endif // SHARE_VM_ASM_REGISTER_HPP