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