Boris Shingarov has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/40905 )

Change subject: arch-power: Add doubleword multiply-add instructions
......................................................................

arch-power: Add doubleword multiply-add instructions

This introduces 128-bit addition helpers and adds the
following instructions.
  * Multiply-Add Low Doubleword (maddld)
  * Multiply-Add High Doubleword (maddhd)
  * Multiply-Add High Doubleword Unsigned (maddhdu)

Change-Id: I04e6ea5fb4978b341a6e648424de2930ad41f449
Signed-off-by: Sandipan Das <sandi...@linux.ibm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40905
Reviewed-by: Boris Shingarov <shinga...@labware.com>
Maintainer: Jason Lowe-Power <power...@gmail.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, 134 insertions(+), 0 deletions(-)

Approvals:
  Boris Shingarov: Looks good to me, approved
  Jason Lowe-Power: 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 25c8691..61b7f08 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -117,6 +117,7 @@
 {
     std::stringstream ss;
     bool printSecondSrc = true;
+    bool printThirdSrc = false;

     // Generate the correct mnemonic
     std::string myMnemonic(mnemonic);
@@ -128,6 +129,10 @@
         myMnemonic == "subfze" ||
         myMnemonic == "neg") {
         printSecondSrc = false;
+    } else if (myMnemonic == "maddhd" ||
+               myMnemonic == "maddhdu" ||
+               myMnemonic == "maddld") {
+        printThirdSrc = true;
     }

     // Additional characters depending on isa bits being set
@@ -151,6 +156,12 @@
         if (_numSrcRegs > 1 && printSecondSrc) {
             ss << ", ";
             printReg(ss, srcRegIdx(1));
+
+            // Print the third source register
+            if (_numSrcRegs > 2 && printThirdSrc) {
+                ss << ", ";
+                printReg(ss, srcRegIdx(2));
+            }
         }
     }

diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh
index 95f1598..fccb7cf 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -134,6 +134,52 @@
     {
     }

+ /* Compute 128-bit sum of 128-bit to 64-bit unsigned integer addition */
+    inline std::tuple<uint64_t, uint64_t>
+    add(uint64_t ralo, uint64_t rahi, uint64_t rb) const
+    {
+        uint64_t slo, shi;
+    #if defined(__SIZEOF_INT128__)
+        __uint128_t ra = ((__uint128_t)rahi << 64) | ralo;
+        __uint128_t sum = ra + rb;
+        slo = sum;
+        shi = sum >> 64;
+    #else
+        shi = rahi + ((ralo + rb) < ralo);
+        slo = ralo + rb;
+    #endif
+        return std::make_tuple(slo, shi);
+    }
+
+    /* Compute 128-bit sum of 128-bit to 64-bit signed integer addition */
+    inline std::tuple<uint64_t, int64_t>
+    add(uint64_t ralo, int64_t rahi, int64_t rb) const
+    {
+        uint64_t slo;
+        int64_t shi;
+    #if defined(__SIZEOF_INT128__)
+        __int128_t ra = ((__int128_t)rahi << 64) | ralo;
+        __int128_t sum = (__int128_t)ra + rb;
+        slo = sum;
+        shi = sum >> 64;
+    #else
+        if (rb < 0) {
+            shi = rahi - 1;
+            slo = ralo + rb;
+            if (slo < rb) {
+                shi++;
+            }
+        } else {
+            shi = rahi;
+            slo = ralo + rb;
+            if (slo < rb) {
+                shi++;
+            }
+        }
+    #endif
+        return std::make_tuple(slo, shi);
+    }
+
     /**
      * Compute 128-bit product of 64-bit unsigned integer multiplication
      * based on https://stackoverflow.com/a/28904636
@@ -177,6 +223,48 @@
         return std::make_tuple(plo, (int64_t)phi);
     }

+    /**
+     * Compute 128-bit result of 64-bit unsigned integer multiplication
+     * followed by addition
+     */
+    inline std::tuple<uint64_t, uint64_t>
+    multiplyAdd(uint64_t ra, uint64_t rb, uint64_t rc) const
+    {
+        uint64_t rlo, rhi;
+    #if defined(__SIZEOF_INT128__)
+        __uint128_t res = ((__uint128_t)ra * rb) + rc;
+        rlo = res;
+        rhi = res >> 64;
+    #else
+        uint64_t plo, phi;
+        std::tie(plo, phi) = multiply(ra, rb);
+        std::tie(rlo, rhi) = add(plo, phi, rc);
+    #endif
+        return std::make_tuple(rlo, rhi);
+    }
+
+    /**
+     * Compute 128-bit result of 64-bit signed integer multiplication
+     * followed by addition
+     */
+    inline std::tuple<uint64_t, int64_t>
+    multiplyAdd(int64_t ra, int64_t rb, int64_t rc) const
+    {
+        uint64_t rlo;
+        int64_t rhi;
+    #if defined(__SIZEOF_INT128__)
+        __int128_t res = (__int128_t)ra * rb + rc;
+        rlo = res;
+        rhi = res >> 64;
+    #else
+        uint64_t plo;
+        int64_t phi;
+        std::tie(plo, phi) = multiply(ra, rb);
+        std::tie(rlo, rhi) = add(plo, phi, rc);
+    #endif
+        return std::make_tuple(rlo, rhi);
+    }
+
     std::string generateDisassembly(
             Addr pc, const Loader::SymbolTable *symtab) const override;
 };
diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa
index b4c90fc..e8fcb66 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -36,6 +36,31 @@
 //
 decode PO default Unknown::unknown() {

+    4: decode VA_XO {
+
+        // Arithmetic instructions that use source registers Ra, Rb and Rc,
+        // with destination register Rt.
+        format IntArithOp {
+            48: maddhd({{
+                int64_t res;
+ std::tie(std::ignore, res) = multiplyAdd(Ra_sd, Rb_sd, Rc_sd);
+                Rt = res;
+            }});
+
+            49: maddhdu({{
+                uint64_t res;
+                std::tie(std::ignore, res) = multiplyAdd(Ra, Rb, Rc);
+                Rt = res;
+            }});
+
+            51: maddld({{
+                uint64_t res;
+ std::tie(res, std::ignore) = multiplyAdd(Ra_sd, Rb_sd, Rc_sd);
+                Rt = res;
+            }});
+        }
+    }
+
     format IntImmArithOp {
         7: mulli({{
             int64_t res = Ra_sd * si;
diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa
index 183c08b..924198d 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -290,6 +290,16 @@

 }};

+// Instructions that use source registers Ra and Rb, with the result
+// placed into Rt but do not check for carry, overflow or the Rc bit.
+def format IntArithOp(code, inst_flags = []) {{
+
+    # Generate the class
+    (header_output, decoder_output, decode_block, exec_output) = \
+        GenAluOp(name, Name, 'IntArithOp', code, inst_flags, BasicDecode,
+                 BasicConstructor)
+}};
+

 // Instructions that use source registers Ra and Rb, with the result
 // placed into Rt. Basically multiply and divide instructions. The



6 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40905
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: I04e6ea5fb4978b341a6e648424de2930ad41f449
Gerrit-Change-Number: 40905
Gerrit-PatchSet: 8
Gerrit-Owner: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-Reviewer: Boris Shingarov <shinga...@labware.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.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