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