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

Change subject: arch-power: Fix fixed-point word rotate instructions
......................................................................

arch-power: Fix fixed-point word rotate instructions

This fixes the following rotate instructions:
  * Rotate Left Word Immediate then And with Mask (rlwinm[.])
  * Rotate Left Word then And with Mask (rlwnm[.])
  * Rotate Left Word Immediate then Mask Insert (rlwimi[.])

For 64-bit execution, these instructions should perform rotate
operations on a 64-bit value formed by concatenating two copies
of the lower order 32 bits of the value in the source register.

This also fixes disassembly generation for all of the above.

Change-Id: Iccd8c6ad10a26d66dcecd64c8f1f8118ec8c1278
Signed-off-by: Sandipan Das <[email protected]>
---
M src/arch/power/insts/integer.cc
M src/arch/power/insts/integer.hh
M src/arch/power/isa/decoder.isa
M src/arch/power/isa/formats/integer.isa
4 files changed, 119 insertions(+), 26 deletions(-)



diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc
index 090ec48..ce4ab46 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -697,8 +697,40 @@
 IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
 {
     stringstream ss;
+    bool printSecondSrc = true;
+    bool printShift = true;
+    bool printMaskBeg = true;
+    bool printMaskEnd = true;

-    ccprintf(ss, "%-10s ", mnemonic);
+    // Generate the correct mnemonic
+    string myMnemonic(mnemonic);
+
+    // Special cases
+    if (!myMnemonic.compare("rlwinm")) {
+        if (maskBeg == 0 && maskEnd == 31) {
+            myMnemonic = "rotlwi";
+            printMaskBeg = false;
+            printMaskEnd = false;
+        } else if (shift == 0 && maskEnd == 31) {
+            myMnemonic = "clrlwi";
+            printShift = false;
+            printMaskEnd = false;
+        }
+        printSecondSrc = false;
+    } else if (!myMnemonic.compare("rlwnm")) {
+        if (maskBeg == 0 && maskEnd == 31) {
+            myMnemonic = "rotlw";
+            printMaskBeg = false;
+            printMaskEnd = false;
+        }
+        printShift = false;
+    } else if (!myMnemonic.compare("rlwimi")) {
+        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) {
@@ -711,10 +743,40 @@
             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]);
+                }
+            }
+        }
     }

-    // Print the shift, mask begin and mask end
-    ss << ", " << sh << ", " << mb << ", " << me;
+    // Print the shift value
+    if (printShift) {
+        ss << ", " << shift;
+    }
+
+    // Print the mask bounds
+    if (printMaskBeg) {
+        ss << ", " << maskBeg;
+    }
+    if (printMaskEnd) {
+        ss << ", " << maskEnd;
+    }

     return ss.str();
 }
diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
index e6c30ac..b2d2256 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -645,34 +645,46 @@


 /**
- * Class for integer rotate operations.
+ * Class for integer rotate operations with a shift amount obtained
+ * from a register or an immediate and the first and last bits of a
+ * mask obtained from immediates.
  */
 class IntRotateOp : public IntShiftOp
 {
   protected:

-    uint32_t mb;
-    uint32_t me;
-    uint32_t fullMask;
+    uint32_t maskBeg;
+    uint32_t maskEnd;

     /// Constructor
     IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
       : IntShiftOp(mnem, _machInst, __opClass),
-        mb(machInst.mb),
-        me(machInst.me)
+        maskBeg(machInst.mb),
+        maskEnd(machInst.me)
     {
-        if (me >= mb) {
-            fullMask = mask(31 - mb, 31 - me);
-        } else {
-            fullMask = ~mask(31 - (me + 1), 31 - (mb - 1));
-        }
     }

-    uint32_t
-    rotateValue(uint32_t rs, uint32_t shift) const
+    inline uint64_t
+    rotate(uint32_t rs, uint32_t sh) const
     {
-        uint32_t n = shift & 31;
-        return (rs << n) | (rs >> (32 - n));
+        uint64_t res;
+        sh = sh & 0x1f;
+        res = rs;
+        res = (res << 32) | res;
+        res = (res << sh) | (res >> (32 - sh));
+        return res;
+    }
+
+    inline uint64_t
+    bitmask(uint32_t mb, uint32_t me) const
+    {
+        mb = mb & 0x1f;
+        me = me & 0x1f;
+        if (mb <= me) {
+            return mask(31 - mb, 31 - me);
+        } else {
+            return ~mask(31 - (me + 1), 31 - (mb - 1));
+        }
     }

     std::string generateDisassembly(
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index c753016..dffe5f9 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -284,10 +284,27 @@
     }

     format IntRotateOp {
-        21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }});
-        23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }});
-        20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) |
-                           (Ra & ~fullMask); }});
+        21: rlwinm({{
+            uint64_t res;
+            res = rotate(Rs, shift);
+            res = res & bitmask(maskBeg, maskEnd);
+            Ra = res;
+        }});
+
+        23: rlwnm({{
+            uint64_t res;
+            res = rotate(Rs, Rb);
+            res = res & bitmask(maskBeg, maskEnd);
+            Ra = res;
+        }});
+
+        20: rlwimi({{
+            uint64_t res, mask;
+            mask = bitmask(maskBeg, maskEnd);
+            res = rotate(Rs, shift);
+            res = (res & mask) | (Ra & ~mask);
+            Ra = res;
+        }});
     }

     // There are a large number of instructions that have the same primary
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
index 8f8c2bd..78f8062 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -523,15 +523,17 @@
 }};


-// A special format for rotate instructions which use certain fields
-// from the instruction's binary encoding. We need two versions for each
-// instruction to deal with the Rc bit.
+// Integer instructions with or without immediate that perform rotate
+// operations. All instructions write to Ra and use Rs as a source
+// register. If immediate is not used, Rb is also used as a source
+// register. We need two versions for each instruction to deal with
+// the Rc bit.
 def format IntRotateOp(code, inst_flags = []) {{

     # The result is always in Ra
     dict = {'result':'Ra'}

-    # Setup the code for when Rc is set
+    # Code when Rc is set
     code_rc1 = readXERCode + code + computeCR0Code % dict

     # Generate the first class

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/16636
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: Iccd8c6ad10a26d66dcecd64c8f1f8118ec8c1278
Gerrit-Change-Number: 16636
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