| 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 | 9 #include "vm/simulator.h" |
| 10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. | 14 // TODO(regis): Enable this flag after PrintStopMessage stub is implemented. |
| 15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); | 15 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
| 16 | 16 |
| 17 | 17 |
| 18 bool CPUFeatures::integer_division_supported_ = false; |
| 19 #if defined(DEBUG) |
| 20 bool CPUFeatures::initialized_ = false; |
| 21 #endif |
| 22 |
| 23 |
| 24 bool CPUFeatures::integer_division_supported() { |
| 25 DEBUG_ASSERT(initialized_); |
| 26 return integer_division_supported_; |
| 27 } |
| 28 |
| 29 |
| 30 #if defined(USING_SIMULATOR) |
| 31 void CPUFeatures::set_integer_division_supported(bool supported) { |
| 32 integer_division_supported_ = supported; |
| 33 } |
| 34 #endif |
| 35 |
| 36 |
| 37 #define __ assembler. |
| 38 |
| 39 void CPUFeatures::InitOnce() { |
| 40 #if defined(USING_SIMULATOR) |
| 41 integer_division_supported_ = true; |
| 42 #else |
| 43 Assembler assembler; |
| 44 __ mrc(R0, 15, 0, 0, 2, 0); |
| 45 __ Lsr(R0, R0, 24); |
| 46 __ and_(R0, R0, ShifterOperand(0xf)); |
| 47 __ Ret(); |
| 48 |
| 49 const Code& code = |
| 50 Code::Handle(Code::FinalizeCode("DetectCPUFeatures", &assembler)); |
| 51 Instructions& instructions = Instructions::Handle(code.instructions()); |
| 52 typedef int32_t (*DetectCPUFeatures)(); |
| 53 int32_t features = |
| 54 reinterpret_cast<DetectCPUFeatures>(instructions.EntryPoint())(); |
| 55 integer_division_supported_ = features != 0; |
| 56 #endif // defined(USING_SIMULATOR) |
| 57 #if defined(DEBUG) |
| 58 initialized_ = true; |
| 59 #endif |
| 60 } |
| 61 |
| 62 #undef __ |
| 63 |
| 64 |
| 18 // Instruction encoding bits. | 65 // Instruction encoding bits. |
| 19 enum { | 66 enum { |
| 20 H = 1 << 5, // halfword (or byte) | 67 H = 1 << 5, // halfword (or byte) |
| 21 L = 1 << 20, // load (or store) | 68 L = 1 << 20, // load (or store) |
| 22 S = 1 << 20, // set condition code (or leave unchanged) | 69 S = 1 << 20, // set condition code (or leave unchanged) |
| 23 W = 1 << 21, // writeback base register (or leave unchanged) | 70 W = 1 << 21, // writeback base register (or leave unchanged) |
| 24 A = 1 << 21, // accumulate in multiply instruction (or not) | 71 A = 1 << 21, // accumulate in multiply instruction (or not) |
| 25 B = 1 << 22, // unsigned byte (or word) | 72 B = 1 << 22, // unsigned byte (or word) |
| 26 D = 1 << 22, // high/lo bit of start of s/d register range | 73 D = 1 << 22, // high/lo bit of start of s/d register range |
| 27 N = 1 << 22, // long (or short) | 74 N = 1 << 22, // long (or short) |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 void Assembler::blx(Register rm, Condition cond) { | 1156 void Assembler::blx(Register rm, Condition cond) { |
| 1110 ASSERT(rm != kNoRegister); | 1157 ASSERT(rm != kNoRegister); |
| 1111 ASSERT(cond != kNoCondition); | 1158 ASSERT(cond != kNoCondition); |
| 1112 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | | 1159 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 1113 B24 | B21 | (0xfff << 8) | B5 | B4 | | 1160 B24 | B21 | (0xfff << 8) | B5 | B4 | |
| 1114 (static_cast<int32_t>(rm) << kRmShift); | 1161 (static_cast<int32_t>(rm) << kRmShift); |
| 1115 Emit(encoding); | 1162 Emit(encoding); |
| 1116 } | 1163 } |
| 1117 | 1164 |
| 1118 | 1165 |
| 1166 void Assembler::mrc(Register rd, int32_t coproc, int32_t opc1, |
| 1167 int32_t crn, int32_t crm, int32_t opc2, Condition cond) { |
| 1168 ASSERT(rd != kNoRegister); |
| 1169 ASSERT(cond != kNoCondition); |
| 1170 |
| 1171 // This is all the simulator and disassembler know about. |
| 1172 ASSERT(coproc == 15); |
| 1173 ASSERT(opc1 == 0); |
| 1174 ASSERT(crn == 0); |
| 1175 ASSERT(crm == 2); |
| 1176 ASSERT(opc2 == 0); |
| 1177 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | |
| 1178 B27 | B26 | B25 | B20 | B4 | |
| 1179 ((opc1 & 0x7) << kOpc1Shift) | |
| 1180 ((crn & 0xf) << kCRnShift) | |
| 1181 ((coproc & 0xf) << kCoprocShift) | |
| 1182 ((opc2 & 0x7) << kOpc2Shift) | |
| 1183 ((crm & 0xf) << kCRmShift) | |
| 1184 (static_cast<int32_t>(rd) << kRdShift); |
| 1185 Emit(encoding); |
| 1186 } |
| 1187 |
| 1188 |
| 1119 void Assembler::MarkExceptionHandler(Label* label) { | 1189 void Assembler::MarkExceptionHandler(Label* label) { |
| 1120 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); | 1190 EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); |
| 1121 Label l; | 1191 Label l; |
| 1122 b(&l); | 1192 b(&l); |
| 1123 EmitBranch(AL, label, false); | 1193 EmitBranch(AL, label, false); |
| 1124 Bind(&l); | 1194 Bind(&l); |
| 1125 } | 1195 } |
| 1126 | 1196 |
| 1127 | 1197 |
| 1128 void Assembler::LoadObject(Register rd, const Object& object) { | 1198 void Assembler::LoadObject(Register rd, const Object& object) { |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 // Do not reuse an existing entry, since each reference may be patched | 1803 // Do not reuse an existing entry, since each reference may be patched |
| 1734 // independently. | 1804 // independently. |
| 1735 object_pool_.Add(smi); | 1805 object_pool_.Add(smi); |
| 1736 return object_pool_.Length() - 1; | 1806 return object_pool_.Length() - 1; |
| 1737 } | 1807 } |
| 1738 | 1808 |
| 1739 } // namespace dart | 1809 } // namespace dart |
| 1740 | 1810 |
| 1741 #endif // defined TARGET_ARCH_ARM | 1811 #endif // defined TARGET_ARCH_ARM |
| 1742 | 1812 |
| OLD | NEW |