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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months 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
(...skipping 13 matching lines...) Expand all
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_ = InstructionPattern::DecodeLoadWordFromPool( 29 ic_data_load_end_ = InstructionPattern::DecodeLoadWordFromPool(
30 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_); 30 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
31 ASSERT(reg == CODE_REG); 31 ASSERT(reg == CODE_REG);
32 } 32 }
33 33
34
35 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) 34 NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
36 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 35 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
37 end_(pc), 36 end_(pc),
38 native_function_pool_index_(-1), 37 native_function_pool_index_(-1),
39 target_code_pool_index_(-1) { 38 target_code_pool_index_(-1) {
40 ASSERT(code.ContainsInstructionAt(pc)); 39 ASSERT(code.ContainsInstructionAt(pc));
41 // Last instruction: blr ip0. 40 // Last instruction: blr ip0.
42 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200); 41 ASSERT(*(reinterpret_cast<uint32_t*>(end_) - 1) == 0xd63f0200);
43 42
44 Register reg; 43 Register reg;
45 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool( 44 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool(
46 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_); 45 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
47 ASSERT(reg == CODE_REG); 46 ASSERT(reg == CODE_REG);
48 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, &reg, 47 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, &reg,
49 &native_function_pool_index_); 48 &native_function_pool_index_);
50 ASSERT(reg == R5); 49 ASSERT(reg == R5);
51 } 50 }
52 51
53
54 RawCode* NativeCallPattern::target() const { 52 RawCode* NativeCallPattern::target() const {
55 return reinterpret_cast<RawCode*>( 53 return reinterpret_cast<RawCode*>(
56 object_pool_.ObjectAt(target_code_pool_index_)); 54 object_pool_.ObjectAt(target_code_pool_index_));
57 } 55 }
58 56
59
60 void NativeCallPattern::set_target(const Code& target) const { 57 void NativeCallPattern::set_target(const Code& target) const {
61 object_pool_.SetObjectAt(target_code_pool_index_, target); 58 object_pool_.SetObjectAt(target_code_pool_index_, target);
62 // No need to flush the instruction cache, since the code is not modified. 59 // No need to flush the instruction cache, since the code is not modified.
63 } 60 }
64 61
65
66 NativeFunction NativeCallPattern::native_function() const { 62 NativeFunction NativeCallPattern::native_function() const {
67 return reinterpret_cast<NativeFunction>( 63 return reinterpret_cast<NativeFunction>(
68 object_pool_.RawValueAt(native_function_pool_index_)); 64 object_pool_.RawValueAt(native_function_pool_index_));
69 } 65 }
70 66
71
72 void NativeCallPattern::set_native_function(NativeFunction func) const { 67 void NativeCallPattern::set_native_function(NativeFunction func) const {
73 object_pool_.SetRawValueAt(native_function_pool_index_, 68 object_pool_.SetRawValueAt(native_function_pool_index_,
74 reinterpret_cast<uword>(func)); 69 reinterpret_cast<uword>(func));
75 } 70 }
76 71
77
78 intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) { 72 intptr_t InstructionPattern::OffsetFromPPIndex(intptr_t index) {
79 return Array::element_offset(index); 73 return Array::element_offset(index);
80 } 74 }
81 75
82
83 // Decodes a load sequence ending at 'end' (the last instruction of the load 76 // Decodes a load sequence ending at 'end' (the last instruction of the load
84 // sequence is the instruction before the one at end). Returns a pointer to 77 // sequence is the instruction before the one at end). Returns a pointer to
85 // the first instruction in the sequence. Returns the register being loaded 78 // the first instruction in the sequence. Returns the register being loaded
86 // and the loaded object in the output parameters 'reg' and 'obj' 79 // and the loaded object in the output parameters 'reg' and 'obj'
87 // respectively. 80 // respectively.
88 uword InstructionPattern::DecodeLoadObject(uword end, 81 uword InstructionPattern::DecodeLoadObject(uword end,
89 const ObjectPool& object_pool, 82 const ObjectPool& object_pool,
90 Register* reg, 83 Register* reg,
91 Object* obj) { 84 Object* obj) {
92 // 1. LoadWordFromPool 85 // 1. LoadWordFromPool
93 // or 86 // or
94 // 2. LoadDecodableImmediate 87 // 2. LoadDecodableImmediate
95 uword start = 0; 88 uword start = 0;
96 Instr* instr = Instr::At(end - Instr::kInstrSize); 89 Instr* instr = Instr::At(end - Instr::kInstrSize);
97 if (instr->IsLoadStoreRegOp()) { 90 if (instr->IsLoadStoreRegOp()) {
98 // Case 1. 91 // Case 1.
99 intptr_t index = 0; 92 intptr_t index = 0;
100 start = DecodeLoadWordFromPool(end, reg, &index); 93 start = DecodeLoadWordFromPool(end, reg, &index);
101 *obj = object_pool.ObjectAt(index); 94 *obj = object_pool.ObjectAt(index);
102 } else { 95 } else {
103 // Case 2. 96 // Case 2.
104 intptr_t value = 0; 97 intptr_t value = 0;
105 start = DecodeLoadWordImmediate(end, reg, &value); 98 start = DecodeLoadWordImmediate(end, reg, &value);
106 *obj = reinterpret_cast<RawObject*>(value); 99 *obj = reinterpret_cast<RawObject*>(value);
107 } 100 }
108 return start; 101 return start;
109 } 102 }
110 103
111
112 // Decodes a load sequence ending at 'end' (the last instruction of the load 104 // Decodes a load sequence ending at 'end' (the last instruction of the load
113 // sequence is the instruction before the one at end). Returns a pointer to 105 // sequence is the instruction before the one at end). Returns a pointer to
114 // the first instruction in the sequence. Returns the register being loaded 106 // the first instruction in the sequence. Returns the register being loaded
115 // and the loaded immediate value in the output parameters 'reg' and 'value' 107 // and the loaded immediate value in the output parameters 'reg' and 'value'
116 // respectively. 108 // respectively.
117 uword InstructionPattern::DecodeLoadWordImmediate(uword end, 109 uword InstructionPattern::DecodeLoadWordImmediate(uword end,
118 Register* reg, 110 Register* reg,
119 intptr_t* value) { 111 intptr_t* value) {
120 // 1. LoadWordFromPool 112 // 1. LoadWordFromPool
121 // or 113 // or
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 instr = Instr::At(start); 167 instr = Instr::At(start);
176 ASSERT(instr->IsMoveWideOp()); 168 ASSERT(instr->IsMoveWideOp());
177 ASSERT(instr->Bits(29, 2) == 2); 169 ASSERT(instr->Bits(29, 2) == 2);
178 ASSERT(instr->HWField() == 0); // movz dst, imm0, 0 170 ASSERT(instr->HWField() == 0); // movz dst, imm0, 0
179 ASSERT(instr->RdField() == *reg); 171 ASSERT(instr->RdField() == *reg);
180 *value |= static_cast<int64_t>(instr->Imm16Field()); 172 *value |= static_cast<int64_t>(instr->Imm16Field());
181 173
182 return start; 174 return start;
183 } 175 }
184 176
185
186 // Decodes a load sequence ending at 'end' (the last instruction of the load 177 // Decodes a load sequence ending at 'end' (the last instruction of the load
187 // sequence is the instruction before the one at end). Returns a pointer to 178 // sequence is the instruction before the one at end). Returns a pointer to
188 // the first instruction in the sequence. Returns the register being loaded 179 // the first instruction in the sequence. Returns the register being loaded
189 // and the index in the pool being read from in the output parameters 'reg' 180 // and the index in the pool being read from in the output parameters 'reg'
190 // and 'index' respectively. 181 // and 'index' respectively.
191 uword InstructionPattern::DecodeLoadWordFromPool(uword end, 182 uword InstructionPattern::DecodeLoadWordFromPool(uword end,
192 Register* reg, 183 Register* reg,
193 intptr_t* index) { 184 intptr_t* index) {
194 // 1. ldr dst, [pp, offset] 185 // 1. ldr dst, [pp, offset]
195 // or 186 // or
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 ASSERT(instr->HWField() == 0); 239 ASSERT(instr->HWField() == 0);
249 offset |= instr->Imm16Field(); 240 offset |= instr->Imm16Field();
250 } 241 }
251 } 242 }
252 // PP is untagged on ARM64. 243 // PP is untagged on ARM64.
253 ASSERT(Utils::IsAligned(offset, 8)); 244 ASSERT(Utils::IsAligned(offset, 8));
254 *index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag); 245 *index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
255 return start; 246 return start;
256 } 247 }
257 248
258
259 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) { 249 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
260 ASSERT(code.ContainsInstructionAt(pc)); 250 ASSERT(code.ContainsInstructionAt(pc));
261 251
262 Instr* instr = Instr::At(pc); 252 Instr* instr = Instr::At(pc);
263 if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) && 253 if (instr->IsLoadStoreRegOp() && (instr->Bit(22) == 1) &&
264 (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) { 254 (instr->Bits(30, 2) == 3) && instr->Bit(24) == 1) {
265 intptr_t offset = (instr->Imm12Field() << 3); 255 intptr_t offset = (instr->Imm12Field() << 3);
266 if (instr->RnField() == PP) { 256 if (instr->RnField() == PP) {
267 // PP is untagged on ARM64. 257 // PP is untagged on ARM64.
268 ASSERT(Utils::IsAligned(offset, 8)); 258 ASSERT(Utils::IsAligned(offset, 8));
269 intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag); 259 intptr_t index = ObjectPool::IndexFromOffset(offset - kHeapObjectTag);
270 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); 260 const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
271 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { 261 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
272 *obj = pool.ObjectAt(index); 262 *obj = pool.ObjectAt(index);
273 return true; 263 return true;
274 } 264 }
275 } else if (instr->RnField() == THR) { 265 } else if (instr->RnField() == THR) {
276 return Thread::ObjectAtOffset(offset, obj); 266 return Thread::ObjectAtOffset(offset, obj);
277 } 267 }
278 } 268 }
279 // TODO(rmacnak): Loads with offsets beyond 12 bits. 269 // TODO(rmacnak): Loads with offsets beyond 12 bits.
280 270
281 return false; 271 return false;
282 } 272 }
283 273
284
285 // Encodes a load sequence ending at 'end'. Encodes a fixed length two 274 // Encodes a load sequence ending at 'end'. Encodes a fixed length two
286 // instruction load from the pool pointer in PP using the destination 275 // instruction load from the pool pointer in PP using the destination
287 // register reg as a temporary for the base address. 276 // register reg as a temporary for the base address.
288 // Assumes that the location has already been validated for patching. 277 // Assumes that the location has already been validated for patching.
289 void InstructionPattern::EncodeLoadWordFromPoolFixed(uword end, 278 void InstructionPattern::EncodeLoadWordFromPoolFixed(uword end,
290 int32_t offset) { 279 int32_t offset) {
291 uword start = end - Instr::kInstrSize; 280 uword start = end - Instr::kInstrSize;
292 Instr* instr = Instr::At(start); 281 Instr* instr = Instr::At(start);
293 const int32_t upper12 = offset & 0x00fff000; 282 const int32_t upper12 = offset & 0x00fff000;
294 const int32_t lower12 = offset & 0x00000fff; 283 const int32_t lower12 = offset & 0x00000fff;
295 ASSERT((offset & 0xff000000) == 0); // Can't encode > 24 bits. 284 ASSERT((offset & 0xff000000) == 0); // Can't encode > 24 bits.
296 ASSERT(((lower12 >> 3) << 3) == lower12); // 8-byte aligned. 285 ASSERT(((lower12 >> 3) << 3) == lower12); // 8-byte aligned.
297 instr->SetImm12Bits(instr->InstructionBits(), lower12 >> 3); 286 instr->SetImm12Bits(instr->InstructionBits(), lower12 >> 3);
298 287
299 start -= Instr::kInstrSize; 288 start -= Instr::kInstrSize;
300 instr = Instr::At(start); 289 instr = Instr::At(start);
301 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12); 290 instr->SetImm12Bits(instr->InstructionBits(), upper12 >> 12);
302 instr->SetInstructionBits(instr->InstructionBits() | B22); 291 instr->SetInstructionBits(instr->InstructionBits() | B22);
303 } 292 }
304 293
305
306 RawICData* CallPattern::IcData() { 294 RawICData* CallPattern::IcData() {
307 if (ic_data_.IsNull()) { 295 if (ic_data_.IsNull()) {
308 Register reg; 296 Register reg;
309 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg, 297 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg,
310 &ic_data_); 298 &ic_data_);
311 ASSERT(reg == R5); 299 ASSERT(reg == R5);
312 } 300 }
313 return ic_data_.raw(); 301 return ic_data_.raw();
314 } 302 }
315 303
316
317 RawCode* CallPattern::TargetCode() const { 304 RawCode* CallPattern::TargetCode() const {
318 return reinterpret_cast<RawCode*>( 305 return reinterpret_cast<RawCode*>(
319 object_pool_.ObjectAt(target_code_pool_index_)); 306 object_pool_.ObjectAt(target_code_pool_index_));
320 } 307 }
321 308
322
323 void CallPattern::SetTargetCode(const Code& target) const { 309 void CallPattern::SetTargetCode(const Code& target) const {
324 object_pool_.SetObjectAt(target_code_pool_index_, target); 310 object_pool_.SetObjectAt(target_code_pool_index_, target);
325 // No need to flush the instruction cache, since the code is not modified. 311 // No need to flush the instruction cache, since the code is not modified.
326 } 312 }
327 313
328
329 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) 314 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
330 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 315 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
331 data_pool_index_(-1), 316 data_pool_index_(-1),
332 target_pool_index_(-1) { 317 target_pool_index_(-1) {
333 ASSERT(code.ContainsInstructionAt(pc)); 318 ASSERT(code.ContainsInstructionAt(pc));
334 // Last instruction: blr ip0. 319 // Last instruction: blr ip0.
335 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200); 320 ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200);
336 321
337 Register reg; 322 Register reg;
338 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool( 323 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
339 pc - Instr::kInstrSize, &reg, &data_pool_index_); 324 pc - Instr::kInstrSize, &reg, &data_pool_index_);
340 ASSERT(reg == R5); 325 ASSERT(reg == R5);
341 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize, 326 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
342 &reg, &target_pool_index_); 327 &reg, &target_pool_index_);
343 ASSERT(reg == CODE_REG); 328 ASSERT(reg == CODE_REG);
344 } 329 }
345 330
346
347 RawObject* SwitchableCallPattern::data() const { 331 RawObject* SwitchableCallPattern::data() const {
348 return object_pool_.ObjectAt(data_pool_index_); 332 return object_pool_.ObjectAt(data_pool_index_);
349 } 333 }
350 334
351
352 RawCode* SwitchableCallPattern::target() const { 335 RawCode* SwitchableCallPattern::target() const {
353 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_)); 336 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
354 } 337 }
355 338
356
357 void SwitchableCallPattern::SetData(const Object& data) const { 339 void SwitchableCallPattern::SetData(const Object& data) const {
358 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); 340 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
359 object_pool_.SetObjectAt(data_pool_index_, data); 341 object_pool_.SetObjectAt(data_pool_index_, data);
360 } 342 }
361 343
362
363 void SwitchableCallPattern::SetTarget(const Code& target) const { 344 void SwitchableCallPattern::SetTarget(const Code& target) const {
364 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); 345 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
365 object_pool_.SetObjectAt(target_pool_index_, target); 346 object_pool_.SetObjectAt(target_pool_index_, target);
366 } 347 }
367 348
368
369 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {} 349 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {}
370 350
371
372 bool ReturnPattern::IsValid() const { 351 bool ReturnPattern::IsValid() const {
373 Instr* bx_lr = Instr::At(pc_); 352 Instr* bx_lr = Instr::At(pc_);
374 const Register crn = ConcreteRegister(LR); 353 const Register crn = ConcreteRegister(LR);
375 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift); 354 const int32_t instruction = RET | (static_cast<int32_t>(crn) << kRnShift);
376 return bx_lr->InstructionBits() == instruction; 355 return bx_lr->InstructionBits() == instruction;
377 } 356 }
378 357
379 } // namespace dart 358 } // namespace dart
380 359
381 #endif // defined TARGET_ARCH_ARM64 360 #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