| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/cpuinfo.h" | 10 #include "vm/cpuinfo.h" |
| 11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
| 12 #include "vm/isolate.h" | 12 #include "vm/isolate.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 #include "vm/simulator.h" | 14 #include "vm/simulator.h" |
| 15 | 15 |
| 16 #if defined(HOST_ARCH_ARM) | 16 #if !defined(USING_SIMULATOR) |
| 17 #include <sys/syscall.h> /* NOLINT */ | 17 #include <sys/syscall.h> /* NOLINT */ |
| 18 #include <unistd.h> /* NOLINT */ | 18 #include <unistd.h> /* NOLINT */ |
| 19 #endif | 19 #endif |
| 20 | 20 |
| 21 // ARM version differences. | 21 // ARM version differences. |
| 22 // We support three major 32-bit ARM ISA versions: ARMv5TE, ARMv6 and variants, | 22 // We support three major 32-bit ARM ISA versions: ARMv5TE, ARMv6 and variants, |
| 23 // and ARMv7 and variants. For each of these we detect the presence of vfp, | 23 // and ARMv7 and variants. For each of these we detect the presence of vfp, |
| 24 // neon, and integer division instructions. Considering ARMv5TE as the baseline, | 24 // neon, and integer division instructions. Considering ARMv5TE as the baseline, |
| 25 // later versions add the following features/instructions that we use: | 25 // later versions add the following features/instructions that we use: |
| 26 // | 26 // |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 DEFINE_FLAG(bool, use_neon, false, "Use neon instructions if supported"); | 62 DEFINE_FLAG(bool, use_neon, false, "Use neon instructions if supported"); |
| 63 DEFINE_FLAG(bool, use_integer_division, false, | 63 DEFINE_FLAG(bool, use_integer_division, false, |
| 64 "Use integer division instruction if supported"); | 64 "Use integer division instruction if supported"); |
| 65 #else | 65 #else |
| 66 DEFINE_FLAG(bool, use_vfp, true, "Use vfp instructions if supported"); | 66 DEFINE_FLAG(bool, use_vfp, true, "Use vfp instructions if supported"); |
| 67 DEFINE_FLAG(bool, use_neon, true, "Use neon instructions if supported"); | 67 DEFINE_FLAG(bool, use_neon, true, "Use neon instructions if supported"); |
| 68 DEFINE_FLAG(bool, use_integer_division, true, | 68 DEFINE_FLAG(bool, use_integer_division, true, |
| 69 "Use integer division instruction if supported"); | 69 "Use integer division instruction if supported"); |
| 70 #endif | 70 #endif |
| 71 | 71 |
| 72 #if !defined(HOST_ARCH_ARM) | 72 #if defined(USING_SIMULATOR) |
| 73 #if defined(TARGET_ARCH_ARM_5TE) | 73 #if defined(TARGET_ARCH_ARM_5TE) |
| 74 DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the softfp ABI."); | 74 DEFINE_FLAG(bool, sim_use_hardfp, false, "Use the softfp ABI."); |
| 75 #else | 75 #else |
| 76 DEFINE_FLAG(bool, sim_use_hardfp, true, "Use the softfp ABI."); | 76 DEFINE_FLAG(bool, sim_use_hardfp, true, "Use the softfp ABI."); |
| 77 #endif | 77 #endif |
| 78 #endif | 78 #endif |
| 79 | 79 |
| 80 void CPU::FlushICache(uword start, uword size) { | 80 void CPU::FlushICache(uword start, uword size) { |
| 81 #if defined(HOST_ARCH_ARM) | 81 #if !defined(USING_SIMULATOR) |
| 82 // Nothing to do. Flushing no instructions. | 82 // Nothing to do. Flushing no instructions. |
| 83 if (size == 0) { | 83 if (size == 0) { |
| 84 return; | 84 return; |
| 85 } | 85 } |
| 86 | 86 |
| 87 // ARM recommends using the gcc intrinsic __clear_cache on Linux, and the | 87 // ARM recommends using the gcc intrinsic __clear_cache on Linux, and the |
| 88 // library call cacheflush from unistd.h on Android: | 88 // library call cacheflush from unistd.h on Android: |
| 89 // blogs.arm.com/software-enablement/141-caches-and-self-modifying-code/ | 89 // blogs.arm.com/software-enablement/141-caches-and-self-modifying-code/ |
| 90 #if defined(__linux__) && !defined(ANDROID) | 90 #if defined(__linux__) && !defined(ANDROID) |
| 91 extern void __clear_cache(char*, char*); | 91 extern void __clear_cache(char*, char*); |
| 92 char* beg = reinterpret_cast<char*>(start); | 92 char* beg = reinterpret_cast<char*>(start); |
| 93 char* end = reinterpret_cast<char*>(start + size); | 93 char* end = reinterpret_cast<char*>(start + size); |
| 94 ::__clear_cache(beg, end); | 94 ::__clear_cache(beg, end); |
| 95 #elif defined(ANDROID) | 95 #elif defined(ANDROID) |
| 96 cacheflush(start, start + size, 0); | 96 cacheflush(start, start + size, 0); |
| 97 #else | 97 #else |
| 98 #error FlushICache only tested/supported on Linux and Android | 98 #error FlushICache only tested/supported on Linux and Android |
| 99 #endif | 99 #endif |
| 100 | |
| 101 #endif | 100 #endif |
| 102 } | 101 } |
| 103 | 102 |
| 104 | 103 |
| 105 const char* CPU::Id() { | 104 const char* CPU::Id() { |
| 106 return | 105 return |
| 107 #if !defined(HOST_ARCH_ARM) | 106 #if defined(USING_SIMULATOR) |
| 108 "sim" | 107 "sim" |
| 109 #endif // !defined(HOST_ARCH_ARM) | 108 #endif // defined(USING_SIMULATOR) |
| 110 "arm"; | 109 "arm"; |
| 111 } | 110 } |
| 112 | 111 |
| 113 | 112 |
| 114 bool HostCPUFeatures::integer_division_supported_ = false; | 113 bool HostCPUFeatures::integer_division_supported_ = false; |
| 115 bool HostCPUFeatures::vfp_supported_ = false; | 114 bool HostCPUFeatures::vfp_supported_ = false; |
| 116 bool HostCPUFeatures::neon_supported_ = false; | 115 bool HostCPUFeatures::neon_supported_ = false; |
| 117 bool HostCPUFeatures::hardfp_supported_ = false; | 116 bool HostCPUFeatures::hardfp_supported_ = false; |
| 118 const char* HostCPUFeatures::hardware_ = NULL; | 117 const char* HostCPUFeatures::hardware_ = NULL; |
| 119 ARMVersion HostCPUFeatures::arm_version_ = ARMvUnknown; | 118 ARMVersion HostCPUFeatures::arm_version_ = ARMvUnknown; |
| 120 intptr_t HostCPUFeatures::store_pc_read_offset_ = 8; | 119 intptr_t HostCPUFeatures::store_pc_read_offset_ = 8; |
| 121 #if defined(DEBUG) | 120 #if defined(DEBUG) |
| 122 bool HostCPUFeatures::initialized_ = false; | 121 bool HostCPUFeatures::initialized_ = false; |
| 123 #endif | 122 #endif |
| 124 | 123 |
| 125 | 124 |
| 126 #if defined(HOST_ARCH_ARM) | 125 #if !defined(USING_SIMULATOR) |
| 127 void HostCPUFeatures::InitOnce() { | 126 void HostCPUFeatures::InitOnce() { |
| 128 bool is_arm64 = false; | 127 bool is_arm64 = false; |
| 129 CpuInfo::InitOnce(); | 128 CpuInfo::InitOnce(); |
| 130 hardware_ = CpuInfo::GetCpuModel(); | 129 hardware_ = CpuInfo::GetCpuModel(); |
| 131 | 130 |
| 132 // Check for ARMv5TE, ARMv6, ARMv7, or aarch64. | 131 // Check for ARMv5TE, ARMv6, ARMv7, or aarch64. |
| 133 // It can be in either the Processor or Model information fields. | 132 // It can be in either the Processor or Model information fields. |
| 134 if (CpuInfo::FieldContains(kCpuInfoProcessor, "aarch64") || | 133 if (CpuInfo::FieldContains(kCpuInfoProcessor, "aarch64") || |
| 135 CpuInfo::FieldContains(kCpuInfoModel, "aarch64")) { | 134 CpuInfo::FieldContains(kCpuInfoModel, "aarch64")) { |
| 136 // pretend that this arm64 cpu is really an ARMv7 | 135 // pretend that this arm64 cpu is really an ARMv7 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 void HostCPUFeatures::Cleanup() { | 228 void HostCPUFeatures::Cleanup() { |
| 230 DEBUG_ASSERT(initialized_); | 229 DEBUG_ASSERT(initialized_); |
| 231 #if defined(DEBUG) | 230 #if defined(DEBUG) |
| 232 initialized_ = false; | 231 initialized_ = false; |
| 233 #endif | 232 #endif |
| 234 ASSERT(hardware_ != NULL); | 233 ASSERT(hardware_ != NULL); |
| 235 free(const_cast<char*>(hardware_)); | 234 free(const_cast<char*>(hardware_)); |
| 236 hardware_ = NULL; | 235 hardware_ = NULL; |
| 237 CpuInfo::Cleanup(); | 236 CpuInfo::Cleanup(); |
| 238 } | 237 } |
| 239 #endif // defined(HOST_ARCH_ARM) | 238 #endif // !defined(USING_SIMULATOR) |
| 240 | 239 |
| 241 } // namespace dart | 240 } // namespace dart |
| 242 | 241 |
| 243 #endif // defined TARGET_ARCH_ARM | 242 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |