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:
parent
6cdd89b165
commit
0f20431c36
@ -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));
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user