| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #if V8_TARGET_ARCH_ARM | 39 #if V8_TARGET_ARCH_ARM |
| 40 | 40 |
| 41 #include "src/arm/assembler-arm-inl.h" | 41 #include "src/arm/assembler-arm-inl.h" |
| 42 #include "src/macro-assembler.h" | 42 #include "src/macro-assembler.h" |
| 43 #include "src/serialize.h" | 43 #include "src/serialize.h" |
| 44 | 44 |
| 45 namespace v8 { | 45 namespace v8 { |
| 46 namespace internal { | 46 namespace internal { |
| 47 | 47 |
| 48 // Get the CPU features enabled by the build. For cross compilation the | 48 // Get the CPU features enabled by the build. For cross compilation the |
| 49 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS | 49 // preprocessor symbols CAN_USE_ARMV8_INSTRUCTIONS, CAN_USE_ARMV7_INSTRUCTIONS |
| 50 // can be defined to enable ARMv7 and VFPv3 instructions when building the | 50 // and CAN_USE_VFP3_INSTRUCTIONS can be defined to enable ARMv8, ARMv7 and VFPv3 |
| 51 // snapshot. | 51 // instructions when building the snapshot. |
| 52 static unsigned CpuFeaturesImpliedByCompiler() { | 52 static unsigned CpuFeaturesImpliedByCompiler() { |
| 53 unsigned answer = 0; | 53 unsigned answer = 0; |
| 54 #ifdef CAN_USE_ARMV8_INSTRUCTIONS |
| 55 if (FLAG_enable_armv8) answer |= 1u << ARMv8; |
| 56 #endif // CAN_USE_ARMV8_INSTRUCTIONS |
| 54 #ifdef CAN_USE_ARMV7_INSTRUCTIONS | 57 #ifdef CAN_USE_ARMV7_INSTRUCTIONS |
| 55 if (FLAG_enable_armv7) answer |= 1u << ARMv7; | 58 if (FLAG_enable_armv7) answer |= 1u << ARMv7; |
| 56 #endif // CAN_USE_ARMV7_INSTRUCTIONS | 59 #endif // CAN_USE_ARMV7_INSTRUCTIONS |
| 57 #ifdef CAN_USE_VFP3_INSTRUCTIONS | 60 #ifdef CAN_USE_VFP3_INSTRUCTIONS |
| 58 if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7; | 61 if (FLAG_enable_vfp3) answer |= 1u << VFP3 | 1u << ARMv7; |
| 59 #endif // CAN_USE_VFP3_INSTRUCTIONS | 62 #endif // CAN_USE_VFP3_INSTRUCTIONS |
| 60 #ifdef CAN_USE_VFP32DREGS | 63 #ifdef CAN_USE_VFP32DREGS |
| 61 if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS; | 64 if (FLAG_enable_32dregs) answer |= 1u << VFP32DREGS; |
| 62 #endif // CAN_USE_VFP32DREGS | 65 #endif // CAN_USE_VFP32DREGS |
| 63 #ifdef CAN_USE_NEON | 66 #ifdef CAN_USE_NEON |
| (...skipping 10 matching lines...) Expand all Loading... |
| 74 void CpuFeatures::ProbeImpl(bool cross_compile) { | 77 void CpuFeatures::ProbeImpl(bool cross_compile) { |
| 75 supported_ |= OS::CpuFeaturesImpliedByPlatform(); | 78 supported_ |= OS::CpuFeaturesImpliedByPlatform(); |
| 76 supported_ |= CpuFeaturesImpliedByCompiler(); | 79 supported_ |= CpuFeaturesImpliedByCompiler(); |
| 77 cache_line_size_ = 64; | 80 cache_line_size_ = 64; |
| 78 | 81 |
| 79 // Only use statically determined features for cross compile (snapshot). | 82 // Only use statically determined features for cross compile (snapshot). |
| 80 if (cross_compile) return; | 83 if (cross_compile) return; |
| 81 | 84 |
| 82 #ifndef __arm__ | 85 #ifndef __arm__ |
| 83 // For the simulator build, use whatever the flags specify. | 86 // For the simulator build, use whatever the flags specify. |
| 84 if (FLAG_enable_armv7) { | 87 if (FLAG_enable_armv7 || FLAG_enable_armv8) { |
| 88 if (FLAG_enable_armv8) supported_ |= 1u << ARMv8; |
| 85 supported_ |= 1u << ARMv7; | 89 supported_ |= 1u << ARMv7; |
| 86 if (FLAG_enable_vfp3) supported_ |= 1u << VFP3; | 90 if (FLAG_enable_vfp3) supported_ |= 1u << VFP3; |
| 87 if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS; | 91 if (FLAG_enable_neon) supported_ |= 1u << NEON | 1u << VFP32DREGS; |
| 88 if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV; | 92 if (FLAG_enable_sudiv) supported_ |= 1u << SUDIV; |
| 89 if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 93 if (FLAG_enable_movw_movt) supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
| 90 if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS; | 94 if (FLAG_enable_32dregs) supported_ |= 1u << VFP32DREGS; |
| 91 } | 95 } |
| 92 if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES; | 96 if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES; |
| 93 | 97 |
| 94 #else // __arm__ | 98 #else // __arm__ |
| 95 // Probe for additional features at runtime. | 99 // Probe for additional features at runtime. |
| 96 CPU cpu; | 100 CPU cpu; |
| 97 if (FLAG_enable_vfp3 && cpu.has_vfp3()) { | 101 if (FLAG_enable_vfp3 && cpu.has_vfp3()) { |
| 98 // This implementation also sets the VFP flags if runtime | 102 // This implementation also sets the VFP flags if runtime |
| 99 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI | 103 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI |
| 100 // 0406B, page A1-6. | 104 // 0406B, page A1-6. |
| 101 supported_ |= 1u << VFP3 | 1u << ARMv7; | 105 supported_ |= 1u << VFP3 | 1u << ARMv7; |
| 102 } | 106 } |
| 103 | 107 |
| 104 if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON; | 108 if (FLAG_enable_neon && cpu.has_neon()) supported_ |= 1u << NEON; |
| 105 if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV; | 109 if (FLAG_enable_sudiv && cpu.has_idiva()) supported_ |= 1u << SUDIV; |
| 106 | 110 |
| 107 if (cpu.architecture() >= 7) { | 111 if (cpu.architecture() >= 7) { |
| 112 if ((cpu.architecture() >= 8) && FLAG_enable_armv8) { |
| 113 supported_ |= 1u << ARMv8; |
| 114 } |
| 108 if (FLAG_enable_armv7) supported_ |= 1u << ARMv7; | 115 if (FLAG_enable_armv7) supported_ |= 1u << ARMv7; |
| 109 if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES; | 116 if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES; |
| 110 // Use movw/movt for QUALCOMM ARMv7 cores. | 117 // Use movw/movt for QUALCOMM ARMv7 cores. |
| 111 if (FLAG_enable_movw_movt && cpu.implementer() == CPU::QUALCOMM) { | 118 if (FLAG_enable_movw_movt && cpu.implementer() == CPU::QUALCOMM) { |
| 112 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; | 119 supported_ |= 1u << MOVW_MOVT_IMMEDIATE_LOADS; |
| 113 } | 120 } |
| 114 } | 121 } |
| 115 | 122 |
| 116 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. | 123 // ARM Cortex-A9 and Cortex-A5 have 32 byte cachelines. |
| 117 if (cpu.implementer() == CPU::ARM && (cpu.part() == CPU::ARM_CORTEX_A5 || | 124 if (cpu.implementer() == CPU::ARM && (cpu.part() == CPU::ARM_CORTEX_A5 || |
| 118 cpu.part() == CPU::ARM_CORTEX_A9)) { | 125 cpu.part() == CPU::ARM_CORTEX_A9)) { |
| 119 cache_line_size_ = 32; | 126 cache_line_size_ = 32; |
| 120 } | 127 } |
| 121 | 128 |
| 122 if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS; | 129 if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS; |
| 123 #endif | 130 #endif |
| 124 | 131 |
| 125 ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7)); | 132 ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7)); |
| 126 } | 133 } |
| 127 | 134 |
| 128 | 135 |
| 129 void CpuFeatures::PrintTarget() { | 136 void CpuFeatures::PrintTarget() { |
| 130 const char* arm_arch = NULL; | 137 const char* arm_arch = NULL; |
| 131 const char* arm_test = ""; | 138 const char* arm_test = ""; |
| 132 const char* arm_fpu = ""; | 139 const char* arm_fpu = ""; |
| 133 const char* arm_thumb = ""; | 140 const char* arm_thumb = ""; |
| 134 const char* arm_float_abi = NULL; | 141 const char* arm_float_abi = NULL; |
| 135 | 142 |
| 136 #if defined CAN_USE_ARMV7_INSTRUCTIONS | 143 #if defined CAN_USE_ARMV8_INSTRUCTIONS |
| 144 arm_arch = "arm v8"; |
| 145 #elif defined CAN_USE_ARMV7_INSTRUCTIONS |
| 137 arm_arch = "arm v7"; | 146 arm_arch = "arm v7"; |
| 138 #else | 147 #else |
| 139 arm_arch = "arm v6"; | 148 arm_arch = "arm v6"; |
| 140 #endif | 149 #endif |
| 141 | 150 |
| 142 #ifdef __arm__ | 151 #ifdef __arm__ |
| 143 | 152 |
| 144 # ifdef ARM_TEST | 153 # ifdef ARM_TEST |
| 145 arm_test = " test"; | 154 arm_test = " test"; |
| 146 # endif | 155 # endif |
| (...skipping 29 matching lines...) Expand all Loading... |
| 176 | 185 |
| 177 #endif // __arm__ | 186 #endif // __arm__ |
| 178 | 187 |
| 179 printf("target%s %s%s%s %s\n", | 188 printf("target%s %s%s%s %s\n", |
| 180 arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi); | 189 arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi); |
| 181 } | 190 } |
| 182 | 191 |
| 183 | 192 |
| 184 void CpuFeatures::PrintFeatures() { | 193 void CpuFeatures::PrintFeatures() { |
| 185 printf( | 194 printf( |
| 186 "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d " | 195 "ARMv8=%d ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d " |
| 187 "MOVW_MOVT_IMMEDIATE_LOADS=%d", | 196 "UNALIGNED_ACCESSES=%d MOVW_MOVT_IMMEDIATE_LOADS=%d", |
| 197 CpuFeatures::IsSupported(ARMv8), |
| 188 CpuFeatures::IsSupported(ARMv7), | 198 CpuFeatures::IsSupported(ARMv7), |
| 189 CpuFeatures::IsSupported(VFP3), | 199 CpuFeatures::IsSupported(VFP3), |
| 190 CpuFeatures::IsSupported(VFP32DREGS), | 200 CpuFeatures::IsSupported(VFP32DREGS), |
| 191 CpuFeatures::IsSupported(NEON), | 201 CpuFeatures::IsSupported(NEON), |
| 192 CpuFeatures::IsSupported(SUDIV), | 202 CpuFeatures::IsSupported(SUDIV), |
| 193 CpuFeatures::IsSupported(UNALIGNED_ACCESSES), | 203 CpuFeatures::IsSupported(UNALIGNED_ACCESSES), |
| 194 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); | 204 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); |
| 195 #ifdef __arm__ | 205 #ifdef __arm__ |
| 196 bool eabi_hardfloat = OS::ArmUsingHardFloat(); | 206 bool eabi_hardfloat = OS::ArmUsingHardFloat(); |
| 197 #elif USE_EABI_HARDFLOAT | 207 #elif USE_EABI_HARDFLOAT |
| (...skipping 2555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2753 int vd, d; | 2763 int vd, d; |
| 2754 dst.split_code(&vd, &d); | 2764 dst.split_code(&vd, &d); |
| 2755 int imm5 = 32 - fraction_bits; | 2765 int imm5 = 32 - fraction_bits; |
| 2756 int i = imm5 & 1; | 2766 int i = imm5 & 1; |
| 2757 int imm4 = (imm5 >> 1) & 0xf; | 2767 int imm4 = (imm5 >> 1) & 0xf; |
| 2758 emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 | | 2768 emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 | |
| 2759 vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4); | 2769 vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4); |
| 2760 } | 2770 } |
| 2761 | 2771 |
| 2762 | 2772 |
| 2773 static Instr AArch32EncodeVCVT(const SwVfpRegister dst, |
| 2774 const DwVfpRegister src, |
| 2775 VCVTDataType data_type, |
| 2776 VCVTRoundingMode rounding_mode) { |
| 2777 int vd, d; |
| 2778 dst.split_code(&vd, &d); |
| 2779 int vm, m; |
| 2780 src.split_code(&vm, &m); |
| 2781 return |
| 2782 0xFU*B28 | 0x1D*B23 | d*B22 | 0x3*B20 | 0x3*B18 | rounding_mode*B16 | |
| 2783 vd*B12 | 0x5*B9 | B8 | data_type*B7 | B6 | m*B5 | vm; |
| 2784 } |
| 2785 |
| 2786 |
| 2787 void Assembler::vcvta_s32_f64(const SwVfpRegister dst, |
| 2788 const DwVfpRegister src) { |
| 2789 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2790 emit(AArch32EncodeVCVT(dst, src, kVcvtSigned, kVcvtTiesToAway)); |
| 2791 } |
| 2792 |
| 2793 |
| 2794 void Assembler::vcvta_u32_f64(const SwVfpRegister dst, |
| 2795 const DwVfpRegister src) { |
| 2796 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2797 emit(AArch32EncodeVCVT(dst, src, kVcvtUnsigned, kVcvtTiesToAway)); |
| 2798 } |
| 2799 |
| 2800 |
| 2801 void Assembler::vcvtm_s32_f64(const SwVfpRegister dst, |
| 2802 const DwVfpRegister src) { |
| 2803 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2804 emit(AArch32EncodeVCVT(dst, src, kVcvtSigned, kVcvtTowardMinusInfinity)); |
| 2805 } |
| 2806 |
| 2807 |
| 2808 void Assembler::vcvtm_u32_f64(const SwVfpRegister dst, |
| 2809 const DwVfpRegister src) { |
| 2810 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2811 emit(AArch32EncodeVCVT(dst, src, kVcvtUnsigned, kVcvtTowardMinusInfinity)); |
| 2812 } |
| 2813 |
| 2814 |
| 2815 void Assembler::vcvtn_s32_f64(const SwVfpRegister dst, |
| 2816 const DwVfpRegister src) { |
| 2817 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2818 emit(AArch32EncodeVCVT(dst, src, kVcvtSigned, kVcvtTiesToEven)); |
| 2819 } |
| 2820 |
| 2821 |
| 2822 void Assembler::vcvtn_u32_f64(const SwVfpRegister dst, |
| 2823 const DwVfpRegister src) { |
| 2824 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2825 emit(AArch32EncodeVCVT(dst, src, kVcvtUnsigned, kVcvtTiesToEven)); |
| 2826 } |
| 2827 |
| 2828 |
| 2829 void Assembler::vcvtp_s32_f64(const SwVfpRegister dst, |
| 2830 const DwVfpRegister src) { |
| 2831 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2832 emit(AArch32EncodeVCVT(dst, src, kVcvtSigned, kVcvtTowardPlusInfinity)); |
| 2833 } |
| 2834 |
| 2835 |
| 2836 void Assembler::vcvtp_u32_f64(const SwVfpRegister dst, |
| 2837 const DwVfpRegister src) { |
| 2838 ASSERT(CpuFeatures::IsSupported(ARMv8)); |
| 2839 emit(AArch32EncodeVCVT(dst, src, kVcvtUnsigned, kVcvtTowardPlusInfinity)); |
| 2840 } |
| 2841 |
| 2842 |
| 2763 void Assembler::vneg(const DwVfpRegister dst, | 2843 void Assembler::vneg(const DwVfpRegister dst, |
| 2764 const DwVfpRegister src, | 2844 const DwVfpRegister src, |
| 2765 const Condition cond) { | 2845 const Condition cond) { |
| 2766 // Instruction details available in ARM DDI 0406C.b, A8-968. | 2846 // Instruction details available in ARM DDI 0406C.b, A8-968. |
| 2767 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | | 2847 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
| 2768 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2848 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2769 int vd, d; | 2849 int vd, d; |
| 2770 dst.split_code(&vd, &d); | 2850 dst.split_code(&vd, &d); |
| 2771 int vm, m; | 2851 int vm, m; |
| 2772 src.split_code(&vm, &m); | 2852 src.split_code(&vm, &m); |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3662 ASSERT((index_64bit == count_of_64bit_) && | 3742 ASSERT((index_64bit == count_of_64bit_) && |
| 3663 (index_code_ptr == (index_64bit + count_of_code_ptr_)) && | 3743 (index_code_ptr == (index_64bit + count_of_code_ptr_)) && |
| 3664 (index_heap_ptr == (index_code_ptr + count_of_heap_ptr_)) && | 3744 (index_heap_ptr == (index_code_ptr + count_of_heap_ptr_)) && |
| 3665 (index_32bit == (index_heap_ptr + count_of_32bit_))); | 3745 (index_32bit == (index_heap_ptr + count_of_32bit_))); |
| 3666 } | 3746 } |
| 3667 | 3747 |
| 3668 | 3748 |
| 3669 } } // namespace v8::internal | 3749 } } // namespace v8::internal |
| 3670 | 3750 |
| 3671 #endif // V8_TARGET_ARCH_ARM | 3751 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |