| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 return 15; | 550 return 15; |
| 551 } | 551 } |
| 552 // 'off8: 8-bit offset for extra load and store instructions | 552 // 'off8: 8-bit offset for extra load and store instructions |
| 553 ASSERT(STRING_STARTS_WITH(format, "off8")); | 553 ASSERT(STRING_STARTS_WITH(format, "off8")); |
| 554 int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue(); | 554 int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue(); |
| 555 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 555 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
| 556 "%d", offs8); | 556 "%d", offs8); |
| 557 return 4; | 557 return 4; |
| 558 } | 558 } |
| 559 case 'p': { // 'pu: P and U bits for load and store instructions | 559 case 'p': { // 'pu: P and U bits for load and store instructions |
| 560 ASSERT(STRING_STARTS_WITH(format, "pu")); | 560 if (STRING_STARTS_WITH(format, "pu")) { |
| 561 PrintPU(instr); | 561 PrintPU(instr); |
| 562 return 2; | 562 return 2; |
| 563 } else { |
| 564 ASSERT(STRING_STARTS_WITH(format, "preload")); |
| 565 Print("pld"); |
| 566 return 7; |
| 567 } |
| 563 } | 568 } |
| 564 case 'r': { | 569 case 'r': { |
| 565 return FormatRegister(instr, format); | 570 return FormatRegister(instr, format); |
| 566 } | 571 } |
| 567 case 's': { | 572 case 's': { |
| 568 if (format[1] == 'h') { // 'shift_op or 'shift_rm or 'shift_sat. | 573 if (format[1] == 'h') { // 'shift_op or 'shift_rm or 'shift_sat. |
| 569 if (format[6] == 'o') { // 'shift_op | 574 if (format[6] == 'o') { // 'shift_op |
| 570 ASSERT(STRING_STARTS_WITH(format, "shift_op")); | 575 ASSERT(STRING_STARTS_WITH(format, "shift_op")); |
| 571 if (instr->TypeValue() == 0) { | 576 if (instr->TypeValue() == 0) { |
| 572 PrintShiftRm(instr); | 577 PrintShiftRm(instr); |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 } | 954 } |
| 950 case ia_x: { | 955 case ia_x: { |
| 951 if (instr->HasW()) { | 956 if (instr->HasW()) { |
| 952 Unknown(instr); // not used in V8 | 957 Unknown(instr); // not used in V8 |
| 953 return; | 958 return; |
| 954 } | 959 } |
| 955 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); | 960 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); |
| 956 break; | 961 break; |
| 957 } | 962 } |
| 958 case db_x: { | 963 case db_x: { |
| 959 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); | 964 if (instr->ConditionField() == kSpecialCondition) { |
| 965 Format(instr, "'preload ['rn, #-'off12]"); |
| 966 } else { |
| 967 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); |
| 968 } |
| 960 break; | 969 break; |
| 961 } | 970 } |
| 962 case ib_x: { | 971 case ib_x: { |
| 963 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); | 972 if (instr->ConditionField() == kSpecialCondition) { |
| 973 Format(instr, "'preload ['rn, #+'off12]"); |
| 974 } else { |
| 975 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); |
| 976 } |
| 964 break; | 977 break; |
| 965 } | 978 } |
| 966 default: { | 979 default: { |
| 967 // The PU field is a 2-bit field. | 980 // The PU field is a 2-bit field. |
| 968 UNREACHABLE(); | 981 UNREACHABLE(); |
| 969 break; | 982 break; |
| 970 } | 983 } |
| 971 } | 984 } |
| 972 } | 985 } |
| 973 | 986 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 997 if (!instr->HasW()) { | 1010 if (!instr->HasW()) { |
| 998 if (instr->Bits(5, 4) == 0x1) { | 1011 if (instr->Bits(5, 4) == 0x1) { |
| 999 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { | 1012 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { |
| 1000 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs | 1013 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs |
| 1001 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); | 1014 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); |
| 1002 break; | 1015 break; |
| 1003 } | 1016 } |
| 1004 } | 1017 } |
| 1005 } | 1018 } |
| 1006 } | 1019 } |
| 1007 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); | 1020 if (instr->ConditionField() == kSpecialCondition) { |
| 1021 Format(instr, "'preload ['rn, -'shift_rm]"); |
| 1022 } else { |
| 1023 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); |
| 1024 } |
| 1008 break; | 1025 break; |
| 1009 } | 1026 } |
| 1010 case ib_x: { | 1027 case ib_x: { |
| 1011 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { | 1028 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { |
| 1012 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); | 1029 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); |
| 1013 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); | 1030 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); |
| 1014 uint32_t msbit = widthminus1 + lsbit; | 1031 uint32_t msbit = widthminus1 + lsbit; |
| 1015 if (msbit <= 31) { | 1032 if (msbit <= 31) { |
| 1016 if (instr->Bit(22)) { | 1033 if (instr->Bit(22)) { |
| 1017 Format(instr, "ubfx'cond 'rd, 'rm, 'f"); | 1034 Format(instr, "ubfx'cond 'rd, 'rm, 'f"); |
| 1018 } else { | 1035 } else { |
| 1019 Format(instr, "sbfx'cond 'rd, 'rm, 'f"); | 1036 Format(instr, "sbfx'cond 'rd, 'rm, 'f"); |
| 1020 } | 1037 } |
| 1021 } else { | 1038 } else { |
| 1022 UNREACHABLE(); | 1039 UNREACHABLE(); |
| 1023 } | 1040 } |
| 1024 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) { | 1041 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) { |
| 1025 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); | 1042 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); |
| 1026 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16)); | 1043 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16)); |
| 1027 if (msbit >= lsbit) { | 1044 if (msbit >= lsbit) { |
| 1028 if (instr->RmValue() == 15) { | 1045 if (instr->RmValue() == 15) { |
| 1029 Format(instr, "bfc'cond 'rd, 'f"); | 1046 Format(instr, "bfc'cond 'rd, 'f"); |
| 1030 } else { | 1047 } else { |
| 1031 Format(instr, "bfi'cond 'rd, 'rm, 'f"); | 1048 Format(instr, "bfi'cond 'rd, 'rm, 'f"); |
| 1032 } | 1049 } |
| 1033 } else { | 1050 } else { |
| 1034 UNREACHABLE(); | 1051 UNREACHABLE(); |
| 1035 } | 1052 } |
| 1053 } else if (instr->ConditionField() == kSpecialCondition) { |
| 1054 Format(instr, "'preload ['rn, +'shift_rm]"); |
| 1036 } else { | 1055 } else { |
| 1037 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); | 1056 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); |
| 1038 } | 1057 } |
| 1039 break; | 1058 break; |
| 1040 } | 1059 } |
| 1041 default: { | 1060 default: { |
| 1042 // The PU field is a 2-bit field. | 1061 // The PU field is a 2-bit field. |
| 1043 UNREACHABLE(); | 1062 UNREACHABLE(); |
| 1044 break; | 1063 break; |
| 1045 } | 1064 } |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1424 } | 1443 } |
| 1425 | 1444 |
| 1426 | 1445 |
| 1427 // Disassemble the instruction at *instr_ptr into the output buffer. | 1446 // Disassemble the instruction at *instr_ptr into the output buffer. |
| 1428 int Decoder::InstructionDecode(byte* instr_ptr) { | 1447 int Decoder::InstructionDecode(byte* instr_ptr) { |
| 1429 Instruction* instr = Instruction::At(instr_ptr); | 1448 Instruction* instr = Instruction::At(instr_ptr); |
| 1430 // Print raw instruction bytes. | 1449 // Print raw instruction bytes. |
| 1431 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 1450 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
| 1432 "%08x ", | 1451 "%08x ", |
| 1433 instr->InstructionBits()); | 1452 instr->InstructionBits()); |
| 1434 if (instr->ConditionField() == kSpecialCondition) { | 1453 if (instr->ConditionField() == kSpecialCondition && !instr->IsPld()) { |
| 1435 Unknown(instr); | 1454 Unknown(instr); |
| 1436 return Instruction::kInstrSize; | 1455 return Instruction::kInstrSize; |
| 1437 } | 1456 } |
| 1438 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1457 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
| 1439 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { | 1458 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { |
| 1440 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 1459 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
| 1441 "constant pool begin (length %d)", | 1460 "constant pool begin (length %d)", |
| 1442 DecodeConstantPoolLength(instruction_bits)); | 1461 DecodeConstantPoolLength(instruction_bits)); |
| 1443 return Instruction::kInstrSize; | 1462 return Instruction::kInstrSize; |
| 1444 } | 1463 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 pc += d.InstructionDecode(buffer, pc); | 1575 pc += d.InstructionDecode(buffer, pc); |
| 1557 fprintf(f, "%p %08x %s\n", | 1576 fprintf(f, "%p %08x %s\n", |
| 1558 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1577 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
| 1559 } | 1578 } |
| 1560 } | 1579 } |
| 1561 | 1580 |
| 1562 | 1581 |
| 1563 } // namespace disasm | 1582 } // namespace disasm |
| 1564 | 1583 |
| 1565 #endif // V8_TARGET_ARCH_ARM | 1584 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |