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 #endif // SHARE_VM_ASM_REGISTER_HPP