Revision: 6083
Author: [email protected]
Date: Mon Dec 20 05:52:14 2010
Log: Add untagged double versions of Math.sin and Math.cos. Merge classes TranscendentalCacheStub and TranscendentalCacheSSE2Stub.
Review URL: http://codereview.chromium.org/5996002
http://code.google.com/p/v8/source/detail?r=6083

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc
 /branches/bleeding_edge/src/ia32/code-stubs-ia32.h
 /branches/bleeding_edge/src/ia32/codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Dec 15 04:32:19 2010
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Mon Dec 20 05:52:14 2010
@@ -1375,6 +1375,12 @@
     case kMathLog:
       Abort("MathLog LUnaryMathOperation not implemented");
       return NULL;
+    case kMathCos:
+      Abort("MathCos LUnaryMathOperation not implemented");
+      return NULL;
+    case kMathSin:
+      Abort("MathSin LUnaryMathOperation not implemented");
+      return NULL;
     default:
       UNREACHABLE();
       return NULL;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Dec 15 04:32:19 2010 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Mon Dec 20 05:52:14 2010
@@ -1547,7 +1547,7 @@


 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
-  Abort("LUnaryMathOperation unimplemented.");
+  Abort("DoMathAbs unimplemented.");
 }


@@ -1562,9 +1562,6 @@


 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
-  ASSERT(instr->op() == kMathFloor ||
-         instr->op() == kMathAbs);
-
   switch (instr->op()) {
     case kMathAbs:
       DoMathAbs(instr);
@@ -1576,6 +1573,7 @@
       DoMathSqrt(instr);
       break;
     default:
+      Abort("Unimplemented type of LUnaryMathOperation.");
       UNREACHABLE();
   }
 }
=======================================
--- /branches/bleeding_edge/src/heap.h  Tue Dec 14 05:21:29 2010
+++ /branches/bleeding_edge/src/heap.h  Mon Dec 20 05:52:14 2010
@@ -1968,6 +1968,8 @@
 class TranscendentalCache {
  public:
   enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches};
+  static const int kTranscendentalTypeBits = 3;
+  STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);

   explicit TranscendentalCache(Type t);

=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Dec 17 05:44:19 2010 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Mon Dec 20 05:52:14 2010
@@ -1389,6 +1389,8 @@
       case kMathSqrt:
       case kMathPowHalf:
       case kMathLog:
+      case kMathSin:
+      case kMathCos:
         set_representation(Representation::Double());
         break;
       default:
@@ -1411,6 +1413,8 @@
       case kMathSqrt:
       case kMathPowHalf:
       case kMathLog:
+      case kMathSin:
+      case kMathCos:
         return Representation::Double();
         break;
       case kMathAbs:
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Mon Dec 20 05:18:47 2010
+++ /branches/bleeding_edge/src/hydrogen.cc     Mon Dec 20 05:52:14 2010
@@ -4097,6 +4097,8 @@
     case kMathAbs:
     case kMathSqrt:
     case kMathLog:
