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 <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40931
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Boris Shingarov <shingarov@labware.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sandipan Das
2021-02-06 17:22:03 +05:30
parent f6ff1b19f7
commit 59ae544eb3

View File

@@ -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();
}