Sandipan Das has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/40903 )
Change subject: arch-power: Add doubleword multiply instructions
......................................................................
arch-power: Add doubleword multiply instructions
This introduces 128-bit multiplication helpers and adds
the following instructions.
* Multiply Low Doubleword (mulld[o][.])
* Multiply High Doubleword (mulhd[.])
* Multiply High Doubleword Unsigned (mulhdu[.])
Change-Id: Id579c95468ffe5fe7b5164579ec1dfb18f0b3ab3
Signed-off-by: Sandipan Das <sandi...@linux.ibm.com>
---
M src/arch/power/insts/integer.hh
M src/arch/power/isa/decoder.isa
2 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/src/arch/power/insts/integer.hh
b/src/arch/power/insts/integer.hh
index a75f38b..12ad8fc 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -154,6 +154,49 @@
{
}
+ /**
+ * Compute 128-bit product of 64-bit unsigned integer multiplication
+ * based on https://stackoverflow.com/a/28904636
+ */
+ inline std::tuple<uint64_t, uint64_t>
+ multiply(uint64_t ra, uint64_t rb) const
+ {
+ uint64_t plo, phi;
+ #if defined(__SIZEOF_INT128__)
+ __uint128_t prod = (__uint128_t)ra * rb;
+ plo = prod;
+ phi = prod >> 64;
+ #else
+ uint64_t ralo = (uint32_t)ra, rahi = ra >> 32;
+ uint64_t rblo = (uint32_t)rb, rbhi = rb >> 32;
+ uint64_t pp0 = ralo * rblo;
+ uint64_t pp1 = rahi * rblo;
+ uint64_t pp2 = ralo * rbhi;
+ uint64_t pp3 = rahi * rbhi;
+ uint64_t c = ((uint32_t)pp1) + ((uint32_t)pp2) + (pp0 >> 32);
+ phi = pp3 + (pp2 >> 32) + (pp1 >> 32) + (c >> 32);
+ plo = (c << 32) | ((uint32_t)pp0);
+ #endif
+ return std::make_tuple(plo, phi);
+ }
+
+ /* Compute 128-bit product of 64-bit signed integer multiplication */
+ inline std::tuple<uint64_t, int64_t>
+ multiply(int64_t ra, int64_t rb) const
+ {
+ uint64_t plo, phi;
+ #if defined(__SIZEOF_INT128__)
+ __int128_t prod = (__int128_t)ra * rb;
+ plo = prod;
+ phi = prod >> 64;
+ #else
+ std::tie(plo, phi) = multiply((uint64_t)ra, (uint64_t)rb);
+ if (rb < 0) phi -= (uint64_t)ra;
+ if (ra < 0) phi -= (uint64_t)rb;
+ #endif
+ return std::make_tuple(plo, (int64_t)phi);
+ }
+
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 ff4fece..13bbe87 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -557,6 +557,30 @@
}},
true);
+ 73: mulhd({{
+ int64_t res;
+ std::tie(std::ignore, res) = multiply(Ra_sd, Rb_sd);
+ Rt = res;
+ }});
+
+ 9: mulhdu({{
+ uint64_t res;
+ std::tie(std::ignore, res) = multiply(Ra, Rb);
+ Rt = res;
+ }});
+
+ 233: mulld({{
+ int64_t src1 = Ra_sd;
+ int64_t src2 = Rb_sd;
+ uint64_t res = src1 * src2;
+ std::tie(res, std::ignore) = multiply(src1, src2);
+ if (src1 != 0 && (int64_t)res / src1 != src2) {
+ setOV = true;
+ }
+ Rt = res;
+ }},
+ true);
+
491: divw({{
int32_t src1 = Ra_sw;
int32_t src2 = Rb_sw;
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40903
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: Id579c95468ffe5fe7b5164579ec1dfb18f0b3ab3
Gerrit-Change-Number: 40903
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