1 /*
   2  * Copyright (c) 2000, 2002, 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 // Use AbstractRegister as shortcut
  26 class AbstractRegisterImpl;
  27 typedef AbstractRegisterImpl* AbstractRegister;
  28 
  29 
  30 // The super class for platform specific registers. Instead of using value objects,
  31 // registers are implemented as pointers. Subclassing is used so all registers can
  32 // use the debugging suport below. No virtual functions are used for efficiency.
  33 // They are canonicalized; i.e., registers are equal if their pointers are equal,
  34 // and vice versa. A concrete implementation may just map the register onto 'this'.
  35 
  36 class AbstractRegisterImpl {
  37  protected:
  38   int value() const                              { return (int)(intx)this; }
  39 };
  40 
  41 
  42 //
  43 // Macros for use in defining Register instances.  We'd like to be
  44 // able to simply define const instances of the RegisterImpl* for each
  45 // of the registers needed on a system in a header file.  However many
  46 // compilers don't handle this very well and end up producing a
  47 // private definition in every file which includes the header file.
  48 // Along with the static constructors necessary for initialization it
  49 // can consume a significant amount of space in the result library.
  50 //
  51 // The following macros allow us to declare the instance in a .hpp and
  52 // produce an enumeration value which has the same number.  Then in a
  53 // .cpp the the register instance can be defined using the enumeration
  54 // value.  This avoids the use of static constructors and multiple
  55 // definitions per .cpp.  In addition #defines for the register can be
  56 // produced so that the constant registers can be inlined.  These
  57 // macros should not be used inside other macros, because you may get
  58 // multiple evaluations of the macros which can give bad results.
  59 //
  60 // Here are some example uses and expansions.  Note that the macro
  61 // invocation is terminated with a ;.
  62 //
  63 // CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
  64 //
  65 // extern const Register G0 ;
  66 // enum { G0_RegisterEnumValue = 0 } ;
  67 //
  68 // REGISTER_DECLARATION(Register, Gmethod, G5);
  69 //
  70 // extern const Register Gmethod ;
  71 // enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
  72 //
  73 // REGISTER_DEFINITION(Register, G0);
  74 //
  75 // const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
  76 //
  77 
  78 #define AS_REGISTER(type,name)         ((type)name##_##type##EnumValue)
  79 
  80 #define CONSTANT_REGISTER_DECLARATION(type, name, value) \
  81 extern const type name;                                  \
  82 enum { name##_##type##EnumValue = (value) }
  83 
  84 #define REGISTER_DECLARATION(type, name, value) \
  85 extern const type name;                         \
  86 enum { name##_##type##EnumValue = value##_##type##EnumValue }
  87 
  88 #define REGISTER_DEFINITION(type, name) \
  89 const type name = ((type)name##_##type##EnumValue)
  90 
  91 
  92 
  93 // Debugging support
  94 
  95 inline void assert_different_registers(
  96   AbstractRegister a,
  97   AbstractRegister b
  98 ) {
  99   assert(
 100     a != b,
 101     "registers must be different"
 102   );
 103 }
 104 
 105 
 106 inline void assert_different_registers(
 107   AbstractRegister a,
 108   AbstractRegister b,
 109   AbstractRegister c
 110 ) {
 111   assert(
 112     a != b && a != c
 113            && b != c,
 114     "registers must be different"
 115   );
 116 }
 117 
 118 
 119 inline void assert_different_registers(
 120   AbstractRegister a,
 121   AbstractRegister b,
 122   AbstractRegister c,
 123   AbstractRegister d
 124 ) {
 125   assert(
 126     a != b && a != c && a != d
 127            && b != c && b != d
 128                      && c != d,
 129     "registers must be different"
 130   );
 131 }
 132 
 133 
 134 inline void assert_different_registers(
 135   AbstractRegister a,
 136   AbstractRegister b,
 137   AbstractRegister c,
 138   AbstractRegister d,
 139   AbstractRegister e
 140 ) {
 141   assert(
 142     a != b && a != c && a != d && a != e
 143            && b != c && b != d && b != e
 144                      && c != d && c != e
 145                                && d != e,
 146     "registers must be different"
 147   );
 148 }
 149 
 150 
 151 inline void assert_different_registers(
 152   AbstractRegister a,
 153   AbstractRegister b,
 154   AbstractRegister c,
 155   AbstractRegister d,
 156   AbstractRegister e,
 157   AbstractRegister f
 158 ) {
 159   assert(
 160     a != b && a != c && a != d && a != e && a != f
 161            && b != c && b != d && b != e && b != f
 162                      && c != d && c != e && c != f
 163                                && d != e && d != f
 164                                          && e != f,
 165     "registers must be different"
 166   );
 167 }
 168 
 169 
 170 inline void assert_different_registers(
 171   AbstractRegister a,
 172   AbstractRegister b,
 173   AbstractRegister c,
 174   AbstractRegister d,
 175   AbstractRegister e,
 176   AbstractRegister f,
 177   AbstractRegister g
 178 ) {
 179   assert(
 180     a != b && a != c && a != d && a != e && a != f && a != g
 181            && b != c && b != d && b != e && b != f && b != g
 182                      && c != d && c != e && c != f && c != g
 183                                && d != e && d != f && d != g
 184                                          && e != f && e != g
 185                                                    && f != g,
 186     "registers must be different"
 187   );
 188 }
 189 
 190 
 191 inline void assert_different_registers(
 192   AbstractRegister a,
 193   AbstractRegister b,
 194   AbstractRegister c,
 195   AbstractRegister d,
 196   AbstractRegister e,
 197   AbstractRegister f,
 198   AbstractRegister g,
 199   AbstractRegister h
 200 ) {
 201   assert(
 202     a != b && a != c && a != d && a != e && a != f && a != g && a != h
 203            && b != c && b != d && b != e && b != f && b != g && b != h
 204                      && c != d && c != e && c != f && c != g && c != h
 205                                && d != e && d != f && d != g && d != h
 206                                          && e != f && e != g && e != h
 207                                                    && f != g && f != h
 208                                                              && g != h,
 209     "registers must be different"
 210   );
 211 }