Implement Math.tan in generated code.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Nov 2011 13:15:31 +0000 (13:15 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 25 Nov 2011 13:15:31 +0000 (13:15 +0000)
Review URL: http://codereview.chromium.org/8700004

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

21 files changed:
src/arm/code-stubs-arm.cc
src/arm/full-codegen-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/lithium-codegen-arm.h
src/assembler.cc
src/assembler.h
src/hydrogen.cc
src/ia32/assembler-ia32.cc
src/ia32/assembler-ia32.h
src/ia32/code-stubs-ia32.cc
src/ia32/full-codegen-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-codegen-ia32.h
src/math.js
src/runtime.h
src/x64/assembler-x64.cc
src/x64/assembler-x64.h
src/x64/code-stubs-x64.cc
src/x64/full-codegen-x64.cc
src/x64/lithium-codegen-x64.cc
src/x64/lithium-codegen-x64.h

index 43ed1aed7eccd64a27dcadfa4e060a20d10c6b15..d10266445190a96a149330090901f5410f459295 100644 (file)
@@ -3272,6 +3272,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
     __ cmp(r3, r5);
     __ b(ne, &calculate);
     // Cache hit. Load result, cleanup and return.
+    Counters* counters = masm->isolate()->counters();
+    __ IncrementCounter(counters->transcendental_cache_hit(), 1);
     if (tagged) {
       // Pop input value from stack and load result into r0.
       __ pop();
@@ -3284,6 +3286,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   }  // if (CpuFeatures::IsSupported(VFP3))
 
   __ bind(&calculate);
+  __ IncrementCounter(counters->transcendental_cache_miss(), 1);
   if (tagged) {
     __ bind(&invalid_cache);
     ExternalReference runtime_function =
@@ -3371,6 +3374,10 @@ void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
       __ CallCFunction(ExternalReference::math_cos_double_function(isolate),
           0, 1);
       break;
+    case TranscendentalCache::TAN:
+      __ CallCFunction(ExternalReference::math_tan_double_function(isolate),
+          0, 1);
+      break;
     case TranscendentalCache::LOG:
       __ CallCFunction(ExternalReference::math_log_double_function(isolate),
           0, 1);
@@ -3388,6 +3395,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
     // Add more cases when necessary.
     case TranscendentalCache::SIN: return Runtime::kMath_sin;
     case TranscendentalCache::COS: return Runtime::kMath_cos;
+    case TranscendentalCache::TAN: return Runtime::kMath_tan;
     case TranscendentalCache::LOG: return Runtime::kMath_log;
     default:
       UNIMPLEMENTED();
index 8e9c189f4db816aa3fe71e1865836aeebfd21e46..8c3e825d191e29a47c5de391fa4a8217202dbd67 100644 (file)
@@ -3131,6 +3131,18 @@ void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
 }
 
 
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(r0);
+}
+
+
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
   TranscendentalCacheStub stub(TranscendentalCache::LOG,
index 86cded109de5a8177b7317020183a5aadcb1bc73..93a4a060d8e2b7b81c8e51df78f4644ef86bc771 100644 (file)
@@ -3170,6 +3170,14 @@ void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
 }
 
 
