| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2617 // Subtracting from length accounts for one of them add one more. | 2617 // Subtracting from length accounts for one of them add one more. |
| 2618 if (instr->index()->IsRegister()) { | 2618 if (instr->index()->IsRegister()) { |
| 2619 __ subl(length, ToRegister(instr->index())); | 2619 __ subl(length, ToRegister(instr->index())); |
| 2620 } else { | 2620 } else { |
| 2621 __ subl(length, ToOperand(instr->index())); | 2621 __ subl(length, ToOperand(instr->index())); |
| 2622 } | 2622 } |
| 2623 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); | 2623 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
| 2624 } | 2624 } |
| 2625 | 2625 |
| 2626 | 2626 |
| 2627 template <class T> | |
| 2628 inline void LCodeGen::PrepareKeyForKeyedOp(T* hydrogen_instr, LOperand* key) { | |
| 2629 if (ArrayOpClobbersKey<T>(hydrogen_instr)) { | |
| 2630 // Even though the HLoad/StoreKeyed (in this case) instructions force | |
| 2631 // the input representation for the key to be an integer, the input | |
| 2632 // gets replaced during bound check elimination with the index argument | |
| 2633 // to the bounds check, which can be tagged, so that case must be | |
| 2634 // handled here, too. | |
| 2635 Register key_reg = ToRegister(key); | |
| 2636 if (hydrogen_instr->key()->representation().IsTagged()) { | |
| 2637 __ SmiToInteger64(key_reg, key_reg); | |
| 2638 } else if (hydrogen_instr->IsDehoisted()) { | |
| 2639 // Sign extend key because it could be a 32 bit negative value | |
| 2640 // and the dehoisted address computation happens in 64 bits | |
| 2641 __ movsxlq(key_reg, key_reg); | |
| 2642 } | |
| 2643 } | |
| 2644 } | |
| 2645 | |
| 2646 | |
| 2647 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2627 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2648 ElementsKind elements_kind = instr->elements_kind(); | 2628 ElementsKind elements_kind = instr->elements_kind(); |
| 2649 LOperand* key = instr->key(); | 2629 LOperand* key = instr->key(); |
| 2650 PrepareKeyForKeyedOp(instr->hydrogen(), key); | 2630 if (!key->IsConstantOperand()) { |
| 2631 Register key_reg = ToRegister(key); |
| 2632 // Even though the HLoad/StoreKeyed (in this case) instructions force |
| 2633 // the input representation for the key to be an integer, the input |
| 2634 // gets replaced during bound check elimination with the index argument |
| 2635 // to the bounds check, which can be tagged, so that case must be |
| 2636 // handled here, too. |
| 2637 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2638 __ SmiToInteger64(key_reg, key_reg); |
| 2639 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2640 // Sign extend key because it could be a 32 bit negative value |
| 2641 // and the dehoisted address computation happens in 64 bits |
| 2642 __ movsxlq(key_reg, key_reg); |
| 2643 } |
| 2644 } |
| 2651 Operand operand(BuildFastArrayOperand( | 2645 Operand operand(BuildFastArrayOperand( |
| 2652 instr->elements(), | 2646 instr->elements(), |
| 2653 key, | 2647 key, |
| 2654 elements_kind, | 2648 elements_kind, |
| 2655 0, | 2649 0, |
| 2656 instr->additional_index())); | 2650 instr->additional_index())); |
| 2657 | 2651 |
| 2658 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2652 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 2659 XMMRegister result(ToDoubleRegister(instr->result())); | 2653 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2660 __ movss(result, operand); | 2654 __ movss(result, operand); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2700 UNREACHABLE(); | 2694 UNREACHABLE(); |
| 2701 break; | 2695 break; |
| 2702 } | 2696 } |
| 2703 } | 2697 } |
| 2704 } | 2698 } |
| 2705 | 2699 |
| 2706 | 2700 |
| 2707 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 2701 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 2708 XMMRegister result(ToDoubleRegister(instr->result())); | 2702 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2709 LOperand* key = instr->key(); | 2703 LOperand* key = instr->key(); |
| 2710 PrepareKeyForKeyedOp<HLoadKeyed>(instr->hydrogen(), key); | 2704 if (!key->IsConstantOperand()) { |
| 2705 Register key_reg = ToRegister(key); |
| 2706 // Even though the HLoad/StoreKeyed instructions force the input |
| 2707 // representation for the key to be an integer, the input gets replaced |
| 2708 // during bound check elimination with the index argument to the bounds |
| 2709 // check, which can be tagged, so that case must be handled here, too. |
| 2710 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2711 __ SmiToInteger64(key_reg, key_reg); |
| 2712 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2713 // Sign extend key because it could be a 32 bit negative value |
| 2714 // and the dehoisted address computation happens in 64 bits |
| 2715 __ movsxlq(key_reg, key_reg); |
| 2716 } |
| 2717 } |
| 2718 |
| 2711 if (instr->hydrogen()->RequiresHoleCheck()) { | 2719 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2712 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 2720 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 2713 sizeof(kHoleNanLower32); | 2721 sizeof(kHoleNanLower32); |
| 2714 Operand hole_check_operand = BuildFastArrayOperand( | 2722 Operand hole_check_operand = BuildFastArrayOperand( |
| 2715 instr->elements(), | 2723 instr->elements(), |
| 2716 key, | 2724 key, |
| 2717 FAST_DOUBLE_ELEMENTS, | 2725 FAST_DOUBLE_ELEMENTS, |
| 2718 offset, | 2726 offset, |
| 2719 instr->additional_index()); | 2727 instr->additional_index()); |
| 2720 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 2728 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| 2721 DeoptimizeIf(equal, instr->environment()); | 2729 DeoptimizeIf(equal, instr->environment()); |
| 2722 } | 2730 } |
| 2723 | 2731 |
| 2724 Operand double_load_operand = BuildFastArrayOperand( | 2732 Operand double_load_operand = BuildFastArrayOperand( |
| 2725 instr->elements(), | 2733 instr->elements(), |
| 2726 key, | 2734 key, |
| 2727 FAST_DOUBLE_ELEMENTS, | 2735 FAST_DOUBLE_ELEMENTS, |
| 2728 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 2736 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 2729 instr->additional_index()); | 2737 instr->additional_index()); |
| 2730 __ movsd(result, double_load_operand); | 2738 __ movsd(result, double_load_operand); |
| 2731 } | 2739 } |
| 2732 | 2740 |
| 2733 | 2741 |
| 2734 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 2742 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 2735 Register result = ToRegister(instr->result()); | 2743 Register result = ToRegister(instr->result()); |
| 2736 LOperand* key = instr->key(); | 2744 LOperand* key = instr->key(); |
| 2737 PrepareKeyForKeyedOp<HLoadKeyed>(instr->hydrogen(), key); | 2745 if (!key->IsConstantOperand()) { |
| 2746 Register key_reg = ToRegister(key); |
| 2747 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 2748 // the input representation for the key to be an integer, the input |
| 2749 // gets replaced during bound check elimination with the index |
| 2750 // argument to the bounds check, which can be tagged, so that |
| 2751 // case must be handled here, too. |
| 2752 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2753 __ SmiToInteger64(key_reg, key_reg); |
| 2754 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2755 // Sign extend key because it could be a 32 bit negative value |
| 2756 // and the dehoisted address computation happens in 64 bits |
| 2757 __ movsxlq(key_reg, key_reg); |
| 2758 } |
| 2759 } |
| 2738 | 2760 |
| 2739 // Load the result. | 2761 // Load the result. |
| 2740 __ movq(result, | 2762 __ movq(result, |
| 2741 BuildFastArrayOperand(instr->elements(), | 2763 BuildFastArrayOperand(instr->elements(), |
| 2742 key, | 2764 key, |
| 2743 FAST_ELEMENTS, | 2765 FAST_ELEMENTS, |
| 2744 FixedArray::kHeaderSize - kHeapObjectTag, | 2766 FixedArray::kHeaderSize - kHeapObjectTag, |
| 2745 instr->additional_index())); | 2767 instr->additional_index())); |
| 2746 | 2768 |
| 2747 // Check for the hole value. | 2769 // Check for the hole value. |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3722 __ cmpq(length, ToRegister(instr->index())); | 3744 __ cmpq(length, ToRegister(instr->index())); |
| 3723 } | 3745 } |
| 3724 } | 3746 } |
| 3725 DeoptimizeIf(below_equal, instr->environment()); | 3747 DeoptimizeIf(below_equal, instr->environment()); |
| 3726 } | 3748 } |
| 3727 | 3749 |
| 3728 | 3750 |
| 3729 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 3751 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 3730 ElementsKind elements_kind = instr->elements_kind(); | 3752 ElementsKind elements_kind = instr->elements_kind(); |
| 3731 LOperand* key = instr->key(); | 3753 LOperand* key = instr->key(); |
| 3732 PrepareKeyForKeyedOp<HStoreKeyed>(instr->hydrogen(), key); | 3754 if (!key->IsConstantOperand()) { |
| 3755 Register key_reg = ToRegister(key); |
| 3756 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3757 // the input representation for the key to be an integer, the input |
| 3758 // gets replaced during bound check elimination with the index |
| 3759 // argument to the bounds check, which can be tagged, so that case |
| 3760 // must be handled here, too. |
| 3761 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3762 __ SmiToInteger64(key_reg, key_reg); |
| 3763 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3764 // Sign extend key because it could be a 32 bit negative value |
| 3765 // and the dehoisted address computation happens in 64 bits |
| 3766 __ movsxlq(key_reg, key_reg); |
| 3767 } |
| 3768 } |
| 3733 Operand operand(BuildFastArrayOperand( | 3769 Operand operand(BuildFastArrayOperand( |
| 3734 instr->elements(), | 3770 instr->elements(), |
| 3735 key, | 3771 key, |
| 3736 elements_kind, | 3772 elements_kind, |
| 3737 0, | 3773 0, |
| 3738 instr->additional_index())); | 3774 instr->additional_index())); |
| 3739 | 3775 |
| 3740 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3776 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3741 XMMRegister value(ToDoubleRegister(instr->value())); | 3777 XMMRegister value(ToDoubleRegister(instr->value())); |
| 3742 __ cvtsd2ss(value, value); | 3778 __ cvtsd2ss(value, value); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3772 UNREACHABLE(); | 3808 UNREACHABLE(); |
| 3773 break; | 3809 break; |
| 3774 } | 3810 } |
| 3775 } | 3811 } |
| 3776 } | 3812 } |
| 3777 | 3813 |
| 3778 | 3814 |
| 3779 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 3815 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 3780 XMMRegister value = ToDoubleRegister(instr->value()); | 3816 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3781 LOperand* key = instr->key(); | 3817 LOperand* key = instr->key(); |
| 3782 PrepareKeyForKeyedOp<HStoreKeyed>(instr->hydrogen(), key); | 3818 if (!key->IsConstantOperand()) { |
| 3819 Register key_reg = ToRegister(key); |
| 3820 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3821 // the input representation for the key to be an integer, the |
| 3822 // input gets replaced during bound check elimination with the index |
| 3823 // argument to the bounds check, which can be tagged, so that case |
| 3824 // must be handled here, too. |
| 3825 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3826 __ SmiToInteger64(key_reg, key_reg); |
| 3827 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3828 // Sign extend key because it could be a 32 bit negative value |
| 3829 // and the dehoisted address computation happens in 64 bits |
| 3830 __ movsxlq(key_reg, key_reg); |
| 3831 } |
| 3832 } |
| 3833 |
| 3783 if (instr->NeedsCanonicalization()) { | 3834 if (instr->NeedsCanonicalization()) { |
| 3784 Label have_value; | 3835 Label have_value; |
| 3785 | 3836 |
| 3786 __ ucomisd(value, value); | 3837 __ ucomisd(value, value); |
| 3787 __ j(parity_odd, &have_value); // NaN. | 3838 __ j(parity_odd, &have_value); // NaN. |
| 3788 | 3839 |
| 3789 __ Set(kScratchRegister, BitCast<uint64_t>( | 3840 __ Set(kScratchRegister, BitCast<uint64_t>( |
| 3790 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 3841 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
| 3791 __ movq(value, kScratchRegister); | 3842 __ movq(value, kScratchRegister); |
| 3792 | 3843 |
| 3793 __ bind(&have_value); | 3844 __ bind(&have_value); |
| 3794 } | 3845 } |
| 3795 | 3846 |
| 3796 Operand double_store_operand = BuildFastArrayOperand( | 3847 Operand double_store_operand = BuildFastArrayOperand( |
| 3797 instr->elements(), | 3848 instr->elements(), |
| 3798 key, | 3849 key, |
| 3799 FAST_DOUBLE_ELEMENTS, | 3850 FAST_DOUBLE_ELEMENTS, |
| 3800 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3851 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3801 instr->additional_index()); | 3852 instr->additional_index()); |
| 3802 | 3853 |
| 3803 __ movsd(double_store_operand, value); | 3854 __ movsd(double_store_operand, value); |
| 3804 } | 3855 } |
| 3805 | 3856 |
| 3806 | 3857 |
| 3807 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 3858 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 3808 Register value = ToRegister(instr->value()); | 3859 Register value = ToRegister(instr->value()); |
| 3809 Register elements = ToRegister(instr->elements()); | 3860 Register elements = ToRegister(instr->elements()); |
| 3810 LOperand* key = instr->key(); | 3861 LOperand* key = instr->key(); |
| 3811 PrepareKeyForKeyedOp<HStoreKeyed>(instr->hydrogen(), key); | 3862 if (!key->IsConstantOperand()) { |
| 3863 Register key_reg = ToRegister(key); |
| 3864 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3865 // the input representation for the key to be an integer, the |
| 3866 // input gets replaced during bound check elimination with the index |
| 3867 // argument to the bounds check, which can be tagged, so that case |
| 3868 // must be handled here, too. |
| 3869 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3870 __ SmiToInteger64(key_reg, key_reg); |
| 3871 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3872 // Sign extend key because it could be a 32 bit negative value |
| 3873 // and the dehoisted address computation happens in 64 bits |
| 3874 __ movsxlq(key_reg, key_reg); |
| 3875 } |
| 3876 } |
| 3812 | 3877 |
| 3813 Operand operand = | 3878 Operand operand = |
| 3814 BuildFastArrayOperand(instr->elements(), | 3879 BuildFastArrayOperand(instr->elements(), |
| 3815 key, | 3880 key, |
| 3816 FAST_ELEMENTS, | 3881 FAST_ELEMENTS, |
| 3817 FixedArray::kHeaderSize - kHeapObjectTag, | 3882 FixedArray::kHeaderSize - kHeapObjectTag, |
| 3818 instr->additional_index()); | 3883 instr->additional_index()); |
| 3819 | 3884 |
| 3820 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3885 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3821 ASSERT(!instr->key()->IsConstantOperand()); | 3886 ASSERT(!instr->key()->IsConstantOperand()); |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5283 FixedArray::kHeaderSize - kPointerSize)); | 5348 FixedArray::kHeaderSize - kPointerSize)); |
| 5284 __ bind(&done); | 5349 __ bind(&done); |
| 5285 } | 5350 } |
| 5286 | 5351 |
| 5287 | 5352 |
| 5288 #undef __ | 5353 #undef __ |
| 5289 | 5354 |
| 5290 } } // namespace v8::internal | 5355 } } // namespace v8::internal |
| 5291 | 5356 |
| 5292 #endif // V8_TARGET_ARCH_X64 | 5357 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |