| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 3690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3701 | 3701 |
| 3702 __ movsd(xmm_scratch, Operand::StaticVariable(one_half)); | 3702 __ movsd(xmm_scratch, Operand::StaticVariable(one_half)); |
| 3703 __ ucomisd(xmm_scratch, input_reg); | 3703 __ ucomisd(xmm_scratch, input_reg); |
| 3704 __ j(above, &below_one_half, Label::kNear); | 3704 __ j(above, &below_one_half, Label::kNear); |
| 3705 | 3705 |
| 3706 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). | 3706 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). |
| 3707 __ addsd(xmm_scratch, input_reg); | 3707 __ addsd(xmm_scratch, input_reg); |
| 3708 __ cvttsd2si(output_reg, Operand(xmm_scratch)); | 3708 __ cvttsd2si(output_reg, Operand(xmm_scratch)); |
| 3709 // Overflow is signalled with minint. | 3709 // Overflow is signalled with minint. |
| 3710 __ cmp(output_reg, 0x1); | 3710 __ cmp(output_reg, 0x1); |
| 3711 __ RecordComment("D2I conversion overflow"); | 3711 DeoptimizeIf(overflow, instr, "conversion overflow"); |
| 3712 DeoptimizeIf(overflow, instr); | |
| 3713 __ jmp(&done, dist); | 3712 __ jmp(&done, dist); |
| 3714 | 3713 |
| 3715 __ bind(&below_one_half); | 3714 __ bind(&below_one_half); |
| 3716 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); | 3715 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); |
| 3717 __ ucomisd(xmm_scratch, input_reg); | 3716 __ ucomisd(xmm_scratch, input_reg); |
| 3718 __ j(below_equal, &round_to_zero, Label::kNear); | 3717 __ j(below_equal, &round_to_zero, Label::kNear); |
| 3719 | 3718 |
| 3720 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 3719 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then |
| 3721 // compare and compensate. | 3720 // compare and compensate. |
| 3722 __ movaps(input_temp, input_reg); // Do not alter input_reg. | 3721 __ movaps(input_temp, input_reg); // Do not alter input_reg. |
| 3723 __ subsd(input_temp, xmm_scratch); | 3722 __ subsd(input_temp, xmm_scratch); |
| 3724 __ cvttsd2si(output_reg, Operand(input_temp)); | 3723 __ cvttsd2si(output_reg, Operand(input_temp)); |
| 3725 // Catch minint due to overflow, and to prevent overflow when compensating. | 3724 // Catch minint due to overflow, and to prevent overflow when compensating. |
| 3726 __ cmp(output_reg, 0x1); | 3725 __ cmp(output_reg, 0x1); |
| 3727 __ RecordComment("D2I conversion overflow"); | 3726 DeoptimizeIf(overflow, instr, "conversion overflow"); |
| 3728 DeoptimizeIf(overflow, instr); | |
| 3729 | 3727 |
| 3730 __ Cvtsi2sd(xmm_scratch, output_reg); | 3728 __ Cvtsi2sd(xmm_scratch, output_reg); |
| 3731 __ ucomisd(xmm_scratch, input_temp); | 3729 __ ucomisd(xmm_scratch, input_temp); |
| 3732 __ j(equal, &done, dist); | 3730 __ j(equal, &done, dist); |
| 3733 __ sub(output_reg, Immediate(1)); | 3731 __ sub(output_reg, Immediate(1)); |
| 3734 // No overflow because we already ruled out minint. | 3732 // No overflow because we already ruled out minint. |
| 3735 __ jmp(&done, dist); | 3733 __ jmp(&done, dist); |
| 3736 | 3734 |
| 3737 __ bind(&round_to_zero); | 3735 __ bind(&round_to_zero); |
| 3738 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if | 3736 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if |
| 3739 // we can ignore the difference between a result of -0 and +0. | 3737 // we can ignore the difference between a result of -0 and +0. |
| 3740 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3738 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3741 // If the sign is positive, we return +0. | 3739 // If the sign is positive, we return +0. |
| 3742 __ movmskpd(output_reg, input_reg); | 3740 __ movmskpd(output_reg, input_reg); |
| 3743 __ test(output_reg, Immediate(1)); | 3741 __ test(output_reg, Immediate(1)); |
| 3744 __ RecordComment("Minus zero"); | 3742 DeoptimizeIf(not_zero, instr, "minus zero"); |
| 3745 DeoptimizeIf(not_zero, instr); | |
| 3746 } | 3743 } |
| 3747 __ Move(output_reg, Immediate(0)); | 3744 __ Move(output_reg, Immediate(0)); |
| 3748 __ bind(&done); | 3745 __ bind(&done); |
| 3749 } | 3746 } |
| 3750 | 3747 |
| 3751 | 3748 |
| 3752 void LCodeGen::DoMathFround(LMathFround* instr) { | 3749 void LCodeGen::DoMathFround(LMathFround* instr) { |
| 3753 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3750 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3754 XMMRegister output_reg = ToDoubleRegister(instr->result()); | 3751 XMMRegister output_reg = ToDoubleRegister(instr->result()); |
| 3755 __ cvtsd2ss(output_reg, input_reg); | 3752 __ cvtsd2ss(output_reg, input_reg); |
| (...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4755 __ jmp(done); | 4752 __ jmp(done); |
| 4756 | 4753 |
| 4757 __ bind(&check_bools); | 4754 __ bind(&check_bools); |
| 4758 __ cmp(input_reg, factory()->true_value()); | 4755 __ cmp(input_reg, factory()->true_value()); |
| 4759 __ j(not_equal, &check_false, Label::kNear); | 4756 __ j(not_equal, &check_false, Label::kNear); |
| 4760 __ Move(input_reg, Immediate(1)); | 4757 __ Move(input_reg, Immediate(1)); |
| 4761 __ jmp(done); | 4758 __ jmp(done); |
| 4762 | 4759 |
| 4763 __ bind(&check_false); | 4760 __ bind(&check_false); |
| 4764 __ cmp(input_reg, factory()->false_value()); | 4761 __ cmp(input_reg, factory()->false_value()); |
| 4765 __ RecordComment("Deferred TaggedToI: cannot truncate"); | 4762 DeoptimizeIf(not_equal, instr, "cannot truncate"); |
| 4766 DeoptimizeIf(not_equal, instr); | |
| 4767 __ Move(input_reg, Immediate(0)); | 4763 __ Move(input_reg, Immediate(0)); |
| 4768 } else { | 4764 } else { |
| 4769 XMMRegister scratch = ToDoubleRegister(instr->temp()); | 4765 XMMRegister scratch = ToDoubleRegister(instr->temp()); |
| 4770 DCHECK(!scratch.is(xmm0)); | 4766 DCHECK(!scratch.is(xmm0)); |
| 4771 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 4767 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 4772 isolate()->factory()->heap_number_map()); | 4768 isolate()->factory()->heap_number_map()); |
| 4773 __ RecordComment("Deferred TaggedToI: not a heap number"); | 4769 DeoptimizeIf(not_equal, instr, "not a heap number"); |
| 4774 DeoptimizeIf(not_equal, instr); | |
| 4775 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 4770 __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 4776 __ cvttsd2si(input_reg, Operand(xmm0)); | 4771 __ cvttsd2si(input_reg, Operand(xmm0)); |
| 4777 __ Cvtsi2sd(scratch, Operand(input_reg)); | 4772 __ Cvtsi2sd(scratch, Operand(input_reg)); |
| 4778 __ ucomisd(xmm0, scratch); | 4773 __ ucomisd(xmm0, scratch); |
| 4779 __ RecordComment("Deferred TaggedToI: lost precision"); | 4774 DeoptimizeIf(not_equal, instr, "lost precision"); |
| 4780 DeoptimizeIf(not_equal, instr); | 4775 DeoptimizeIf(parity_even, instr, "NaN"); |
| 4781 __ RecordComment("Deferred TaggedToI: NaN"); | |
| 4782 DeoptimizeIf(parity_even, instr); | |
| 4783 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { | 4776 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { |
| 4784 __ test(input_reg, Operand(input_reg)); | 4777 __ test(input_reg, Operand(input_reg)); |
| 4785 __ j(not_zero, done); | 4778 __ j(not_zero, done); |
| 4786 __ movmskpd(input_reg, xmm0); | 4779 __ movmskpd(input_reg, xmm0); |
| 4787 __ and_(input_reg, 1); | 4780 __ and_(input_reg, 1); |
| 4788 __ RecordComment("Deferred TaggedToI: minus zero"); | 4781 DeoptimizeIf(not_zero, instr, "minus zero"); |
| 4789 DeoptimizeIf(not_zero, instr); | |
| 4790 } | 4782 } |
| 4791 } | 4783 } |
| 4792 } | 4784 } |
| 4793 | 4785 |
| 4794 | 4786 |
| 4795 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 4787 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
| 4796 class DeferredTaggedToI FINAL : public LDeferredCode { | 4788 class DeferredTaggedToI FINAL : public LDeferredCode { |
| 4797 public: | 4789 public: |
| 4798 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 4790 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
| 4799 : LDeferredCode(codegen), instr_(instr) { } | 4791 : LDeferredCode(codegen), instr_(instr) { } |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5704 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5696 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 5705 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5697 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 5706 } | 5698 } |
| 5707 | 5699 |
| 5708 | 5700 |
| 5709 #undef __ | 5701 #undef __ |
| 5710 | 5702 |
| 5711 } } // namespace v8::internal | 5703 } } // namespace v8::internal |
| 5712 | 5704 |
| 5713 #endif // V8_TARGET_ARCH_IA32 | 5705 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |