Sandipan Das has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/40933 )

Change subject: arch-power: Add doubleword rotate instructions
......................................................................

arch-power: Add doubleword rotate instructions

This introduces a new class and a new format for MD and
MDS form instructions where the shift amount, mask begin
and mask end are specified by two fields that must be
concatenated and adds the following instructions.
  * Rotate Left Doubleword Immediate then Clear Left (rldicl[.])
  * Rotate Left Doubleword Immediate then Clear Right (rldicr[.])
  * Rotate Left Doubleword Immediate then Clear (rldic[.])
  * Rotate Left Doubleword then Clear Left (rldcl[.])
  * Rotate Left Doubleword then Clear Right (rldcr[.])
  * Rotate Left Doubleword Immediate then Mask Insert (rldimi[.])

Change-Id: Id7f1f24032242ccfdfda2f1aefd6fe9f0331f610
Signed-off-by: Sandipan Das <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40933
Reviewed-by: Boris Shingarov <[email protected]>
Maintainer: Boris Shingarov <[email protected]>
Tested-by: kokoro <[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, 231 insertions(+), 0 deletions(-)

Approvals:
  Boris Shingarov: Looks good to me, approved; Looks good to me, approved
  kokoro: Regressions pass



diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc
index 87efc1d..3203507 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -740,3 +740,83 @@

     return ss.str();
 }
+
+std::string
+IntConcatRotateOp::generateDisassembly(
+        Addr pc, const Loader::SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    bool printSecondSrc = false;
+    bool printShift = true;
+    bool printMaskBeg = true;
+
+    // Generate the correct mnemonic
+    std::string myMnemonic(mnemonic);
+
+    // Special cases
+    if (myMnemonic == "rldicl") {
+        if (mb == 0) {
+            myMnemonic = "rotldi";
+            printMaskBeg = false;
+        } else if (sh == 0) {
+            myMnemonic = "clrldi";
+            printShift = false;
+        }
+    } else if (myMnemonic == "rldcl") {
+        if (mb == 0) {
+            myMnemonic = "rotld";
+            printMaskBeg = false;
+        }
+        printSecondSrc = true;
+        printShift = false;
+    } else if (myMnemonic == "rldcr") {
+        printSecondSrc = true;
+        printShift = false;
+    }
+
+    // Additional characters depending on isa bits being set
+    if (rc)
+        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 (rc) {
+                if (_numSrcRegs > 2) {
+                    ss << ", ";
+                    printReg(ss, srcRegIdx(2));
+                }
+            } else {
+                if (_numSrcRegs > 1) {
+                    ss << ", ";
+                    printReg(ss, srcRegIdx(1));
+                }
+            }
+        }
+    }
+
+    // Print the shift amount
+    if (printShift)
+        ss << ", " << (int) sh;
+
+    // Print the mask bound
+    if (printMaskBeg)
+        ss << ", " << (int) mb;
+
+    return ss.str();
+}
diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
index e6a8e2e..69bc633 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -669,6 +669,50 @@
             Addr pc, const loader::SymbolTable *symtab) const override;
 };

+
+/**
+ * Class for integer rotate operations with a shift amount obtained
+ * from a register or by concatenating immediate fields and the first
+ * and last bits of a mask obtained by concatenating immediate fields.
+ */
+class IntConcatRotateOp : public IntConcatShiftOp
+{
+  protected:
+
+    uint8_t mb;
+    uint8_t me;
+
+    /// Constructor
+ IntConcatRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : IntConcatShiftOp(mnem, _machInst, __opClass),
+        mb((machInst.mbn << 5) | machInst.mb),
+        me((machInst.men << 5) | machInst.mb)
+    {
+    }
+
+    inline uint64_t
+    rotate(uint64_t value, uint32_t shift) const
+    {
+        shift = shift & 0x3f;
+        return (value << shift) | (value >> (64 - shift));
+    }
+
+    inline uint64_t
+    bitmask(uint32_t begin, uint32_t end) const
+    {
+        begin = begin & 0x3f;
+        end = end & 0x3f;
+        if (begin <= end) {
+            return mask(63 - begin, 63 - end);
+        } else {
+            return ~mask(63 - (end + 1), 63 - (begin - 1));
+        }
+    }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
+};
+
 } // namespace PowerISA

 #endif //__ARCH_POWER_INSTS_INTEGER_HH__
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index 75af444..2742065 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -227,6 +227,84 @@
         29: andis_({{ Ra = Rs & (ui << 16); }}, true);
     }

