From baa8d8be1f1a3d83caf248533fda9abaa3b0ee70 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 27 Sep 2014 11:01:22 -0700 Subject: [PATCH] Avoid use of __int128_t It is nonstandard, and GCC doesn't support it on 32-bit platforms. The resulting code for MULH[[S]U] is crappier, but that doesn't really matter, as these instructions are dynamically infrequent. --- hwacha/insn_template_hwacha_ut.h | 1 + riscv/cachesim.h | 2 +- riscv/decode.h | 6 +---- riscv/dummy-rocc-test.c | 2 +- riscv/insn_template.h | 1 + riscv/insns/mulh.h | 8 ++----- riscv/insns/mulhsu.h | 8 ++----- riscv/insns/mulhu.h | 4 ++-- riscv/memtracer.h | 2 +- riscv/mulhi.h | 41 ++++++++++++++++++++++++++++++++ riscv/riscv.mk.in | 1 + 11 files changed, 54 insertions(+), 22 deletions(-) create mode 100644 riscv/mulhi.h diff --git a/hwacha/insn_template_hwacha_ut.h b/hwacha/insn_template_hwacha_ut.h index a26e528..d585f9b 100644 --- a/hwacha/insn_template_hwacha_ut.h +++ b/hwacha/insn_template_hwacha_ut.h @@ -1,4 +1,5 @@ #include "hwacha.h" +#include "mulhi.h" #include "decode_hwacha_ut.h" #include "softfloat.h" #include "platform.h" // softfloat isNaNF32UI, etc. diff --git a/riscv/cachesim.h b/riscv/cachesim.h index 51044c3..a529007 100644 --- a/riscv/cachesim.h +++ b/riscv/cachesim.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include class lfsr_t { diff --git a/riscv/decode.h b/riscv/decode.h index d647b2c..b32c6e4 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -7,17 +7,13 @@ # error spike requires a two''s-complement c++ implementation #endif -#define __STDC_LIMIT_MACROS -#include +#include #include #include "encoding.h" #include "config.h" #include "common.h" #include -typedef int int128_t __attribute__((mode(TI))); -typedef unsigned int uint128_t __attribute__((mode(TI))); - typedef int64_t sreg_t; typedef uint64_t reg_t; typedef uint64_t freg_t; diff --git a/riscv/dummy-rocc-test.c b/riscv/dummy-rocc-test.c index ba362a4..4071ece 100644 --- a/riscv/dummy-rocc-test.c +++ b/riscv/dummy-rocc-test.c @@ -5,7 +5,7 @@ #include #include -#include +#include int main() { uint64_t x = 123, y = 456, z = 0; diff --git a/riscv/insn_template.h b/riscv/insn_template.h index 109b4c4..56a9c7f 100644 --- a/riscv/insn_template.h +++ b/riscv/insn_template.h @@ -1,4 +1,5 @@ #include "mmu.h" +#include "mulhi.h" #include "softfloat.h" #include "platform.h" // softfloat isNaNF32UI, etc. #include "internals.h" // ditto diff --git a/riscv/insns/mulh.h b/riscv/insns/mulh.h index f63869d..8ae7520 100644 --- a/riscv/insns/mulh.h +++ b/riscv/insns/mulh.h @@ -1,8 +1,4 @@ -if(xpr64) -{ - int64_t a = RS1; - int64_t b = RS2; - WRITE_RD((int128_t(a) * int128_t(b)) >> 64); -} +if (xpr64) + WRITE_RD(mulh(RS1, RS2)); else WRITE_RD(sext32((sext32(RS1) * sext32(RS2)) >> 32)); diff --git a/riscv/insns/mulhsu.h b/riscv/insns/mulhsu.h index d62256e..3168ade 100644 --- a/riscv/insns/mulhsu.h +++ b/riscv/insns/mulhsu.h @@ -1,8 +1,4 @@ -if(xpr64) -{ - int64_t a = RS1; - uint64_t b = RS2; - WRITE_RD((int128_t(a) * uint128_t(b)) >> 64); -} +if (xpr64) + WRITE_RD(mulhsu(RS1, RS2)); else WRITE_RD(sext32((sext32(RS1) * reg_t((uint32_t)RS2)) >> 32)); diff --git a/riscv/insns/mulhu.h b/riscv/insns/mulhu.h index 2d6f48c..b03b870 100644 --- a/riscv/insns/mulhu.h +++ b/riscv/insns/mulhu.h @@ -1,4 +1,4 @@ -if(xpr64) - WRITE_RD((uint128_t(RS1) * uint128_t(RS2)) >> 64); +if (xpr64) + WRITE_RD(mulhu(RS1, RS2)); else WRITE_RD(sext32(((uint64_t)(uint32_t)RS1 * (uint64_t)(uint32_t)RS2) >> 32)); diff --git a/riscv/memtracer.h b/riscv/memtracer.h index e223c43..f2f1b1c 100644 --- a/riscv/memtracer.h +++ b/riscv/memtracer.h @@ -3,7 +3,7 @@ #ifndef _MEMTRACER_H #define _MEMTRACER_H -#include +#include #include #include diff --git a/riscv/mulhi.h b/riscv/mulhi.h new file mode 100644 index 0000000..f0a5d7b --- /dev/null +++ b/riscv/mulhi.h @@ -0,0 +1,41 @@ +#ifndef _RISCV_MULHI_H +#define _RISCV_MULHI_H + +#include + +inline uint64_t mulhu(uint64_t a, uint64_t b) +{ + uint64_t t; + uint32_t y1, y2, y3; + uint64_t a0 = (uint32_t)a, a1 = a >> 32; + uint64_t b0 = (uint32_t)b, b1 = b >> 32; + + t = a1*b0 + ((a0*b0) >> 32); + y1 = t; + y2 = t >> 32; + + t = a0*b1 + y1; + y1 = t; + + t = a1*b1 + y2 + (t >> 32); + y2 = t; + y3 = t >> 32; + + return ((uint64_t)y3 << 32) | y2; +} + +inline int64_t mulh(int64_t a, int64_t b) +{ + int negate = (a < 0) != (b < 0); + uint64_t res = mulhu(a < 0 ? -a : a, b < 0 ? -b : b); + return negate ? ~res + (a * b == 0) : res; +} + +inline int64_t mulhsu(int64_t a, uint64_t b) +{ + int negate = a < 0; + uint64_t res = mulhu(a < 0 ? -a : a, b); + return negate ? ~res + (a * b == 0) : res; +} + +#endif diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 0fd5eaf..e9ca63f 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -21,6 +21,7 @@ riscv_hdrs = \ rocc.h \ dummy-rocc.h \ insn_template.h \ + mulhi.h \ riscv_precompiled_hdrs = \ insn_template.h \ -- 2.30.2