arch-power: Fix disassembly for load-store instructions
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:47:12 +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 load-store instructions
based on how the base classess that are used to distinguish
between the types of operands used by these instructions.

Change-Id: I5a0f8644cdc6fec934475536861ad342c0a1fb4c
Signed-off-by: Sandipan Das <sandipan@linux.ibm.com>
src/arch/power/insts/mem.cc
src/arch/power/insts/mem.hh

index 596d78d25feac5a05692d3e930675fff76abe0c0..94508a7ce6d8ae84206e72e5146f19c2fe63f125 100644 (file)
@@ -38,6 +38,7 @@ MemOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
     return csprintf("%-10s", mnemonic);
 }
 
+
 std::string
 MemDispOp::generateDisassembly(
         Addr pc, const Loader::SymbolTable *symtab) const
@@ -59,16 +60,162 @@ MemDispOp::generateDisassembly(
 
     // Print the data register for a store
     else {
-        printReg(ss, srcRegIdx(1));
+        if (_numSrcRegs > 0) {
+            printReg(ss, srcRegIdx(0));
+        }
     }
 
     // Print the displacement
-    ss << ", " << (int32_t)disp;
+    ss << ", " << disp;
+    ss << "(";
 
-    // Print the address register
+    // Print the address register for a load
+    if (!flags[IsStore]) {
+        if (_numSrcRegs > 0) {
+            printReg(ss, srcRegIdx(0));
+        }
+
+        // The address register is skipped if it is R0
+        else {
+            ss << "0";
+        }
+    }
+
+    // Print the address register for a store
+    else {
+        if (_numSrcRegs > 1) {
+            printReg(ss, srcRegIdx(1));
+        }
+
+        // The address register is skipped if it is R0
+        else {
+            ss << "0";
+        }
+    }
+
+    ss << ")";
+
+    return ss.str();
+}
+
+
+std::string
+MemDispShiftOp::generateDisassembly(
+        Addr pc, const Loader::SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the destination only for a load
+    if (!flags[IsStore]) {
+        if (_numDestRegs > 0) {
+
+            // If the instruction updates the source register with the
+            // EA, then this source register is placed in position 0,
+            // therefore we print the last destination register.
+            printReg(ss, destRegIdx(_numDestRegs-1));
+        }
+    }
+
+    // Print the data register for a store
+    else {
+        if (_numSrcRegs > 0) {
+            printReg(ss, srcRegIdx(0));
+        }
+    }
+
+    // Print the displacement
+    ss << ", " << (disp << 2);
     ss << "(";
-    printReg(ss, srcRegIdx(0));
+
+    // Print the address register for a load
+    if (!flags[IsStore]) {
+        if (_numSrcRegs > 0) {
+            printReg(ss, srcRegIdx(0));
+        }
+
+        // The address register is skipped if it is R0
+        else {
+            ss << "0";
+        }
+    }
+
+    // Print the address register for a store
+    else {
+        if (_numSrcRegs > 1) {
+            printReg(ss, srcRegIdx(1));
+        }
+
+        // The address register is skipped if it is R0
+        else {
+            ss << "0";
+        }
+    }
+
     ss << ")";
 
     return ss.str();
 }
+
+
+std::string
+MemIndexOp::generateDisassembly(
+        Addr pc, const Loader::SymbolTable *symtab) const
+{
+    std::stringstream ss;
+
+    ccprintf(ss, "%-10s ", mnemonic);
+
+    // Print the destination only for a load
+    if (!flags[IsStore]) {
+        if (_numDestRegs > 0) {
+
+            // If the instruction updates the source register with the
+            // EA, then this source register is placed in position 0,
+            // therefore we print the last destination register.
+            printReg(ss, destRegIdx(_numDestRegs-1));
+        }
+    }
+
+    // Print the data register for a store
+    else {
+        if (_numSrcRegs > 0) {
+            printReg(ss, srcRegIdx(0));
+        }
+    }
+
+    ss << ", ";
+
+    // Print the address registers for a load
+    if (!flags[IsStore]) {
+        if (_numSrcRegs > 1) {
+            printReg(ss, srcRegIdx(0));
+            ss << ", ";
+            printReg(ss, srcRegIdx(1));
+        }
+
+        // The first address register is skipped if it is R0
+        else if (_numSrcRegs > 0) {
+            ss << "0, ";
+            printReg(ss, srcRegIdx(0));
+        }
+    }
+
+    // Print the address registers for a store
+    else {
+        if (_numSrcRegs > 2) {
+            printReg(ss, srcRegIdx(1));
+            ss << ", ";
+            printReg(ss, srcRegIdx(2));
+        }
+
+        // The first address register is skipped if it is R0
+        else if (_numSrcRegs > 1) {
+            ss << "0, ";
+            printReg(ss, srcRegIdx(1));
+        }
+    }
+
+    return ss.str();
+}
index d14f1e6f7bae318437891a860525a7b981575915..f800ae3d5ae197285e3e06e9f5169c8eeaf7a075 100644 (file)
@@ -90,6 +90,9 @@ class MemDispShiftOp : public MemOp
         disp(sext<14>(machInst.ds))
     {
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };
 
 
@@ -105,6 +108,9 @@ class MemIndexOp : public MemOp
       : MemOp(mnem, _machInst, __opClass)
     {
     }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
 };
 
 } // namespace PowerISA