supported_ = kDefaultCpuFeatures | (1 << CPUID);
{ Scope fscope(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::NONE);
+ __ cpuid();
}
supported_ = kDefaultCpuFeatures;
- // Move the result from ecx:edx to rax and make sure to mark the
- // CPUID feature as supported.
- __ movl(rax, rdx); // Zero-extended to 64 bits.
- __ shl(rcx, Immediate(32));
+ // 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));
// Feature flags bit positions. They are mostly based on the CPUID spec.
// (We assign CPUID itself to one of the currently reserved bits --
// feel free to change this if needed.)
- enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 };
+ enum Feature { SSE3 = 32,
+ SSE2 = 26,
+ CMOV = 15,
+ RDTSC = 4,
+ CPUID = 10,
+ SAHF = 0};
// Detect features of the target CPU. Set safe defaults if the serializer
// is enabled (snapshots must be portable).
static void Probe();
// One operand is a smi.
// Check whether the non-smi is a heap number.
- ASSERT_EQ(1, kSmiTagMask);
+ ASSERT_EQ(static_cast<intptr_t>(1), kSmiTagMask);
// rcx still holds rax & kSmiTag, which is either zero or one.
__ decq(rcx); // If rax is a smi, all 1s, else all 0s.
__ movq(rbx, rdx);
__ fild_s(Operand(rsp, 0 * kPointerSize));
__ fucompp();
__ fnstsw_ax();
- __ sahf(); // TODO(X64): Not available.
- __ j(not_zero, &operand_conversion_failure);
- __ j(parity_even, &operand_conversion_failure);
-
+ if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) {
+ __ sahf();
+ __ j(not_zero, &operand_conversion_failure);
+ __ j(parity_even, &operand_conversion_failure);
+ } else {
+ __ and_(rax, Immediate(0x4400));
+ __ cmpl(rax, Immediate(0x4000));
+ __ j(not_zero, &operand_conversion_failure);
+ }
// Check if left operand is int32.
__ fist_s(Operand(rsp, 1 * kPointerSize));
__ fild_s(Operand(rsp, 1 * kPointerSize));
__ fucompp();
__ fnstsw_ax();
- __ sahf(); // TODO(X64): Not available. Test bits in ax directly
- __ j(not_zero, &operand_conversion_failure);
- __ j(parity_even, &operand_conversion_failure);
+ if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) {
+ __ sahf();
+ __ j(not_zero, &operand_conversion_failure);
+ __ j(parity_even, &operand_conversion_failure);
+ } else {
+ __ and_(rax, Immediate(0x4400));
+ __ cmpl(rax, Immediate(0x4000));
+ __ j(not_zero, &operand_conversion_failure);
+ }
}
// Get int32 operands and perform bitop.