arch-power: Fix disassembly for logical instructions

This fixes disassembly generated for integer logical
instructions based on the type of operands and special
use cases for which the Power ISA provides extended
mnemonics.

Change-Id: I6b67569ef413b0b542e35082ca360c9b4262fc5b
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40918
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:21:12 +05:30
parent 91f13cad50
commit a45afa54cb
2 changed files with 119 additions and 8 deletions

View File

@@ -42,14 +42,11 @@ IntOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
std::string myMnemonic(mnemonic);
// Special cases
if (myMnemonic == "or" && srcRegIdx(0) == srcRegIdx(1)) {
myMnemonic = "mr";
printSecondSrc = false;
} else if (myMnemonic == "mtcrf" ||
myMnemonic == "mtxer" ||
myMnemonic == "mtlr" ||
myMnemonic == "mtctr" ||
myMnemonic == "mttar") {
if (myMnemonic == "mtcrf" ||
myMnemonic == "mtxer" ||
myMnemonic == "mtlr" ||
myMnemonic == "mtctr" ||
myMnemonic == "mttar") {
printDest = false;
} else if (myMnemonic == "mfcr" ||
myMnemonic == "mfxer" ||
@@ -273,6 +270,114 @@ IntDispArithOp::generateDisassembly(
}
std::string
IntLogicOp::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 == "or" && srcRegIdx(0) == srcRegIdx(1)) {
myMnemonic = "mr";
printSecondSrc = false;
} else if (myMnemonic == "extsb" ||
myMnemonic == "extsh" ||
myMnemonic == "cntlzw") {
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)
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 (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));
}
}
}
}
return ss.str();
}
std::string
IntImmLogicOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream ss;
bool printRegs = true;
// Generate the correct mnemonic
std::string myMnemonic(mnemonic);
// Special cases
if (myMnemonic == "ori" &&
destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
myMnemonic = "nop";
printRegs = false;
} else if (myMnemonic == "xori" &&
destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
myMnemonic = "xnop";
printRegs = false;
} else if (myMnemonic == "andi_") {
myMnemonic = "andi.";
} else if (myMnemonic == "andis_") {
myMnemonic = "andis.";
}
ccprintf(ss, "%-10s ", myMnemonic);
if (printRegs) {
// 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
ss << ", " << ui;
}
return ss.str();
}
std::string
IntCompOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const

View File

@@ -498,6 +498,9 @@ class IntLogicOp : public IntOp
return 32;
}
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;
};
@@ -516,6 +519,9 @@ class IntImmLogicOp : public IntLogicOp
ui(machInst.ui)
{
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;
};