Sandipan Das has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/16608

Change subject: arch-power: Fix fixed-point load and store instructions
......................................................................

arch-power: Fix fixed-point load and store instructions

This fixes the following load and store instructions as a result
of the change in register widths:
  * Load Word and Zero (lwz)
  * Load Word and Zero Indexed (lwzx)
  * Load Word and Zero with Update (lwzu)
  * Load Word and Zero with Update Indexed (lwzux)
  * Load Word Algebraic (lwa)
  * Load Word And Reserve Indexed (lwarx)
  * Store Word (stw)
  * Store Word Indexed (stwx)
  * Store Word with Update (stwu)
  * Store Word with Update Indexed (stwux)
  * Store Word Conditional Indexed (stwcx.)

This also fixes disassembly generation for all of the above.

Change-Id: I1a25cdb5ffe86145b7ffcf2c2bd7b27048a415d2
Signed-off-by: Sandipan Das <[email protected]>
---
M src/arch/power/insts/mem.cc
M src/arch/power/insts/mem.hh
M src/arch/power/isa/decoder.isa
M src/arch/power/isa/formats/mem.isa
M src/arch/power/isa/operands.isa
M src/arch/power/types.hh
6 files changed, 218 insertions(+), 26 deletions(-)



diff --git a/src/arch/power/insts/mem.cc b/src/arch/power/insts/mem.cc
index 68a33c6..85a5aee 100644
--- a/src/arch/power/insts/mem.cc
+++ b/src/arch/power/insts/mem.cc
@@ -40,6 +40,7 @@
     return csprintf("%-10s", mnemonic);
 }

+
 std::string
 MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
 {
@@ -60,16 +61,160 @@

     // 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;
-
-    // Print the address register
+    ss << ", " << disp;
     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
+MemDispShiftOp::generateDisassembly(Addr pc, const 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 << "(";
+
+    // 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 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();
+}
diff --git a/src/arch/power/insts/mem.hh b/src/arch/power/insts/mem.hh
index 6c41b16..ad2c23f 100644
--- a/src/arch/power/insts/mem.hh
+++ b/src/arch/power/insts/mem.hh
@@ -77,6 +77,44 @@
             Addr pc, const SymbolTable *symtab) const override;
 };

+/**
+ * Class for memory operations with shifted displacement.
+ */
+class MemDispShiftOp : public MemOp
+{
+  protected:
+
+    int16_t disp;
+
+    /// Constructor
+    MemDispShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : MemOp(mnem, _machInst, __opClass),
+        disp(sext<14>(machInst.ds))
+    {
+    }
+
+    std::string generateDisassembly(
+            Addr pc, const SymbolTable *symtab) const override;
+};
+
+
+/**
+ * Class for memory operations with register indexed addressing.
+ */
+class MemIndexOp : public MemOp
+{
+  protected:
+
+    /// Constructor
+    MemIndexOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : MemOp(mnem, _machInst, __opClass)
+    {
+    }
+
+    std::string generateDisassembly(
+            Addr pc, const SymbolTable *symtab) const override;
+};
+
 } // namespace PowerISA

 #endif //__ARCH_POWER_INSTS_MEM_HH__
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index bce9465..67639ad 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -146,14 +146,12 @@
         34: lbz({{ Rt = Mem_ub; }});
         40: lhz({{ Rt = Mem_uh; }});
         42: lha({{ Rt = Mem_sh; }});
-        32: lwz({{ Rt = Mem; }});
+        32: lwz({{ Rt = Mem_uw; }});
     }

     58: decode DS_XO {
-        format LoadDispOp {
-            2: lwa({{ Rt = Mem_sw; }},
-                   {{ EA = Ra + (disp & 0xfffffffc); }},
-                   {{ EA = disp & 0xfffffffc; }});
+        format LoadDispShiftOp {
+            2: lwa({{ Rt = Mem_sw; }});
         }
     }

@@ -161,19 +159,19 @@
         35: lbzu({{ Rt = Mem_ub; }});
         41: lhzu({{ Rt = Mem_uh; }});
         43: lhau({{ Rt = Mem_sh; }});
-        33: lwzu({{ Rt = Mem; }});
+        33: lwzu({{ Rt = Mem_uw; }});
     }

     format StoreDispOp {
         38: stb({{ Mem_ub = Rs_ub; }});
         44: sth({{ Mem_uh = Rs_uh; }});
-        36: stw({{ Mem = Rs; }});
+        36: stw({{ Mem_uw = Rs_uw; }});
     }

     format StoreDispUpdateOp {
         39: stbu({{ Mem_ub = Rs_ub; }});
         45: sthu({{ Mem_uh = Rs_uh; }});
-        37: stwu({{ Mem = Rs; }});
+        37: stwu({{ Mem_uw = Rs_uw; }});
     }

     format IntImmArithCheckRaOp {
@@ -253,9 +251,9 @@
             87: lbzx({{ Rt = Mem_ub; }});
             279: lhzx({{ Rt = Mem_uh; }});
             343: lhax({{ Rt = Mem_sh; }});
-            23: lwzx({{ Rt = Mem; }});
+            23: lwzx({{ Rt = Mem_uw; }});
             341: lwax({{ Rt = Mem_sw; }});
- 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); + 20: lwarx({{ Rt = Mem_uw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }});
             535: lfsx({{ Ft_sf = Mem_sf; }});
             599: lfdx({{ Ft = Mem_df; }});
             855: lfiwax({{ Ft_uw = Mem; }});
