Commit 827575b0 authored by ager@chromium.org's avatar ager@chromium.org

Optimize sine and cosine by checking up front if the fsin or fcos

operation can throw an exception.

Review URL: http://codereview.chromium.org/504073

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3506 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9c627d6b
...@@ -5390,9 +5390,17 @@ void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { ...@@ -5390,9 +5390,17 @@ void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) {
number.ToRegister(); number.ToRegister();
frame_->Spill(number.reg()); frame_->Spill(number.reg());
FloatingPointHelper::LoadFloatOperand(masm_, number.reg()); FloatingPointHelper::LoadFloatOperand(masm_, number.reg());
// Check whether the exponent is so big that performing a sine or
// cosine operation could result in inaccurate results or an
// exception. In that case call the runtime routine.
__ and_(number.reg(), HeapNumber::kExponentMask);
__ cmp(Operand(number.reg()), Immediate(kTwoToThePowerOf63Exponent));
call_runtime.Branch(greater_equal, not_taken);
number.Unuse(); number.Unuse();
// Perform the operation on the number. // Perform the operation on the number. This will succeed since we
// already checked that it is in range.
switch (op) { switch (op) {
case SIN: case SIN:
__ fsin(); __ fsin();
...@@ -5402,14 +5410,6 @@ void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) { ...@@ -5402,14 +5410,6 @@ void CodeGenerator::GenerateFastMathOp(MathOp op, ZoneList<Expression*>* args) {
break; break;
} }
// Go slow case if argument to operation is out of range.
Result eax_reg = allocator_->Allocate(eax);
ASSERT(eax_reg.is_valid());
__ fnstsw_ax();
__ sahf();
eax_reg.Unuse();
call_runtime.Branch(parity_even, not_taken);
// Allocate heap number for result if possible. // Allocate heap number for result if possible.
Result scratch1 = allocator()->Allocate(); Result scratch1 = allocator()->Allocate();
Result scratch2 = allocator()->Allocate(); Result scratch2 = allocator()->Allocate();
...@@ -7465,9 +7465,8 @@ void IntegerConvert(MacroAssembler* masm, ...@@ -7465,9 +7465,8 @@ void IntegerConvert(MacroAssembler* masm,
if (use_sse3) { if (use_sse3) {
CpuFeatures::Scope scope(SSE3); CpuFeatures::Scope scope(SSE3);
// Check whether the exponent is too big for a 64 bit signed integer. // Check whether the exponent is too big for a 64 bit signed integer.
const uint32_t too_big_exponent = __ cmp(Operand(scratch2),
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; Immediate(CodeGenerator::kTwoToThePowerOf63Exponent));
__ cmp(Operand(scratch2), Immediate(too_big_exponent));
__ j(greater_equal, conversion_failure); __ j(greater_equal, conversion_failure);
// Load x87 register with heap number. // Load x87 register with heap number.
__ fld_d(FieldOperand(source, HeapNumber::kValueOffset)); __ fld_d(FieldOperand(source, HeapNumber::kValueOffset));
......
...@@ -326,6 +326,9 @@ class CodeGenerator: public AstVisitor { ...@@ -326,6 +326,9 @@ class CodeGenerator: public AstVisitor {
bool in_spilled_code() const { return in_spilled_code_; } bool in_spilled_code() const { return in_spilled_code_; }
void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; } void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
static const uint32_t kTwoToThePowerOf63Exponent =
(HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
private: private:
// Construction/Destruction // Construction/Destruction
CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval); CodeGenerator(int buffer_size, Handle<Script> script, bool is_eval);
......
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