Push fix for 64-bit machines without the 'sahf' instruction to trunk.


git-svn-id: http://v8.googlecode.com/svn/trunk@2803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/version.cc b/src/version.cc
index d90b446..b640ea7 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     1
 #define MINOR_VERSION     3
 #define BUILD_NUMBER      8
-#define PATCH_LEVEL       1
+#define PATCH_LEVEL       2
 #define CANDIDATE_VERSION false
 
 // Define SONAME to have the SCons build the put a specific SONAME into the
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index a02557e..6304324 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -120,13 +120,23 @@
   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));
 
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 9d602b9..4d341c6 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -361,7 +361,12 @@
   // 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();
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index e59237b..c61cdc9 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -6377,7 +6377,7 @@
         // 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);
@@ -7559,18 +7559,29 @@
         __ 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.
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 157ec2e..0f79fba 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -584,8 +584,14 @@
   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);
 }