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" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
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/constants_arm.h" | 9 #include "vm/constants_arm.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 Register reg; | 26 Register reg; |
27 ic_data_load_end_ = | 27 ic_data_load_end_ = |
28 InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, | 28 InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, |
29 ®, | 29 ®, |
30 &target_code_pool_index_); | 30 &target_code_pool_index_); |
31 ASSERT(reg == CODE_REG); | 31 ASSERT(reg == CODE_REG); |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 int CallPattern::DeoptCallPatternLengthInInstructions() { | |
36 const ARMVersion version = TargetCPUFeatures::arm_version(); | |
37 if ((version == ARMv5TE) || (version == ARMv6)) { | |
38 return 5; | |
39 } else { | |
40 ASSERT(version == ARMv7); | |
41 return 3; | |
42 } | |
43 } | |
44 | |
45 int CallPattern::DeoptCallPatternLengthInBytes() { | |
46 return DeoptCallPatternLengthInInstructions() * Instr::kInstrSize; | |
47 } | |
48 | |
49 | |
50 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) | 35 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) |
51 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), | 36 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
52 end_(pc), | 37 end_(pc), |
53 native_function_pool_index_(-1), | 38 native_function_pool_index_(-1), |
54 target_code_pool_index_(-1) { | 39 target_code_pool_index_(-1) { |
55 ASSERT(code.ContainsInstructionAt(pc)); | 40 ASSERT(code.ContainsInstructionAt(pc)); |
56 // Last instruction: blx lr. | 41 // Last instruction: blx lr. |
57 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); | 42 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); |
58 | 43 |
59 Register reg; | 44 Register reg; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 return reinterpret_cast<RawCode*>( | 242 return reinterpret_cast<RawCode*>( |
258 object_pool_.ObjectAt(target_code_pool_index_)); | 243 object_pool_.ObjectAt(target_code_pool_index_)); |
259 } | 244 } |
260 | 245 |
261 | 246 |
262 void CallPattern::SetTargetCode(const Code& target_code) const { | 247 void CallPattern::SetTargetCode(const Code& target_code) const { |
263 object_pool_.SetObjectAt(target_code_pool_index_, target_code); | 248 object_pool_.SetObjectAt(target_code_pool_index_, target_code); |
264 } | 249 } |
265 | 250 |
266 | 251 |
267 void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) { | |
268 const ARMVersion version = TargetCPUFeatures::arm_version(); | |
269 if ((version == ARMv5TE) || (version == ARMv6)) { | |
270 const uint32_t byte0 = (target_address & 0x000000ff); | |
271 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; | |
272 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; | |
273 const uint32_t byte3 = (target_address & 0xff000000) >> 24; | |
274 | |
275 const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) | |
276 const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) | |
277 const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) | |
278 const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 | |
279 const uword blx_ip = 0xe12fff3c; | |
280 | |
281 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = mov_ip; | |
282 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = or1_ip; | |
283 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = or2_ip; | |
284 *reinterpret_cast<uword*>(pc + (3 * Instr::kInstrSize)) = or3_ip; | |
285 *reinterpret_cast<uword*>(pc + (4 * Instr::kInstrSize)) = blx_ip; | |
286 | |
287 ASSERT(DeoptCallPatternLengthInBytes() == 5 * Instr::kInstrSize); | |
288 CPU::FlushICache(pc, DeoptCallPatternLengthInBytes()); | |
289 } else { | |
290 ASSERT(version == ARMv7); | |
291 const uint16_t target_lo = target_address & 0xffff; | |
292 const uint16_t target_hi = target_address >> 16; | |
293 | |
294 const uword movw_ip = | |
295 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); | |
296 const uword movt_ip = | |
297 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); | |
298 const uword blx_ip = 0xe12fff3c; | |
299 | |
300 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = movw_ip; | |
301 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip; | |
302 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip; | |
303 | |
304 ASSERT(DeoptCallPatternLengthInBytes() == 3 * Instr::kInstrSize); | |
305 CPU::FlushICache(pc, DeoptCallPatternLengthInBytes()); | |
306 } | |
307 } | |
308 | |
309 | |
310 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) | 252 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) |
311 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), | 253 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
312 data_pool_index_(-1), | 254 data_pool_index_(-1), |
313 target_pool_index_(-1) { | 255 target_pool_index_(-1) { |
314 ASSERT(code.ContainsInstructionAt(pc)); | 256 ASSERT(code.ContainsInstructionAt(pc)); |
315 // Last instruction: blx lr. | 257 // Last instruction: blx lr. |
316 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e); | 258 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e); |
317 | 259 |
318 Register reg; | 260 Register reg; |
319 uword stub_load_end = | 261 uword stub_load_end = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 } else { | 312 } else { |
371 ASSERT(version == ARMv7); | 313 ASSERT(version == ARMv7); |
372 return bx_lr->InstructionBits() == instruction; | 314 return bx_lr->InstructionBits() == instruction; |
373 } | 315 } |
374 return false; | 316 return false; |
375 } | 317 } |
376 | 318 |
377 } // namespace dart | 319 } // namespace dart |
378 | 320 |
379 #endif // defined TARGET_ARCH_ARM | 321 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |