1 /* Copyright (C) 2014-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
28 #include "libgcc_tm.h"
30 #ifdef HAVE_GAS_HIDDEN
31 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
33 #define ATTRIBUTE_HIDDEN
36 /* Work out the largest "word" size that we can deal with on this target. */
37 #if MIN_UNITS_PER_WORD > 4
38 # define LIBGCC2_MAX_UNITS_PER_WORD 8
39 #elif (MIN_UNITS_PER_WORD > 2 \
40 || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4))
41 # define LIBGCC2_MAX_UNITS_PER_WORD 4
43 # define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD
46 /* Work out what word size we are using for this compilation.
47 The value can be set on the command line. */
48 #ifndef LIBGCC2_UNITS_PER_WORD
49 #define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD
52 #if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD
56 /* umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
57 UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
58 word product in HIGH_PROD and LOW_PROD. */
61 #define umul_ppmm(wh, wl, u, v) \
63 /* Generate multu instruction. */ \
64 UDWtype __t = (UDWtype)(u) * (UDWtype)(v); \
66 (wh) = (UWtype)(__t >> W_TYPE_SIZE); \
69 /* sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
70 high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
71 composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
72 LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
73 and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
77 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
78 __asm__ ("sub.l %0,%2,%4\n\t" \
80 : "=&r" (sl), "=r" (sh) \
81 : "r" (al), "r" (ah), "r" (bl), "r" (bh))
83 /* udiv_qqrnnd(high_quotient, low_quotient, remainder, high_numerator,
84 low_numerator, denominator) divides a UDWtype, composed by the UWtype
85 HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
86 in QUOTIENT and the remainder in REMAINDER. */
88 #define udiv_qqrnnd(qh, ql, r, nh, nl, d) \
89 __asm__ ("writemd %3,%4\n\t" \
94 : "=r" (ql), "=r" (qh), "=r" (r) \
95 : "r" (nl), "r" (nh), "r" (d) \
98 #if (defined (L_udivdi3) || defined (L_divdi3) || \
99 defined (L_umoddi3) || defined (L_moddi3))
105 #if (defined (L_udivdi3) || defined (L_divdi3) || \
106 defined (L_umoddi3) || defined (L_moddi3))
107 static inline __attribute__ ((__always_inline__
))
110 __udivmoddi4 (UDWtype n
, UDWtype d
, UDWtype
*rp
)
112 const DWunion nn
= {.ll
= n
};
113 const DWunion dd
= {.ll
= d
};
115 UWtype d0
, d1
, n0
, n1
, n2
;
129 d0
= 1 / d0
; /* Divide intentionally by zero. */
131 udiv_qqrnnd (q1
, q0
, n0
, n1
, n0
, d0
);
133 /* Remainder in n0. */
152 /* Remainder in n1n0. */
164 count_leading_zeros (bm
, d1
);
167 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
168 conclude (the most significant bit of n1 is set) /\ (the
169 quotient digit q0 = 0 or 1).
171 This special case is necessary, not an optimization. */
173 /* The condition on the next line takes advantage of that
174 n1 >= d1 (true due to program flow). */
175 if (n1
> d1
|| n0
>= d0
)
178 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
197 b
= W_TYPE_SIZE
- bm
;
199 d1
= (d1
<< bm
) | (d0
>> b
);
202 n1
= (n1
<< bm
) | (n0
>> b
);
205 udiv_qqrnnd (q1
, q0
, n1
, n2
, n1
, d1
);
206 umul_ppmm (m1
, m0
, q0
, d0
);
208 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
211 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
214 /* Remainder in (n1n0 - m1m0) >> bm. */
217 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
218 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
219 rr
.s
.high
= n1
>> bm
;
226 const DWunion ww
= {{.low
= q0
, .high
= q1
}};
233 __divdi3 (DWtype u
, DWtype v
)
236 DWunion uu
= {.ll
= u
};
237 DWunion vv
= {.ll
= v
};
247 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDWtype
*) 0);
257 __moddi3 (DWtype u
, DWtype v
)
260 DWunion uu
= {.ll
= u
};
261 DWunion vv
= {.ll
= v
};
270 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, (UDWtype
*)&w
);
280 __umoddi3 (UDWtype u
, UDWtype v
)
284 (void) __udivmoddi4 (u
, v
, &w
);
292 __udivdi3 (UDWtype n
, UDWtype d
)
294 return __udivmoddi4 (n
, d
, (UDWtype
*) 0);
298 #ifdef L_set_trampoline_parity
300 extern void __set_trampoline_parity (UWtype
*);
303 parity_bit (UWtype x
)
310 return x
& ((UWtype
) 1 << (W_TYPE_SIZE
- 1));
314 __set_trampoline_parity (UWtype
*addr
)
319 i
< (__LIBGCC_TRAMPOLINE_SIZE__
* __CHAR_BIT__
) / W_TYPE_SIZE
;
321 addr
[i
] |= parity_bit (addr
[i
]);
325 #endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */