From 75c995c104733345ebed5014668234c505e4fb6c 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40894 Reviewed-by: Boris Shingarov Maintainer: Jason Lowe-Power Tested-by: kokoro --- 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 3275623e37..a2954f8760 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 << ", " << d; - - // Print the address register 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 +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 << ", " << (ds << 2); + ss << "("; + + // 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 18f81986a0..ddb36bb83d 100644 --- a/src/arch/power/insts/mem.hh +++ b/src/arch/power/insts/mem.hh @@ -91,6 +91,9 @@ class MemDispShiftOp : public MemOp ds(sext<14>(machInst.ds)) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -106,6 +109,9 @@ class MemIndexOp : public MemOp : MemOp(mnem, _machInst, __opClass) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; } // namespace PowerISA