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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 4711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4722 __ cmp(input_reg, factory()->true_value()); | 4722 __ cmp(input_reg, factory()->true_value()); |
4723 __ j(not_equal, &check_false, Label::kNear); | 4723 __ j(not_equal, &check_false, Label::kNear); |
4724 __ Move(input_reg, Immediate(1)); | 4724 __ Move(input_reg, Immediate(1)); |
4725 __ jmp(done); | 4725 __ jmp(done); |
4726 | 4726 |
4727 __ bind(&check_false); | 4727 __ bind(&check_false); |
4728 __ cmp(input_reg, factory()->false_value()); | 4728 __ cmp(input_reg, factory()->false_value()); |
4729 __ RecordComment("Deferred TaggedToI: cannot truncate"); | 4729 __ RecordComment("Deferred TaggedToI: cannot truncate"); |
4730 DeoptimizeIf(not_equal, instr->environment()); | 4730 DeoptimizeIf(not_equal, instr->environment()); |
4731 __ Move(input_reg, Immediate(0)); | 4731 __ Move(input_reg, Immediate(0)); |
| 4732 __ jmp(done); |
4732 } else { | 4733 } else { |
4733 Label bailout; | 4734 // TODO(olivf) Converting a number on the fpu is actually quite slow. We |
4734 __ TaggedToI(input_reg, input_reg, | 4735 // should first try a fast conversion and then bailout to this slow case. |
4735 instr->hydrogen()->GetMinusZeroMode(), &bailout); | 4736 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 4737 isolate()->factory()->heap_number_map()); |
| 4738 __ RecordComment("Deferred TaggedToI: not a heap number"); |
| 4739 DeoptimizeIf(not_equal, instr->environment()); |
| 4740 |
| 4741 __ sub(esp, Immediate(kPointerSize)); |
| 4742 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 4743 |
| 4744 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { |
| 4745 Label no_precision_lost, not_nan, zero_check; |
| 4746 __ fld(0); |
| 4747 |
| 4748 __ fist_s(MemOperand(esp, 0)); |
| 4749 __ fild_s(MemOperand(esp, 0)); |
| 4750 __ FCmp(); |
| 4751 __ pop(input_reg); |
| 4752 |
| 4753 __ j(equal, &no_precision_lost, Label::kNear); |
| 4754 __ fstp(0); |
| 4755 __ RecordComment("Deferred TaggedToI: lost precision"); |
| 4756 DeoptimizeIf(no_condition, instr->environment()); |
| 4757 __ bind(&no_precision_lost); |
| 4758 |
| 4759 __ j(parity_odd, ¬_nan); |
| 4760 __ fstp(0); |
| 4761 __ RecordComment("Deferred TaggedToI: NaN"); |
| 4762 DeoptimizeIf(no_condition, instr->environment()); |
| 4763 __ bind(¬_nan); |
| 4764 |
| 4765 __ test(input_reg, Operand(input_reg)); |
| 4766 __ j(zero, &zero_check, Label::kNear); |
| 4767 __ fstp(0); |
| 4768 __ jmp(done); |
| 4769 |
| 4770 __ bind(&zero_check); |
| 4771 // To check for minus zero, we load the value again as float, and check |
| 4772 // if that is still 0. |
| 4773 __ sub(esp, Immediate(kPointerSize)); |
| 4774 __ fstp_s(Operand(esp, 0)); |
| 4775 __ pop(input_reg); |
| 4776 __ test(input_reg, Operand(input_reg)); |
| 4777 __ RecordComment("Deferred TaggedToI: minus zero"); |
| 4778 DeoptimizeIf(not_zero, instr->environment()); |
| 4779 } else { |
| 4780 __ fist_s(MemOperand(esp, 0)); |
| 4781 __ fild_s(MemOperand(esp, 0)); |
| 4782 __ FCmp(); |
| 4783 __ pop(input_reg); |
| 4784 __ RecordComment("Deferred TaggedToI: lost precision"); |
| 4785 DeoptimizeIf(not_equal, instr->environment()); |
| 4786 __ RecordComment("Deferred TaggedToI: NaN"); |
| 4787 DeoptimizeIf(parity_even, instr->environment()); |
| 4788 } |
4736 __ jmp(done); | 4789 __ jmp(done); |
4737 __ bind(&bailout); | |
4738 DeoptimizeIf(no_condition, instr->environment()); | |
4739 } | 4790 } |
4740 } | 4791 } |
4741 | 4792 |
4742 | 4793 |
4743 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 4794 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
4744 class DeferredTaggedToI FINAL : public LDeferredCode { | 4795 class DeferredTaggedToI FINAL : public LDeferredCode { |
4745 public: | 4796 public: |
4746 DeferredTaggedToI(LCodeGen* codegen, | 4797 DeferredTaggedToI(LCodeGen* codegen, |
4747 LTaggedToI* instr, | 4798 LTaggedToI* instr, |
4748 const X87Stack& x87_stack) | 4799 const X87Stack& x87_stack) |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5729 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5780 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5730 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5781 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5731 } | 5782 } |
5732 | 5783 |
5733 | 5784 |
5734 #undef __ | 5785 #undef __ |
5735 | 5786 |
5736 } } // namespace v8::internal | 5787 } } // namespace v8::internal |
5737 | 5788 |
5738 #endif // V8_TARGET_ARCH_X87 | 5789 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |