summaryrefslogtreecommitdiff
path: root/stdlib/longlong.h
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/longlong.h')
-rw-r--r--stdlib/longlong.h38
1 files changed, 35 insertions, 3 deletions
diff --git a/stdlib/longlong.h b/stdlib/longlong.h
index 4f2c4f5dfc..5cbc410fb0 100644
--- a/stdlib/longlong.h
+++ b/stdlib/longlong.h
@@ -1,5 +1,5 @@
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -139,6 +139,9 @@ extern const UQItype __clz_tab[256] attribute_hidden;
#endif /* __aarch64__ */
#if defined (__alpha) && W_TYPE_SIZE == 64
+/* There is a bug in g++ before version 5 that
+ errors on __builtin_alpha_umulh. */
+#if !defined(__cplusplus) || __GNUC__ >= 5
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
@@ -146,6 +149,7 @@ extern const UQItype __clz_tab[256] attribute_hidden;
(pl) = __m0 * __m1; \
} while (0)
#define UMUL_TIME 46
+#endif /* !c++ */
#ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \
do { UDItype __r; \
@@ -1082,7 +1086,7 @@ extern UDItype __umulsidi3 (USItype, USItype);
} while (0)
#endif
-#if defined(__sh__) && !__SHMEDIA__ && W_TYPE_SIZE == 32
+#if defined(__sh__) && (!defined (__SHMEDIA__) || !__SHMEDIA__) && W_TYPE_SIZE == 32
#ifndef __sh1__
#define umul_ppmm(w1, w0, u, v) \
__asm__ ( \
@@ -1098,6 +1102,33 @@ extern UDItype __umulsidi3 (USItype, USItype);
/* This is the same algorithm as __udiv_qrnnd_c. */
#define UDIV_NEEDS_NORMALIZATION 1
+#ifdef __FDPIC__
+/* FDPIC needs a special version of the asm fragment to extract the
+ code address from the function descriptor. __udiv_qrnnd_16 is
+ assumed to be local and not to use the GOT, so loading r12 is
+ not needed. */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \
+ __attribute__ ((visibility ("hidden"))); \
+ /* r0: rn r1: qn */ /* r0: n1 r4: n0 r5: d r6: d1 */ /* r2: __m */ \
+ __asm__ ( \
+ "mov%M4 %4,r5\n" \
+" swap.w %3,r4\n" \
+" swap.w r5,r6\n" \
+" mov.l @%5,r2\n" \
+" jsr @r2\n" \
+" shll16 r6\n" \
+" swap.w r4,r4\n" \
+" mov.l @%5,r2\n" \
+" jsr @r2\n" \
+" swap.w r1,%0\n" \
+" or r1,%0" \
+ : "=r" (q), "=&z" (r) \
+ : "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \
+ : "r1", "r2", "r4", "r5", "r6", "pr", "t"); \
+ } while (0)
+#else
#define udiv_qrnnd(q, r, n1, n0, d) \
do { \
extern UWtype __udiv_qrnnd_16 (UWtype, UWtype) \
@@ -1117,6 +1148,7 @@ extern UDItype __umulsidi3 (USItype, USItype);
: "1" (n1), "r" (n0), "rm" (d), "r" (&__udiv_qrnnd_16) \
: "r1", "r2", "r4", "r5", "r6", "pr", "t"); \
} while (0)
+#endif /* __FDPIC__ */
#define UDIV_TIME 80
@@ -1127,7 +1159,7 @@ extern UDItype __umulsidi3 (USItype, USItype);
#endif /* __sh__ */
-#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32
+#if defined (__SH5__) && defined (__SHMEDIA__) && __SHMEDIA__ && W_TYPE_SIZE == 32
#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
#define count_leading_zeros(count, x) \
do \