Sandipan Das has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/40908 )
Change subject: arch-power: Add doubleword divide-extended instructions
......................................................................
arch-power: Add doubleword divide-extended instructions
This introduces 128-bit division helpers for adds the
following instructions.
* Divide Doubleword Extended (divde[o][.])
* Divide Doubleword Extended Unsigned (divdeu[o][.])
Change-Id: I3591d91f22df2dce74fed5147d5de2ce82a83642
Signed-off-by: Sandipan Das <[email protected]>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40908
Reviewed-by: Boris Shingarov <[email protected]>
Maintainer: Boris Shingarov <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/arch/power/insts/integer.hh
M src/arch/power/isa/decoder.isa
2 files changed, 118 insertions(+), 0 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.hh
b/src/arch/power/insts/integer.hh
index fccb7cf..6433d85 100644
--- a/src/arch/power/insts/integer.hh
+++ b/src/arch/power/insts/integer.hh
@@ -265,6 +265,100 @@
return std::make_tuple(rlo, rhi);
}
+ /**
+ * Compute overflow, 64-bit quotient and 64-bit remainder of
+ * 128-bit by 64-bit unsigned integer division based on
+ * https://codereview.stackexchange.com/a/71013
+ */
+ inline std::tuple<bool, uint64_t, uint64_t>
+ divide(uint64_t ralo, uint64_t rahi, uint64_t rb) const
+ {
+ bool ov;
+ uint64_t q, r;
+ #if defined(__SIZEOF_INT128__)
+ if (rb == 0) {
+ ov = true;
+ } else {
+ __uint128_t ra = ((__uint128_t)rahi << 64) | ralo;
+ __uint128_t res = ra / rb;
+ q = res;
+ r = ra % rb;
+ ov = res > UINT64_MAX;
+ }
+ #else
+ uint64_t c = 0;
+
+ if (rb == 0) {
+ ov = true;
+ } else if (rahi == 0) {
+ q = ralo / rb;
+ r = ralo % rb;
+ ov = false;
+ } else if (rahi >= rb) {
+ ov = true;
+ } else {
+ for (int i = 0; i < 64; ++i) {
+ c = rahi >> 63;
+ rahi = (rahi << 1) | (ralo >> 63);
+ if (c || (rahi >= rb)) {
+ rahi -= rb;
+ c = 1;
+ } else {
+ c = 0;
+ }
+ ralo = (ralo << 1) | c;
+ }
+ q = ralo;
+ r = rahi;
+ ov = false;
+ }
+ #endif
+ return std::make_tuple(ov, q, r);
+ }
+
+ /**
+ * Compute overflow, 64-bit quotient and 64-bit remainder of
+ * 128-bit by 64-bit signed integer division
+ */
+ inline std::tuple<bool, int64_t, int64_t>
+ divide(uint64_t ralo, int64_t rahi, int64_t rb) const
+ {
+ bool ov;
+ int64_t q, r;
+ #if defined(__SIZEOF_INT128__)
+ if (rb == 0) {
+ ov = true;
+ } else {
+ __int128_t ra = ((__int128_t)rahi << 64) | ralo;
+ __int128_t res = ra / rb;
+ q = res;
+ r = ra % rb;
+ ov = res != q;
+ }
+ #else
+ bool raneg = rahi < 0;
+ bool rbneg = rb < 0;
+
+ if (raneg) {
+ ralo = ~(ralo);
+ rahi = ~(rahi);
+ if (ralo == -1ULL) {
+ ralo = 0;
+ rahi++;
+ } else {
+ ralo++;
+ }
+ }
+
+ if (rbneg) rb = -rb;
+ std::tie(ov, q, r) = divide(ralo, (uint64_t)rahi, (uint64_t)rb);
+ if (raneg ^ rbneg) q = -q;
+ if (raneg) r = -r;
+ if (!ov) ov = ((q < 0) ^ (raneg ^ rbneg));
+ #endif
+ return std::make_tuple(ov, q, r);
+ }
+
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 2a9bfcd..131be8d 100644
--- a/src/arch/power/isa/decoder.isa
+++ b/src/arch/power/isa/decoder.isa
@@ -574,6 +574,18 @@
266: IntSumOp::add({{ Ra }}, {{ Rb }});
format IntArithCheckRcOp {
+ 393: divdeu({{
+ uint64_t src1 = Ra;
+ uint64_t src2 = Rb;
+ uint64_t res;
+ std::tie(setOV, res, std::ignore) = divide(0, src1,
src2);
+ if (!setOV) {
+ Rt = res;
+ } else {
+ Rt = 0;
+ }
+ }}, true);
+
395: divweu({{
uint32_t src1 = Ra_ud;
uint32_t src2 = Rb_ud;
@@ -592,6 +604,18 @@
}
}}, true);
+ 425: divde({{
+ int64_t src1 = Ra_sd;
+ int64_t src2 = Rb_sd;
+ int64_t res;
+ std::tie(setOV, res, std::ignore) = divide(0, src1,
src2);
+ if (!setOV) {
+ Rt = res;
+ } else {
+ Rt = 0;
+ }
+ }}, true);
+
427: divwe({{
int32_t src1 = Ra_sw;
int32_t src2 = Rb_sw;
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/40908
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: I3591d91f22df2dce74fed5147d5de2ce82a83642
Gerrit-Change-Number: 40908
Gerrit-PatchSet: 8
Gerrit-Owner: Sandipan Das <[email protected]>
Gerrit-Reviewer: Boris Shingarov <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: Sandipan Das <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s