arch-power: Fix disassembly for arithmetic instructions
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:47:34 +0000 (17:17 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:38 +0000 (14:02 +0530)
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>
src/arch/power/insts/integer.cc
src/arch/power/insts/integer.hh

index 5ecb8ccd8df342486cb04e4ba87e872b32d6fe11..015ed723dda2165166da34b79f688077acf280d7 100644 (file)
@@ -91,15 +91,112 @@ IntImmOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
 {
     std::stringstream ss;
 
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // 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 last
+    ss << ", " << (int32_t)imm;
+
+    return ss.str();
+}
+
+
+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.compare("addi") && _numSrcRegs == 0) {
-        myMnemonic = "li";
-    } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) {
-        myMnemonic = "lis";
+    if (!myMnemonic.compare("addme") ||
+        !myMnemonic.compare("addze") ||
+        !myMnemonic.compare("subfme") ||
+        !myMnemonic.compare("subfze") ||
+        !myMnemonic.compare("neg")){
+        printSecondSrc = false;
     }
+
+    // Additional characters depending on isa bits being set
+    if (oeSet) myMnemonic = myMnemonic + "o";
+    if (rcSet) 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 negateSimm = false;
+
+    // Generate the correct mnemonic
+    std::string myMnemonic(mnemonic);
+
+    // Special cases
+    if (!myMnemonic.compare("addi")) {
+        if (_numSrcRegs == 0) {
+            myMnemonic = "li";
+        } else if (simm < 0) {
+            myMnemonic = "subi";
+            negateSimm = true;
+        }
+    } else if (!myMnemonic.compare("addis")) {
+        if (_numSrcRegs == 0) {
+            myMnemonic = "lis";
+        } else if (simm < 0) {
+            myMnemonic = "subis";
+            negateSimm = true;
+        }
+    } else if (!myMnemonic.compare("addic") && simm < 0) {
+        myMnemonic = "subic";
+        negateSimm = true;
+    } else if (!myMnemonic.compare("addic_")) {
+        if (simm < 0) {
+            myMnemonic = "subic.";
+            negateSimm = true;
+        } else {
+            myMnemonic = "addic.";
+        }
+    }
+
     ccprintf(ss, "%-10s ", myMnemonic);
 
     // Print the first destination only
@@ -115,8 +212,12 @@ IntImmOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
         printReg(ss, srcRegIdx(0));
     }
 
-    // Print the immediate value last
-    ss << ", " << (int32_t)imm;
+    // Print the immediate value
+    if (negateSimm) {
+        ss << ", " << -simm;
+    } else {
+        ss << ", " << simm;
+    }
 
     return ss.str();
 }
index 9efda43378f7a22341991b2ae96ebe36279d6b06..32c1ccd37ccec8a076d569d1b7658bd02f40e76e 100644 (file)
@@ -153,6 +153,9 @@ class IntArithOp : public IntOp
       : IntOp(mnem, _machInst, __opClass)
     {
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };
 
 
@@ -171,6 +174,9 @@ class IntImmArithOp : public IntArithOp
         simm((int16_t)machInst.si)
     {
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };