| 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 |