+    // These instructions are of MD form and use bits 27 - 29 as XO.
+    30: decode MD_XO {
+        format IntConcatRotateOp {
+            0: rldicl({{
+                uint64_t res;
+                if (sh != 0) {
+                    res = rotate(Rs, sh);
+                } else {
+                    res = Rs;
+                }
+                res = res & bitmask(mb, 63);
+                Ra = res;
+            }});
+
+            1: rldicr({{
+                uint64_t res;
+                if (sh != 0) {
+                    res = rotate(Rs, sh);
+                } else {
+                    res = Rs;
+                }
+                res = res & bitmask(0, me);
+                Ra = res;
+            }});
+
+            2: rldic({{
+                uint64_t res;
+                if (sh != 0) {
+                    res = rotate(Rs, sh);
+                } else {
+                    res = Rs;
+                }
+                res = res & bitmask(mb, ~sh);
+                Ra = res;
+            }});
+
+            3: rldimi({{
+                uint64_t res, mask;
+                mask = bitmask(mb, ~sh);
+                if (sh != 0) {
+                    res = rotate(Rs, sh);
+                } else {
+                    res = Rs;
+                }
+                res = res & mask;
+                res = res | (Ra & ~mask);
+                Ra = res;
+            }});
+
+ // These instructions are of MDS form and use bits 27 - 30 as XO.
+            default: decode MDS_XO {
+                8: rldcl({{
+                    uint64_t res;
+                    uint32_t shift = Rb & 0x3f;
+                    if (shift != 0) {
+                        res = rotate(Rs, shift);
+                    } else {
+                        res = Rs;
+                    }
+                    res = res & bitmask(mb, 63);
+                    Ra = res;
+                }});
+
+                9: rldcr({{
+                    uint64_t res;
+                    uint32_t shift = Rb & 0x3f;
+                    if (shift != 0) {
+                        res = rotate(Rs, shift);
+                    } else {
+                        res = Rs;
+                    }
+                    res = res & bitmask(0, me);
+                    Ra = res;
+                }});
+            }
+        }
+    }
+
     // There are a large number of instructions that have the same primary
     // opcode (PO) of 31. In this case, the instructions are of different
     // forms. For every form, the XO fields may vary in position and width.
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
index 1bdf639..98759ee 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -516,3 +516,32 @@
     decoder_output += decoder_output_rc1
     exec_output += exec_output_rc1
 }};
+
+
+// Everything is same as above except that the immediates may need to be
+// concatenated to get the final values for the mask bounds or the shift
+// value. We need two versions for each instruction to deal with the Rc
+// bit.
+def format IntConcatRotateOp(code, inst_flags = []) {{
+
+    # The result is always in Ra
+    dict = {'result':'Ra'}
+
+    # Code when Rc is set
+    code_rc1 = readXERCode + code + computeCR0Code % dict
+
+    # Generate the first class
+    (header_output, decoder_output, decode_block, exec_output) = \
+        GenAluOp(name, Name, 'IntConcatRotateOp', code, inst_flags,
+                 CheckRcDecode, BasicConstructor)
+
+    # Generate the second class
+    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+        GenAluOp(name, Name + 'RcSet', 'IntConcatRotateOp', code_rc1,
+                 inst_flags, CheckRcDecode, BasicConstructor)
+
+    # Finally, add to the other outputs
+    header_output += header_output_rc1
+    decoder_output += decoder_output_rc1
+    exec_output += exec_output_rc1
+}};

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

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Id7f1f24032242ccfdfda2f1aefd6fe9f0331f610
Gerrit-Change-Number: 40933
Gerrit-PatchSet: 8
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-Reviewer: Boris Shingarov <[email protected]>
Gerrit-Reviewer: Sandipan Das <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to