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