+    case kMathSin:
+    case kMathCos:
       if (argument_count == 2) {
         HValue* argument = Pop();
         Drop(1);  // Receiver.
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Thu Dec 16 00:58:42 2010 +++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.cc Mon Dec 20 05:52:14 2010
@@ -2472,41 +2472,66 @@


 void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
-  // Input on stack:
-  // esp[4]: argument (should be number).
-  // esp[0]: return address.
-  // Test that eax is a number.
+  // TAGGED case:
+  //   Input:
+  //     esp[4]: tagged number input argument (should be number).
+  //     esp[0]: return address.
+  //   Output:
+  //     eax: tagged double result.
+  // UNTAGGED case:
+  //   Input::
+  //     esp[0]: return address.
+  //     xmm1: untagged double input argument
+  //   Output:
+  //     xmm1: untagged double result.
+
   Label runtime_call;
   Label runtime_call_clear_stack;
-  NearLabel input_not_smi;
-  NearLabel loaded;
-  __ mov(eax, Operand(esp, kPointerSize));
-  __ test(eax, Immediate(kSmiTagMask));
-  __ j(not_zero, &input_not_smi);
-  // Input is a smi. Untag and load it onto the FPU stack.
-  // Then load the low and high words of the double into ebx, edx.
-  STATIC_ASSERT(kSmiTagSize == 1);
-  __ sar(eax, 1);
-  __ sub(Operand(esp), Immediate(2 * kPointerSize));
-  __ mov(Operand(esp, 0), eax);
-  __ fild_s(Operand(esp, 0));
-  __ fst_d(Operand(esp, 0));
-  __ pop(edx);
-  __ pop(ebx);
-  __ jmp(&loaded);
-  __ bind(&input_not_smi);
-  // Check if input is a HeapNumber.
-  __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
-  __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
-  __ j(not_equal, &runtime_call);
-  // Input is a HeapNumber. Push it on the FPU stack and load its
-  // low and high words into ebx, edx.
-  __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
-  __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
-  __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
-
-  __ bind(&loaded);
-  // ST[0] == double value
+  Label skip_cache;
+  Label call_runtime;
+  const bool tagged = (argument_type_ == TAGGED);
+  if (tagged) {
+    // Test that eax is a number.
+    NearLabel input_not_smi;
+    NearLabel loaded;
+    __ mov(eax, Operand(esp, kPointerSize));
+    __ test(eax, Immediate(kSmiTagMask));
+    __ j(not_zero, &input_not_smi);
+    // Input is a smi. Untag and load it onto the FPU stack.
+    // Then load the low and high words of the double into ebx, edx.
+    STATIC_ASSERT(kSmiTagSize == 1);
+    __ sar(eax, 1);
+    __ sub(Operand(esp), Immediate(2 * kPointerSize));
+    __ mov(Operand(esp, 0), eax);
+    __ fild_s(Operand(esp, 0));
+    __ fst_d(Operand(esp, 0));
+    __ pop(edx);
+    __ pop(ebx);
+    __ jmp(&loaded);
+    __ bind(&input_not_smi);
+    // Check if input is a HeapNumber.
+    __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
+    __ cmp(Operand(ebx), Immediate(Factory::heap_number_map()));
+    __ j(not_equal, &runtime_call);
+    // Input is a HeapNumber. Push it on the FPU stack and load its
+    // low and high words into ebx, edx.
+    __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
+    __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
+    __ mov(ebx, FieldOperand(eax, HeapNumber::kMantissaOffset));
+
+    __ bind(&loaded);
+  } else {  // UNTAGGED.
+    if (CpuFeatures::IsSupported(SSE4_1)) {
+      CpuFeatures::Scope sse4_scope(SSE4_1);
+      __ pextrd(Operand(edx), xmm1, 0x1);  // copy xmm1[63..32] to edx.
+    } else {
+      __ pshufd(xmm0, xmm1, 0x1);
+      __ movd(Operand(edx), xmm0);
+    }
+    __ movd(Operand(ebx), xmm1);
+  }
+
+  // ST[0] or xmm1  == double value
   // ebx = low 32 bits of double value
   // edx = high 32 bits of double value
   // Compute hash (the shifts are arithmetic):
@@ -2522,7 +2547,7 @@
   ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
   __ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));

-  // ST[0] == double value.
+  // ST[0] or xmm1 == double value.
   // ebx = low 32 bits of double value.
   // edx = high 32 bits of double value.
   // ecx = TranscendentalCache::hash(double value).
@@ -2559,31 +2584,72 @@
   __ j(not_equal, &cache_miss);
   // Cache hit!
   __ mov(eax, Operand(ecx, 2 * kIntSize));
