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 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 // Convert and store int passed in register ival to IEEE 754 single precision | 979 // Convert and store int passed in register ival to IEEE 754 single precision |
980 // floating point value at memory location (dst + 4 * wordoffset) | 980 // floating point value at memory location (dst + 4 * wordoffset) |
981 // If VFP3 is available use it for conversion. | 981 // If VFP3 is available use it for conversion. |
982 static void StoreIntAsFloat(MacroAssembler* masm, | 982 static void StoreIntAsFloat(MacroAssembler* masm, |
983 Register dst, | 983 Register dst, |
984 Register wordoffset, | 984 Register wordoffset, |
985 Register ival, | 985 Register ival, |
986 Register fval, | 986 Register fval, |
987 Register scratch1, | 987 Register scratch1, |
988 Register scratch2) { | 988 Register scratch2) { |
989 if (CpuFeatures::IsSupported(VFP3)) { | 989 if (CpuFeatures::IsSupported(VFP2)) { |
990 CpuFeatures::Scope scope(VFP3); | 990 CpuFeatures::Scope scope(VFP2); |
991 __ vmov(s0, ival); | 991 __ vmov(s0, ival); |
992 __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); | 992 __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); |
993 __ vcvt_f32_s32(s0, s0); | 993 __ vcvt_f32_s32(s0, s0); |
994 __ vstr(s0, scratch1, 0); | 994 __ vstr(s0, scratch1, 0); |
995 } else { | 995 } else { |
996 Label not_special, done; | 996 Label not_special, done; |
997 // Move sign bit from source to destination. This works because the sign | 997 // Move sign bit from source to destination. This works because the sign |
998 // bit in the exponent word of the double has the same position and polarity | 998 // bit in the exponent word of the double has the same position and polarity |
999 // as the 2's complement sign bit in a Smi. | 999 // as the 2's complement sign bit in a Smi. |
1000 ASSERT(kBinary32SignMask == 0x80000000u); | 1000 ASSERT(kBinary32SignMask == 0x80000000u); |
(...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2082 Handle<JSFunction> function, | 2082 Handle<JSFunction> function, |
2083 Handle<String> name) { | 2083 Handle<String> name) { |
2084 // ----------- S t a t e ------------- | 2084 // ----------- S t a t e ------------- |
2085 // -- r2 : function name | 2085 // -- r2 : function name |
2086 // -- lr : return address | 2086 // -- lr : return address |
2087 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 2087 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
2088 // -- ... | 2088 // -- ... |
2089 // -- sp[argc * 4] : receiver | 2089 // -- sp[argc * 4] : receiver |
2090 // ----------------------------------- | 2090 // ----------------------------------- |
2091 | 2091 |
2092 if (!CpuFeatures::IsSupported(VFP3)) { | 2092 if (!CpuFeatures::IsSupported(VFP2)) { |
2093 return Handle<Code>::null(); | 2093 return Handle<Code>::null(); |
2094 } | 2094 } |
2095 | 2095 |
2096 CpuFeatures::Scope scope_vfp3(VFP3); | 2096 CpuFeatures::Scope scope_vfp2(VFP2); |
2097 const int argc = arguments().immediate(); | 2097 const int argc = arguments().immediate(); |
2098 // If the object is not a JSObject or we got an unexpected number of | 2098 // If the object is not a JSObject or we got an unexpected number of |
2099 // arguments, bail out to the regular call. | 2099 // arguments, bail out to the regular call. |
2100 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); | 2100 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); |
2101 | 2101 |
2102 Label miss, slow; | 2102 Label miss, slow; |
2103 GenerateNameCheck(name, &miss); | 2103 GenerateNameCheck(name, &miss); |
2104 | 2104 |
2105 if (cell.is_null()) { | 2105 if (cell.is_null()) { |
2106 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); | 2106 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); |
(...skipping 1440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3547 return false; | 3547 return false; |
3548 } | 3548 } |
3549 | 3549 |
3550 | 3550 |
3551 static void GenerateSmiKeyCheck(MacroAssembler* masm, | 3551 static void GenerateSmiKeyCheck(MacroAssembler* masm, |
3552 Register key, | 3552 Register key, |
3553 Register scratch0, | 3553 Register scratch0, |
3554 Register scratch1, | 3554 Register scratch1, |
3555 DwVfpRegister double_scratch0, | 3555 DwVfpRegister double_scratch0, |
3556 Label* fail) { | 3556 Label* fail) { |
3557 if (CpuFeatures::IsSupported(VFP3)) { | 3557 if (CpuFeatures::IsSupported(VFP2)) { |
3558 CpuFeatures::Scope scope(VFP3); | 3558 CpuFeatures::Scope scope(VFP2); |
3559 Label key_ok; | 3559 Label key_ok; |
3560 // Check for smi or a smi inside a heap number. We convert the heap | 3560 // Check for smi or a smi inside a heap number. We convert the heap |
3561 // number and check if the conversion is exact and fits into the smi | 3561 // number and check if the conversion is exact and fits into the smi |
3562 // range. | 3562 // range. |
3563 __ JumpIfSmi(key, &key_ok); | 3563 __ JumpIfSmi(key, &key_ok); |
3564 __ CheckMap(key, | 3564 __ CheckMap(key, |
3565 scratch0, | 3565 scratch0, |
3566 Heap::kHeapNumberMapRootIndex, | 3566 Heap::kHeapNumberMapRootIndex, |
3567 fail, | 3567 fail, |
3568 DONT_DO_SMI_CHECK); | 3568 DONT_DO_SMI_CHECK); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3634 __ ldrsh(value, MemOperand(r3, key, LSL, 0)); | 3634 __ ldrsh(value, MemOperand(r3, key, LSL, 0)); |
3635 break; | 3635 break; |
3636 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3636 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3637 __ ldrh(value, MemOperand(r3, key, LSL, 0)); | 3637 __ ldrh(value, MemOperand(r3, key, LSL, 0)); |
3638 break; | 3638 break; |
3639 case EXTERNAL_INT_ELEMENTS: | 3639 case EXTERNAL_INT_ELEMENTS: |
3640 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3640 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3641 __ ldr(value, MemOperand(r3, key, LSL, 1)); | 3641 __ ldr(value, MemOperand(r3, key, LSL, 1)); |
3642 break; | 3642 break; |
3643 case EXTERNAL_FLOAT_ELEMENTS: | 3643 case EXTERNAL_FLOAT_ELEMENTS: |
3644 if (CpuFeatures::IsSupported(VFP3)) { | 3644 if (CpuFeatures::IsSupported(VFP2)) { |
3645 CpuFeatures::Scope scope(VFP3); | 3645 CpuFeatures::Scope scope(VFP2); |
3646 __ add(r2, r3, Operand(key, LSL, 1)); | 3646 __ add(r2, r3, Operand(key, LSL, 1)); |
3647 __ vldr(s0, r2, 0); | 3647 __ vldr(s0, r2, 0); |
3648 } else { | 3648 } else { |
3649 __ ldr(value, MemOperand(r3, key, LSL, 1)); | 3649 __ ldr(value, MemOperand(r3, key, LSL, 1)); |
3650 } | 3650 } |
3651 break; | 3651 break; |
3652 case EXTERNAL_DOUBLE_ELEMENTS: | 3652 case EXTERNAL_DOUBLE_ELEMENTS: |
3653 if (CpuFeatures::IsSupported(VFP3)) { | 3653 if (CpuFeatures::IsSupported(VFP2)) { |
3654 CpuFeatures::Scope scope(VFP3); | 3654 CpuFeatures::Scope scope(VFP2); |
3655 __ add(r2, r3, Operand(key, LSL, 2)); | 3655 __ add(r2, r3, Operand(key, LSL, 2)); |
3656 __ vldr(d0, r2, 0); | 3656 __ vldr(d0, r2, 0); |
3657 } else { | 3657 } else { |
3658 __ add(r4, r3, Operand(key, LSL, 2)); | 3658 __ add(r4, r3, Operand(key, LSL, 2)); |
3659 // r4: pointer to the beginning of the double we want to load. | 3659 // r4: pointer to the beginning of the double we want to load. |
3660 __ ldr(r2, MemOperand(r4, 0)); | 3660 __ ldr(r2, MemOperand(r4, 0)); |
3661 __ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); | 3661 __ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); |
3662 } | 3662 } |
3663 break; | 3663 break; |
3664 case FAST_ELEMENTS: | 3664 case FAST_ELEMENTS: |
(...skipping 30 matching lines...) Expand all Loading... |
3695 | 3695 |
3696 __ bind(&box_int); | 3696 __ bind(&box_int); |
3697 // Allocate a HeapNumber for the result and perform int-to-double | 3697 // Allocate a HeapNumber for the result and perform int-to-double |
3698 // conversion. Don't touch r0 or r1 as they are needed if allocation | 3698 // conversion. Don't touch r0 or r1 as they are needed if allocation |
3699 // fails. | 3699 // fails. |
3700 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3700 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
3701 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); | 3701 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); |
3702 // Now we can use r0 for the result as key is not needed any more. | 3702 // Now we can use r0 for the result as key is not needed any more. |
3703 __ mov(r0, r5); | 3703 __ mov(r0, r5); |
3704 | 3704 |
3705 if (CpuFeatures::IsSupported(VFP3)) { | 3705 if (CpuFeatures::IsSupported(VFP2)) { |
3706 CpuFeatures::Scope scope(VFP3); | 3706 CpuFeatures::Scope scope(VFP2); |
3707 __ vmov(s0, value); | 3707 __ vmov(s0, value); |
3708 __ vcvt_f64_s32(d0, s0); | 3708 __ vcvt_f64_s32(d0, s0); |
3709 __ sub(r3, r0, Operand(kHeapObjectTag)); | 3709 __ sub(r3, r0, Operand(kHeapObjectTag)); |
3710 __ vstr(d0, r3, HeapNumber::kValueOffset); | 3710 __ vstr(d0, r3, HeapNumber::kValueOffset); |
3711 __ Ret(); | 3711 __ Ret(); |
3712 } else { | 3712 } else { |
3713 Register dst1 = r1; | 3713 Register dst1 = r1; |
3714 Register dst2 = r3; | 3714 Register dst2 = r3; |
3715 FloatingPointHelper::Destination dest = | 3715 FloatingPointHelper::Destination dest = |
3716 FloatingPointHelper::kCoreRegisters; | 3716 FloatingPointHelper::kCoreRegisters; |
3717 FloatingPointHelper::ConvertIntToDouble(masm, | 3717 FloatingPointHelper::ConvertIntToDouble(masm, |
3718 value, | 3718 value, |
3719 dest, | 3719 dest, |
3720 d0, | 3720 d0, |
3721 dst1, | 3721 dst1, |
3722 dst2, | 3722 dst2, |
3723 r9, | 3723 r9, |
3724 s0); | 3724 s0); |
3725 __ str(dst1, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 3725 __ str(dst1, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
3726 __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 3726 __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
3727 __ Ret(); | 3727 __ Ret(); |
3728 } | 3728 } |
3729 } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 3729 } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
3730 // The test is different for unsigned int values. Since we need | 3730 // The test is different for unsigned int values. Since we need |
3731 // the value to be in the range of a positive smi, we can't | 3731 // the value to be in the range of a positive smi, we can't |
3732 // handle either of the top two bits being set in the value. | 3732 // handle either of the top two bits being set in the value. |
3733 if (CpuFeatures::IsSupported(VFP3)) { | 3733 if (CpuFeatures::IsSupported(VFP2)) { |
3734 CpuFeatures::Scope scope(VFP3); | 3734 CpuFeatures::Scope scope(VFP2); |
3735 Label box_int, done; | 3735 Label box_int, done; |
3736 __ tst(value, Operand(0xC0000000)); | 3736 __ tst(value, Operand(0xC0000000)); |
3737 __ b(ne, &box_int); | 3737 __ b(ne, &box_int); |
3738 // Tag integer as smi and return it. | 3738 // Tag integer as smi and return it. |
3739 __ mov(r0, Operand(value, LSL, kSmiTagSize)); | 3739 __ mov(r0, Operand(value, LSL, kSmiTagSize)); |
3740 __ Ret(); | 3740 __ Ret(); |
3741 | 3741 |
3742 __ bind(&box_int); | 3742 __ bind(&box_int); |
3743 __ vmov(s0, value); | 3743 __ vmov(s0, value); |
3744 // Allocate a HeapNumber for the result and perform int-to-double | 3744 // Allocate a HeapNumber for the result and perform int-to-double |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3787 | 3787 |
3788 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset)); | 3788 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset)); |
3789 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); | 3789 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); |
3790 | 3790 |
3791 __ mov(r0, r4); | 3791 __ mov(r0, r4); |
3792 __ Ret(); | 3792 __ Ret(); |
3793 } | 3793 } |
3794 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 3794 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
3795 // For the floating-point array type, we need to always allocate a | 3795 // For the floating-point array type, we need to always allocate a |
3796 // HeapNumber. | 3796 // HeapNumber. |
3797 if (CpuFeatures::IsSupported(VFP3)) { | 3797 if (CpuFeatures::IsSupported(VFP2)) { |
3798 CpuFeatures::Scope scope(VFP3); | 3798 CpuFeatures::Scope scope(VFP2); |
3799 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3799 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
3800 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3800 // AllocateHeapNumber clobbers all registers - also when jumping due to |
3801 // exhausted young space. | 3801 // exhausted young space. |
3802 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3802 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
3803 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); | 3803 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); |
3804 __ vcvt_f64_f32(d0, s0); | 3804 __ vcvt_f64_f32(d0, s0); |
3805 __ sub(r1, r2, Operand(kHeapObjectTag)); | 3805 __ sub(r1, r2, Operand(kHeapObjectTag)); |
3806 __ vstr(d0, r1, HeapNumber::kValueOffset); | 3806 __ vstr(d0, r1, HeapNumber::kValueOffset); |
3807 | 3807 |
3808 __ mov(r0, r2); | 3808 __ mov(r0, r2); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3855 __ orr(r2, r2, Operand(r0, LSR, kMantissaShiftForHiWord)); | 3855 __ orr(r2, r2, Operand(r0, LSR, kMantissaShiftForHiWord)); |
3856 __ mov(r0, Operand(r0, LSL, kMantissaShiftForLoWord)); | 3856 __ mov(r0, Operand(r0, LSL, kMantissaShiftForLoWord)); |
3857 | 3857 |
3858 __ str(r2, FieldMemOperand(r3, HeapNumber::kExponentOffset)); | 3858 __ str(r2, FieldMemOperand(r3, HeapNumber::kExponentOffset)); |
3859 __ str(r0, FieldMemOperand(r3, HeapNumber::kMantissaOffset)); | 3859 __ str(r0, FieldMemOperand(r3, HeapNumber::kMantissaOffset)); |
3860 | 3860 |
3861 __ mov(r0, r3); | 3861 __ mov(r0, r3); |
3862 __ Ret(); | 3862 __ Ret(); |
3863 } | 3863 } |
3864 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3864 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3865 if (CpuFeatures::IsSupported(VFP3)) { | 3865 if (CpuFeatures::IsSupported(VFP2)) { |
3866 CpuFeatures::Scope scope(VFP3); | 3866 CpuFeatures::Scope scope(VFP2); |
3867 // Allocate a HeapNumber for the result. Don't use r0 and r1 as | 3867 // Allocate a HeapNumber for the result. Don't use r0 and r1 as |
3868 // AllocateHeapNumber clobbers all registers - also when jumping due to | 3868 // AllocateHeapNumber clobbers all registers - also when jumping due to |
3869 // exhausted young space. | 3869 // exhausted young space. |
3870 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 3870 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
3871 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); | 3871 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); |
3872 __ sub(r1, r2, Operand(kHeapObjectTag)); | 3872 __ sub(r1, r2, Operand(kHeapObjectTag)); |
3873 __ vstr(d0, r1, HeapNumber::kValueOffset); | 3873 __ vstr(d0, r1, HeapNumber::kValueOffset); |
3874 | 3874 |
3875 __ mov(r0, r2); | 3875 __ mov(r0, r2); |
3876 __ Ret(); | 3876 __ Ret(); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3981 break; | 3981 break; |
3982 case EXTERNAL_FLOAT_ELEMENTS: | 3982 case EXTERNAL_FLOAT_ELEMENTS: |
3983 // Perform int-to-float conversion and store to memory. | 3983 // Perform int-to-float conversion and store to memory. |
3984 __ SmiUntag(r4, key); | 3984 __ SmiUntag(r4, key); |
3985 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); | 3985 StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); |
3986 break; | 3986 break; |
3987 case EXTERNAL_DOUBLE_ELEMENTS: | 3987 case EXTERNAL_DOUBLE_ELEMENTS: |
3988 __ add(r3, r3, Operand(key, LSL, 2)); | 3988 __ add(r3, r3, Operand(key, LSL, 2)); |
3989 // r3: effective address of the double element | 3989 // r3: effective address of the double element |
3990 FloatingPointHelper::Destination destination; | 3990 FloatingPointHelper::Destination destination; |
3991 if (CpuFeatures::IsSupported(VFP3)) { | 3991 if (CpuFeatures::IsSupported(VFP2)) { |
3992 destination = FloatingPointHelper::kVFPRegisters; | 3992 destination = FloatingPointHelper::kVFPRegisters; |
3993 } else { | 3993 } else { |
3994 destination = FloatingPointHelper::kCoreRegisters; | 3994 destination = FloatingPointHelper::kCoreRegisters; |
3995 } | 3995 } |
3996 FloatingPointHelper::ConvertIntToDouble( | 3996 FloatingPointHelper::ConvertIntToDouble( |
3997 masm, r5, destination, | 3997 masm, r5, destination, |
3998 d0, r6, r7, // These are: double_dst, dst1, dst2. | 3998 d0, r6, r7, // These are: double_dst, dst1, dst2. |
3999 r4, s2); // These are: scratch2, single_scratch. | 3999 r4, s2); // These are: scratch2, single_scratch. |
4000 if (destination == FloatingPointHelper::kVFPRegisters) { | 4000 if (destination == FloatingPointHelper::kVFPRegisters) { |
4001 CpuFeatures::Scope scope(VFP3); | 4001 CpuFeatures::Scope scope(VFP2); |
4002 __ vstr(d0, r3, 0); | 4002 __ vstr(d0, r3, 0); |
4003 } else { | 4003 } else { |
4004 __ str(r6, MemOperand(r3, 0)); | 4004 __ str(r6, MemOperand(r3, 0)); |
4005 __ str(r7, MemOperand(r3, Register::kSizeInBytes)); | 4005 __ str(r7, MemOperand(r3, Register::kSizeInBytes)); |
4006 } | 4006 } |
4007 break; | 4007 break; |
4008 case FAST_ELEMENTS: | 4008 case FAST_ELEMENTS: |
4009 case FAST_SMI_ELEMENTS: | 4009 case FAST_SMI_ELEMENTS: |
4010 case FAST_DOUBLE_ELEMENTS: | 4010 case FAST_DOUBLE_ELEMENTS: |
4011 case FAST_HOLEY_ELEMENTS: | 4011 case FAST_HOLEY_ELEMENTS: |
(...skipping 14 matching lines...) Expand all Loading... |
4026 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); | 4026 __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); |
4027 __ b(ne, &slow); | 4027 __ b(ne, &slow); |
4028 | 4028 |
4029 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); | 4029 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); |
4030 | 4030 |
4031 // r3: base pointer of external storage. | 4031 // r3: base pointer of external storage. |
4032 | 4032 |
4033 // The WebGL specification leaves the behavior of storing NaN and | 4033 // The WebGL specification leaves the behavior of storing NaN and |
4034 // +/-Infinity into integer arrays basically undefined. For more | 4034 // +/-Infinity into integer arrays basically undefined. For more |
4035 // reproducible behavior, convert these to zero. | 4035 // reproducible behavior, convert these to zero. |
4036 if (CpuFeatures::IsSupported(VFP3)) { | 4036 if (CpuFeatures::IsSupported(VFP2)) { |
4037 CpuFeatures::Scope scope(VFP3); | 4037 CpuFeatures::Scope scope(VFP2); |
4038 | 4038 |
4039 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4039 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
4040 // vldr requires offset to be a multiple of 4 so we can not | 4040 // vldr requires offset to be a multiple of 4 so we can not |
4041 // include -kHeapObjectTag into it. | 4041 // include -kHeapObjectTag into it. |
4042 __ sub(r5, r0, Operand(kHeapObjectTag)); | 4042 __ sub(r5, r0, Operand(kHeapObjectTag)); |
4043 __ vldr(d0, r5, HeapNumber::kValueOffset); | 4043 __ vldr(d0, r5, HeapNumber::kValueOffset); |
4044 __ add(r5, r3, Operand(key, LSL, 1)); | 4044 __ add(r5, r3, Operand(key, LSL, 1)); |
4045 __ vcvt_f32_f64(s0, d0); | 4045 __ vcvt_f32_f64(s0, d0); |
4046 __ vstr(s0, r5, 0); | 4046 __ vstr(s0, r5, 0); |
4047 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4047 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4680 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4680 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4681 } | 4681 } |
4682 } | 4682 } |
4683 | 4683 |
4684 | 4684 |
4685 #undef __ | 4685 #undef __ |
4686 | 4686 |
4687 } } // namespace v8::internal | 4687 } } // namespace v8::internal |
4688 | 4688 |
4689 #endif // V8_TARGET_ARCH_ARM | 4689 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |