arch-power: Fix disassembly for arithmetic instructions

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

Change-Id: I89b8271994e4d4b7b16efad170af5eeb5ee1aa10
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40900
Reviewed-by: Boris Shingarov <shingarov@labware.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Sandipan Das
2021-02-06 17:17:34 +05:30
committed by Boris Shingarov
parent af98e17364
commit 8455995d09
2 changed files with 122 additions and 26 deletions

View File

@@ -68,15 +68,13 @@ IntOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
ccprintf(ss, "%-10s ", myMnemonic);
// Print the first destination only
if (_numDestRegs > 0 && printDest) {
if (_numDestRegs > 0 && printDest)
printReg(ss, destRegIdx(0));
}
// Print the (possibly) two source registers
if (_numSrcRegs > 0 && printSrcs) {
if (_numDestRegs > 0 && printDest) {
if (_numDestRegs > 0 && printDest)
ss << ", ";
}
printReg(ss, srcRegIdx(0));
if (_numSrcRegs > 1 && printSecondSrc) {
ss << ", ";
@@ -93,27 +91,16 @@ IntImmOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
{
std::stringstream ss;
// Generate the correct mnemonic
std::string myMnemonic(mnemonic);
// Special cases
if (!myMnemonic.compare("addi") && _numSrcRegs == 0) {
myMnemonic = "li";
} else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
myMnemonic = "lis";
}
ccprintf(ss, "%-10s ", myMnemonic);
ccprintf(ss, "%-10s ", mnemonic);
// Print the first destination only
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
printReg(ss, destRegIdx(0));
}
// Print the source register
if (_numSrcRegs > 0) {
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
ss << ", ";
}
printReg(ss, srcRegIdx(0));
}
@@ -124,6 +111,113 @@ IntImmOp::generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const
}
std::string
IntArithOp::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 == "addme" ||
myMnemonic == "addze" ||
myMnemonic == "subfme" ||
myMnemonic == "subfze" ||
myMnemonic == "neg") {
printSecondSrc = false;
}
// Additional characters depending on isa bits being set
if (oe)
myMnemonic = myMnemonic + "o";
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 (_numSrcRegs > 1 && printSecondSrc) {
ss << ", ";
printReg(ss, srcRegIdx(1));
}
}
return ss.str();
}
std::string
IntImmArithOp::generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const
{
std::stringstream ss;
bool negateImm = false;
// Generate the correct mnemonic
std::string myMnemonic(mnemonic);
// Special cases
if (myMnemonic == "addi") {
if (_numSrcRegs == 0) {
myMnemonic = "li";
} else if (si < 0) {
myMnemonic = "subi";
negateImm = true;
}
} else if (myMnemonic == "addis") {
if (_numSrcRegs == 0) {
myMnemonic = "lis";
} else if (si < 0) {
myMnemonic = "subis";
negateImm = true;
}
} else if (myMnemonic == "addic" && si < 0) {
myMnemonic = "subic";
negateImm = true;
} else if (myMnemonic == "addic_") {
if (si < 0) {
myMnemonic = "subic.";
negateImm = true;
} else {
myMnemonic = "addic.";
}
}
ccprintf(ss, "%-10s ", myMnemonic);
// 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
if (negateImm)
ss << ", " << -si;
else
ss << ", " << si;
return ss.str();
}
std::string
IntShiftOp::generateDisassembly(
Addr pc, const loader::SymbolTable *symtab) const
@@ -133,15 +227,13 @@ IntShiftOp::generateDisassembly(
ccprintf(ss, "%-10s ", mnemonic);
// Print the first destination only
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
printReg(ss, destRegIdx(0));
}
// Print the first source register
if (_numSrcRegs > 0) {
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
ss << ", ";
}
printReg(ss, srcRegIdx(0));
}
@@ -161,15 +253,13 @@ IntRotateOp::generateDisassembly(
ccprintf(ss, "%-10s ", mnemonic);
// Print the first destination only
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
printReg(ss, destRegIdx(0));
}
// Print the first source register
if (_numSrcRegs > 0) {
if (_numDestRegs > 0) {
if (_numDestRegs > 0)
ss << ", ";
}
printReg(ss, srcRegIdx(0));
}

View File

@@ -133,6 +133,9 @@ class IntArithOp : public IntOp
: IntOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;
};
@@ -151,6 +154,9 @@ class IntImmArithOp : public IntArithOp
si(sext<16>(machInst.si))
{
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;
};