1 /*
   2  * Copyright (c) 2000, 2016, 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/debug.hpp"
  29 #include "utilities/globalDefinitions.hpp"
  30 #include "utilities/macros.hpp"
  31 
  32 // Use AbstractRegister as shortcut
  33 class AbstractRegisterImpl;
  34 typedef AbstractRegisterImpl* AbstractRegister;
  35 
  36 
  37 // The super class for platform specific registers. Instead of using value objects,
  38 // registers are implemented as pointers. Subclassing is used so all registers can
  39 // use the debugging suport below. No virtual functions are used for efficiency.
  40 // They are canonicalized; i.e., registers are equal if their pointers are equal,
  41 // and vice versa. A concrete implementation may just map the register onto 'this'.
  42 
  43 class AbstractRegisterImpl {
  44  protected:
  45   int value() const                              { return (int)(intx)this; }
  46 };
  47 
  48 
  49 //
  50 // Macros for use in defining Register instances.  We'd like to be
  51 // able to simply define const instances of the RegisterImpl* for each
  52 // of the registers needed on a system in a header file.  However many
  53 // compilers don't handle this very well and end up producing a
  54 // private definition in every file which includes the header file.
  55 // Along with the static constructors necessary for initialization it
  56 // can consume a significant amount of space in the result library.
  57 //
  58 // The following macros allow us to declare the instance in a .hpp and
  59 // produce an enumeration value which has the same number.  Then in a
  60 // .cpp the the register instance can be defined using the enumeration
  61 // value.  This avoids the use of static constructors and multiple
  62 // definitions per .cpp.  In addition #defines for the register can be
  63 // produced so that the constant registers can be inlined.  These
  64 // macros should not be used inside other macros, because you may get
  65 // multiple evaluations of the macros which can give bad results.
  66 //
  67 // Here are some example uses and expansions.  Note that the macro
  68 // invocation is terminated with a ;.
  69 //
  70 // CONSTANT_REGISTER_DECLARATION(Register, G0, 0);
  71 //
  72 // extern const Register G0 ;
  73 // enum { G0_RegisterEnumValue = 0 } ;
  74 //
  75 // REGISTER_DECLARATION(Register, Gmethod, G5);
  76 //
  77 // extern const Register Gmethod ;
  78 // enum { Gmethod_RegisterEnumValue = G5_RegisterEnumValue } ;
  79 //
  80 // REGISTER_DEFINITION(Register, G0);
  81 //
  82 // const Register G0 = ( ( Register ) G0_RegisterEnumValue ) ;
  83 //
  84 
  85 #define AS_REGISTER(type,name)         ((type)name##_##type##EnumValue)
  86 
  87 #define CONSTANT_REGISTER_DECLARATION(type, name, value) \
  88 extern const type name;                                  \
  89 enum { name##_##type##EnumValue = (value) }
  90 
  91 #define REGISTER_DECLARATION(type, name, value) \
  92 extern const type name;                         \
  93 enum { name##_##type##EnumValue = value##_##type##EnumValue }
  94 
  95 #define REGISTER_DEFINITION(type, name) \
  96 const type name = ((type)name##_##type##EnumValue)
  97 
  98 #include CPU_HEADER(register)
  99 
 100 // Debugging support
 101 
 102 inline void assert_different_registers(
 103   AbstractRegister a,
 104   AbstractRegister b
 105 ) {
 106   assert(
 107     a != b,
 108     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT "", p2i(a), p2i(b)
 109   );
 110 }
 111 
 112 
 113 inline void assert_different_registers(
 114   AbstractRegister a,
 115   AbstractRegister b,
 116   AbstractRegister c
 117 ) {
 118   assert(
 119     a != b && a != c
 120            && b != c,
 121     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 122     ", c=" INTPTR_FORMAT "",
 123     p2i(a), p2i(b), p2i(c)
 124   );
 125 }
 126 
 127 
 128 inline void assert_different_registers(
 129   AbstractRegister a,
 130   AbstractRegister b,
 131   AbstractRegister c,
 132   AbstractRegister d
 133 ) {
 134   assert(
 135     a != b && a != c && a != d
 136            && b != c && b != d
 137                      && c != d,
 138     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 139     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT "",
 140     p2i(a), p2i(b), p2i(c), p2i(d)
 141   );
 142 }
 143 
 144 
 145 inline void assert_different_registers(
 146   AbstractRegister a,
 147   AbstractRegister b,
 148   AbstractRegister c,
 149   AbstractRegister d,
 150   AbstractRegister e
 151 ) {
 152   assert(
 153     a != b && a != c && a != d && a != e
 154            && b != c && b != d && b != e
 155                      && c != d && c != e
 156                                && d != e,
 157     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 158     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT "",
 159     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e)
 160   );
 161 }
 162 
 163 
 164 inline void assert_different_registers(
 165   AbstractRegister a,
 166   AbstractRegister b,
 167   AbstractRegister c,
 168   AbstractRegister d,
 169   AbstractRegister e,
 170   AbstractRegister f
 171 ) {
 172   assert(
 173     a != b && a != c && a != d && a != e && a != f
 174            && b != c && b != d && b != e && b != f
 175                      && c != d && c != e && c != f
 176                                && d != e && d != f
 177                                          && e != f,
 178     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 179     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 180     ", f=" INTPTR_FORMAT "",
 181     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f)
 182   );
 183 }
 184 
 185 
 186 inline void assert_different_registers(
 187   AbstractRegister a,
 188   AbstractRegister b,
 189   AbstractRegister c,
 190   AbstractRegister d,
 191   AbstractRegister e,
 192   AbstractRegister f,
 193   AbstractRegister g
 194 ) {
 195   assert(
 196     a != b && a != c && a != d && a != e && a != f && a != g
 197            && b != c && b != d && b != e && b != f && b != g
 198                      && c != d && c != e && c != f && c != g
 199                                && d != e && d != f && d != g
 200                                          && e != f && e != g
 201                                                    && f != g,
 202     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 203     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 204     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT "",
 205     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g)
 206   );
 207 }
 208 
 209 
 210 inline void assert_different_registers(
 211   AbstractRegister a,
 212   AbstractRegister b,
 213   AbstractRegister c,
 214   AbstractRegister d,
 215   AbstractRegister e,
 216   AbstractRegister f,
 217   AbstractRegister g,
 218   AbstractRegister h
 219 ) {
 220   assert(
 221     a != b && a != c && a != d && a != e && a != f && a != g && a != h
 222            && b != c && b != d && b != e && b != f && b != g && b != h
 223                      && c != d && c != e && c != f && c != g && c != h
 224                                && d != e && d != f && d != g && d != h
 225                                          && e != f && e != g && e != h
 226                                                    && f != g && f != h
 227                                                              && g != h,
 228     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 229     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 230     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT "",
 231     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h)
 232   );
 233 }
 234 
 235 
 236 inline void assert_different_registers(
 237   AbstractRegister a,
 238   AbstractRegister b,
 239   AbstractRegister c,
 240   AbstractRegister d,
 241   AbstractRegister e,
 242   AbstractRegister f,
 243   AbstractRegister g,
 244   AbstractRegister h,
 245   AbstractRegister i
 246 ) {
 247   assert(
 248     a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
 249            && b != c && b != d && b != e && b != f && b != g && b != h && b != i
 250                      && c != d && c != e && c != f && c != g && c != h && c != i
 251                                && d != e && d != f && d != g && d != h && d != i
 252                                          && e != f && e != g && e != h && e != i
 253                                                    && f != g && f != h && f != i
 254                                                              && g != h && g != i
 255                                                                        && h != i,
 256     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 257     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 258     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
 259     ", i=" INTPTR_FORMAT "",
 260     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i)
 261   );
 262 }
 263 
 264 inline void assert_different_registers(
 265   AbstractRegister a,
 266   AbstractRegister b,
 267   AbstractRegister c,
 268   AbstractRegister d,
 269   AbstractRegister e,
 270   AbstractRegister f,
 271   AbstractRegister g,
 272   AbstractRegister h,
 273   AbstractRegister i,
 274   AbstractRegister j
 275 ) {
 276   assert(
 277     a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j
 278            && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j
 279                      && c != d && c != e && c != f && c != g && c != h && c != i && c != j
 280                                && d != e && d != f && d != g && d != h && d != i && d != j
 281                                          && e != f && e != g && e != h && e != i && e != j
 282                                                    && f != g && f != h && f != i && f != j
 283                                                              && g != h && g != i && g != j
 284                                                                        && h != i && h != j
 285                                                                                  && i != j,
 286     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 287     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 288     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
 289     ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT "",
 290     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j)
 291   );
 292 }
 293 
 294 inline void assert_different_registers(
 295   AbstractRegister a,
 296   AbstractRegister b,
 297   AbstractRegister c,
 298   AbstractRegister d,
 299   AbstractRegister e,
 300   AbstractRegister f,
 301   AbstractRegister g,
 302   AbstractRegister h,
 303   AbstractRegister i,
 304   AbstractRegister j,
 305   AbstractRegister k
 306 ) {
 307   assert(
 308     a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k
 309            && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k
 310                      && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k
 311                                && d != e && d != f && d != g && d != h && d != i && d != j && d !=k
 312                                          && e != f && e != g && e != h && e != i && e != j && e !=k
 313                                                    && f != g && f != h && f != i && f != j && f !=k
 314                                                              && g != h && g != i && g != j && g !=k
 315                                                                        && h != i && h != j && h !=k
 316                                                                                  && i != j && i !=k
 317                                                                                            && j !=k,
 318     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 319     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 320     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
 321     ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT "",
 322     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k)
 323   );
 324 }
 325 
 326 inline void assert_different_registers(
 327   AbstractRegister a,
 328   AbstractRegister b,
 329   AbstractRegister c,
 330   AbstractRegister d,
 331   AbstractRegister e,
 332   AbstractRegister f,
 333   AbstractRegister g,
 334   AbstractRegister h,
 335   AbstractRegister i,
 336   AbstractRegister j,
 337   AbstractRegister k,
 338   AbstractRegister l
 339 ) {
 340   assert(
 341     a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i && a != j && a !=k && a !=l
 342            && b != c && b != d && b != e && b != f && b != g && b != h && b != i && b != j && b !=k && b !=l
 343                      && c != d && c != e && c != f && c != g && c != h && c != i && c != j && c !=k && c !=l
 344                                && d != e && d != f && d != g && d != h && d != i && d != j && d !=k && d !=l
 345                                          && e != f && e != g && e != h && e != i && e != j && e !=k && e !=l
 346                                                    && f != g && f != h && f != i && f != j && f !=k && f !=l
 347                                                              && g != h && g != i && g != j && g !=k && g !=l
 348                                                                        && h != i && h != j && h !=k && h !=l
 349                                                                                  && i != j && i !=k && i !=l
 350                                                                                            && j !=k && j !=l
 351                                                                                                     && k !=l,
 352     "registers must be different: a=" INTPTR_FORMAT ", b=" INTPTR_FORMAT
 353     ", c=" INTPTR_FORMAT ", d=" INTPTR_FORMAT ", e=" INTPTR_FORMAT
 354     ", f=" INTPTR_FORMAT ", g=" INTPTR_FORMAT ", h=" INTPTR_FORMAT
 355     ", i=" INTPTR_FORMAT ", j=" INTPTR_FORMAT ", k=" INTPTR_FORMAT
 356     ", l=" INTPTR_FORMAT "",
 357     p2i(a), p2i(b), p2i(c), p2i(d), p2i(e), p2i(f), p2i(g), p2i(h), p2i(i), p2i(j), p2i(k), p2i(l)
 358   );
 359 }
 360 
 361 #endif // SHARE_VM_ASM_REGISTER_HPP