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 <sandi...@linux.ibm.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(-)
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<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
@@ -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<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 13bbe87..4297d7d 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -209,6 +209,31 @@
}});
}
+ 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 IntImmOp {
10: cmpli({{
Xer xer = XER;
diff --git a/src/arch/power/isa/formats/integer.isa
b/src/arch/power/isa/formats/integer.isa
index cb858a8..6860c26 100644
--- a/src/arch/power/isa/formats/integer.isa
+++ b/src/arch/power/isa/formats/integer.isa
@@ -328,6 +328,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
--
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: 1
Gerrit-Owner: Sandipan Das <sandi...@linux.ibm.com>
Gerrit-MessageType: newchange
_______________________________________________
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