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

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

Issue 227593012: Adds ldr and str to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
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/disassembler.h" 5 #include "vm/disassembler.h"
6 6
7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. 7 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
8 #if defined(TARGET_ARCH_ARM64) 8 #if defined(TARGET_ARCH_ARM64)
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 10
(...skipping 14 matching lines...) Expand all
25 // Returns true if the instruction was successfully decoded, false otherwise. 25 // Returns true if the instruction was successfully decoded, false otherwise.
26 void InstructionDecode(uword pc); 26 void InstructionDecode(uword pc);
27 27
28 private: 28 private:
29 // Bottleneck functions to print into the out_buffer. 29 // Bottleneck functions to print into the out_buffer.
30 void Print(const char* str); 30 void Print(const char* str);
31 31
32 // Printing of common values. 32 // Printing of common values.
33 void PrintRegister(int reg, R31Type r31t); 33 void PrintRegister(int reg, R31Type r31t);
34 void PrintShiftExtendRm(Instr* instr); 34 void PrintShiftExtendRm(Instr* instr);
35 void PrintMemOperand(Instr* instr);
35 void PrintS(Instr* instr); 36 void PrintS(Instr* instr);
36 37
37 // Handle formatting of instructions and their options. 38 // Handle formatting of instructions and their options.
38 int FormatRegister(Instr* instr, const char* option); 39 int FormatRegister(Instr* instr, const char* option);
39 int FormatOption(Instr* instr, const char* format); 40 int FormatOption(Instr* instr, const char* format);
40 void Format(Instr* instr, const char* format); 41 void Format(Instr* instr, const char* format);
41 void Unknown(Instr* instr); 42 void Unknown(Instr* instr);
42 43
43 // Decode instructions. 44 // Decode instructions.
44 #define DECODE_OP(op) \ 45 #define DECODE_OP(op) \
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 // Shift amount. 155 // Shift amount.
155 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 156 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
156 remaining_size_in_buffer(), 157 remaining_size_in_buffer(),
157 " %d", 158 " %d",
158 extend_shift_amount); 159 extend_shift_amount);
159 } 160 }
160 } 161 }
161 } 162 }
162 163
163 164
165 void ARM64Decoder::PrintMemOperand(Instr* instr) {
166 const Register rn = instr->RnField();
167 if (instr->Bit(24) == 1) {
168 // rn + scaled unsigned 12-bit immediate offset.
169 const uint32_t scale = instr->SzField();
170 const uint32_t imm12 = instr->Imm12Field();
171 const uint32_t off = imm12 << scale;
172 Print("[");
173 PrintRegister(rn, R31IsSP);
174 if (off != 0) {
175 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
176 remaining_size_in_buffer(),
177 ", #%d",
178 off);
179 }
180 Print("]");
181 } else {
182 switch (instr->Bits(10, 2)) {
183 case 1: {
184 const int32_t imm9 = instr->SImm9Field();
185 // rn + signed 9-bit immediate, post-index, writeback.
186 Print("[");
187 PrintRegister(rn, R31IsSP);
188 Print("]");
189 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
190 remaining_size_in_buffer(),
191 ", #%d !",
192 imm9);
193 break;
194 }
195 case 3: {
196 const int32_t imm9 = instr->SImm9Field();
197 // rn + signed 9-bit immediate, pre-index, writeback.
198 Print("[");
199 PrintRegister(rn, R31IsSP);
200 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
201 remaining_size_in_buffer(),
202 ", #%d",
203 imm9);
204 Print("] !");
205 break;
206 }
207 case 2: {
208 const Register rm = instr->RmField();
209 const Extend ext = instr->ExtendTypeField();
210 const int s = instr->Bit(12);
211 Print("[");
212 PrintRegister(rn, R31IsSP);
213 Print(", ");
214 PrintRegister(rm, R31IsZR);
215 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
216 remaining_size_in_buffer(),
217 " %s",
218 extend_names[ext]);
219 if (s == 1) {
220 Print(" scaled");
221 }
222 Print("]");
223 break;
224 }
225 default: {
226 Print("???");
227 }
228 }
229 }
230 }
231
232
164 // Handle all register based formatting in these functions to reduce the 233 // Handle all register based formatting in these functions to reduce the
165 // complexity of FormatOption. 234 // complexity of FormatOption.
166 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { 235 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) {
167 ASSERT(format[0] == 'r'); 236 ASSERT(format[0] == 'r');
168 if (format[1] == 'n') { // 'rn: Rn register 237 if (format[1] == 'n') { // 'rn: Rn register
169 int reg = instr->RnField(); 238 int reg = instr->RnField();
170 PrintRegister(reg, instr->RnMode()); 239 PrintRegister(reg, instr->RnMode());
171 return 2; 240 return 2;
172 } else if (format[1] == 'd') { // 'rd: Rd register 241 } else if (format[1] == 'd') { // 'rd: Rd register
173 int reg = instr->RdField(); 242 int reg = instr->RdField();
174 PrintRegister(reg, instr->RdMode()); 243 PrintRegister(reg, instr->RdMode());
175 return 2; 244 return 2;
176 } else if (format[1] == 'm') { // 'rm: Rm register 245 } else if (format[1] == 'm') { // 'rm: Rm register
177 int reg = instr->RmField(); 246 int reg = instr->RmField();
178 PrintRegister(reg, R31IsZR); 247 PrintRegister(reg, R31IsZR);
179 return 2; 248 return 2;
249 } else if (format[1] == 't') { // 'rt: Rt register
250 int reg = instr->RtField();
251 PrintRegister(reg, R31IsZR);
252 return 2;
180 } 253 }
181 UNREACHABLE(); 254 UNREACHABLE();
182 return -1; 255 return -1;
183 } 256 }
184 257
185 258
186 // FormatOption takes a formatting string and interprets it based on 259 // FormatOption takes a formatting string and interprets it based on
187 // the current instructions. The format string points to the first 260 // the current instructions. The format string points to the first
188 // character of the option string (the option escape has already been 261 // character of the option string (the option escape has already been
189 // consumed by the caller.) FormatOption returns the number of 262 // consumed by the caller.) FormatOption returns the number of
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } else if (format[1] == 'f') { 296 } else if (format[1] == 'f') {
224 ASSERT(STRING_STARTS_WITH(format, "sf")); 297 ASSERT(STRING_STARTS_WITH(format, "sf"));
225 if (instr->SFField() == 1) { 298 if (instr->SFField() == 1) {
226 // TODO(zra): If we don't use the w form much, we can omit printing 299 // TODO(zra): If we don't use the w form much, we can omit printing
227 // this x. 300 // this x.
228 Print("x"); 301 Print("x");
229 } else { 302 } else {
230 Print("w"); 303 Print("w");
231 } 304 }
232 return 2; 305 return 2;
306 } else if (format[1] == 'z') {
307 ASSERT(STRING_STARTS_WITH(format, "sz"));
308 const int sz = instr->SzField();
309 char const* sz_str;
310 switch (sz) {
311 case 0: sz_str = "b"; break;
312 case 1: sz_str = "h"; break;
313 case 2: sz_str = "w"; break;
314 case 3: sz_str = "x"; break;
315 default: sz_str = "?"; break;
316 }
317 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
318 remaining_size_in_buffer(),
319 "%s",
320 sz_str);
321 return 2;
233 } else if (format[1] == ' ') { 322 } else if (format[1] == ' ') {
234 if (instr->HasS()) { 323 if (instr->HasS()) {
235 Print("s"); 324 Print("s");
236 } 325 }
237 return 1; 326 return 1;
238 } else { 327 } else {
239 UNREACHABLE(); 328 UNREACHABLE();
240 } 329 }
241 } 330 }
242 case 'r': { 331 case 'r': {
243 return FormatRegister(instr, format); 332 return FormatRegister(instr, format);
244 } 333 }
245 case 'h': { 334 case 'h': {
246 ASSERT(STRING_STARTS_WITH(format, "hw")); 335 ASSERT(STRING_STARTS_WITH(format, "hw"));
247 const int shift = instr->HWField() << 4; 336 const int shift = instr->HWField() << 4;
248 if (shift != 0) { 337 if (shift != 0) {
249 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 338 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
250 remaining_size_in_buffer(), 339 remaining_size_in_buffer(),
251 "lsl %d", 340 "lsl %d",
252 shift); 341 shift);
253 } 342 }
254 return 2; 343 return 2;
255 } 344 }
345 case 'm': {
346 ASSERT(STRING_STARTS_WITH(format, "memop"));
347 PrintMemOperand(instr);
348 return 5;
349 }
256 default: { 350 default: {
257 UNREACHABLE(); 351 UNREACHABLE();
258 break; 352 break;
259 } 353 }
260 } 354 }
261 UNREACHABLE(); 355 UNREACHABLE();
262 return -1; 356 return -1;
263 } 357 }
264 358
265 359
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 case 3: 392 case 3:
299 Format(instr, "movk'sf 'rd, 'imm16 'hw"); 393 Format(instr, "movk'sf 'rd, 'imm16 'hw");
300 break; 394 break;
301 default: 395 default:
302 Unknown(instr); 396 Unknown(instr);
303 break; 397 break;
304 } 398 }
305 } 399 }
306 400
307 401
402 void ARM64Decoder::DecodeLoadStoreReg(Instr* instr) {
403 if (instr->Bits(25, 2) != 0) {
404 Unknown(instr);
405 return;
406 }
407 if (instr->Bit(22) == 1) {
408 Format(instr, "ldr'sz 'rt, 'memop");
409 } else {
410 Format(instr, "str'sz 'rt, 'memop");
411 }
412 }
413
414
308 void ARM64Decoder::DecodeAddSubImm(Instr* instr) { 415 void ARM64Decoder::DecodeAddSubImm(Instr* instr) {
309 switch (instr->Bit(30)) { 416 switch (instr->Bit(30)) {
310 case 0: 417 case 0:
311 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s"); 418 Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
312 break; 419 break;
313 case 1: 420 case 1:
314 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s"); 421 Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
315 break; 422 break;
316 default: 423 default:
317 Unknown(instr); 424 Unknown(instr);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 DecodeSystem(instr); 494 DecodeSystem(instr);
388 } else if (instr->IsUnconditionalBranchRegOp()) { 495 } else if (instr->IsUnconditionalBranchRegOp()) {
389 DecodeUnconditionalBranchReg(instr); 496 DecodeUnconditionalBranchReg(instr);
390 } else { 497 } else {
391 Unknown(instr); 498 Unknown(instr);
392 } 499 }
393 } 500 }
394 501
395 502
396 void ARM64Decoder::DecodeLoadStore(Instr* instr) { 503 void ARM64Decoder::DecodeLoadStore(Instr* instr) {
397 Unknown(instr); 504 if (instr->IsLoadStoreRegOp()) {
505 DecodeLoadStoreReg(instr);
506 } else {
507 Unknown(instr);
508 }
398 } 509 }
399 510
400 511
401 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { 512 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) {
402 switch (instr->Bit(30)) { 513 switch (instr->Bit(30)) {
403 case 0: 514 case 0:
404 Format(instr, "add'sf's 'rd, 'rn, 'shift_op"); 515 Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
405 break; 516 break;
406 case 1: 517 case 1:
407 Format(instr, "sub'sf's 'rd, 'rn, 'shift_op"); 518 Format(instr, "sub'sf's 'rd, 'rn, 'shift_op");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 human_buffer, 604 human_buffer,
494 sizeof(human_buffer), 605 sizeof(human_buffer),
495 pc); 606 pc);
496 pc += instruction_length; 607 pc += instruction_length;
497 } 608 }
498 } 609 }
499 610
500 } // namespace dart 611 } // namespace dart
501 612
502 #endif // defined TARGET_ARCH_ARM 613 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698