Index: src/x64/assembler-x64.cc |
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc |
index 68d2c05edc526626976de2c7e5c6a7a0f6d6a8f6..f3ce4b9420dd36ecdfaf017b34bdf32af7fb9eb3 100644 |
--- a/src/x64/assembler-x64.cc |
+++ b/src/x64/assembler-x64.cc |
@@ -63,98 +63,32 @@ void CpuFeatures::Probe() { |
return; // No features if we might serialize. |
} |
- const int kBufferSize = 4 * KB; |
- VirtualMemory* memory = new VirtualMemory(kBufferSize); |
- if (!memory->IsReserved()) { |
- delete memory; |
- return; |
+ uint64_t probed_features = 0; |
+ CPU cpu; |
+ if (cpu.has_sse41()) { |
+ probed_features |= static_cast<uint64_t>(1) << SSE4_1; |
} |
- ASSERT(memory->size() >= static_cast<size_t>(kBufferSize)); |
- if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) { |
- delete memory; |
- return; |
+ if (cpu.has_sse3()) { |
+ probed_features |= static_cast<uint64_t>(1) << SSE3; |
} |
- Assembler assm(NULL, memory->address(), kBufferSize); |
- Label cpuid, done; |
-#define __ assm. |
- // Save old rsp, since we are going to modify the stack. |
- __ push(rbp); |
- __ pushfq(); |
- __ push(rdi); |
- __ push(rcx); |
- __ push(rbx); |
- __ movq(rbp, rsp); |
- |
- // If we can modify bit 21 of the EFLAGS register, then CPUID is supported. |
- __ pushfq(); |
- __ pop(rax); |
- __ movq(rdx, rax); |
- __ xor_(rax, Immediate(0x200000)); // Flip bit 21. |
- __ push(rax); |
- __ popfq(); |
- __ pushfq(); |
- __ pop(rax); |
- __ xor_(rax, rdx); // Different if CPUID is supported. |
- __ j(not_zero, &cpuid); |
- |
- // CPUID not supported. Clear the supported features in rax. |
- __ xor_(rax, rax); |
- __ jmp(&done); |
- |
- // Invoke CPUID with 1 in eax to get feature information in |
- // ecx:edx. Temporarily enable CPUID support because we know it's |
- // safe here. |
- __ bind(&cpuid); |
- __ movl(rax, Immediate(1)); |
- supported_ = kDefaultCpuFeatures | (1 << CPUID); |
- { CpuFeatureScope fscope(&assm, CPUID); |
- __ cpuid(); |
- // Move the result from ecx:edx to rdi. |
- __ movl(rdi, rdx); // Zero-extended to 64 bits. |
- __ shl(rcx, Immediate(32)); |
- __ or_(rdi, rcx); |
- |
- // Get the sahf supported flag, from CPUID(0x80000001) |
- __ movq(rax, 0x80000001, RelocInfo::NONE64); |
- __ cpuid(); |
+ // SSE2 must be available on every x64 CPU. |
+ ASSERT(cpu.has_sse2()); |
+ probed_features |= static_cast<uint64_t>(1) << SSE2; |
+ |
+ // CMOD must be available on every x64 CPU. |
+ ASSERT(cpu.has_cmov()); |
+ probed_features |= static_cast<uint64_t>(1) << CMOV; |
+ |
+ // SAHF is not generally available in long mode. |
+ if (cpu.has_sahf()) { |
+ probed_features |= static_cast<uint64_t>(1) << SAHF; |
} |
- supported_ = kDefaultCpuFeatures; |
- // Put the CPU flags in rax. |
- // rax = (rcx & 1) | (rdi & ~1) | (1 << CPUID). |
- __ movl(rax, Immediate(1)); |
- __ and_(rcx, rax); // Bit 0 is set if SAHF instruction supported. |
- __ not_(rax); |
- __ and_(rax, rdi); |
- __ or_(rax, rcx); |
- __ or_(rax, Immediate(1 << CPUID)); |
- |
- // Done. |
- __ bind(&done); |
- __ movq(rsp, rbp); |
- __ pop(rbx); |
- __ pop(rcx); |
- __ pop(rdi); |
- __ popfq(); |
- __ pop(rbp); |
- __ ret(0); |
-#undef __ |
- |
- typedef uint64_t (*F0)(); |
- F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address())); |
- |
- uint64_t probed_features = probe(); |
uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform(); |
supported_ = probed_features | platform_features; |
found_by_runtime_probing_only_ |
= probed_features & ~kDefaultCpuFeatures & ~platform_features; |
- |
- // CMOV must be available on an X64 CPU. |
- ASSERT(IsSupported(CPUID)); |
- ASSERT(IsSupported(CMOV)); |
- |
- delete memory; |
} |
@@ -987,7 +921,6 @@ void Assembler::cmpb_al(Immediate imm8) { |
void Assembler::cpuid() { |
- ASSERT(IsEnabled(CPUID)); |
EnsureSpace ensure_space(this); |
emit(0x0F); |
emit(0xA2); |