1 /*
2  * Copyright (c) 2000, 2014, 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_VM_REGISTER_SPARC_HPP
26 #define CPU_SPARC_VM_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 
as_Register(int encoding)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
encoding() const70   int   encoding() const                              { assert(is_valid(), "invalid register"); return value(); }
71   const char* name() const;
72 
73   // testers
is_valid() const74   bool is_valid() const                               { return (0 <= (value()&0x7F) && (value()&0x7F) < number_of_registers); }
is_even() const75   bool is_even() const                                { return (encoding() & 1) == 0; }
is_in() const76   bool is_in() const                                  { return (encoding() >> log_set_size) == iset_no; }
is_local() const77   bool is_local() const                               { return (encoding() >> log_set_size) == lset_no; }
is_out() const78   bool is_out() const                                 { return (encoding() >> log_set_size) == oset_no; }
is_global() const79   bool is_global() const                              { return (encoding() >> log_set_size) == gset_no; }
80 
81   // derived registers, offsets, and addresses
successor() const82   Register successor() const                          { return as_Register(encoding() + 1); }
83 
input_number() const84   int input_number() const {
85     assert(is_in(), "must be input register");
86     return encoding() - ibase;
87   }
88 
after_save() const89   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 
after_restore() const94   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 
sp_offset_in_saved_window() const99   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
as_iRegister(int number)109 inline Register as_iRegister(int number)            { return as_Register(RegisterImpl::ibase + number); }
as_lRegister(int number)110 inline Register as_lRegister(int number)            { return as_Register(RegisterImpl::lbase + number); }
as_oRegister(int number)111 inline Register as_oRegister(int number)            { return as_Register(RegisterImpl::obase + number); }
as_gRegister(int 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
as_FloatRegister(int encoding)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
encoding() const183   int encoding() const { assert(is_valid(), "invalid register"); return value(); }
184 
185  public:
encoding(Width w) const186   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 
is_valid() const205   bool is_valid() const { return 0 <= value() && value() < number_of_registers; }
is_even() const206   bool is_even()  const { return (encoding() & 1) == 0; }
207 
208   const char* name() const;
209 
successor() const210   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:
as_SingleFloatRegister(int encoding)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:
as_DoubleFloatRegister(int encoding)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:
as_QuadFloatRegister(int encoding)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_VM_REGISTER_SPARC_HPP
341