| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/longjump.h" | 10 #include "vm/longjump.h" |
| 10 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
| 11 #include "vm/simulator.h" | 12 #include "vm/simulator.h" |
| 12 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
| 13 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
| 14 | 15 |
| 15 // An extra check since we are assuming the existence of /proc/cpuinfo below. | 16 // An extra check since we are assuming the existence of /proc/cpuinfo below. |
| 16 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) | 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) |
| 17 #error ARM cross-compile only supported on Linux | 18 #error ARM cross-compile only supported on Linux |
| 18 #endif | 19 #endif |
| 19 | 20 |
| 20 namespace dart { | 21 namespace dart { |
| 21 | 22 |
| 22 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 23 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 23 DECLARE_FLAG(bool, inline_alloc); | 24 DECLARE_FLAG(bool, inline_alloc); |
| 24 | 25 |
| 25 bool CPUFeatures::integer_division_supported_ = false; | |
| 26 bool CPUFeatures::neon_supported_ = false; | |
| 27 #if defined(DEBUG) | |
| 28 bool CPUFeatures::initialized_ = false; | |
| 29 #endif | |
| 30 | |
| 31 | |
| 32 bool CPUFeatures::integer_division_supported() { | |
| 33 DEBUG_ASSERT(initialized_); | |
| 34 return integer_division_supported_; | |
| 35 } | |
| 36 | |
| 37 | |
| 38 bool CPUFeatures::neon_supported() { | |
| 39 DEBUG_ASSERT(initialized_); | |
| 40 return neon_supported_; | |
| 41 } | |
| 42 | |
| 43 | |
| 44 // If we are using the simulator, allow tests to enable/disable support for | |
| 45 // integer division. | |
| 46 #if defined(USING_SIMULATOR) | |
| 47 void CPUFeatures::set_integer_division_supported(bool supported) { | |
| 48 integer_division_supported_ = supported; | |
| 49 } | |
| 50 | |
| 51 | |
| 52 void CPUFeatures::set_neon_supported(bool supported) { | |
| 53 neon_supported_ = supported; | |
| 54 } | |
| 55 #endif | |
| 56 | |
| 57 | |
| 58 // Probe /proc/cpuinfo for features of the ARM processor. | |
| 59 #if !defined(USING_SIMULATOR) | |
| 60 static bool CPUInfoContainsString(const char* search_string) { | |
| 61 const char* file_name = "/proc/cpuinfo"; | |
| 62 // This is written as a straight shot one pass parser | |
| 63 // and not using STL string and ifstream because, | |
| 64 // on Linux, it's reading from a (non-mmap-able) | |
| 65 // character special device. | |
| 66 FILE* f = NULL; | |
| 67 const char* what = search_string; | |
| 68 | |
| 69 if (NULL == (f = fopen(file_name, "r"))) | |
| 70 return false; | |
| 71 | |
| 72 int k; | |
| 73 while (EOF != (k = fgetc(f))) { | |
| 74 if (k == *what) { | |
| 75 ++what; | |
| 76 while ((*what != '\0') && (*what == fgetc(f))) { | |
| 77 ++what; | |
| 78 } | |
| 79 if (*what == '\0') { | |
| 80 fclose(f); | |
| 81 return true; | |
| 82 } else { | |
| 83 what = search_string; | |
| 84 } | |
| 85 } | |
| 86 } | |
| 87 fclose(f); | |
| 88 | |
| 89 // Did not find string in the proc file. | |
| 90 return false; | |
| 91 } | |
| 92 #endif | |
| 93 | |
| 94 | |
| 95 void CPUFeatures::InitOnce() { | |
| 96 #if defined(USING_SIMULATOR) | |
| 97 integer_division_supported_ = true; | |
| 98 neon_supported_ = true; | |
| 99 #else | |
| 100 ASSERT(CPUInfoContainsString("ARMv7")); // Implements ARMv7. | |
| 101 ASSERT(CPUInfoContainsString("vfp")); // Has floating point unit. | |
| 102 // Has integer division. | |
| 103 if (CPUInfoContainsString("QCT APQ8064")) { | |
| 104 // Special case for Qualcomm Krait CPUs in Nexus 4 and 7. | |
| 105 integer_division_supported_ = true; | |
| 106 } else { | |
| 107 integer_division_supported_ = CPUInfoContainsString("idiva"); | |
| 108 } | |
| 109 neon_supported_ = CPUInfoContainsString("neon"); | |
| 110 #endif // defined(USING_SIMULATOR) | |
| 111 #if defined(DEBUG) | |
| 112 initialized_ = true; | |
| 113 #endif | |
| 114 } | |
| 115 | |
| 116 | 26 |
| 117 // Instruction encoding bits. | 27 // Instruction encoding bits. |
| 118 enum { | 28 enum { |
| 119 H = 1 << 5, // halfword (or byte) | 29 H = 1 << 5, // halfword (or byte) |
| 120 L = 1 << 20, // load (or store) | 30 L = 1 << 20, // load (or store) |
| 121 S = 1 << 20, // set condition code (or leave unchanged) | 31 S = 1 << 20, // set condition code (or leave unchanged) |
| 122 W = 1 << 21, // writeback base register (or leave unchanged) | 32 W = 1 << 21, // writeback base register (or leave unchanged) |
| 123 A = 1 << 21, // accumulate in multiply instruction (or not) | 33 A = 1 << 21, // accumulate in multiply instruction (or not) |
| 124 B = 1 << 22, // unsigned byte (or word) | 34 B = 1 << 22, // unsigned byte (or word) |
| 125 D = 1 << 22, // high/lo bit of start of s/d register range | 35 D = 1 << 22, // high/lo bit of start of s/d register range |
| (...skipping 2628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 | 2664 |
| 2755 | 2665 |
| 2756 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2666 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2757 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 2667 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 2758 return fpu_reg_names[reg]; | 2668 return fpu_reg_names[reg]; |
| 2759 } | 2669 } |
| 2760 | 2670 |
| 2761 } // namespace dart | 2671 } // namespace dart |
| 2762 | 2672 |
| 2763 #endif // defined TARGET_ARCH_ARM | 2673 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |