1 /*
   2  * Copyright (c) 2000, 2012, 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=%d, b=%d",
 122                 a, 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=%d, b=%d, c=%d",
 136                 a, b, c)
 137   );
 138 }
 139 
 140 
 141 inline void assert_different_registers(
 142   AbstractRegister a,
 143   AbstractRegister b,
 144   AbstractRegister c,
 145   AbstractRegister d
 146 ) {
 147   assert(
 148     a != b && a != c && a != d
 149            && b != c && b != d
 150                      && c != d,
 151     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d",
 152                 a, b, c, d)
 153   );
 154 }
 155 
 156 
 157 inline void assert_different_registers(
 158   AbstractRegister a,
 159   AbstractRegister b,
 160   AbstractRegister c,
 161   AbstractRegister d,
 162   AbstractRegister e
 163 ) {
 164   assert(
 165     a != b && a != c && a != d && a != e
 166            && b != c && b != d && b != e
 167                      && c != d && c != e
 168                                && d != e,
 169     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d",
 170                 a, b, c, d, e)
 171   );
 172 }
 173 
 174 
 175 inline void assert_different_registers(
 176   AbstractRegister a,
 177   AbstractRegister b,
 178   AbstractRegister c,
 179   AbstractRegister d,
 180   AbstractRegister e,
 181   AbstractRegister f
 182 ) {
 183   assert(
 184     a != b && a != c && a != d && a != e && a != f
 185            && b != c && b != d && b != e && b != f
 186                      && c != d && c != e && c != f
 187                                && d != e && d != f
 188                                          && e != f,
 189     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d",
 190                 a, b, c, d, e, f)
 191   );
 192 }
 193 
 194 
 195 inline void assert_different_registers(
 196   AbstractRegister a,
 197   AbstractRegister b,
 198   AbstractRegister c,
 199   AbstractRegister d,
 200   AbstractRegister e,
 201   AbstractRegister f,
 202   AbstractRegister g
 203 ) {
 204   assert(
 205     a != b && a != c && a != d && a != e && a != f && a != g
 206            && b != c && b != d && b != e && b != f && b != g
 207                      && c != d && c != e && c != f && c != g
 208                                && d != e && d != f && d != g
 209                                          && e != f && e != g
 210                                                    && f != g,
 211     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d",
 212                 a, b, c, d, e, f, g)
 213   );
 214 }
 215 
 216 
 217 inline void assert_different_registers(
 218   AbstractRegister a,
 219   AbstractRegister b,
 220   AbstractRegister c,
 221   AbstractRegister d,
 222   AbstractRegister e,
 223   AbstractRegister f,
 224   AbstractRegister g,
 225   AbstractRegister h
 226 ) {
 227   assert(
 228     a != b && a != c && a != d && a != e && a != f && a != g && a != h
 229            && b != c && b != d && b != e && b != f && b != g && b != h
 230                      && c != d && c != e && c != f && c != g && c != h
 231                                && d != e && d != f && d != g && d != h
 232                                          && e != f && e != g && e != h
 233                                                    && f != g && f != h
 234                                                              && g != h,
 235     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d",
 236                 a, b, c, d, e, f, g, h)
 237   );
 238 }
 239 
 240 
 241 inline void assert_different_registers(
 242   AbstractRegister a,
 243   AbstractRegister b,
 244   AbstractRegister c,
 245   AbstractRegister d,
 246   AbstractRegister e,
 247   AbstractRegister f,
 248   AbstractRegister g,
 249   AbstractRegister h,
 250   AbstractRegister i
 251 ) {
 252   assert(
 253     a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
 254            && b != c && b != d && b != e && b != f && b != g && b != h && b != i
 255                      && c != d && c != e && c != f && c != g && c != h && c != i
 256                                && d != e && d != f && d != g && d != h && d != i
 257                                          && e != f && e != g && e != h && e != i
 258                                                    && f != g && f != h && f != i
 259                                                              && g != h && g != i
 260                                                                        && h != i,
 261     err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d",
 262                 a, b, c, d, e, f, g, h, i)
 263   );
 264 }
 265 
 266 #endif // SHARE_VM_ASM_REGISTER_HPP