| 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 |