[gem5-dev] Change in gem5/gem5[develop]: arch-power: Add doubleword multiply-add instructions
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
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