Revision: 4577
Author: [email protected]
Date: Tue May  4 05:05:55 2010
Log: X64: Minor change of control flow in inline transcendental cache.
Move NaN-handling away from main code path.

Review URL: http://codereview.chromium.org/1851002
http://code.google.com/p/v8/source/detail?r=4577

Modified:
 /branches/bleeding_edge/src/x64/codegen-x64.cc
 /branches/bleeding_edge/src/x64/codegen-x64.h

=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue May  4 04:17:45 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc      Tue May  4 05:05:55 2010
@@ -43,8 +43,6 @@

 #define __ ACCESS_MASM(masm_)

-static int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
-
// -------------------------------------------------------------------------
 // Platform-specific DeferredCode functions.

@@ -7725,8 +7723,9 @@

   __ bind(&cache_miss);
   // Update cache with new value.
+  Label nan_result;
+  GenerateOperation(masm, &nan_result);
   __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack);
-  GenerateOperation(masm);
   __ movq(Operand(rcx, 0), rbx);
   __ movq(Operand(rcx, 2 * kIntSize), rax);
   __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset));
@@ -7736,6 +7735,13 @@
   __ fstp(0);
   __ bind(&runtime_call);
   __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+
+  __ bind(&nan_result);
+  __ fstp(0);  // Remove argument from FPU stack.
+  __ LoadRoot(rax, Heap::kNanValueRootIndex);
+  __ movq(Operand(rcx, 0), rbx);
+  __ movq(Operand(rcx, 2 * kIntSize), rax);
+  __ ret(kPointerSize);
 }


@@ -7751,8 +7757,12 @@
 }


-void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
-  // Only free register is rdi.
+void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
+                                                Label* on_nan_result) {
+  // Registers:
+  // rbx: Bits of input double. Must be preserved.
+  // rcx: Pointer to cache entry. Must be preserved.
+  // st(0): Input double
   Label done;
   ASSERT(type_ == TranscendentalCache::SIN ||
          type_ == TranscendentalCache::COS);
@@ -7774,21 +7784,9 @@
   __ j(below, &in_range);
   // Check for infinity and NaN. Both return NaN for sin.
   __ cmpl(rdi, Immediate(0x7ff));
-  Label non_nan_result;
-  __ j(not_equal, &non_nan_result);
-  // Input is +/-Infinity or NaN. Result is NaN.
-  __ fstp(0);  // Clear fpu stack.
-  // NaN is represented by 0x7ff8000000000000.
-  __ movq(rdi, kNaNValue, RelocInfo::NONE);
-  __ push(rdi);
-  __ fld_d(Operand(rsp, 0));
-  __ addq(rsp, Immediate(kPointerSize));
-  __ jmp(&done);
-
-  __ bind(&non_nan_result);
+  __ j(equal, on_nan_result);

   // Use fpmod to restrict argument to the range +/-2*PI.
-  __ movq(rdi, rax);  // Save rax before using fnstsw_ax.
   __ fldpi();
   __ fadd(0);
   __ fld(1);
@@ -7798,7 +7796,7 @@
     __ fwait();
     __ fnstsw_ax();
     // Clear if Illegal Operand or Zero Division exceptions are set.
-    __ testl(rax, Immediate(5));
+    __ testl(rax, Immediate(5));  // #IO and #ZD flags of FPU status word.
     __ j(zero, &no_exceptions);
     __ fnclex();
     __ bind(&no_exceptions);
@@ -7820,9 +7818,6 @@
   __ fstp(2);
   // FPU Stack: input % 2*pi, 2*pi,
   __ fstp(0);
-  // FPU Stack: input % 2*pi
-  __ movq(rax, rdi);  // Restore rax (allocated HeapNumber pointer).
-
   // FPU Stack: input % 2*pi
   __ bind(&in_range);
   switch (type_) {
@@ -11379,6 +11374,7 @@
   __ testb(rax, Immediate(5));
   __ j(zero, &valid_result);
   __ fstp(0);  // Drop result in st(0).
+  int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
   __ movq(rcx, kNaNValue, RelocInfo::NONE);
   __ movq(Operand(rsp, kPointerSize), rcx);
   __ movsd(xmm0, Operand(rsp, kPointerSize));
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.h       Tue May  4 04:06:59 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.h       Tue May  4 05:05:55 2010
@@ -686,7 +686,7 @@
   Major MajorKey() { return TranscendentalCache; }
   int MinorKey() { return type_; }
   Runtime::FunctionId RuntimeFunction();
-  void GenerateOperation(MacroAssembler* masm);
+  void GenerateOperation(MacroAssembler* masm, Label* on_nan_result);
 };


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to