OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 if (instr->HasB()) { | 394 if (instr->HasB()) { |
395 Print("b"); | 395 Print("b"); |
396 } | 396 } |
397 return 1; | 397 return 1; |
398 } | 398 } |
399 case 'c': { // 'cond: conditional execution | 399 case 'c': { // 'cond: conditional execution |
400 ASSERT(STRING_STARTS_WITH(format, "cond")); | 400 ASSERT(STRING_STARTS_WITH(format, "cond")); |
401 PrintCondition(instr); | 401 PrintCondition(instr); |
402 return 4; | 402 return 4; |
403 } | 403 } |
| 404 case 'f': { // 'f: bitfield instructions - v7 and above. |
| 405 uint32_t lsbit = instr->Bits(11, 7); |
| 406 uint32_t width = instr->Bits(20, 16) + 1; |
| 407 if (instr->Bit(21) == 0) { |
| 408 // BFC/BFI: |
| 409 // Bits 20-16 represent most-significant bit. Covert to width. |
| 410 width -= lsbit; |
| 411 ASSERT(width > 0); |
| 412 } |
| 413 ASSERT((width + lsbit) <= 32); |
| 414 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
| 415 "#%d, #%d", lsbit, width); |
| 416 return 1; |
| 417 } |
404 case 'h': { // 'h: halfword operation for extra loads and stores | 418 case 'h': { // 'h: halfword operation for extra loads and stores |
405 if (instr->HasH()) { | 419 if (instr->HasH()) { |
406 Print("h"); | 420 Print("h"); |
407 } else { | 421 } else { |
408 Print("b"); | 422 Print("b"); |
409 } | 423 } |
410 return 1; | 424 return 1; |
411 } | 425 } |
412 case 'l': { // 'l: branch and link | 426 case 'l': { // 'l: branch and link |
413 if (instr->HasLink()) { | 427 if (instr->HasLink()) { |
(...skipping 25 matching lines...) Expand all Loading... |
439 "%s", converter_.NameInCode(str)); | 453 "%s", converter_.NameInCode(str)); |
440 return 3; | 454 return 3; |
441 } | 455 } |
442 case 'o': { | 456 case 'o': { |
443 if ((format[3] == '1') && (format[4] == '2')) { | 457 if ((format[3] == '1') && (format[4] == '2')) { |
444 // 'off12: 12-bit offset for load and store instructions | 458 // 'off12: 12-bit offset for load and store instructions |
445 ASSERT(STRING_STARTS_WITH(format, "off12")); | 459 ASSERT(STRING_STARTS_WITH(format, "off12")); |
446 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 460 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
447 "%d", instr->Offset12Field()); | 461 "%d", instr->Offset12Field()); |
448 return 5; | 462 return 5; |
449 } else if ((format[3] == '1') && (format[4] == '6')) { | |
450 ASSERT(STRING_STARTS_WITH(format, "off16to20")); | |
451 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
452 "%d", instr->Bits(20, 16) +1); | |
453 return 9; | |
454 } else if (format[3] == '7') { | |
455 ASSERT(STRING_STARTS_WITH(format, "off7to11")); | |
456 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
457 "%d", instr->ShiftAmountField()); | |
458 return 8; | |
459 } else if (format[3] == '0') { | 463 } else if (format[3] == '0') { |
460 // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0. | 464 // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0. |
461 ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19")); | 465 ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19")); |
462 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 466 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
463 "%d", | 467 "%d", |
464 (instr->Bits(19, 8) << 4) + | 468 (instr->Bits(19, 8) << 4) + |
465 instr->Bits(3, 0)); | 469 instr->Bits(3, 0)); |
466 return 15; | 470 return 15; |
467 } | 471 } |
468 // 'off8: 8-bit offset for extra load and store instructions | 472 // 'off8: 8-bit offset for extra load and store instructions |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); | 879 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); |
876 break; | 880 break; |
877 } | 881 } |
878 case 2: { | 882 case 2: { |
879 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); | 883 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); |
880 break; | 884 break; |
881 } | 885 } |
882 case 3: { | 886 case 3: { |
883 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { | 887 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { |
884 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); | 888 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); |
885 uint32_t lsbit = static_cast<uint32_t>(instr->ShiftAmountField()); | 889 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); |
886 uint32_t msbit = widthminus1 + lsbit; | 890 uint32_t msbit = widthminus1 + lsbit; |
887 if (msbit <= 31) { | 891 if (msbit <= 31) { |
888 Format(instr, "ubfx'cond 'rd, 'rm, #'off7to11, #'off16to20"); | 892 if (instr->Bit(22)) { |
| 893 Format(instr, "ubfx'cond 'rd, 'rm, 'f"); |
| 894 } else { |
| 895 Format(instr, "sbfx'cond 'rd, 'rm, 'f"); |
| 896 } |
| 897 } else { |
| 898 UNREACHABLE(); |
| 899 } |
| 900 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) { |
| 901 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); |
| 902 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16)); |
| 903 if (msbit >= lsbit) { |
| 904 if (instr->RmField() == 15) { |
| 905 Format(instr, "bfc'cond 'rd, 'f"); |
| 906 } else { |
| 907 Format(instr, "bfi'cond 'rd, 'rm, 'f"); |
| 908 } |
889 } else { | 909 } else { |
890 UNREACHABLE(); | 910 UNREACHABLE(); |
891 } | 911 } |
892 } else { | 912 } else { |
893 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); | 913 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); |
894 } | 914 } |
895 break; | 915 break; |
896 } | 916 } |
897 default: { | 917 default: { |
898 // The PU field is a 2-bit field. | 918 // The PU field is a 2-bit field. |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 pc += d.InstructionDecode(buffer, pc); | 1373 pc += d.InstructionDecode(buffer, pc); |
1354 fprintf(f, "%p %08x %s\n", | 1374 fprintf(f, "%p %08x %s\n", |
1355 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1375 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1356 } | 1376 } |
1357 } | 1377 } |
1358 | 1378 |
1359 | 1379 |
1360 } // namespace disasm | 1380 } // namespace disasm |
1361 | 1381 |
1362 #endif // V8_TARGET_ARCH_ARM | 1382 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |