| 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 |