| 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_X86_REGISTER_X86_HPP | 
| 26 | #define CPU_X86_REGISTER_X86_HPP | 
| 27 |  | 
| 28 | #include "asm/register.hpp" | 
| 29 |  | 
| 30 | class VMRegImpl; | 
| 31 | typedef VMRegImpl* VMReg; | 
| 32 |  | 
| 33 | // Use Register as shortcut | 
| 34 | class RegisterImpl; | 
| 35 | typedef RegisterImpl* Register; | 
| 36 |  | 
| 37 |  | 
| 38 | // The implementation of integer registers for the ia32 architecture | 
| 39 | inline Register as_Register(int encoding) { | 
| 40 |   return (Register)(intptr_t) encoding; | 
| 41 | } | 
| 42 |  | 
| 43 | class RegisterImpl: public AbstractRegisterImpl { | 
| 44 |  public: | 
| 45 |   enum { | 
| 46 | #ifndef AMD64 | 
| 47 |     number_of_registers      = 8, | 
| 48 |     number_of_byte_registers = 4, | 
| 49 |     max_slots_per_register   = 1 | 
| 50 | #else | 
| 51 |     number_of_registers      = 16, | 
| 52 |     number_of_byte_registers = 16, | 
| 53 |     max_slots_per_register   = 1 | 
| 54 | #endif // AMD64 | 
| 55 |   }; | 
| 56 |  | 
| 57 |   // derived registers, offsets, and addresses | 
| 58 |   Register successor() const                          { return as_Register(encoding() + 1); } | 
| 59 |  | 
| 60 |   // construction | 
| 61 |   inline friend Register as_Register(int encoding); | 
| 62 |  | 
| 63 |   inline VMReg as_VMReg(); | 
| 64 |  | 
| 65 |   // accessors | 
| 66 |   int   encoding() const                         { assert(is_valid(), "invalid register" ); return (intptr_t)this; } | 
| 67 |   bool  is_valid() const                         { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } | 
| 68 |   bool  has_byte_register() const                { return 0 <= (intptr_t)this && (intptr_t)this < number_of_byte_registers; } | 
| 69 |   const char* name() const; | 
| 70 | }; | 
| 71 |  | 
| 72 | // The integer registers of the ia32/amd64 architecture | 
| 73 |  | 
| 74 | CONSTANT_REGISTER_DECLARATION(Register, noreg, (-1)); | 
| 75 |  | 
| 76 |  | 
| 77 | CONSTANT_REGISTER_DECLARATION(Register, rax,    (0)); | 
| 78 | CONSTANT_REGISTER_DECLARATION(Register, rcx,    (1)); | 
| 79 | CONSTANT_REGISTER_DECLARATION(Register, rdx,    (2)); | 
| 80 | CONSTANT_REGISTER_DECLARATION(Register, rbx,    (3)); | 
| 81 | CONSTANT_REGISTER_DECLARATION(Register, rsp,    (4)); | 
| 82 | CONSTANT_REGISTER_DECLARATION(Register, rbp,    (5)); | 
| 83 | CONSTANT_REGISTER_DECLARATION(Register, rsi,    (6)); | 
| 84 | CONSTANT_REGISTER_DECLARATION(Register, rdi,    (7)); | 
| 85 | #ifdef AMD64 | 
| 86 | CONSTANT_REGISTER_DECLARATION(Register, r8,     (8)); | 
| 87 | CONSTANT_REGISTER_DECLARATION(Register, r9,     (9)); | 
| 88 | CONSTANT_REGISTER_DECLARATION(Register, r10,   (10)); | 
| 89 | CONSTANT_REGISTER_DECLARATION(Register, r11,   (11)); | 
| 90 | CONSTANT_REGISTER_DECLARATION(Register, r12,   (12)); | 
| 91 | CONSTANT_REGISTER_DECLARATION(Register, r13,   (13)); | 
| 92 | CONSTANT_REGISTER_DECLARATION(Register, r14,   (14)); | 
| 93 | CONSTANT_REGISTER_DECLARATION(Register, r15,   (15)); | 
| 94 | #endif // AMD64 | 
| 95 |  | 
| 96 | // Use FloatRegister as shortcut | 
| 97 | class FloatRegisterImpl; | 
| 98 | typedef FloatRegisterImpl* FloatRegister; | 
| 99 |  | 
| 100 | inline FloatRegister as_FloatRegister(int encoding) { | 
| 101 |   return (FloatRegister)(intptr_t) encoding; | 
| 102 | } | 
| 103 |  | 
| 104 | // The implementation of floating point registers for the ia32 architecture | 
| 105 | class FloatRegisterImpl: public AbstractRegisterImpl { | 
| 106 |  public: | 
| 107 |   enum { | 
| 108 |     number_of_registers = 8 | 
| 109 |   }; | 
| 110 |  | 
| 111 |   // construction | 
| 112 |   inline friend FloatRegister as_FloatRegister(int encoding); | 
| 113 |  | 
| 114 |   inline VMReg as_VMReg(); | 
| 115 |  | 
| 116 |   // derived registers, offsets, and addresses | 
| 117 |  | 
| 118 |   FloatRegister successor() const                          { return as_FloatRegister(encoding() + 1); } | 
| 119 |  | 
| 120 |   // accessors | 
| 121 |   int   encoding() const                          { assert(is_valid(), "invalid register" ); return (intptr_t)this; } | 
| 122 |   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } | 
| 123 |   const char* name() const; | 
| 124 |  | 
| 125 | }; | 
| 126 |  | 
| 127 | CONSTANT_REGISTER_DECLARATION(FloatRegister, fnoreg, (-1)); | 
| 128 |  | 
| 129 | // Use XMMRegister as shortcut | 
| 130 | class XMMRegisterImpl; | 
| 131 | typedef XMMRegisterImpl* XMMRegister; | 
| 132 |  | 
| 133 | // Use MMXRegister as shortcut | 
| 134 | class MMXRegisterImpl; | 
| 135 | typedef MMXRegisterImpl* MMXRegister; | 
| 136 |  | 
| 137 | inline XMMRegister as_XMMRegister(int encoding) { | 
| 138 |   return (XMMRegister)(intptr_t)encoding; | 
| 139 | } | 
| 140 |  | 
| 141 | inline MMXRegister as_MMXRegister(int encoding) { | 
| 142 |   return (MMXRegister)(intptr_t)encoding; | 
| 143 | } | 
| 144 |  | 
| 145 | // The implementation of XMM registers for the IA32 architecture | 
| 146 | class XMMRegisterImpl: public AbstractRegisterImpl { | 
| 147 |  public: | 
| 148 |   enum { | 
| 149 | #ifndef AMD64 | 
| 150 |     number_of_registers = 8, | 
| 151 |     max_slots_per_register = 16   // 512-bit | 
| 152 | #else | 
| 153 |     number_of_registers = 32, | 
| 154 |     max_slots_per_register = 16   // 512-bit | 
| 155 | #endif // AMD64 | 
| 156 |   }; | 
| 157 |  | 
| 158 |   // construction | 
| 159 |   friend XMMRegister as_XMMRegister(int encoding); | 
| 160 |  | 
| 161 |   inline VMReg as_VMReg(); | 
| 162 |  | 
| 163 |   // derived registers, offsets, and addresses | 
| 164 |   XMMRegister successor() const                          { return as_XMMRegister(encoding() + 1); } | 
| 165 |  | 
| 166 |   // accessors | 
| 167 |   int   encoding() const                          { assert(is_valid(), "invalid register (%d)" , (int)(intptr_t)this ); return (intptr_t)this; } | 
| 168 |   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } | 
| 169 |   const char* name() const; | 
| 170 |   const char* sub_word_name(int offset) const; | 
| 171 | }; | 
| 172 |  | 
| 173 |  | 
| 174 | // The XMM registers, for P3 and up chips | 
| 175 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xnoreg , (-1)); | 
| 176 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm0 , ( 0)); | 
| 177 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm1 , ( 1)); | 
| 178 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm2 , ( 2)); | 
| 179 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm3 , ( 3)); | 
| 180 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm4 , ( 4)); | 
| 181 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm5 , ( 5)); | 
| 182 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm6 , ( 6)); | 
| 183 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm7 , ( 7)); | 
| 184 | #ifdef AMD64 | 
| 185 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm8,      (8)); | 
| 186 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm9,      (9)); | 
| 187 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm10,    (10)); | 
| 188 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm11,    (11)); | 
| 189 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm12,    (12)); | 
| 190 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm13,    (13)); | 
| 191 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm14,    (14)); | 
| 192 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm15,    (15)); | 
| 193 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm16,    (16)); | 
| 194 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm17,    (17)); | 
| 195 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm18,    (18)); | 
| 196 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm19,    (19)); | 
| 197 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm20,    (20)); | 
| 198 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm21,    (21)); | 
| 199 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm22,    (22)); | 
| 200 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm23,    (23)); | 
| 201 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm24,    (24)); | 
| 202 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm25,    (25)); | 
| 203 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm26,    (26)); | 
| 204 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm27,    (27)); | 
| 205 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm28,    (28)); | 
| 206 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm29,    (29)); | 
| 207 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm30,    (30)); | 
| 208 | CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm31,    (31)); | 
| 209 | #endif // AMD64 | 
| 210 |  | 
| 211 | // Only used by the 32bit stubGenerator. These can't be described by vmreg and hence | 
| 212 | // can't be described in oopMaps and therefore can't be used by the compilers (at least | 
| 213 | // were deopt might wan't to see them). | 
| 214 |  | 
| 215 | // The MMX registers, for P3 and up chips | 
| 216 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mnoreg , (-1)); | 
| 217 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx0 , ( 0)); | 
| 218 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx1 , ( 1)); | 
| 219 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx2 , ( 2)); | 
| 220 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx3 , ( 3)); | 
| 221 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx4 , ( 4)); | 
| 222 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx5 , ( 5)); | 
| 223 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx6 , ( 6)); | 
| 224 | CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx7 , ( 7)); | 
| 225 |  | 
| 226 | // Use XMMRegister as shortcut | 
| 227 | class KRegisterImpl; | 
| 228 | typedef KRegisterImpl* KRegister; | 
| 229 |  | 
| 230 | inline KRegister as_KRegister(int encoding) { | 
| 231 |   return (KRegister)(intptr_t)encoding; | 
| 232 | } | 
| 233 |  | 
| 234 | // The implementation of XMM registers for the IA32 architecture | 
| 235 | class KRegisterImpl : public AbstractRegisterImpl { | 
| 236 | public: | 
| 237 |   enum { | 
| 238 |     number_of_registers = 8, | 
| 239 |     max_slots_per_register = 1 | 
| 240 |   }; | 
| 241 |  | 
| 242 |   // construction | 
| 243 |   friend KRegister as_KRegister(int encoding); | 
| 244 |  | 
| 245 |   inline VMReg as_VMReg(); | 
| 246 |  | 
| 247 |   // derived registers, offsets, and addresses | 
| 248 |   KRegister successor() const                          { return as_KRegister(encoding() + 1); } | 
| 249 |  | 
| 250 |   // accessors | 
| 251 |   int   encoding() const                          { assert(is_valid(), "invalid register (%d)" , (int)(intptr_t)this); return (intptr_t)this; } | 
| 252 |   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; } | 
| 253 |   const char* name() const; | 
| 254 | }; | 
| 255 |  | 
| 256 | // The Mask registers, for AVX3 enabled and up chips | 
| 257 | CONSTANT_REGISTER_DECLARATION(KRegister, knoreg, (-1)); | 
| 258 | CONSTANT_REGISTER_DECLARATION(KRegister, k0, (0)); | 
| 259 | CONSTANT_REGISTER_DECLARATION(KRegister, k1, (1)); | 
| 260 | CONSTANT_REGISTER_DECLARATION(KRegister, k2, (2)); | 
| 261 | CONSTANT_REGISTER_DECLARATION(KRegister, k3, (3)); | 
| 262 | CONSTANT_REGISTER_DECLARATION(KRegister, k4, (4)); | 
| 263 | CONSTANT_REGISTER_DECLARATION(KRegister, k5, (5)); | 
| 264 | CONSTANT_REGISTER_DECLARATION(KRegister, k6, (6)); | 
| 265 | CONSTANT_REGISTER_DECLARATION(KRegister, k7, (7)); | 
| 266 |  | 
| 267 | // Need to know the total number of registers of all sorts for SharedInfo. | 
| 268 | // Define a class that exports it. | 
| 269 | class ConcreteRegisterImpl : public AbstractRegisterImpl { | 
| 270 |  public: | 
| 271 |   enum { | 
| 272 |   // A big enough number for C2: all the registers plus flags | 
| 273 |   // This number must be large enough to cover REG_COUNT (defined by c2) registers. | 
| 274 |   // There is no requirement that any ordering here matches any ordering c2 gives | 
| 275 |   // it's optoregs. | 
| 276 |  | 
| 277 |     number_of_registers = RegisterImpl::number_of_registers + | 
| 278 | #ifdef AMD64 | 
| 279 |       RegisterImpl::number_of_registers +  // "H" half of a 64bit register | 
| 280 | #endif // AMD64 | 
| 281 |       2 * FloatRegisterImpl::number_of_registers + | 
| 282 |       XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers + | 
| 283 |       KRegisterImpl::number_of_registers + // mask registers | 
| 284 |       1 // eflags | 
| 285 |   }; | 
| 286 |  | 
| 287 |   static const int max_gpr; | 
| 288 |   static const int max_fpr; | 
| 289 |   static const int max_xmm; | 
| 290 |   static const int max_kpr; | 
| 291 |  | 
| 292 | }; | 
| 293 |  | 
| 294 | #endif // CPU_X86_REGISTER_X86_HPP | 
| 295 |  |