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 |