Chromium Code Reviews| 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 3769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3780 // the value can be represented in a Smi. If not, we need to convert | 3780 // the value can be represented in a Smi. If not, we need to convert |
| 3781 // it to a HeapNumber. | 3781 // it to a HeapNumber. |
| 3782 Label box_int; | 3782 Label box_int; |
| 3783 __ cmp(value, Operand(0xC0000000)); | 3783 __ cmp(value, Operand(0xC0000000)); |
| 3784 __ b(mi, &box_int); | 3784 __ b(mi, &box_int); |
| 3785 // Tag integer as smi and return it. | 3785 // Tag integer as smi and return it. |
| 3786 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3786 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
| 3787 __ Ret(); | 3787 __ Ret(); |
| 3788 | 3788 |
| 3789 __ bind(&box_int); | 3789 __ bind(&box_int); |
| 3790 // Allocate a HeapNumber for the result and perform int-to-double | |
| 3791 // conversion. Don't touch r0 or r1 as they are needed if allocation | |
| 3792 // fails. | |
| 3793 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | |
| 3794 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); | |
| 3795 // Now we can use r0 for the result as key is not needed any more. | |
| 3796 __ mov(r0, r5); | |
| 3797 | |
| 3798 if (CpuFeatures::IsSupported(VFP2)) { | 3790 if (CpuFeatures::IsSupported(VFP2)) { |
| 3799 CpuFeatures::Scope scope(VFP2); | 3791 CpuFeatures::Scope scope(VFP2); |
| 3792 // Allocate a HeapNumber for the result and perform int-to-double | |
| 3793 // conversion. Don't touch r0 or r1 as they are needed if allocation | |
| 3794 // fails. | |
| 3795 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | |
| 3796 | |
| 3797 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT); | |
| 3798 // Now we can use r0 for the result as key is not needed any more. | |
| 3799 __ add(r0, r5, Operand(kHeapObjectTag)); | |
| 3800 __ vmov(s0, value); | 3800 __ vmov(s0, value); |
| 3801 __ vcvt_f64_s32(d0, s0); | 3801 __ vcvt_f64_s32(d0, s0); |
| 3802 __ sub(r3, r0, Operand(kHeapObjectTag)); | 3802 __ vstr(d0, r5, HeapNumber::kValueOffset); |
| 3803 __ vstr(d0, r3, HeapNumber::kValueOffset); | |
| 3804 __ Ret(); | 3803 __ Ret(); |
| 3805 } else { | 3804 } else { |
| 3805 // Allocate a HeapNumber for the result and perform int-to-double | |
| 3806 // conversion. Don't touch r0 or r1 as they are needed if allocation | |
| 3807 // fails. | |
| 3808 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | |
| 3809 | |
|
danno
2012/10/11 13:03:57
nit: remove introduced whitespace
aberent
2012/10/11 15:16:53
Done.
| |
| 3810 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT); | |
| 3811 // Now we can use r0 for the result as key is not needed any more. | |
| 3812 __ mov(r0, r5); | |
| 3806 Register dst1 = r1; | 3813 Register dst1 = r1; |
| 3807 Register dst2 = r3; | 3814 Register dst2 = r3; |
| 3808 FloatingPointHelper::Destination dest = | 3815 FloatingPointHelper::Destination dest = |
| 3809 FloatingPointHelper::kCoreRegisters; | 3816 FloatingPointHelper::kCoreRegisters; |
| 3810 FloatingPointHelper::ConvertIntToDouble(masm, | 3817 FloatingPointHelper::ConvertIntToDouble(masm, |
| 3811 value, | 3818 value, |
| 3812 dest, | 3819 dest, |
| 3813 d0, | 3820 d0, |
| 3814 dst1, | 3821 dst1, |
| 3815 dst2, | 3822 dst2, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 3831 // Tag integer as smi and return it. | 3838 // Tag integer as smi and return it. |
| 3832 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3839 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
| 3833 __ Ret(); | 3840 __ Ret(); |
| 3834 | 3841 |
| 3835 __ bind(&box_int); | 3842 __ bind(&box_int); |
| 3836 __ vmov(s0, value); | 3843 __ vmov(s0, value); |
| 3837 // Allocate a HeapNumber for the result and perform int-to-double | 3844 // Allocate a HeapNumber for the result and perform int-to-double |
| 3838 // conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all | 3845 // conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all |
| 3839 // registers - also when jumping due to exhausted young space. | 3846 // registers - also when jumping due to exhausted young space. |
| 3840 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3847 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3841 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); | 3848 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT); |
| 3842 | 3849 |
| 3843 __ vcvt_f64_u32(d0, s0); | 3850 __ vcvt_f64_u32(d0, s0); |
| 3844 __ sub(r1, r2, Operand(kHeapObjectTag)); | 3851 __ vstr(d0, r2, HeapNumber::kValueOffset); |
| 3845 __ vstr(d0, r1, HeapNumber::kValueOffset); | |
| 3846 | 3852 |
| 3847 __ mov(r0, r2); | 3853 __ add(r0, r2, Operand(kHeapObjectTag)); |
| 3848 __ Ret(); | 3854 __ Ret(); |
| 3849 } else { | 3855 } else { |
| 3850 // Check whether unsigned integer fits into smi. | 3856 // Check whether unsigned integer fits into smi. |
| 3851 Label box_int_0, box_int_1, done; | 3857 Label box_int_0, box_int_1, done; |
| 3852 __ tst(value, Operand(0x80000000)); | 3858 __ tst(value, Operand(0x80000000)); |
| 3853 __ b(ne, &box_int_0); | 3859 __ b(ne, &box_int_0); |
| 3854 __ tst(value, Operand(0x40000000)); | 3860 __ tst(value, Operand(0x40000000)); |
| 3855 __ b(ne, &box_int_1); | 3861 __ b(ne, &box_int_1); |
| 3856 // Tag integer as smi and return it. | 3862 // Tag integer as smi and return it. |
| 3857 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3863 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 3869 // Integer has one leading zero. | 3875 // Integer has one leading zero. |
| 3870 GenerateUInt2Double(masm, hiword, loword, r4, 1); | 3876 GenerateUInt2Double(masm, hiword, loword, r4, 1); |
| 3871 | 3877 |
| 3872 | 3878 |
| 3873 __ bind(&done); | 3879 __ bind(&done); |
| 3874 // Integer was converted to double in registers hiword:loword. | 3880 // Integer was converted to double in registers hiword:loword. |
| 3875 // Wrap it into a HeapNumber. Don't use r0 and r1 as AllocateHeapNumber | 3881 // Wrap it into a HeapNumber. Don't use r0 and r1 as AllocateHeapNumber |
| 3876 // clobbers all registers - also when jumping due to exhausted young | 3882 // clobbers all registers - also when jumping due to exhausted young |
| 3877 // space. | 3883 // space. |
| 3878 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3884 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3879 __ AllocateHeapNumber(r4, r5, r7, r6, &slow); | 3885 __ AllocateHeapNumber(r4, r5, r7, r6, &slow, TAG_RESULT); |
| 3880 | 3886 |
| 3881 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset)); | 3887 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset)); |
| 3882 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); | 3888 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); |
| 3883 | 3889 |
| 3884 __ mov(r0, r4); | 3890 __ mov(r0, r4); |
| 3885 __ Ret(); | 3891 __ Ret(); |
| 3886 } | 3892 } |
| 3887 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3893 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 3888 // For the floating-point array type, we need to always allocate a | 3894 // For the floating-point array type, we need to always allocate a |
| 3889 // HeapNumber. | 3895 // HeapNumber. |
| 3890 if (CpuFeatures::IsSupported(VFP2)) { | 3896 if (CpuFeatures::IsSupported(VFP2)) { |
| 3891 CpuFeatures::Scope scope(VFP2); | 3897 CpuFeatures::Scope scope(VFP2); |
| 3892 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3898 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3893 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3899 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3894 // exhausted young space. | 3900 // exhausted young space. |
| 3895 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3901 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3896 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); | 3902 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT); |
| 3897 __ vcvt_f64_f32(d0, s0); | 3903 __ vcvt_f64_f32(d0, s0); |
| 3898 __ sub(r1, r2, Operand(kHeapObjectTag)); | 3904 __ vstr(d0, r2, HeapNumber::kValueOffset); |
| 3899 __ vstr(d0, r1, HeapNumber::kValueOffset); | |
| 3900 | 3905 |
| 3901 __ mov(r0, r2); | 3906 __ add(r0, r2, Operand(kHeapObjectTag)); |
| 3902 __ Ret(); | 3907 __ Ret(); |
| 3903 } else { | 3908 } else { |
| 3904 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3909 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3905 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3910 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3906 // exhausted young space. | 3911 // exhausted young space. |
| 3907 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3912 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3908 __ AllocateHeapNumber(r3, r4, r5, r6, &slow); | 3913 __ AllocateHeapNumber(r3, r4, r5, r6, &slow, TAG_RESULT); |
| 3909 // VFP is not available, do manual single to double conversion. | 3914 // VFP is not available, do manual single to double conversion. |
| 3910 | 3915 |
| 3911 // r2: floating point value (binary32) | 3916 // r2: floating point value (binary32) |
| 3912 // r3: heap number for result | 3917 // r3: heap number for result |
| 3913 | 3918 |
| 3914 // Extract mantissa to r0. OK to clobber r0 now as there are no jumps to | 3919 // Extract mantissa to r0. OK to clobber r0 now as there are no jumps to |
| 3915 // the slow case from here. | 3920 // the slow case from here. |
| 3916 __ and_(r0, value, Operand(kBinary32MantissaMask)); | 3921 __ and_(r0, value, Operand(kBinary32MantissaMask)); |
| 3917 | 3922 |
| 3918 // Extract exponent to r1. OK to clobber r1 now as there are no jumps to | 3923 // Extract exponent to r1. OK to clobber r1 now as there are no jumps to |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3954 __ mov(r0, r3); | 3959 __ mov(r0, r3); |
| 3955 __ Ret(); | 3960 __ Ret(); |
| 3956 } | 3961 } |
| 3957 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3962 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 3958 if (CpuFeatures::IsSupported(VFP2)) { | 3963 if (CpuFeatures::IsSupported(VFP2)) { |
| 3959 CpuFeatures::Scope scope(VFP2); | 3964 CpuFeatures::Scope scope(VFP2); |
| 3960 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3965 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3961 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3966 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3962 // exhausted young space. | 3967 // exhausted young space. |
| 3963 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3968 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3964 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); | 3969 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT); |
| 3965 __ sub(r1, r2, Operand(kHeapObjectTag)); | 3970 __ vstr(d0, r2, HeapNumber::kValueOffset); |
| 3966 __ vstr(d0, r1, HeapNumber::kValueOffset); | |
| 3967 | 3971 |
| 3968 __ mov(r0, r2); | 3972 __ add(r0, r2, Operand(kHeapObjectTag)); |
| 3969 __ Ret(); | 3973 __ Ret(); |
| 3970 } else { | 3974 } else { |
| 3971 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3975 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3972 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3976 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3973 // exhausted young space. | 3977 // exhausted young space. |
| 3974 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex); | 3978 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex); |
| 3975 __ AllocateHeapNumber(r4, r5, r6, r7, &slow); | 3979 __ AllocateHeapNumber(r4, r5, r6, r7, &slow, TAG_RESULT); |
| 3976 | 3980 |
| 3977 __ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); | 3981 __ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); |
| 3978 __ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset)); | 3982 __ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset)); |
| 3979 __ mov(r0, r4); | 3983 __ mov(r0, r4); |
| 3980 __ Ret(); | 3984 __ Ret(); |
| 3981 } | 3985 } |
| 3982 | 3986 |
| 3983 } else { | 3987 } else { |
| 3984 // Tag integer as smi and return it. | 3988 // Tag integer as smi and return it. |
| 3985 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3989 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4432 __ add(indexed_double_offset, elements_reg, | 4436 __ add(indexed_double_offset, elements_reg, |
| 4433 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); | 4437 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); |
| 4434 uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32); | 4438 uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32); |
| 4435 __ ldr(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset)); | 4439 __ ldr(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset)); |
| 4436 __ cmp(scratch, Operand(kHoleNanUpper32)); | 4440 __ cmp(scratch, Operand(kHoleNanUpper32)); |
| 4437 __ b(&miss_force_generic, eq); | 4441 __ b(&miss_force_generic, eq); |
| 4438 | 4442 |
| 4439 // Non-NaN. Allocate a new heap number and copy the double value into it. | 4443 // Non-NaN. Allocate a new heap number and copy the double value into it. |
| 4440 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 4444 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| 4441 __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3, | 4445 __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3, |
| 4442 heap_number_map, &slow_allocate_heapnumber); | 4446 heap_number_map, &slow_allocate_heapnumber, TAG_RESULT); |
| 4443 | 4447 |
| 4444 // Don't need to reload the upper 32 bits of the double, it's already in | 4448 // Don't need to reload the upper 32 bits of the double, it's already in |
| 4445 // scratch. | 4449 // scratch. |
| 4446 __ str(scratch, FieldMemOperand(heap_number_reg, | 4450 __ str(scratch, FieldMemOperand(heap_number_reg, |
| 4447 HeapNumber::kExponentOffset)); | 4451 HeapNumber::kExponentOffset)); |
| 4448 __ ldr(scratch, FieldMemOperand(indexed_double_offset, | 4452 __ ldr(scratch, FieldMemOperand(indexed_double_offset, |
| 4449 FixedArray::kHeaderSize)); | 4453 FixedArray::kHeaderSize)); |
| 4450 __ str(scratch, FieldMemOperand(heap_number_reg, | 4454 __ str(scratch, FieldMemOperand(heap_number_reg, |
| 4451 HeapNumber::kMantissaOffset)); | 4455 HeapNumber::kMantissaOffset)); |
| 4452 | 4456 |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4774 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4778 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
| 4775 } | 4779 } |
| 4776 } | 4780 } |
| 4777 | 4781 |
| 4778 | 4782 |
| 4779 #undef __ | 4783 #undef __ |
| 4780 | 4784 |
| 4781 } } // namespace v8::internal | 4785 } } // namespace v8::internal |
| 4782 | 4786 |
| 4783 #endif // V8_TARGET_ARCH_ARM | 4787 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |