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 |