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