Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: src/mips/lithium-codegen-mips.cc

Issue 11369110: MIPS: Consolidated all the key store/load classes in the Hydrogen and Lithium space into just two: … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2615 // There are two words between the frame pointer and the last argument. 2615 // There are two words between the frame pointer and the last argument.
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 __ subu(length, length, index); 2617 __ subu(length, length, index);
2618 __ Addu(length, length, Operand(1)); 2618 __ Addu(length, length, Operand(1));
2619 __ sll(length, length, kPointerSizeLog2); 2619 __ sll(length, length, kPointerSizeLog2);
2620 __ Addu(at, arguments, Operand(length)); 2620 __ Addu(at, arguments, Operand(length));
2621 __ lw(result, MemOperand(at, 0)); 2621 __ lw(result, MemOperand(at, 0));
2622 } 2622 }
2623 2623
2624 2624
2625 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2625 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2626 Register elements = ToRegister(instr->elements()); 2626 Register external_pointer = ToRegister(instr->elements());
2627 Register result = ToRegister(instr->result()); 2627 Register key = no_reg;
2628 Register scratch = scratch0(); 2628 ElementsKind elements_kind = instr->elements_kind();
2629 Register store_base = scratch; 2629 bool key_is_constant = instr->key()->IsConstantOperand();
2630 int offset = 0; 2630 int constant_key = 0;
2631 if (key_is_constant) {
2632 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2633 if (constant_key & 0xF0000000) {
2634 Abort("array index constant value too big.");
2635 }
2636 } else {
2637 key = ToRegister(instr->key());
2638 }
2639 int element_size_shift = ElementsKindToShiftSize(elements_kind);
2640 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2641 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2642 int additional_offset = instr->additional_index() << element_size_shift;
2631 2643
2632 if (instr->key()->IsConstantOperand()) { 2644 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2633 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 2645 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2634 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + 2646 FPURegister result = ToDoubleRegister(instr->result());
2635 instr->additional_index()); 2647 if (key_is_constant) {
2636 store_base = elements; 2648 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
2649 } else {
2650 __ sll(scratch0(), key, shift_size);
2651 __ Addu(scratch0(), scratch0(), external_pointer);
2652 }
2653
2654 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2655 __ lwc1(result, MemOperand(scratch0(), additional_offset));
2656 __ cvt_d_s(result, result);
2657 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2658 __ ldc1(result, MemOperand(scratch0(), additional_offset));
2659 }
2637 } else { 2660 } else {
2638 Register key = EmitLoadRegister(instr->key(), scratch); 2661 Register result = ToRegister(instr->result());
2639 // Even though the HLoadKeyedFastElement instruction forces the input 2662 MemOperand mem_operand = PrepareKeyedOperand(
2640 // representation for the key to be an integer, the input gets replaced 2663 key, external_pointer, key_is_constant, constant_key,
2641 // during bound check elimination with the index argument to the bounds 2664 element_size_shift, shift_size,
2642 // check, which can be tagged, so that case must be handled here, too. 2665 instr->additional_index(), additional_offset);
2643 if (instr->hydrogen()->key()->representation().IsTagged()) { 2666 switch (elements_kind) {
2644 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize); 2667 case EXTERNAL_BYTE_ELEMENTS:
2645 __ addu(scratch, elements, scratch); 2668 __ lb(result, mem_operand);
2646 } else { 2669 break;
2647 __ sll(scratch, key, kPointerSizeLog2); 2670 case EXTERNAL_PIXEL_ELEMENTS:
2648 __ addu(scratch, elements, scratch); 2671 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2649 } 2672 __ lbu(result, mem_operand);
2650 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 2673 break;
2651 } 2674 case EXTERNAL_SHORT_ELEMENTS:
2652 __ lw(result, FieldMemOperand(store_base, offset)); 2675 __ lh(result, mem_operand);
2653 2676 break;
2654 // Check for the hole value. 2677 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2655 if (instr->hydrogen()->RequiresHoleCheck()) { 2678 __ lhu(result, mem_operand);
2656 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { 2679 break;
2657 __ And(scratch, result, Operand(kSmiTagMask)); 2680 case EXTERNAL_INT_ELEMENTS:
2658 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); 2681 __ lw(result, mem_operand);
2659 } else { 2682 break;
2660 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2683 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2661 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch)); 2684 __ lw(result, mem_operand);
2685 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2686 DeoptimizeIf(Ugreater_equal, instr->environment(),
2687 result, Operand(0x80000000));
2688 }
2689 break;
2690 case EXTERNAL_FLOAT_ELEMENTS:
2691 case EXTERNAL_DOUBLE_ELEMENTS:
2692 case FAST_DOUBLE_ELEMENTS:
2693 case FAST_ELEMENTS:
2694 case FAST_SMI_ELEMENTS:
2695 case FAST_HOLEY_DOUBLE_ELEMENTS:
2696 case FAST_HOLEY_ELEMENTS:
2697 case FAST_HOLEY_SMI_ELEMENTS:
2698 case DICTIONARY_ELEMENTS:
2699 case NON_STRICT_ARGUMENTS_ELEMENTS:
2700 UNREACHABLE();
2701 break;
2662 } 2702 }
2663 } 2703 }
2664 } 2704 }
2665 2705
2666 2706
2667 void LCodeGen::DoLoadKeyedFastDoubleElement( 2707 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2668 LLoadKeyedFastDoubleElement* instr) {
2669 Register elements = ToRegister(instr->elements()); 2708 Register elements = ToRegister(instr->elements());
2670 bool key_is_constant = instr->key()->IsConstantOperand(); 2709 bool key_is_constant = instr->key()->IsConstantOperand();
2671 Register key = no_reg; 2710 Register key = no_reg;
2672 DoubleRegister result = ToDoubleRegister(instr->result()); 2711 DoubleRegister result = ToDoubleRegister(instr->result());
2673 Register scratch = scratch0(); 2712 Register scratch = scratch0();
2674 2713
2675 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 2714 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
2676 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 2715 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2677 ? (element_size_shift - kSmiTagSize) : element_size_shift; 2716 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2678 int constant_key = 0; 2717 int constant_key = 0;
(...skipping 21 matching lines...) Expand all
2700 2739
2701 if (instr->hydrogen()->RequiresHoleCheck()) { 2740 if (instr->hydrogen()->RequiresHoleCheck()) {
2702 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 2741 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2703 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); 2742 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
2704 } 2743 }
2705 2744
2706 __ ldc1(result, MemOperand(elements)); 2745 __ ldc1(result, MemOperand(elements));
2707 } 2746 }
2708 2747
2709 2748
2749 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2750 Register elements = ToRegister(instr->elements());
2751 Register result = ToRegister(instr->result());
2752 Register scratch = scratch0();
2753 Register store_base = scratch;
2754 int offset = 0;
2755
2756 if (instr->key()->IsConstantOperand()) {
2757 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
2758 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
2759 instr->additional_index());
2760 store_base = elements;
2761 } else {
2762 Register key = EmitLoadRegister(instr->key(), scratch0());
2763 // Even though the HLoadKeyed instruction forces the input
2764 // representation for the key to be an integer, the input gets replaced
2765 // during bound check elimination with the index argument to the bounds
2766 // check, which can be tagged, so that case must be handled here, too.
2767 if (instr->hydrogen()->key()->representation().IsTagged()) {
2768 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
2769 __ addu(scratch, elements, scratch);
2770 } else {
2771 __ sll(scratch, key, kPointerSizeLog2);
2772 __ addu(scratch, elements, scratch);
2773 }
2774 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
2775 }
2776 __ lw(result, FieldMemOperand(store_base, offset));
2777
2778 // Check for the hole value.
2779 if (instr->hydrogen()->RequiresHoleCheck()) {
2780 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2781 __ And(scratch, result, Operand(kSmiTagMask));
2782 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
2783 } else {
2784 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2785 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
2786 }
2787 }
2788 }
2789
2790
2791 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2792 if (instr->is_external()) {
2793 DoLoadKeyedExternalArray(instr);
2794 } else if (instr->hydrogen()->representation().IsDouble()) {
2795 DoLoadKeyedFixedDoubleArray(instr);
2796 } else {
2797 DoLoadKeyedFixedArray(instr);
2798 }
2799 }
2800
2801
2710 MemOperand LCodeGen::PrepareKeyedOperand(Register key, 2802 MemOperand LCodeGen::PrepareKeyedOperand(Register key,
2711 Register base, 2803 Register base,
2712 bool key_is_constant, 2804 bool key_is_constant,
2713 int constant_key, 2805 int constant_key,
2714 int element_size, 2806 int element_size,
2715 int shift_size, 2807 int shift_size,
2716 int additional_index, 2808 int additional_index,
2717 int additional_offset) { 2809 int additional_offset) {
2718 if (additional_index != 0 && !key_is_constant) { 2810 if (additional_index != 0 && !key_is_constant) {
2719 additional_index *= 1 << (element_size - shift_size); 2811 additional_index *= 1 << (element_size - shift_size);
(...skipping 24 matching lines...) Expand all
2744 return MemOperand(scratch0()); 2836 return MemOperand(scratch0());
2745 } else { 2837 } else {
2746 ASSERT_EQ(-1, shift_size); 2838 ASSERT_EQ(-1, shift_size);
2747 __ srl(scratch0(), scratch0(), 1); 2839 __ srl(scratch0(), scratch0(), 1);
2748 __ Addu(scratch0(), base, scratch0()); 2840 __ Addu(scratch0(), base, scratch0());
2749 return MemOperand(scratch0()); 2841 return MemOperand(scratch0());
2750 } 2842 }
2751 } 2843 }
2752 2844
2753 2845
2754 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2755 LLoadKeyedSpecializedArrayElement* instr) {
2756 Register external_pointer = ToRegister(instr->external_pointer());
2757 Register key = no_reg;
2758 ElementsKind elements_kind = instr->elements_kind();
2759 bool key_is_constant = instr->key()->IsConstantOperand();
2760 int constant_key = 0;
2761 if (key_is_constant) {
2762 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2763 if (constant_key & 0xF0000000) {
2764 Abort("array index constant value too big.");
2765 }
2766 } else {
2767 key = ToRegister(instr->key());
2768 }
2769 int element_size_shift = ElementsKindToShiftSize(elements_kind);
2770 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2771 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2772 int additional_offset = instr->additional_index() << element_size_shift;
2773
2774 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2775 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2776 FPURegister result = ToDoubleRegister(instr->result());
2777 if (key_is_constant) {
2778 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
2779 } else {
2780 __ sll(scratch0(), key, shift_size);
2781 __ Addu(scratch0(), scratch0(), external_pointer);
2782 }
2783
2784 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2785 __ lwc1(result, MemOperand(scratch0(), additional_offset));
2786 __ cvt_d_s(result, result);
2787 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2788 __ ldc1(result, MemOperand(scratch0(), additional_offset));
2789 }
2790 } else {
2791 Register result = ToRegister(instr->result());
2792 MemOperand mem_operand = PrepareKeyedOperand(
2793 key, external_pointer, key_is_constant, constant_key,
2794 element_size_shift, shift_size,
2795 instr->additional_index(), additional_offset);
2796 switch (elements_kind) {
2797 case EXTERNAL_BYTE_ELEMENTS:
2798 __ lb(result, mem_operand);
2799 break;
2800 case EXTERNAL_PIXEL_ELEMENTS:
2801 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2802 __ lbu(result, mem_operand);
2803 break;
2804 case EXTERNAL_SHORT_ELEMENTS:
2805 __ lh(result, mem_operand);
2806 break;
2807 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2808 __ lhu(result, mem_operand);
2809 break;
2810 case EXTERNAL_INT_ELEMENTS:
2811 __ lw(result, mem_operand);
2812 break;
2813 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2814 __ lw(result, mem_operand);
2815 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2816 DeoptimizeIf(Ugreater_equal, instr->environment(),
2817 result, Operand(0x80000000));
2818 }
2819 break;
2820 case EXTERNAL_FLOAT_ELEMENTS:
2821 case EXTERNAL_DOUBLE_ELEMENTS:
2822 case FAST_DOUBLE_ELEMENTS:
2823 case FAST_ELEMENTS:
2824 case FAST_SMI_ELEMENTS:
2825 case FAST_HOLEY_DOUBLE_ELEMENTS:
2826 case FAST_HOLEY_ELEMENTS:
2827 case FAST_HOLEY_SMI_ELEMENTS:
2828 case DICTIONARY_ELEMENTS:
2829 case NON_STRICT_ARGUMENTS_ELEMENTS:
2830 UNREACHABLE();
2831 break;
2832 }
2833 }
2834 }
2835
2836
2837 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2846 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2838 ASSERT(ToRegister(instr->object()).is(a1)); 2847 ASSERT(ToRegister(instr->object()).is(a1));
2839 ASSERT(ToRegister(instr->key()).is(a0)); 2848 ASSERT(ToRegister(instr->key()).is(a0));
2840 2849
2841 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2850 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2842 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2851 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2843 } 2852 }
2844 2853
2845 2854
2846 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 2855 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
3730 Operand(ToRegister(instr->length()))); 3739 Operand(ToRegister(instr->length())));
3731 } else { 3740 } else {
3732 DeoptimizeIf(hs, 3741 DeoptimizeIf(hs,
3733 instr->environment(), 3742 instr->environment(),
3734 ToRegister(instr->index()), 3743 ToRegister(instr->index()),
3735 Operand(ToRegister(instr->length()))); 3744 Operand(ToRegister(instr->length())));
3736 } 3745 }
3737 } 3746 }
3738 3747
3739 3748
3740 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3749 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
3741 Register value = ToRegister(instr->value()); 3750 Register external_pointer = ToRegister(instr->elements());
3742 Register elements = ToRegister(instr->object());
3743 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3744 Register scratch = scratch0();
3745 Register store_base = scratch;
3746 int offset = 0;
3747
3748 // Do the store.
3749 if (instr->key()->IsConstantOperand()) {
3750 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3751 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3752 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3753 instr->additional_index());
3754 store_base = elements;
3755 } else {
3756 // Even though the HLoadKeyedFastElement instruction forces the input
3757 // representation for the key to be an integer, the input gets replaced
3758 // during bound check elimination with the index argument to the bounds
3759 // check, which can be tagged, so that case must be handled here, too.
3760 if (instr->hydrogen()->key()->representation().IsTagged()) {
3761 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
3762 __ addu(scratch, elements, scratch);
3763 } else {
3764 __ sll(scratch, key, kPointerSizeLog2);
3765 __ addu(scratch, elements, scratch);
3766 }
3767 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3768 }
3769 __ sw(value, FieldMemOperand(store_base, offset));
3770
3771 if (instr->hydrogen()->NeedsWriteBarrier()) {
3772 HType type = instr->hydrogen()->value()->type();
3773 SmiCheck check_needed =
3774 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3775 // Compute address of modified element and store it into key register.
3776 __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
3777 __ RecordWrite(elements,
3778 key,
3779 value,
3780 kRAHasBeenSaved,
3781 kSaveFPRegs,
3782 EMIT_REMEMBERED_SET,
3783 check_needed);
3784 }
3785 }
3786
3787
3788 void LCodeGen::DoStoreKeyedFastDoubleElement(
3789 LStoreKeyedFastDoubleElement* instr) {
3790 DoubleRegister value = ToDoubleRegister(instr->value());
3791 Register elements = ToRegister(instr->elements());
3792 Register key = no_reg;
3793 Register scratch = scratch0();
3794 bool key_is_constant = instr->key()->IsConstantOperand();
3795 int constant_key = 0;
3796 Label not_nan;
3797
3798 // Calculate the effective address of the slot in the array to store the
3799 // double value.
3800 if (key_is_constant) {
3801 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3802 if (constant_key & 0xF0000000) {
3803 Abort("array index constant value too big.");
3804 }
3805 } else {
3806 key = ToRegister(instr->key());
3807 }
3808 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3809 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3810 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3811 if (key_is_constant) {
3812 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
3813 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3814 } else {
3815 __ sll(scratch, key, shift_size);
3816 __ Addu(scratch, elements, Operand(scratch));
3817 __ Addu(scratch, scratch,
3818 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3819 }
3820
3821 if (instr->NeedsCanonicalization()) {
3822 Label is_nan;
3823 // Check for NaN. All NaNs must be canonicalized.
3824 __ BranchF(NULL, &is_nan, eq, value, value);
3825 __ Branch(&not_nan);
3826
3827 // Only load canonical NaN if the comparison above set the overflow.
3828 __ bind(&is_nan);
3829 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
3830 }
3831
3832 __ bind(&not_nan);
3833 __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
3834 element_size_shift));
3835 }
3836
3837
3838 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3839 LStoreKeyedSpecializedArrayElement* instr) {
3840
3841 Register external_pointer = ToRegister(instr->external_pointer());
3842 Register key = no_reg; 3751 Register key = no_reg;
3843 ElementsKind elements_kind = instr->elements_kind(); 3752 ElementsKind elements_kind = instr->elements_kind();
3844 bool key_is_constant = instr->key()->IsConstantOperand(); 3753 bool key_is_constant = instr->key()->IsConstantOperand();
3845 int constant_key = 0; 3754 int constant_key = 0;
3846 if (key_is_constant) { 3755 if (key_is_constant) {
3847 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3756 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3848 if (constant_key & 0xF0000000) { 3757 if (constant_key & 0xF0000000) {
3849 Abort("array index constant value too big."); 3758 Abort("array index constant value too big.");
3850 } 3759 }
3851 } else { 3760 } else {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3902 case FAST_HOLEY_ELEMENTS: 3811 case FAST_HOLEY_ELEMENTS:
3903 case FAST_HOLEY_SMI_ELEMENTS: 3812 case FAST_HOLEY_SMI_ELEMENTS:
3904 case DICTIONARY_ELEMENTS: 3813 case DICTIONARY_ELEMENTS:
3905 case NON_STRICT_ARGUMENTS_ELEMENTS: 3814 case NON_STRICT_ARGUMENTS_ELEMENTS:
3906 UNREACHABLE(); 3815 UNREACHABLE();
3907 break; 3816 break;
3908 } 3817 }
3909 } 3818 }
3910 } 3819 }
3911 3820
3821
3822 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
3823 DoubleRegister value = ToDoubleRegister(instr->value());
3824 Register elements = ToRegister(instr->elements());
3825 Register key = no_reg;
3826 Register scratch = scratch0();
3827 bool key_is_constant = instr->key()->IsConstantOperand();
3828 int constant_key = 0;
3829 Label not_nan;
3830
3831 // Calculate the effective address of the slot in the array to store the
3832 // double value.
3833 if (key_is_constant) {
3834 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3835 if (constant_key & 0xF0000000) {
3836 Abort("array index constant value too big.");
3837 }
3838 } else {
3839 key = ToRegister(instr->key());
3840 }
3841 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3842 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3843 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3844 if (key_is_constant) {
3845 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) +
3846 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3847 } else {
3848 __ sll(scratch, key, shift_size);
3849 __ Addu(scratch, elements, Operand(scratch));
3850 __ Addu(scratch, scratch,
3851 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3852 }
3853
3854 if (instr->NeedsCanonicalization()) {
3855 Label is_nan;
3856 // Check for NaN. All NaNs must be canonicalized.
3857 __ BranchF(NULL, &is_nan, eq, value, value);
3858 __ Branch(&not_nan);
3859
3860 // Only load canonical NaN if the comparison above set the overflow.
3861 __ bind(&is_nan);
3862 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
3863 }
3864
3865 __ bind(&not_nan);
3866 __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
3867 element_size_shift));
3868 }
3869
3870
3871 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
3872 Register value = ToRegister(instr->value());
3873 Register elements = ToRegister(instr->elements());
3874 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
3875 : no_reg;
3876 Register scratch = scratch0();
3877 Register store_base = scratch;
3878 int offset = 0;
3879
3880 // Do the store.
3881 if (instr->key()->IsConstantOperand()) {
3882 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3883 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3884 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3885 instr->additional_index());
3886 store_base = elements;
3887 } else {
3888 // Even though the HLoadKeyed instruction forces the input
3889 // representation for the key to be an integer, the input gets replaced
3890 // during bound check elimination with the index argument to the bounds
3891 // check, which can be tagged, so that case must be handled here, too.
3892 if (instr->hydrogen()->key()->representation().IsTagged()) {
3893 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
3894 __ addu(scratch, elements, scratch);
3895 } else {
3896 __ sll(scratch, key, kPointerSizeLog2);
3897 __ addu(scratch, elements, scratch);
3898 }
3899 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3900 }
3901 __ sw(value, FieldMemOperand(store_base, offset));
3902
3903 if (instr->hydrogen()->NeedsWriteBarrier()) {
3904 HType type = instr->hydrogen()->value()->type();
3905 SmiCheck check_needed =
3906 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3907 // Compute address of modified element and store it into key register.
3908 __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
3909 __ RecordWrite(elements,
3910 key,
3911 value,
3912 kRAHasBeenSaved,
3913 kSaveFPRegs,
3914 EMIT_REMEMBERED_SET,
3915 check_needed);
3916 }
3917 }
3918
3919
3920 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3921 // By cases: external, fast double
3922 if (instr->is_external()) {
3923 DoStoreKeyedExternalArray(instr);
3924 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3925 DoStoreKeyedFixedDoubleArray(instr);
3926 } else {
3927 DoStoreKeyedFixedArray(instr);
3928 }
3929 }
3930
3931
3912 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3932 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3913 ASSERT(ToRegister(instr->object()).is(a2)); 3933 ASSERT(ToRegister(instr->object()).is(a2));
3914 ASSERT(ToRegister(instr->key()).is(a1)); 3934 ASSERT(ToRegister(instr->key()).is(a1));
3915 ASSERT(ToRegister(instr->value()).is(a0)); 3935 ASSERT(ToRegister(instr->value()).is(a0));
3916 3936
3917 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3937 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3918 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3938 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3919 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3939 : isolate()->builtins()->KeyedStoreIC_Initialize();
3920 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3940 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3921 } 3941 }
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after
5440 __ Subu(scratch, result, scratch); 5460 __ Subu(scratch, result, scratch);
5441 __ lw(result, FieldMemOperand(scratch, 5461 __ lw(result, FieldMemOperand(scratch,
5442 FixedArray::kHeaderSize - kPointerSize)); 5462 FixedArray::kHeaderSize - kPointerSize));
5443 __ bind(&done); 5463 __ bind(&done);
5444 } 5464 }
5445 5465
5446 5466
5447 #undef __ 5467 #undef __
5448 5468
5449 } } // namespace v8::internal 5469 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698