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

Side by Side Diff: runtime/vm/instructions_arm.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_arm.h ('k') | runtime/vm/instructions_arm64.h » ('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) 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/instructions.h" 8 #include "vm/instructions.h"
9 #include "vm/instructions_arm.h" 9 #include "vm/instructions_arm.h"
10 10
11 #include "vm/assembler.h" 11 #include "vm/assembler.h"
12 #include "vm/constants_arm.h" 12 #include "vm/constants_arm.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: blx lr. 25 // Last instruction: blx lr.
26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); 26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
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: blx lr. 41 // Last instruction: blx lr.
44 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); 42 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
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 == R9); 50 ASSERT(reg == R9);
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& new_target) const { 60 void NativeCallPattern::set_target(const Code& new_target) const {
66 object_pool_.SetObjectAt(target_code_pool_index_, new_target); 61 object_pool_.SetObjectAt(target_code_pool_index_, new_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 // Decodes a load sequence ending at 'end' (the last instruction of the load 78 // 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 79 // 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 80 // the first instruction in the sequence. Returns the register being loaded
86 // and the loaded object in the output parameters 'reg' and 'obj' 81 // and the loaded object in the output parameters 'reg' and 'obj'
87 // respectively. 82 // respectively.
88 uword InstructionPattern::DecodeLoadObject(uword end, 83 uword InstructionPattern::DecodeLoadObject(uword end,
89 const ObjectPool& object_pool, 84 const ObjectPool& object_pool,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo 144 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo
150 imm |= (instr & 0xf0000) >> 4; 145 imm |= (instr & 0xf0000) >> 4;
151 imm |= instr & 0xfff; 146 imm |= instr & 0xfff;
152 *reg = static_cast<Register>((instr & 0xf000) >> 12); 147 *reg = static_cast<Register>((instr & 0xf000) >> 12);
153 *value = imm; 148 *value = imm;
154 } 149 }
155 return start; 150 return start;
156 } 151 }
157 152
158 153
159 static bool IsLoadWithOffset(int32_t instr, Register base, 154 static bool IsLoadWithOffset(int32_t instr,
160 intptr_t* offset, Register* dst) { 155 Register base,
156 intptr_t* offset,
157 Register* dst) {
161 if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) { 158 if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) {
162 // ldr reg, [base, #+offset] 159 // ldr reg, [base, #+offset]
163 *offset = instr & 0xfff; 160 *offset = instr & 0xfff;
164 *dst = static_cast<Register>((instr & 0xf000) >> 12); 161 *dst = static_cast<Register>((instr & 0xf000) >> 12);
165 return true; 162 return true;
166 } 163 }
167 return false; 164 return false;
168 } 165 }
169 166
170 167
(...skipping 25 matching lines...) Expand all
196 ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16))); 193 ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16)));
197 // add reg, pp, reg 194 // add reg, pp, reg
198 end = DecodeLoadWordImmediate(end, reg, &offset); 195 end = DecodeLoadWordImmediate(end, reg, &offset);
199 } 196 }
200 } 197 }
201 *index = ObjectPool::IndexFromOffset(offset); 198 *index = ObjectPool::IndexFromOffset(offset);
202 return start; 199 return start;
203 } 200 }
204 201
205 202
206 bool DecodeLoadObjectFromPoolOrThread(uword pc, 203 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
207 const Code& code,
208 Object* obj) {
209 ASSERT(code.ContainsInstructionAt(pc)); 204 ASSERT(code.ContainsInstructionAt(pc));
210 205
211 int32_t instr = Instr::At(pc)->InstructionBits(); 206 int32_t instr = Instr::At(pc)->InstructionBits();
212 intptr_t offset; 207 intptr_t offset;
213 Register dst; 208 Register dst;
214 if (IsLoadWithOffset(instr, PP, &offset, &dst)) { 209 if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
215 intptr_t index = ObjectPool::IndexFromOffset(offset); 210 intptr_t index = ObjectPool::IndexFromOffset(offset);
216 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); 211 const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
217 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { 212 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
218 *obj = pool.ObjectAt(index); 213 *obj = pool.ObjectAt(index);
219 return true; 214 return true;
220 } 215 }
221 } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) { 216 } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
222 return Thread::ObjectAtOffset(offset, obj); 217 return Thread::ObjectAtOffset(offset, obj);
223 } 218 }
224 // TODO(rmacnak): Sequence for loads beyond 12 bits. 219 // TODO(rmacnak): Sequence for loads beyond 12 bits.
225 220
226 return false; 221 return false;
227 } 222 }
228 223
229 224
230 RawICData* CallPattern::IcData() { 225 RawICData* CallPattern::IcData() {
231 if (ic_data_.IsNull()) { 226 if (ic_data_.IsNull()) {
232 Register reg; 227 Register reg;
233 InstructionPattern::DecodeLoadObject(ic_data_load_end_, 228 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg,
234 object_pool_,
235 &reg,
236 &ic_data_); 229 &ic_data_);
237 ASSERT(reg == R9); 230 ASSERT(reg == R9);
238 } 231 }
239 return ic_data_.raw(); 232 return ic_data_.raw();
240 } 233 }
241 234
242 235
243 RawCode* CallPattern::TargetCode() const { 236 RawCode* CallPattern::TargetCode() const {
244 return reinterpret_cast<RawCode*>( 237 return reinterpret_cast<RawCode*>(
245 object_pool_.ObjectAt(target_code_pool_index_)); 238 object_pool_.ObjectAt(target_code_pool_index_));
246 } 239 }
247 240
248 241
249 void CallPattern::SetTargetCode(const Code& target_code) const { 242 void CallPattern::SetTargetCode(const Code& target_code) const {
250 object_pool_.SetObjectAt(target_code_pool_index_, target_code); 243 object_pool_.SetObjectAt(target_code_pool_index_, target_code);
251 } 244 }
252 245
253 246
254 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) 247 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
255 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 248 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
256 data_pool_index_(-1), 249 data_pool_index_(-1),
257 target_pool_index_(-1) { 250 target_pool_index_(-1) {
258 ASSERT(code.ContainsInstructionAt(pc)); 251 ASSERT(code.ContainsInstructionAt(pc));
259 // Last instruction: blx lr. 252 // Last instruction: blx lr.
260 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e); 253 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e);
261 254
262 Register reg; 255 Register reg;
263 uword data_load_end = 256 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
264 InstructionPattern::DecodeLoadWordFromPool(pc - Instr::kInstrSize, 257 pc - Instr::kInstrSize, &reg, &data_pool_index_);
265 &reg,
266 &data_pool_index_);
267 ASSERT(reg == R9); 258 ASSERT(reg == R9);
268 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize, 259 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
269 &reg, 260 &reg, &target_pool_index_);
270 &target_pool_index_);
271 ASSERT(reg == CODE_REG); 261 ASSERT(reg == CODE_REG);
272 } 262 }
273 263
274 264
275 RawObject* SwitchableCallPattern::data() const { 265 RawObject* SwitchableCallPattern::data() const {
276 return object_pool_.ObjectAt(data_pool_index_); 266 return object_pool_.ObjectAt(data_pool_index_);
277 } 267 }
278 268
279 269
280 RawCode* SwitchableCallPattern::target() const { 270 RawCode* SwitchableCallPattern::target() const {
281 return reinterpret_cast<RawCode*>( 271 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
282 object_pool_.ObjectAt(target_pool_index_));
283 } 272 }
284 273
285 274
286 void SwitchableCallPattern::SetData(const Object& data) const { 275 void SwitchableCallPattern::SetData(const Object& data) const {
287 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); 276 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
288 object_pool_.SetObjectAt(data_pool_index_, data); 277 object_pool_.SetObjectAt(data_pool_index_, data);
289 } 278 }
290 279
291 280
292 void SwitchableCallPattern::SetTarget(const Code& target) const { 281 void SwitchableCallPattern::SetTarget(const Code& target) const {
293 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); 282 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
294 object_pool_.SetObjectAt(target_pool_index_, target); 283 object_pool_.SetObjectAt(target_pool_index_, target);
295 } 284 }
296 285
297 286
298 ReturnPattern::ReturnPattern(uword pc) 287 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {}
299 : pc_(pc) {
300 }
301 288
302 289
303 bool ReturnPattern::IsValid() const { 290 bool ReturnPattern::IsValid() const {
304 Instr* bx_lr = Instr::At(pc_); 291 Instr* bx_lr = Instr::At(pc_);
305 const int32_t B4 = 1 << 4; 292 const int32_t B4 = 1 << 4;
306 const int32_t B21 = 1 << 21; 293 const int32_t B21 = 1 << 21;
307 const int32_t B24 = 1 << 24; 294 const int32_t B24 = 1 << 24;
308 int32_t instruction = (static_cast<int32_t>(AL) << kConditionShift) | 295 int32_t instruction = (static_cast<int32_t>(AL) << kConditionShift) | B24 |
309 B24 | B21 | (0xfff << 8) | B4 | 296 B21 | (0xfff << 8) | B4 |
310 (static_cast<int32_t>(LR) << kRmShift); 297 (static_cast<int32_t>(LR) << kRmShift);
311 const ARMVersion version = TargetCPUFeatures::arm_version(); 298 const ARMVersion version = TargetCPUFeatures::arm_version();
312 if ((version == ARMv5TE) || (version == ARMv6)) { 299 if ((version == ARMv5TE) || (version == ARMv6)) {
313 return bx_lr->InstructionBits() == instruction; 300 return bx_lr->InstructionBits() == instruction;
314 } else { 301 } else {
315 ASSERT(version == ARMv7); 302 ASSERT(version == ARMv7);
316 return bx_lr->InstructionBits() == instruction; 303 return bx_lr->InstructionBits() == instruction;
317 } 304 }
318 return false; 305 return false;
319 } 306 }
320 307
321 } // namespace dart 308 } // namespace dart
322 309
323 #endif // defined TARGET_ARCH_ARM 310 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/instructions_arm.h ('k') | runtime/vm/instructions_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698