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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user