| 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 2594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 // Subtracting from length accounts for one of them add one more. | 2605 // Subtracting from length accounts for one of them add one more. |
| 2606 if (instr->index()->IsRegister()) { | 2606 if (instr->index()->IsRegister()) { |
| 2607 __ subl(length, ToRegister(instr->index())); | 2607 __ subl(length, ToRegister(instr->index())); |
| 2608 } else { | 2608 } else { |
| 2609 __ subl(length, ToOperand(instr->index())); | 2609 __ subl(length, ToOperand(instr->index())); |
| 2610 } | 2610 } |
| 2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); | 2611 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize)); |
| 2612 } | 2612 } |
| 2613 | 2613 |
| 2614 | 2614 |
| 2615 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2615 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2616 Register result = ToRegister(instr->result()); | 2616 ElementsKind elements_kind = instr->elements_kind(); |
| 2617 LOperand* key = instr->key(); | 2617 LOperand* key = instr->key(); |
| 2618 if (!key->IsConstantOperand()) { | 2618 if (!key->IsConstantOperand()) { |
| 2619 Register key_reg = ToRegister(key); | 2619 Register key_reg = ToRegister(key); |
| 2620 // Even though the HLoad/StoreKeyedFastElement instructions force the input | 2620 // Even though the HLoad/StoreKeyed (in this case) instructions force |
| 2621 // representation for the key to be an integer, the input gets replaced | 2621 // the input representation for the key to be an integer, the input |
| 2622 // during bound check elimination with the index argument to the bounds | 2622 // gets replaced during bound check elimination with the index argument |
| 2623 // check, which can be tagged, so that case must be handled here, too. | 2623 // to the bounds check, which can be tagged, so that case must be |
| 2624 // handled here, too. |
| 2624 if (instr->hydrogen()->key()->representation().IsTagged()) { | 2625 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2625 __ SmiToInteger64(key_reg, key_reg); | 2626 __ SmiToInteger64(key_reg, key_reg); |
| 2626 } else if (instr->hydrogen()->IsDehoisted()) { | 2627 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2627 // Sign extend key because it could be a 32 bit negative value | 2628 // Sign extend key because it could be a 32 bit negative value |
| 2628 // and the dehoisted address computation happens in 64 bits | 2629 // and the dehoisted address computation happens in 64 bits |
| 2629 __ movsxlq(key_reg, key_reg); | 2630 __ movsxlq(key_reg, key_reg); |
| 2630 } | 2631 } |
| 2631 } | 2632 } |
| 2633 Operand operand(BuildFastArrayOperand( |
| 2634 instr->elements(), |
| 2635 key, |
| 2636 elements_kind, |
| 2637 0, |
| 2638 instr->additional_index())); |
| 2632 | 2639 |
| 2633 // Load the result. | 2640 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 2634 __ movq(result, | 2641 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2635 BuildFastArrayOperand(instr->elements(), | 2642 __ movss(result, operand); |
| 2636 key, | 2643 __ cvtss2sd(result, result); |
| 2637 FAST_ELEMENTS, | 2644 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 2638 FixedArray::kHeaderSize - kHeapObjectTag, | 2645 __ movsd(ToDoubleRegister(instr->result()), operand); |
| 2639 instr->additional_index())); | 2646 } else { |
| 2640 | 2647 Register result(ToRegister(instr->result())); |
| 2641 // Check for the hole value. | 2648 switch (elements_kind) { |
| 2642 if (instr->hydrogen()->RequiresHoleCheck()) { | 2649 case EXTERNAL_BYTE_ELEMENTS: |
| 2643 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 2650 __ movsxbq(result, operand); |
| 2644 Condition smi = __ CheckSmi(result); | 2651 break; |
| 2645 DeoptimizeIf(NegateCondition(smi), instr->environment()); | 2652 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2646 } else { | 2653 case EXTERNAL_PIXEL_ELEMENTS: |
| 2647 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 2654 __ movzxbq(result, operand); |
| 2648 DeoptimizeIf(equal, instr->environment()); | 2655 break; |
| 2656 case EXTERNAL_SHORT_ELEMENTS: |
| 2657 __ movsxwq(result, operand); |
| 2658 break; |
| 2659 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2660 __ movzxwq(result, operand); |
| 2661 break; |
| 2662 case EXTERNAL_INT_ELEMENTS: |
| 2663 __ movsxlq(result, operand); |
| 2664 break; |
| 2665 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2666 __ movl(result, operand); |
| 2667 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { |
| 2668 __ testl(result, result); |
| 2669 DeoptimizeIf(negative, instr->environment()); |
| 2670 } |
| 2671 break; |
| 2672 case EXTERNAL_FLOAT_ELEMENTS: |
| 2673 case EXTERNAL_DOUBLE_ELEMENTS: |
| 2674 case FAST_ELEMENTS: |
| 2675 case FAST_SMI_ELEMENTS: |
| 2676 case FAST_DOUBLE_ELEMENTS: |
| 2677 case FAST_HOLEY_ELEMENTS: |
| 2678 case FAST_HOLEY_SMI_ELEMENTS: |
| 2679 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 2680 case DICTIONARY_ELEMENTS: |
| 2681 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 2682 UNREACHABLE(); |
| 2683 break; |
| 2649 } | 2684 } |
| 2650 } | 2685 } |
| 2651 } | 2686 } |
| 2652 | 2687 |
| 2653 | 2688 |
| 2654 void LCodeGen::DoLoadKeyedFastDoubleElement( | 2689 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 2655 LLoadKeyedFastDoubleElement* instr) { | |
| 2656 XMMRegister result(ToDoubleRegister(instr->result())); | 2690 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2657 LOperand* key = instr->key(); | 2691 LOperand* key = instr->key(); |
| 2658 if (!key->IsConstantOperand()) { | 2692 if (!key->IsConstantOperand()) { |
| 2659 Register key_reg = ToRegister(key); | 2693 Register key_reg = ToRegister(key); |
| 2660 // Even though the HLoad/StoreKeyedFastElement instructions force the input | 2694 // Even though the HLoad/StoreKeyed instructions force the input |
| 2661 // representation for the key to be an integer, the input gets replaced | 2695 // representation for the key to be an integer, the input gets replaced |
| 2662 // during bound check elimination with the index argument to the bounds | 2696 // during bound check elimination with the index argument to the bounds |
| 2663 // check, which can be tagged, so that case must be handled here, too. | 2697 // check, which can be tagged, so that case must be handled here, too. |
| 2664 if (instr->hydrogen()->key()->representation().IsTagged()) { | 2698 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2665 __ SmiToInteger64(key_reg, key_reg); | 2699 __ SmiToInteger64(key_reg, key_reg); |
| 2666 } else if (instr->hydrogen()->IsDehoisted()) { | 2700 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2667 // Sign extend key because it could be a 32 bit negative value | 2701 // Sign extend key because it could be a 32 bit negative value |
| 2668 // and the dehoisted address computation happens in 64 bits | 2702 // and the dehoisted address computation happens in 64 bits |
| 2669 __ movsxlq(key_reg, key_reg); | 2703 __ movsxlq(key_reg, key_reg); |
| 2670 } | 2704 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2686 Operand double_load_operand = BuildFastArrayOperand( | 2720 Operand double_load_operand = BuildFastArrayOperand( |
| 2687 instr->elements(), | 2721 instr->elements(), |
| 2688 key, | 2722 key, |
| 2689 FAST_DOUBLE_ELEMENTS, | 2723 FAST_DOUBLE_ELEMENTS, |
| 2690 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 2724 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 2691 instr->additional_index()); | 2725 instr->additional_index()); |
| 2692 __ movsd(result, double_load_operand); | 2726 __ movsd(result, double_load_operand); |
| 2693 } | 2727 } |
| 2694 | 2728 |
| 2695 | 2729 |
| 2730 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 2731 Register result = ToRegister(instr->result()); |
| 2732 LOperand* key = instr->key(); |
| 2733 if (!key->IsConstantOperand()) { |
| 2734 Register key_reg = ToRegister(key); |
| 2735 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 2736 // the input representation for the key to be an integer, the input |
| 2737 // gets replaced during bound check elimination with the index |
| 2738 // argument to the bounds check, which can be tagged, so that |
| 2739 // case must be handled here, too. |
| 2740 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 2741 __ SmiToInteger64(key_reg, key_reg); |
| 2742 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2743 // Sign extend key because it could be a 32 bit negative value |
| 2744 // and the dehoisted address computation happens in 64 bits |
| 2745 __ movsxlq(key_reg, key_reg); |
| 2746 } |
| 2747 } |
| 2748 |
| 2749 // Load the result. |
| 2750 __ movq(result, |
| 2751 BuildFastArrayOperand(instr->elements(), |
| 2752 key, |
| 2753 FAST_ELEMENTS, |
| 2754 FixedArray::kHeaderSize - kHeapObjectTag, |
| 2755 instr->additional_index())); |
| 2756 |
| 2757 // Check for the hole value. |
| 2758 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2759 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 2760 Condition smi = __ CheckSmi(result); |
| 2761 DeoptimizeIf(NegateCondition(smi), instr->environment()); |
| 2762 } else { |
| 2763 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 2764 DeoptimizeIf(equal, instr->environment()); |
| 2765 } |
| 2766 } |
| 2767 } |
| 2768 |
| 2769 |
| 2770 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) { |
| 2771 if (instr->is_external()) { |
| 2772 DoLoadKeyedExternalArray(instr); |
| 2773 } else if (instr->hydrogen()->representation().IsDouble()) { |
| 2774 DoLoadKeyedFixedDoubleArray(instr); |
| 2775 } else { |
| 2776 DoLoadKeyedFixedArray(instr); |
| 2777 } |
| 2778 } |
| 2779 |
| 2780 |
| 2696 Operand LCodeGen::BuildFastArrayOperand( | 2781 Operand LCodeGen::BuildFastArrayOperand( |
| 2697 LOperand* elements_pointer, | 2782 LOperand* elements_pointer, |
| 2698 LOperand* key, | 2783 LOperand* key, |
| 2699 ElementsKind elements_kind, | 2784 ElementsKind elements_kind, |
| 2700 uint32_t offset, | 2785 uint32_t offset, |
| 2701 uint32_t additional_index) { | 2786 uint32_t additional_index) { |
| 2702 Register elements_pointer_reg = ToRegister(elements_pointer); | 2787 Register elements_pointer_reg = ToRegister(elements_pointer); |
| 2703 int shift_size = ElementsKindToShiftSize(elements_kind); | 2788 int shift_size = ElementsKindToShiftSize(elements_kind); |
| 2704 if (key->IsConstantOperand()) { | 2789 if (key->IsConstantOperand()) { |
| 2705 int constant_value = ToInteger32(LConstantOperand::cast(key)); | 2790 int constant_value = ToInteger32(LConstantOperand::cast(key)); |
| 2706 if (constant_value & 0xF0000000) { | 2791 if (constant_value & 0xF0000000) { |
| 2707 Abort("array index constant value too big"); | 2792 Abort("array index constant value too big"); |
| 2708 } | 2793 } |
| 2709 return Operand(elements_pointer_reg, | 2794 return Operand(elements_pointer_reg, |
| 2710 ((constant_value + additional_index) << shift_size) | 2795 ((constant_value + additional_index) << shift_size) |
| 2711 + offset); | 2796 + offset); |
| 2712 } else { | 2797 } else { |
| 2713 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); | 2798 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
| 2714 return Operand(elements_pointer_reg, | 2799 return Operand(elements_pointer_reg, |
| 2715 ToRegister(key), | 2800 ToRegister(key), |
| 2716 scale_factor, | 2801 scale_factor, |
| 2717 offset + (additional_index << shift_size)); | 2802 offset + (additional_index << shift_size)); |
| 2718 } | 2803 } |
| 2719 } | 2804 } |
| 2720 | 2805 |
| 2721 | 2806 |
| 2722 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | |
| 2723 LLoadKeyedSpecializedArrayElement* instr) { | |
| 2724 ElementsKind elements_kind = instr->elements_kind(); | |
| 2725 LOperand* key = instr->key(); | |
| 2726 if (!key->IsConstantOperand()) { | |
| 2727 Register key_reg = ToRegister(key); | |
| 2728 // Even though the HLoad/StoreKeyedFastElement instructions force the input | |
| 2729 // representation for the key to be an integer, the input gets replaced | |
| 2730 // during bound check elimination with the index argument to the bounds | |
| 2731 // check, which can be tagged, so that case must be handled here, too. | |
| 2732 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 2733 __ SmiToInteger64(key_reg, key_reg); | |
| 2734 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 2735 // Sign extend key because it could be a 32 bit negative value | |
| 2736 // and the dehoisted address computation happens in 64 bits | |
| 2737 __ movsxlq(key_reg, key_reg); | |
| 2738 } | |
| 2739 } | |
| 2740 Operand operand(BuildFastArrayOperand( | |
| 2741 instr->external_pointer(), | |
| 2742 key, | |
| 2743 elements_kind, | |
| 2744 0, | |
| 2745 instr->additional_index())); | |
| 2746 | |
| 2747 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | |
| 2748 XMMRegister result(ToDoubleRegister(instr->result())); | |
| 2749 __ movss(result, operand); | |
| 2750 __ cvtss2sd(result, result); | |
| 2751 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
| 2752 __ movsd(ToDoubleRegister(instr->result()), operand); | |
| 2753 } else { | |
| 2754 Register result(ToRegister(instr->result())); | |
| 2755 switch (elements_kind) { | |
| 2756 case EXTERNAL_BYTE_ELEMENTS: | |
| 2757 __ movsxbq(result, operand); | |
| 2758 break; | |
| 2759 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 2760 case EXTERNAL_PIXEL_ELEMENTS: | |
| 2761 __ movzxbq(result, operand); | |
| 2762 break; | |
| 2763 case EXTERNAL_SHORT_ELEMENTS: | |
| 2764 __ movsxwq(result, operand); | |
| 2765 break; | |
| 2766 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 2767 __ movzxwq(result, operand); | |
| 2768 break; | |
| 2769 case EXTERNAL_INT_ELEMENTS: | |
| 2770 __ movsxlq(result, operand); | |
| 2771 break; | |
| 2772 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 2773 __ movl(result, operand); | |
| 2774 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { | |
| 2775 __ testl(result, result); | |
| 2776 DeoptimizeIf(negative, instr->environment()); | |
| 2777 } | |
| 2778 break; | |
| 2779 case EXTERNAL_FLOAT_ELEMENTS: | |
| 2780 case EXTERNAL_DOUBLE_ELEMENTS: | |
| 2781 case FAST_ELEMENTS: | |
| 2782 case FAST_SMI_ELEMENTS: | |
| 2783 case FAST_DOUBLE_ELEMENTS: | |
| 2784 case FAST_HOLEY_ELEMENTS: | |
| 2785 case FAST_HOLEY_SMI_ELEMENTS: | |
| 2786 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
| 2787 case DICTIONARY_ELEMENTS: | |
| 2788 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 2789 UNREACHABLE(); | |
| 2790 break; | |
| 2791 } | |
| 2792 } | |
| 2793 } | |
| 2794 | |
| 2795 | |
| 2796 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2807 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| 2797 ASSERT(ToRegister(instr->object()).is(rdx)); | 2808 ASSERT(ToRegister(instr->object()).is(rdx)); |
| 2798 ASSERT(ToRegister(instr->key()).is(rax)); | 2809 ASSERT(ToRegister(instr->key()).is(rax)); |
| 2799 | 2810 |
| 2800 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2811 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2801 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2812 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2802 } | 2813 } |
| 2803 | 2814 |
| 2804 | 2815 |
| 2805 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 2816 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3658 ASSERT(ToRegister(instr->value()).is(rax)); | 3669 ASSERT(ToRegister(instr->value()).is(rax)); |
| 3659 | 3670 |
| 3660 __ Move(rcx, instr->hydrogen()->name()); | 3671 __ Move(rcx, instr->hydrogen()->name()); |
| 3661 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 3672 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 3662 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3673 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 3663 : isolate()->builtins()->StoreIC_Initialize(); | 3674 : isolate()->builtins()->StoreIC_Initialize(); |
| 3664 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3675 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3665 } | 3676 } |
| 3666 | 3677 |
| 3667 | 3678 |
| 3668 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | |
| 3669 LStoreKeyedSpecializedArrayElement* instr) { | |
| 3670 ElementsKind elements_kind = instr->elements_kind(); | |
| 3671 LOperand* key = instr->key(); | |
| 3672 if (!key->IsConstantOperand()) { | |
| 3673 Register key_reg = ToRegister(key); | |
| 3674 // Even though the HLoad/StoreKeyedFastElement instructions force the input | |
| 3675 // representation for the key to be an integer, the input gets replaced | |
| 3676 // during bound check elimination with the index argument to the bounds | |
| 3677 // check, which can be tagged, so that case must be handled here, too. | |
| 3678 if (instr->hydrogen()->key()->representation().IsTagged()) { | |
| 3679 __ SmiToInteger64(key_reg, key_reg); | |
| 3680 } else if (instr->hydrogen()->IsDehoisted()) { | |
| 3681 // Sign extend key because it could be a 32 bit negative value | |
| 3682 // and the dehoisted address computation happens in 64 bits | |
| 3683 __ movsxlq(key_reg, key_reg); | |
| 3684 } | |
| 3685 } | |
| 3686 Operand operand(BuildFastArrayOperand( | |
| 3687 instr->external_pointer(), | |
| 3688 key, | |
| 3689 elements_kind, | |
| 3690 0, | |
| 3691 instr->additional_index())); | |
| 3692 | |
| 3693 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | |
| 3694 XMMRegister value(ToDoubleRegister(instr->value())); | |
| 3695 __ cvtsd2ss(value, value); | |
| 3696 __ movss(operand, value); | |
| 3697 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | |
| 3698 __ movsd(operand, ToDoubleRegister(instr->value())); | |
| 3699 } else { | |
| 3700 Register value(ToRegister(instr->value())); | |
| 3701 switch (elements_kind) { | |
| 3702 case EXTERNAL_PIXEL_ELEMENTS: | |
| 3703 case EXTERNAL_BYTE_ELEMENTS: | |
| 3704 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
| 3705 __ movb(operand, value); | |
| 3706 break; | |
| 3707 case EXTERNAL_SHORT_ELEMENTS: | |
| 3708 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
| 3709 __ movw(operand, value); | |
| 3710 break; | |
| 3711 case EXTERNAL_INT_ELEMENTS: | |
| 3712 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
| 3713 __ movl(operand, value); | |
| 3714 break; | |
| 3715 case EXTERNAL_FLOAT_ELEMENTS: | |
| 3716 case EXTERNAL_DOUBLE_ELEMENTS: | |
| 3717 case FAST_ELEMENTS: | |
| 3718 case FAST_SMI_ELEMENTS: | |
| 3719 case FAST_DOUBLE_ELEMENTS: | |
| 3720 case FAST_HOLEY_ELEMENTS: | |
| 3721 case FAST_HOLEY_SMI_ELEMENTS: | |
| 3722 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
| 3723 case DICTIONARY_ELEMENTS: | |
| 3724 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
| 3725 UNREACHABLE(); | |
| 3726 break; | |
| 3727 } | |
| 3728 } | |
| 3729 } | |
| 3730 | |
| 3731 | |
| 3732 void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment, | 3679 void LCodeGen::DeoptIfTaggedButNotSmi(LEnvironment* environment, |
| 3733 HValue* value, | 3680 HValue* value, |
| 3734 LOperand* operand) { | 3681 LOperand* operand) { |
| 3735 if (value->representation().IsTagged() && !value->type().IsSmi()) { | 3682 if (value->representation().IsTagged() && !value->type().IsSmi()) { |
| 3736 Condition cc; | 3683 Condition cc; |
| 3737 if (operand->IsRegister()) { | 3684 if (operand->IsRegister()) { |
| 3738 cc = masm()->CheckSmi(ToRegister(operand)); | 3685 cc = masm()->CheckSmi(ToRegister(operand)); |
| 3739 } else { | 3686 } else { |
| 3740 cc = masm()->CheckSmi(ToOperand(operand)); | 3687 cc = masm()->CheckSmi(ToOperand(operand)); |
| 3741 } | 3688 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3782 __ cmpq(length, Immediate(constant_index)); | 3729 __ cmpq(length, Immediate(constant_index)); |
| 3783 } | 3730 } |
| 3784 } else { | 3731 } else { |
| 3785 __ cmpq(length, ToRegister(instr->index())); | 3732 __ cmpq(length, ToRegister(instr->index())); |
| 3786 } | 3733 } |
| 3787 } | 3734 } |
| 3788 DeoptimizeIf(below_equal, instr->environment()); | 3735 DeoptimizeIf(below_equal, instr->environment()); |
| 3789 } | 3736 } |
| 3790 | 3737 |
| 3791 | 3738 |
| 3792 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { | 3739 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 3793 Register value = ToRegister(instr->value()); | 3740 ElementsKind elements_kind = instr->elements_kind(); |
| 3794 Register elements = ToRegister(instr->object()); | |
| 3795 LOperand* key = instr->key(); | 3741 LOperand* key = instr->key(); |
| 3796 if (!key->IsConstantOperand()) { | 3742 if (!key->IsConstantOperand()) { |
| 3797 Register key_reg = ToRegister(key); | 3743 Register key_reg = ToRegister(key); |
| 3798 // Even though the HLoad/StoreKeyedFastElement instructions force the input | 3744 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3799 // representation for the key to be an integer, the input gets replaced | 3745 // the input representation for the key to be an integer, the input |
| 3800 // during bound check elimination with the index argument to the bounds | 3746 // gets replaced during bound check elimination with the index |
| 3801 // check, which can be tagged, so that case must be handled here, too. | 3747 // argument to the bounds check, which can be tagged, so that case |
| 3748 // must be handled here, too. |
| 3802 if (instr->hydrogen()->key()->representation().IsTagged()) { | 3749 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3803 __ SmiToInteger64(key_reg, key_reg); | 3750 __ SmiToInteger64(key_reg, key_reg); |
| 3804 } else if (instr->hydrogen()->IsDehoisted()) { | 3751 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3805 // Sign extend key because it could be a 32 bit negative value | 3752 // Sign extend key because it could be a 32 bit negative value |
| 3806 // and the dehoisted address computation happens in 64 bits | 3753 // and the dehoisted address computation happens in 64 bits |
| 3807 __ movsxlq(key_reg, key_reg); | 3754 __ movsxlq(key_reg, key_reg); |
| 3808 } | 3755 } |
| 3809 } | 3756 } |
| 3757 Operand operand(BuildFastArrayOperand( |
| 3758 instr->elements(), |
| 3759 key, |
| 3760 elements_kind, |
| 3761 0, |
| 3762 instr->additional_index())); |
| 3810 | 3763 |
| 3811 Operand operand = | 3764 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3812 BuildFastArrayOperand(instr->object(), | 3765 XMMRegister value(ToDoubleRegister(instr->value())); |
| 3813 key, | 3766 __ cvtsd2ss(value, value); |
| 3814 FAST_ELEMENTS, | 3767 __ movss(operand, value); |
| 3815 FixedArray::kHeaderSize - kHeapObjectTag, | 3768 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3816 instr->additional_index()); | 3769 __ movsd(operand, ToDoubleRegister(instr->value())); |
| 3817 | |
| 3818 if (instr->hydrogen()->NeedsWriteBarrier()) { | |
| 3819 ASSERT(!instr->key()->IsConstantOperand()); | |
| 3820 HType type = instr->hydrogen()->value()->type(); | |
| 3821 SmiCheck check_needed = | |
| 3822 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | |
| 3823 // Compute address of modified element and store it into key register. | |
| 3824 Register key_reg(ToRegister(key)); | |
| 3825 __ lea(key_reg, operand); | |
| 3826 __ movq(Operand(key_reg, 0), value); | |
| 3827 __ RecordWrite(elements, | |
| 3828 key_reg, | |
| 3829 value, | |
| 3830 kSaveFPRegs, | |
| 3831 EMIT_REMEMBERED_SET, | |
| 3832 check_needed); | |
| 3833 } else { | 3770 } else { |
| 3834 __ movq(operand, value); | 3771 Register value(ToRegister(instr->value())); |
| 3772 switch (elements_kind) { |
| 3773 case EXTERNAL_PIXEL_ELEMENTS: |
| 3774 case EXTERNAL_BYTE_ELEMENTS: |
| 3775 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3776 __ movb(operand, value); |
| 3777 break; |
| 3778 case EXTERNAL_SHORT_ELEMENTS: |
| 3779 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3780 __ movw(operand, value); |
| 3781 break; |
| 3782 case EXTERNAL_INT_ELEMENTS: |
| 3783 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3784 __ movl(operand, value); |
| 3785 break; |
| 3786 case EXTERNAL_FLOAT_ELEMENTS: |
| 3787 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3788 case FAST_ELEMENTS: |
| 3789 case FAST_SMI_ELEMENTS: |
| 3790 case FAST_DOUBLE_ELEMENTS: |
| 3791 case FAST_HOLEY_ELEMENTS: |
| 3792 case FAST_HOLEY_SMI_ELEMENTS: |
| 3793 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 3794 case DICTIONARY_ELEMENTS: |
| 3795 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 3796 UNREACHABLE(); |
| 3797 break; |
| 3798 } |
| 3835 } | 3799 } |
| 3836 } | 3800 } |
| 3837 | 3801 |
| 3838 | 3802 |
| 3839 void LCodeGen::DoStoreKeyedFastDoubleElement( | 3803 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 3840 LStoreKeyedFastDoubleElement* instr) { | |
| 3841 XMMRegister value = ToDoubleRegister(instr->value()); | 3804 XMMRegister value = ToDoubleRegister(instr->value()); |
| 3842 LOperand* key = instr->key(); | 3805 LOperand* key = instr->key(); |
| 3843 if (!key->IsConstantOperand()) { | 3806 if (!key->IsConstantOperand()) { |
| 3844 Register key_reg = ToRegister(key); | 3807 Register key_reg = ToRegister(key); |
| 3845 // Even though the HLoad/StoreKeyedFastElement instructions force the input | 3808 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3846 // representation for the key to be an integer, the input gets replaced | 3809 // the input representation for the key to be an integer, the |
| 3847 // during bound check elimination with the index argument to the bounds | 3810 // input gets replaced during bound check elimination with the index |
| 3848 // check, which can be tagged, so that case must be handled here, too. | 3811 // argument to the bounds check, which can be tagged, so that case |
| 3812 // must be handled here, too. |
| 3849 if (instr->hydrogen()->key()->representation().IsTagged()) { | 3813 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3850 __ SmiToInteger64(key_reg, key_reg); | 3814 __ SmiToInteger64(key_reg, key_reg); |
| 3851 } else if (instr->hydrogen()->IsDehoisted()) { | 3815 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3852 // Sign extend key because it could be a 32 bit negative value | 3816 // Sign extend key because it could be a 32 bit negative value |
| 3853 // and the dehoisted address computation happens in 64 bits | 3817 // and the dehoisted address computation happens in 64 bits |
| 3854 __ movsxlq(key_reg, key_reg); | 3818 __ movsxlq(key_reg, key_reg); |
| 3855 } | 3819 } |
| 3856 } | 3820 } |
| 3857 | 3821 |
| 3858 if (instr->NeedsCanonicalization()) { | 3822 if (instr->NeedsCanonicalization()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3871 Operand double_store_operand = BuildFastArrayOperand( | 3835 Operand double_store_operand = BuildFastArrayOperand( |
| 3872 instr->elements(), | 3836 instr->elements(), |
| 3873 key, | 3837 key, |
| 3874 FAST_DOUBLE_ELEMENTS, | 3838 FAST_DOUBLE_ELEMENTS, |
| 3875 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3839 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3876 instr->additional_index()); | 3840 instr->additional_index()); |
| 3877 | 3841 |
| 3878 __ movsd(double_store_operand, value); | 3842 __ movsd(double_store_operand, value); |
| 3879 } | 3843 } |
| 3880 | 3844 |
| 3845 |
| 3846 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 3847 Register value = ToRegister(instr->value()); |
| 3848 Register elements = ToRegister(instr->elements()); |
| 3849 LOperand* key = instr->key(); |
| 3850 if (!key->IsConstantOperand()) { |
| 3851 Register key_reg = ToRegister(key); |
| 3852 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3853 // the input representation for the key to be an integer, the |
| 3854 // input gets replaced during bound check elimination with the index |
| 3855 // argument to the bounds check, which can be tagged, so that case |
| 3856 // must be handled here, too. |
| 3857 if (instr->hydrogen()->key()->representation().IsTagged()) { |
| 3858 __ SmiToInteger64(key_reg, key_reg); |
| 3859 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3860 // Sign extend key because it could be a 32 bit negative value |
| 3861 // and the dehoisted address computation happens in 64 bits |
| 3862 __ movsxlq(key_reg, key_reg); |
| 3863 } |
| 3864 } |
| 3865 |
| 3866 Operand operand = |
| 3867 BuildFastArrayOperand(instr->elements(), |
| 3868 key, |
| 3869 FAST_ELEMENTS, |
| 3870 FixedArray::kHeaderSize - kHeapObjectTag, |
| 3871 instr->additional_index()); |
| 3872 |
| 3873 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3874 ASSERT(!instr->key()->IsConstantOperand()); |
| 3875 HType type = instr->hydrogen()->value()->type(); |
| 3876 SmiCheck check_needed = |
| 3877 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3878 // Compute address of modified element and store it into key register. |
| 3879 Register key_reg(ToRegister(key)); |
| 3880 __ lea(key_reg, operand); |
| 3881 __ movq(Operand(key_reg, 0), value); |
| 3882 __ RecordWrite(elements, |
| 3883 key_reg, |
| 3884 value, |
| 3885 kSaveFPRegs, |
| 3886 EMIT_REMEMBERED_SET, |
| 3887 check_needed); |
| 3888 } else { |
| 3889 __ movq(operand, value); |
| 3890 } |
| 3891 } |
| 3892 |
| 3893 |
| 3894 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
| 3895 if (instr->is_external()) { |
| 3896 DoStoreKeyedExternalArray(instr); |
| 3897 } else if (instr->hydrogen()->value()->representation().IsDouble()) { |
| 3898 DoStoreKeyedFixedDoubleArray(instr); |
| 3899 } else { |
| 3900 DoStoreKeyedFixedArray(instr); |
| 3901 } |
| 3902 } |
| 3903 |
| 3904 |
| 3881 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 3905 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 3882 ASSERT(ToRegister(instr->object()).is(rdx)); | 3906 ASSERT(ToRegister(instr->object()).is(rdx)); |
| 3883 ASSERT(ToRegister(instr->key()).is(rcx)); | 3907 ASSERT(ToRegister(instr->key()).is(rcx)); |
| 3884 ASSERT(ToRegister(instr->value()).is(rax)); | 3908 ASSERT(ToRegister(instr->value()).is(rax)); |
| 3885 | 3909 |
| 3886 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 3910 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 3887 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3911 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 3888 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3912 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 3889 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 3913 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 3890 } | 3914 } |
| (...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5311 FixedArray::kHeaderSize - kPointerSize)); | 5335 FixedArray::kHeaderSize - kPointerSize)); |
| 5312 __ bind(&done); | 5336 __ bind(&done); |
| 5313 } | 5337 } |
| 5314 | 5338 |
| 5315 | 5339 |
| 5316 #undef __ | 5340 #undef __ |
| 5317 | 5341 |
| 5318 } } // namespace v8::internal | 5342 } } // namespace v8::internal |
| 5319 | 5343 |
| 5320 #endif // V8_TARGET_ARCH_X64 | 5344 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |