X64: Use sahf instruction only on processors that support it.

Review URL: http://codereview.chromium.org/183028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2793 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2009-09-01 11:32:20 +00:00
parent 6cdd89b165
commit 0f20431c36
4 changed files with 47 additions and 15 deletions

View File

@ -120,13 +120,23 @@ void CpuFeatures::Probe() {
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));

View File

@ -361,7 +361,12 @@ class CpuFeatures : public AllStatic {
// 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();

View File

@ -6546,7 +6546,7 @@ void CompareStub::Generate(MacroAssembler* masm) {
// 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);
@ -7722,18 +7722,29 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) {
__ 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.

View File

@ -600,8 +600,14 @@ void MacroAssembler::FCmp() {
fcompp();
push(rax);
fnstsw_ax();
// TODO(X64): Check that sahf is safe to use, using CPUProbe.
sahf();
if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) {
sahf();
} else {
shrl(rax, Immediate(8));
and_(rax, Immediate(0xFF));
push(rax);
popfq();
}
pop(rax);
}