Commit 66836efb authored by whesse@chromium.org's avatar whesse@chromium.org

Add generated code to calculate Math.log and to search Transcendental cache...

Add generated code to calculate Math.log and to search Transcendental cache for logs.  Implemented on all platforms.
Review URL: http://codereview.chromium.org/5437002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5912 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent be20c55b
......@@ -2290,6 +2290,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::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
return Runtime::kAbort;
......
......@@ -5750,6 +5750,20 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
if (CpuFeatures::IsSupported(VFP3)) {
TranscendentalCacheStub stub(TranscendentalCache::LOG);
frame_->SpillAllButCopyTOSToR0();
frame_->CallStub(&stub, 1);
} else {
frame_->CallRuntime(Runtime::kMath_log, 1);
}
frame_->EmitPush(r0);
}
void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
ASSERT(args->length() == 2);
......
......@@ -516,6 +516,7 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(ZoneList<Expression*>* args);
void GenerateMathLog(ZoneList<Expression*>* args);
void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
......
......@@ -2617,6 +2617,15 @@ void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
}
void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the runtime function.
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallRuntime(Runtime::kMath_log, 1);
context()->Plug(r0);
}
void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
ASSERT(args->length() >= 2);
......
......@@ -1772,6 +1772,14 @@ void Assembler::fldz() {
}
void Assembler::fldln2() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xED);
}
void Assembler::fld_s(const Operand& adr) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
......@@ -1902,6 +1910,14 @@ void Assembler::fsin() {
}
void Assembler::fyl2x() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xF1);
}
void Assembler::fadd(int i) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
......
......@@ -720,6 +720,7 @@ class Assembler : public Malloced {
void fld1();
void fldz();
void fldpi();
void fldln2();
void fld_s(const Operand& adr);
void fld_d(const Operand& adr);
......@@ -744,6 +745,7 @@ class Assembler : public Malloced {
void fchs();
void fcos();
void fsin();
void fyl2x();
void fadd(int i);
void fsub(int i);
......
......@@ -1330,6 +1330,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::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
return Runtime::kAbort;
......@@ -1339,11 +1340,10 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
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;
ASSERT(type_ == TranscendentalCache::SIN ||
type_ == TranscendentalCache::COS);
// More transcendental types can be added later.
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.
......@@ -1418,6 +1418,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
UNREACHABLE();
}
__ bind(&done);
} else {
ASSERT(type_ == TranscendentalCache::LOG);
__ fldln2();
__ fxch();
__ fyl2x();
}
}
......
......@@ -7995,6 +7995,15 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
TranscendentalCacheStub stub(TranscendentalCache::LOG);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
// Generates the Math.sqrt method. Please note - this function assumes that
// the callsite has executed ToNumber on the argument.
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
......
......@@ -705,8 +705,9 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(ZoneList<Expression*>* args);
void GenerateMathLog(ZoneList<Expression*>* args);
// Check whether two RegExps are equivalent
// Check whether two RegExps are equivalent.
void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args);
......
......@@ -733,7 +733,9 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
case 0xE4: mnem = "ftst"; break;
case 0xE8: mnem = "fld1"; break;
case 0xEB: mnem = "fldpi"; break;
case 0xED: mnem = "fldln2"; break;
case 0xEE: mnem = "fldz"; break;
case 0xF1: mnem = "fyl2x"; break;
case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break;
......
......@@ -2917,6 +2917,16 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
}
void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the stub.
TranscendentalCacheStub stub(TranscendentalCache::LOG);
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallStub(&stub);
context()->Plug(eax);
}
void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the runtime function.
ASSERT(args->length() == 1);
......
......@@ -113,7 +113,7 @@ function MathFloor(x) {
// ECMA 262 - 15.8.2.10
function MathLog(x) {
if (!IS_NUMBER(x)) x = ToNumber(x);
return %Math_log(x);
return %_MathLog(x);
}
// ECMA 262 - 15.8.2.11
......
......@@ -417,6 +417,7 @@ namespace internal {
F(MathSin, 1, 1) \
F(MathCos, 1, 1) \
F(MathSqrt, 1, 1) \
F(MathLog, 1, 1) \
F(IsRegExpEquivalent, 2, 1) \
F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1) \
......
......@@ -2217,6 +2217,14 @@ void Assembler::fldpi() {
}
void Assembler::fldln2() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0xD9);
emit(0xED);
}
void Assembler::fld_s(const Operand& adr) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
......@@ -2358,6 +2366,14 @@ void Assembler::fsin() {
}
void Assembler::fyl2x() {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
emit(0xD9);
emit(0xF1);
}
void Assembler::fadd(int i) {
EnsureSpace ensure_space(this);
last_pc_ = pc_;
......
......@@ -1046,6 +1046,7 @@ class Assembler : public Malloced {
void fld1();
void fldz();
void fldpi();
void fldln2();
void fld_s(const Operand& adr);
void fld_d(const Operand& adr);
......@@ -1100,6 +1101,7 @@ class Assembler : public Malloced {
void fsin();
void fcos();
void fyl2x();
void frndint();
......
......@@ -1107,6 +1107,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::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
return Runtime::kAbort;
......@@ -1121,10 +1122,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
// rcx: Pointer to cache entry. Must be preserved.
// st(0): Input double
Label done;
ASSERT(type_ == TranscendentalCache::SIN ||
type_ == TranscendentalCache::COS);
// More transcendental types can be added later.
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.
......@@ -1188,6 +1186,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
UNREACHABLE();
}
__ bind(&done);
} else {
ASSERT(type_ == TranscendentalCache::LOG);
__ fldln2();
__ fxch();
__ fyl2x();
}
}
......
......@@ -7111,6 +7111,15 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
}
void CodeGenerator::GenerateMathLog(ZoneList<Expression*>* args) {
ASSERT_EQ(args->length(), 1);
Load(args->at(0));
TranscendentalCacheStub stub(TranscendentalCache::LOG);
Result result = frame_->CallStub(&stub, 1);
frame_->Push(&result);
}
// Generates the Math.sqrt method. Please note - this function assumes that
// the callsite has executed ToNumber on the argument.
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
......
......@@ -664,14 +664,16 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(ZoneList<Expression*>* args);
void GenerateMathLog(ZoneList<Expression*>* args);
// Check whether two RegExps are equivalent.
void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args);
void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args);
void GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args);
// Simple condition analysis.
// Simple condition analysis.
enum ConditionAnalysis {
ALWAYS_TRUE,
ALWAYS_FALSE,
......
......@@ -906,7 +906,9 @@ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
case 0xE4: mnem = "ftst"; break;
case 0xE8: mnem = "fld1"; break;
case 0xEB: mnem = "fldpi"; break;
case 0xED: mnem = "fldln2"; break;
case 0xEE: mnem = "fldz"; break;
case 0xF1: mnem = "fyl2x"; break;
case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break;
......
......@@ -2623,6 +2623,16 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) {
}
void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the stub.
TranscendentalCacheStub stub(TranscendentalCache::LOG);
ASSERT(args->length() == 1);
VisitForStackValue(args->at(0));
__ CallStub(&stub);
context()->Plug(rax);
}
void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the runtime function.
ASSERT(args->length() == 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment