1 /*
   2  * Copyright (c) 2000, 2010, 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 
  97 
  98 // Debugging support
  99 
 100 inline void assert_different_registers(
 101   AbstractRegister a,
 102   AbstractRegister b
 103 ) {
 104   assert(
 105     a != b,
 106     "registers must be different"
 107   );
 108 }
 109 
 110 
 111 inline void assert_different_registers(
 112   AbstractRegister a,
 113   AbstractRegister b,
 114   AbstractRegister c
 115 ) {
 116   assert(
 117     a != b && a != c
 118            && b != c,
 119     "registers must be different"
 120   );
 121 }
 122 
 123 
 124 inline void assert_different_registers(
 125   AbstractRegister a,
 126   AbstractRegister b,
 127   AbstractRegister c,
 128   AbstractRegister d
 129 ) {
 130   assert(
 131     a != b && a != c && a != d
 132            && b != c && b != d
 133                      && c != d,
 134     "registers must be different"
 135   );
 136 }
 137 
 138 
 139 inline void assert_different_registers(
 140   AbstractRegister a,
 141   AbstractRegister b,
 142   AbstractRegister c,
 143   AbstractRegister d,
 144   AbstractRegister e
 145 ) {
 146   assert(
 147     a != b && a != c && a != d && a != e
 148            && b != c && b != d && b != e
 149                      && c != d && c != e
 150                                && d != e,
 151     "registers must be different"
 152   );
 153 }
 154 
 155 
 156 inline void assert_different_registers(
 157   AbstractRegister a,
 158   AbstractRegister b,
 159   AbstractRegister c,
 160   AbstractRegister d,
 161   AbstractRegister e,
 162   AbstractRegister f
 163 ) {
 164   assert(
 165     a != b && a != c && a != d && a != e && a != f
 166            && b != c && b != d && b != e && b != f
 167                      && c != d && c != e && c != f
 168                                && d != e && d != f
 169                                          && e != f,
 170     "registers must be different"
 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   AbstractRegister g
 183 ) {
 184   assert(
 185     a != b && a != c && a != d && a != e && a != f && a != g
 186            && b != c && b != d && b != e && b != f && b != g
 187                      && c != d && c != e && c != f && c != g
 188                                && d != e && d != f && d != g
 189                                          && e != f && e != g
 190                                                    && f != g,
 191     "registers must be different"
 192   );
 193 }
 194 
 195 
 196 inline void assert_different_registers(
 197   AbstractRegister a,
 198   AbstractRegister b,
 199   AbstractRegister c,
 200   AbstractRegister d,
 201   AbstractRegister e,
 202   AbstractRegister f,
 203   AbstractRegister g,
 204   AbstractRegister h
 205 ) {
 206   assert(
 207     a != b && a != c && a != d && a != e && a != f && a != g && a != h
 208            && b != c && b != d && b != e && b != f && b != g && b != h
 209                      && c != d && c != e && c != f && c != g && c != h
 210                                && d != e && d != f && d != g && d != h
 211                                          && e != f && e != g && e != h
 212                                                    && f != g && f != h
 213                                                              && g != h,
 214     "registers must be different"
 215   );
 216 }
 217 
 218 #endif // SHARE_VM_ASM_REGISTER_HPP