Implement Math.tan in generated code.
Review URL: http://codereview.chromium.org/8700004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10067 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ebccde15bc
commit
dcc05b9fca
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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_);}
|
||||
|
@ -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()));
|
||||
|
@ -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);
|
||||
|
@ -924,6 +924,7 @@ class Assembler : public AssemblerBase {
|
||||
void fchs();
|
||||
void fcos();
|
||||
void fsin();
|
||||
void fptan();
|
||||
void fyl2x();
|
||||
|
||||
void fadd(int i);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
|
@ -1275,6 +1275,7 @@ class Assembler : public AssemblerBase {
|
||||
|
||||
void fsin();
|
||||
void fcos();
|
||||
void fptan();
|
||||
void fyl2x();
|
||||
|
||||
void frndint();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user