@@ -265,7 +263,7 @@
             119: lbzux({{ Rt = Mem_ub; }});
             311: lhzux({{ Rt = Mem_uh; }});
             375: lhaux({{ Rt = Mem_sh; }});
-            55: lwzux({{ Rt = Mem; }});
+            55: lwzux({{ Rt = Mem_uw; }});
             373: lwaux({{ Rt = Mem_sw; }});
             567: lfsux({{ Ft_sf = Mem_sf; }});
             631: lfdux({{ Ft = Mem_df; }});
@@ -274,10 +272,10 @@
         format StoreIndexOp {
             215: stbx({{ Mem_ub = Rs_ub; }});
             407: sthx({{ Mem_uh = Rs_uh; }});
-            151: stwx({{ Mem = Rs; }});
+            151: stwx({{ Mem_uw = Rs_uw; }});
             150: stwcx({{
                 bool store_performed = false;
-                Mem = Rs;
+                Mem_uw = Rs_uw;
                 if (Rsv) {
                     if (RsvLen == 4) {
                         if (RsvAddr == EA) {
@@ -296,7 +294,7 @@
         format StoreIndexUpdateOp {
             247: stbux({{ Mem_ub = Rs_ub; }});
             439: sthux({{ Mem_uh = Rs_uh; }});
-            183: stwux({{ Mem = Rs; }});
+            183: stwux({{ Mem_uw = Rs_uw; }});
         }

         format IntOp {
diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa
index 47ffc91..31c050e 100644
--- a/src/arch/power/isa/formats/mem.isa
+++ b/src/arch/power/isa/formats/mem.isa
@@ -239,7 +239,7 @@
                        mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
         GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
-                 'MemOp', 'Load', mem_flags, inst_flags)
+                 'MemIndexOp', 'Load', mem_flags, inst_flags)
 }};


@@ -248,7 +248,7 @@
                         mem_flags = [], inst_flags = []) {{
     (header_output, decoder_output, decode_block, exec_output) = \
         GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
-                 'MemOp', 'Store', mem_flags, inst_flags)
+                 'MemIndexOp', 'Store', mem_flags, inst_flags)
 }};


@@ -261,7 +261,7 @@
     # Generate the class
     (header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
-                      base_class = 'MemOp',
+                      base_class = 'MemIndexOp',
                       exec_template_base = 'Load')
 }};

@@ -275,7 +275,7 @@
     # Generate the class
     (header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
-                      base_class = 'MemOp',
+                      base_class = 'MemIndexOp',
                       exec_template_base = 'Store')
 }};

@@ -298,6 +298,16 @@
 }};


+def format LoadDispShiftOp(memacc_code,
+                           ea_code = {{ EA = Ra + (disp << 2); }},
+                           ea_code_ra0 = {{ EA = (disp << 2); }},
+                           mem_flags = [], inst_flags = []) {{
+    (header_output, decoder_output, decode_block, exec_output) = \
+        GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0,
+                 'MemDispShiftOp', 'Load', mem_flags, inst_flags)
+}};
+
+
 def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }},
                             mem_flags = [], inst_flags = []) {{

diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa
index 7551171..c50c3e6 100644
--- a/src/arch/power/isa/operands.isa
+++ b/src/arch/power/isa/operands.isa
@@ -43,9 +43,9 @@

 def operands {{
     # General Purpose Integer Reg Operands
-    'Ra': ('IntReg', 'ud', 'RA', 'IsInteger', 1),
-    'Rb': ('IntReg', 'ud', 'RB', 'IsInteger', 2),
-    'Rs': ('IntReg', 'ud', 'RS', 'IsInteger', 3),
+    'Rs': ('IntReg', 'ud', 'RS', 'IsInteger', 1),
+    'Ra': ('IntReg', 'ud', 'RA', 'IsInteger', 2),
+    'Rb': ('IntReg', 'ud', 'RB', 'IsInteger', 3),
     'Rt': ('IntReg', 'ud', 'RT', 'IsInteger', 4),

     # General Purpose Floating Point Reg Operands
diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh
index 83917ec..929f765 100644
--- a/src/arch/power/types.hh
+++ b/src/arch/power/types.hh
@@ -54,6 +54,7 @@
     // Immediate fields
     Bitfield<15,  0> si;
     Bitfield<15,  0> d;
+    Bitfield<15,  2> ds;

     // Special purpose register identifier
     Bitfield<20, 11> spr;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/16608
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I1a25cdb5ffe86145b7ffcf2c2bd7b27048a415d2
Gerrit-Change-Number: 16608
Gerrit-PatchSet: 1
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to