X64: Minor change of control flow in inline transcendental cache.
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 4 May 2010 12:05:55 +0000 (12:05 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 4 May 2010 12:05:55 +0000 (12:05 +0000)
Move NaN-handling away from main code path.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4577 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/x64/codegen-x64.cc
src/x64/codegen-x64.h

index 2ae30ac..c8a9198 100644 (file)
@@ -43,8 +43,6 @@ namespace internal {
 
 #define __ ACCESS_MASM(masm_)
 
-static int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000);
-
 // -------------------------------------------------------------------------
 // Platform-specific DeferredCode functions.
 
@@ -7725,8 +7723,9 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
 
   __ 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 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   __ 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 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
 }
 
 
-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 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   __ 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 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
     __ 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);
@@ -7821,9 +7819,6 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   // 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_) {
     case TranscendentalCache::SIN:
@@ -11379,6 +11374,7 @@ ModuloFunction CreateModuloFunction() {
   __ 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));
index c85d6a1..5d9861b 100644 (file)
@@ -686,7 +686,7 @@ class TranscendentalCacheStub: public CodeStub {
   Major MajorKey() { return TranscendentalCache; }
   int MinorKey() { return type_; }
   Runtime::FunctionId RuntimeFunction();
-  void GenerateOperation(MacroAssembler* masm);
+  void GenerateOperation(MacroAssembler* masm, Label* on_nan_result);
 };