Chromium Code Reviews| 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 // An extra check since we are assuming the existence of /proc/cpuinfo below. | |
| 9 #if !defined(__linux__) | |
| 10 #error ARM cross-compile only supported on Linux | |
| 11 #endif | |
|
regis
2013/05/07 17:14:35
Shoudn't it be
#if !defined(USING_SIMULATOR) && !
zra
2013/05/07 17:50:18
Done.
| |
| 12 | |
| 8 #include "vm/assembler.h" | 13 #include "vm/assembler.h" |
| 9 #include "vm/simulator.h" | 14 #include "vm/simulator.h" |
| 10 #include "vm/runtime_entry.h" | 15 #include "vm/runtime_entry.h" |
| 11 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 12 | 17 |
| 13 namespace dart { | 18 namespace dart { |
| 14 | 19 |
| 15 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); | 20 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| 16 | 21 |
| 17 | 22 |
| 18 bool CPUFeatures::integer_division_supported_ = false; | 23 bool CPUFeatures::integer_division_supported_ = false; |
| 19 #if defined(DEBUG) | 24 #if defined(DEBUG) |
| 20 bool CPUFeatures::initialized_ = false; | 25 bool CPUFeatures::initialized_ = false; |
| 21 #endif | 26 #endif |
| 22 | 27 |
| 23 | 28 |
| 24 bool CPUFeatures::integer_division_supported() { | 29 bool CPUFeatures::integer_division_supported() { |
| 25 DEBUG_ASSERT(initialized_); | 30 DEBUG_ASSERT(initialized_); |
| 26 return integer_division_supported_; | 31 return integer_division_supported_; |
| 27 } | 32 } |
| 28 | 33 |
| 29 | 34 |
| 35 // If we are using the simulator, allow tests to enable/disable support for | |
| 36 // integer division. | |
| 30 #if defined(USING_SIMULATOR) | 37 #if defined(USING_SIMULATOR) |
| 31 void CPUFeatures::set_integer_division_supported(bool supported) { | 38 void CPUFeatures::set_integer_division_supported(bool supported) { |
| 32 integer_division_supported_ = supported; | 39 integer_division_supported_ = supported; |
| 33 } | 40 } |
| 34 #endif | 41 #endif |
| 35 | 42 |
| 36 | 43 |
| 37 #define __ assembler. | 44 // Probe /proc/cpuinfo for features of the ARM processor. |
| 45 #if !defined(USING_SIMULATOR) | |
| 46 static bool CPUInfoContainsString(const char* search_string) { | |
| 47 const char* file_name = "/proc/cpuinfo"; | |
| 48 // This is written as a straight shot one pass parser | |
| 49 // and not using STL string and ifstream because, | |
| 50 // on Linux, it's reading from a (non-mmap-able) | |
| 51 // character special device. | |
| 52 FILE* f = NULL; | |
| 53 const char* what = search_string; | |
| 54 | |
| 55 if (NULL == (f = fopen(file_name, "r"))) | |
| 56 return false; | |
| 57 | |
| 58 int k; | |
| 59 while (EOF != (k = fgetc(f))) { | |
| 60 if (k == *what) { | |
| 61 ++what; | |
| 62 while ((*what != '\0') && (*what == fgetc(f))) { | |
| 63 ++what; | |
| 64 } | |
| 65 if (*what == '\0') { | |
| 66 fclose(f); | |
| 67 return true; | |
| 68 } else { | |
| 69 what = search_string; | |
| 70 } | |
| 71 } | |
| 72 } | |
| 73 fclose(f); | |
| 74 | |
| 75 // Did not find string in the proc file. | |
| 76 return false; | |
| 77 } | |
| 78 #endif | |
| 38 | 79 |
| 39 void CPUFeatures::InitOnce() { | 80 void CPUFeatures::InitOnce() { |
| 40 #if defined(USING_SIMULATOR) | 81 #if defined(USING_SIMULATOR) |
| 41 integer_division_supported_ = true; | 82 integer_division_supported_ = true; |
| 42 #else | 83 #else |
| 43 integer_division_supported_ = false; | 84 ASSERT(CPUInfoContainsString("ARMv7")); // Implements ARMv7. |
| 85 ASSERT(CPUInfoContainsString("vfp")); // Has floating point unit. | |
| 86 // Has integer division. | |
| 87 integer_division_supported_ = CPUInfoContainsString("idiva"); | |
| 44 #endif // defined(USING_SIMULATOR) | 88 #endif // defined(USING_SIMULATOR) |
| 45 #if defined(DEBUG) | 89 #if defined(DEBUG) |
| 46 initialized_ = true; | 90 initialized_ = true; |
| 47 #endif | 91 #endif |
| 48 } | 92 } |
| 49 | 93 |
| 50 #undef __ | |
| 51 | |
| 52 | 94 |
| 53 // Instruction encoding bits. | 95 // Instruction encoding bits. |
| 54 enum { | 96 enum { |
| 55 H = 1 << 5, // halfword (or byte) | 97 H = 1 << 5, // halfword (or byte) |
| 56 L = 1 << 20, // load (or store) | 98 L = 1 << 20, // load (or store) |
| 57 S = 1 << 20, // set condition code (or leave unchanged) | 99 S = 1 << 20, // set condition code (or leave unchanged) |
| 58 W = 1 << 21, // writeback base register (or leave unchanged) | 100 W = 1 << 21, // writeback base register (or leave unchanged) |
| 59 A = 1 << 21, // accumulate in multiply instruction (or not) | 101 A = 1 << 21, // accumulate in multiply instruction (or not) |
| 60 B = 1 << 22, // unsigned byte (or word) | 102 B = 1 << 22, // unsigned byte (or word) |
| 61 D = 1 << 22, // high/lo bit of start of s/d register range | 103 D = 1 << 22, // high/lo bit of start of s/d register range |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 88 B24 = 1 << 24, | 130 B24 = 1 << 24, |
| 89 B25 = 1 << 25, | 131 B25 = 1 << 25, |
| 90 B26 = 1 << 26, | 132 B26 = 1 << 26, |
| 91 B27 = 1 << 27, | 133 B27 = 1 << 27, |
| 92 | 134 |
| 93 // ldrex/strex register field encodings. | 135 // ldrex/strex register field encodings. |
| 94 kLdExRnShift = 16, | 136 kLdExRnShift = 16, |
| 95 kLdExRtShift = 12, | 137 kLdExRtShift = 12, |
| 96 kStrExRnShift = 16, | 138 kStrExRnShift = 16, |
| 97 kStrExRdShift = 12, | 139 kStrExRdShift = 12, |
| 98 kStrExRtShift = 0, | 140 kStrExRtShift = 0, |
|
regis
2013/05/07 17:14:35
Unrelated to your change, but these ldrex/strex re
zra
2013/05/07 17:50:18
Done.
| |
| 99 }; | 141 }; |
| 100 | 142 |
| 101 | 143 |
| 102 uint32_t Address::encoding3() const { | 144 uint32_t Address::encoding3() const { |
| 103 if (kind_ == Immediate) { | 145 if (kind_ == Immediate) { |
| 104 uint32_t offset = encoding_ & kOffset12Mask; | 146 uint32_t offset = encoding_ & kOffset12Mask; |
| 105 ASSERT(offset < 256); | 147 ASSERT(offset < 256); |
| 106 return (encoding_ & ~kOffset12Mask) | B22 | | 148 return (encoding_ & ~kOffset12Mask) | B22 | |
| 107 ((offset & 0xf0) << 4) | (offset & 0xf); | 149 ((offset & 0xf0) << 4) | (offset & 0xf); |
| 108 } | 150 } |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 | 526 |
| 485 void Assembler::EmitDivOp(Condition cond, int32_t opcode, | 527 void Assembler::EmitDivOp(Condition cond, int32_t opcode, |
| 486 Register rd, Register rn, Register rm) { | 528 Register rd, Register rn, Register rm) { |
| 487 ASSERT(CPUFeatures::integer_division_supported()); | 529 ASSERT(CPUFeatures::integer_division_supported()); |
| 488 ASSERT(rd != kNoRegister); | 530 ASSERT(rd != kNoRegister); |
| 489 ASSERT(rn != kNoRegister); | 531 ASSERT(rn != kNoRegister); |
| 490 ASSERT(rm != kNoRegister); | 532 ASSERT(rm != kNoRegister); |
| 491 ASSERT(cond != kNoCondition); | 533 ASSERT(cond != kNoCondition); |
| 492 int32_t encoding = opcode | | 534 int32_t encoding = opcode | |
| 493 (static_cast<int32_t>(cond) << kConditionShift) | | 535 (static_cast<int32_t>(cond) << kConditionShift) | |
| 494 (static_cast<int32_t>(rn) << kRnShift) | | 536 (static_cast<int32_t>(rn) << kDivRnShift) | |
| 495 (static_cast<int32_t>(rd) << kRdShift) | | 537 (static_cast<int32_t>(rd) << kDivRdShift) | |
| 496 B26 | B25 | B24 | B20 | B4 | | 538 B26 | B25 | B24 | B20 | B4 | |
| 497 (static_cast<int32_t>(rm) << kRmShift); | 539 (static_cast<int32_t>(rm) << kDivRmShift); |
| 498 Emit(encoding); | 540 Emit(encoding); |
| 499 } | 541 } |
| 500 | 542 |
| 501 | 543 |
| 502 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { | 544 void Assembler::sdiv(Register rd, Register rn, Register rm, Condition cond) { |
| 503 EmitDivOp(cond, 0, rd, rn, rm); | 545 EmitDivOp(cond, 0, rd, rn, rm); |
| 504 } | 546 } |
| 505 | 547 |
| 506 | 548 |
| 507 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { | 549 void Assembler::udiv(Register rd, Register rn, Register rm, Condition cond) { |
| (...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2128 | 2170 |
| 2129 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2171 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2130 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 2172 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 2131 return fpu_reg_names[reg]; | 2173 return fpu_reg_names[reg]; |
| 2132 } | 2174 } |
| 2133 | 2175 |
| 2134 } // namespace dart | 2176 } // namespace dart |
| 2135 | 2177 |
| 2136 #endif // defined TARGET_ARCH_ARM | 2178 #endif // defined TARGET_ARCH_ARM |
| 2137 | 2179 |
| OLD | NEW |