From 5a9d543311a8afc0bdd279d11dcf4712988bbd3f Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:20:56 +0530 Subject: [PATCH] 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40914 Reviewed-by: Boris Shingarov Maintainer: Boris Shingarov Tested-by: kokoro --- src/arch/power/insts/integer.cc | 154 +++++++++++++++++++++++++++++++- src/arch/power/insts/integer.hh | 9 ++ 2 files changed, 161 insertions(+), 2 deletions(-) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 61b7f08f22..95de652e8b 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -49,8 +49,7 @@ IntOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const myMnemonic == "mtxer" || myMnemonic == "mtlr" || myMnemonic == "mtctr" || - myMnemonic == "mttar" || - myMnemonic == "cmpi") { + myMnemonic == "mttar") { printDest = false; } else if (myMnemonic == "mfcr" || myMnemonic == "mfxer" || @@ -274,6 +273,157 @@ 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 == "cmp" || + myMnemonic == "cmpl") { + myMnemonic += l ? "d" : "w"; + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (bf > 0) + ss << "cr" << (int) bf; + } else { + ss << (int) bf; + } + + // Print the length + if (printLength) { + if (!printFieldPrefix || bf > 0) + ss << ", "; + ss << (int) l; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || bf > 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 == "cmpi") { + myMnemonic = l ? "cmpdi" : "cmpwi"; + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (bf > 0) + ss << "cr" << (int) bf; + } else { + ss << (int) bf; + } + + // Print the length + if (printLength) { + if (!printFieldPrefix || bf > 0) + ss << ", "; + ss << (int) l; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || bf > 0 || printLength) + ss << ", "; + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << si; + + 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 == "cmpli") { + myMnemonic = l ? "cmpldi" : "cmplwi"; + printFieldPrefix = true; + printLength = false; + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (printFieldPrefix) { + if (bf > 0) + ss << "cr" << (int) bf; + } else { + ss << (int) bf; + } + + // Print the length + if (printLength) { + if (!printFieldPrefix || bf > 0) + ss << ", "; + ss << (int) l; + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (!printFieldPrefix || bf > 0 || printLength) + ss << ", "; + printReg(ss, srcRegIdx(0)); + } + + // Print the immediate value + ss << ", " << ui; + + 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 6fb797a95d..64ba635ec6 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -423,6 +423,9 @@ class IntCompOp : public IntOp bf(machInst.bf) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -441,6 +444,9 @@ class IntImmCompOp : public IntCompOp si(sext<16>(machInst.si)) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -459,6 +465,9 @@ class IntImmCompLogicOp : public IntCompOp ui(machInst.ui) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; };