| 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/simulator.h" | 9 #include "vm/simulator.h" |
| 10 #include "vm/runtime_entry.h" | 10 #include "vm/runtime_entry.h" |
| (...skipping 1206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1217 | 1217 |
| 1218 void Assembler::Drop(intptr_t stack_elements) { | 1218 void Assembler::Drop(intptr_t stack_elements) { |
| 1219 ASSERT(stack_elements >= 0); | 1219 ASSERT(stack_elements >= 0); |
| 1220 if (stack_elements > 0) { | 1220 if (stack_elements > 0) { |
| 1221 AddImmediate(SP, SP, stack_elements * kWordSize); | 1221 AddImmediate(SP, SP, stack_elements * kWordSize); |
| 1222 } | 1222 } |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 | 1225 |
| 1226 // Uses a code sequence that can easily be decoded. | 1226 // Uses a code sequence that can easily be decoded. |
| 1227 void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) { | 1227 void Assembler::LoadWordFromPoolOffset(Register rd, |
| 1228 int32_t offset, |
| 1229 Condition cond) { |
| 1228 ASSERT(rd != PP); | 1230 ASSERT(rd != PP); |
| 1229 int32_t offset_mask = 0; | 1231 int32_t offset_mask = 0; |
| 1230 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { | 1232 if (Address::CanHoldLoadOffset(kLoadWord, offset, &offset_mask)) { |
| 1231 ldr(rd, Address(PP, offset)); | 1233 ldr(rd, Address(PP, offset), cond); |
| 1232 } else { | 1234 } else { |
| 1233 int32_t offset_hi = offset & ~offset_mask; // signed | 1235 int32_t offset_hi = offset & ~offset_mask; // signed |
| 1234 uint32_t offset_lo = offset & offset_mask; // unsigned | 1236 uint32_t offset_lo = offset & offset_mask; // unsigned |
| 1235 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). | 1237 // Inline a simplified version of AddImmediate(rd, PP, offset_hi). |
| 1236 ShifterOperand shifter_op; | 1238 ShifterOperand shifter_op; |
| 1237 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { | 1239 if (ShifterOperand::CanHold(offset_hi, &shifter_op)) { |
| 1238 add(rd, PP, shifter_op); | 1240 add(rd, PP, shifter_op, cond); |
| 1239 } else { | 1241 } else { |
| 1240 movw(rd, Utils::Low16Bits(offset_hi)); | 1242 movw(rd, Utils::Low16Bits(offset_hi)); |
| 1241 const uint16_t value_high = Utils::High16Bits(offset_hi); | 1243 const uint16_t value_high = Utils::High16Bits(offset_hi); |
| 1242 if (value_high != 0) { | 1244 if (value_high != 0) { |
| 1243 movt(rd, value_high); | 1245 movt(rd, value_high, cond); |
| 1244 } | 1246 } |
| 1245 add(rd, PP, ShifterOperand(LR)); | 1247 add(rd, PP, ShifterOperand(LR), cond); |
| 1246 } | 1248 } |
| 1247 ldr(rd, Address(rd, offset_lo)); | 1249 ldr(rd, Address(rd, offset_lo), cond); |
| 1248 } | 1250 } |
| 1249 } | 1251 } |
| 1250 | 1252 |
| 1251 | 1253 |
| 1252 void Assembler::LoadPoolPointer() { | 1254 void Assembler::LoadPoolPointer() { |
| 1253 const intptr_t object_pool_pc_dist = | 1255 const intptr_t object_pool_pc_dist = |
| 1254 Instructions::HeaderSize() - Instructions::object_pool_offset() + | 1256 Instructions::HeaderSize() - Instructions::object_pool_offset() + |
| 1255 CodeSize() + Instr::kPCReadOffset; | 1257 CodeSize() + Instr::kPCReadOffset; |
| 1256 LoadFromOffset(kLoadWord, PP, PC, -object_pool_pc_dist); | 1258 LoadFromOffset(kLoadWord, PP, PC, -object_pool_pc_dist); |
| 1257 } | 1259 } |
| 1258 | 1260 |
| 1259 | 1261 |
| 1260 void Assembler::LoadObject(Register rd, const Object& object) { | 1262 void Assembler::LoadObject(Register rd, const Object& object, Condition cond) { |
| 1261 // Smis and VM heap objects are never relocated; do not use object pool. | 1263 // Smis and VM heap objects are never relocated; do not use object pool. |
| 1262 if (object.IsSmi()) { | 1264 if (object.IsSmi()) { |
| 1263 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw())); | 1265 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); |
| 1264 } else if (object.InVMHeap()) { | 1266 } else if (object.InVMHeap()) { |
| 1265 // Make sure that class CallPattern is able to decode this load immediate. | 1267 // Make sure that class CallPattern is able to decode this load immediate. |
| 1266 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); | 1268 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); |
| 1267 movw(rd, Utils::Low16Bits(object_raw)); | 1269 movw(rd, Utils::Low16Bits(object_raw), cond); |
| 1268 const uint16_t value_high = Utils::High16Bits(object_raw); | 1270 const uint16_t value_high = Utils::High16Bits(object_raw); |
| 1269 if (value_high != 0) { | 1271 if (value_high != 0) { |
| 1270 movt(rd, value_high); | 1272 movt(rd, value_high, cond); |
| 1271 } | 1273 } |
| 1272 } else { | 1274 } else { |
| 1273 // Make sure that class CallPattern is able to decode this load from the | 1275 // Make sure that class CallPattern is able to decode this load from the |
| 1274 // object pool. | 1276 // object pool. |
| 1275 const int32_t offset = | 1277 const int32_t offset = |
| 1276 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; | 1278 Array::data_offset() + 4*AddObject(object) - kHeapObjectTag; |
| 1277 LoadWordFromPoolOffset(rd, offset); | 1279 LoadWordFromPoolOffset(rd, offset, cond); |
| 1278 } | 1280 } |
| 1279 } | 1281 } |
| 1280 | 1282 |
| 1281 | 1283 |
| 1282 void Assembler::PushObject(const Object& object) { | 1284 void Assembler::PushObject(const Object& object) { |
| 1283 LoadObject(IP, object); | 1285 LoadObject(IP, object); |
| 1284 Push(IP); | 1286 Push(IP); |
| 1285 } | 1287 } |
| 1286 | 1288 |
| 1287 | 1289 |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2114 | 2116 |
| 2115 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 2117 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 2116 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 2118 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 2117 return fpu_reg_names[reg]; | 2119 return fpu_reg_names[reg]; |
| 2118 } | 2120 } |
| 2119 | 2121 |
| 2120 } // namespace dart | 2122 } // namespace dart |
| 2121 | 2123 |
| 2122 #endif // defined TARGET_ARCH_ARM | 2124 #endif // defined TARGET_ARCH_ARM |
| 2123 | 2125 |
| OLD | NEW |