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