Chromium Code Reviews| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 return (reg.code() >= 6) ? reg.code() - 2 : reg.code(); | 134 return (reg.code() >= 6) ? reg.code() - 2 : reg.code(); |
| 135 } | 135 } |
| 136 | 136 |
| 137 | 137 |
| 138 inline Register Register::FromAllocationIndex(int index) { | 138 inline Register Register::FromAllocationIndex(int index) { |
| 139 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 139 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 140 return (index >= 4) ? from_code(index + 2) : from_code(index); | 140 return (index >= 4) ? from_code(index + 2) : from_code(index); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 struct IntelDoubleRegister { | 144 struct DoubleRegister { |
| 145 static const int kMaxNumRegisters = 8; | 145 static const int kMaxNumRegisters = 8; |
| 146 static const int kMaxNumAllocatableRegisters = 7; | 146 static const int kMaxNumAllocatableRegisters = 7; |
| 147 static int NumAllocatableRegisters(); | 147 static int NumAllocatableRegisters(); |
| 148 static int NumRegisters(); | 148 static int NumRegisters(); |
| 149 static const char* AllocationIndexToString(int index); | 149 static const char* AllocationIndexToString(int index); |
| 150 | 150 |
| 151 static int ToAllocationIndex(IntelDoubleRegister reg) { | 151 static int ToAllocationIndex(DoubleRegister reg) { |
| 152 ASSERT(reg.code() != 0); | 152 ASSERT(reg.code() != 0); |
| 153 return reg.code() - 1; | 153 return reg.code() - 1; |
| 154 } | 154 } |
| 155 | 155 |
| 156 static IntelDoubleRegister FromAllocationIndex(int index) { | 156 static DoubleRegister FromAllocationIndex(int index) { |
| 157 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | 157 ASSERT(index >= 0 && index < NumAllocatableRegisters()); |
| 158 return from_code(index + 1); | 158 return from_code(index + 1); |
| 159 } | 159 } |
| 160 | 160 |
| 161 static IntelDoubleRegister from_code(int code) { | 161 static DoubleRegister from_code(int code) { |
| 162 IntelDoubleRegister result = { code }; | 162 DoubleRegister result = { code }; |
| 163 return result; | 163 return result; |
| 164 } | 164 } |
| 165 | 165 |
| 166 bool is_valid() const { | 166 bool is_valid() const { |
| 167 return 0 <= code_ && code_ < NumRegisters(); | 167 return 0 <= code_ && code_ < NumRegisters(); |
| 168 } | 168 } |
| 169 int code() const { | 169 int code() const { |
| 170 ASSERT(is_valid()); | 170 ASSERT(is_valid()); |
| 171 return code_; | 171 return code_; |
| 172 } | 172 } |
| 173 | 173 |
| 174 int code_; | 174 int code_; |
| 175 }; | 175 }; |
| 176 | 176 |
| 177 | 177 |
| 178 const IntelDoubleRegister double_register_0 = { 0 }; | 178 const DoubleRegister double_register_0 = { 0 }; |
| 179 const IntelDoubleRegister double_register_1 = { 1 }; | 179 const DoubleRegister double_register_1 = { 1 }; |
| 180 const IntelDoubleRegister double_register_2 = { 2 }; | 180 const DoubleRegister double_register_2 = { 2 }; |
| 181 const IntelDoubleRegister double_register_3 = { 3 }; | 181 const DoubleRegister double_register_3 = { 3 }; |
| 182 const IntelDoubleRegister double_register_4 = { 4 }; | 182 const DoubleRegister double_register_4 = { 4 }; |
| 183 const IntelDoubleRegister double_register_5 = { 5 }; | 183 const DoubleRegister double_register_5 = { 5 }; |
| 184 const IntelDoubleRegister double_register_6 = { 6 }; | 184 const DoubleRegister double_register_6 = { 6 }; |
| 185 const IntelDoubleRegister double_register_7 = { 7 }; | 185 const DoubleRegister double_register_7 = { 7 }; |
| 186 const IntelDoubleRegister no_double_reg = { -1 }; | 186 const DoubleRegister no_double_reg = { -1 }; |
| 187 | 187 |
| 188 | 188 |
| 189 struct XMMRegister : IntelDoubleRegister { | 189 struct XMMRegister : DoubleRegister { |
|
Jakob Kummerow
2014/05/08 10:55:03
I think you can combine these two classes as well.
Sven Panne
2014/05/08 12:13:07
This is what I actually meant with my initial comm
| |
| 190 static const int kNumAllocatableRegisters = 7; | 190 static const int kNumAllocatableRegisters = 7; |
| 191 static const int kNumRegisters = 8; | 191 static const int kNumRegisters = 8; |
| 192 | 192 |
| 193 static XMMRegister from_code(int code) { | 193 static XMMRegister from_code(int code) { |
| 194 STATIC_ASSERT(sizeof(XMMRegister) == sizeof(IntelDoubleRegister)); | 194 STATIC_ASSERT(sizeof(XMMRegister) == sizeof(DoubleRegister)); |
| 195 XMMRegister result; | 195 XMMRegister result; |
| 196 result.code_ = code; | 196 result.code_ = code; |
| 197 return result; | 197 return result; |
| 198 } | 198 } |
| 199 | 199 |
| 200 bool is(XMMRegister reg) const { return code_ == reg.code_; } | 200 bool is(XMMRegister reg) const { return code_ == reg.code_; } |
| 201 | 201 |
| 202 static XMMRegister FromAllocationIndex(int index) { | 202 static XMMRegister FromAllocationIndex(int index) { |
| 203 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | 203 ASSERT(index >= 0 && index < NumAllocatableRegisters()); |
| 204 return from_code(index + 1); | 204 return from_code(index + 1); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 224 #define xmm1 (static_cast<const XMMRegister&>(double_register_1)) | 224 #define xmm1 (static_cast<const XMMRegister&>(double_register_1)) |
| 225 #define xmm2 (static_cast<const XMMRegister&>(double_register_2)) | 225 #define xmm2 (static_cast<const XMMRegister&>(double_register_2)) |
| 226 #define xmm3 (static_cast<const XMMRegister&>(double_register_3)) | 226 #define xmm3 (static_cast<const XMMRegister&>(double_register_3)) |
| 227 #define xmm4 (static_cast<const XMMRegister&>(double_register_4)) | 227 #define xmm4 (static_cast<const XMMRegister&>(double_register_4)) |
| 228 #define xmm5 (static_cast<const XMMRegister&>(double_register_5)) | 228 #define xmm5 (static_cast<const XMMRegister&>(double_register_5)) |
| 229 #define xmm6 (static_cast<const XMMRegister&>(double_register_6)) | 229 #define xmm6 (static_cast<const XMMRegister&>(double_register_6)) |
| 230 #define xmm7 (static_cast<const XMMRegister&>(double_register_7)) | 230 #define xmm7 (static_cast<const XMMRegister&>(double_register_7)) |
| 231 #define no_xmm_reg (static_cast<const XMMRegister&>(no_double_reg)) | 231 #define no_xmm_reg (static_cast<const XMMRegister&>(no_double_reg)) |
| 232 | 232 |
| 233 | 233 |
| 234 struct X87Register : IntelDoubleRegister { | |
| 235 static const int kNumAllocatableRegisters = 5; | |
| 236 static const int kNumRegisters = 5; | |
| 237 | |
| 238 bool is(X87Register reg) const { | |
| 239 return code_ == reg.code_; | |
| 240 } | |
| 241 | |
| 242 static const char* AllocationIndexToString(int index) { | |
| 243 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | |
| 244 const char* const names[] = { | |
| 245 "stX_0", "stX_1", "stX_2", "stX_3", "stX_4" | |
| 246 }; | |
| 247 return names[index]; | |
| 248 } | |
| 249 | |
| 250 static X87Register FromAllocationIndex(int index) { | |
| 251 STATIC_ASSERT(sizeof(X87Register) == sizeof(IntelDoubleRegister)); | |
| 252 ASSERT(index >= 0 && index < NumAllocatableRegisters()); | |
| 253 X87Register result; | |
| 254 result.code_ = index; | |
| 255 return result; | |
| 256 } | |
| 257 | |
| 258 static int ToAllocationIndex(X87Register reg) { | |
| 259 return reg.code_; | |
| 260 } | |
| 261 }; | |
| 262 | |
| 263 #define stX_0 static_cast<const X87Register&>(double_register_0) | |
| 264 #define stX_1 static_cast<const X87Register&>(double_register_1) | |
| 265 #define stX_2 static_cast<const X87Register&>(double_register_2) | |
| 266 #define stX_3 static_cast<const X87Register&>(double_register_3) | |
| 267 #define stX_4 static_cast<const X87Register&>(double_register_4) | |
| 268 | |
| 269 | |
| 270 typedef IntelDoubleRegister DoubleRegister; | |
| 271 | |
| 272 | |
| 273 enum Condition { | 234 enum Condition { |
| 274 // any value < 0 is considered no_condition | 235 // any value < 0 is considered no_condition |
| 275 no_condition = -1, | 236 no_condition = -1, |
| 276 | 237 |
| 277 overflow = 0, | 238 overflow = 0, |
| 278 no_overflow = 1, | 239 no_overflow = 1, |
| 279 below = 2, | 240 below = 2, |
| 280 above_equal = 3, | 241 above_equal = 3, |
| 281 equal = 4, | 242 equal = 4, |
| 282 not_equal = 5, | 243 not_equal = 5, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 class NextField: public BitField<int, 2, 32-2> {}; | 474 class NextField: public BitField<int, 2, 32-2> {}; |
| 514 | 475 |
| 515 void init(Label* L, Type type); | 476 void init(Label* L, Type type); |
| 516 }; | 477 }; |
| 517 | 478 |
| 518 | 479 |
| 519 | 480 |
| 520 // CpuFeatures keeps track of which features are supported by the target CPU. | 481 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 521 // Supported features must be enabled by a CpuFeatureScope before use. | 482 // Supported features must be enabled by a CpuFeatureScope before use. |
| 522 // Example: | 483 // Example: |
| 523 // if (assembler->IsSupported(SSE2)) { | 484 // if (assembler->IsSupported(CMOV)) { |
| 524 // CpuFeatureScope fscope(assembler, SSE2); | 485 // CpuFeatureScope fscope(assembler, CMOV); |
| 525 // // Generate SSE2 floating point code. | 486 // // Generate code containing cmov. |
| 526 // } else { | 487 // } else { |
| 527 // // Generate standard x87 floating point code. | 488 // // Generate alternative code. |
| 528 // } | 489 // } |
| 529 class CpuFeatures : public AllStatic { | 490 class CpuFeatures : public AllStatic { |
| 530 public: | 491 public: |
| 531 // Detect features of the target CPU. Set safe defaults if the serializer | 492 // Detect features of the target CPU. Set safe defaults if the serializer |
| 532 // is enabled (snapshots must be portable). | 493 // is enabled (snapshots must be portable). |
| 533 static void Probe(bool serializer_enabled); | 494 static void Probe(bool serializer_enabled); |
| 534 | 495 |
| 535 // Check whether a feature is supported by the target CPU. | 496 // Check whether a feature is supported by the target CPU. |
| 536 static bool IsSupported(CpuFeature f) { | 497 static bool IsSupported(CpuFeature f) { |
| 537 ASSERT(initialized_); | 498 ASSERT(initialized_); |
| 538 if (Check(f, cross_compile_)) return true; | 499 if (Check(f, cross_compile_)) return true; |
| 539 if (f == SSE2 && !FLAG_enable_sse2) return false; | |
| 540 if (f == SSE3 && !FLAG_enable_sse3) return false; | 500 if (f == SSE3 && !FLAG_enable_sse3) return false; |
| 541 if (f == SSE4_1 && !FLAG_enable_sse4_1) return false; | 501 if (f == SSE4_1 && !FLAG_enable_sse4_1) return false; |
| 542 if (f == CMOV && !FLAG_enable_cmov) return false; | 502 if (f == CMOV && !FLAG_enable_cmov) return false; |
| 543 return Check(f, supported_); | 503 return Check(f, supported_); |
| 544 } | 504 } |
| 545 | 505 |
| 546 static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) { | 506 static bool IsSafeForSnapshot(Isolate* isolate, CpuFeature f) { |
| 547 return Check(f, cross_compile_) || | 507 return Check(f, cross_compile_) || |
| 548 (IsSupported(f) && | 508 (IsSupported(f) && |
| 549 !(Serializer::enabled(isolate) && | 509 !(Serializer::enabled(isolate) && |
| 550 Check(f, found_by_runtime_probing_only_))); | 510 Check(f, found_by_runtime_probing_only_))); |
| 551 } | 511 } |
| 552 | 512 |
| 553 static bool VerifyCrossCompiling() { | 513 static bool VerifyCrossCompiling() { |
| 554 return cross_compile_ == 0; | 514 return cross_compile_ == 0; |
| 555 } | 515 } |
| 556 | 516 |
| 557 static bool VerifyCrossCompiling(CpuFeature f) { | 517 static bool VerifyCrossCompiling(CpuFeature f) { |
| 558 uint64_t mask = flag2set(f); | 518 uint64_t mask = flag2set(f); |
| 559 return cross_compile_ == 0 || | 519 return cross_compile_ == 0 || |
| 560 (cross_compile_ & mask) == mask; | 520 (cross_compile_ & mask) == mask; |
| 561 } | 521 } |
| 562 | 522 |
| 563 static bool SupportsCrankshaft() { return IsSupported(SSE2); } | 523 static bool SupportsCrankshaft() { return true; } |
| 564 | 524 |
| 565 private: | 525 private: |
| 566 static bool Check(CpuFeature f, uint64_t set) { | 526 static bool Check(CpuFeature f, uint64_t set) { |
| 567 return (set & flag2set(f)) != 0; | 527 return (set & flag2set(f)) != 0; |
| 568 } | 528 } |
| 569 | 529 |
| 570 static uint64_t flag2set(CpuFeature f) { | 530 static uint64_t flag2set(CpuFeature f) { |
| 571 return static_cast<uint64_t>(1) << f; | 531 return static_cast<uint64_t>(1) << f; |
| 572 } | 532 } |
| 573 | 533 |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1288 private: | 1248 private: |
| 1289 Assembler* assembler_; | 1249 Assembler* assembler_; |
| 1290 #ifdef DEBUG | 1250 #ifdef DEBUG |
| 1291 int space_before_; | 1251 int space_before_; |
| 1292 #endif | 1252 #endif |
| 1293 }; | 1253 }; |
| 1294 | 1254 |
| 1295 } } // namespace v8::internal | 1255 } } // namespace v8::internal |
| 1296 | 1256 |
| 1297 #endif // V8_IA32_ASSEMBLER_IA32_H_ | 1257 #endif // V8_IA32_ASSEMBLER_IA32_H_ |
| OLD | NEW |