Roger Chang has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/70597?usp=email )

Change subject: arch-riscv: Simplify amd merge RV32/RV64 the RVM instructions
......................................................................

arch-riscv: Simplify amd merge RV32/RV64 the RVM instructions

The change move the details implementation to utility.hh and merge
the RV32 and RV64 versions into one.

Change-Id: I438bfb0fc511f0f27e83f247d386c58493db65b4
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/70597
Tested-by: kokoro <noreply+kok...@google.com>
Reviewed-by: Yu-hsin Wang <yuhsi...@google.com>
Maintainer: Bobby Bruce <bbr...@ucdavis.edu>
---
M src/arch/riscv/isa/decoder.isa
M src/arch/riscv/utility.hh
2 files changed, 149 insertions(+), 183 deletions(-)

Approvals:
  kokoro: Regressions pass
  Yu-hsin Wang: Looks good to me, approved
  Bobby Bruce: Looks good to me, approved




diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa
index 3acd80e..47519ee 100644
--- a/src/arch/riscv/isa/decoder.isa
+++ b/src/arch/riscv/isa/decoder.isa
@@ -1084,34 +1084,13 @@
                     0x0: sll({{
                         Rd = rvSext(Rs1 << rvSelect(Rs2<4:0>, Rs2<5:0>));
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_mulh({{
-                            Rd_sw = ((int64_t)Rs1_sw * Rs2_sw) >> 32;
-                        }}, IntMultOp);
-                        0x1: mulh({{
-                            bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
-
-                            uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
- uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd)
32;
-                            uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
- uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd)
32;
-
-                            uint64_t hi = Rs1_hi*Rs2_hi;
-                            uint64_t mid1 = Rs1_hi*Rs2_lo;
-                            uint64_t mid2 = Rs1_lo*Rs2_hi;
-                            uint64_t lo = Rs2_lo*Rs1_lo;
-                            uint64_t carry = ((uint64_t)(uint32_t)mid1
-                                    + (uint64_t)(uint32_t)mid2
-                                    + (lo >> 32)) >> 32;
-
-                            uint64_t res = hi +
-                                          (mid1 >> 32) +
-                                          (mid2 >> 32) +
-                                          carry;
- Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
-                                        : res;
-                        }}, IntMultOp);
-                    }
+                    0x1: mulh({{
+                        if (machInst.rv_type == RV32) {
+                            Rd_sd = mulh_32(Rs1_sd, Rs2_sd);
+                        } else {
+                            Rd_sd = mulh_64(Rs1_sd, Rs2_sd);
+                        }
+                    }}, IntMultOp);
                     0x5: clmul({{
                         uint64_t result = 0;
                         for (int i = 0; i < rvSelect(32, 64); i++) {
@@ -1144,32 +1123,13 @@
                     0x0: slt({{
                         Rd = (rvSext(Rs1_sd) < rvSext(Rs2_sd)) ? 1 : 0;
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_mulhsu({{
-                            Rd_sw = ((int64_t)Rs1_sw * Rs2_uw) >> 32;
-                        }}, IntMultOp);
-                        0x1: mulhsu({{
-                            bool negate = Rs1_sd < 0;
-                            uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
- uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd)
32;
-                            uint64_t Rs2_lo = (uint32_t)Rs2;
-                            uint64_t Rs2_hi = Rs2 >> 32;
-
-                            uint64_t hi = Rs1_hi*Rs2_hi;
-                            uint64_t mid1 = Rs1_hi*Rs2_lo;
-                            uint64_t mid2 = Rs1_lo*Rs2_hi;
-                            uint64_t lo = Rs1_lo*Rs2_lo;
-                            uint64_t carry = ((uint64_t)(uint32_t)mid1
-                                    + (uint64_t)(uint32_t)mid2
-                                    + (lo >> 32)) >> 32;
-
-                            uint64_t res = hi +
-                                          (mid1 >> 32) +
-                                          (mid2 >> 32) +
-                                          carry;
- Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
-                        }}, IntMultOp);
-                    }
+                    0x1: mulhsu({{
+                        if (machInst.rv_type == RV32) {
+                            Rd_sd = mulhsu_32(Rs1_sd, Rs2);
+                        } else {
+                            Rd_sd = mulhsu_64(Rs1_sd, Rs2);
+                        }
+                    }}, IntMultOp);
                     0x5: clmulr({{
                         uint64_t result = 0;
                         uint64_t xlen = rvSelect(32, 64);
@@ -1197,27 +1157,13 @@
                     0x0: sltu({{
                         Rd = (rvZext(Rs1) < rvZext(Rs2)) ? 1 : 0;
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_mulhu({{
-                            Rd_sw = ((uint64_t)Rs1_uw * Rs2_uw) >> 32;
-                        }}, IntMultOp);
-                        0x1: mulhu({{
-                            uint64_t Rs1_lo = (uint32_t)Rs1;
-                            uint64_t Rs1_hi = Rs1 >> 32;
-                            uint64_t Rs2_lo = (uint32_t)Rs2;
-                            uint64_t Rs2_hi = Rs2 >> 32;
-
-                            uint64_t hi = Rs1_hi*Rs2_hi;
-                            uint64_t mid1 = Rs1_hi*Rs2_lo;
-                            uint64_t mid2 = Rs1_lo*Rs2_hi;
-                            uint64_t lo = Rs1_lo*Rs2_lo;
-                            uint64_t carry = ((uint64_t)(uint32_t)mid1
-                                    + (uint64_t)(uint32_t)mid2
-                                    + (lo >> 32)) >> 32;
-
-                            Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
-                        }}, IntMultOp);
-                    }
+                    0x1: mulhu({{
+                        if (machInst.rv_type == RV32) {
+                            Rd = (int32_t)mulhu_32(Rs1, Rs2);
+                        } else {
+                            Rd = mulhu_64(Rs1, Rs2);
+                        }
+                    }}, IntMultOp);
                     0x5: clmulh({{
                         uint64_t result = 0;
                         uint64_t xlen = rvSelect(32, 64);
@@ -1235,30 +1181,13 @@
                     0x0: xor({{
                         Rd = rvSext(Rs1 ^ Rs2);
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_div({{
-                            constexpr int32_t kRsMin = \
-                                std::numeric_limits<int32_t>::min();
-                            if (Rs2_sw == 0) {
-                                Rd_sw = -1;
-                            } else if (Rs1_sw == kRsMin && Rs2_sw == -1) {
-                                Rd_sw = kRsMin;
-                            } else {
-                                Rd_sw = Rs1_sw/Rs2_sw;
-                            }
-                        }}, IntDivOp);
-                        0x1: div({{
-                            constexpr int64_t kRsMin = \
-                                std::numeric_limits<int64_t>::min();
-                            if (Rs2_sd == 0) {
-                                Rd_sd = -1;
-                            } else if (Rs1_sd == kRsMin && Rs2_sd == -1) {
-                                Rd_sd = kRsMin;
-                            } else {
-                                Rd_sd = Rs1_sd/Rs2_sd;
-                            }
-                        }}, IntDivOp);
-                    }
+                    0x1: div({{
+                        if (machInst.rv_type == RV32) {
+                            Rd_sd = div<int32_t>(Rs1, Rs2);
+                        } else {
+                            Rd_sd = div<int64_t>(Rs1, Rs2);
+                        }
+                    }}, IntDivOp);
                     0x4: pack({{
                         int xlen = rvSelect(32, 64);
                         Rd = rvSext(
@@ -1289,22 +1218,13 @@
                         Rd = rvSext(rvZext(Rs1) >>
                                     rvSelect(Rs2<4:0>, Rs2<5:0>));
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_divu({{
-                            if (Rs2_uw == 0) {
- Rd_sw = std::numeric_limits<uint32_t>::max();
-                            } else {
-                                Rd_sw = Rs1_uw/Rs2_uw;
-                            }
-                        }}, IntDivOp);
-                        0x1: divu({{
-                            if (Rs2 == 0) {
-                                Rd = std::numeric_limits<uint64_t>::max();
-                            } else {
-                                Rd = Rs1/Rs2;
-                            }
-                        }}, IntDivOp);
-                    }
+                    0x1: divu({{
+                        if (machInst.rv_type == RV32) {
+                            Rd = (int32_t)divu<uint32_t>(Rs1, Rs2);
+                        } else {
+                            Rd = divu<uint64_t>(Rs1, Rs2);
+                        }
+                    }}, IntDivOp);
                     0x20: sra({{
Rd = rvSext(Rs1_sd) >> rvSelect(Rs2<4:0>, Rs2<5:0>);
                     }});
@@ -1327,30 +1247,13 @@
                     0x0: or({{
                         Rd = rvSext(Rs1 | Rs2);
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_rem({{
-                            constexpr int32_t kRsMin = \
-                                std::numeric_limits<int32_t>::min();
-                            if (Rs2_sw == 0) {
-                                Rd_sw = Rs1_sw;
-                            } else if (Rs1_sw == kRsMin && Rs2_sw == -1) {
-                                Rd_sw = 0;
-                            } else {
-                                Rd_sw = Rs1_sw%Rs2_sw;
-                            }
-                        }}, IntDivOp);
-                        0x1: rem({{
-                            constexpr int64_t kRsMin = \
-                                std::numeric_limits<int64_t>::min();
-                            if (Rs2_sd == 0) {
-                                Rd = Rs1_sd;
-                            } else if (Rs1_sd == kRsMin && Rs2_sd == -1) {
-                                Rd = 0;
-                            } else {
-                                Rd = Rs1_sd%Rs2_sd;
-                            }
-                        }}, IntDivOp);
-                    }
+                    0x1: rem({{
+                        if (machInst.rv_type == RV32) {
+                            Rd_sd = rem<int32_t>(Rs1, Rs2);
+                        } else {
+                            Rd_sd = rem<int64_t>(Rs1, Rs2);
+                        }
+                    }}, IntDivOp);
                     0x5: max({{
                         Rd_sd = std::max(rvSext(Rs1_sd), rvSext(Rs2_sd));
                     }});
@@ -1365,22 +1268,13 @@
                     0x0: and({{
                         Rd = rvSext(Rs1 & Rs2);
                     }});
-                    0x1: decode RVTYPE {
-                        0x0: rv32_remu({{
-                            if (Rs2_uw == 0) {
-                                Rd_sw = Rs1_uw;
-                            } else {
-                                Rd_sw = Rs1_uw%Rs2_uw;
-                            }
-                        }}, IntDivOp);
-                        0x1: remu({{
-                            if (Rs2 == 0) {
-                                Rd = Rs1;
-                            } else {
-                                Rd = Rs1%Rs2;
-                            }
-                        }}, IntDivOp);
-                    }
+                    0x1: remu({{
+                        if (machInst.rv_type == RV32) {
+                            Rd = (int32_t)remu<uint32_t>(Rs1, Rs2);
+                        } else {
+                            Rd = remu<uint64_t>(Rs1, Rs2);
+                        }
+                    }}, IntDivOp);
                     0x4: packh({{
                         // It doesn't need to sign ext as MSB is always 0
                         Rd = (Rs2_ub << 8) | Rs1_ub;
@@ -1432,15 +1326,7 @@
                     }
                     0x4: decode FUNCT7 {
                         0x1: divw({{
-                            constexpr int32_t kRsMin = \
-                                std::numeric_limits<int32_t>::min();
-                            if (Rs2_sw == 0) {
-                                Rd_sd = -1;
-                            } else if (Rs1_sw == kRsMin && Rs2_sw == -1) {
-                                Rd_sd = kRsMin;
-                            } else {
-                                Rd_sd = Rs1_sw/Rs2_sw;
-                            }
+                            Rd_sd = div<int32_t>(Rs1, Rs2);
                         }}, IntDivOp);
                         0x4: packw({{
                             Rd_sd = sext<32>((Rs2_uh << 16) | Rs1_uh);
@@ -1454,11 +1340,7 @@
                             Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
                         }});
                         0x1: divuw({{
-                            if (Rs2_uw == 0) {
- Rd_sd = std::numeric_limits<uint64_t>::max();
-                            } else {
-                                Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
-                            }
+                            Rd = sext<32>(divu<uint32_t>(Rs1, Rs2));
                         }}, IntDivOp);
                         0x20: sraw({{
                             Rd_sd = Rs1_sw >> Rs2<4:0>;
@@ -1470,26 +1352,14 @@
                     }
                     0x6:  decode FUNCT7 {
                         0x1: remw({{
-                            constexpr int32_t kRsMin = \
-                                std::numeric_limits<int32_t>::min();
-                            if (Rs2_sw == 0) {
-                                Rd_sd = Rs1_sw;
-                            } else if (Rs1_sw == kRsMin && Rs2_sw == -1) {
-                                Rd_sd = 0;
-                            } else {
-                                Rd_sd = Rs1_sw%Rs2_sw;
-                            }
+                            Rd_sd = rem<int32_t>(Rs1, Rs2);
                         }}, IntDivOp);
                         0x10: sh3add_uw({{
                             Rd = (((uint64_t)Rs1_uw) << 3) + Rs2;
                         }});
                     }
                     0x7: remuw({{
-                        if (Rs2_uw == 0) {
-                            Rd_sd = (int32_t)Rs1_uw;
-                        } else {
-                            Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
-                        }
+                        Rd = sext<32>(remu<uint32_t>(Rs1, Rs2));
                     }}, IntDivOp);
                 }
             }
diff --git a/src/arch/riscv/utility.hh b/src/arch/riscv/utility.hh
index 3bd34c4..5fccc84 100644
--- a/src/arch/riscv/utility.hh
+++ b/src/arch/riscv/utility.hh
@@ -55,6 +55,7 @@
 #include "cpu/reg_class.hh"
 #include "cpu/static_inst.hh"
 #include "cpu/thread_context.hh"
+#include "enums/RiscvType.hh"
 #include "rvk.hh"

 namespace gem5
@@ -137,6 +138,101 @@
     }
 }

+inline uint32_t
+mulhu_32(uint32_t rs1, uint32_t rs2)
+{
+    return ((uint64_t)rs1 * rs2) >> 32;
+}
+
+inline uint64_t
+mulhu_64(uint64_t rs1, uint64_t rs2)
+{
+    uint64_t rs1_lo = (uint32_t)rs1;
+    uint64_t rs1_hi = rs1 >> 32;
+    uint64_t rs2_lo = (uint32_t)rs2;
+    uint64_t rs2_hi = rs2 >> 32;
+
+    uint64_t hi = rs1_hi * rs2_hi;
+    uint64_t mid1 = rs1_hi * rs2_lo;
+    uint64_t mid2 = rs1_lo * rs2_hi;
+    uint64_t lo = rs1_lo * rs2_lo;
+    uint64_t carry = ((uint64_t)(uint32_t)mid1
+            + (uint64_t)(uint32_t)mid2
+            + (lo >> 32)) >> 32;
+
+    return hi + (mid1 >> 32) + (mid2 >> 32) + carry;
+}
+
+inline int32_t
+mulh_32(int32_t rs1, int32_t rs2)
+{
+    return ((int64_t)rs1 * rs2) >> 32;
+}
+
+inline int64_t
+mulh_64(int64_t rs1, int64_t rs2)
+{
+    bool negate = (rs1 < 0) != (rs2 < 0);
+    uint64_t res = mulhu_64(std::abs(rs1), std::abs(rs2));
+    return negate ? ~res + (rs1 * rs2 == 0 ? 1 : 0) : res;
+}
+
+inline int32_t
+mulhsu_32(int32_t rs1, uint32_t rs2)
+{
+    return ((int64_t)rs1 * rs2) >> 32;
+}
+
+inline int64_t
+mulhsu_64(int64_t rs1, uint64_t rs2)
+{
+    bool negate = rs1 < 0;
+    uint64_t res = mulhu_64(std::abs(rs1), rs2);
+    return negate ? ~res + (rs1 * rs2 == 0 ? 1 : 0) : res;
+}
+
+template<typename T> inline T
+div(T rs1, T rs2)
+{
+    constexpr T kRsMin = std::numeric_limits<T>::min();
+    if (rs2 == 0) {
+        return -1;
+    } else if (rs1 == kRsMin && rs2 == -1) {
+        return kRsMin;
+    } else {
+        return rs1 / rs2;
+    }
+}
+
+template<typename T> inline T
+divu(T rs1, T rs2)
+{
+    if (rs2 == 0) {
+        return std::numeric_limits<T>::max();
+    } else {
+        return rs1 / rs2;
+    }
+}
+
+template<typename T> inline T
+rem(T rs1, T rs2)
+{
+    constexpr T kRsMin = std::numeric_limits<T>::min();
+    if (rs2 == 0) {
+        return rs1;
+    } else if (rs1 == kRsMin && rs2 == -1) {
+        return 0;
+    } else {
+        return rs1 % rs2;
+    }
+}
+
+template<typename T> inline T
+remu(T rs1, T rs2)
+{
+    return (rs2 == 0) ? rs1 : rs1 % rs2;
+}
+
 } // namespace RiscvISA
 } // namespace gem5


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/70597?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I438bfb0fc511f0f27e83f247d386c58493db65b4
Gerrit-Change-Number: 70597
Gerrit-PatchSet: 3
Gerrit-Owner: Roger Chang <rogerycch...@google.com>
Gerrit-Reviewer: Ayaz Akram <yazak...@ucdavis.edu>
Gerrit-Reviewer: Bobby Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Hoa Nguyen <hoangu...@ucdavis.edu>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: Roger Chang <rogerycch...@google.com>
Gerrit-Reviewer: Yu-hsin Wang <yuhsi...@google.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to