+void LCodeGen::DoMathTan(LUnaryMathOperation* instr) {
+  ASSERT(ToDoubleRegister(instr->result()).is(d2));
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::UNTAGGED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
   ASSERT(ToDoubleRegister(instr->result()).is(d2));
   TranscendentalCacheStub stub(TranscendentalCache::COS,
@@ -3209,6 +3217,9 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
     case kMathSin:
       DoMathSin(instr);
       break;
+    case kMathTan:
+      DoMathTan(instr);
+      break;
     case kMathLog:
       DoMathLog(instr);
       break;
index df0bc85fc11c7d54cf56a03af7e1749585981d0b..363449a50916112fcf3067d7e59c0a8ab152aebc 100644 (file)
@@ -242,6 +242,7 @@ class LCodeGen BASE_EMBEDDED {
   void DoMathSqrt(LUnaryMathOperation* instr);
   void DoMathPowHalf(LUnaryMathOperation* instr);
   void DoMathLog(LUnaryMathOperation* instr);
+  void DoMathTan(LUnaryMathOperation* instr);
   void DoMathCos(LUnaryMathOperation* instr);
   void DoMathSin(LUnaryMathOperation* instr);
 
index 4dc2394b06076916baa012c4a77223d11e867e3b..bc05c01800dc51889ee58e31264d533045be84ff 100644 (file)
@@ -1051,6 +1051,11 @@ static double math_cos_double(double x) {
 }
 
 
+static double math_tan_double(double x) {
+  return tan(x);
+}
+
+
 static double math_log_double(double x) {
   return log(x);
 }
@@ -1072,6 +1077,14 @@ ExternalReference ExternalReference::math_cos_double_function(
 }
 
 
+ExternalReference ExternalReference::math_tan_double_function(
+    Isolate* isolate) {
+  return ExternalReference(Redirect(isolate,
+                                    FUNCTION_ADDR(math_tan_double),
+                                    BUILTIN_FP_CALL));
+}
+
+
 ExternalReference ExternalReference::math_log_double_function(
     Isolate* isolate) {
   return ExternalReference(Redirect(isolate,
index 5b7136375916137d09ec1404e56c476f4f2ea762..c4bb2125740aad7f6c6bc7a27d6d80c56fa76544 100644 (file)
@@ -652,6 +652,7 @@ class ExternalReference BASE_EMBEDDED {
 
   static ExternalReference math_sin_double_function(Isolate* isolate);
   static ExternalReference math_cos_double_function(Isolate* isolate);
+  static ExternalReference math_tan_double_function(Isolate* isolate);
   static ExternalReference math_log_double_function(Isolate* isolate);
 
   Address address() const {return reinterpret_cast<Address>(address_);}
index d200a1e88b8a51959641e3a616a79f80e8c6c3c4..5c0703bc37434ea91b475990e4f09349a596b2c2 100644 (file)
@@ -6649,6 +6649,18 @@ void HGraphBuilder::GenerateMathCos(CallRuntime* call) {
 }
 
 
+void HGraphBuilder::GenerateMathTan(CallRuntime* call) {
+  ASSERT_EQ(1, call->arguments()->length());
+  CHECK_ALIVE(VisitArgumentList(call->arguments()));
+  HValue* context = environment()->LookupContext();
+  HCallStub* result =
+      new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1);
+  result->set_transcendental_type(TranscendentalCache::TAN);
+  Drop(1);
+  return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
 void HGraphBuilder::GenerateMathLog(CallRuntime* call) {
   ASSERT_EQ(1, call->arguments()->length());
   CHECK_ALIVE(VisitArgumentList(call->arguments()));
index c6030f9aaf64eb4b4f656d2e30f0f925f6c9ce45..fb625fb24d7248762dff832f177110f9d2c4d57b 100644 (file)
@@ -1626,6 +1626,13 @@ void Assembler::fsin() {
 }
 
 
+void Assembler::fptan() {
+  EnsureSpace ensure_space(this);
+  EMIT(0xD9);
+  EMIT(0xF2);
+}
+
+
 void Assembler::fyl2x() {
   EnsureSpace ensure_space(this);
   EMIT(0xD9);
index fbd04bb7128a9f3689d186b6a6a314140d692e5d..d798f818ada454741fd2ba4fc69cca345500adbe 100644 (file)
@@ -924,6 +924,7 @@ class Assembler : public AssemblerBase {
   void fchs();
   void fcos();
   void fsin();
+  void fptan();
   void fyl2x();
 
   void fadd(int i);
index 02910ad29743900831e574f7f21b5912eacd6ef7..179bf0daae1b40057bb6895b7552058781783f73 100644 (file)
@@ -2485,6 +2485,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   __ cmp(edx, Operand(ecx, kIntSize));
   __ j(not_equal, &cache_miss, Label::kNear);
   // Cache hit!
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->transcendental_cache_hit(), 1);
   __ mov(eax, Operand(ecx, 2 * kIntSize));
   if (tagged) {
     __ fstp(0);
@@ -2495,6 +2497,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   }
 
   __ bind(&cache_miss);
+  __ IncrementCounter(counters->transcendental_cache_miss(), 1);
   // Update cache with new value.
   // We are short on registers, so use no_reg as scratch.
   // This gives slightly larger code.
@@ -2566,6 +2569,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
   switch (type_) {
     case TranscendentalCache::SIN: return Runtime::kMath_sin;
     case TranscendentalCache::COS: return Runtime::kMath_cos;
+    case TranscendentalCache::TAN: return Runtime::kMath_tan;
     case TranscendentalCache::LOG: return Runtime::kMath_log;
     default:
       UNIMPLEMENTED();
@@ -2579,7 +2583,9 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   // 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) {
+  if (type_ == TranscendentalCache::SIN ||
+      type_ == TranscendentalCache::COS ||
+      type_ == TranscendentalCache::TAN) {
     // 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.
@@ -2650,6 +2656,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
       case TranscendentalCache::COS:
         __ fcos();
         break;
+      case TranscendentalCache::TAN:
+        // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the
+        // FP register stack.
+        __ fptan();
+        __ fstp(0);  // Pop FP register stack.
+        break;
       default:
         UNREACHABLE();
     }
index 9575c5a83dcd3e80ce59b1b6b43eb845bf0ddd11..0702b3472a92970e662e85ab5c57c18c5fe6419f 100644 (file)
@@ -3082,6 +3082,18 @@ void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
 }
 
 
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(eax);
+}
+
+
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
   TranscendentalCacheStub stub(TranscendentalCache::LOG,
index 093dbce589a33118fac1beac02ba4b9fba291ea3..95ad5e0665db740cd1260e55a5d5d1312c199ae4 100644 (file)
@@ -3034,6 +3034,14 @@ void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
 }
 
 
+void LCodeGen::DoMathTan(LUnaryMathOperation* instr) {
+  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::UNTAGGED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
   ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
   TranscendentalCacheStub stub(TranscendentalCache::COS,
@@ -3073,6 +3081,9 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
     case kMathSin:
       DoMathSin(instr);
       break;
+    case kMathTan:
+      DoMathTan(instr);
+      break;
     case kMathLog:
       DoMathLog(instr);
       break;
index 6f1f47711283ffb87089f3604e6e3738a2330dfe..9d1a4f78d3312ff03511e07e838725b3536258fc 100644 (file)
@@ -241,6 +241,7 @@ class LCodeGen BASE_EMBEDDED {
   void DoMathSqrt(LUnaryMathOperation* instr);
   void DoMathPowHalf(LUnaryMathOperation* instr);
   void DoMathLog(LUnaryMathOperation* instr);
+  void DoMathTan(LUnaryMathOperation* instr);
   void DoMathCos(LUnaryMathOperation* instr);
   void DoMathSin(LUnaryMathOperation* instr);
 
index ac26b8a657a3683decca86b4ebad0a810a3efea6..18492aa050c0245cd078202cbb01780d189702d6 100644 (file)
@@ -189,7 +189,7 @@ function MathSqrt(x) {
 // ECMA 262 - 15.8.2.18
 function MathTan(x) {
   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
-  return %Math_tan(x);
+  return %_MathTan(x);
 }
 
 
index d6de195c5261c5c29cb84b6f2898093e1d171f65..b13662df0effe0c5f799a3a691ace2590fd91515 100644 (file)
@@ -505,6 +505,7 @@ namespace internal {
   F(MathPow, 2, 1)                                                           \
   F(MathSin, 1, 1)                                                           \
   F(MathCos, 1, 1)                                                           \
+  F(MathTan, 1, 1)                                                           \
   F(MathSqrt, 1, 1)                                                          \
   F(MathLog, 1, 1)                                                           \
   F(IsRegExpEquivalent, 2, 1)                                                \
index 1c4980ebc18c0bd54950ac1afbedd74dd6eaa68d..d578bf9c57b7fd7e84927b1f760f0f5f41a49e6c 100644 (file)
@@ -2299,6 +2299,13 @@ void Assembler::fsin() {
 }
 
 
+void Assembler::fptan() {
+  EnsureSpace ensure_space(this);
+  emit(0xD9);
+  emit(0xF2);
+}
+
+
 void Assembler::fyl2x() {
   EnsureSpace ensure_space(this);
   emit(0xD9);
index 4dff7bdc4fd3f679089f418453ae6b6592ae5a51..0189c08507337f32982d331524c400403121ed91 100644 (file)
@@ -1275,6 +1275,7 @@ class Assembler : public AssemblerBase {
 
   void fsin();
   void fcos();
+  void fptan();
   void fyl2x();
 
   void frndint();
index 693ff0728d184c970a33ad8317a6fa0626e68607..2281c4c8dbfcf0615187cefa1d71042d4f8cc124 100644 (file)
@@ -1607,6 +1607,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   __ cmpq(rbx, Operand(rcx, 0));
   __ j(not_equal, &cache_miss, Label::kNear);
   // Cache hit!
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->transcendental_cache_hit(), 1);
   __ movq(rax, Operand(rcx, 2 * kIntSize));
   if (tagged) {
     __ fstp(0);  // Clear FPU stack.
@@ -1617,6 +1619,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
   }
 
   __ bind(&cache_miss);
+  __ IncrementCounter(counters->transcendental_cache_miss(), 1);
   // Update cache with new value.
   if (tagged) {
   __ AllocateHeapNumber(rax, rdi, &runtime_call_clear_stack);
@@ -1683,6 +1686,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
     // Add more cases when necessary.
     case TranscendentalCache::SIN: return Runtime::kMath_sin;
     case TranscendentalCache::COS: return Runtime::kMath_cos;
+    case TranscendentalCache::TAN: return Runtime::kMath_tan;
     case TranscendentalCache::LOG: return Runtime::kMath_log;
     default:
       UNIMPLEMENTED();
@@ -1698,7 +1702,9 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
   // rcx: Pointer to cache entry. Must be preserved.
   // st(0): Input double
   Label done;
-  if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
+  if (type_ == TranscendentalCache::SIN ||
+      type_ == TranscendentalCache::COS ||
+      type_ == TranscendentalCache::TAN) {
     // 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.
@@ -1768,6 +1774,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
       case TranscendentalCache::COS:
         __ fcos();
         break;
+      case TranscendentalCache::TAN:
+        // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the
+        // FP register stack.
+        __ fptan();
+        __ fstp(0);  // Pop FP register stack.
+        break;
       default:
         UNREACHABLE();
     }
index f8e5deaf719c93b73d895f2d533bc417e9d81438..c2bca84bc7c75ba0b93624c3dbf7dc27c8513c38 100644 (file)
@@ -3015,6 +3015,18 @@ void FullCodeGenerator::EmitMathCos(CallRuntime* expr) {
 }
 
 
+void FullCodeGenerator::EmitMathTan(CallRuntime* expr) {
+  // Load the argument on the stack and call the stub.
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::TAGGED);
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+  VisitForStackValue(args->at(0));
+  __ CallStub(&stub);
+  context()->Plug(rax);
+}
+
+
 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
   // Load the argument on the stack and call the stub.
   TranscendentalCacheStub stub(TranscendentalCache::LOG,
index 9f566cf797689fd8c6761d7abce1e7cbbf4749b0..38ee36106ba1d746f7e753ce2d9f0c66a3e1c70c 100644 (file)
@@ -2919,6 +2919,14 @@ void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
 }
 
 
+void LCodeGen::DoMathTan(LUnaryMathOperation* instr) {
+  ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
+  TranscendentalCacheStub stub(TranscendentalCache::TAN,
+                               TranscendentalCacheStub::UNTAGGED);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) {
   ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
   TranscendentalCacheStub stub(TranscendentalCache::COS,
@@ -2958,6 +2966,9 @@ void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
     case kMathSin:
       DoMathSin(instr);
       break;
+    case kMathTan:
+      DoMathTan(instr);
+      break;
     case kMathLog:
       DoMathLog(instr);
       break;
index afa6c216bfb1a92f4133b87759bc6d077106051e..868f75e90e09bfcc633027b71f1da6470683287f 100644 (file)
@@ -231,6 +231,7 @@ class LCodeGen BASE_EMBEDDED {
   void DoMathSqrt(LUnaryMathOperation* instr);
   void DoMathPowHalf(LUnaryMathOperation* instr);
   void DoMathLog(LUnaryMathOperation* instr);
+  void DoMathTan(LUnaryMathOperation* instr);
   void DoMathCos(LUnaryMathOperation* instr);
   void DoMathSin(LUnaryMathOperation* instr);