-  __ fstp(0);
-  __ ret(kPointerSize);
+  if (tagged) {
+    __ fstp(0);
+    __ ret(kPointerSize);
+  } else {  // UNTAGGED.
+    __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+    __ Ret();
+  }

   __ bind(&cache_miss);
   // Update cache with new value.
   // We are short on registers, so use no_reg as scratch.
   // This gives slightly larger code.
-  __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
+  if (tagged) {
+    __ AllocateHeapNumber(eax, edi, no_reg, &runtime_call_clear_stack);
+  } else {  // UNTAGGED.
+    __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
+    __ sub(Operand(esp), Immediate(kDoubleSize));
+    __ movdbl(Operand(esp, 0), xmm1);
+    __ fld_d(Operand(esp, 0));
+    __ add(Operand(esp), Immediate(kDoubleSize));
+  }
   GenerateOperation(masm);
   __ mov(Operand(ecx, 0), ebx);
   __ mov(Operand(ecx, kIntSize), edx);
   __ mov(Operand(ecx, 2 * kIntSize), eax);
   __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
-  __ ret(kPointerSize);
-
-  __ bind(&runtime_call_clear_stack);
-  __ fstp(0);
-  __ bind(&runtime_call);
-  __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+  if (tagged) {
+    __ ret(kPointerSize);
+  } else {  // UNTAGGED.
+    __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+    __ Ret();
+
+    // Skip cache and return answer directly, only in untagged case.
+    __ bind(&skip_cache);
+    __ sub(Operand(esp), Immediate(kDoubleSize));
+    __ movdbl(Operand(esp, 0), xmm1);
+    __ fld_d(Operand(esp, 0));
+    GenerateOperation(masm);
+    __ fstp_d(Operand(esp, 0));
+    __ movdbl(xmm1, Operand(esp, 0));
+    __ add(Operand(esp), Immediate(kDoubleSize));
+    __ Ret();
+  }
+
+  // Call runtime, doing whatever allocation and cleanup is necessary.
+  if (tagged) {
+    __ bind(&runtime_call_clear_stack);
+    __ fstp(0);
+    __ bind(&runtime_call);
+ __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1);
+  } else {  // UNTAGGED.
+    __ bind(&call_runtime);
+    __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
+    __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
+    __ EnterInternalFrame();
+    __ push(eax);
+    __ CallRuntime(RuntimeFunction(), 1);
+    __ LeaveInternalFrame();
+    __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
+    __ Ret();
+  }
 }


 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
   switch (type_) {
-    // Add more cases when necessary.
     case TranscendentalCache::SIN: return Runtime::kMath_sin;
     case TranscendentalCache::COS: return Runtime::kMath_cos;
     case TranscendentalCache::LOG: return Runtime::kMath_log;
@@ -2596,14 +2662,14 @@

 void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   // Only free register is edi.
-  // Input value is on FP stack, and also in ebx/edx.  Address of result
-  // (a newly allocated HeapNumber) is in eax.
-  NearLabel done;
+  // Input value is on FP stack, and also in ebx/edx.
+  // Input value is possibly in xmm1.
+  // Address of result (a newly allocated HeapNumber) may be in eax.
if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
     // Both fsin and fcos require arguments in the range +/-2^63 and
     // return NaN for infinities and NaN. They can share all code except
     // the actual fsin/fcos operation.
-    NearLabel in_range;
+    NearLabel in_range, done;
     // If argument is outside the range -2^63..2^63, fsin/cos doesn't
     // work. We must reduce it to the appropriate range.
     __ mov(edi, edx);
@@ -2681,145 +2747,6 @@
     __ fyl2x();
   }
 }
