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 |