From 59ae544eb3af663ed4e309ef6e804e8182e55560 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 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40931 Reviewed-by: Boris Shingarov Maintainer: Boris Shingarov Tested-by: kokoro --- src/arch/power/insts/integer.cc | 66 +++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc index e59532d7eb..87efc1da61 100644 --- a/src/arch/power/insts/integer.cc +++ b/src/arch/power/insts/integer.cc @@ -661,8 +661,41 @@ 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 == "rlwinm") { + if (mb == 0 && me == 31) { + myMnemonic = "rotlwi"; + printMaskBeg = false; + printMaskEnd = false; + } else if (sh == 0 && me == 31) { + myMnemonic = "clrlwi"; + printShift = false; + printMaskEnd = false; + } + printSecondSrc = false; + } else if (myMnemonic == "rlwnm") { + if (mb == 0 && me == 31) { + myMnemonic = "rotlw"; + printMaskBeg = false; + printMaskEnd = false; + } + printShift = false; + } else if (myMnemonic == "rlwimi") { + printSecondSrc = false; + } + + // Additional characters depending on isa bits being set + if (rc) + myMnemonic = myMnemonic + "."; + ccprintf(ss, "%-10s ", myMnemonic); // Print the first destination only if (_numDestRegs > 0) @@ -673,10 +706,37 @@ IntRotateOp::generateDisassembly( 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 (rc) { + if (_numSrcRegs > 2) { + ss << ", "; + printReg(ss, srcRegIdx(2)); + } + } else { + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, srcRegIdx(1)); + } + } + } } - // Print the shift, mask begin and mask end - ss << ", " << (int) sh << ", " << (int) mb << ", " << (int) me; + // Print the shift value + if (printShift) + ss << ", " << (int) sh; + + // Print the mask bounds + if (printMaskBeg) + ss << ", " << (int) mb; + if (printMaskEnd) + ss << ", " << (int) me; return ss.str(); }