| Index: src/assembler-ia32.cc
|
| ===================================================================
|
| --- src/assembler-ia32.cc (revision 1360)
|
| +++ src/assembler-ia32.cc (working copy)
|
| @@ -69,27 +69,27 @@
|
| // Implementation of CpuFeatures
|
|
|
| // Safe default is no features.
|
| -uint32_t CpuFeatures::supported_ = 0;
|
| -uint32_t CpuFeatures::enabled_ = 0;
|
| +uint64_t CpuFeatures::supported_ = 0;
|
| +uint64_t CpuFeatures::enabled_ = 0;
|
|
|
|
|
| -typedef int (*F0)();
|
| -
|
| // The Probe method needs executable memory, so it uses Heap::CreateCode.
|
| // Allocation failure is silent and leads to safe default.
|
| void CpuFeatures::Probe() {
|
| - supported_ = 0;
|
| + ASSERT(Heap::HasBeenSetup());
|
| + ASSERT(supported_ == 0);
|
| if (Serializer::enabled()) return; // No features if we might serialize.
|
| +
|
| Assembler assm(NULL, 0);
|
| - Label done;
|
| + Label cpuid, done;
|
| #define __ assm.
|
| // Save old esp, since we are going to modify the stack.
|
| __ push(ebp);
|
| __ pushfd();
|
| __ push(ecx);
|
| - __ push(edx);
|
| __ push(ebx);
|
| __ mov(ebp, Operand(esp));
|
| +
|
| // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
|
| __ pushfd();
|
| __ pop(eax);
|
| @@ -100,34 +100,48 @@
|
| __ pushfd();
|
| __ pop(eax);
|
| __ xor_(eax, Operand(edx)); // Different if CPUID is supported.
|
| - __ j(zero, &done);
|
| - // Invoke CPUID with 1 in eax to get feature information in edx.
|
| + __ j(not_zero, &cpuid);
|
| +
|
| + // CPUID not supported. Clear the supported features in edx:eax.
|
| + __ xor_(eax, Operand(eax));
|
| + __ xor_(edx, Operand(edx));
|
| + __ 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);
|
| __ mov(eax, 1);
|
| - // Temporarily force CPUID support, since we know it is safe here.
|
| supported_ = (1 << CPUID);
|
| { Scope fscope(CPUID);
|
| __ cpuid();
|
| }
|
| supported_ = 0;
|
| - // Return result in eax.
|
| +
|
| + // Move the result from ecx:edx to edx:eax and make sure to mark the
|
| + // CPUID feature as supported.
|
| __ mov(eax, Operand(edx));
|
| + __ or_(eax, 1 << CPUID);
|
| + __ mov(edx, Operand(ecx));
|
| +
|
| + // Done.
|
| __ bind(&done);
|
| __ mov(esp, Operand(ebp));
|
| __ pop(ebx);
|
| - __ pop(edx);
|
| __ pop(ecx);
|
| __ popfd();
|
| __ pop(ebp);
|
| __ ret(0);
|
| #undef __
|
| +
|
| CodeDesc desc;
|
| assm.GetCode(&desc);
|
| Object* code =
|
| Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL);
|
| if (!code->IsCode()) return;
|
| - F0 f = FUNCTION_CAST<F0>(Code::cast(code)->entry());
|
| - uint32_t res = f();
|
| - supported_ = (res | (1 << CPUID));
|
| + typedef uint64_t (*F0)();
|
| + F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
|
| + supported_ = probe();
|
| }
|
|
|
|
|
| @@ -1614,6 +1628,15 @@
|
| }
|
|
|
|
|
| +void Assembler::fisttp_s(const Operand& adr) {
|
| + ASSERT(CpuFeatures::IsEnabled(CpuFeatures::SSE3));
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + EMIT(0xDB);
|
| + emit_operand(ecx, adr);
|
| +}
|
| +
|
| +
|
| void Assembler::fist_s(const Operand& adr) {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
| @@ -1809,6 +1832,14 @@
|
| }
|
|
|
|
|
| +void Assembler::fnclex() {
|
| + EnsureSpace ensure_space(this);
|
| + last_pc_ = pc_;
|
| + EMIT(0xDB);
|
| + EMIT(0xE2);
|
| +}
|
| +
|
| +
|
| void Assembler::sahf() {
|
| EnsureSpace ensure_space(this);
|
| last_pc_ = pc_;
|
|
|