| Index: src/x87/lithium-codegen-x87.cc
|
| diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc
|
| index 0bd32fe1b1c67aa8a05daeee6777a3bdc3253ddc..30e1c03c4011529a0b03d9622f5c5c6530519e5a 100644
|
| --- a/src/x87/lithium-codegen-x87.cc
|
| +++ b/src/x87/lithium-codegen-x87.cc
|
| @@ -4730,12 +4730,61 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
|
| DeoptimizeIf(not_equal, instr->environment());
|
| __ Move(input_reg, Immediate(0));
|
| } else {
|
| - Label bailout;
|
| - __ TaggedToI(input_reg, input_reg,
|
| - instr->hydrogen()->GetMinusZeroMode(), &bailout);
|
| - __ jmp(done);
|
| - __ bind(&bailout);
|
| - DeoptimizeIf(no_condition, instr->environment());
|
| + // TODO(olivf) Converting a number on the fpu is actually quite slow. We
|
| + // should first try a fast conversion and then bailout to this slow case.
|
| + __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| + isolate()->factory()->heap_number_map());
|
| + __ RecordComment("Deferred TaggedToI: not a heap number");
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| +
|
| + __ sub(esp, Immediate(kPointerSize));
|
| + __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
|
| +
|
| + if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) {
|
| + Label no_precision_lost, not_nan, zero_check;
|
| + __ fld(0);
|
| +
|
| + __ fist_s(MemOperand(esp, 0));
|
| + __ fild_s(MemOperand(esp, 0));
|
| + __ FCmp();
|
| + __ pop(input_reg);
|
| +
|
| + __ j(equal, &no_precision_lost, Label::kNear);
|
| + __ fstp(0);
|
| + __ RecordComment("Deferred TaggedToI: lost precision");
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + __ bind(&no_precision_lost);
|
| +
|
| + __ j(parity_odd, ¬_nan);
|
| + __ fstp(0);
|
| + __ RecordComment("Deferred TaggedToI: NaN");
|
| + DeoptimizeIf(no_condition, instr->environment());
|
| + __ bind(¬_nan);
|
| +
|
| + __ test(input_reg, Operand(input_reg));
|
| + __ j(zero, &zero_check, Label::kNear);
|
| + __ fstp(0);
|
| + __ jmp(done);
|
| +
|
| + __ bind(&zero_check);
|
| + // To check for minus zero, we load the value again as float, and check
|
| + // if that is still 0.
|
| + __ sub(esp, Immediate(kPointerSize));
|
| + __ fstp_s(Operand(esp, 0));
|
| + __ pop(input_reg);
|
| + __ test(input_reg, Operand(input_reg));
|
| + __ RecordComment("Deferred TaggedToI: minus zero");
|
| + DeoptimizeIf(not_zero, instr->environment());
|
| + } else {
|
| + __ fist_s(MemOperand(esp, 0));
|
| + __ fild_s(MemOperand(esp, 0));
|
| + __ FCmp();
|
| + __ pop(input_reg);
|
| + __ RecordComment("Deferred TaggedToI: lost precision");
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + __ RecordComment("Deferred TaggedToI: NaN");
|
| + DeoptimizeIf(parity_even, instr->environment());
|
| + }
|
| }
|
| }
|
|
|
|
|