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

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

Issue 630033003: Adds ldp and stp instructions to ARM64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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
« no previous file with comments | « runtime/vm/constants_arm64.h ('k') | runtime/vm/simulator_arm64.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/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 16 matching lines...) Expand all
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 PrintVRegister(int reg); 34 void PrintVRegister(int reg);
35 void PrintShiftExtendRm(Instr* instr); 35 void PrintShiftExtendRm(Instr* instr);
36 void PrintMemOperand(Instr* instr); 36 void PrintMemOperand(Instr* instr);
37 void PrintPairMemOperand(Instr* instr);
37 void PrintS(Instr* instr); 38 void PrintS(Instr* instr);
38 void PrintCondition(Instr* instr); 39 void PrintCondition(Instr* instr);
39 40
40 // Handle formatting of instructions and their options. 41 // Handle formatting of instructions and their options.
41 int FormatRegister(Instr* instr, const char* option); 42 int FormatRegister(Instr* instr, const char* option);
42 int FormatVRegister(Instr*instr, const char* option); 43 int FormatVRegister(Instr*instr, const char* option);
43 int FormatOption(Instr* instr, const char* format); 44 int FormatOption(Instr* instr, const char* format);
44 void Format(Instr* instr, const char* format); 45 void Format(Instr* instr, const char* format);
45 void Unknown(Instr* instr); 46 void Unknown(Instr* instr);
46 47
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 } 210 }
210 Print("]"); 211 Print("]");
211 } else { 212 } else {
212 switch (instr->Bits(10, 2)) { 213 switch (instr->Bits(10, 2)) {
213 case 0: { 214 case 0: {
214 // rn + signed 9-bit immediate, pre-index, no writeback. 215 // rn + signed 9-bit immediate, pre-index, no writeback.
215 const int32_t imm9 = instr->SImm9Field(); 216 const int32_t imm9 = instr->SImm9Field();
216 Print("["); 217 Print("[");
217 PrintRegister(rn, R31IsSP); 218 PrintRegister(rn, R31IsSP);
218 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 219 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
219 remaining_size_in_buffer(), 220 remaining_size_in_buffer(),
220 ", #%d", 221 ", #%d",
221 imm9); 222 imm9);
222 Print("]"); 223 Print("]");
223 break; 224 break;
224 } 225 }
225 case 1: { 226 case 1: {
226 const int32_t imm9 = instr->SImm9Field(); 227 const int32_t imm9 = instr->SImm9Field();
227 // rn + signed 9-bit immediate, post-index, writeback. 228 // rn + signed 9-bit immediate, post-index, writeback.
228 Print("["); 229 Print("[");
229 PrintRegister(rn, R31IsSP); 230 PrintRegister(rn, R31IsSP);
230 Print("]"); 231 Print("]");
231 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 232 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 break; 266 break;
266 } 267 }
267 default: { 268 default: {
268 Print("???"); 269 Print("???");
269 } 270 }
270 } 271 }
271 } 272 }
272 } 273 }
273 274
274 275
276 void ARM64Decoder::PrintPairMemOperand(Instr* instr) {
277 const Register rn = instr->RnField();
278 const int32_t simm7 = instr->SImm7Field();
279 const int32_t offset = simm7 << (2 + instr->Bit(31));
280 Print("[");
281 PrintRegister(rn, R31IsSP);
282 switch (instr->Bits(23, 3)) {
283 case 1:
284 // rn + (imm7 << (2 + B31)), post-index, writeback.
285 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
286 remaining_size_in_buffer(),
287 "], #%d !",
288 offset);
289 break;
290 case 2:
291 // rn + (imm7 << (2 + B31)), pre-index, no writeback.
292 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
293 remaining_size_in_buffer(),
294 ", #%d ]",
295 offset);
296 break;
297 case 3:
298 // rn + (imm7 << (2 + B31)), pre-index, writeback.
299 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
300 remaining_size_in_buffer(),
301 ", #%d ]!",
302 offset);
303 break;
304 default:
305 Print(", ???]");
306 break;
307 }
308 }
309
310
275 // Handle all register based formatting in these functions to reduce the 311 // Handle all register based formatting in these functions to reduce the
276 // complexity of FormatOption. 312 // complexity of FormatOption.
277 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) { 313 int ARM64Decoder::FormatRegister(Instr* instr, const char* format) {
278 ASSERT(format[0] == 'r'); 314 ASSERT(format[0] == 'r');
279 if (format[1] == 'n') { // 'rn: Rn register 315 if (format[1] == 'n') { // 'rn: Rn register
280 int reg = instr->RnField(); 316 int reg = instr->RnField();
281 PrintRegister(reg, instr->RnMode()); 317 PrintRegister(reg, instr->RnMode());
282 return 2; 318 return 2;
283 } else if (format[1] == 'd') { // 'rd: Rd register 319 } else if (format[1] == 'd') { // 'rd: Rd register
284 int reg = instr->RdField(); 320 int reg = instr->RdField();
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 dimm); 540 dimm);
505 return 4; 541 return 4;
506 } 542 }
507 } 543 }
508 case 'm': { 544 case 'm': {
509 ASSERT(STRING_STARTS_WITH(format, "memop")); 545 ASSERT(STRING_STARTS_WITH(format, "memop"));
510 PrintMemOperand(instr); 546 PrintMemOperand(instr);
511 return 5; 547 return 5;
512 } 548 }
513 case 'p': { 549 case 'p': {
514 if (format[2] == 'a') { 550 if (format[1] == 'c') {
515 ASSERT(STRING_STARTS_WITH(format, "pcadr")); 551 if (format[2] == 'a') {
516 const int64_t immhi = instr->SImm19Field(); 552 ASSERT(STRING_STARTS_WITH(format, "pcadr"));
517 const int64_t immlo = instr->Bits(29, 2); 553 const int64_t immhi = instr->SImm19Field();
518 const int64_t off = (immhi << 2) | immlo; 554 const int64_t immlo = instr->Bits(29, 2);
519 const int64_t pc = reinterpret_cast<int64_t>(instr); 555 const int64_t off = (immhi << 2) | immlo;
520 const int64_t dest = pc + off; 556 const int64_t pc = reinterpret_cast<int64_t>(instr);
521 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 557 const int64_t dest = pc + off;
522 remaining_size_in_buffer(), 558 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
523 "0x%"Px64, 559 remaining_size_in_buffer(),
524 dest); 560 "0x%"Px64,
561 dest);
562 } else {
563 ASSERT(STRING_STARTS_WITH(format, "pcldr"));
564 const int64_t off = instr->SImm19Field() << 2;
565 const int64_t pc = reinterpret_cast<int64_t>(instr);
566 const int64_t dest = pc + off;
567 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
568 remaining_size_in_buffer(),
569 "0x%"Px64,
570 dest);
571 }
572 return 5;
525 } else { 573 } else {
526 ASSERT(STRING_STARTS_WITH(format, "pcldr")); 574 ASSERT(STRING_STARTS_WITH(format, "pmemop"));
527 const int64_t off = instr->SImm19Field() << 2; 575 PrintPairMemOperand(instr);
528 const int64_t pc = reinterpret_cast<int64_t>(instr); 576 return 6;
529 const int64_t dest = pc + off;
530 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
531 remaining_size_in_buffer(),
532 "0x%"Px64,
533 dest);
534 } 577 }
535 return 5;
536 } 578 }
537 case 'r': { 579 case 'r': {
538 return FormatRegister(instr, format); 580 return FormatRegister(instr, format);
539 } 581 }
540 case 'v': { 582 case 'v': {
541 if (format[1] == 's') { 583 if (format[1] == 's') {
542 ASSERT(STRING_STARTS_WITH(format, "vsz")); 584 ASSERT(STRING_STARTS_WITH(format, "vsz"));
543 char const* sz_str = NULL; 585 char const* sz_str = NULL;
544 if (instr->Bits(14, 2) == 3) { 586 if (instr->Bits(14, 2) == 3) {
545 switch (instr->Bit(22)) { 587 switch (instr->Bit(22)) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 // Integer src/dst. 709 // Integer src/dst.
668 if (instr->Bits(22, 2) == 0) { 710 if (instr->Bits(22, 2) == 0) {
669 Format(instr, "str'sz 'rt, 'memop"); 711 Format(instr, "str'sz 'rt, 'memop");
670 } else { 712 } else {
671 Format(instr, "ldr'sz 'rt, 'memop"); 713 Format(instr, "ldr'sz 'rt, 'memop");
672 } 714 }
673 } 715 }
674 } 716 }
675 717
676 718
719 void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) {
720 if (instr->Bit(22) == 1) {
721 // Load.
722 Format(instr, "ldp'sf 'rt, 'ra, 'pmemop");
723 } else {
724 // Store.
725 Format(instr, "stp'sf 'rt, 'ra, 'pmemop");
726 }
727 }
728
729
677 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) { 730 void ARM64Decoder::DecodeLoadRegLiteral(Instr* instr) {
678 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || 731 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) ||
679 (instr->Bits(24, 3) != 0)) { 732 (instr->Bits(24, 3) != 0)) {
680 Unknown(instr); 733 Unknown(instr);
681 } 734 }
682 if (instr->Bit(30)) { 735 if (instr->Bit(30)) {
683 Format(instr, "ldrx 'rt, 'pcldr"); 736 Format(instr, "ldrx 'rt, 'pcldr");
684 } else { 737 } else {
685 Format(instr, "ldrw 'rt, 'pcldr"); 738 Format(instr, "ldrw 'rt, 'pcldr");
686 } 739 }
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 DecodeUnconditionalBranch(instr); 927 DecodeUnconditionalBranch(instr);
875 } else { 928 } else {
876 Unknown(instr); 929 Unknown(instr);
877 } 930 }
878 } 931 }
879 932
880 933
881 void ARM64Decoder::DecodeLoadStore(Instr* instr) { 934 void ARM64Decoder::DecodeLoadStore(Instr* instr) {
882 if (instr->IsLoadStoreRegOp()) { 935 if (instr->IsLoadStoreRegOp()) {
883 DecodeLoadStoreReg(instr); 936 DecodeLoadStoreReg(instr);
937 } else if (instr->IsLoadStoreRegPairOp()) {
938 DecodeLoadStoreRegPair(instr);
884 } else if (instr->IsLoadRegLiteralOp()) { 939 } else if (instr->IsLoadRegLiteralOp()) {
885 DecodeLoadRegLiteral(instr); 940 DecodeLoadRegLiteral(instr);
886 } else { 941 } else {
887 Unknown(instr); 942 Unknown(instr);
888 } 943 }
889 } 944 }
890 945
891 946
892 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) { 947 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) {
893 switch (instr->Bit(30)) { 948 switch (instr->Bit(30)) {
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 human_buffer, 1441 human_buffer,
1387 sizeof(human_buffer), 1442 sizeof(human_buffer),
1388 pc); 1443 pc);
1389 pc += instruction_length; 1444 pc += instruction_length;
1390 } 1445 }
1391 } 1446 }
1392 1447
1393 } // namespace dart 1448 } // namespace dart
1394 1449
1395 #endif // defined TARGET_ARCH_ARM 1450 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/constants_arm64.h ('k') | runtime/vm/simulator_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698