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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 ASSERT(!initialized_); | 94 ASSERT(!initialized_); |
95 ASSERT(supported_ == 0); | 95 ASSERT(supported_ == 0); |
96 #ifdef DEBUG | 96 #ifdef DEBUG |
97 initialized_ = true; | 97 initialized_ = true; |
98 #endif | 98 #endif |
99 if (Serializer::enabled()) { | 99 if (Serializer::enabled()) { |
100 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 100 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
101 return; // No features if we might serialize. | 101 return; // No features if we might serialize. |
102 } | 102 } |
103 | 103 |
104 const int kBufferSize = 4 * KB; | 104 uint64_t probed_features = 0; |
105 VirtualMemory* memory = new VirtualMemory(kBufferSize); | 105 CPU cpu; |
106 if (!memory->IsReserved()) { | 106 if (cpu.has_sse41()) { |
107 delete memory; | 107 probed_features |= static_cast<uint64_t>(1) << SSE4_1; |
108 return; | |
109 } | 108 } |
110 ASSERT(memory->size() >= static_cast<size_t>(kBufferSize)); | 109 if (cpu.has_sse3()) { |
111 if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) { | 110 probed_features |= static_cast<uint64_t>(1) << SSE3; |
112 delete memory; | 111 } |
113 return; | 112 if (cpu.has_sse2()) { |
| 113 probed_features |= static_cast<uint64_t>(1) << SSE2; |
| 114 } |
| 115 if (cpu.has_cmov()) { |
| 116 probed_features |= static_cast<uint64_t>(1) << CMOV; |
114 } | 117 } |
115 | 118 |
116 Assembler assm(NULL, memory->address(), kBufferSize); | 119 // SAHF must be available in compat/legacy mode. |
117 Label cpuid, done; | 120 ASSERT(cpu.has_sahf()); |
118 #define __ assm. | 121 probed_features |= static_cast<uint64_t>(1) << SAHF; |
119 // Save old esp, since we are going to modify the stack. | |
120 __ push(ebp); | |
121 __ pushfd(); | |
122 __ push(ecx); | |
123 __ push(ebx); | |
124 __ mov(ebp, esp); | |
125 | 122 |
126 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. | |
127 __ pushfd(); | |
128 __ pop(eax); | |
129 __ mov(edx, eax); | |
130 __ xor_(eax, 0x200000); // Flip bit 21. | |
131 __ push(eax); | |
132 __ popfd(); | |
133 __ pushfd(); | |
134 __ pop(eax); | |
135 __ xor_(eax, edx); // Different if CPUID is supported. | |
136 __ j(not_zero, &cpuid); | |
137 | |
138 // CPUID not supported. Clear the supported features in edx:eax. | |
139 __ xor_(eax, eax); | |
140 __ xor_(edx, edx); | |
141 __ jmp(&done); | |
142 | |
143 // Invoke CPUID with 1 in eax to get feature information in | |
144 // ecx:edx. Temporarily enable CPUID support because we know it's | |
145 // safe here. | |
146 __ bind(&cpuid); | |
147 __ mov(eax, 1); | |
148 supported_ = (1 << CPUID); | |
149 { CpuFeatureScope fscope(&assm, CPUID); | |
150 __ cpuid(); | |
151 } | |
152 supported_ = 0; | |
153 | |
154 // Move the result from ecx:edx to edx:eax and make sure to mark the | |
155 // CPUID feature as supported. | |
156 __ mov(eax, edx); | |
157 __ or_(eax, 1 << CPUID); | |
158 __ mov(edx, ecx); | |
159 | |
160 // Done. | |
161 __ bind(&done); | |
162 __ mov(esp, ebp); | |
163 __ pop(ebx); | |
164 __ pop(ecx); | |
165 __ popfd(); | |
166 __ pop(ebp); | |
167 __ ret(0); | |
168 #undef __ | |
169 | |
170 typedef uint64_t (*F0)(); | |
171 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address())); | |
172 uint64_t probed_features = probe(); | |
173 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); | 123 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); |
174 supported_ = probed_features | platform_features; | 124 supported_ = probed_features | platform_features; |
175 found_by_runtime_probing_only_ = probed_features & ~platform_features; | 125 found_by_runtime_probing_only_ = probed_features & ~platform_features; |
176 | |
177 delete memory; | |
178 } | 126 } |
179 | 127 |
180 | 128 |
181 // ----------------------------------------------------------------------------- | 129 // ----------------------------------------------------------------------------- |
182 // Implementation of Displacement | 130 // Implementation of Displacement |
183 | 131 |
184 void Displacement::init(Label* L, Type type) { | 132 void Displacement::init(Label* L, Type type) { |
185 ASSERT(!L->is_bound()); | 133 ASSERT(!L->is_bound()); |
186 int next = 0; | 134 int next = 0; |
187 if (L->is_linked()) { | 135 if (L->is_linked()) { |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 415 } |
468 } | 416 } |
469 | 417 |
470 | 418 |
471 void Assembler::CodeTargetAlign() { | 419 void Assembler::CodeTargetAlign() { |
472 Align(16); // Preferred alignment of jump targets on ia32. | 420 Align(16); // Preferred alignment of jump targets on ia32. |
473 } | 421 } |
474 | 422 |
475 | 423 |
476 void Assembler::cpuid() { | 424 void Assembler::cpuid() { |
477 ASSERT(IsEnabled(CPUID)); | |
478 EnsureSpace ensure_space(this); | 425 EnsureSpace ensure_space(this); |
479 EMIT(0x0F); | 426 EMIT(0x0F); |
480 EMIT(0xA2); | 427 EMIT(0xA2); |
481 } | 428 } |
482 | 429 |
483 | 430 |
484 void Assembler::pushad() { | 431 void Assembler::pushad() { |
485 EnsureSpace ensure_space(this); | 432 EnsureSpace ensure_space(this); |
486 EMIT(0x60); | 433 EMIT(0x60); |
487 } | 434 } |
(...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2707 fprintf(coverage_log, "%s\n", file_line); | 2654 fprintf(coverage_log, "%s\n", file_line); |
2708 fflush(coverage_log); | 2655 fflush(coverage_log); |
2709 } | 2656 } |
2710 } | 2657 } |
2711 | 2658 |
2712 #endif | 2659 #endif |
2713 | 2660 |
2714 } } // namespace v8::internal | 2661 } } // namespace v8::internal |
2715 | 2662 |
2716 #endif // V8_TARGET_ARCH_IA32 | 2663 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |