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

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

arch-power: Add doubleword shift instructions

This introduces a new class and a new format for XS form
instructions where the shift amount is specified by two
fields that must be concatenated and adds the following
instructions.
  * Shift Left Doubleword (sld[.])
  * Shift Right Doubleword (srd[.])
  * Shift Right Algebraic Doubleword (srad[.])
  * Shift Right Algebraic Doubleword Immediate (sradi[.])
  * Extend-Sign Word and Shift Left Immediate (extswsli[.])

Change-Id: If51c676009ddafb40f855b66c00eeeffa5d8874c
Signed-off-by: Sandipan Das <sandi...@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40928
Reviewed-by: Boris Shingarov <shinga...@labware.com>
Maintainer: Boris Shingarov <shinga...@labware.com>
Tested-by: kokoro <noreply+kok...@google.com>
---
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, 243 insertions(+), 61 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 2a3ab31..484354b 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -595,6 +595,68 @@


 std::string
+IntConcatShiftOp::generateDisassembly(
+        Addr pc, const Loader::SymbolTable *symtab) const
+{
+    std::stringstream ss;
+    bool printSecondSrc = true;
+    bool printShift = false;
+
+    // Generate the correct mnemonic
+    std::string myMnemonic(mnemonic);
+
+    // Special cases
+    if (myMnemonic == "sradi" ||
+        myMnemonic == "extswsli") {
+        printSecondSrc = false;
+        printShift = true;
+    }
+
+    // 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 value
+    if (printShift)
+        ss << ", " << (int) sh;
+
+    return ss.str();
+}
+
+
+std::string
 IntRotateOp::generateDisassembly(
         Addr pc, const loader::SymbolTable *symtab) const
 {
diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
index 7a8c201..d655e08 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -601,6 +601,28 @@


 /**
+ * Class for integer shift operations with a shift value obtained from
+ * a register or by concatenating immediates.
+ */
+class IntConcatShiftOp : public IntOp
+{
+  protected:
+
+    uint8_t sh;
+
+    /// Constructor
+ IntConcatShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass)
+      : IntOp(mnem, _machInst, __opClass),
+        sh((machInst.shn << 5) | machInst.sh)
+    {
+    }
+
+    std::string generateDisassembly(
+            Addr pc, const Loader::SymbolTable *symtab) const override;
+};
+
+
+/**
  * Class for integer rotate operations.
  */
 class IntRotateOp : public IntShiftOp
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index 2db66b6..2a21a48 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -250,10 +250,19 @@
             Ra = res;
         }});

-        format IntLogicOp {
-            26: cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true);
-            28: and({{ Ra = Rs & Rb; }}, true);
-        }
+        26: IntLogicOp::cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true);
+
+        27: IntConcatShiftOp::sld({{
+            int64_t shift = Rb_sd;
+            uint64_t res = Rs & ~((shift << 57) >> 63);
+            if (shift != 0) {
+                shift = bits(shift, 5, 0);
+                res = res << shift;
+            }
+            Ra = res;
+        }});
+
+        28: IntLogicOp::and({{ Ra = Rs & Rb; }}, true);

         32: IntCompOp::cmpl({{
             if (l)
@@ -512,6 +521,17 @@
         }});

538: IntLogicOp::cnttzw({{ Ra = findTrailingZeros(Rs_uw); }}, true);
+
+        539: IntConcatShiftOp::srd({{
+            int64_t shift = Rb_sd;
+            uint64_t res = Rs & ~((shift << 57) >> 63);
+            if (shift != 0) {
+                shift = bits(shift, 5, 0);
+                res = res >> shift;
+            }
+            Ra = res;
+        }});
+
         567: LoadIndexUpdateOp::lfsux({{ Ft_sf = Mem_sf; }});
         570: IntLogicOp::cnttzd({{ Ra = findTrailingZeros(Rs); }}, true);
         598: MiscOp::sync({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
@@ -590,40 +610,57 @@

         790: LoadIndexOp::lhbrx({{ Rt = swap_byte(Mem_uh); }});

-        format IntShiftOp {
-            792: sraw({{
-                int32_t src = Rs_sw;
-                uint32_t shift = Rb_uw;
-                int64_t res;
-                if (bits(shift, 5)) {
-                    res = src >> 31;
-                    if (res != 0) {
-                        setCA = true;
-                    }
-                } else {
-                    if (shift != 0) {
-                        shift = bits(shift, 4, 0);
-                        res = src >> shift;
-                        setCA = src < 0 && (src & mask(shift)) != 0;
-                    } else {
-                        res = src;
-                    }
+        792: IntShiftOp::sraw({{
+            int32_t src = Rs_sw;
+            uint32_t shift = Rb_uw;
+            int64_t res;
+            if (bits(shift, 5)) {
+                res = src >> 31;
+                if (res != 0) {
+                    setCA = true;
                 }
-                Ra = res;
-            }}, true);
-
-            824: srawi({{
-                int32_t src = Rs_sw;
-                int64_t res;
-                if (sh) {
-                    res = src >> sh;
-                    setCA = src < 0 && (src & mask(sh)) != 0;
+            } else {
+                if (shift != 0) {
+                    shift = bits(shift, 4, 0);
+                    res = src >> shift;
+                    setCA = src < 0 && (src & mask(shift)) != 0;
                 } else {
                     res = src;
                 }
-                Ra = res;
-            }}, true);
-        }
+            }
+            Ra = res;
+        }}, true);
+
+        794: IntConcatShiftOp::srad({{
+            int64_t src = Rs_sd;
+            uint64_t shift = Rb;
+            int64_t res;
+            if (bits(shift, 6)) {
+                res = src >> 63;
+                setCA = res != 0;
+            } else {
+                if (shift != 0) {
+                    shift = shift & 0x3f;
+                    res = src >> shift;
+                    setCA = src < 0 && (src & mask(shift)) != 0;
+                } else {
+                    res = src;
+                }
+            }
+            Ra = res;
+        }}, true);
+
+        824: IntShiftOp::srawi({{
+            int32_t src = Rs_sw;
+            int64_t res;
+            if (sh) {
+                res = src >> sh;
+                setCA = src < 0 && (src & mask(sh)) != 0;
+            } else {
+                res = src;
+            }
+            Ra = res;
+        }}, true);

         854: MiscOp::eieio({{ }}, [ IsReadBarrier, IsWriteBarrier ]);
         855: LoadIndexOp::lfiwax({{ Ft_uw = Mem; }});
@@ -810,38 +847,64 @@
                 }}, true);
             }

