diff options
Diffstat (limited to 'disas/libvixl/a64/disasm-a64.cc')
-rw-r--r-- | disas/libvixl/a64/disasm-a64.cc | 259 |
1 files changed, 168 insertions, 91 deletions
diff --git a/disas/libvixl/a64/disasm-a64.cc b/disas/libvixl/a64/disasm-a64.cc index 248ebfd..e4a74aa 100644 --- a/disas/libvixl/a64/disasm-a64.cc +++ b/disas/libvixl/a64/disasm-a64.cc @@ -57,7 +57,7 @@ char* Disassembler::GetOutput() { } -void Disassembler::VisitAddSubImmediate(Instruction* instr) { +void Disassembler::VisitAddSubImmediate(const Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool stack_op = (rd_is_zr || RnIsZROrSP(instr)) && (instr->ImmAddSub() == 0) ? true : false; @@ -102,7 +102,7 @@ void Disassembler::VisitAddSubImmediate(Instruction* instr) { } -void Disassembler::VisitAddSubShifted(Instruction* instr) { +void Disassembler::VisitAddSubShifted(const Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -149,7 +149,7 @@ void Disassembler::VisitAddSubShifted(Instruction* instr) { } -void Disassembler::VisitAddSubExtended(Instruction* instr) { +void Disassembler::VisitAddSubExtended(const Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); const char *mnemonic = ""; Extend mode = static_cast<Extend>(instr->ExtendMode()); @@ -187,7 +187,7 @@ void Disassembler::VisitAddSubExtended(Instruction* instr) { } -void Disassembler::VisitAddSubWithCarry(Instruction* instr) { +void Disassembler::VisitAddSubWithCarry(const Instruction* instr) { bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; const char *form = "'Rd, 'Rn, 'Rm"; @@ -222,7 +222,7 @@ void Disassembler::VisitAddSubWithCarry(Instruction* instr) { } -void Disassembler::VisitLogicalImmediate(Instruction* instr) { +void Disassembler::VisitLogicalImmediate(const Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -294,7 +294,7 @@ bool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) { } -void Disassembler::VisitLogicalShifted(Instruction* instr) { +void Disassembler::VisitLogicalShifted(const Instruction* instr) { bool rd_is_zr = RdIsZROrSP(instr); bool rn_is_zr = RnIsZROrSP(instr); const char *mnemonic = ""; @@ -345,7 +345,7 @@ void Disassembler::VisitLogicalShifted(Instruction* instr) { } -void Disassembler::VisitConditionalCompareRegister(Instruction* instr) { +void Disassembler::VisitConditionalCompareRegister(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rn, 'Rm, 'INzcv, 'Cond"; @@ -360,7 +360,7 @@ void Disassembler::VisitConditionalCompareRegister(Instruction* instr) { } -void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { +void Disassembler::VisitConditionalCompareImmediate(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rn, 'IP, 'INzcv, 'Cond"; @@ -375,7 +375,7 @@ void Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { } -void Disassembler::VisitConditionalSelect(Instruction* instr) { +void Disassembler::VisitConditionalSelect(const Instruction* instr) { bool rnm_is_zr = (RnIsZROrSP(instr) && RmIsZROrSP(instr)); bool rn_is_rm = (instr->Rn() == instr->Rm()); const char *mnemonic = ""; @@ -428,7 +428,7 @@ void Disassembler::VisitConditionalSelect(Instruction* instr) { } -void Disassembler::VisitBitfield(Instruction* instr) { +void Disassembler::VisitBitfield(const Instruction* instr) { unsigned s = instr->ImmS(); unsigned r = instr->ImmR(); unsigned rd_size_minus_1 = @@ -506,7 +506,7 @@ void Disassembler::VisitBitfield(Instruction* instr) { } -void Disassembler::VisitExtract(Instruction* instr) { +void Disassembler::VisitExtract(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Rn, 'Rm, 'IExtract"; @@ -527,7 +527,7 @@ void Disassembler::VisitExtract(Instruction* instr) { } -void Disassembler::VisitPCRelAddressing(Instruction* instr) { +void Disassembler::VisitPCRelAddressing(const Instruction* instr) { switch (instr->Mask(PCRelAddressingMask)) { case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; case ADRP: Format(instr, "adrp", "'Xd, 'AddrPCRelPage"); break; @@ -536,7 +536,7 @@ void Disassembler::VisitPCRelAddressing(Instruction* instr) { } -void Disassembler::VisitConditionalBranch(Instruction* instr) { +void Disassembler::VisitConditionalBranch(const Instruction* instr) { switch (instr->Mask(ConditionalBranchMask)) { case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break; default: VIXL_UNREACHABLE(); @@ -544,7 +544,8 @@ void Disassembler::VisitConditionalBranch(Instruction* instr) { } -void Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { +void Disassembler::VisitUnconditionalBranchToRegister( + const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Xn"; @@ -564,7 +565,7 @@ void Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { } -void Disassembler::VisitUnconditionalBranch(Instruction* instr) { +void Disassembler::VisitUnconditionalBranch(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'BImmUncn"; @@ -577,7 +578,7 @@ void Disassembler::VisitUnconditionalBranch(Instruction* instr) { } -void Disassembler::VisitDataProcessing1Source(Instruction* instr) { +void Disassembler::VisitDataProcessing1Source(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Rn"; @@ -598,7 +599,7 @@ void Disassembler::VisitDataProcessing1Source(Instruction* instr) { } -void Disassembler::VisitDataProcessing2Source(Instruction* instr) { +void Disassembler::VisitDataProcessing2Source(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Rd, 'Rn, 'Rm"; @@ -619,7 +620,7 @@ void Disassembler::VisitDataProcessing2Source(Instruction* instr) { } -void Disassembler::VisitDataProcessing3Source(Instruction* instr) { +void Disassembler::VisitDataProcessing3Source(const Instruction* instr) { bool ra_is_zr = RaIsZROrSP(instr); const char *mnemonic = ""; const char *form = "'Xd, 'Wn, 'Wm, 'Xa"; @@ -697,7 +698,7 @@ void Disassembler::VisitDataProcessing3Source(Instruction* instr) { } -void Disassembler::VisitCompareBranch(Instruction* instr) { +void Disassembler::VisitCompareBranch(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rt, 'BImmCmpa"; @@ -712,7 +713,7 @@ void Disassembler::VisitCompareBranch(Instruction* instr) { } -void Disassembler::VisitTestBranch(Instruction* instr) { +void Disassembler::VisitTestBranch(const Instruction* instr) { const char *mnemonic = ""; // If the top bit of the immediate is clear, the tested register is // disassembled as Wt, otherwise Xt. As the top bit of the immediate is @@ -729,7 +730,7 @@ void Disassembler::VisitTestBranch(Instruction* instr) { } -void Disassembler::VisitMoveWideImmediate(Instruction* instr) { +void Disassembler::VisitMoveWideImmediate(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'IMoveImm"; @@ -768,7 +769,7 @@ void Disassembler::VisitMoveWideImmediate(Instruction* instr) { V(LDR_s, "ldr", "'St") \ V(LDR_d, "ldr", "'Dt") -void Disassembler::VisitLoadStorePreIndex(Instruction* instr) { +void Disassembler::VisitLoadStorePreIndex(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePreIndex)"; @@ -782,7 +783,7 @@ void Disassembler::VisitLoadStorePreIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePostIndex(Instruction* instr) { +void Disassembler::VisitLoadStorePostIndex(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePostIndex)"; @@ -796,7 +797,7 @@ void Disassembler::VisitLoadStorePostIndex(Instruction* instr) { } -void Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { +void Disassembler::VisitLoadStoreUnsignedOffset(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreUnsignedOffset)"; @@ -811,7 +812,7 @@ void Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { } -void Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { +void Disassembler::VisitLoadStoreRegisterOffset(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreRegisterOffset)"; @@ -826,7 +827,7 @@ void Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { } -void Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { +void Disassembler::VisitLoadStoreUnscaledOffset(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Wt, ['Xns'ILS]"; const char *form_x = "'Xt, ['Xns'ILS]"; @@ -857,7 +858,7 @@ void Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { } -void Disassembler::VisitLoadLiteral(Instruction* instr) { +void Disassembler::VisitLoadLiteral(const Instruction* instr) { const char *mnemonic = "ldr"; const char *form = "(LoadLiteral)"; @@ -866,6 +867,11 @@ void Disassembler::VisitLoadLiteral(Instruction* instr) { case LDR_x_lit: form = "'Xt, 'ILLiteral 'LValue"; break; case LDR_s_lit: form = "'St, 'ILLiteral 'LValue"; break; case LDR_d_lit: form = "'Dt, 'ILLiteral 'LValue"; break; + case LDRSW_x_lit: { + mnemonic = "ldrsw"; + form = "'Xt, 'ILLiteral 'LValue"; + break; + } default: mnemonic = "unimplemented"; } Format(instr, mnemonic, form); @@ -883,7 +889,7 @@ void Disassembler::VisitLoadLiteral(Instruction* instr) { V(STP_d, "stp", "'Dt, 'Dt2", "8") \ V(LDP_d, "ldp", "'Dt, 'Dt2", "8") -void Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { +void Disassembler::VisitLoadStorePairPostIndex(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPostIndex)"; @@ -897,7 +903,7 @@ void Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { +void Disassembler::VisitLoadStorePairPreIndex(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPreIndex)"; @@ -911,7 +917,7 @@ void Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { } -void Disassembler::VisitLoadStorePairOffset(Instruction* instr) { +void Disassembler::VisitLoadStorePairOffset(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairOffset)"; @@ -925,7 +931,7 @@ void Disassembler::VisitLoadStorePairOffset(Instruction* instr) { } -void Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) { +void Disassembler::VisitLoadStorePairNonTemporal(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form; @@ -944,7 +950,7 @@ void Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) { } -void Disassembler::VisitLoadStoreExclusive(Instruction* instr) { +void Disassembler::VisitLoadStoreExclusive(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form; @@ -987,7 +993,7 @@ void Disassembler::VisitLoadStoreExclusive(Instruction* instr) { } -void Disassembler::VisitFPCompare(Instruction* instr) { +void Disassembler::VisitFPCompare(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Fn, 'Fm"; const char *form_zero = "'Fn, #0.0"; @@ -1003,7 +1009,7 @@ void Disassembler::VisitFPCompare(Instruction* instr) { } -void Disassembler::VisitFPConditionalCompare(Instruction* instr) { +void Disassembler::VisitFPConditionalCompare(const Instruction* instr) { const char *mnemonic = "unmplemented"; const char *form = "'Fn, 'Fm, 'INzcv, 'Cond"; @@ -1018,7 +1024,7 @@ void Disassembler::VisitFPConditionalCompare(Instruction* instr) { } -void Disassembler::VisitFPConditionalSelect(Instruction* instr) { +void Disassembler::VisitFPConditionalSelect(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm, 'Cond"; @@ -1031,7 +1037,7 @@ void Disassembler::VisitFPConditionalSelect(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { +void Disassembler::VisitFPDataProcessing1Source(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'Fd, 'Fn"; @@ -1059,7 +1065,7 @@ void Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { +void Disassembler::VisitFPDataProcessing2Source(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm"; @@ -1083,7 +1089,7 @@ void Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { } -void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { +void Disassembler::VisitFPDataProcessing3Source(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Fd, 'Fn, 'Fm, 'Fa"; @@ -1102,7 +1108,7 @@ void Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { } -void Disassembler::VisitFPImmediate(Instruction* instr) { +void Disassembler::VisitFPImmediate(const Instruction* instr) { const char *mnemonic = ""; const char *form = "(FPImmediate)"; @@ -1115,7 +1121,7 @@ void Disassembler::VisitFPImmediate(Instruction* instr) { } -void Disassembler::VisitFPIntegerConvert(Instruction* instr) { +void Disassembler::VisitFPIntegerConvert(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "(FPIntegerConvert)"; const char *form_rf = "'Rd, 'Fn"; @@ -1171,7 +1177,7 @@ void Disassembler::VisitFPIntegerConvert(Instruction* instr) { } -void Disassembler::VisitFPFixedPointConvert(Instruction* instr) { +void Disassembler::VisitFPFixedPointConvert(const Instruction* instr) { const char *mnemonic = ""; const char *form = "'Rd, 'Fn, 'IFPFBits"; const char *form_fr = "'Fd, 'Rn, 'IFPFBits"; @@ -1199,7 +1205,7 @@ void Disassembler::VisitFPFixedPointConvert(Instruction* instr) { } -void Disassembler::VisitSystem(Instruction* instr) { +void Disassembler::VisitSystem(const Instruction* instr) { // Some system instructions hijack their Op and Cp fields to represent a // range of immediates instead of indicating a different instruction. This // makes the decoding tricky. @@ -1267,7 +1273,7 @@ void Disassembler::VisitSystem(Instruction* instr) { } -void Disassembler::VisitException(Instruction* instr) { +void Disassembler::VisitException(const Instruction* instr) { const char *mnemonic = "unimplemented"; const char *form = "'IDebug"; @@ -1286,22 +1292,75 @@ void Disassembler::VisitException(Instruction* instr) { } -void Disassembler::VisitUnimplemented(Instruction* instr) { +void Disassembler::VisitUnimplemented(const Instruction* instr) { Format(instr, "unimplemented", "(Unimplemented)"); } -void Disassembler::VisitUnallocated(Instruction* instr) { +void Disassembler::VisitUnallocated(const Instruction* instr) { Format(instr, "unallocated", "(Unallocated)"); } -void Disassembler::ProcessOutput(Instruction* /*instr*/) { +void Disassembler::ProcessOutput(const Instruction* /*instr*/) { // The base disasm does nothing more than disassembling into a buffer. } -void Disassembler::Format(Instruction* instr, const char* mnemonic, +void Disassembler::AppendRegisterNameToOutput(const Instruction* instr, + const CPURegister& reg) { + USE(instr); + VIXL_ASSERT(reg.IsValid()); + char reg_char; + + if (reg.IsRegister()) { + reg_char = reg.Is64Bits() ? 'x' : 'w'; + } else { + VIXL_ASSERT(reg.IsFPRegister()); + reg_char = reg.Is64Bits() ? 'd' : 's'; + } + + if (reg.IsFPRegister() || !(reg.Aliases(sp) || reg.Aliases(xzr))) { + // A normal register: w0 - w30, x0 - x30, s0 - s31, d0 - d31. + AppendToOutput("%c%d", reg_char, reg.code()); + } else if (reg.Aliases(sp)) { + // Disassemble w31/x31 as stack pointer wsp/sp. + AppendToOutput("%s", reg.Is64Bits() ? "sp" : "wsp"); + } else { + // Disassemble w31/x31 as zero register wzr/xzr. + AppendToOutput("%czr", reg_char); + } +} + + +void Disassembler::AppendPCRelativeOffsetToOutput(const Instruction* instr, + int64_t offset) { + USE(instr); + char sign = (offset < 0) ? '-' : '+'; + AppendToOutput("#%c0x%" PRIx64, sign, std::abs(offset)); +} + + +void Disassembler::AppendAddressToOutput(const Instruction* instr, + const void* addr) { + USE(instr); + AppendToOutput("(addr %p)", addr); +} + + +void Disassembler::AppendCodeAddressToOutput(const Instruction* instr, + const void* addr) { + AppendAddressToOutput(instr, addr); +} + + +void Disassembler::AppendDataAddressToOutput(const Instruction* instr, + const void* addr) { + AppendAddressToOutput(instr, addr); +} + + +void Disassembler::Format(const Instruction* instr, const char* mnemonic, const char* format) { VIXL_ASSERT(mnemonic != NULL); ResetOutput(); @@ -1315,7 +1374,7 @@ void Disassembler::Format(Instruction* instr, const char* mnemonic, } -void Disassembler::Substitute(Instruction* instr, const char* string) { +void Disassembler::Substitute(const Instruction* instr, const char* string) { char chr = *string++; while (chr != '\0') { if (chr == '\'') { @@ -1328,7 +1387,8 @@ void Disassembler::Substitute(Instruction* instr, const char* string) { } -int Disassembler::SubstituteField(Instruction* instr, const char* format) { +int Disassembler::SubstituteField(const Instruction* instr, + const char* format) { switch (format[0]) { case 'R': // Register. X or W, selected by sf bit. case 'F': // FP Register. S or D, selected by type field. @@ -1354,7 +1414,7 @@ int Disassembler::SubstituteField(Instruction* instr, const char* format) { } -int Disassembler::SubstituteRegisterField(Instruction* instr, +int Disassembler::SubstituteRegisterField(const Instruction* instr, const char* format) { unsigned reg_num = 0; unsigned field_len = 2; @@ -1381,34 +1441,47 @@ int Disassembler::SubstituteRegisterField(Instruction* instr, field_len = 3; } - char reg_type; + CPURegister::RegisterType reg_type; + unsigned reg_size; + if (format[0] == 'R') { // Register type is R: use sf bit to choose X and W. - reg_type = instr->SixtyFourBits() ? 'x' : 'w'; + reg_type = CPURegister::kRegister; + reg_size = instr->SixtyFourBits() ? kXRegSize : kWRegSize; } else if (format[0] == 'F') { // Floating-point register: use type field to choose S or D. - reg_type = ((instr->FPType() & 1) == 0) ? 's' : 'd'; + reg_type = CPURegister::kFPRegister; + reg_size = ((instr->FPType() & 1) == 0) ? kSRegSize : kDRegSize; } else { - // Register type is specified. Make it lower case. - reg_type = format[0] + 0x20; + // The register type is specified. + switch (format[0]) { + case 'W': + reg_type = CPURegister::kRegister; reg_size = kWRegSize; break; + case 'X': + reg_type = CPURegister::kRegister; reg_size = kXRegSize; break; + case 'S': + reg_type = CPURegister::kFPRegister; reg_size = kSRegSize; break; + case 'D': + reg_type = CPURegister::kFPRegister; reg_size = kDRegSize; break; + default: + VIXL_UNREACHABLE(); + reg_type = CPURegister::kRegister; + reg_size = kXRegSize; + } } - if ((reg_num != kZeroRegCode) || (reg_type == 's') || (reg_type == 'd')) { - // A normal register: w0 - w30, x0 - x30, s0 - s31, d0 - d31. - AppendToOutput("%c%d", reg_type, reg_num); - } else if (format[2] == 's') { - // Disassemble w31/x31 as stack pointer wsp/sp. - AppendToOutput("%s", (reg_type == 'w') ? "wsp" : "sp"); - } else { - // Disassemble w31/x31 as zero register wzr/xzr. - AppendToOutput("%czr", reg_type); + if ((reg_type == CPURegister::kRegister) && + (reg_num == kZeroRegCode) && (format[2] == 's')) { + reg_num = kSPRegInternalCode; } + AppendRegisterNameToOutput(instr, CPURegister(reg_num, reg_size, reg_type)); + return field_len; } -int Disassembler::SubstituteImmediateField(Instruction* instr, +int Disassembler::SubstituteImmediateField(const Instruction* instr, const char* format) { VIXL_ASSERT(format[0] == 'I'); @@ -1458,8 +1531,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, } case 'C': { // ICondB - Immediate Conditional Branch. int64_t offset = instr->ImmCondBranch() << 2; - char sign = (offset >= 0) ? '+' : '-'; - AppendToOutput("#%c0x%" PRIx64, sign, offset); + AppendPCRelativeOffsetToOutput(instr, offset); return 6; } case 'A': { // IAddSub. @@ -1522,7 +1594,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, } -int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, +int Disassembler::SubstituteBitfieldImmediateField(const Instruction* instr, const char* format) { VIXL_ASSERT((format[0] == 'I') && (format[1] == 'B')); unsigned r = instr->ImmR(); @@ -1557,7 +1629,7 @@ int Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, } -int Disassembler::SubstituteLiteralField(Instruction* instr, +int Disassembler::SubstituteLiteralField(const Instruction* instr, const char* format) { VIXL_ASSERT(strncmp(format, "LValue", 6) == 0); USE(format); @@ -1565,16 +1637,21 @@ int Disassembler::SubstituteLiteralField(Instruction* instr, switch (instr->Mask(LoadLiteralMask)) { case LDR_w_lit: case LDR_x_lit: + case LDRSW_x_lit: case LDR_s_lit: - case LDR_d_lit: AppendToOutput("(addr %p)", instr->LiteralAddress()); break; - default: VIXL_UNREACHABLE(); + case LDR_d_lit: + AppendDataAddressToOutput(instr, instr->LiteralAddress()); + break; + default: + VIXL_UNREACHABLE(); } return 6; } -int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { +int Disassembler::SubstituteShiftField(const Instruction* instr, + const char* format) { VIXL_ASSERT(format[0] == 'H'); VIXL_ASSERT(instr->ShiftDP() <= 0x3); @@ -1597,7 +1674,7 @@ int Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { } -int Disassembler::SubstituteConditionField(Instruction* instr, +int Disassembler::SubstituteConditionField(const Instruction* instr, const char* format) { VIXL_ASSERT(format[0] == 'C'); const char* condition_code[] = { "eq", "ne", "hs", "lo", @@ -1618,27 +1695,28 @@ int Disassembler::SubstituteConditionField(Instruction* instr, } -int Disassembler::SubstitutePCRelAddressField(Instruction* instr, +int Disassembler::SubstitutePCRelAddressField(const Instruction* instr, const char* format) { VIXL_ASSERT((strcmp(format, "AddrPCRelByte") == 0) || // Used by `adr`. (strcmp(format, "AddrPCRelPage") == 0)); // Used by `adrp`. int64_t offset = instr->ImmPCRel(); - Instruction * base = instr; + const Instruction * base = instr; if (format[9] == 'P') { offset *= kPageSize; base = AlignDown(base, kPageSize); } - char sign = (offset < 0) ? '-' : '+'; - void * target = reinterpret_cast<void *>(base + offset); - AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, std::abs(offset), target); + const void* target = reinterpret_cast<const void*>(base + offset); + AppendPCRelativeOffsetToOutput(instr, offset); + AppendToOutput(" "); + AppendAddressToOutput(instr, target); return 13; } -int Disassembler::SubstituteBranchTargetField(Instruction* instr, +int Disassembler::SubstituteBranchTargetField(const Instruction* instr, const char* format) { VIXL_ASSERT(strncmp(format, "BImm", 4) == 0); @@ -1655,19 +1733,18 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr, default: VIXL_UNIMPLEMENTED(); } offset <<= kInstructionSizeLog2; - char sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } + const void* target_address = reinterpret_cast<const void*>(instr + offset); VIXL_STATIC_ASSERT(sizeof(*instr) == 1); - void * address = reinterpret_cast<void *>(instr + offset); - AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, address); + + AppendPCRelativeOffsetToOutput(instr, offset); + AppendToOutput(" "); + AppendCodeAddressToOutput(instr, target_address); + return 8; } -int Disassembler::SubstituteExtendField(Instruction* instr, +int Disassembler::SubstituteExtendField(const Instruction* instr, const char* format) { VIXL_ASSERT(strncmp(format, "Ext", 3) == 0); VIXL_ASSERT(instr->ExtendMode() <= 7); @@ -1694,7 +1771,7 @@ int Disassembler::SubstituteExtendField(Instruction* instr, } -int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, +int Disassembler::SubstituteLSRegOffsetField(const Instruction* instr, const char* format) { VIXL_ASSERT(strncmp(format, "Offsetreg", 9) == 0); const char* extend_mode[] = { "undefined", "undefined", "uxtw", "lsl", @@ -1723,7 +1800,7 @@ int Disassembler::SubstituteLSRegOffsetField(Instruction* instr, } -int Disassembler::SubstitutePrefetchField(Instruction* instr, +int Disassembler::SubstitutePrefetchField(const Instruction* instr, const char* format) { VIXL_ASSERT(format[0] == 'P'); USE(format); @@ -1738,7 +1815,7 @@ int Disassembler::SubstitutePrefetchField(Instruction* instr, return 6; } -int Disassembler::SubstituteBarrierField(Instruction* instr, +int Disassembler::SubstituteBarrierField(const Instruction* instr, const char* format) { VIXL_ASSERT(format[0] == 'M'); USE(format); @@ -1770,7 +1847,7 @@ void Disassembler::AppendToOutput(const char* format, ...) { } -void PrintDisassembler::ProcessOutput(Instruction* instr) { +void PrintDisassembler::ProcessOutput(const Instruction* instr) { fprintf(stream_, "0x%016" PRIx64 " %08" PRIx32 "\t\t%s\n", reinterpret_cast<uint64_t>(instr), instr->InstructionBits(), |