| OLD | NEW | 
|---|
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 
| 2 // All Rights Reserved. | 2 // All Rights Reserved. | 
| 3 // | 3 // | 
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without | 
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are | 
| 6 // met: | 6 // met: | 
| 7 // | 7 // | 
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, | 
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. | 
| 10 // | 10 // | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 40 | 40 | 
| 41 #include <set> | 41 #include <set> | 
| 42 | 42 | 
| 43 #include "src/assembler.h" | 43 #include "src/assembler.h" | 
| 44 #include "src/compiler.h" | 44 #include "src/compiler.h" | 
| 45 #include "src/mips64/constants-mips64.h" | 45 #include "src/mips64/constants-mips64.h" | 
| 46 | 46 | 
| 47 namespace v8 { | 47 namespace v8 { | 
| 48 namespace internal { | 48 namespace internal { | 
| 49 | 49 | 
| 50 // clang-format off |  | 
| 51 #define GENERAL_REGISTERS(V)                              \ |  | 
| 52   V(zero_reg)  V(at)  V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3)  \ |  | 
| 53   V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2)  V(t3)  \ |  | 
| 54   V(s0)  V(s1)  V(s2)  V(s3)  V(s4)  V(s5)  V(s6)  V(s7)  V(t8)  V(t9) \ |  | 
| 55   V(k0)  V(k1)  V(gp)  V(sp)  V(fp)  V(ra) |  | 
| 56 |  | 
| 57 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ |  | 
| 58   V(v0)  V(v1)  V(a0)  V(a1)  V(a2)  V(a3) \ |  | 
| 59   V(a4)  V(a5)  V(a6)  V(a7)  V(t0)  V(t1)  V(t2) V(s7) |  | 
| 60 |  | 
| 61 #define DOUBLE_REGISTERS(V)                               \ |  | 
| 62   V(f0)  V(f1)  V(f2)  V(f3)  V(f4)  V(f5)  V(f6)  V(f7)  \ |  | 
| 63   V(f8)  V(f9)  V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \ |  | 
| 64   V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \ |  | 
| 65   V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31) |  | 
| 66 |  | 
| 67 #define ALLOCATABLE_DOUBLE_REGISTERS(V)                   \ |  | 
| 68   V(f0)  V(f2)  V(f4)  V(f6)  V(f8)  V(f10) V(f12) V(f14) \ |  | 
| 69   V(f16) V(f18) V(f20) V(f22) V(f24) V(f26) |  | 
| 70 // clang-format on |  | 
| 71 |  | 
| 72 // CPU Registers. | 50 // CPU Registers. | 
| 73 // | 51 // | 
| 74 // 1) We would prefer to use an enum, but enum values are assignment- | 52 // 1) We would prefer to use an enum, but enum values are assignment- | 
| 75 // compatible with int, which has caused code-generation bugs. | 53 // compatible with int, which has caused code-generation bugs. | 
| 76 // | 54 // | 
| 77 // 2) We would prefer to use a class instead of a struct but we don't like | 55 // 2) We would prefer to use a class instead of a struct but we don't like | 
| 78 // the register initialization to depend on the particular initialization | 56 // the register initialization to depend on the particular initialization | 
| 79 // order (which appears to be different on OS X, Linux, and Windows for the | 57 // order (which appears to be different on OS X, Linux, and Windows for the | 
| 80 // installed versions of C++ we tried). Using a struct permits C-style | 58 // installed versions of C++ we tried). Using a struct permits C-style | 
| 81 // "initialization". Also, the Register objects cannot be const as this | 59 // "initialization". Also, the Register objects cannot be const as this | 
| 82 // forces initialization stubs in MSVC, making us dependent on initialization | 60 // forces initialization stubs in MSVC, making us dependent on initialization | 
| 83 // order. | 61 // order. | 
| 84 // | 62 // | 
| 85 // 3) By not using an enum, we are possibly preventing the compiler from | 63 // 3) By not using an enum, we are possibly preventing the compiler from | 
| 86 // doing certain constant folds, which may significantly reduce the | 64 // doing certain constant folds, which may significantly reduce the | 
| 87 // code generated for some assembly instructions (because they boil down | 65 // code generated for some assembly instructions (because they boil down | 
| 88 // to a few constants). If this is a problem, we could change the code | 66 // to a few constants). If this is a problem, we could change the code | 
| 89 // such that we use an enum in optimized mode, and the struct in debug | 67 // such that we use an enum in optimized mode, and the struct in debug | 
| 90 // mode. This way we get the compile-time error checking in debug mode | 68 // mode. This way we get the compile-time error checking in debug mode | 
| 91 // and best performance in optimized code. | 69 // and best performance in optimized code. | 
| 92 | 70 | 
| 93 | 71 | 
| 94 // ----------------------------------------------------------------------------- | 72 // ----------------------------------------------------------------------------- | 
| 95 // Implementation of Register and FPURegister. | 73 // Implementation of Register and FPURegister. | 
| 96 | 74 | 
|  | 75 // Core register. | 
| 97 struct Register { | 76 struct Register { | 
|  | 77   static const int kNumRegisters = v8::internal::kNumRegisters; | 
|  | 78   static const int kMaxNumAllocatableRegisters = 14;  // v0 through t2 and cp. | 
|  | 79   static const int kSizeInBytes = 8; | 
| 98   static const int kCpRegister = 23;  // cp (s7) is the 23rd register. | 80   static const int kCpRegister = 23;  // cp (s7) is the 23rd register. | 
| 99 | 81 | 
| 100 #if defined(V8_TARGET_LITTLE_ENDIAN) | 82 #if defined(V8_TARGET_LITTLE_ENDIAN) | 
| 101   static const int kMantissaOffset = 0; | 83   static const int kMantissaOffset = 0; | 
| 102   static const int kExponentOffset = 4; | 84   static const int kExponentOffset = 4; | 
| 103 #elif defined(V8_TARGET_BIG_ENDIAN) | 85 #elif defined(V8_TARGET_BIG_ENDIAN) | 
| 104   static const int kMantissaOffset = 4; | 86   static const int kMantissaOffset = 4; | 
| 105   static const int kExponentOffset = 0; | 87   static const int kExponentOffset = 0; | 
| 106 #else | 88 #else | 
| 107 #error Unknown endianness | 89 #error Unknown endianness | 
| 108 #endif | 90 #endif | 
| 109 | 91 | 
| 110   enum Code { | 92   inline static int NumAllocatableRegisters(); | 
| 111 #define REGISTER_CODE(R) kCode_##R, |  | 
| 112     GENERAL_REGISTERS(REGISTER_CODE) |  | 
| 113 #undef REGISTER_CODE |  | 
| 114         kAfterLast, |  | 
| 115     kCode_no_reg = -1 |  | 
| 116   }; |  | 
| 117 | 93 | 
| 118   static const int kNumRegisters = Code::kAfterLast; | 94   static int ToAllocationIndex(Register reg) { | 
|  | 95     DCHECK((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) || | 
|  | 96            reg.is(from_code(kCpRegister))); | 
|  | 97     return reg.is(from_code(kCpRegister)) ? | 
|  | 98            kMaxNumAllocatableRegisters - 1 :  // Return last index for 'cp'. | 
|  | 99            reg.code() - 2;  // zero_reg and 'at' are skipped. | 
|  | 100   } | 
|  | 101 | 
|  | 102   static Register FromAllocationIndex(int index) { | 
|  | 103     DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | 
|  | 104     return index == kMaxNumAllocatableRegisters - 1 ? | 
|  | 105            from_code(kCpRegister) :  // Last index is always the 'cp' register. | 
|  | 106            from_code(index + 2);  // zero_reg and 'at' are skipped. | 
|  | 107   } | 
|  | 108 | 
|  | 109   static const char* AllocationIndexToString(int index) { | 
|  | 110     DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | 
|  | 111     const char* const names[] = { | 
|  | 112       "v0", | 
|  | 113       "v1", | 
|  | 114       "a0", | 
|  | 115       "a1", | 
|  | 116       "a2", | 
|  | 117       "a3", | 
|  | 118       "a4", | 
|  | 119       "a5", | 
|  | 120       "a6", | 
|  | 121       "a7", | 
|  | 122       "t0", | 
|  | 123       "t1", | 
|  | 124       "t2", | 
|  | 125       "s7", | 
|  | 126     }; | 
|  | 127     return names[index]; | 
|  | 128   } | 
| 119 | 129 | 
| 120   static Register from_code(int code) { | 130   static Register from_code(int code) { | 
| 121     DCHECK(code >= 0); |  | 
| 122     DCHECK(code < kNumRegisters); |  | 
| 123     Register r = { code }; | 131     Register r = { code }; | 
| 124     return r; | 132     return r; | 
| 125   } | 133   } | 
| 126 | 134 | 
| 127   const char* ToString(); | 135   bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 
| 128   bool IsAllocatable() const; | 136   bool is(Register reg) const { return code_ == reg.code_; } | 
| 129   bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |  | 
| 130   bool is(Register reg) const { return reg_code == reg.reg_code; } |  | 
| 131   int code() const { | 137   int code() const { | 
| 132     DCHECK(is_valid()); | 138     DCHECK(is_valid()); | 
| 133     return reg_code; | 139     return code_; | 
| 134   } | 140   } | 
| 135   int bit() const { | 141   int bit() const { | 
| 136     DCHECK(is_valid()); | 142     DCHECK(is_valid()); | 
| 137     return 1 << reg_code; | 143     return 1 << code_; | 
| 138   } | 144   } | 
| 139 | 145 | 
| 140   // Unfortunately we can't make this private in a struct. | 146   // Unfortunately we can't make this private in a struct. | 
| 141   int reg_code; | 147   int code_; | 
| 142 }; | 148 }; | 
| 143 | 149 | 
| 144 // s7: context register | 150 #define REGISTER(N, C) \ | 
| 145 // s3: lithium scratch | 151   const int kRegister_ ## N ## _Code = C; \ | 
| 146 // s4: lithium scratch2 | 152   const Register N = { C } | 
| 147 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; | 153 | 
| 148 GENERAL_REGISTERS(DECLARE_REGISTER) | 154 REGISTER(no_reg, -1); | 
| 149 #undef DECLARE_REGISTER | 155 // Always zero. | 
| 150 const Register no_reg = {Register::kCode_no_reg}; | 156 REGISTER(zero_reg, 0); | 
|  | 157 // at: Reserved for synthetic instructions. | 
|  | 158 REGISTER(at, 1); | 
|  | 159 // v0, v1: Used when returning multiple values from subroutines. | 
|  | 160 REGISTER(v0, 2); | 
|  | 161 REGISTER(v1, 3); | 
|  | 162 // a0 - a4: Used to pass non-FP parameters. | 
|  | 163 REGISTER(a0, 4); | 
|  | 164 REGISTER(a1, 5); | 
|  | 165 REGISTER(a2, 6); | 
|  | 166 REGISTER(a3, 7); | 
|  | 167 // a4 - a7 t0 - t3: Can be used without reservation, act as temporary registers | 
|  | 168 // and are allowed to be destroyed by subroutines. | 
|  | 169 REGISTER(a4, 8); | 
|  | 170 REGISTER(a5, 9); | 
|  | 171 REGISTER(a6, 10); | 
|  | 172 REGISTER(a7, 11); | 
|  | 173 REGISTER(t0, 12); | 
|  | 174 REGISTER(t1, 13); | 
|  | 175 REGISTER(t2, 14); | 
|  | 176 REGISTER(t3, 15); | 
|  | 177 // s0 - s7: Subroutine register variables. Subroutines that write to these | 
|  | 178 // registers must restore their values before exiting so that the caller can | 
|  | 179 // expect the values to be preserved. | 
|  | 180 REGISTER(s0, 16); | 
|  | 181 REGISTER(s1, 17); | 
|  | 182 REGISTER(s2, 18); | 
|  | 183 REGISTER(s3, 19); | 
|  | 184 REGISTER(s4, 20); | 
|  | 185 REGISTER(s5, 21); | 
|  | 186 REGISTER(s6, 22); | 
|  | 187 REGISTER(s7, 23); | 
|  | 188 REGISTER(t8, 24); | 
|  | 189 REGISTER(t9, 25); | 
|  | 190 // k0, k1: Reserved for system calls and interrupt handlers. | 
|  | 191 REGISTER(k0, 26); | 
|  | 192 REGISTER(k1, 27); | 
|  | 193 // gp: Reserved. | 
|  | 194 REGISTER(gp, 28); | 
|  | 195 // sp: Stack pointer. | 
|  | 196 REGISTER(sp, 29); | 
|  | 197 // fp: Frame pointer. | 
|  | 198 REGISTER(fp, 30); | 
|  | 199 // ra: Return address pointer. | 
|  | 200 REGISTER(ra, 31); | 
|  | 201 | 
|  | 202 #undef REGISTER | 
| 151 | 203 | 
| 152 | 204 | 
| 153 int ToNumber(Register reg); | 205 int ToNumber(Register reg); | 
| 154 | 206 | 
| 155 Register ToRegister(int num); | 207 Register ToRegister(int num); | 
| 156 | 208 | 
| 157 // Coprocessor register. | 209 // Coprocessor register. | 
| 158 struct DoubleRegister { | 210 struct FPURegister { | 
| 159   enum Code { | 211   static const int kMaxNumRegisters = v8::internal::kNumFPURegisters; | 
| 160 #define REGISTER_CODE(R) kCode_##R, |  | 
| 161     DOUBLE_REGISTERS(REGISTER_CODE) |  | 
| 162 #undef REGISTER_CODE |  | 
| 163         kAfterLast, |  | 
| 164     kCode_no_reg = -1 |  | 
| 165   }; |  | 
| 166 |  | 
| 167   static const int kMaxNumRegisters = Code::kAfterLast; |  | 
| 168 |  | 
| 169   inline static int NumRegisters(); |  | 
| 170 | 212 | 
| 171   // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers | 213   // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers | 
| 172   // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to | 214   // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to | 
| 173   // number of Double regs (64-bit regs, or FPU-reg-pairs). | 215   // number of Double regs (64-bit regs, or FPU-reg-pairs). | 
| 174 | 216 | 
| 175   const char* ToString(); | 217   // A few double registers are reserved: one as a scratch register and one to | 
| 176   bool IsAllocatable() const; | 218   // hold 0.0. | 
| 177   bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } | 219   //  f28: 0.0 | 
| 178   bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } | 220   //  f30: scratch register. | 
| 179   DoubleRegister low() const { | 221   static const int kNumReservedRegisters = 2; | 
|  | 222   static const int kMaxNumAllocatableRegisters = kMaxNumRegisters / 2 - | 
|  | 223       kNumReservedRegisters; | 
|  | 224 | 
|  | 225   inline static int NumRegisters(); | 
|  | 226   inline static int NumAllocatableRegisters(); | 
|  | 227 | 
|  | 228   // TODO(turbofan): Proper support for float32. | 
|  | 229   inline static int NumAllocatableAliasedRegisters(); | 
|  | 230 | 
|  | 231   inline static int ToAllocationIndex(FPURegister reg); | 
|  | 232   static const char* AllocationIndexToString(int index); | 
|  | 233 | 
|  | 234   static FPURegister FromAllocationIndex(int index) { | 
|  | 235     DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | 
|  | 236     return from_code(index * 2); | 
|  | 237   } | 
|  | 238 | 
|  | 239   static FPURegister from_code(int code) { | 
|  | 240     FPURegister r = { code }; | 
|  | 241     return r; | 
|  | 242   } | 
|  | 243 | 
|  | 244   bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; } | 
|  | 245   bool is(FPURegister creg) const { return code_ == creg.code_; } | 
|  | 246   FPURegister low() const { | 
| 180     // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1. | 247     // TODO(plind): Create DCHECK for FR=0 mode. This usage suspect for FR=1. | 
| 181     // Find low reg of a Double-reg pair, which is the reg itself. | 248     // Find low reg of a Double-reg pair, which is the reg itself. | 
| 182     DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even. | 249     DCHECK(code_ % 2 == 0);  // Specified Double reg must be even. | 
| 183     DoubleRegister reg; | 250     FPURegister reg; | 
| 184     reg.reg_code = reg_code; | 251     reg.code_ = code_; | 
| 185     DCHECK(reg.is_valid()); | 252     DCHECK(reg.is_valid()); | 
| 186     return reg; | 253     return reg; | 
| 187   } | 254   } | 
| 188   DoubleRegister high() const { | 255   FPURegister high() const { | 
| 189     // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1. | 256     // TODO(plind): Create DCHECK for FR=0 mode. This usage illegal in FR=1. | 
| 190     // Find high reg of a Doubel-reg pair, which is reg + 1. | 257     // Find high reg of a Doubel-reg pair, which is reg + 1. | 
| 191     DCHECK(reg_code % 2 == 0);  // Specified Double reg must be even. | 258     DCHECK(code_ % 2 == 0);  // Specified Double reg must be even. | 
| 192     DoubleRegister reg; | 259     FPURegister reg; | 
| 193     reg.reg_code = reg_code + 1; | 260     reg.code_ = code_ + 1; | 
| 194     DCHECK(reg.is_valid()); | 261     DCHECK(reg.is_valid()); | 
| 195     return reg; | 262     return reg; | 
| 196   } | 263   } | 
| 197 | 264 | 
| 198   int code() const { | 265   int code() const { | 
| 199     DCHECK(is_valid()); | 266     DCHECK(is_valid()); | 
| 200     return reg_code; | 267     return code_; | 
| 201   } | 268   } | 
| 202   int bit() const { | 269   int bit() const { | 
| 203     DCHECK(is_valid()); | 270     DCHECK(is_valid()); | 
| 204     return 1 << reg_code; | 271     return 1 << code_; | 
| 205   } |  | 
| 206 |  | 
| 207   static DoubleRegister from_code(int code) { |  | 
| 208     DoubleRegister r = {code}; |  | 
| 209     return r; |  | 
| 210   } | 272   } | 
| 211   void setcode(int f) { | 273   void setcode(int f) { | 
| 212     reg_code = f; | 274     code_ = f; | 
| 213     DCHECK(is_valid()); | 275     DCHECK(is_valid()); | 
| 214   } | 276   } | 
| 215   // Unfortunately we can't make this private in a struct. | 277   // Unfortunately we can't make this private in a struct. | 
| 216   int reg_code; | 278   int code_; | 
| 217 }; | 279 }; | 
| 218 | 280 | 
| 219 // A few double registers are reserved: one as a scratch register and one to |  | 
| 220 // hold 0.0. |  | 
| 221 //  f28: 0.0 |  | 
| 222 //  f30: scratch register. |  | 
| 223 |  | 
| 224 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32 | 281 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32 | 
| 225 // 32-bit registers, f0 through f31. When used as 'double' they are used | 282 // 32-bit registers, f0 through f31. When used as 'double' they are used | 
| 226 // in pairs, starting with the even numbered register. So a double operation | 283 // in pairs, starting with the even numbered register. So a double operation | 
| 227 // on f0 really uses f0 and f1. | 284 // on f0 really uses f0 and f1. | 
| 228 // (Modern mips hardware also supports 32 64-bit registers, via setting | 285 // (Modern mips hardware also supports 32 64-bit registers, via setting | 
| 229 // (privileged) Status Register FR bit to 1. This is used by the N32 ABI, | 286 // (privileged) Status Register FR bit to 1. This is used by the N32 ABI, | 
| 230 // but it is not in common use. Someday we will want to support this in v8.) | 287 // but it is not in common use. Someday we will want to support this in v8.) | 
| 231 | 288 | 
| 232 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. | 289 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. | 
| 233 typedef DoubleRegister FPURegister; | 290 typedef FPURegister DoubleRegister; | 
| 234 typedef DoubleRegister FloatRegister; | 291 typedef FPURegister FloatRegister; | 
| 235 | 292 | 
| 236 const DoubleRegister no_freg = {-1}; | 293 const FPURegister no_freg = { -1 }; | 
| 237 | 294 | 
| 238 const DoubleRegister f0 = {0};  // Return value in hard float mode. | 295 const FPURegister f0 = { 0 };  // Return value in hard float mode. | 
| 239 const DoubleRegister f1 = {1}; | 296 const FPURegister f1 = { 1 }; | 
| 240 const DoubleRegister f2 = {2}; | 297 const FPURegister f2 = { 2 }; | 
| 241 const DoubleRegister f3 = {3}; | 298 const FPURegister f3 = { 3 }; | 
| 242 const DoubleRegister f4 = {4}; | 299 const FPURegister f4 = { 4 }; | 
| 243 const DoubleRegister f5 = {5}; | 300 const FPURegister f5 = { 5 }; | 
| 244 const DoubleRegister f6 = {6}; | 301 const FPURegister f6 = { 6 }; | 
| 245 const DoubleRegister f7 = {7}; | 302 const FPURegister f7 = { 7 }; | 
| 246 const DoubleRegister f8 = {8}; | 303 const FPURegister f8 = { 8 }; | 
| 247 const DoubleRegister f9 = {9}; | 304 const FPURegister f9 = { 9 }; | 
| 248 const DoubleRegister f10 = {10}; | 305 const FPURegister f10 = { 10 }; | 
| 249 const DoubleRegister f11 = {11}; | 306 const FPURegister f11 = { 11 }; | 
| 250 const DoubleRegister f12 = {12};  // Arg 0 in hard float mode. | 307 const FPURegister f12 = { 12 };  // Arg 0 in hard float mode. | 
| 251 const DoubleRegister f13 = {13}; | 308 const FPURegister f13 = { 13 }; | 
| 252 const DoubleRegister f14 = {14};  // Arg 1 in hard float mode. | 309 const FPURegister f14 = { 14 };  // Arg 1 in hard float mode. | 
| 253 const DoubleRegister f15 = {15}; | 310 const FPURegister f15 = { 15 }; | 
| 254 const DoubleRegister f16 = {16}; | 311 const FPURegister f16 = { 16 }; | 
| 255 const DoubleRegister f17 = {17}; | 312 const FPURegister f17 = { 17 }; | 
| 256 const DoubleRegister f18 = {18}; | 313 const FPURegister f18 = { 18 }; | 
| 257 const DoubleRegister f19 = {19}; | 314 const FPURegister f19 = { 19 }; | 
| 258 const DoubleRegister f20 = {20}; | 315 const FPURegister f20 = { 20 }; | 
| 259 const DoubleRegister f21 = {21}; | 316 const FPURegister f21 = { 21 }; | 
| 260 const DoubleRegister f22 = {22}; | 317 const FPURegister f22 = { 22 }; | 
| 261 const DoubleRegister f23 = {23}; | 318 const FPURegister f23 = { 23 }; | 
| 262 const DoubleRegister f24 = {24}; | 319 const FPURegister f24 = { 24 }; | 
| 263 const DoubleRegister f25 = {25}; | 320 const FPURegister f25 = { 25 }; | 
| 264 const DoubleRegister f26 = {26}; | 321 const FPURegister f26 = { 26 }; | 
| 265 const DoubleRegister f27 = {27}; | 322 const FPURegister f27 = { 27 }; | 
| 266 const DoubleRegister f28 = {28}; | 323 const FPURegister f28 = { 28 }; | 
| 267 const DoubleRegister f29 = {29}; | 324 const FPURegister f29 = { 29 }; | 
| 268 const DoubleRegister f30 = {30}; | 325 const FPURegister f30 = { 30 }; | 
| 269 const DoubleRegister f31 = {31}; | 326 const FPURegister f31 = { 31 }; | 
| 270 | 327 | 
| 271 // Register aliases. | 328 // Register aliases. | 
| 272 // cp is assumed to be a callee saved register. | 329 // cp is assumed to be a callee saved register. | 
| 273 // Defined using #define instead of "static const Register&" because Clang | 330 // Defined using #define instead of "static const Register&" because Clang | 
| 274 // complains otherwise when a compilation unit that includes this header | 331 // complains otherwise when a compilation unit that includes this header | 
| 275 // doesn't use the variables. | 332 // doesn't use the variables. | 
| 276 #define kRootRegister s6 | 333 #define kRootRegister s6 | 
| 277 #define cp s7 | 334 #define cp s7 | 
| 278 #define kLithiumScratchReg s3 | 335 #define kLithiumScratchReg s3 | 
| 279 #define kLithiumScratchReg2 s4 | 336 #define kLithiumScratchReg2 s4 | 
| 280 #define kLithiumScratchDouble f30 | 337 #define kLithiumScratchDouble f30 | 
| 281 #define kDoubleRegZero f28 | 338 #define kDoubleRegZero f28 | 
| 282 // Used on mips64r6 for compare operations. | 339 // Used on mips64r6 for compare operations. | 
| 283 // We use the last non-callee saved odd register for N64 ABI | 340 // We use the last non-callee saved odd register for N64 ABI | 
| 284 #define kDoubleCompareReg f23 | 341 #define kDoubleCompareReg f23 | 
| 285 | 342 | 
| 286 // FPU (coprocessor 1) control registers. | 343 // FPU (coprocessor 1) control registers. | 
| 287 // Currently only FCSR (#31) is implemented. | 344 // Currently only FCSR (#31) is implemented. | 
| 288 struct FPUControlRegister { | 345 struct FPUControlRegister { | 
| 289   bool is_valid() const { return reg_code == kFCSRRegister; } | 346   bool is_valid() const { return code_ == kFCSRRegister; } | 
| 290   bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; } | 347   bool is(FPUControlRegister creg) const { return code_ == creg.code_; } | 
| 291   int code() const { | 348   int code() const { | 
| 292     DCHECK(is_valid()); | 349     DCHECK(is_valid()); | 
| 293     return reg_code; | 350     return code_; | 
| 294   } | 351   } | 
| 295   int bit() const { | 352   int bit() const { | 
| 296     DCHECK(is_valid()); | 353     DCHECK(is_valid()); | 
| 297     return 1 << reg_code; | 354     return 1 << code_; | 
| 298   } | 355   } | 
| 299   void setcode(int f) { | 356   void setcode(int f) { | 
| 300     reg_code = f; | 357     code_ = f; | 
| 301     DCHECK(is_valid()); | 358     DCHECK(is_valid()); | 
| 302   } | 359   } | 
| 303   // Unfortunately we can't make this private in a struct. | 360   // Unfortunately we can't make this private in a struct. | 
| 304   int reg_code; | 361   int code_; | 
| 305 }; | 362 }; | 
| 306 | 363 | 
| 307 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; | 364 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; | 
| 308 const FPUControlRegister FCSR = { kFCSRRegister }; | 365 const FPUControlRegister FCSR = { kFCSRRegister }; | 
| 309 | 366 | 
| 310 | 367 | 
| 311 // ----------------------------------------------------------------------------- | 368 // ----------------------------------------------------------------------------- | 
| 312 // Machine instruction Operands. | 369 // Machine instruction Operands. | 
| 313 const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 370 const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 
| 314 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; | 371 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; | 
| (...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1447  public: | 1504  public: | 
| 1448   explicit EnsureSpace(Assembler* assembler) { | 1505   explicit EnsureSpace(Assembler* assembler) { | 
| 1449     assembler->CheckBuffer(); | 1506     assembler->CheckBuffer(); | 
| 1450   } | 1507   } | 
| 1451 }; | 1508 }; | 
| 1452 | 1509 | 
| 1453 }  // namespace internal | 1510 }  // namespace internal | 
| 1454 }  // namespace v8 | 1511 }  // namespace v8 | 
| 1455 | 1512 | 
| 1456 #endif  // V8_ARM_ASSEMBLER_MIPS_H_ | 1513 #endif  // V8_ARM_ASSEMBLER_MIPS_H_ | 
| OLD | NEW | 
|---|