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

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

Issue 261783005: Begins work on arm64 floating point instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 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/parser_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/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 13 matching lines...) Expand all
24 // Writes one disassembled instruction into 'buffer' (0-terminated). 24 // Writes one disassembled instruction into 'buffer' (0-terminated).
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 PrintVRegister(int reg);
34 void PrintShiftExtendRm(Instr* instr); 35 void PrintShiftExtendRm(Instr* instr);
35 void PrintMemOperand(Instr* instr); 36 void PrintMemOperand(Instr* instr);
36 void PrintS(Instr* instr); 37 void PrintS(Instr* instr);
37 void PrintCondition(Instr* instr); 38 void PrintCondition(Instr* instr);
38 39
39 // Handle formatting of instructions and their options. 40 // Handle formatting of instructions and their options.
40 int FormatRegister(Instr* instr, const char* option); 41 int FormatRegister(Instr* instr, const char* option);
42 int FormatVRegister(Instr*instr, const char* option);
41 int FormatOption(Instr* instr, const char* format); 43 int FormatOption(Instr* instr, const char* format);
42 void Format(Instr* instr, const char* format); 44 void Format(Instr* instr, const char* format);
43 void Unknown(Instr* instr); 45 void Unknown(Instr* instr);
44 46
45 // Decode instructions. 47 // Decode instructions.
46 #define DECODE_OP(op) \ 48 #define DECODE_OP(op) \
47 void Decode##op(Instr* instr); 49 void Decode##op(Instr* instr);
48 APPLY_OP_LIST(DECODE_OP) 50 APPLY_OP_LIST(DECODE_OP)
49 #undef DECODE_OP 51 #undef DECODE_OP
50 52
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 ASSERT(reg < kNumberOfCpuRegisters); 98 ASSERT(reg < kNumberOfCpuRegisters);
97 if (reg == 31) { 99 if (reg == 31) {
98 const char* rstr = (r31t == R31IsZR) ? "zr" : "sp"; 100 const char* rstr = (r31t == R31IsZR) ? "zr" : "sp";
99 Print(rstr); 101 Print(rstr);
100 } else { 102 } else {
101 Print(reg_names[reg]); 103 Print(reg_names[reg]);
102 } 104 }
103 } 105 }
104 106
105 107
108 void ARM64Decoder::PrintVRegister(int reg) {
109 ASSERT(0 <= reg);
110 ASSERT(reg < kNumberOfVRegisters);
111 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
112 remaining_size_in_buffer(),
113 "v%d", reg);
114 }
115
116
106 // These shift names are defined in a way to match the native disassembler 117 // These shift names are defined in a way to match the native disassembler
107 // formatting. See for example the command "objdump -d <binary file>". 118 // formatting. See for example the command "objdump -d <binary file>".
108 static const char* shift_names[kMaxShift] = { 119 static const char* shift_names[kMaxShift] = {
109 "lsl", "lsr", "asr", "ror" 120 "lsl", "lsr", "asr", "ror"
110 }; 121 };
111 122
112 123
113 static const char* extend_names[kMaxExtend] = { 124 static const char* extend_names[kMaxExtend] = {
114 "uxtb", "uxth", "uxtw", "uxtx", 125 "uxtb", "uxth", "uxtw", "uxtx",
115 "sxtb", "sxth", "sxtw", "sxtx", 126 "sxtb", "sxth", "sxtw", "sxtx",
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 } else if (format[1] == 'a') { // 'ra: Ra register 295 } else if (format[1] == 'a') { // 'ra: Ra register
285 int reg = instr->RaField(); 296 int reg = instr->RaField();
286 PrintRegister(reg, R31IsZR); 297 PrintRegister(reg, R31IsZR);
287 return 2; 298 return 2;
288 } 299 }
289 UNREACHABLE(); 300 UNREACHABLE();
290 return -1; 301 return -1;
291 } 302 }
292 303
293 304
305 int ARM64Decoder::FormatVRegister(Instr* instr, const char* format) {
306 ASSERT(format[0] == 'v');
307 if (format[1] == 'd') {
308 int reg = instr->VdField();
309 PrintVRegister(reg);
310 return 2;
311 } else if (format[1] == 'n') {
312 int reg = instr->VnField();
313 PrintVRegister(reg);
314 return 2;
315 }
316 UNREACHABLE();
317 return -1;
318 }
319
320
294 // FormatOption takes a formatting string and interprets it based on 321 // FormatOption takes a formatting string and interprets it based on
295 // the current instructions. The format string points to the first 322 // the current instructions. The format string points to the first
296 // character of the option string (the option escape has already been 323 // character of the option string (the option escape has already been
297 // consumed by the caller.) FormatOption returns the number of 324 // consumed by the caller.) FormatOption returns the number of
298 // characters that were consumed from the formatting string. 325 // characters that were consumed from the formatting string.
299 int ARM64Decoder::FormatOption(Instr* instr, const char* format) { 326 int ARM64Decoder::FormatOption(Instr* instr, const char* format) {
300 switch (format[0]) { 327 switch (format[0]) {
301 case 'b': { 328 case 'b': {
302 if (format[3] == 'i') { 329 if (format[3] == 'i') {
303 ASSERT(STRING_STARTS_WITH(format, "bitimm")); 330 ASSERT(STRING_STARTS_WITH(format, "bitimm"));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 ASSERT(STRING_STARTS_WITH(format, "hw")); 383 ASSERT(STRING_STARTS_WITH(format, "hw"));
357 const int shift = instr->HWField() << 4; 384 const int shift = instr->HWField() << 4;
358 if (shift != 0) { 385 if (shift != 0) {
359 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 386 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
360 remaining_size_in_buffer(), 387 remaining_size_in_buffer(),
361 "lsl %d", 388 "lsl %d",
362 shift); 389 shift);
363 } 390 }
364 return 2; 391 return 2;
365 } 392 }
366 case 'i': { // 'imm12, imm16 393 case 'i': { // 'imm12, 'imm16, 'immd
367 uint64_t imm; 394 if (format[3] == '1') {
368 int ret = 5; 395 uint64_t imm;
369 if (format[4] == '2') { 396 int ret = 5;
370 ASSERT(STRING_STARTS_WITH(format, "imm12")); 397 if (format[4] == '2') {
371 imm = instr->Imm12Field(); 398 ASSERT(STRING_STARTS_WITH(format, "imm12"));
372 if (format[5] == 's') { 399 imm = instr->Imm12Field();
373 // shifted immediate. 400 if (format[5] == 's') {
374 if (instr->Imm12ShiftField() == 1) { 401 // shifted immediate.
375 imm = imm << 12; 402 if (instr->Imm12ShiftField() == 1) {
376 } else if ((instr->Imm12ShiftField() & 0x2) != 0) { 403 imm = imm << 12;
377 Print("Unknown Shift"); 404 } else if ((instr->Imm12ShiftField() & 0x2) != 0) {
405 Print("Unknown Shift");
406 }
407 ret = 6;
378 } 408 }
379 ret = 6; 409 } else {
410 ASSERT(STRING_STARTS_WITH(format, "imm16"));
411 imm = instr->Imm16Field();
380 } 412 }
413 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
414 remaining_size_in_buffer(),
415 "0x%"Px64,
416 imm);
417 return ret;
381 } else { 418 } else {
382 ASSERT(STRING_STARTS_WITH(format, "imm16")); 419 ASSERT(STRING_STARTS_WITH(format, "immd"));
383 imm = instr->Imm16Field(); 420 double dimm = bit_cast<double, int64_t>(
421 Instr::VFPExpandImm(instr->Imm8Field()));
422 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
423 remaining_size_in_buffer(),
424 "%f",
425 dimm);
426 return 4;
384 } 427 }
385 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
386 remaining_size_in_buffer(),
387 "0x%"Px64,
388 imm);
389 return ret;
390 } 428 }
391 case 'm': { 429 case 'm': {
392 ASSERT(STRING_STARTS_WITH(format, "memop")); 430 ASSERT(STRING_STARTS_WITH(format, "memop"));
393 PrintMemOperand(instr); 431 PrintMemOperand(instr);
394 return 5; 432 return 5;
395 } 433 }
396 case 'p': { 434 case 'p': {
397 if (format[2] == 'a') { 435 if (format[2] == 'a') {
398 ASSERT(STRING_STARTS_WITH(format, "pcadr")); 436 ASSERT(STRING_STARTS_WITH(format, "pcadr"));
399 const int64_t immhi = instr->SImm19Field(); 437 const int64_t immhi = instr->SImm19Field();
(...skipping 13 matching lines...) Expand all
413 buffer_pos_ += OS::SNPrint(current_position_in_buffer(), 451 buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
414 remaining_size_in_buffer(), 452 remaining_size_in_buffer(),
415 "0x%"Px64, 453 "0x%"Px64,
416 dest); 454 dest);
417 } 455 }
418 return 5; 456 return 5;
419 } 457 }
420 case 'r': { 458 case 'r': {
421 return FormatRegister(instr, format); 459 return FormatRegister(instr, format);
422 } 460 }
461 case 'v': {
462 return FormatVRegister(instr, format);
463 }
423 case 's': { // 's: S flag. 464 case 's': { // 's: S flag.
424 if (format[1] == 'h') { 465 if (format[1] == 'h') {
425 ASSERT(STRING_STARTS_WITH(format, "shift_op")); 466 ASSERT(STRING_STARTS_WITH(format, "shift_op"));
426 PrintShiftExtendRm(instr); 467 PrintShiftExtendRm(instr);
427 return 8; 468 return 8;
428 } else if (format[1] == 'f') { 469 } else if (format[1] == 'f') {
429 ASSERT(STRING_STARTS_WITH(format, "sf")); 470 ASSERT(STRING_STARTS_WITH(format, "sf"));
430 if (instr->SFField() == 1) { 471 if (instr->SFField() == 1) {
431 // TODO(zra): If we don't use the w form much, we can omit printing 472 // TODO(zra): If we don't use the w form much, we can omit printing
432 // this x. 473 // this x.
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 Unknown(instr); 913 Unknown(instr);
873 } 914 }
874 } 915 }
875 916
876 917
877 void ARM64Decoder::DecodeDPSimd1(Instr* instr) { 918 void ARM64Decoder::DecodeDPSimd1(Instr* instr) {
878 Unknown(instr); 919 Unknown(instr);
879 } 920 }
880 921
881 922
923 void ARM64Decoder::DecodeFPImm(Instr* instr) {
924 if ((instr->Bit(31) != 0) || (instr->Bit(29) != 0) || (instr->Bit(23) != 0) ||
925 (instr->Bits(5, 5) != 0)) {
926 Unknown(instr);
927 return;
928 }
929 if (instr->Bit(22) == 1) {
930 // Double.
931 Format(instr, "fmovd 'vd, 'immd");
932 } else {
933 // Single.
934 Unknown(instr);
935 }
936 }
937
938
939 void ARM64Decoder::DecodeFPIntCvt(Instr* instr) {
940 if ((instr->SFField() != 1) || (instr->Bit(29) != 0) ||
941 (instr->Bits(22, 2) != 1)) {
942 Unknown(instr);
943 return;
944 }
945 if (instr->Bits(16, 3) == 6) {
946 Format(instr, "fmovrd 'rd, 'vn");
947 } else if (instr->Bits(16, 3) == 7) {
948 Format(instr, "fmovdr 'vd, 'rn");
949 } else {
950 Unknown(instr);
951 }
952 }
953
954
955 void ARM64Decoder::DecodeFP(Instr* instr) {
956 if (instr->IsFPImmOp()) {
957 DecodeFPImm(instr);
958 } else if (instr->IsFPIntCvtOp()) {
959 DecodeFPIntCvt(instr);
960 } else {
961 Unknown(instr);
962 }
963 }
964
965
882 void ARM64Decoder::DecodeDPSimd2(Instr* instr) { 966 void ARM64Decoder::DecodeDPSimd2(Instr* instr) {
883 Unknown(instr); 967 if (instr->IsFPOp()) {
968 DecodeFP(instr);
969 } else {
970 Unknown(instr);
971 }
884 } 972 }
885 973
886 974
887 void ARM64Decoder::InstructionDecode(uword pc) { 975 void ARM64Decoder::InstructionDecode(uword pc) {
888 Instr* instr = Instr::At(pc); 976 Instr* instr = Instr::At(pc);
889 977
890 if (instr->IsDPImmediateOp()) { 978 if (instr->IsDPImmediateOp()) {
891 DecodeDPImmediate(instr); 979 DecodeDPImmediate(instr);
892 } else if (instr->IsCompareBranchOp()) { 980 } else if (instr->IsCompareBranchOp()) {
893 DecodeCompareBranch(instr); 981 DecodeCompareBranch(instr);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 human_buffer, 1034 human_buffer,
947 sizeof(human_buffer), 1035 sizeof(human_buffer),
948 pc); 1036 pc);
949 pc += instruction_length; 1037 pc += instruction_length;
950 } 1038 }
951 } 1039 }
952 1040
953 } // namespace dart 1041 } // namespace dart
954 1042
955 #endif // defined TARGET_ARCH_ARM 1043 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/constants_arm64.h ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698