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