| 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 17 matching lines...) Expand all Loading... |
| 28 Register reg; | 28 Register reg; |
| 29 ic_data_load_end_ = | 29 ic_data_load_end_ = |
| 30 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, | 30 InstructionPattern::DecodeLoadWordFromPool(end_ - Instr::kInstrSize, |
| 31 ®, | 31 ®, |
| 32 &target_address_pool_index_); | 32 &target_address_pool_index_); |
| 33 ASSERT(reg == LR); | 33 ASSERT(reg == LR); |
| 34 } | 34 } |
| 35 | 35 |
| 36 | 36 |
| 37 int CallPattern::LengthInBytes() { | 37 int CallPattern::LengthInBytes() { |
| 38 if (TargetCPUFeatures::arm_version() == ARMv6) { | 38 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 39 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 39 return 5 * Instr::kInstrSize; | 40 return 5 * Instr::kInstrSize; |
| 40 } else { | 41 } else { |
| 41 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 42 ASSERT(version == ARMv7); |
| 42 return 3 * Instr::kInstrSize; | 43 return 3 * Instr::kInstrSize; |
| 43 } | 44 } |
| 44 } | 45 } |
| 45 | 46 |
| 46 | 47 |
| 47 // Decodes a load sequence ending at 'end' (the last instruction of the load | 48 // Decodes a load sequence ending at 'end' (the last instruction of the load |
| 48 // sequence is the instruction before the one at end). Returns a pointer to | 49 // sequence is the instruction before the one at end). Returns a pointer to |
| 49 // the first instruction in the sequence. Returns the register being loaded | 50 // the first instruction in the sequence. Returns the register being loaded |
| 50 // and the loaded object in the output parameters 'reg' and 'obj' | 51 // and the loaded object in the output parameters 'reg' and 'obj' |
| 51 // respectively. | 52 // respectively. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 73 // sequence is the instruction before the one at end). Returns a pointer to | 74 // sequence is the instruction before the one at end). Returns a pointer to |
| 74 // the first instruction in the sequence. Returns the register being loaded | 75 // the first instruction in the sequence. Returns the register being loaded |
| 75 // and the loaded immediate value in the output parameters 'reg' and 'value' | 76 // and the loaded immediate value in the output parameters 'reg' and 'value' |
| 76 // respectively. | 77 // respectively. |
| 77 uword InstructionPattern::DecodeLoadWordImmediate(uword end, | 78 uword InstructionPattern::DecodeLoadWordImmediate(uword end, |
| 78 Register* reg, | 79 Register* reg, |
| 79 intptr_t* value) { | 80 intptr_t* value) { |
| 80 uword start = end - Instr::kInstrSize; | 81 uword start = end - Instr::kInstrSize; |
| 81 int32_t instr = Instr::At(start)->InstructionBits(); | 82 int32_t instr = Instr::At(start)->InstructionBits(); |
| 82 intptr_t imm = 0; | 83 intptr_t imm = 0; |
| 83 if (TargetCPUFeatures::arm_version() == ARMv6) { | 84 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 85 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 84 ASSERT((instr & 0xfff00000) == 0xe3800000); // orr rd, rd, byte0 | 86 ASSERT((instr & 0xfff00000) == 0xe3800000); // orr rd, rd, byte0 |
| 85 imm |= (instr & 0x000000ff); | 87 imm |= (instr & 0x000000ff); |
| 86 | 88 |
| 87 start -= Instr::kInstrSize; | 89 start -= Instr::kInstrSize; |
| 88 instr = Instr::At(start)->InstructionBits(); | 90 instr = Instr::At(start)->InstructionBits(); |
| 89 ASSERT((instr & 0xfff00000) == 0xe3800c00); // orr rd, rd, (byte1 rot 12) | 91 ASSERT((instr & 0xfff00000) == 0xe3800c00); // orr rd, rd, (byte1 rot 12) |
| 90 imm |= (instr & 0x000000ff); | 92 imm |= (instr & 0x000000ff); |
| 91 | 93 |
| 92 start -= Instr::kInstrSize; | 94 start -= Instr::kInstrSize; |
| 93 instr = Instr::At(start)->InstructionBits(); | 95 instr = Instr::At(start)->InstructionBits(); |
| 94 ASSERT((instr & 0xfff00f00) == 0xe3800800); // orr rd, rd, (byte2 rot 8) | 96 ASSERT((instr & 0xfff00f00) == 0xe3800800); // orr rd, rd, (byte2 rot 8) |
| 95 imm |= (instr & 0x000000ff); | 97 imm |= (instr & 0x000000ff); |
| 96 | 98 |
| 97 start -= Instr::kInstrSize; | 99 start -= Instr::kInstrSize; |
| 98 instr = Instr::At(start)->InstructionBits(); | 100 instr = Instr::At(start)->InstructionBits(); |
| 99 ASSERT((instr & 0xffff0f00) == 0xe3a00400); // mov rd, (byte3 rot 4) | 101 ASSERT((instr & 0xffff0f00) == 0xe3a00400); // mov rd, (byte3 rot 4) |
| 100 imm |= (instr & 0x000000ff); | 102 imm |= (instr & 0x000000ff); |
| 101 | 103 |
| 102 *reg = static_cast<Register>((instr & 0x0000f000) >> 12); | 104 *reg = static_cast<Register>((instr & 0x0000f000) >> 12); |
| 103 *value = imm; | 105 *value = imm; |
| 104 } else { | 106 } else { |
| 105 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 107 ASSERT(version == ARMv7); |
| 106 if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, #imm_hi | 108 if ((instr & 0xfff00000) == 0xe3400000) { // movt reg, #imm_hi |
| 107 imm |= (instr & 0xf0000) << 12; | 109 imm |= (instr & 0xf0000) << 12; |
| 108 imm |= (instr & 0xfff) << 16; | 110 imm |= (instr & 0xfff) << 16; |
| 109 start -= Instr::kInstrSize; | 111 start -= Instr::kInstrSize; |
| 110 instr = Instr::At(start)->InstructionBits(); | 112 instr = Instr::At(start)->InstructionBits(); |
| 111 } | 113 } |
| 112 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo | 114 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo |
| 113 imm |= (instr & 0xf0000) >> 4; | 115 imm |= (instr & 0xf0000) >> 4; |
| 114 imm |= instr & 0xfff; | 116 imm |= instr & 0xfff; |
| 115 *reg = static_cast<Register>((instr & 0xf000) >> 12); | 117 *reg = static_cast<Register>((instr & 0xf000) >> 12); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 void CallPattern::SetTargetAddress(uword target_address) const { | 198 void CallPattern::SetTargetAddress(uword target_address) const { |
| 197 ASSERT(Utils::IsAligned(target_address, 4)); | 199 ASSERT(Utils::IsAligned(target_address, 4)); |
| 198 // The address is stored in the object array as a RawSmi. | 200 // The address is stored in the object array as a RawSmi. |
| 199 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); | 201 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); |
| 200 object_pool_.SetAt(target_address_pool_index_, smi); | 202 object_pool_.SetAt(target_address_pool_index_, smi); |
| 201 // No need to flush the instruction cache, since the code is not modified. | 203 // No need to flush the instruction cache, since the code is not modified. |
| 202 } | 204 } |
| 203 | 205 |
| 204 | 206 |
| 205 void CallPattern::InsertAt(uword pc, uword target_address) { | 207 void CallPattern::InsertAt(uword pc, uword target_address) { |
| 206 if (TargetCPUFeatures::arm_version() == ARMv6) { | 208 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 209 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 207 const uint32_t byte0 = (target_address & 0x000000ff); | 210 const uint32_t byte0 = (target_address & 0x000000ff); |
| 208 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; | 211 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; |
| 209 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; | 212 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; |
| 210 const uint32_t byte3 = (target_address & 0xff000000) >> 24; | 213 const uint32_t byte3 = (target_address & 0xff000000) >> 24; |
| 211 | 214 |
| 212 const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) | 215 const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) |
| 213 const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) | 216 const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) |
| 214 const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) | 217 const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) |
| 215 const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 | 218 const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 |
| 216 const uword blx_ip = 0xe12fff3c; | 219 const uword blx_ip = 0xe12fff3c; |
| 217 | 220 |
| 218 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = mov_ip; | 221 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = mov_ip; |
| 219 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = or1_ip; | 222 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = or1_ip; |
| 220 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = or2_ip; | 223 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = or2_ip; |
| 221 *reinterpret_cast<uword*>(pc + (3 * Instr::kInstrSize)) = or3_ip; | 224 *reinterpret_cast<uword*>(pc + (3 * Instr::kInstrSize)) = or3_ip; |
| 222 *reinterpret_cast<uword*>(pc + (4 * Instr::kInstrSize)) = blx_ip; | 225 *reinterpret_cast<uword*>(pc + (4 * Instr::kInstrSize)) = blx_ip; |
| 223 | 226 |
| 224 ASSERT(LengthInBytes() == 5 * Instr::kInstrSize); | 227 ASSERT(LengthInBytes() == 5 * Instr::kInstrSize); |
| 225 CPU::FlushICache(pc, LengthInBytes()); | 228 CPU::FlushICache(pc, LengthInBytes()); |
| 226 } else { | 229 } else { |
| 227 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 230 ASSERT(version == ARMv7); |
| 228 const uint16_t target_lo = target_address & 0xffff; | 231 const uint16_t target_lo = target_address & 0xffff; |
| 229 const uint16_t target_hi = target_address >> 16; | 232 const uint16_t target_hi = target_address >> 16; |
| 230 | 233 |
| 231 const uword movw_ip = | 234 const uword movw_ip = |
| 232 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); | 235 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); |
| 233 const uword movt_ip = | 236 const uword movt_ip = |
| 234 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); | 237 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); |
| 235 const uword blx_ip = 0xe12fff3c; | 238 const uword blx_ip = 0xe12fff3c; |
| 236 | 239 |
| 237 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = movw_ip; | 240 *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = movw_ip; |
| 238 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip; | 241 *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip; |
| 239 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip; | 242 *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip; |
| 240 | 243 |
| 241 ASSERT(LengthInBytes() == 3 * Instr::kInstrSize); | 244 ASSERT(LengthInBytes() == 3 * Instr::kInstrSize); |
| 242 CPU::FlushICache(pc, LengthInBytes()); | 245 CPU::FlushICache(pc, LengthInBytes()); |
| 243 } | 246 } |
| 244 } | 247 } |
| 245 | 248 |
| 246 | 249 |
| 247 JumpPattern::JumpPattern(uword pc, const Code& code) : pc_(pc) { } | 250 JumpPattern::JumpPattern(uword pc, const Code& code) : pc_(pc) { } |
| 248 | 251 |
| 249 | 252 |
| 250 int JumpPattern::pattern_length_in_bytes() { | 253 int JumpPattern::pattern_length_in_bytes() { |
| 251 if (TargetCPUFeatures::arm_version() == ARMv6) { | 254 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 255 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 252 return 5 * Instr::kInstrSize; | 256 return 5 * Instr::kInstrSize; |
| 253 } else { | 257 } else { |
| 254 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 258 ASSERT(version == ARMv7); |
| 255 return 3 * Instr::kInstrSize; | 259 return 3 * Instr::kInstrSize; |
| 256 } | 260 } |
| 257 } | 261 } |
| 258 | 262 |
| 259 | 263 |
| 260 bool JumpPattern::IsValid() const { | 264 bool JumpPattern::IsValid() const { |
| 261 if (TargetCPUFeatures::arm_version() == ARMv6) { | 265 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 266 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 262 Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); | 267 Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); |
| 263 Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); | 268 Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); |
| 264 Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); | 269 Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
| 265 Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); | 270 Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); |
| 266 Instr* bx_ip = Instr::At(pc_ + (4 * Instr::kInstrSize)); | 271 Instr* bx_ip = Instr::At(pc_ + (4 * Instr::kInstrSize)); |
| 267 return ((mov_ip->InstructionBits() & 0xffffff00) == 0xe3a0c400) && | 272 return ((mov_ip->InstructionBits() & 0xffffff00) == 0xe3a0c400) && |
| 268 ((or1_ip->InstructionBits() & 0xffffff00) == 0xe38cc800) && | 273 ((or1_ip->InstructionBits() & 0xffffff00) == 0xe38cc800) && |
| 269 ((or2_ip->InstructionBits() & 0xffffff00) == 0xe38ccc00) && | 274 ((or2_ip->InstructionBits() & 0xffffff00) == 0xe38ccc00) && |
| 270 ((or3_ip->InstructionBits() & 0xffffff00) == 0xe38cc000) && | 275 ((or3_ip->InstructionBits() & 0xffffff00) == 0xe38cc000) && |
| 271 ((bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c); | 276 ((bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c); |
| 272 } else { | 277 } else { |
| 273 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 278 ASSERT(version == ARMv7); |
| 274 Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo | 279 Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo |
| 275 Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi | 280 Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi |
| 276 Instr* bx_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); | 281 Instr* bx_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
| 277 return (movw_ip->InstructionBits() & 0xfff0f000) == 0xe300c000 && | 282 return (movw_ip->InstructionBits() & 0xfff0f000) == 0xe300c000 && |
| 278 (movt_ip->InstructionBits() & 0xfff0f000) == 0xe340c000 && | 283 (movt_ip->InstructionBits() & 0xfff0f000) == 0xe340c000 && |
| 279 (bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c; | 284 (bx_ip->InstructionBits() & 0xffffffff) == 0xe12fff1c; |
| 280 } | 285 } |
| 281 } | 286 } |
| 282 | 287 |
| 283 | 288 |
| 284 uword JumpPattern::TargetAddress() const { | 289 uword JumpPattern::TargetAddress() const { |
| 285 if (TargetCPUFeatures::arm_version() == ARMv6) { | 290 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 291 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 286 Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); | 292 Instr* mov_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); |
| 287 Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); | 293 Instr* or1_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); |
| 288 Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); | 294 Instr* or2_ip = Instr::At(pc_ + (2 * Instr::kInstrSize)); |
| 289 Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); | 295 Instr* or3_ip = Instr::At(pc_ + (3 * Instr::kInstrSize)); |
| 290 uword imm = 0; | 296 uword imm = 0; |
| 291 imm |= or3_ip->Immed8Field(); | 297 imm |= or3_ip->Immed8Field(); |
| 292 imm |= or2_ip->Immed8Field() << 8; | 298 imm |= or2_ip->Immed8Field() << 8; |
| 293 imm |= or1_ip->Immed8Field() << 16; | 299 imm |= or1_ip->Immed8Field() << 16; |
| 294 imm |= mov_ip->Immed8Field() << 24; | 300 imm |= mov_ip->Immed8Field() << 24; |
| 295 return imm; | 301 return imm; |
| 296 } else { | 302 } else { |
| 297 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 303 ASSERT(version == ARMv7); |
| 298 Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo | 304 Instr* movw_ip = Instr::At(pc_ + (0 * Instr::kInstrSize)); // target_lo |
| 299 Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi | 305 Instr* movt_ip = Instr::At(pc_ + (1 * Instr::kInstrSize)); // target_hi |
| 300 uint16_t target_lo = movw_ip->MovwField(); | 306 uint16_t target_lo = movw_ip->MovwField(); |
| 301 uint16_t target_hi = movt_ip->MovwField(); | 307 uint16_t target_hi = movt_ip->MovwField(); |
| 302 return (target_hi << 16) | target_lo; | 308 return (target_hi << 16) | target_lo; |
| 303 } | 309 } |
| 304 } | 310 } |
| 305 | 311 |
| 306 | 312 |
| 307 void JumpPattern::SetTargetAddress(uword target_address) const { | 313 void JumpPattern::SetTargetAddress(uword target_address) const { |
| 308 if (TargetCPUFeatures::arm_version() == ARMv6) { | 314 const ARMVersion version = TargetCPUFeatures::arm_version(); |
| 315 if ((version == ARMv5TE) || (version == ARMv6)) { |
| 309 const uint32_t byte0 = (target_address & 0x000000ff); | 316 const uint32_t byte0 = (target_address & 0x000000ff); |
| 310 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; | 317 const uint32_t byte1 = (target_address & 0x0000ff00) >> 8; |
| 311 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; | 318 const uint32_t byte2 = (target_address & 0x00ff0000) >> 16; |
| 312 const uint32_t byte3 = (target_address & 0xff000000) >> 24; | 319 const uint32_t byte3 = (target_address & 0xff000000) >> 24; |
| 313 | 320 |
| 314 const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) | 321 const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4) |
| 315 const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) | 322 const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8) |
| 316 const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) | 323 const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12) |
| 317 const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 | 324 const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0 |
| 318 | 325 |
| 319 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = mov_ip; | 326 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = mov_ip; |
| 320 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = or1_ip; | 327 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = or1_ip; |
| 321 *reinterpret_cast<uword*>(pc_ + (2 * Instr::kInstrSize)) = or2_ip; | 328 *reinterpret_cast<uword*>(pc_ + (2 * Instr::kInstrSize)) = or2_ip; |
| 322 *reinterpret_cast<uword*>(pc_ + (3 * Instr::kInstrSize)) = or3_ip; | 329 *reinterpret_cast<uword*>(pc_ + (3 * Instr::kInstrSize)) = or3_ip; |
| 323 CPU::FlushICache(pc_, 4 * Instr::kInstrSize); | 330 CPU::FlushICache(pc_, 4 * Instr::kInstrSize); |
| 324 } else { | 331 } else { |
| 325 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); | 332 ASSERT(version == ARMv7); |
| 326 const uint16_t target_lo = target_address & 0xffff; | 333 const uint16_t target_lo = target_address & 0xffff; |
| 327 const uint16_t target_hi = target_address >> 16; | 334 const uint16_t target_hi = target_address >> 16; |
| 328 | 335 |
| 329 const uword movw_ip = | 336 const uword movw_ip = |
| 330 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); | 337 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); |
| 331 const uword movt_ip = | 338 const uword movt_ip = |
| 332 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); | 339 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); |
| 333 | 340 |
| 334 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip; | 341 *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw_ip; |
| 335 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip; | 342 *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt_ip; |
| 336 CPU::FlushICache(pc_, 2 * Instr::kInstrSize); | 343 CPU::FlushICache(pc_, 2 * Instr::kInstrSize); |
| 337 } | 344 } |
| 338 } | 345 } |
| 339 | 346 |
| 340 } // namespace dart | 347 } // namespace dart |
| 341 | 348 |
| 342 #endif // defined TARGET_ARCH_ARM | 349 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |