From 8455995d09109fd59b7de9ff74078d845be8b442 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:17:34 +0530 Subject: [PATCH] arch-power: Fix disassembly for arithmetic instructions This fixes disassembly generated for integer add and subtract arithmetic instructions based on the type of operands and the special use cases for which the Power ISA provides extended mnemonics. Change-Id: I89b8271994e4d4b7b16efad170af5eeb5ee1aa10 Signed-off-by: Sandipan Das Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40900 Reviewed-by: Boris Shingarov Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/arch/power/insts/integer.cc | 142 ++++++++++++++++++++++++++------ src/arch/power/insts/integer.hh | 6 ++ 2 files changed, 122 insertions(+), 26 deletions(-) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index 7da5bf5ff8..2035b5c78f 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -68,15 +68,13 @@ IntOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const ccprintf(ss, "%-10s ", myMnemonic); // Print the first destination only - if (_numDestRegs > 0 && printDest) { + if (_numDestRegs > 0 && printDest) printReg(ss, destRegIdx(0)); - } // Print the (possibly) two source registers if (_numSrcRegs > 0 && printSrcs) { - if (_numDestRegs > 0 && printDest) { + if (_numDestRegs > 0 && printDest) ss << ", "; - } printReg(ss, srcRegIdx(0)); if (_numSrcRegs > 1 && printSecondSrc) { ss << ", "; @@ -93,27 +91,16 @@ IntImmOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const { std::stringstream ss; - // Generate the correct mnemonic - std::string myMnemonic(mnemonic); - - // Special cases - if (!myMnemonic.compare("addi") && _numSrcRegs == 0) { - myMnemonic = "li"; - } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) { - myMnemonic = "lis"; - } - ccprintf(ss, "%-10s ", myMnemonic); + ccprintf(ss, "%-10s ", mnemonic); // Print the first destination only - if (_numDestRegs > 0) { + if (_numDestRegs > 0) printReg(ss, destRegIdx(0)); - } // Print the source register if (_numSrcRegs > 0) { - if (_numDestRegs > 0) { + if (_numDestRegs > 0) ss << ", "; - } printReg(ss, srcRegIdx(0)); } @@ -124,6 +111,113 @@ IntImmOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const } +std::string +IntArithOp::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 == "addme" || + myMnemonic == "addze" || + myMnemonic == "subfme" || + myMnemonic == "subfze" || + myMnemonic == "neg") { + printSecondSrc = false; + } + + // Additional characters depending on isa bits being set + if (oe) + myMnemonic = myMnemonic + "o"; + if (rc) + 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 (_numSrcRegs > 1 && printSecondSrc) { + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + } + + return ss.str(); +} + + +std::string +IntImmArithOp::generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const +{ + std::stringstream ss; + bool negateImm = false; + + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (myMnemonic == "addi") { + if (_numSrcRegs == 0) { + myMnemonic = "li"; + } else if (si < 0) { + myMnemonic = "subi"; + negateImm = true; + } + } else if (myMnemonic == "addis") { + if (_numSrcRegs == 0) { + myMnemonic = "lis"; + } else if (si < 0) { + myMnemonic = "subis"; + negateImm = true; + } + } else if (myMnemonic == "addic" && si < 0) { + myMnemonic = "subic"; + negateImm = true; + } else if (myMnemonic == "addic_") { + if (si < 0) { + myMnemonic = "subic."; + negateImm = true; + } else { + myMnemonic = "addic."; + } + } + + ccprintf(ss, "%-10s ", myMnemonic); + + // 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 + if (negateImm) + ss << ", " << -si; + else + ss << ", " << si; + + return ss.str(); +} + + std::string IntShiftOp::generateDisassembly( Addr pc, const loader::SymbolTable *symtab) const @@ -133,15 +227,13 @@ IntShiftOp::generateDisassembly( ccprintf(ss, "%-10s ", mnemonic); // Print the first destination only - if (_numDestRegs > 0) { + if (_numDestRegs > 0) printReg(ss, destRegIdx(0)); - } // Print the first source register if (_numSrcRegs > 0) { - if (_numDestRegs > 0) { + if (_numDestRegs > 0) ss << ", "; - } printReg(ss, srcRegIdx(0)); } @@ -161,15 +253,13 @@ IntRotateOp::generateDisassembly( ccprintf(ss, "%-10s ", mnemonic); // Print the first destination only - if (_numDestRegs > 0) { + if (_numDestRegs > 0) printReg(ss, destRegIdx(0)); - } // Print the first source register if (_numSrcRegs > 0) { - if (_numDestRegs > 0) { + if (_numDestRegs > 0) ss << ", "; - } printReg(ss, srcRegIdx(0)); } diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh index a25e65c97d..daef626e21 100644 --- a/src/arch/power/insts/integer.hh +++ b/src/arch/power/insts/integer.hh @@ -133,6 +133,9 @@ class IntArithOp : public IntOp : IntOp(mnem, _machInst, __opClass) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; }; @@ -151,6 +154,9 @@ class IntImmArithOp : public IntArithOp si(sext<16>(machInst.si)) { } + + std::string generateDisassembly( + Addr pc, const Loader::SymbolTable *symtab) const override; };