-
-
-void TranscendentalCacheSSE2Stub::Generate(MacroAssembler* masm) {
-  // Input on stack:
-  // esp[0]: return address.
-  // Input in registers:
-  // xmm1:   untagged double input argument.
-  // Output:
-  // xmm1:   untagged double result.
-  Label skip_cache;
-  Label call_runtime;
-
-  // Input is an untagged double in xmm1.
-  // Compute hash (the shifts are arithmetic):
- // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
-  if (CpuFeatures::IsSupported(SSE4_1)) {
-    CpuFeatures::Scope sse4_scope(SSE4_1);
-    __ pextrd(Operand(edx), xmm1, 0x1);  // copy xmm1[63..32] to edx.
-  } else {
-    __ pshufd(xmm0, xmm1, 0x1);
-    __ movd(Operand(edx), xmm0);
-  }
-  __ movd(Operand(ebx), xmm1);
-
-  // xmm1 = double value
-  // ebx = low 32 bits of double value
-  // edx = high 32 bits of double value
-  // Compute hash (the shifts are arithmetic):
- // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1);
-  __ mov(ecx, ebx);
-  __ xor_(ecx, Operand(edx));
-  __ mov(eax, ecx);
-  __ sar(eax, 16);
-  __ xor_(ecx, Operand(eax));
-  __ mov(eax, ecx);
-  __ sar(eax, 8);
-  __ xor_(ecx, Operand(eax));
-  ASSERT(IsPowerOf2(TranscendentalCache::kCacheSize));
-  __ and_(Operand(ecx), Immediate(TranscendentalCache::kCacheSize - 1));
-
-  // xmm1 = double value.
-  // ebx = low 32 bits of double value.
-  // edx = high 32 bits of double value.
-  // ecx = TranscendentalCache::hash(double value).
-  __ mov(eax,
- Immediate(ExternalReference::transcendental_cache_array_address()));
-  // Eax points to cache array.
- __ mov(eax, Operand(eax, type_ * sizeof(TranscendentalCache::caches_[0])));
-  // Eax points to the cache for the type type_.
-  // If NULL, the cache hasn't been initialized yet, so go through runtime.
-  __ test(eax, Operand(eax));
-  __ j(zero, &call_runtime);
-#ifdef DEBUG
-  // Check that the layout of cache elements match expectations.
-  { TranscendentalCache::Element test_elem[2];
-    char* elem_start = reinterpret_cast<char*>(&test_elem[0]);
-    char* elem2_start = reinterpret_cast<char*>(&test_elem[1]);
-    char* elem_in0  = reinterpret_cast<char*>(&(test_elem[0].in[0]));
-    char* elem_in1  = reinterpret_cast<char*>(&(test_elem[0].in[1]));
-    char* elem_out = reinterpret_cast<char*>(&(test_elem[0].output));
- CHECK_EQ(12, elem2_start - elem_start); // Two uint_32's and a pointer.
-    CHECK_EQ(0, elem_in0 - elem_start);
-    CHECK_EQ(kIntSize, elem_in1 - elem_start);
-    CHECK_EQ(2 * kIntSize, elem_out - elem_start);
-  }
-#endif
-  // Find the address of the ecx'th entry in the cache, i.e., &eax[ecx*12].
-  __ lea(ecx, Operand(ecx, ecx, times_2, 0));
-  __ lea(ecx, Operand(eax, ecx, times_4, 0));
-  // Check if cache matches: Double value is stored in uint32_t[2] array.
-  NearLabel cache_miss;
-  __ cmp(ebx, Operand(ecx, 0));
-  __ j(not_equal, &cache_miss);
-  __ cmp(edx, Operand(ecx, kIntSize));
-  __ j(not_equal, &cache_miss);
-  // Cache hit!
-  __ mov(eax, Operand(ecx, 2 * kIntSize));
-  __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-  __ Ret();
-
-  __ bind(&cache_miss);
-  // Update cache with new value.
-  // We are short on registers, so use no_reg as scratch.
-  // This gives slightly larger code.
-  __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
-  __ sub(Operand(esp), Immediate(kDoubleSize));
-  __ movdbl(Operand(esp, 0), xmm1);
-  __ fld_d(Operand(esp, 0));
-  __ add(Operand(esp), Immediate(kDoubleSize));
-  GenerateOperation(masm);
-  __ mov(Operand(ecx, 0), ebx);
-  __ mov(Operand(ecx, kIntSize), edx);
-  __ mov(Operand(ecx, 2 * kIntSize), eax);
-  __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
-  __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-  __ Ret();
-
-  __ bind(&skip_cache);
-  __ sub(Operand(esp), Immediate(kDoubleSize));
-  __ movdbl(Operand(esp, 0), xmm1);
-  __ fld_d(Operand(esp, 0));
-  GenerateOperation(masm);
-  __ fstp_d(Operand(esp, 0));
-  __ movdbl(xmm1, Operand(esp, 0));
-  __ add(Operand(esp), Immediate(kDoubleSize));
-  __ Ret();
-
-  __ bind(&call_runtime);
-  __ AllocateHeapNumber(eax, edi, no_reg, &skip_cache);
-  __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm1);
-  __ EnterInternalFrame();
-  __ push(eax);
-  __ CallRuntime(RuntimeFunction(), 1);
-  __ LeaveInternalFrame();
-  __ movdbl(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
-  __ Ret();
-}
-
-
-Runtime::FunctionId TranscendentalCacheSSE2Stub::RuntimeFunction() {
-  switch (type_) {
-    // Add more cases when necessary.
-    case TranscendentalCache::LOG: return Runtime::kMath_log;
-    default:
-      UNIMPLEMENTED();
-      return Runtime::kAbort;
-  }
-}
-
-
-void TranscendentalCacheSSE2Stub::GenerateOperation(MacroAssembler* masm) {
-  // Only free register is edi.
-  // Input value is on FP stack and in xmm1.
-
-  ASSERT(type_ == TranscendentalCache::LOG);
-  __ fldln2();
-  __ fxch();
-  __ fyl2x();
-}


