From 5042d6d0b49355c66daf3260d5040c3d1d373917 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:17:12 +0530 Subject: [PATCH] arch-power: Fix disassembly for load-store instructions This fixes disassembly generated for load-store instructions based on how the base classess that are used to distinguish between the types of operands used by these instructions. Change-Id: I5a0f8644cdc6fec934475536861ad342c0a1fb4c Signed-off-by: Sandipan Das --- src/arch/power/insts/mem.cc | 155 +++++++++++++++++++++++++++++++++++- src/arch/power/insts/mem.hh | 6 ++ 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/src/arch/power/insts/mem.cc b/src/arch/power/insts/mem.cc index 596d78d25..94508a7ce 100644 --- a/src/arch/power/insts/mem.cc +++ b/src/arch/power/insts/mem.cc @@ -38,6 +38,7 @@ MemOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const return csprintf("%-10s", mnemonic); } + std::string MemDispOp::generateDisassembly( Addr pc, const Loader::SymbolTable *symtab) const @@ -59,16 +60,162 @@ MemDispOp::generateDisassembly( // Print the data register for a store else { - printReg(ss, srcRegIdx(1)); + if (_numSrcRegs > 0) { + printReg(ss, srcRegIdx(0)); + } } // Print the displacement - ss << ", " << (int32_t)disp; + ss << ", " << disp; + ss << "("; - // Print the address register + // Print the address register for a load + if (!flags[IsStore]) { + if (_numSrcRegs > 0) { + printReg(ss, srcRegIdx(0)); + } + + // The address register is skipped if it is R0 + else { + ss << "0"; + } + } + + // Print the address register for a store + else { + if (_numSrcRegs > 1) { + printReg(ss, srcRegIdx(1)); + } + + // The address register is skipped if it is R0 + else { + ss << "0"; + } + } + + ss << ")"; + + return ss.str(); +} + + +std::string +MemDispShiftOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the destination only for a load + if (!flags[IsStore]) { + if (_numDestRegs > 0) { + + // If the instruction updates the source register with the + // EA, then this source register is placed in position 0, + // therefore we print the last destination register. + printReg(ss, destRegIdx(_numDestRegs-1)); + } + } + + // Print the data register for a store + else { + if (_numSrcRegs > 0) { + printReg(ss, srcRegIdx(0)); + } + } + + // Print the displacement + ss << ", " << (disp << 2); ss << "("; - printReg(ss, srcRegIdx(0)); + + // Print the address register for a load + if (!flags[IsStore]) { + if (_numSrcRegs > 0) { + printReg(ss, srcRegIdx(0)); + } + + // The address register is skipped if it is R0 + else { + ss << "0"; + } + } + + // Print the address register for a store + else { + if (_numSrcRegs > 1) { + printReg(ss, srcRegIdx(1)); + } + + // The address register is skipped if it is R0 + else { + ss << "0"; + } + } + ss << ")"; return ss.str(); } + + +std::string +MemIndexOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the destination only for a load + if (!flags[IsStore]) { + if (_numDestRegs > 0) { + + // If the instruction updates the source register with the + // EA, then this source register is placed in position 0, + // therefore we print the last destination register. + printReg(ss, destRegIdx(_numDestRegs-1)); + } + } + + // Print the data register for a store + else { + if (_numSrcRegs > 0) { + printReg(ss, srcRegIdx(0)); + } + } + + ss << ", "; + + // Print the address registers for a load + if (!flags[IsStore]) { + if (_numSrcRegs > 1) { + printReg(ss, srcRegIdx(0)); + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + + // The first address register is skipped if it is R0 + else if (_numSrcRegs > 0) { + ss << "0, "; + printReg(ss, srcRegIdx(0)); + } + } + + // Print the address registers for a store + else { + if (_numSrcRegs > 2) { + printReg(ss, srcRegIdx(1)); + ss << ", "; + printReg(ss, srcRegIdx(2)); + } + + // The first address register is skipped if it is R0 + else if (_numSrcRegs > 1) { + ss << "0, "; + printReg(ss, srcRegIdx(1)); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/mem.hh b/src/arch/power/insts/mem.hh index d14f1e6f7..f800ae3d5 100644 --- a/src/arch/power/insts/mem.hh +++ b/src/arch/power/insts/mem.hh @@ -90,6 +90,9 @@ class MemDispShiftOp : public MemOp disp(sext<14>(machInst.ds)) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -105,6 +108,9 @@ class MemIndexOp : public MemOp : MemOp(mnem, _machInst, __opClass) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; } // namespace PowerISA -- 2.30.2