-            default: decode XFX_XO {
-                format IntOp {
-                    19: mfcr({{ Rt = CR; }});
-
-                    144: mtcrf({{
-                        uint32_t mask = 0;
-                        for (int i = 0; i < 8; ++i) {
-                            if (((FXM >> i) & 0x1) == 0x1) {
-                                mask |= 0xf << (4 * i);
+ // These instructions are of XS form and use bits 21 - 29 as XO.
+            default: decode XS_XO {
+                format IntConcatShiftOp {
+                    413: sradi({{
+                        int64_t src = Rs_sd;
+                        if (sh != 0) {
+                            Ra = src >> sh;
+                            if (src < 0 && (src & mask(sh))) {
+                                setCA = true;
                             }
+                        } else {
+                            Ra = src;
                         }
-                        CR = (Rs & mask) | (CR & ~mask);
+                    }}, true);
+
+                    445: extswsli({{
+                        int64_t src = Rs_sw;
+                        if (sh != 0) {
+                            Ra = src << sh;
+                        } else {
+                            Ra = src;
+                        }
                     }});
+                }

-                    339: decode SPR {
-                        0x20: mfxer({{ Rt = XER; }});
-                        0x100: mflr({{ Rt = LR; }});
-                        0x120: mfctr({{ Rt = CTR; }});
-                        0x1f9: mftar({{ Rt = TAR; }});
+                default: decode XFX_XO {
+                    format IntOp {
+                        19: mfcr({{ Rt = CR; }});
+
+                        144: mtcrf({{
+                            uint32_t mask = 0;
+                            for (int i = 0; i < 8; ++i) {
+                                if (((FXM >> i) & 0x1) == 0x1) {
+                                    mask |= 0xf << (4 * i);
+                                }
+                            }
+                            CR = (Rs & mask) | (CR & ~mask);
+                        }});
+
+                        339: decode SPR {
+                            0x20: mfxer({{ Rt = XER; }});
+                            0x100: mflr({{ Rt = LR; }});
+                            0x120: mfctr({{ Rt = CTR; }});
+                            0x1f9: mftar({{ Rt = TAR; }});
+                        }
+
+                        467: decode SPR {
+                            0x20: mtxer({{ XER = Rs; }});
+                            0x100: mtlr({{ LR = Rs; }});
+                            0x120: mtctr({{ CTR = Rs; }});
+                            0x1f9: mttar({{ TAR = Rs; }});
+                        }
+
+                        512: mcrxr({{
+                            CR = insertCRField(CR, BF, XER<31:28>);
+                            XER = XER<27:0>;
+                        }});
                     }
-
-                    467: decode SPR {
-                        0x20: mtxer({{ XER = Rs; }});
-                        0x100: mtlr({{ LR = Rs; }});
-                        0x120: mtctr({{ CTR = Rs; }});
-                        0x1f9: mttar({{ TAR = Rs; }});
-                    }
-
-                    512: mcrxr({{
-                        CR = insertCRField(CR, BF, XER<31:28>);
-                        XER = XER<27:0>;
-                    }});
                 }
             }
         }
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
index d8abd5a..3cef9cc 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -453,6 +453,41 @@
 }};


+// Integer instructions that also perform shift operations. Everything
+// is same as above except if the shift value is not obtained from a
+// register, two immediates need to be concatenated to get the final
+// shift value.
+def format IntConcatShiftOp(code, computeCA = 0, inst_flags = []) {{
+    dict = {'result':'Ra'}
+
+    # Add code to setup variables and access XER if necessary
+    code  = 'GEM5_VAR_USED bool setCA = false;\n' + code
+
+    # Code when Rc is set
+    code_rc1 = readXERCode + code + computeCR0Code % dict
+
+    # Add code for calculating the carry, if needed
+    if computeCA:
+        code = readXERCode + code + setCACode + setXERCode
+        code_rc1 += setCACode + setXERCode
+
+    # Generate the first class
+    (header_output, decoder_output, decode_block, exec_output) = \
+        GenAluOp(name, Name, 'IntConcatShiftOp', code, inst_flags,
+                 CheckRcDecode, BasicConstructor)
+
+    # Generate the second class
+    (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \
+        GenAluOp(name, Name + 'RcSet', 'IntConcatShiftOp', 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
+}};
+
+
 // 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.

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40928
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: If51c676009ddafb40f855b66c00eeeffa5d8874c
Gerrit-Change-Number: 40928
Gerrit-PatchSet: 8
Gerrit-Owner: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-Reviewer: Boris Shingarov <shinga...@labware.com>
Gerrit-Reviewer: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to