OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3510 break; | 3510 break; |
3511 case kExternalFloatArray: | 3511 case kExternalFloatArray: |
3512 if (CpuFeatures::IsSupported(VFP3)) { | 3512 if (CpuFeatures::IsSupported(VFP3)) { |
3513 CpuFeatures::Scope scope(VFP3); | 3513 CpuFeatures::Scope scope(VFP3); |
3514 __ add(r2, r3, Operand(key, LSL, 1)); | 3514 __ add(r2, r3, Operand(key, LSL, 1)); |
3515 __ vldr(s0, r2, 0); | 3515 __ vldr(s0, r2, 0); |
3516 } else { | 3516 } else { |
3517 __ ldr(value, MemOperand(r3, key, LSL, 1)); | 3517 __ ldr(value, MemOperand(r3, key, LSL, 1)); |
3518 } | 3518 } |
3519 break; | 3519 break; |
| 3520 case kExternalDoubleArray: |
| 3521 if (CpuFeatures::IsSupported(VFP3)) { |
| 3522 CpuFeatures::Scope scope(VFP3); |
| 3523 __ add(r2, r3, Operand(key, LSL, 2)); |
| 3524 __ vldr(d0, r2, 0); |
| 3525 } else { |
| 3526 __ add(r4, r3, Operand(key, LSL, 2)); |
| 3527 // r4: pointer to the beginning of the double we want to load. |
| 3528 __ ldr(r2, MemOperand(r4, 0)); |
| 3529 __ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); |
| 3530 } |
| 3531 break; |
3520 default: | 3532 default: |
3521 UNREACHABLE(); | 3533 UNREACHABLE(); |
3522 break; | 3534 break; |
3523 } | 3535 } |
3524 | 3536 |
3525 // For integer array types: | 3537 // For integer array types: |
3526 // r2: value | 3538 // r2: value |
3527 // For floating-point array type | 3539 // For float array type: |
3528 // s0: value (if VFP3 is supported) | 3540 // s0: value (if VFP3 is supported) |
3529 // r2: value (if VFP3 is not supported) | 3541 // r2: value (if VFP3 is not supported) |
| 3542 // For double array type: |
| 3543 // d0: value (if VFP3 is supported) |
| 3544 // r2/r3: value (if VFP3 is not supported) |
3530 | 3545 |
3531 if (array_type == kExternalIntArray) { | 3546 if (array_type == kExternalIntArray) { |
3532 // For the Int and UnsignedInt array types, we need to see whether | 3547 // For the Int and UnsignedInt array types, we need to see whether |
3533 // the value can be represented in a Smi. If not, we need to convert | 3548 // the value can be represented in a Smi. If not, we need to convert |
3534 // it to a HeapNumber. | 3549 // it to a HeapNumber. |
3535 Label box_int; | 3550 Label box_int; |
3536 __ cmp(value, Operand(0xC0000000)); | 3551 __ cmp(value, Operand(0xC0000000)); |
3537 __ b(mi, &box_int); | 3552 __ b(mi, &box_int); |
3538 // Tag integer as smi and return it. | 3553 // Tag integer as smi and return it. |
3539 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3554 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3687 | 3702 |
3688 __ orr(r2, r2, Operand(r0, LSR, kMantissaShiftForHiWord)); | 3703 __ orr(r2, r2, Operand(r0, LSR, kMantissaShiftForHiWord)); |
3689 __ mov(r0, Operand(r0, LSL, kMantissaShiftForLoWord)); | 3704 __ mov(r0, Operand(r0, LSL, kMantissaShiftForLoWord)); |
3690 | 3705 |
3691 __ str(r2, FieldMemOperand(r3, HeapNumber::kExponentOffset)); | 3706 __ str(r2, FieldMemOperand(r3, HeapNumber::kExponentOffset)); |
3692 __ str(r0, FieldMemOperand(r3, HeapNumber::kMantissaOffset)); | 3707 __ str(r0, FieldMemOperand(r3, HeapNumber::kMantissaOffset)); |
3693 | 3708 |
3694 __ mov(r0, r3); | 3709 __ mov(r0, r3); |
3695 __ Ret(); | 3710 __ Ret(); |
3696 } | 3711 } |
| 3712 } else if (array_type == kExternalDoubleArray) { |
| 3713 if (CpuFeatures::IsSupported(VFP3)) { |
| 3714 CpuFeatures::Scope scope(VFP3); |
| 3715 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3716 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3717 // exhausted young space. |
| 3718 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 3719 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); |
| 3720 __ sub(r1, r2, Operand(kHeapObjectTag)); |
| 3721 __ vstr(d0, r1, HeapNumber::kValueOffset); |
| 3722 |
| 3723 __ mov(r0, r2); |
| 3724 __ Ret(); |
| 3725 } else { |
| 3726 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
| 3727 // AllocateHeapNumber clobbers all registers - also when jumping due to |
| 3728 // exhausted young space. |
| 3729 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex); |
| 3730 __ AllocateHeapNumber(r4, r5, r6, r7, &slow); |
| 3731 |
| 3732 __ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); |
| 3733 __ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset)); |
| 3734 __ mov(r0, r4); |
| 3735 __ Ret(); |
| 3736 } |
3697 | 3737 |
3698 } else { | 3738 } else { |
3699 // Tag integer as smi and return it. | 3739 // Tag integer as smi and return it. |
3700 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3740 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
3701 __ Ret(); | 3741 __ Ret(); |
3702 } | 3742 } |
3703 | 3743 |
3704 // Slow case, key and receiver still in r0 and r1. | 3744 // Slow case, key and receiver still in r0 and r1. |
3705 __ bind(&slow); | 3745 __ bind(&slow); |
3706 __ IncrementCounter( | 3746 __ IncrementCounter( |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3790 __ strh(r5, MemOperand(r3, r4, LSL, 1)); | 3830 __ strh(r5, MemOperand(r3, r4, LSL, 1)); |
3791 break; | 3831 break; |
3792 case kExternalIntArray: | 3832 case kExternalIntArray: |
3793 case kExternalUnsignedIntArray: | 3833 case kExternalUnsignedIntArray: |
3794 __ str(r5, MemOperand(r3, r4, LSL, 2)); | 3834 __ str(r5, MemOperand(r3, r4, LSL, 2)); |
3795 break; | 3835 break; |
3796 case kExternalFloatArray: | 3836 case kExternalFloatArray: |
3797 // Perform int-to-float conversion and store to memory. | 3837 // Perform int-to-float conversion and store to memory. |
3798 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9); | 3838 StoreIntAsFloat(masm(), r3, r4, r5, r6, r7, r9); |
3799 break; | 3839 break; |
| 3840 case kExternalDoubleArray: |
| 3841 __ add(r3, r3, Operand(r4, LSL, 3)); |
| 3842 // r3: effective address of the double element |
| 3843 FloatingPointHelper::Destination destination; |
| 3844 if (CpuFeatures::IsSupported(VFP3)) { |
| 3845 destination = FloatingPointHelper::kVFPRegisters; |
| 3846 } else { |
| 3847 destination = FloatingPointHelper::kCoreRegisters; |
| 3848 } |
| 3849 FloatingPointHelper::ConvertIntToDouble( |
| 3850 masm(), r5, destination, |
| 3851 d0, r6, r7, // These are: double_dst, dst1, dst2. |
| 3852 r4, s2); // These are: scratch2, single_scratch. |
| 3853 if (destination == FloatingPointHelper::kVFPRegisters) { |
| 3854 CpuFeatures::Scope scope(VFP3); |
| 3855 __ vstr(d0, r3, 0); |
| 3856 } else { |
| 3857 __ str(r6, MemOperand(r3, 0)); |
| 3858 __ str(r7, MemOperand(r3, Register::kSizeInBytes)); |
| 3859 } |
| 3860 break; |
3800 default: | 3861 default: |
3801 UNREACHABLE(); | 3862 UNREACHABLE(); |
3802 break; | 3863 break; |
3803 } | 3864 } |
3804 | 3865 |
3805 // Entry registers are intact, r0 holds the value which is the return value. | 3866 // Entry registers are intact, r0 holds the value which is the return value. |
3806 __ Ret(); | 3867 __ Ret(); |
3807 | 3868 |
3808 if (array_type != kExternalPixelArray) { | 3869 if (array_type != kExternalPixelArray) { |
3809 // r3: external array. | 3870 // r3: external array. |
(...skipping 14 matching lines...) Expand all Loading... |
3824 CpuFeatures::Scope scope(VFP3); | 3885 CpuFeatures::Scope scope(VFP3); |
3825 | 3886 |
3826 if (array_type == kExternalFloatArray) { | 3887 if (array_type == kExternalFloatArray) { |
3827 // vldr requires offset to be a multiple of 4 so we can not | 3888 // vldr requires offset to be a multiple of 4 so we can not |
3828 // include -kHeapObjectTag into it. | 3889 // include -kHeapObjectTag into it. |
3829 __ sub(r5, r0, Operand(kHeapObjectTag)); | 3890 __ sub(r5, r0, Operand(kHeapObjectTag)); |
3830 __ vldr(d0, r5, HeapNumber::kValueOffset); | 3891 __ vldr(d0, r5, HeapNumber::kValueOffset); |
3831 __ add(r5, r3, Operand(r4, LSL, 2)); | 3892 __ add(r5, r3, Operand(r4, LSL, 2)); |
3832 __ vcvt_f32_f64(s0, d0); | 3893 __ vcvt_f32_f64(s0, d0); |
3833 __ vstr(s0, r5, 0); | 3894 __ vstr(s0, r5, 0); |
| 3895 } else if (array_type == kExternalDoubleArray) { |
| 3896 __ sub(r5, r0, Operand(kHeapObjectTag)); |
| 3897 __ vldr(d0, r5, HeapNumber::kValueOffset); |
| 3898 __ add(r5, r3, Operand(r4, LSL, 3)); |
| 3899 __ vstr(d0, r5, 0); |
3834 } else { | 3900 } else { |
3835 // Need to perform float-to-int conversion. | 3901 // Need to perform float-to-int conversion. |
3836 // Test for NaN or infinity (both give zero). | 3902 // Test for NaN or infinity (both give zero). |
3837 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset)); | 3903 __ ldr(r6, FieldMemOperand(value, HeapNumber::kExponentOffset)); |
3838 | 3904 |
3839 // Hoisted load. vldr requires offset to be a multiple of 4 so we can | 3905 // Hoisted load. vldr requires offset to be a multiple of 4 so we can |
3840 // not include -kHeapObjectTag into it. | 3906 // not include -kHeapObjectTag into it. |
3841 __ sub(r5, value, Operand(kHeapObjectTag)); | 3907 __ sub(r5, value, Operand(kHeapObjectTag)); |
3842 __ vldr(d0, r5, HeapNumber::kValueOffset); | 3908 __ vldr(d0, r5, HeapNumber::kValueOffset); |
3843 | 3909 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3926 // value. | 3992 // value. |
3927 __ Ret(); | 3993 __ Ret(); |
3928 | 3994 |
3929 __ bind(&nan_or_infinity_or_zero); | 3995 __ bind(&nan_or_infinity_or_zero); |
3930 __ and_(r7, r5, Operand(HeapNumber::kSignMask)); | 3996 __ and_(r7, r5, Operand(HeapNumber::kSignMask)); |
3931 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); | 3997 __ and_(r5, r5, Operand(HeapNumber::kMantissaMask)); |
3932 __ orr(r9, r9, r7); | 3998 __ orr(r9, r9, r7); |
3933 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); | 3999 __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); |
3934 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); | 4000 __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); |
3935 __ b(&done); | 4001 __ b(&done); |
| 4002 } else if (array_type == kExternalDoubleArray) { |
| 4003 __ add(r7, r3, Operand(r4, LSL, 3)); |
| 4004 // r7: effective address of destination element. |
| 4005 __ str(r6, MemOperand(r7, 0)); |
| 4006 __ str(r5, MemOperand(r7, Register::kSizeInBytes)); |
| 4007 __ Ret(); |
3936 } else { | 4008 } else { |
3937 bool is_signed_type = IsElementTypeSigned(array_type); | 4009 bool is_signed_type = IsElementTypeSigned(array_type); |
3938 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; | 4010 int meaningfull_bits = is_signed_type ? (kBitsPerInt - 1) : kBitsPerInt; |
3939 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; | 4011 int32_t min_value = is_signed_type ? 0x80000000 : 0x00000000; |
3940 | 4012 |
3941 Label done, sign; | 4013 Label done, sign; |
3942 | 4014 |
3943 // Test for all special exponent values: zeros, subnormal numbers, NaNs | 4015 // Test for all special exponent values: zeros, subnormal numbers, NaNs |
3944 // and infinities. All these should be converted to 0. | 4016 // and infinities. All these should be converted to 0. |
3945 __ mov(r7, Operand(HeapNumber::kExponentMask)); | 4017 __ mov(r7, Operand(HeapNumber::kExponentMask)); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4025 | 4097 |
4026 return GetCode(flags); | 4098 return GetCode(flags); |
4027 } | 4099 } |
4028 | 4100 |
4029 | 4101 |
4030 #undef __ | 4102 #undef __ |
4031 | 4103 |
4032 } } // namespace v8::internal | 4104 } } // namespace v8::internal |
4033 | 4105 |
4034 #endif // V8_TARGET_ARCH_ARM | 4106 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |