| 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 | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 #define ABI_PASSES_HANDLES_IN_REGS \ | 54 #define ABI_PASSES_HANDLES_IN_REGS \ |
| 55 (!V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64) | 55 (!V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64) |
| 56 | 56 |
| 57 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS \ | 57 #define ABI_RETURNS_OBJECT_PAIRS_IN_REGS \ |
| 58 (!V8_HOST_ARCH_PPC || !V8_TARGET_ARCH_PPC64 || V8_TARGET_LITTLE_ENDIAN) | 58 (!V8_HOST_ARCH_PPC || !V8_TARGET_ARCH_PPC64 || V8_TARGET_LITTLE_ENDIAN) |
| 59 | 59 |
| 60 #define ABI_TOC_ADDRESSABILITY_VIA_IP \ | 60 #define ABI_TOC_ADDRESSABILITY_VIA_IP \ |
| 61 (V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) | 61 (V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN) |
| 62 | 62 |
| 63 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 | 63 #if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64 |
| 64 #define ABI_TOC_REGISTER kRegister_r2_Code | 64 #define ABI_TOC_REGISTER Register::kCode_r2 |
| 65 #else | 65 #else |
| 66 #define ABI_TOC_REGISTER kRegister_r13_Code | 66 #define ABI_TOC_REGISTER Register::kCode_r13 |
| 67 #endif | 67 #endif |
| 68 | 68 |
| 69 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC | 69 #define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC |
| 70 | 70 |
| 71 namespace v8 { | 71 namespace v8 { |
| 72 namespace internal { | 72 namespace internal { |
| 73 | 73 |
| 74 // clang-format off |
| 75 #define GENERAL_REGISTERS(V) \ |
| 76 V(r0) V(sp) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \ |
| 77 V(r8) V(r9) V(r10) V(r11) V(ip) V(r13) V(r14) V(r15) \ |
| 78 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
| 79 V(r24) V(r25) V(r26) V(r27) V(r28) V(r29) V(r30) V(fp) |
| 80 |
| 81 #if V8_EMBEDDED_CONSTANT_POOL |
| 82 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ |
| 83 V(r3) V(r4) V(r5) V(r6) V(r7) \ |
| 84 V(r8) V(r9) V(r10) V(r14) V(r15) \ |
| 85 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
| 86 V(r24) V(r25) V(r26) V(r27) V(r30) |
| 87 #else |
| 88 #define ALLOCATABLE_GENERAL_REGISTERS(V) \ |
| 89 V(r3) V(r4) V(r5) V(r6) V(r7) \ |
| 90 V(r8) V(r9) V(r10) V(r14) V(r15) \ |
| 91 V(r16) V(r17) V(r18) V(r19) V(r20) V(r21) V(r22) V(r23) \ |
| 92 V(r24) V(r25) V(r26) V(r27) V(r28) V(r30) |
| 93 #endif |
| 94 |
| 95 #define DOUBLE_REGISTERS(V) \ |
| 96 V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ |
| 97 V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \ |
| 98 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ |
| 99 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) |
| 100 |
| 101 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \ |
| 102 V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \ |
| 103 V(d8) V(d9) V(d10) V(d11) V(d12) V(d15) \ |
| 104 V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \ |
| 105 V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31) |
| 106 // clang-format on |
| 107 |
| 74 // CPU Registers. | 108 // CPU Registers. |
| 75 // | 109 // |
| 76 // 1) We would prefer to use an enum, but enum values are assignment- | 110 // 1) We would prefer to use an enum, but enum values are assignment- |
| 77 // compatible with int, which has caused code-generation bugs. | 111 // compatible with int, which has caused code-generation bugs. |
| 78 // | 112 // |
| 79 // 2) We would prefer to use a class instead of a struct but we don't like | 113 // 2) We would prefer to use a class instead of a struct but we don't like |
| 80 // the register initialization to depend on the particular initialization | 114 // the register initialization to depend on the particular initialization |
| 81 // order (which appears to be different on OS X, Linux, and Windows for the | 115 // order (which appears to be different on OS X, Linux, and Windows for the |
| 82 // installed versions of C++ we tried). Using a struct permits C-style | 116 // installed versions of C++ we tried). Using a struct permits C-style |
| 83 // "initialization". Also, the Register objects cannot be const as this | 117 // "initialization". Also, the Register objects cannot be const as this |
| 84 // forces initialization stubs in MSVC, making us dependent on initialization | 118 // forces initialization stubs in MSVC, making us dependent on initialization |
| 85 // order. | 119 // order. |
| 86 // | 120 // |
| 87 // 3) By not using an enum, we are possibly preventing the compiler from | 121 // 3) By not using an enum, we are possibly preventing the compiler from |
| 88 // doing certain constant folds, which may significantly reduce the | 122 // doing certain constant folds, which may significantly reduce the |
| 89 // code generated for some assembly instructions (because they boil down | 123 // code generated for some assembly instructions (because they boil down |
| 90 // to a few constants). If this is a problem, we could change the code | 124 // to a few constants). If this is a problem, we could change the code |
| 91 // such that we use an enum in optimized mode, and the struct in debug | 125 // such that we use an enum in optimized mode, and the struct in debug |
| 92 // mode. This way we get the compile-time error checking in debug mode | 126 // mode. This way we get the compile-time error checking in debug mode |
| 93 // and best performance in optimized code. | 127 // and best performance in optimized code. |
| 94 | 128 |
| 95 // Core register | |
| 96 struct Register { | 129 struct Register { |
| 97 static const int kNumRegisters = 32; | 130 enum Code { |
| 98 static const int kSizeInBytes = kPointerSize; | 131 #define REGISTER_CODE(R) kCode_##R, |
| 132 GENERAL_REGISTERS(REGISTER_CODE) |
| 133 #undef REGISTER_CODE |
| 134 kAfterLast, |
| 135 kCode_no_reg = -1 |
| 136 }; |
| 137 |
| 138 static const int kNumRegisters = Code::kAfterLast; |
| 139 |
| 140 #define REGISTER_COUNT(R) 1 + |
| 141 static const int kNumAllocatable = |
| 142 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT)0; |
| 143 #undef REGISTER_COUNT |
| 144 |
| 145 #define REGISTER_BIT(R) 1 << kCode_##R | |
| 146 static const RegList kAllocatable = |
| 147 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT)0; |
| 148 #undef REGISTER_BIT |
| 149 |
| 150 static Register from_code(int code) { |
| 151 DCHECK(code >= 0); |
| 152 DCHECK(code < kNumRegisters); |
| 153 Register r = {code}; |
| 154 return r; |
| 155 } |
| 156 const char* ToString(); |
| 157 bool IsAllocatable() const; |
| 158 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |
| 159 bool is(Register reg) const { return reg_code == reg.reg_code; } |
| 160 int code() const { |
| 161 DCHECK(is_valid()); |
| 162 return reg_code; |
| 163 } |
| 164 int bit() const { |
| 165 DCHECK(is_valid()); |
| 166 return 1 << reg_code; |
| 167 } |
| 168 void set_code(int code) { |
| 169 reg_code = code; |
| 170 DCHECK(is_valid()); |
| 171 } |
| 99 | 172 |
| 100 #if V8_TARGET_LITTLE_ENDIAN | 173 #if V8_TARGET_LITTLE_ENDIAN |
| 101 static const int kMantissaOffset = 0; | 174 static const int kMantissaOffset = 0; |
| 102 static const int kExponentOffset = 4; | 175 static const int kExponentOffset = 4; |
| 103 #else | 176 #else |
| 104 static const int kMantissaOffset = 4; | 177 static const int kMantissaOffset = 4; |
| 105 static const int kExponentOffset = 0; | 178 static const int kExponentOffset = 0; |
| 106 #endif | 179 #endif |
| 107 | 180 |
| 108 static const int kAllocatableLowRangeBegin = 3; | 181 // Unfortunately we can't make this private in a struct. |
| 109 static const int kAllocatableLowRangeEnd = 10; | 182 int reg_code; |
| 110 static const int kAllocatableHighRangeBegin = 14; | 183 }; |
| 111 static const int kAllocatableHighRangeEnd = | |
| 112 FLAG_enable_embedded_constant_pool ? 27 : 28; | |
| 113 static const int kAllocatableContext = 30; | |
| 114 | 184 |
| 115 static const int kNumAllocatableLow = | 185 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; |
| 116 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; | 186 GENERAL_REGISTERS(DECLARE_REGISTER) |
| 117 static const int kNumAllocatableHigh = | 187 #undef DECLARE_REGISTER |
| 118 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; | 188 const Register no_reg = {Register::kCode_no_reg}; |
| 119 static const int kMaxNumAllocatableRegisters = | |
| 120 kNumAllocatableLow + kNumAllocatableHigh + 1; // cp | |
| 121 | 189 |
| 122 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 190 // Aliases |
| 191 const Register kLithiumScratch = r11; // lithium scratch. |
| 192 const Register kConstantPoolRegister = r28; // Constant pool. |
| 193 const Register kRootRegister = r29; // Roots array pointer. |
| 194 const Register cp = r30; // JavaScript context pointer. |
| 123 | 195 |
| 124 static int ToAllocationIndex(Register reg) { | 196 // Double word FP register. |
| 125 int index; | 197 struct DoubleRegister { |
| 126 int code = reg.code(); | 198 enum Code { |
| 127 if (code == kAllocatableContext) { | 199 #define REGISTER_CODE(R) kCode_##R, |
| 128 // Context is the last index | 200 DOUBLE_REGISTERS(REGISTER_CODE) |
| 129 index = NumAllocatableRegisters() - 1; | 201 #undef REGISTER_CODE |
| 130 } else if (code <= kAllocatableLowRangeEnd) { | 202 kAfterLast, |
| 131 // low range | 203 kCode_no_reg = -1 |
| 132 index = code - kAllocatableLowRangeBegin; | 204 }; |
| 133 } else { | |
| 134 // high range | |
| 135 index = code - kAllocatableHighRangeBegin + kNumAllocatableLow; | |
| 136 } | |
| 137 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | |
| 138 return index; | |
| 139 } | |
| 140 | 205 |
| 141 static Register FromAllocationIndex(int index) { | 206 static const int kNumRegisters = Code::kAfterLast; |
| 142 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | 207 static const int kMaxNumRegisters = kNumRegisters; |
| 143 // Last index is always the 'cp' register. | |
| 144 if (index == kMaxNumAllocatableRegisters - 1) { | |
| 145 return from_code(kAllocatableContext); | |
| 146 } | |
| 147 return (index < kNumAllocatableLow) | |
| 148 ? from_code(index + kAllocatableLowRangeBegin) | |
| 149 : from_code(index - kNumAllocatableLow + | |
| 150 kAllocatableHighRangeBegin); | |
| 151 } | |
| 152 | 208 |
| 153 static const char* AllocationIndexToString(int index) { | 209 const char* ToString(); |
| 154 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | 210 bool IsAllocatable() const; |
| 155 const char* const names[] = { | 211 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |
| 156 "r3", | 212 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } |
| 157 "r4", | |
| 158 "r5", | |
| 159 "r6", | |
| 160 "r7", | |
| 161 "r8", | |
| 162 "r9", | |
| 163 "r10", | |
| 164 "r14", | |
| 165 "r15", | |
| 166 "r16", | |
| 167 "r17", | |
| 168 "r18", | |
| 169 "r19", | |
| 170 "r20", | |
| 171 "r21", | |
| 172 "r22", | |
| 173 "r23", | |
| 174 "r24", | |
| 175 "r25", | |
| 176 "r26", | |
| 177 "r27", | |
| 178 "r28", | |
| 179 "cp", | |
| 180 }; | |
| 181 if (FLAG_enable_embedded_constant_pool && | |
| 182 (index == kMaxNumAllocatableRegisters - 2)) { | |
| 183 return names[index + 1]; | |
| 184 } | |
| 185 return names[index]; | |
| 186 } | |
| 187 | |
| 188 static const RegList kAllocatable = | |
| 189 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6 | 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10 | | |
| 190 1 << 14 | 1 << 15 | 1 << 16 | 1 << 17 | 1 << 18 | 1 << 19 | 1 << 20 | | |
| 191 1 << 21 | 1 << 22 | 1 << 23 | 1 << 24 | 1 << 25 | 1 << 26 | 1 << 27 | | |
| 192 (FLAG_enable_embedded_constant_pool ? 0 : 1 << 28) | 1 << 30; | |
| 193 | |
| 194 static Register from_code(int code) { | |
| 195 Register r = {code}; | |
| 196 return r; | |
| 197 } | |
| 198 | |
| 199 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | |
| 200 bool is(Register reg) const { return code_ == reg.code_; } | |
| 201 int code() const { | 213 int code() const { |
| 202 DCHECK(is_valid()); | 214 DCHECK(is_valid()); |
| 203 return code_; | 215 return reg_code; |
| 204 } | 216 } |
| 205 int bit() const { | 217 int bit() const { |
| 206 DCHECK(is_valid()); | 218 DCHECK(is_valid()); |
| 207 return 1 << code_; | 219 return 1 << reg_code; |
| 208 } | 220 } |
| 209 | 221 |
| 210 void set_code(int code) { | |
| 211 code_ = code; | |
| 212 DCHECK(is_valid()); | |
| 213 } | |
| 214 | |
| 215 // Unfortunately we can't make this private in a struct. | |
| 216 int code_; | |
| 217 }; | |
| 218 | |
| 219 // These constants are used in several locations, including static initializers | |
| 220 const int kRegister_no_reg_Code = -1; | |
| 221 const int kRegister_r0_Code = 0; // general scratch | |
| 222 const int kRegister_sp_Code = 1; // stack pointer | |
| 223 const int kRegister_r2_Code = 2; // special on PowerPC | |
| 224 const int kRegister_r3_Code = 3; | |
| 225 const int kRegister_r4_Code = 4; | |
| 226 const int kRegister_r5_Code = 5; | |
| 227 const int kRegister_r6_Code = 6; | |
| 228 const int kRegister_r7_Code = 7; | |
| 229 const int kRegister_r8_Code = 8; | |
| 230 const int kRegister_r9_Code = 9; | |
| 231 const int kRegister_r10_Code = 10; | |
| 232 const int kRegister_r11_Code = 11; // lithium scratch | |
| 233 const int kRegister_ip_Code = 12; // ip (general scratch) | |
| 234 const int kRegister_r13_Code = 13; // special on PowerPC | |
| 235 const int kRegister_r14_Code = 14; | |
| 236 const int kRegister_r15_Code = 15; | |
| 237 | |
| 238 const int kRegister_r16_Code = 16; | |
| 239 const int kRegister_r17_Code = 17; | |
| 240 const int kRegister_r18_Code = 18; | |
| 241 const int kRegister_r19_Code = 19; | |
| 242 const int kRegister_r20_Code = 20; | |
| 243 const int kRegister_r21_Code = 21; | |
| 244 const int kRegister_r22_Code = 22; | |
| 245 const int kRegister_r23_Code = 23; | |
| 246 const int kRegister_r24_Code = 24; | |
| 247 const int kRegister_r25_Code = 25; | |
| 248 const int kRegister_r26_Code = 26; | |
| 249 const int kRegister_r27_Code = 27; | |
| 250 const int kRegister_r28_Code = 28; // constant pool pointer | |
| 251 const int kRegister_r29_Code = 29; // roots array pointer | |
| 252 const int kRegister_r30_Code = 30; // context pointer | |
| 253 const int kRegister_fp_Code = 31; // frame pointer | |
| 254 | |
| 255 const Register no_reg = {kRegister_no_reg_Code}; | |
| 256 | |
| 257 const Register r0 = {kRegister_r0_Code}; | |
| 258 const Register sp = {kRegister_sp_Code}; | |
| 259 const Register r2 = {kRegister_r2_Code}; | |
| 260 const Register r3 = {kRegister_r3_Code}; | |
| 261 const Register r4 = {kRegister_r4_Code}; | |
| 262 const Register r5 = {kRegister_r5_Code}; | |
| 263 const Register r6 = {kRegister_r6_Code}; | |
| 264 const Register r7 = {kRegister_r7_Code}; | |
| 265 const Register r8 = {kRegister_r8_Code}; | |
| 266 const Register r9 = {kRegister_r9_Code}; | |
| 267 const Register r10 = {kRegister_r10_Code}; | |
| 268 const Register r11 = {kRegister_r11_Code}; | |
| 269 const Register ip = {kRegister_ip_Code}; | |
| 270 const Register r13 = {kRegister_r13_Code}; | |
| 271 const Register r14 = {kRegister_r14_Code}; | |
| 272 const Register r15 = {kRegister_r15_Code}; | |
| 273 | |
| 274 const Register r16 = {kRegister_r16_Code}; | |
| 275 const Register r17 = {kRegister_r17_Code}; | |
| 276 const Register r18 = {kRegister_r18_Code}; | |
| 277 const Register r19 = {kRegister_r19_Code}; | |
| 278 const Register r20 = {kRegister_r20_Code}; | |
| 279 const Register r21 = {kRegister_r21_Code}; | |
| 280 const Register r22 = {kRegister_r22_Code}; | |
| 281 const Register r23 = {kRegister_r23_Code}; | |
| 282 const Register r24 = {kRegister_r24_Code}; | |
| 283 const Register r25 = {kRegister_r25_Code}; | |
| 284 const Register r26 = {kRegister_r26_Code}; | |
| 285 const Register r27 = {kRegister_r27_Code}; | |
| 286 const Register r28 = {kRegister_r28_Code}; | |
| 287 const Register r29 = {kRegister_r29_Code}; | |
| 288 const Register r30 = {kRegister_r30_Code}; | |
| 289 const Register fp = {kRegister_fp_Code}; | |
| 290 | |
| 291 // Give alias names to registers | |
| 292 const Register cp = {kRegister_r30_Code}; // JavaScript context pointer | |
| 293 const Register kRootRegister = {kRegister_r29_Code}; // Roots array pointer. | |
| 294 const Register kConstantPoolRegister = {kRegister_r28_Code}; // Constant pool | |
| 295 | |
| 296 // Double word FP register. | |
| 297 struct DoubleRegister { | |
| 298 static const int kNumRegisters = 32; | |
| 299 static const int kMaxNumRegisters = kNumRegisters; | |
| 300 static const int kNumVolatileRegisters = 14; // d0-d13 | |
| 301 static const int kSizeInBytes = 8; | |
| 302 | |
| 303 static const int kAllocatableLowRangeBegin = 1; | |
| 304 static const int kAllocatableLowRangeEnd = 12; | |
| 305 static const int kAllocatableHighRangeBegin = 15; | |
| 306 static const int kAllocatableHighRangeEnd = 31; | |
| 307 | |
| 308 static const int kNumAllocatableLow = | |
| 309 kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1; | |
| 310 static const int kNumAllocatableHigh = | |
| 311 kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1; | |
| 312 static const int kMaxNumAllocatableRegisters = | |
| 313 kNumAllocatableLow + kNumAllocatableHigh; | |
| 314 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | |
| 315 | |
| 316 // TODO(turbofan) | |
| 317 inline static int NumAllocatableAliasedRegisters() { | |
| 318 return NumAllocatableRegisters(); | |
| 319 } | |
| 320 | |
| 321 static int ToAllocationIndex(DoubleRegister reg) { | |
| 322 int code = reg.code(); | |
| 323 int index = (code <= kAllocatableLowRangeEnd) | |
| 324 ? code - kAllocatableLowRangeBegin | |
| 325 : code - kAllocatableHighRangeBegin + kNumAllocatableLow; | |
| 326 DCHECK(index < kMaxNumAllocatableRegisters); | |
| 327 return index; | |
| 328 } | |
| 329 | |
| 330 static DoubleRegister FromAllocationIndex(int index) { | |
| 331 DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters); | |
| 332 return (index < kNumAllocatableLow) | |
| 333 ? from_code(index + kAllocatableLowRangeBegin) | |
| 334 : from_code(index - kNumAllocatableLow + | |
| 335 kAllocatableHighRangeBegin); | |
| 336 } | |
| 337 | |
| 338 static const char* AllocationIndexToString(int index); | |
| 339 | |
| 340 static DoubleRegister from_code(int code) { | 222 static DoubleRegister from_code(int code) { |
| 341 DoubleRegister r = {code}; | 223 DoubleRegister r = {code}; |
| 342 return r; | 224 return r; |
| 343 } | 225 } |
| 344 | 226 |
| 345 bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; } | 227 int reg_code; |
| 346 bool is(DoubleRegister reg) const { return code_ == reg.code_; } | |
| 347 | |
| 348 int code() const { | |
| 349 DCHECK(is_valid()); | |
| 350 return code_; | |
| 351 } | |
| 352 int bit() const { | |
| 353 DCHECK(is_valid()); | |
| 354 return 1 << code_; | |
| 355 } | |
| 356 void split_code(int* vm, int* m) const { | |
| 357 DCHECK(is_valid()); | |
| 358 *m = (code_ & 0x10) >> 4; | |
| 359 *vm = code_ & 0x0F; | |
| 360 } | |
| 361 | |
| 362 int code_; | |
| 363 }; | 228 }; |
| 364 | 229 |
| 365 | 230 #define DECLARE_REGISTER(R) \ |
| 366 const DoubleRegister no_dreg = {-1}; | 231 const DoubleRegister R = {DoubleRegister::kCode_##R}; |
| 367 const DoubleRegister d0 = {0}; | 232 DOUBLE_REGISTERS(DECLARE_REGISTER) |
| 368 const DoubleRegister d1 = {1}; | 233 #undef DECLARE_REGISTER |
| 369 const DoubleRegister d2 = {2}; | 234 const Register no_dreg = {Register::kCode_no_reg}; |
| 370 const DoubleRegister d3 = {3}; | |
| 371 const DoubleRegister d4 = {4}; | |
| 372 const DoubleRegister d5 = {5}; | |
| 373 const DoubleRegister d6 = {6}; | |
| 374 const DoubleRegister d7 = {7}; | |
| 375 const DoubleRegister d8 = {8}; | |
| 376 const DoubleRegister d9 = {9}; | |
| 377 const DoubleRegister d10 = {10}; | |
| 378 const DoubleRegister d11 = {11}; | |
| 379 const DoubleRegister d12 = {12}; | |
| 380 const DoubleRegister d13 = {13}; | |
| 381 const DoubleRegister d14 = {14}; | |
| 382 const DoubleRegister d15 = {15}; | |
| 383 const DoubleRegister d16 = {16}; | |
| 384 const DoubleRegister d17 = {17}; | |
| 385 const DoubleRegister d18 = {18}; | |
| 386 const DoubleRegister d19 = {19}; | |
| 387 const DoubleRegister d20 = {20}; | |
| 388 const DoubleRegister d21 = {21}; | |
| 389 const DoubleRegister d22 = {22}; | |
| 390 const DoubleRegister d23 = {23}; | |
| 391 const DoubleRegister d24 = {24}; | |
| 392 const DoubleRegister d25 = {25}; | |
| 393 const DoubleRegister d26 = {26}; | |
| 394 const DoubleRegister d27 = {27}; | |
| 395 const DoubleRegister d28 = {28}; | |
| 396 const DoubleRegister d29 = {29}; | |
| 397 const DoubleRegister d30 = {30}; | |
| 398 const DoubleRegister d31 = {31}; | |
| 399 | 235 |
| 400 // Aliases for double registers. Defined using #define instead of | 236 // Aliases for double registers. Defined using #define instead of |
| 401 // "static const DoubleRegister&" because Clang complains otherwise when a | 237 // "static const DoubleRegister&" because Clang complains otherwise when a |
| 402 // compilation unit that includes this header doesn't use the variables. | 238 // compilation unit that includes this header doesn't use the variables. |
| 403 #define kFirstCalleeSavedDoubleReg d14 | 239 #define kFirstCalleeSavedDoubleReg d14 |
| 404 #define kLastCalleeSavedDoubleReg d31 | 240 #define kLastCalleeSavedDoubleReg d31 |
| 405 #define kDoubleRegZero d14 | 241 #define kDoubleRegZero d14 |
| 406 #define kScratchDoubleReg d13 | 242 #define kScratchDoubleReg d13 |
| 407 | 243 |
| 408 Register ToRegister(int num); | 244 Register ToRegister(int num); |
| 409 | 245 |
| 410 // Coprocessor register | 246 // Coprocessor register |
| 411 struct CRegister { | 247 struct CRegister { |
| 412 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 248 bool is_valid() const { return 0 <= reg_code && reg_code < 16; } |
| 413 bool is(CRegister creg) const { return code_ == creg.code_; } | 249 bool is(CRegister creg) const { return reg_code == creg.reg_code; } |
| 414 int code() const { | 250 int code() const { |
| 415 DCHECK(is_valid()); | 251 DCHECK(is_valid()); |
| 416 return code_; | 252 return reg_code; |
| 417 } | 253 } |
| 418 int bit() const { | 254 int bit() const { |
| 419 DCHECK(is_valid()); | 255 DCHECK(is_valid()); |
| 420 return 1 << code_; | 256 return 1 << reg_code; |
| 421 } | 257 } |
| 422 | 258 |
| 423 // Unfortunately we can't make this private in a struct. | 259 // Unfortunately we can't make this private in a struct. |
| 424 int code_; | 260 int reg_code; |
| 425 }; | 261 }; |
| 426 | 262 |
| 427 | 263 |
| 428 const CRegister no_creg = {-1}; | 264 const CRegister no_creg = {-1}; |
| 429 | 265 |
| 430 const CRegister cr0 = {0}; | 266 const CRegister cr0 = {0}; |
| 431 const CRegister cr1 = {1}; | 267 const CRegister cr1 = {1}; |
| 432 const CRegister cr2 = {2}; | 268 const CRegister cr2 = {2}; |
| 433 const CRegister cr3 = {3}; | 269 const CRegister cr3 = {3}; |
| 434 const CRegister cr4 = {4}; | 270 const CRegister cr4 = {4}; |
| (...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 | 1445 |
| 1610 | 1446 |
| 1611 class EnsureSpace BASE_EMBEDDED { | 1447 class EnsureSpace BASE_EMBEDDED { |
| 1612 public: | 1448 public: |
| 1613 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } | 1449 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } |
| 1614 }; | 1450 }; |
| 1615 } // namespace internal | 1451 } // namespace internal |
| 1616 } // namespace v8 | 1452 } // namespace v8 |
| 1617 | 1453 |
| 1618 #endif // V8_PPC_ASSEMBLER_PPC_H_ | 1454 #endif // V8_PPC_ASSEMBLER_PPC_H_ |
| OLD | NEW |