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

index 4a03f8fa39a5978bad8e5515ab9115d5d9369ae1..c937a6f8f0963a121b300ebb880ff4aaa68c796f 100644 (file)
@@ -285,6 +285,117 @@ 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.compare("or") && srcRegIdx(0) == srcRegIdx(1)) {
+        myMnemonic = "mr";
+        printSecondSrc = false;
+    } else if (!myMnemonic.compare("extsb") ||
+               !myMnemonic.compare("extsh") ||
+               !myMnemonic.compare("cntlzw")) {
+        printSecondSrc = false;
+    }
+
+    // Additional characters depending on isa bits being set
+    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 (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 (rcSet) {
+                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.compare("ori") &&
+        destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
+        myMnemonic = "nop";
+        printRegs = false;
+    } else if (!myMnemonic.compare("xori") &&
+               destRegIdx(0).index() == 0 && srcRegIdx(0).index() == 0) {
+        myMnemonic = "xnop";
+        printRegs = false;
+    } else if (!myMnemonic.compare("andi_")) {
+        myMnemonic = "andi.";
+    } else if (!myMnemonic.compare("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 << ", " << uimm;
+    }
+
+     return ss.str();
+}
+
+
 std::string
 IntCompOp::generateDisassembly(
         Addr pc, const Loader::SymbolTable *symtab) const
index d310e7340d567203ae5e617a530510d5ffe223d1..a3d99ff33a2cc160cfe3145a27ad4a4b27bd3c1b 100644 (file)
@@ -518,6 +518,9 @@ class IntLogicOp : public IntOp
             return 32;
         }
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };
 
 
@@ -536,6 +539,9 @@ class IntImmLogicOp : public IntLogicOp
         uimm(machInst.si)
     {
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };