[gem5-dev] Change in gem5/gem5[develop]: arch-power: Add doubleword multiply-add instructions

2021-06-28 Thread Boris Shingarov (Gerrit) via gem5-dev
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 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40905
Reviewed-by: Boris Shingarov 
Maintainer: Jason Lowe-Power 
Tested-by: kokoro 
---
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
+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
+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
+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
+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) = 

[gem5-dev] Change in gem5/gem5[develop]: arch-power: Add doubleword multiply-add instructions

2021-02-07 Thread Sandipan Das (Gerrit) via gem5-dev
Sandipan Das has uploaded this change for review. (  
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 
---
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(-)



diff --git a/src/arch/power/insts/integer.cc  
b/src/arch/power/insts/integer.cc

index d2862ff..da7f392 100644
--- a/src/arch/power/insts/integer.cc
+++ b/src/arch/power/insts/integer.cc
@@ -119,6 +119,7 @@
 {
 std::stringstream ss;
 bool printSecondSrc = true;
+bool printThirdSrc = false;

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

 // Additional characters depending on isa bits being set
@@ -153,6 +158,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 12ad8fc..366d36a 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -154,6 +154,52 @@
 {
 }

+/* Compute 128-bit sum of 128-bit to 64-bit unsigned integer addition  
*/

+inline std::tuple
+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
+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
@@ -197,6 +243,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
+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
+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