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() { ...@@ -2290,6 +2290,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
// Add more cases when necessary. // Add more cases when necessary.
case TranscendentalCache::SIN: return Runtime::kMath_sin; case TranscendentalCache::SIN: return Runtime::kMath_sin;
case TranscendentalCache::COS: return Runtime::kMath_cos; case TranscendentalCache::COS: return Runtime::kMath_cos;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
return Runtime::kAbort; return Runtime::kAbort;
......
...@@ -5750,6 +5750,20 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { ...@@ -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) { void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
ASSERT(args->length() == 2); ASSERT(args->length() == 2);
......
...@@ -516,6 +516,7 @@ class CodeGenerator: public AstVisitor { ...@@ -516,6 +516,7 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(ZoneList<Expression*>* args); void GenerateMathSqrt(ZoneList<Expression*>* args);
void GenerateMathLog(ZoneList<Expression*>* args);
void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args); void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
......
...@@ -2617,6 +2617,15 @@ void FullCodeGenerator::EmitMathSqrt(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) { void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) {
ASSERT(args->length() >= 2); ASSERT(args->length() >= 2);
......
...@@ -1772,6 +1772,14 @@ void Assembler::fldz() { ...@@ -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) { void Assembler::fld_s(const Operand& adr) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -1902,6 +1910,14 @@ void Assembler::fsin() { ...@@ -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) { void Assembler::fadd(int i) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
......
...@@ -720,6 +720,7 @@ class Assembler : public Malloced { ...@@ -720,6 +720,7 @@ class Assembler : public Malloced {
void fld1(); void fld1();
void fldz(); void fldz();
void fldpi(); void fldpi();
void fldln2();
void fld_s(const Operand& adr); void fld_s(const Operand& adr);
void fld_d(const Operand& adr); void fld_d(const Operand& adr);
...@@ -744,6 +745,7 @@ class Assembler : public Malloced { ...@@ -744,6 +745,7 @@ class Assembler : public Malloced {
void fchs(); void fchs();
void fcos(); void fcos();
void fsin(); void fsin();
void fyl2x();
void fadd(int i); void fadd(int i);
void fsub(int i); void fsub(int i);
......
...@@ -1330,6 +1330,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { ...@@ -1330,6 +1330,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
// Add more cases when necessary. // Add more cases when necessary.
case TranscendentalCache::SIN: return Runtime::kMath_sin; case TranscendentalCache::SIN: return Runtime::kMath_sin;
case TranscendentalCache::COS: return Runtime::kMath_cos; case TranscendentalCache::COS: return Runtime::kMath_cos;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
return Runtime::kAbort; return Runtime::kAbort;
...@@ -1339,11 +1340,10 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { ...@@ -1339,11 +1340,10 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
// Only free register is edi. // 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; NearLabel done;
ASSERT(type_ == TranscendentalCache::SIN || if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
type_ == TranscendentalCache::COS);
// More transcendental types can be added later.
// Both fsin and fcos require arguments in the range +/-2^63 and // Both fsin and fcos require arguments in the range +/-2^63 and
// return NaN for infinities and NaN. They can share all code except // return NaN for infinities and NaN. They can share all code except
// the actual fsin/fcos operation. // the actual fsin/fcos operation.
...@@ -1418,6 +1418,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { ...@@ -1418,6 +1418,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) {
UNREACHABLE(); UNREACHABLE();
} }
__ bind(&done); __ bind(&done);
} else {
ASSERT(type_ == TranscendentalCache::LOG);
__ fldln2();
__ fxch();
__ fyl2x();
}
} }
......
...@@ -7995,6 +7995,15 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { ...@@ -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 // Generates the Math.sqrt method. Please note - this function assumes that
// the callsite has executed ToNumber on the argument. // the callsite has executed ToNumber on the argument.
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
......
...@@ -705,8 +705,9 @@ class CodeGenerator: public AstVisitor { ...@@ -705,8 +705,9 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(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 GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args); void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args);
......
...@@ -733,7 +733,9 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, ...@@ -733,7 +733,9 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
case 0xE4: mnem = "ftst"; break; case 0xE4: mnem = "ftst"; break;
case 0xE8: mnem = "fld1"; break; case 0xE8: mnem = "fld1"; break;
case 0xEB: mnem = "fldpi"; break; case 0xEB: mnem = "fldpi"; break;
case 0xED: mnem = "fldln2"; break;
case 0xEE: mnem = "fldz"; break; case 0xEE: mnem = "fldz"; break;
case 0xF1: mnem = "fyl2x"; break;
case 0xF5: mnem = "fprem1"; break; case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break; case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break; case 0xF8: mnem = "fprem"; break;
......
...@@ -2917,6 +2917,16 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { ...@@ -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) { void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the runtime function. // Load the argument on the stack and call the runtime function.
ASSERT(args->length() == 1); ASSERT(args->length() == 1);
......
...@@ -113,7 +113,7 @@ function MathFloor(x) { ...@@ -113,7 +113,7 @@ function MathFloor(x) {
// ECMA 262 - 15.8.2.10 // ECMA 262 - 15.8.2.10
function MathLog(x) { function MathLog(x) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
return %Math_log(x); return %_MathLog(x);
} }
// ECMA 262 - 15.8.2.11 // ECMA 262 - 15.8.2.11
......
...@@ -417,6 +417,7 @@ namespace internal { ...@@ -417,6 +417,7 @@ namespace internal {
F(MathSin, 1, 1) \ F(MathSin, 1, 1) \
F(MathCos, 1, 1) \ F(MathCos, 1, 1) \
F(MathSqrt, 1, 1) \ F(MathSqrt, 1, 1) \
F(MathLog, 1, 1) \
F(IsRegExpEquivalent, 2, 1) \ F(IsRegExpEquivalent, 2, 1) \
F(HasCachedArrayIndex, 1, 1) \ F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1) \ F(GetCachedArrayIndex, 1, 1) \
......
...@@ -2217,6 +2217,14 @@ void Assembler::fldpi() { ...@@ -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) { void Assembler::fld_s(const Operand& adr) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
...@@ -2358,6 +2366,14 @@ void Assembler::fsin() { ...@@ -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) { void Assembler::fadd(int i) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
last_pc_ = pc_; last_pc_ = pc_;
......
...@@ -1046,6 +1046,7 @@ class Assembler : public Malloced { ...@@ -1046,6 +1046,7 @@ class Assembler : public Malloced {
void fld1(); void fld1();
void fldz(); void fldz();
void fldpi(); void fldpi();
void fldln2();
void fld_s(const Operand& adr); void fld_s(const Operand& adr);
void fld_d(const Operand& adr); void fld_d(const Operand& adr);
...@@ -1100,6 +1101,7 @@ class Assembler : public Malloced { ...@@ -1100,6 +1101,7 @@ class Assembler : public Malloced {
void fsin(); void fsin();
void fcos(); void fcos();
void fyl2x();
void frndint(); void frndint();
......
...@@ -1107,6 +1107,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { ...@@ -1107,6 +1107,7 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
// Add more cases when necessary. // Add more cases when necessary.
case TranscendentalCache::SIN: return Runtime::kMath_sin; case TranscendentalCache::SIN: return Runtime::kMath_sin;
case TranscendentalCache::COS: return Runtime::kMath_cos; case TranscendentalCache::COS: return Runtime::kMath_cos;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default: default:
UNIMPLEMENTED(); UNIMPLEMENTED();
return Runtime::kAbort; return Runtime::kAbort;
...@@ -1121,10 +1122,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm, ...@@ -1121,10 +1122,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
// rcx: Pointer to cache entry. Must be preserved. // rcx: Pointer to cache entry. Must be preserved.
// st(0): Input double // st(0): Input double
Label done; Label done;
ASSERT(type_ == TranscendentalCache::SIN || if (type_ == TranscendentalCache::SIN || type_ == TranscendentalCache::COS) {
type_ == TranscendentalCache::COS);
// More transcendental types can be added later.
// Both fsin and fcos require arguments in the range +/-2^63 and // Both fsin and fcos require arguments in the range +/-2^63 and
// return NaN for infinities and NaN. They can share all code except // return NaN for infinities and NaN. They can share all code except
// the actual fsin/fcos operation. // the actual fsin/fcos operation.
...@@ -1188,6 +1186,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm, ...@@ -1188,6 +1186,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm,
UNREACHABLE(); UNREACHABLE();
} }
__ bind(&done); __ bind(&done);
} else {
ASSERT(type_ == TranscendentalCache::LOG);
__ fldln2();
__ fxch();
__ fyl2x();
}
} }
......
...@@ -7111,6 +7111,15 @@ void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) { ...@@ -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 // Generates the Math.sqrt method. Please note - this function assumes that
// the callsite has executed ToNumber on the argument. // the callsite has executed ToNumber on the argument.
void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
......
...@@ -664,14 +664,16 @@ class CodeGenerator: public AstVisitor { ...@@ -664,14 +664,16 @@ class CodeGenerator: public AstVisitor {
void GenerateMathSin(ZoneList<Expression*>* args); void GenerateMathSin(ZoneList<Expression*>* args);
void GenerateMathCos(ZoneList<Expression*>* args); void GenerateMathCos(ZoneList<Expression*>* args);
void GenerateMathSqrt(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 GenerateIsRegExpEquivalent(ZoneList<Expression*>* args);
void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args); void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args);
void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args); void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args);
void GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args); void GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args);
// Simple condition analysis. // Simple condition analysis.
enum ConditionAnalysis { enum ConditionAnalysis {
ALWAYS_TRUE, ALWAYS_TRUE,
ALWAYS_FALSE, ALWAYS_FALSE,
......
...@@ -906,7 +906,9 @@ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode, ...@@ -906,7 +906,9 @@ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
case 0xE4: mnem = "ftst"; break; case 0xE4: mnem = "ftst"; break;
case 0xE8: mnem = "fld1"; break; case 0xE8: mnem = "fld1"; break;
case 0xEB: mnem = "fldpi"; break; case 0xEB: mnem = "fldpi"; break;
case 0xED: mnem = "fldln2"; break;
case 0xEE: mnem = "fldz"; break; case 0xEE: mnem = "fldz"; break;
case 0xF1: mnem = "fyl2x"; break;
case 0xF5: mnem = "fprem1"; break; case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break; case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break; case 0xF8: mnem = "fprem"; break;
......
...@@ -2623,6 +2623,16 @@ void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { ...@@ -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) { void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) {
// Load the argument on the stack and call the runtime function. // Load the argument on the stack and call the runtime function.
ASSERT(args->length() == 1); 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