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 2730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2741 | 2741 |
2742 | 2742 |
2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
2744 Register elements = ToRegister(instr->elements()); | 2744 Register elements = ToRegister(instr->elements()); |
2745 Register key = EmitLoadRegister(instr->key(), scratch0()); | 2745 Register key = EmitLoadRegister(instr->key(), scratch0()); |
2746 Register result = ToRegister(instr->result()); | 2746 Register result = ToRegister(instr->result()); |
2747 Register scratch = scratch0(); | 2747 Register scratch = scratch0(); |
2748 | 2748 |
2749 // Load the result. | 2749 // Load the result. |
2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
2751 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 2751 uint32_t offset = FixedArray::kHeaderSize + |
| 2752 (instr->additional_index() << kPointerSizeLog2); |
| 2753 __ ldr(result, FieldMemOperand(scratch, offset)); |
2752 | 2754 |
2753 // Check for the hole value. | 2755 // Check for the hole value. |
2754 if (instr->hydrogen()->RequiresHoleCheck()) { | 2756 if (instr->hydrogen()->RequiresHoleCheck()) { |
2755 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); | 2757 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
2756 __ cmp(result, scratch); | 2758 __ cmp(result, scratch); |
2757 DeoptimizeIf(eq, instr->environment()); | 2759 DeoptimizeIf(eq, instr->environment()); |
2758 } | 2760 } |
2759 } | 2761 } |
2760 | 2762 |
2761 | 2763 |
(...skipping 11 matching lines...) Expand all Loading... |
2773 if (key_is_constant) { | 2775 if (key_is_constant) { |
2774 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2776 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2775 if (constant_key & 0xF0000000) { | 2777 if (constant_key & 0xF0000000) { |
2776 Abort("array index constant value too big."); | 2778 Abort("array index constant value too big."); |
2777 } | 2779 } |
2778 } else { | 2780 } else { |
2779 key = ToRegister(instr->key()); | 2781 key = ToRegister(instr->key()); |
2780 } | 2782 } |
2781 | 2783 |
2782 Operand operand = key_is_constant | 2784 Operand operand = key_is_constant |
2783 ? Operand(constant_key * (1 << shift_size) + | 2785 ? Operand(((constant_key + instr->additional_index()) << shift_size) + |
2784 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | 2786 FixedDoubleArray::kHeaderSize - kHeapObjectTag) |
2785 : Operand(key, LSL, shift_size); | 2787 : Operand(key, LSL, shift_size); |
2786 __ add(elements, elements, operand); | 2788 __ add(elements, elements, operand); |
2787 if (!key_is_constant) { | 2789 if (!key_is_constant) { |
2788 __ add(elements, elements, | 2790 __ add(elements, elements, |
2789 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 2791 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
| 2792 (instr->additional_index() << shift_size))); |
2790 } | 2793 } |
2791 | 2794 |
2792 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 2795 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
2793 __ cmp(scratch, Operand(kHoleNanUpper32)); | 2796 __ cmp(scratch, Operand(kHoleNanUpper32)); |
2794 DeoptimizeIf(eq, instr->environment()); | 2797 DeoptimizeIf(eq, instr->environment()); |
2795 | 2798 |
2796 __ vldr(result, elements, 0); | 2799 __ vldr(result, elements, 0); |
2797 } | 2800 } |
2798 | 2801 |
2799 | 2802 |
2800 void LCodeGen::DoLoadKeyedSpecializedArrayElement( | 2803 void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
2801 LLoadKeyedSpecializedArrayElement* instr) { | 2804 LLoadKeyedSpecializedArrayElement* instr) { |
2802 Register external_pointer = ToRegister(instr->external_pointer()); | 2805 Register external_pointer = ToRegister(instr->external_pointer()); |
2803 Register key = no_reg; | 2806 Register key = no_reg; |
2804 ElementsKind elements_kind = instr->elements_kind(); | 2807 ElementsKind elements_kind = instr->elements_kind(); |
2805 bool key_is_constant = instr->key()->IsConstantOperand(); | 2808 bool key_is_constant = instr->key()->IsConstantOperand(); |
2806 int constant_key = 0; | 2809 int constant_key = 0; |
2807 if (key_is_constant) { | 2810 if (key_is_constant) { |
2808 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 2811 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
2809 if (constant_key & 0xF0000000) { | 2812 if (constant_key & 0xF0000000) { |
2810 Abort("array index constant value too big."); | 2813 Abort("array index constant value too big."); |
2811 } | 2814 } |
2812 } else { | 2815 } else { |
2813 key = ToRegister(instr->key()); | 2816 key = ToRegister(instr->key()); |
2814 } | 2817 } |
2815 int shift_size = ElementsKindToShiftSize(elements_kind); | 2818 int shift_size = ElementsKindToShiftSize(elements_kind); |
| 2819 int additional_offset = instr->additional_index() << shift_size; |
2816 | 2820 |
2817 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2821 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
2818 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2822 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2819 CpuFeatures::Scope scope(VFP3); | 2823 CpuFeatures::Scope scope(VFP3); |
2820 DwVfpRegister result = ToDoubleRegister(instr->result()); | 2824 DwVfpRegister result = ToDoubleRegister(instr->result()); |
2821 Operand operand = key_is_constant | 2825 Operand operand = key_is_constant |
2822 ? Operand(constant_key * (1 << shift_size)) | 2826 ? Operand(constant_key << shift_size) |
2823 : Operand(key, LSL, shift_size); | 2827 : Operand(key, LSL, shift_size); |
2824 __ add(scratch0(), external_pointer, operand); | 2828 __ add(scratch0(), external_pointer, operand); |
2825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2829 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2826 __ vldr(result.low(), scratch0(), 0); | 2830 __ vldr(result.low(), scratch0(), additional_offset); |
2827 __ vcvt_f64_f32(result, result.low()); | 2831 __ vcvt_f64_f32(result, result.low()); |
2828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 2832 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2829 __ vldr(result, scratch0(), 0); | 2833 __ vldr(result, scratch0(), additional_offset); |
2830 } | 2834 } |
2831 } else { | 2835 } else { |
2832 Register result = ToRegister(instr->result()); | 2836 Register result = ToRegister(instr->result()); |
| 2837 if (instr->additional_index() != 0 && !key_is_constant) { |
| 2838 __ add(scratch0(), key, Operand(instr->additional_index())); |
| 2839 } |
2833 MemOperand mem_operand(key_is_constant | 2840 MemOperand mem_operand(key_is_constant |
2834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) | 2841 ? MemOperand(external_pointer, |
2835 : MemOperand(external_pointer, key, LSL, shift_size)); | 2842 (constant_key << shift_size) + additional_offset) |
| 2843 : (instr->additional_index() == 0 |
| 2844 ? MemOperand(external_pointer, key, LSL, shift_size) |
| 2845 : MemOperand(external_pointer, scratch0(), LSL, shift_size))); |
2836 switch (elements_kind) { | 2846 switch (elements_kind) { |
2837 case EXTERNAL_BYTE_ELEMENTS: | 2847 case EXTERNAL_BYTE_ELEMENTS: |
2838 __ ldrsb(result, mem_operand); | 2848 __ ldrsb(result, mem_operand); |
2839 break; | 2849 break; |
2840 case EXTERNAL_PIXEL_ELEMENTS: | 2850 case EXTERNAL_PIXEL_ELEMENTS: |
2841 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2851 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
2842 __ ldrb(result, mem_operand); | 2852 __ ldrb(result, mem_operand); |
2843 break; | 2853 break; |
2844 case EXTERNAL_SHORT_ELEMENTS: | 2854 case EXTERNAL_SHORT_ELEMENTS: |
2845 __ ldrsh(result, mem_operand); | 2855 __ ldrsh(result, mem_operand); |
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3723 Register value = ToRegister(instr->value()); | 3733 Register value = ToRegister(instr->value()); |
3724 Register elements = ToRegister(instr->object()); | 3734 Register elements = ToRegister(instr->object()); |
3725 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 3735 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
3726 Register scratch = scratch0(); | 3736 Register scratch = scratch0(); |
3727 | 3737 |
3728 // Do the store. | 3738 // Do the store. |
3729 if (instr->key()->IsConstantOperand()) { | 3739 if (instr->key()->IsConstantOperand()) { |
3730 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3740 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
3731 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3741 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
3732 int offset = | 3742 int offset = |
3733 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; | 3743 (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize |
| 3744 + FixedArray::kHeaderSize; |
3734 __ str(value, FieldMemOperand(elements, offset)); | 3745 __ str(value, FieldMemOperand(elements, offset)); |
3735 } else { | 3746 } else { |
3736 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 3747 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
| 3748 if (instr->additional_index() != 0) { |
| 3749 __ add(scratch, |
| 3750 scratch, |
| 3751 Operand(instr->additional_index() << kPointerSizeLog2)); |
| 3752 } |
3737 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); | 3753 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
3738 } | 3754 } |
3739 | 3755 |
3740 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3756 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3741 HType type = instr->hydrogen()->value()->type(); | 3757 HType type = instr->hydrogen()->value()->type(); |
3742 SmiCheck check_needed = | 3758 SmiCheck check_needed = |
3743 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3759 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
3744 // Compute address of modified element and store it into key register. | 3760 // Compute address of modified element and store it into key register. |
3745 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3761 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
3746 __ RecordWrite(elements, | 3762 __ RecordWrite(elements, |
(...skipping 21 matching lines...) Expand all Loading... |
3768 if (key_is_constant) { | 3784 if (key_is_constant) { |
3769 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3785 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3770 if (constant_key & 0xF0000000) { | 3786 if (constant_key & 0xF0000000) { |
3771 Abort("array index constant value too big."); | 3787 Abort("array index constant value too big."); |
3772 } | 3788 } |
3773 } else { | 3789 } else { |
3774 key = ToRegister(instr->key()); | 3790 key = ToRegister(instr->key()); |
3775 } | 3791 } |
3776 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3792 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
3777 Operand operand = key_is_constant | 3793 Operand operand = key_is_constant |
3778 ? Operand(constant_key * (1 << shift_size) + | 3794 ? Operand((constant_key << shift_size) + |
3779 FixedDoubleArray::kHeaderSize - kHeapObjectTag) | 3795 FixedDoubleArray::kHeaderSize - kHeapObjectTag) |
3780 : Operand(key, LSL, shift_size); | 3796 : Operand(key, LSL, shift_size); |
3781 __ add(scratch, elements, operand); | 3797 __ add(scratch, elements, operand); |
3782 if (!key_is_constant) { | 3798 if (!key_is_constant) { |
3783 __ add(scratch, scratch, | 3799 __ add(scratch, scratch, |
3784 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 3800 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
3785 } | 3801 } |
3786 | 3802 |
3787 if (instr->NeedsCanonicalization()) { | 3803 if (instr->NeedsCanonicalization()) { |
3788 // Check for NaN. All NaNs must be canonicalized. | 3804 // Check for NaN. All NaNs must be canonicalized. |
3789 __ VFPCompareAndSetFlags(value, value); | 3805 __ VFPCompareAndSetFlags(value, value); |
3790 // Only load canonical NaN if the comparison above set the overflow. | 3806 // Only load canonical NaN if the comparison above set the overflow. |
3791 __ Vmov(value, | 3807 __ Vmov(value, |
3792 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), | 3808 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), |
3793 vs); | 3809 vs); |
3794 } | 3810 } |
3795 | 3811 |
3796 __ vstr(value, scratch, 0); | 3812 __ vstr(value, scratch, instr->additional_index() << shift_size); |
3797 } | 3813 } |
3798 | 3814 |
3799 | 3815 |
3800 void LCodeGen::DoStoreKeyedSpecializedArrayElement( | 3816 void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
3801 LStoreKeyedSpecializedArrayElement* instr) { | 3817 LStoreKeyedSpecializedArrayElement* instr) { |
3802 | 3818 |
3803 Register external_pointer = ToRegister(instr->external_pointer()); | 3819 Register external_pointer = ToRegister(instr->external_pointer()); |
3804 Register key = no_reg; | 3820 Register key = no_reg; |
3805 ElementsKind elements_kind = instr->elements_kind(); | 3821 ElementsKind elements_kind = instr->elements_kind(); |
3806 bool key_is_constant = instr->key()->IsConstantOperand(); | 3822 bool key_is_constant = instr->key()->IsConstantOperand(); |
3807 int constant_key = 0; | 3823 int constant_key = 0; |
3808 if (key_is_constant) { | 3824 if (key_is_constant) { |
3809 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3825 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
3810 if (constant_key & 0xF0000000) { | 3826 if (constant_key & 0xF0000000) { |
3811 Abort("array index constant value too big."); | 3827 Abort("array index constant value too big."); |
3812 } | 3828 } |
3813 } else { | 3829 } else { |
3814 key = ToRegister(instr->key()); | 3830 key = ToRegister(instr->key()); |
3815 } | 3831 } |
3816 int shift_size = ElementsKindToShiftSize(elements_kind); | 3832 int shift_size = ElementsKindToShiftSize(elements_kind); |
| 3833 int additional_offset = instr->additional_index() << shift_size; |
3817 | 3834 |
3818 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3835 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3819 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3836 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3820 CpuFeatures::Scope scope(VFP3); | 3837 CpuFeatures::Scope scope(VFP3); |
3821 DwVfpRegister value(ToDoubleRegister(instr->value())); | 3838 DwVfpRegister value(ToDoubleRegister(instr->value())); |
3822 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) | 3839 Operand operand(key_is_constant ? Operand(constant_key << shift_size) |
3823 : Operand(key, LSL, shift_size)); | 3840 : Operand(key, LSL, shift_size)); |
3824 __ add(scratch0(), external_pointer, operand); | 3841 __ add(scratch0(), external_pointer, operand); |
3825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3842 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3826 __ vcvt_f32_f64(double_scratch0().low(), value); | 3843 __ vcvt_f32_f64(double_scratch0().low(), value); |
3827 __ vstr(double_scratch0().low(), scratch0(), 0); | 3844 __ vstr(double_scratch0().low(), scratch0(), additional_offset); |
3828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 3845 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
3829 __ vstr(value, scratch0(), 0); | 3846 __ vstr(value, scratch0(), additional_offset); |
3830 } | 3847 } |
3831 } else { | 3848 } else { |
3832 Register value(ToRegister(instr->value())); | 3849 Register value(ToRegister(instr->value())); |
| 3850 if (instr->additional_index() != 0 && !key_is_constant) { |
| 3851 __ add(scratch0(), key, Operand(instr->additional_index())); |
| 3852 } |
3833 MemOperand mem_operand(key_is_constant | 3853 MemOperand mem_operand(key_is_constant |
3834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) | 3854 ? MemOperand(external_pointer, |
3835 : MemOperand(external_pointer, key, LSL, shift_size)); | 3855 ((constant_key + instr->additional_index()) |
| 3856 << shift_size)) |
| 3857 : (instr->additional_index() == 0 |
| 3858 ? MemOperand(external_pointer, key, LSL, shift_size) |
| 3859 : MemOperand(external_pointer, scratch0(), LSL, shift_size))); |
3836 switch (elements_kind) { | 3860 switch (elements_kind) { |
3837 case EXTERNAL_PIXEL_ELEMENTS: | 3861 case EXTERNAL_PIXEL_ELEMENTS: |
3838 case EXTERNAL_BYTE_ELEMENTS: | 3862 case EXTERNAL_BYTE_ELEMENTS: |
3839 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3863 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3840 __ strb(value, mem_operand); | 3864 __ strb(value, mem_operand); |
3841 break; | 3865 break; |
3842 case EXTERNAL_SHORT_ELEMENTS: | 3866 case EXTERNAL_SHORT_ELEMENTS: |
3843 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3867 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3844 __ strh(value, mem_operand); | 3868 __ strh(value, mem_operand); |
3845 break; | 3869 break; |
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5311 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5335 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5312 __ ldr(result, FieldMemOperand(scratch, | 5336 __ ldr(result, FieldMemOperand(scratch, |
5313 FixedArray::kHeaderSize - kPointerSize)); | 5337 FixedArray::kHeaderSize - kPointerSize)); |
5314 __ bind(&done); | 5338 __ bind(&done); |
5315 } | 5339 } |
5316 | 5340 |
5317 | 5341 |
5318 #undef __ | 5342 #undef __ |
5319 | 5343 |
5320 } } // namespace v8::internal | 5344 } } // namespace v8::internal |
OLD | NEW |