From 4e1973afdf08a3eaed0bea50e7b62ea992541e42 Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:22:03 +0530 Subject: [PATCH] arch-power: Fix disassembly for rotate instructions This fixes disassembly generated for integer rotate instructions based on special use cases for which the Power ISA provides extended mnemonics. Change-Id: I8c33e7c8128ad62d856ce050df8a91b2dfd52f4c Signed-off-by: Sandipan Das --- src/arch/power/insts/integer.cc | 68 +++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index d921b5d1b..aaa79253f 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -712,8 +712,40 @@ IntRotateOp::generateDisassembly( Addr pc, const Loader::SymbolTable *symtab) const { std::stringstream ss; + bool printSecondSrc = true; + bool printShift = true; + bool printMaskBeg = true; + bool printMaskEnd = true; - ccprintf(ss, "%-10s ", mnemonic); + // Generate the correct mnemonic + std::string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("rlwinm")) { + if (maskBeg == 0 && maskEnd == 31) { + myMnemonic = "rotlwi"; + printMaskBeg = false; + printMaskEnd = false; + } else if (shift == 0 && maskEnd == 31) { + myMnemonic = "clrlwi"; + printShift = false; + printMaskEnd = false; + } + printSecondSrc = false; + } else if (!myMnemonic.compare("rlwnm")) { + if (maskBeg == 0 && maskEnd == 31) { + myMnemonic = "rotlw"; + printMaskBeg = false; + printMaskEnd = false; + } + printShift = false; + } else if (!myMnemonic.compare("rlwimi")) { + 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) { @@ -726,10 +758,40 @@ IntRotateOp::generateDisassembly( 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)); + } + } + } + } + + // Print the shift value + if (printShift) { + ss << ", " << shift; } - // Print the shift, mask begin and mask end - ss << ", " << sh << ", " << maskBeg << ", " << maskEnd; + // Print the mask bounds + if (printMaskBeg) { + ss << ", " << maskBeg; + } + if (printMaskEnd) { + ss << ", " << maskEnd; + } return ss.str(); } -- 2.30.2