Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: runtime/vm/instructions_arm64.cc

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/instructions_arm64.h ('k') | runtime/vm/instructions_arm64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/instructions.h" 8 #include "vm/instructions.h"
9 #include "vm/instructions_arm64.h" 9 #include "vm/instructions_arm64.h"
10 10
11 #include "vm/assembler.h" 11 #include "vm/assembler.h"
12 #include "vm/constants_arm64.h" 12 #include "vm/constants_arm64.h"
13 #include "vm/cpu.h" 13 #include "vm/cpu.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 CallPattern::CallPattern(uword pc, const Code& code) 18 CallPattern::CallPattern(uword pc, const Code& code)
19 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 19 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
20 end_(pc), 20 end_(pc),
21 ic_data_load_end_(0), 21 ic_data_load_end_(0),
22 target_code_pool_index_(-1), 22 target_code_pool_index_(-1),
23 ic_data_(ICData::Handle()) { 23 ic_data_(ICData::Handle()) {
24 ASSERT(code.ContainsInstructionAt(pc)); 24 ASSERT(code.ContainsInstructionAt(pc));
25 // Last instruction: blr ip0. 25 // Last instruction: blr ip0.
26 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); 26 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200);
27 27
28 Register reg; 28 Register reg;
29 ic_data_load_end_ = 29 ic_data_load_end_ = InstructionPattern::DecodeLoadWordFromPool(
30 InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, 30 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
31 &reg,
32 &target_code_pool_index_);
33 ASSERT(reg == CODE_REG); 31 ASSERT(reg == CODE_REG);
34 } 32 }
35 33
36 34
37 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) 35 NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
38 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 36 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
39 end_(pc), 37 end_(pc),
40 native_function_pool_index_(-1), 38 native_function_pool_index_(-1),
41 target_code_pool_index_(-1) { 39 target_code_pool_index_(-1) {
42 ASSERT(code.ContainsInstructionAt(pc)); 40 ASSERT(code.ContainsInstructionAt(pc));
43 // Last instruction: blr ip0. 41 // Last instruction: blr ip0.
44 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); 42 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200);
45 43
46 Register reg; 44 Register reg;
47 uword native_function_load_end = 45 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool(
48 InstructionPattern::DecodeLoadWordFromPool(end_ - 2 * Instr::kInstrSize, 46 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
49 &reg,
50 &target_code_pool_index_);
51 ASSERT(reg == CODE_REG); 47 ASSERT(reg == CODE_REG);
52 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, 48 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, &reg,
53 &reg,
54 &native_function_pool_index_); 49 &native_function_pool_index_);
55 ASSERT(reg == R5); 50 ASSERT(reg == R5);
56 } 51 }
57 52
58 53
59 RawCode* NativeCallPattern::target() const { 54 RawCode* NativeCallPattern::target() const {
60 return reinterpret_cast<RawCode*>( 55 return reinterpret_cast<RawCode*>(
61 object_pool_.ObjectAt(target_code_pool_index_)); 56 object_pool_.ObjectAt(target_code_pool_index_));
62 } 57 }
63 58
64 59
65 void NativeCallPattern::set_target(const Code& target) const { 60 void NativeCallPattern::set_target(const Code& target) const {
66 object_pool_.SetObjectAt(target_code_pool_index_, target); 61 object_pool_.SetObjectAt(target_code_pool_index_, target);
67 // No need to flush the instruction cache, since the code is not modified. 62 // No need to flush the instruction cache, since the code is not modified.
68 } 63 }
69 64
70 65
71 NativeFunction NativeCallPattern::native_function() const { 66 NativeFunction NativeCallPattern::native_function() const {
72 return reinterpret_cast<NativeFunction>( 67 return reinterpret_cast<NativeFunction>(
73 object_pool_.RawValueAt(native_function_pool_index_)); 68 object_pool_.RawValueAt(native_function_pool_index_));
74 } 69 }
75 70
76 71
77 void NativeCallPattern::set_native_function(NativeFunction func) const { 72 void NativeCallPattern::set_native_function(NativeFunction func) const {
78 object_pool_.SetRawValueAt(native_function_pool_index_, 73 object_pool_.SetRawValueAt(native_function_pool_index_,
79 reinterpret_cast<uword>(func)); 74 reinterpret_cast<uword>(func));
80 } 75 }
81 76
82 77
83 intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) { 78 intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) {
84 return Array::element_offset(index); 79 return Array::element_offset(index);
85 } 80 }
86 81
87 82
88 // Decodes a load sequence ending at 'end' (the last instruction of the load 83 // Decodes a load sequence ending at 'end' (the last instruction of the load
89 // sequence is the instruction before the one at end). Returns a pointer to 84 // sequence is the instruction before the one at end). Returns a pointer to
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 // or 198 // or
204 // 3. movz dst, low_offset, 0 199 // 3. movz dst, low_offset, 0
205 // movk dst, hi_offset, 1 (optional) 200 // movk dst, hi_offset, 1 (optional)
206 // ldr dst, [pp, dst] 201 // ldr dst, [pp, dst]
207 uword start = end - Instr::kInstrSize; 202 uword start = end - Instr::kInstrSize;
208 Instr* instr = Instr::At(start); 203 Instr* instr = Instr::At(start);
209 intptr_t offset = 0; 204 intptr_t offset = 0;
210 205
211 // Last instruction is always an ldr into a 64-bit X register. 206 // Last instruction is always an ldr into a 64-bit X register.
212 ASSERT(instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) && 207 ASSERT(instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
213 (instr->Bits(30, 2) == 3)); 208 (instr->Bits(30, 2) == 3));
214 209
215 // Grab the destination register from the ldr instruction. 210 // Grab the destination register from the ldr instruction.
216 *reg = instr->RtField(); 211 *reg = instr->RtField();
217 212
218 if (instr->Bit(24) == 1) { 213 if (instr->Bit(24) == 1) {
219 // base + scaled unsigned 12-bit immediate offset. 214 // base + scaled unsigned 12-bit immediate offset.
220 // Case 1. 215 // Case 1.
221 offset |= (instr->Imm12Field() << 3); 216 offset |= (instr->Imm12Field() << 3);
222 if (instr->RnField() == *reg) { 217 if (instr->RnField() == *reg) {
223 start -= Instr::kInstrSize; 218 start -= Instr::kInstrSize;
(...skipping 30 matching lines...) Expand all
254 offset |= instr->Imm16Field(); 249 offset |= instr->Imm16Field();
255 } 250 }
256 } 251 }
257 // PP is untagged on ARM64. 252 // PP is untagged on ARM64.
258 ASSERT(Utils::IsAligned(offset, 8)); 253 ASSERT(Utils::IsAligned(offset, 8));
259 *index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag); 254 *index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
260 return start; 255 return start;
261 } 256 }
262 257
263 258
264 bool DecodeLoadObjectFromPoolOrThread(uword pc, 259 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
265 const Code& code,
266 Object* obj) {
267 ASSERT(code.ContainsInstructionAt(pc)); 260 ASSERT(code.ContainsInstructionAt(pc));
268 261
269 Instr* instr = Instr::At(pc); 262 Instr* instr = Instr::At(pc);
270 if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) && 263 if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
271 (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) { 264 (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) {
272 intptr_t offset = (instr->Imm12Field() << 3); 265 intptr_t offset = (instr->Imm12Field() << 3);
273 if (instr->RnField() == PP) { 266 if (instr->RnField() == PP) {
274 // PP is untagged on ARM64. 267 // PP is untagged on ARM64.
275 ASSERT(Utils::IsAligned(offset, 8)); 268 ASSERT(Utils::IsAligned(offset, 8));
276 intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag); 269 intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
(...skipping 15 matching lines...) Expand all
292 // Encodes a load sequence ending at 'end'. Encodes a fixed length two 285 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
293 // instruction load from the pool pointer in PP using the destination 286 // instruction load from the pool pointer in PP using the destination
294 // register reg as a temporary for the base address. 287 // register reg as a temporary for the base address.
295 // Assumes that the location has already been validated for patching. 288 // Assumes that the location has already been validated for patching.
296 void InstructionPattern::EncodeLoadWordFromPoolFixed(uword end, 289 void InstructionPattern::EncodeLoadWordFromPoolFixed(uword end,
297 int32_t offset) { 290 int32_t offset) {
298 uword start = end - Instr::kInstrSize; 291 uword start = end - Instr::kInstrSize;
299 Instr* instr = Instr::At(start); 292 Instr* instr = Instr::At(start);
300 const int32_t upper12 = offset & 0x00fff000; 293 const int32_t upper12 = offset & 0x00fff000;
301 const int32_t lower12 = offset & 0x00000fff; 294 const int32_t lower12 = offset & 0x00000fff;
302 ASSERT((offset & 0xff000000) == 0); // Can't encode > 24 bits. 295 ASSERT((offset & 0xff000000) == 0); // Can't encode > 24 bits.
303 ASSERT(((lower12 >> 3) << 3) == lower12); // 8-byte aligned. 296 ASSERT(((lower12 >> 3) << 3) == lower12); // 8-byte aligned.
304 instr->SetImm12Bits(instr->InstructionBits(), lower12 >> 3); 297 instr->SetImm12Bits(instr->InstructionBits(), lower12 >> 3);
305 298
306 start -= Instr::kInstrSize; 299 start -= Instr::kInstrSize;
307 instr = Instr::At(start); 300 instr = Instr::At(start);
308 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12); 301 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12);
309 instr->SetInstructionBits(instr->InstructionBits() | B22); 302 instr->SetInstructionBits(instr->InstructionBits() | B22);
310 } 303 }
311 304
312 305
313 RawICData* CallPattern::IcData() { 306 RawICData* CallPattern::IcData() {
314 if (ic_data_.IsNull()) { 307 if (ic_data_.IsNull()) {
315 Register reg; 308 Register reg;
316 InstructionPattern::DecodeLoadObject(ic_data_load_end_, 309 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg,
317 object_pool_,
318 &reg,
319 &ic_data_); 310 &ic_data_);
320 ASSERT(reg == R5); 311 ASSERT(reg == R5);
321 } 312 }
322 return ic_data_.raw(); 313 return ic_data_.raw();
323 } 314 }
324 315
325 316
326 RawCode* CallPattern::TargetCode() const { 317 RawCode* CallPattern::TargetCode() const {
327 return reinterpret_cast<RawCode*>( 318 return reinterpret_cast<RawCode*>(
328 object_pool_.ObjectAt(target_code_pool_index_)); 319 object_pool_.ObjectAt(target_code_pool_index_));
329 } 320 }
330 321
331 322
332 void CallPattern::SetTargetCode(const Code& target) const { 323 void CallPattern::SetTargetCode(const Code& target) const {
333 object_pool_.SetObjectAt(target_code_pool_index_, target); 324 object_pool_.SetObjectAt(target_code_pool_index_, target);
334 // No need to flush the instruction cache, since the code is not modified. 325 // No need to flush the instruction cache, since the code is not modified.
335 } 326 }
336 327
337 328
338 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) 329 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
339 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 330 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
340 data_pool_index_(-1), 331 data_pool_index_(-1),
341 target_pool_index_(-1) { 332 target_pool_index_(-1) {
342 ASSERT(code.ContainsInstructionAt(pc)); 333 ASSERT(code.ContainsInstructionAt(pc));
343 // Last instruction: blr ip0. 334 // Last instruction: blr ip0.
344 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200); 335 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200);
345 336
346 Register reg; 337 Register reg;
347 uword data_load_end = 338 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
348 InstructionPattern::DecodeLoadWordFromPool(pc - Instr::kInstrSize, 339 pc - Instr::kInstrSize, &reg, &data_pool_index_);
349 &reg,
350 &data_pool_index_);
351 ASSERT(reg == R5); 340 ASSERT(reg == R5);
352 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize, 341 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
353 &reg, 342 &reg, &target_pool_index_);
354 &target_pool_index_);
355 ASSERT(reg == CODE_REG); 343 ASSERT(reg == CODE_REG);
356 } 344 }
357 345
358 346
359 RawObject* SwitchableCallPattern::data() const { 347 RawObject* SwitchableCallPattern::data() const {
360 return object_pool_.ObjectAt(data_pool_index_); 348 return object_pool_.ObjectAt(data_pool_index_);
361 } 349 }
362 350
363 351
364 RawCode* SwitchableCallPattern::target() const { 352 RawCode* SwitchableCallPattern::target() const {
365 return reinterpret_cast<RawCode*>( 353 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
366 object_pool_.ObjectAt(target_pool_index_));
367 } 354 }
368 355
369 356
370 void SwitchableCallPattern::SetData(const Object& data) const { 357 void SwitchableCallPattern::SetData(const Object& data) const {
371 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); 358 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
372 object_pool_.SetObjectAt(data_pool_index_, data); 359 object_pool_.SetObjectAt(data_pool_index_, data);
373 } 360 }
374 361
375 362
376 void SwitchableCallPattern::SetTarget(const Code& target) const { 363 void SwitchableCallPattern::SetTarget(const Code& target) const {
377 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); 364 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
378 object_pool_.SetObjectAt(target_pool_index_, target); 365 object_pool_.SetObjectAt(target_pool_index_, target);
379 } 366 }
380 367
381 368
382 ReturnPattern::ReturnPattern(uword pc) 369 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {}
383 : pc_(pc) {
384 }
385 370
386 371
387 bool ReturnPattern::IsValid() const { 372 bool ReturnPattern::IsValid() const {
388 Instr* bx_lr = Instr::At(pc_); 373 Instr* bx_lr = Instr::At(pc_);
389 const Register crn = ConcreteRegister(LR); 374 const Register crn = ConcreteRegister(LR);
390 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); 375 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift);
391 return bx_lr->InstructionBits() == instruction; 376 return bx_lr->InstructionBits() == instruction;
392 } 377 }
393 378
394 } // namespace dart 379 } // namespace dart
395 380
396 #endif // defined TARGET_ARCH_ARM64 381 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/instructions_arm64.h ('k') | runtime/vm/instructions_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698