Chromium Code Reviews

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

Issue 11238016: Consolidated all the key store/load classes in the Hydrogen and Lithium (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed the 2 failing mjsunit tests Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
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...)
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::DoLoadKeyedExternal(LLoadKeyed* instr) {
2626 Register elements = ToRegister(instr->elements());
2627 Register result = ToRegister(instr->result());
2628 Register scratch = scratch0();
2629 Register store_base = scratch;
2630 int offset = 0;
2631
2632 if (instr->key()->IsConstantOperand()) {
2633 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
2634 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
2635 instr->additional_index());
2636 store_base = elements;
2637 } else {
2638 Register key = EmitLoadRegister(instr->key(), scratch);
2639 // Even though the HLoadKeyedFastElement instruction forces the input
2640 // representation for the key to be an integer, the input gets replaced
2641 // during bound check elimination with the index argument to the bounds
2642 // check, which can be tagged, so that case must be handled here, too.
2643 if (instr->hydrogen()->key()->representation().IsTagged()) {
2644 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
2645 __ addu(scratch, elements, scratch);
2646 } else {
2647 __ sll(scratch, key, kPointerSizeLog2);
2648 __ addu(scratch, elements, scratch);
2649 }
2650 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
2651 }
2652 __ lw(result, FieldMemOperand(store_base, offset));
2653
2654 // Check for the hole value.
2655 if (instr->hydrogen()->RequiresHoleCheck()) {
2656 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2657 __ And(scratch, result, Operand(kSmiTagMask));
2658 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
2659 } else {
2660 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2661 DeoptimizeIf(eq, instr->environment(), result, Operand(scratch));
2662 }
2663 }
2664 }
2665
2666
2667 void LCodeGen::DoLoadKeyedFastDoubleElement(
2668 LLoadKeyedFastDoubleElement* instr) {
2669 Register elements = ToRegister(instr->elements());
2670 bool key_is_constant = instr->key()->IsConstantOperand();
2671 Register key = no_reg;
2672 DoubleRegister result = ToDoubleRegister(instr->result());
2673 Register scratch = scratch0();
2674
2675 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
2676 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2677 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2678 int constant_key = 0;
2679 if (key_is_constant) {
2680 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2681 if (constant_key & 0xF0000000) {
2682 Abort("array index constant value too big.");
2683 }
2684 } else {
2685 key = ToRegister(instr->key());
2686 }
2687
2688 if (key_is_constant) {
2689 __ Addu(elements, elements,
2690 Operand(((constant_key + instr->additional_index()) <<
2691 element_size_shift) +
2692 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
2693 } else {
2694 __ sll(scratch, key, shift_size);
2695 __ Addu(elements, elements, Operand(scratch));
2696 __ Addu(elements, elements,
2697 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
2698 (instr->additional_index() << element_size_shift)));
2699 }
2700
2701 if (instr->hydrogen()->RequiresHoleCheck()) {
2702 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2703 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
2704 }
2705
2706 __ ldc1(result, MemOperand(elements));
2707 }
2708
2709
2710 MemOperand LCodeGen::PrepareKeyedOperand(Register key,
2711 Register base,
2712 bool key_is_constant,
2713 int constant_key,
2714 int element_size,
2715 int shift_size,
2716 int additional_index,
2717 int additional_offset) {
2718 if (additional_index != 0 && !key_is_constant) {
2719 additional_index *= 1 << (element_size - shift_size);
2720 __ Addu(scratch0(), key, Operand(additional_index));
2721 }
2722
2723 if (key_is_constant) {
2724 return MemOperand(base,
2725 (constant_key << element_size) + additional_offset);
2726 }
2727
2728 if (additional_index == 0) {
2729 if (shift_size >= 0) {
2730 __ sll(scratch0(), key, shift_size);
2731 __ Addu(scratch0(), base, scratch0());
2732 return MemOperand(scratch0());
2733 } else {
2734 ASSERT_EQ(-1, shift_size);
2735 __ srl(scratch0(), key, 1);
2736 __ Addu(scratch0(), base, scratch0());
2737 return MemOperand(scratch0());
2738 }
2739 }
2740
2741 if (shift_size >= 0) {
2742 __ sll(scratch0(), scratch0(), shift_size);
2743 __ Addu(scratch0(), base, scratch0());
2744 return MemOperand(scratch0());
2745 } else {
2746 ASSERT_EQ(-1, shift_size);
2747 __ srl(scratch0(), scratch0(), 1);
2748 __ Addu(scratch0(), base, scratch0());
2749 return MemOperand(scratch0());
2750 }
2751 }
2752
2753
2754 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2755 LLoadKeyedSpecializedArrayElement* instr) {
2756 Register external_pointer = ToRegister(instr->external_pointer()); 2626 Register external_pointer = ToRegister(instr->external_pointer());
2757 Register key = no_reg; 2627 Register key = no_reg;
2758 ElementsKind elements_kind = instr->elements_kind(); 2628 ElementsKind elements_kind = instr->elements_kind();
2759 bool key_is_constant = instr->key()->IsConstantOperand(); 2629 bool key_is_constant = instr->key()->IsConstantOperand();
2760 int constant_key = 0; 2630 int constant_key = 0;
2761 if (key_is_constant) { 2631 if (key_is_constant) {
2762 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2632 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2763 if (constant_key & 0xF0000000) { 2633 if (constant_key & 0xF0000000) {
2764 Abort("array index constant value too big."); 2634 Abort("array index constant value too big.");
2765 } 2635 }
2766 } else { 2636 } else {
2767 key = ToRegister(instr->key()); 2637 key = ToRegister(instr->key());
2768 } 2638 }
2769 int element_size_shift = ElementsKindToShiftSize(elements_kind); 2639 int element_size_shift = ElementsKindToShiftSize(elements_kind);
2770 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 2640 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2771 ? (element_size_shift - kSmiTagSize) : element_size_shift; 2641 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2772 int additional_offset = instr->additional_index() << element_size_shift; 2642 int additional_offset = instr->additional_index() << element_size_shift;
2773 2643
2774 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 2644 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2775 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2645 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2776 FPURegister result = ToDoubleRegister(instr->result()); 2646 FPURegister result = ToDoubleRegister(instr->result());
2777 if (key_is_constant) { 2647 if (key_is_constant) {
2778 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); 2648 __ Addu(scratch0(), external_pointer,
2649 constant_key << element_size_shift);
2779 } else { 2650 } else {
2780 __ sll(scratch0(), key, shift_size); 2651 __ sll(scratch0(), key, shift_size);
2781 __ Addu(scratch0(), scratch0(), external_pointer); 2652 __ Addu(scratch0(), scratch0(), external_pointer);
2782 } 2653 }
2783 2654
2784 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2655 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2785 __ lwc1(result, MemOperand(scratch0(), additional_offset)); 2656 __ lwc1(result, MemOperand(scratch0(), additional_offset));
2786 __ cvt_d_s(result, result); 2657 __ cvt_d_s(result, result);
2787 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 2658 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2788 __ ldc1(result, MemOperand(scratch0(), additional_offset)); 2659 __ ldc1(result, MemOperand(scratch0(), additional_offset));
(...skipping 18 matching lines...)
2807 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2678 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2808 __ lhu(result, mem_operand); 2679 __ lhu(result, mem_operand);
2809 break; 2680 break;
2810 case EXTERNAL_INT_ELEMENTS: 2681 case EXTERNAL_INT_ELEMENTS:
2811 __ lw(result, mem_operand); 2682 __ lw(result, mem_operand);
2812 break; 2683 break;
2813 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2684 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2814 __ lw(result, mem_operand); 2685 __ lw(result, mem_operand);
2815 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { 2686 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2816 DeoptimizeIf(Ugreater_equal, instr->environment(), 2687 DeoptimizeIf(Ugreater_equal, instr->environment(),
2817 result, Operand(0x80000000)); 2688 result, Operand(0x80000000));
2818 } 2689 }
2819 break; 2690 break;
2820 case EXTERNAL_FLOAT_ELEMENTS: 2691 case EXTERNAL_FLOAT_ELEMENTS:
2821 case EXTERNAL_DOUBLE_ELEMENTS: 2692 case EXTERNAL_DOUBLE_ELEMENTS:
2822 case FAST_DOUBLE_ELEMENTS: 2693 case FAST_DOUBLE_ELEMENTS:
2823 case FAST_ELEMENTS: 2694 case FAST_ELEMENTS:
2824 case FAST_SMI_ELEMENTS: 2695 case FAST_SMI_ELEMENTS:
2825 case FAST_HOLEY_DOUBLE_ELEMENTS: 2696 case FAST_HOLEY_DOUBLE_ELEMENTS:
2826 case FAST_HOLEY_ELEMENTS: 2697 case FAST_HOLEY_ELEMENTS:
2827 case FAST_HOLEY_SMI_ELEMENTS: 2698 case FAST_HOLEY_SMI_ELEMENTS:
2828 case DICTIONARY_ELEMENTS: 2699 case DICTIONARY_ELEMENTS:
2829 case NON_STRICT_ARGUMENTS_ELEMENTS: 2700 case NON_STRICT_ARGUMENTS_ELEMENTS:
2830 UNREACHABLE(); 2701 UNREACHABLE();
2831 break; 2702 break;
2832 } 2703 }
2833 } 2704 }
2834 } 2705 }
2835 2706
2707 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2708 if (instr->is_external()) {
2709 DoLoadKeyedExternal(instr);
2710 } else if (instr->hydrogen()->representation().IsDouble()) {
2711 Register elements = ToRegister(instr->elements());
2712 bool key_is_constant = instr->key()->IsConstantOperand();
2713 Register key = no_reg;
2714 DoubleRegister result = ToDoubleRegister(instr->result());
2715 Register scratch = scratch0();
2716
2717 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
2718 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
2719 ? (element_size_shift - kSmiTagSize) : element_size_shift;
2720 int constant_key = 0;
2721 if (key_is_constant) {
2722 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2723 if (constant_key & 0xF0000000) {
2724 Abort("array index constant value too big.");
2725 }
2726 } else {
2727 key = ToRegister(instr->key());
2728 }
2729
2730 if (key_is_constant) {
2731 __ Addu(elements, elements,
2732 Operand(((constant_key + instr->additional_index()) <<
2733 element_size_shift) +
2734 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
2735 } else {
2736 __ sll(scratch, key, shift_size);
2737 __ Addu(elements, elements, Operand(scratch));
2738 __ Addu(elements, elements,
2739 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
2740 (instr->additional_index() << element_size_shift)));
2741 }
2742
2743 if (instr->hydrogen()->RequiresHoleCheck()) {
2744 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2745 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32));
2746 }
2747
2748 __ ldc1(result, MemOperand(elements));
2749 } else {
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(), scratch);
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
2792 MemOperand LCodeGen::PrepareKeyedOperand(Register key,
2793 Register base,
2794 bool key_is_constant,
2795 int constant_key,
2796 int element_size,
2797 int shift_size,
2798 int additional_index,
2799 int additional_offset) {
2800 if (additional_index != 0 && !key_is_constant) {
2801 additional_index *= 1 << (element_size - shift_size);
2802 __ Addu(scratch0(), key, Operand(additional_index));
2803 }
2804
2805 if (key_is_constant) {
2806 return MemOperand(base,
2807 (constant_key << element_size) + additional_offset);
2808 }
2809
2810 if (additional_index == 0) {
2811 if (shift_size >= 0) {
2812 __ sll(scratch0(), key, shift_size);
2813 __ Addu(scratch0(), base, scratch0());
2814 return MemOperand(scratch0());
2815 } else {
2816 ASSERT_EQ(-1, shift_size);
2817 __ srl(scratch0(), key, 1);
2818 __ Addu(scratch0(), base, scratch0());
2819 return MemOperand(scratch0());
2820 }
2821 }
2822
2823 if (shift_size >= 0) {
2824 __ sll(scratch0(), scratch0(), shift_size);
2825 __ Addu(scratch0(), base, scratch0());
2826 return MemOperand(scratch0());
2827 } else {
2828 ASSERT_EQ(-1, shift_size);
2829 __ srl(scratch0(), scratch0(), 1);
2830 __ Addu(scratch0(), base, scratch0());
2831 return MemOperand(scratch0());
2832 }
2833 }
2834
2836 2835
2837 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2836 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2838 ASSERT(ToRegister(instr->object()).is(a1)); 2837 ASSERT(ToRegister(instr->object()).is(a1));
2839 ASSERT(ToRegister(instr->key()).is(a0)); 2838 ASSERT(ToRegister(instr->key()).is(a0));
2840 2839
2841 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2840 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2842 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2841 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2843 } 2842 }
2844 2843
2845 2844
(...skipping 884 matching lines...)
3730 Operand(ToRegister(instr->length()))); 3729 Operand(ToRegister(instr->length())));
3731 } else { 3730 } else {
3732 DeoptimizeIf(hs, 3731 DeoptimizeIf(hs,
3733 instr->environment(), 3732 instr->environment(),
3734 ToRegister(instr->index()), 3733 ToRegister(instr->index()),
3735 Operand(ToRegister(instr->length()))); 3734 Operand(ToRegister(instr->length())));
3736 } 3735 }
3737 } 3736 }
3738 3737
3739 3738
3740 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3739 void LCodeGen::DoStoreKeyedExternal(LStoreKeyed* instr) {
3741 Register value = ToRegister(instr->value());
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()); 3740 Register external_pointer = ToRegister(instr->external_pointer());
3842 Register key = no_reg; 3741 Register key = no_reg;
3843 ElementsKind elements_kind = instr->elements_kind(); 3742 ElementsKind elements_kind = instr->elements_kind();
3844 bool key_is_constant = instr->key()->IsConstantOperand(); 3743 bool key_is_constant = instr->key()->IsConstantOperand();
3845 int constant_key = 0; 3744 int constant_key = 0;
3846 if (key_is_constant) { 3745 if (key_is_constant) {
3847 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3746 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3848 if (constant_key & 0xF0000000) { 3747 if (constant_key & 0xF0000000) {
3849 Abort("array index constant value too big."); 3748 Abort("array index constant value too big.");
3850 } 3749 }
3851 } else { 3750 } else {
3852 key = ToRegister(instr->key()); 3751 key = ToRegister(instr->key());
3853 } 3752 }
3854 int element_size_shift = ElementsKindToShiftSize(elements_kind); 3753 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3855 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 3754 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3856 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3755 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3857 int additional_offset = instr->additional_index() << element_size_shift; 3756 int additional_offset = instr->additional_index() << element_size_shift;
3858 3757
3859 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3758 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3860 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3759 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3861 FPURegister value(ToDoubleRegister(instr->value())); 3760 FPURegister value(ToDoubleRegister(instr->value()));
3862 if (key_is_constant) { 3761 if (key_is_constant) {
3863 __ Addu(scratch0(), external_pointer, constant_key << 3762 __ Addu(scratch0(), external_pointer, constant_key <<
3864 element_size_shift); 3763 element_size_shift);
3865 } else { 3764 } else {
3866 __ sll(scratch0(), key, shift_size); 3765 __ sll(scratch0(), key, shift_size);
3867 __ Addu(scratch0(), scratch0(), external_pointer); 3766 __ Addu(scratch0(), scratch0(), external_pointer);
3868 } 3767 }
3869 3768
3870 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3769 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3871 __ cvt_s_d(double_scratch0(), value); 3770 __ cvt_s_d(double_scratch0(), value);
3872 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); 3771 __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset));
3873 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3772 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3874 __ sdc1(value, MemOperand(scratch0(), additional_offset)); 3773 __ sdc1(value, MemOperand(scratch0(), additional_offset));
(...skipping 27 matching lines...)
3902 case FAST_HOLEY_ELEMENTS: 3801 case FAST_HOLEY_ELEMENTS:
3903 case FAST_HOLEY_SMI_ELEMENTS: 3802 case FAST_HOLEY_SMI_ELEMENTS:
3904 case DICTIONARY_ELEMENTS: 3803 case DICTIONARY_ELEMENTS:
3905 case NON_STRICT_ARGUMENTS_ELEMENTS: 3804 case NON_STRICT_ARGUMENTS_ELEMENTS:
3906 UNREACHABLE(); 3805 UNREACHABLE();
3907 break; 3806 break;
3908 } 3807 }
3909 } 3808 }
3910 } 3809 }
3911 3810
3811 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3812 // By cases: external, fast double, fast
3813 if (instr->is_external()) {
3814 DoStoreKeyedEternal(instr);
3815 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3816 DoubleRegister value = ToDoubleRegister(instr->value());
3817 Register elements = ToRegister(instr->elements());
3818 Register key = no_reg;
3819 Register scratch = scratch0();
3820 bool key_is_constant = instr->key()->IsConstantOperand();
3821 int constant_key = 0;
3822 Label not_nan;
3823
3824 // Calculate the effective address of the slot in the array to store the
3825 // double value.
3826 if (key_is_constant) {
3827 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3828 if (constant_key & 0xF0000000) {
3829 Abort("array index constant value too big.");
3830 }
3831 } else {
3832 key = ToRegister(instr->key());
3833 }
3834 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3835 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3836 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3837 if (key_is_constant) {
3838 __ Addu(scratch, elements,
3839 Operand((constant_key << element_size_shift) +
3840 FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3841 } else {
3842 __ sll(scratch, key, shift_size);
3843 __ Addu(scratch, elements, Operand(scratch));
3844 __ Addu(scratch, scratch,
3845 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3846 }
3847
3848 if (instr->NeedsCanonicalization()) {
3849 Label is_nan;
3850 // Check for NaN. All NaNs must be canonicalized.
3851 __ BranchF(NULL, &is_nan, eq, value, value);
3852 __ Branch(&not_nan);
3853
3854 // Only load canonical NaN if the comparison above set the overflow.
3855 __ bind(&is_nan);
3856 __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double());
3857 }
3858
3859 __ bind(&not_nan);
3860 __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
3861 element_size_shift));
3862 } else {
3863 Register value = ToRegister(instr->value());
3864 Register elements = ToRegister(instr->object());
3865 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
3866 : no_reg;
3867 Register scratch = scratch0();
3868 Register store_base = scratch;
3869 int offset = 0;
3870
3871 // Do the store.
3872 if (instr->key()->IsConstantOperand()) {
3873 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3874 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3875 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3876 instr->additional_index());
3877 store_base = elements;
3878 } else {
3879 // Even though the HLoadKeyed instruction forces the input
3880 // representation for the key to be an integer, the input gets replaced
3881 // during bound check elimination with the index argument to the bounds
3882 // check, which can be tagged, so that case must be handled here, too.
3883 if (instr->hydrogen()->key()->representation().IsTagged()) {
3884 __ sll(scratch, key, kPointerSizeLog2 - kSmiTagSize);
3885 __ addu(scratch, elements, scratch);
3886 } else {
3887 __ sll(scratch, key, kPointerSizeLog2);
3888 __ addu(scratch, elements, scratch);
3889 }
3890 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
3891 }
3892 __ sw(value, FieldMemOperand(store_base, offset));
3893
3894 if (instr->hydrogen()->NeedsWriteBarrier()) {
3895 HType type = instr->hydrogen()->value()->type();
3896 SmiCheck check_needed =
3897 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3898 // Compute address of modified element and store it into key register.
3899 __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
3900 __ RecordWrite(elements,
3901 key,
3902 value,
3903 kRAHasBeenSaved,
3904 kSaveFPRegs,
3905 EMIT_REMEMBERED_SET,
3906 check_needed);
3907 }
3908 }
3909 }
3910
3911
3912 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3912 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3913 ASSERT(ToRegister(instr->object()).is(a2)); 3913 ASSERT(ToRegister(instr->object()).is(a2));
3914 ASSERT(ToRegister(instr->key()).is(a1)); 3914 ASSERT(ToRegister(instr->key()).is(a1));
3915 ASSERT(ToRegister(instr->value()).is(a0)); 3915 ASSERT(ToRegister(instr->value()).is(a0));
3916 3916
3917 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3917 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
3918 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3918 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3919 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3919 : isolate()->builtins()->KeyedStoreIC_Initialize();
3920 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3920 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3921 } 3921 }
(...skipping 1517 matching lines...)
5439 __ Subu(scratch, result, scratch); 5439 __ Subu(scratch, result, scratch);
5440 __ lw(result, FieldMemOperand(scratch, 5440 __ lw(result, FieldMemOperand(scratch,
5441 FixedArray::kHeaderSize - kPointerSize)); 5441 FixedArray::kHeaderSize - kPointerSize));
5442 __ bind(&done); 5442 __ bind(&done);
5443 } 5443 }
5444 5444
5445 5445
5446 #undef __ 5446 #undef __
5447 5447
5448 } } // namespace v8::internal 5448 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine