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