// Get the integer part of a heap number. Surprisingly, all this bit twiddling
=======================================
--- /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Wed Dec 15 05:56:41 2010 +++ /branches/bleeding_edge/src/ia32/code-stubs-ia32.h Mon Dec 20 05:52:14 2010
@@ -40,32 +40,21 @@
 // TranscendentalCache runtime function.
 class TranscendentalCacheStub: public CodeStub {
  public:
-  explicit TranscendentalCacheStub(TranscendentalCache::Type type)
-      : type_(type) {}
-  void Generate(MacroAssembler* masm);
- private:
-  TranscendentalCache::Type type_;
-
-  Major MajorKey() { return TranscendentalCache; }
-  int MinorKey() { return type_; }
-  Runtime::FunctionId RuntimeFunction();
-  void GenerateOperation(MacroAssembler* masm);
-};
-
-
-// Check the transcendental cache, or generate the result, using SSE2.
-// The argument and result will be in xmm1.
-// Only supports TranscendentalCache::LOG at this point.
-class TranscendentalCacheSSE2Stub: public CodeStub {
- public:
-  explicit TranscendentalCacheSSE2Stub(TranscendentalCache::Type type)
-      : type_(type) {}
+  enum ArgumentType {
+    TAGGED = 0,
+    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
+  };
+
+  explicit TranscendentalCacheStub(TranscendentalCache::Type type,
+                                   ArgumentType argument_type)
+      : type_(type), argument_type_(argument_type) {}
   void Generate(MacroAssembler* masm);
  private:
   TranscendentalCache::Type type_;
-
-  Major MajorKey() { return TranscendentalCacheSSE2; }
-  int MinorKey() { return type_; }
+  ArgumentType argument_type_;
+
+  Major MajorKey() { return TranscendentalCache; }
+  int MinorKey() { return type_ | argument_type_; }
   Runtime::FunctionId RuntimeFunction();
   void GenerateOperation(MacroAssembler* masm);
 };
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu Dec 16 00:58:42 2010 +++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Dec 20 05:52:14 2010
@@ -7912,7 +7912,8 @@
 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
   Load(args->at(0));
