1 /*
   2  * Copyright (c) 2000, 2019, 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 CPU_SPARC_REGISTER_SPARC_HPP
  26 #define CPU_SPARC_REGISTER_SPARC_HPP
  27 
  28 #include "asm/register.hpp"
  29 
  30 // forward declaration
  31 class Address;
  32 class VMRegImpl;
  33 typedef VMRegImpl* VMReg;
  34 
  35 
  36 // Use Register as shortcut
  37 class RegisterImpl;
  38 typedef RegisterImpl* Register;
  39 
  40 
  41 inline Register as_Register(int encoding) {
  42   return (Register)(intptr_t) encoding;
  43 }
  44 
  45 // The implementation of integer registers for the SPARC architecture
  46 class RegisterImpl: public AbstractRegisterImpl {
  47  public:
  48   enum {
  49     log_set_size        = 3,                          // the number of bits to encode the set register number
  50     number_of_sets      = 4,                          // the number of registers sets (in, local, out, global)
  51     number_of_registers = number_of_sets << log_set_size,
  52 
  53     iset_no = 3,  ibase = iset_no << log_set_size,    // the in     register set
  54     lset_no = 2,  lbase = lset_no << log_set_size,    // the local  register set
  55     oset_no = 1,  obase = oset_no << log_set_size,    // the output register set
  56     gset_no = 0,  gbase = gset_no << log_set_size     // the global register set
  57   };
  58 
  59 
  60   friend Register as_Register(int encoding);
  61   // set specific construction
  62   friend Register as_iRegister(int number);
  63   friend Register as_lRegister(int number);
  64   friend Register as_oRegister(int number);
  65   friend Register as_gRegister(int number);
  66 
  67   inline VMReg as_VMReg();
  68 
  69   // accessors
  70   int   encoding() const                              { assert(is_valid(), "invalid register"); return value(); }
  71   const char* name() const;
  72 
  73   // testers
  74   bool is_valid() const                               { return (0 <= (value()&0x7F) && (value()&0x7F) < number_of_registers); }
  75   bool is_even() const                                { return (encoding() & 1) == 0; }
  76   bool is_in() const                                  { return (encoding() >> log_set_size) == iset_no; }
  77   bool is_local() const                               { return (encoding() >> log_set_size) == lset_no; }
  78   bool is_out() const                                 { return (encoding() >> log_set_size) == oset_no; }
  79   bool is_global() const                              { return (encoding() >> log_set_size) == gset_no; }
  80 
  81   // derived registers, offsets, and addresses
  82   Register successor() const                          { return as_Register(encoding() + 1); }
  83 
  84   int input_number() const {
  85     assert(is_in(), "must be input register");
  86     return encoding() - ibase;
  87   }
  88 
  89   Register after_save() const {
  90     assert(is_out() || is_global(), "register not visible after save");
  91     return is_out() ? as_Register(encoding() + (ibase - obase)) : (const Register)this;
  92   }
  93 
  94   Register after_restore() const {
  95     assert(is_in() || is_global(), "register not visible after restore");
  96     return is_in() ? as_Register(encoding() + (obase - ibase)) : (const Register)this;
  97   }
  98 
  99   int sp_offset_in_saved_window() const {
 100     assert(is_in() || is_local(), "only i and l registers are saved in frame");
 101     return encoding() - lbase;
 102   }
 103 
 104   inline Address address_in_saved_window() const;     // implemented in assembler_sparc.hpp
 105 };
 106 
 107 
 108 // set specific construction
 109 inline Register as_iRegister(int number)            { return as_Register(RegisterImpl::ibase + number); }
 110 inline Register as_lRegister(int number)            { return as_Register(RegisterImpl::lbase + number); }
 111 inline Register as_oRegister(int number)            { return as_Register(RegisterImpl::obase + number); }
 112 inline Register as_gRegister(int number)            { return as_Register(RegisterImpl::gbase + number); }
 113 
 114 // The integer registers of the SPARC architecture
 115 
 116 CONSTANT_REGISTER_DECLARATION(Register, noreg , (-1));
 117 
 118 CONSTANT_REGISTER_DECLARATION(Register, G0    , (RegisterImpl::gbase + 0));
 119 CONSTANT_REGISTER_DECLARATION(Register, G1    , (RegisterImpl::gbase + 1));
 120 CONSTANT_REGISTER_DECLARATION(Register, G2    , (RegisterImpl::gbase + 2));
 121 CONSTANT_REGISTER_DECLARATION(Register, G3    , (RegisterImpl::gbase + 3));
 122 CONSTANT_REGISTER_DECLARATION(Register, G4    , (RegisterImpl::gbase + 4));
 123 CONSTANT_REGISTER_DECLARATION(Register, G5    , (RegisterImpl::gbase + 5));
 124 CONSTANT_REGISTER_DECLARATION(Register, G6    , (RegisterImpl::gbase + 6));
 125 CONSTANT_REGISTER_DECLARATION(Register, G7    , (RegisterImpl::gbase + 7));
 126 
 127 CONSTANT_REGISTER_DECLARATION(Register, O0    , (RegisterImpl::obase + 0));
 128 CONSTANT_REGISTER_DECLARATION(Register, O1    , (RegisterImpl::obase + 1));
 129 CONSTANT_REGISTER_DECLARATION(Register, O2    , (RegisterImpl::obase + 2));
 130 CONSTANT_REGISTER_DECLARATION(Register, O3    , (RegisterImpl::obase + 3));
 131 CONSTANT_REGISTER_DECLARATION(Register, O4    , (RegisterImpl::obase + 4));
 132 CONSTANT_REGISTER_DECLARATION(Register, O5    , (RegisterImpl::obase + 5));
 133 CONSTANT_REGISTER_DECLARATION(Register, O6    , (RegisterImpl::obase + 6));
 134 CONSTANT_REGISTER_DECLARATION(Register, O7    , (RegisterImpl::obase + 7));
 135 
 136 CONSTANT_REGISTER_DECLARATION(Register, L0    , (RegisterImpl::lbase + 0));
 137 CONSTANT_REGISTER_DECLARATION(Register, L1    , (RegisterImpl::lbase + 1));
 138 CONSTANT_REGISTER_DECLARATION(Register, L2    , (RegisterImpl::lbase + 2));
 139 CONSTANT_REGISTER_DECLARATION(Register, L3    , (RegisterImpl::lbase + 3));
 140 CONSTANT_REGISTER_DECLARATION(Register, L4    , (RegisterImpl::lbase + 4));
 141 CONSTANT_REGISTER_DECLARATION(Register, L5    , (RegisterImpl::lbase + 5));
 142 CONSTANT_REGISTER_DECLARATION(Register, L6    , (RegisterImpl::lbase + 6));
 143 CONSTANT_REGISTER_DECLARATION(Register, L7    , (RegisterImpl::lbase + 7));
 144 
 145 CONSTANT_REGISTER_DECLARATION(Register, I0    , (RegisterImpl::ibase + 0));
 146 CONSTANT_REGISTER_DECLARATION(Register, I1    , (RegisterImpl::ibase + 1));
 147 CONSTANT_REGISTER_DECLARATION(Register, I2    , (RegisterImpl::ibase + 2));
 148 CONSTANT_REGISTER_DECLARATION(Register, I3    , (RegisterImpl::ibase + 3));
 149 CONSTANT_REGISTER_DECLARATION(Register, I4    , (RegisterImpl::ibase + 4));
 150 CONSTANT_REGISTER_DECLARATION(Register, I5    , (RegisterImpl::ibase + 5));
 151 CONSTANT_REGISTER_DECLARATION(Register, I6    , (RegisterImpl::ibase + 6));
 152 CONSTANT_REGISTER_DECLARATION(Register, I7    , (RegisterImpl::ibase + 7));
 153 
 154 CONSTANT_REGISTER_DECLARATION(Register, FP    , (RegisterImpl::ibase + 6));
 155 CONSTANT_REGISTER_DECLARATION(Register, SP    , (RegisterImpl::obase + 6));
 156 
 157 // Use FloatRegister as shortcut
 158 class FloatRegisterImpl;
 159 typedef FloatRegisterImpl* FloatRegister;
 160 
 161 
 162 // construction
 163 inline FloatRegister as_FloatRegister(int encoding) {
 164   return (FloatRegister)(intptr_t)encoding;
 165 }
 166 
 167 // The implementation of float registers for the SPARC architecture
 168 
 169 class FloatRegisterImpl: public AbstractRegisterImpl {
 170  public:
 171   enum {
 172     number_of_registers = 64
 173   };
 174 
 175   enum Width {
 176     S = 1,  D = 2,  Q = 3
 177   };
 178 
 179   // construction
 180   inline VMReg as_VMReg( );
 181 
 182   // accessors
 183   int encoding() const { assert(is_valid(), "invalid register"); return value(); }
 184 
 185  public:
 186   int encoding(Width w) const {
 187     const int c = encoding();
 188     switch (w) {
 189       case S:
 190         assert(c < 32, "bad single float register");
 191         return c;
 192 
 193       case D:
 194         assert(c < 64  &&  (c & 1) == 0, "bad double float register");
 195         return (c & 0x1e) | ((c & 0x20) >> 5);
 196 
 197       case Q:
 198         assert(c < 64  &&  (c & 3) == 0, "bad quad float register");
 199         return (c & 0x1c) | ((c & 0x20) >> 5);
 200     }
 201     ShouldNotReachHere();
 202     return -1;
 203   }
 204 
 205   bool is_valid() const { return 0 <= value() && value() < number_of_registers; }
 206   bool is_even()  const { return (encoding() & 1) == 0; }
 207 
 208   const char* name() const;
 209 
 210   FloatRegister successor() const { return as_FloatRegister(encoding() + 1); }
 211 };
 212 
 213 
 214 // The float registers of the SPARC architecture
 215 
 216 CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg , (-1));
 217 
 218 CONSTANT_REGISTER_DECLARATION(FloatRegister, F0     , ( 0));
 219 CONSTANT_REGISTER_DECLARATION(FloatRegister, F1     , ( 1));
 220 CONSTANT_REGISTER_DECLARATION(FloatRegister, F2     , ( 2));
 221 CONSTANT_REGISTER_DECLARATION(FloatRegister, F3     , ( 3));
 222 CONSTANT_REGISTER_DECLARATION(FloatRegister, F4     , ( 4));
 223 CONSTANT_REGISTER_DECLARATION(FloatRegister, F5     , ( 5));
 224 CONSTANT_REGISTER_DECLARATION(FloatRegister, F6     , ( 6));
 225 CONSTANT_REGISTER_DECLARATION(FloatRegister, F7     , ( 7));
 226 CONSTANT_REGISTER_DECLARATION(FloatRegister, F8     , ( 8));
 227 CONSTANT_REGISTER_DECLARATION(FloatRegister, F9     , ( 9));
 228 CONSTANT_REGISTER_DECLARATION(FloatRegister, F10    , (10));
 229 CONSTANT_REGISTER_DECLARATION(FloatRegister, F11    , (11));
 230 CONSTANT_REGISTER_DECLARATION(FloatRegister, F12    , (12));
 231 CONSTANT_REGISTER_DECLARATION(FloatRegister, F13    , (13));
 232 CONSTANT_REGISTER_DECLARATION(FloatRegister, F14    , (14));
 233 CONSTANT_REGISTER_DECLARATION(FloatRegister, F15    , (15));
 234 CONSTANT_REGISTER_DECLARATION(FloatRegister, F16    , (16));
 235 CONSTANT_REGISTER_DECLARATION(FloatRegister, F17    , (17));
 236 CONSTANT_REGISTER_DECLARATION(FloatRegister, F18    , (18));
 237 CONSTANT_REGISTER_DECLARATION(FloatRegister, F19    , (19));
 238 CONSTANT_REGISTER_DECLARATION(FloatRegister, F20    , (20));
 239 CONSTANT_REGISTER_DECLARATION(FloatRegister, F21    , (21));
 240 CONSTANT_REGISTER_DECLARATION(FloatRegister, F22    , (22));
 241 CONSTANT_REGISTER_DECLARATION(FloatRegister, F23    , (23));
 242 CONSTANT_REGISTER_DECLARATION(FloatRegister, F24    , (24));
 243 CONSTANT_REGISTER_DECLARATION(FloatRegister, F25    , (25));
 244 CONSTANT_REGISTER_DECLARATION(FloatRegister, F26    , (26));
 245 CONSTANT_REGISTER_DECLARATION(FloatRegister, F27    , (27));
 246 CONSTANT_REGISTER_DECLARATION(FloatRegister, F28    , (28));
 247 CONSTANT_REGISTER_DECLARATION(FloatRegister, F29    , (29));
 248 CONSTANT_REGISTER_DECLARATION(FloatRegister, F30    , (30));
 249 CONSTANT_REGISTER_DECLARATION(FloatRegister, F31    , (31));
 250 
 251 CONSTANT_REGISTER_DECLARATION(FloatRegister, F32    , (32));
 252 CONSTANT_REGISTER_DECLARATION(FloatRegister, F34    , (34));
 253 CONSTANT_REGISTER_DECLARATION(FloatRegister, F36    , (36));
 254 CONSTANT_REGISTER_DECLARATION(FloatRegister, F38    , (38));
 255 CONSTANT_REGISTER_DECLARATION(FloatRegister, F40    , (40));
 256 CONSTANT_REGISTER_DECLARATION(FloatRegister, F42    , (42));
 257 CONSTANT_REGISTER_DECLARATION(FloatRegister, F44    , (44));
 258 CONSTANT_REGISTER_DECLARATION(FloatRegister, F46    , (46));
 259 CONSTANT_REGISTER_DECLARATION(FloatRegister, F48    , (48));
 260 CONSTANT_REGISTER_DECLARATION(FloatRegister, F50    , (50));
 261 CONSTANT_REGISTER_DECLARATION(FloatRegister, F52    , (52));
 262 CONSTANT_REGISTER_DECLARATION(FloatRegister, F54    , (54));
 263 CONSTANT_REGISTER_DECLARATION(FloatRegister, F56    , (56));
 264 CONSTANT_REGISTER_DECLARATION(FloatRegister, F58    , (58));
 265 CONSTANT_REGISTER_DECLARATION(FloatRegister, F60    , (60));
 266 CONSTANT_REGISTER_DECLARATION(FloatRegister, F62    , (62));
 267 
 268 // Maximum number of incoming arguments that can be passed in i registers.
 269 const int SPARC_ARGS_IN_REGS_NUM = 6;
 270 
 271 class ConcreteRegisterImpl : public AbstractRegisterImpl {
 272  public:
 273   enum {
 274     // This number must be large enough to cover REG_COUNT (defined by c2) registers.
 275     // There is no requirement that any ordering here matches any ordering c2 gives
 276     // it's optoregs.
 277     number_of_registers = 2*RegisterImpl::number_of_registers +
 278                             FloatRegisterImpl::number_of_registers +
 279                             1 + // ccr
 280                             4  //  fcc
 281   };
 282   static const int max_gpr;
 283   static const int max_fpr;
 284 
 285 };
 286 
 287 // Single, Double and Quad fp reg classes.  These exist to map the ADLC
 288 // encoding for a floating point register, to the FloatRegister number
 289 // desired by the macroassembler.  A FloatRegister is a number between
 290 // 0 and 63 passed around as a pointer.  For ADLC, an fp register encoding
 291 // is the actual bit encoding used by the sparc hardware.  When ADLC used
 292 // the macroassembler to generate an instruction that references, e.g., a
 293 // double fp reg, it passed the bit encoding to the macroassembler via
 294 // as_FloatRegister, which, for double regs > 30, returns an illegal
 295 // register number.
 296 //
 297 // Therefore we provide the following classes for use by ADLC.  Their
 298 // sole purpose is to convert from sparc register encodings to FloatRegisters.
 299 // At some future time, we might replace FloatRegister with these classes,
 300 // hence the definitions of as_xxxFloatRegister as class methods rather
 301 // than as external inline routines.
 302 
 303 class SingleFloatRegisterImpl;
 304 typedef SingleFloatRegisterImpl *SingleFloatRegister;
 305 
 306 inline FloatRegister as_SingleFloatRegister(int encoding);
 307 class SingleFloatRegisterImpl {
 308  public:
 309   friend inline FloatRegister as_SingleFloatRegister(int encoding) {
 310     assert(encoding < 32, "bad single float register encoding");
 311     return as_FloatRegister(encoding);
 312   }
 313 };
 314 
 315 
 316 class DoubleFloatRegisterImpl;
 317 typedef DoubleFloatRegisterImpl *DoubleFloatRegister;
 318 
 319 inline FloatRegister as_DoubleFloatRegister(int encoding);
 320 class DoubleFloatRegisterImpl {
 321  public:
 322   friend inline FloatRegister as_DoubleFloatRegister(int encoding) {
 323     assert(encoding < 32, "bad double float register encoding");
 324     return as_FloatRegister( ((encoding & 1) << 5) | (encoding & 0x1e) );
 325   }
 326 };
 327 
 328 
 329 class QuadFloatRegisterImpl;
 330 typedef QuadFloatRegisterImpl *QuadFloatRegister;
 331 
 332 class QuadFloatRegisterImpl {
 333  public:
 334   friend FloatRegister as_QuadFloatRegister(int encoding) {
 335     assert(encoding < 32 && ((encoding & 2) == 0), "bad quad float register encoding");
 336     return as_FloatRegister( ((encoding & 1) << 5) | (encoding & 0x1c) );
 337   }
 338 };
 339 
 340 #endif // CPU_SPARC_REGISTER_SPARC_HPP