From: Sandipan Das Date: Sat, 6 Feb 2021 11:50:56 +0000 (+0530) Subject: arch-power: Fix disassembly for compare instructions X-Git-Tag: develop-gem5-snapshot~37 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e4e0ca8b9ad1adbc57ad29b76c15bcbd272726c4;p=gem5.git arch-power: Fix disassembly for compare instructions This fixes disassembly generated for integer compare instructions based on the type of operands, the type of comparison to be made and the special use cases for which the Power ISA provides extended mnemonics. Change-Id: Ia052bef9589cc3ed290400390028398be28c8eff Signed-off-by: Sandipan Das --- diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index da7f392ea..4a03f8fa3 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -49,7 +49,6 @@ IntOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const !myMnemonic.compare("mtxer") || !myMnemonic.compare("mtlr") || !myMnemonic.compare("mtctr") || - !myMnemonic.compare("cmpi") || !myMnemonic.compare("mttar")) { printDest = false; } else if (!myMnemonic.compare("mfcr") || @@ -286,6 +285,185 @@ IntDispArithOp::generateDisassembly( } +std::string +IntCompOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printFieldPrefix = false; + bool printLength = true; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("cmp")) { + if (length) { + myMnemonic = "cmpd"; + } else { + myMnemonic = "cmpw"; + } + printFieldPrefix = true; + printLength = false; + } else if (!myMnemonic.compare("cmpl")) { + if (length) { + myMnemonic = "cmpld"; + } else { + myMnemonic = "cmplw"; + } + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (field > 0) { + ss << "cr" << field; + } + } else { + ss << field; + } + + // Print the length + if (printLength) { + if (!printFieldPrefix || field > 0) { + ss << ", "; + } + ss << length; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || field > 0 || printLength) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + + // Print the second source register + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + } + + return ss.str(); +} + + +std::string +IntImmCompOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printFieldPrefix = false; + bool printLength = true; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("cmpi")) { + if (length) { + myMnemonic = "cmpdi"; + } else { + myMnemonic = "cmpwi"; + } + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (field > 0) { + ss << "cr" << field; + } + } else { + ss << field; + } + + // Print the length + if (printLength) { + if (!printFieldPrefix || field > 0) { + ss << ", "; + } + ss << length; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || field > 0 || printLength) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << simm; + + return ss.str(); +} + + +std::string +IntImmCompLogicOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool printFieldPrefix = false; + bool printLength = true; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("cmpli")) { + if (length) { + myMnemonic = "cmpldi"; + } else { + myMnemonic = "cmplwi"; + } + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (field > 0) { + ss << "cr" << field; + } + } else { + ss << field; + } + + // Print the mode + if (printLength) { + if (!printFieldPrefix || field > 0) { + ss << ", "; + } + ss << length; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || field > 0 || printLength) { + ss << ", "; + } + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << uimm; + + return ss.str(); +} + + std::string IntShiftOp::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 75d4543e2..2cf35ab9c 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -443,6 +443,9 @@ class IntCompOp : public IntOp field(machInst.bf) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -461,6 +464,9 @@ class IntImmCompOp : public IntCompOp simm((int16_t)machInst.si) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -479,6 +485,9 @@ class IntImmCompLogicOp : public IntCompOp uimm(machInst.ui) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; };