-  TranscendentalCacheStub stub(TranscendentalCache::SIN);
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
+                               TranscendentalCacheStub::TAGGED);
   Result result = frame_->CallStub(&stub, 1);
   frame_->Push(&result);
 }
@@ -7921,7 +7922,8 @@
 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
   Load(args->at(0));
-  TranscendentalCacheStub stub(TranscendentalCache::COS);
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   Result result = frame_->CallStub(&stub, 1);
   frame_->Push(&result);
 }
@@ -7930,7 +7932,8 @@
 void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
   ASSERT_EQ(args->length(), 1);
   Load(args->at(0));
-  TranscendentalCacheStub stub(TranscendentalCache::LOG);
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
   Result result = frame_->CallStub(&stub, 1);
   frame_->Push(&result);
 }
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Thu Dec 16 00:58:42 2010 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Dec 20 05:52:14 2010
@@ -3067,7 +3067,8 @@

 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::SIN);
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
+                               TranscendentalCacheStub::TAGGED);
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
   __ CallStub(&stub);
@@ -3077,7 +3078,8 @@

 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::COS);
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::TAGGED);
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
   __ CallStub(&stub);
@@ -3087,7 +3089,8 @@

 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
   // Load the argument on the stack and call the stub.
-  TranscendentalCacheStub stub(TranscendentalCache::LOG);
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::TAGGED);
   ASSERT(args->length() == 1);
   VisitForStackValue(args->at(0));
   __ CallStub(&stub);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Dec 16 00:58:42 2010 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Mon Dec 20 05:52:14 2010
@@ -686,7 +686,8 @@
       break;
     }
     case CodeStub::TranscendentalCache: {
-      TranscendentalCacheStub stub(instr->transcendental_type());
+      TranscendentalCacheStub stub(instr->transcendental_type(),
+                                   TranscendentalCacheStub::TAGGED);
       CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
       break;
     }
@@ -2314,9 +2315,26 @@

 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
   ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
-  TranscendentalCacheSSE2Stub stub(TranscendentalCache::LOG);
+  TranscendentalCacheStub stub(TranscendentalCache::LOG,
+                               TranscendentalCacheStub::UNTAGGED);
   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 }
+
+
+void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
+  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+  TranscendentalCacheStub stub(TranscendentalCache::COS,
+                               TranscendentalCacheStub::UNTAGGED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoMathSin(LUnaryMathOperation* instr) {
+  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+  TranscendentalCacheStub stub(TranscendentalCache::SIN,
+                               TranscendentalCacheStub::UNTAGGED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}


 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
@@ -2336,6 +2354,12 @@
     case kMathPowHalf:
       DoMathPowHalf(instr);
       break;
+    case kMathCos:
+      DoMathCos(instr);
+      break;
+    case kMathSin:
+      DoMathSin(instr);
+      break;
     case kMathLog:
       DoMathLog(instr);
       break;
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Wed Dec 15 04:32:19 2010 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.h Mon Dec 20 05:52:14 2010
@@ -177,6 +177,8 @@
   void DoMathSqrt(LUnaryMathOperation* instr);
   void DoMathPowHalf(LUnaryMathOperation* instr);
   void DoMathLog(LUnaryMathOperation* instr);
+  void DoMathCos(LUnaryMathOperation* instr);
+  void DoMathSin(LUnaryMathOperation* instr);

   // Support for recording safepoint and position information.
   void RecordSafepoint(LPointerMap* pointers, int deoptimization_index);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Dec 16 08:56:45 2010 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Mon Dec 20 05:52:14 2010
@@ -1361,7 +1361,7 @@

LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
   BuiltinFunctionId op = instr->op();
-  if (op == kMathLog) {
+  if (op == kMathLog || op == kMathSin || op == kMathCos) {
     LOperand* input = UseFixedDouble(instr->value(), xmm1);
     LInstruction* result = new LUnaryMathOperation(input);
     return MarkAsCall(DefineFixedDouble(result, xmm1), instr);

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

Reply via email to