RISC-V: Implement __umulsidi3, umul_ppmm and __muluw3

2017-11-20  Kito Cheng  <kito.cheng@gmail.com>

        * longlong.h [__riscv] (__umulsidi3): Define.
        [__riscv] (umul_ppmm): Likewise.
        [__riscv] (__muluw3): Likewise.

From-SVN: r254965
This commit is contained in:
Kito Cheng 2017-11-20 19:08:38 +00:00 committed by Palmer Dabbelt
parent d68ddd2b35
commit ee1c213355
2 changed files with 56 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2017-11-20 Kito Cheng <kito.cheng@gmail.com>
* longlong.h [__riscv] (__umulsidi3): Define.
[__riscv] (umul_ppmm): Likewise.
[__riscv] (__muluw3): Likewise.
2017-11-10 Stephen Crane <sjc@immunant.com>
* plugin-api.h: Add plugin API for processing plugin-added

View File

@ -1050,6 +1050,56 @@ extern UDItype __umulsidi3 (USItype, USItype);
} while (0)
#endif
#if defined(__riscv)
#ifdef __riscv_mul
#define __umulsidi3(u,v) ((UDWtype)(UWtype)(u) * (UWtype)(v))
#define __muluw3(a, b) ((UWtype)(a) * (UWtype)(b))
#else
#if __riscv_xlen == 32
#define MULUW3 "call __mulsi3"
#elif __riscv_xlen == 64
#define MULUW3 "call __muldi3"
#else
#error unsupport xlen
#endif /* __riscv_xlen */
/* We rely on the fact that MULUW3 doesn't clobber the t-registers.
It can get better register allocation result. */
#define __muluw3(a, b) \
({ \
register UWtype __op0 asm ("a0") = a; \
register UWtype __op1 asm ("a1") = b; \
asm volatile (MULUW3 \
: "+r" (__op0), "+r" (__op1) \
: \
: "ra", "a2", "a3"); \
__op0; \
})
#endif /* __riscv_mul */
#define umul_ppmm(w1, w0, u, v) \
do { \
UWtype __x0, __x1, __x2, __x3; \
UHWtype __ul, __vl, __uh, __vh; \
\
__ul = __ll_lowpart (u); \
__uh = __ll_highpart (u); \
__vl = __ll_lowpart (v); \
__vh = __ll_highpart (v); \
\
__x0 = __muluw3 (__ul, __vl); \
__x1 = __muluw3 (__ul, __vh); \
__x2 = __muluw3 (__uh, __vl); \
__x3 = __muluw3 (__uh, __vh); \
\
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
__x1 += __x2; /* but this indeed can */ \
if (__x1 < __x2) /* did we get it? */ \
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
\
(w1) = __x3 + __ll_highpart (__x1); \
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
} while (0)
#endif /* __riscv */
#if defined(__sh__) && W_TYPE_SIZE == 32
#ifndef __sh1__
#define umul_ppmm(w1, w0, u, v) \