From efbcd5f0154344a907e843a15c35248db2c2f57d Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:21:12 +0530 Subject: [PATCH] arch-power: Fix disassembly for logical instructions This fixes disassembly generated for integer logical instructions based on the type of operands and special use cases for which the Power ISA provides extended mnemonics. Change-Id: I6b67569ef413b0b542e35082ca360c9b4262fc5b Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.cc | 111 ++++++++++++++++++++++++++++++++ src/arch/power/insts/integer.hh | 6 ++ 2 files changed, 117 insertions(+) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 4a03f8fa3..c937a6f8f 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -285,6 +285,117 @@ IntDispArithOp::generateDisassembly( } +std::string +IntLogicOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printSecondSrc = true; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("or") && srcRegIdx(0) == srcRegIdx(1)) { + myMnemonic = "mr"; + printSecondSrc = false; + } else if (!myMnemonic.compare("extsb") || + !myMnemonic.compare("extsh") || + !myMnemonic.compare("cntlzw")) { + printSecondSrc = false; + } + + // Additional characters depending on isa bits being set + if (rcSet) myMnemonic = myMnemonic + "."; + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, destRegIdx(0)); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + + // Print the second source register + if (printSecondSrc) { + + // If the instruction updates the CR, the destination register + // Ra is read and thus, it becomes the second source register + // due to its higher precedence over Rb. In this case, it must + // be skipped. + if (rcSet) { + if (_numSrcRegs > 2) { + ss << ", "; + printReg(ss, srcRegIdx(2)); + } + } else { + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + } + } + } + + return ss.str(); +} + + +std::string +IntImmLogicOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printRegs = true; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("ori") && + destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) { + myMnemonic = "nop"; + printRegs = false; + } else if (!myMnemonic.compare("xori") && + destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) { + myMnemonic = "xnop"; + printRegs = false; + } else if (!myMnemonic.compare("andi_")) { + myMnemonic = "andi."; + } else if (!myMnemonic.compare("andis_")) { + myMnemonic = "andis."; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + if (printRegs) { + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, destRegIdx(0)); + } + + // Print the source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << uimm; + } + + return ss.str(); +} + + std::string IntCompOp::generateDisassembly( Addr pc, const Loader::SymbolTable *symtab) const diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index d310e7340..a3d99ff33 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -518,6 +518,9 @@ class IntLogicOp : public IntOp return 32; } } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -536,6 +539,9 @@ class IntImmLogicOp : public IntLogicOp uimm(machInst.si) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; -- 2.30.2