1 /* Copyright (C) 2014-2019 Free Software Foundation, Inc. 2 3 This file is part of GCC. 4 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 8 version. 9 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 13 for more details. 14 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. 18 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/>. */ 23 24 #include "tconfig.h" 25 #include "tsystem.h" 26 #include "coretypes.h" 27 #include "tm.h" 28 #include "libgcc_tm.h" 29 30 #ifdef HAVE_GAS_HIDDEN 31 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) 32 #else 33 #define ATTRIBUTE_HIDDEN 34 #endif 35 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 42 #else 43 # define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD 44 #endif 45 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 50 #endif 51 52 #if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD 53 54 #include "libgcc2.h" 55 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. */ 59 60 #undef umul_ppmm 61 #define umul_ppmm(wh, wl, u, v) \ 62 do { \ 63 /* Generate multu instruction. */ \ 64 UDWtype __t = (UDWtype)(u) * (UDWtype)(v); \ 65 (wl) = (UWtype)__t; \ 66 (wh) = (UWtype)(__t >> W_TYPE_SIZE); \ 67 } while (0) 68 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, 74 and is lost. */ 75 76 #undef sub_ddmmss 77 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 78 __asm__ ("sub.l %0,%2,%4\n\t" \ 79 "subc.l %1,%3,%5" \ 80 : "=&r" (sl), "=r" (sh) \ 81 : "r" (al), "r" (ah), "r" (bl), "r" (bh)) 82 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. */ 87 88 #define udiv_qqrnnd(qh, ql, r, nh, nl, d) \ 89 __asm__ ("writemd %3,%4\n\t" \ 90 "divdu %5\n\t" \ 91 "readmda %0\n\t" \ 92 "readmdb %1\n\t" \ 93 "readmdc %2" \ 94 : "=r" (ql), "=r" (qh), "=r" (r) \ 95 : "r" (nl), "r" (nh), "r" (d) \ 96 : "mdb", "mdc") 97 98 #if (defined (L_udivdi3) || defined (L_divdi3) || \ 99 defined (L_umoddi3) || defined (L_moddi3)) 100 #define L_udivmoddi4 101 #endif 102 103 #ifdef L_udivmoddi4 104 105 #if (defined (L_udivdi3) || defined (L_divdi3) || \ 106 defined (L_umoddi3) || defined (L_moddi3)) 107 static inline __attribute__ ((__always_inline__)) 108 #endif 109 UDWtype 110 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) 111 { 112 const DWunion nn = {.ll = n}; 113 const DWunion dd = {.ll = d}; 114 DWunion rr; 115 UWtype d0, d1, n0, n1, n2; 116 UWtype q0, q1; 117 UWtype b, bm; 118 119 d0 = dd.s.low; 120 d1 = dd.s.high; 121 n0 = nn.s.low; 122 n1 = nn.s.high; 123 124 if (d1 == 0) 125 { 126 /* qq = NN / 0d */ 127 128 if (d0 == 0) 129 d0 = 1 / d0; /* Divide intentionally by zero. */ 130 131 udiv_qqrnnd (q1, q0, n0, n1, n0, d0); 132 133 /* Remainder in n0. */ 134 135 if (rp != 0) 136 { 137 rr.s.low = n0; 138 rr.s.high = 0; 139 *rp = rr.ll; 140 } 141 } 142 143 else 144 { 145 if (d1 > n1) 146 { 147 /* 00 = nn / DD */ 148 149 q0 = 0; 150 q1 = 0; 151 152 /* Remainder in n1n0. */ 153 if (rp != 0) 154 { 155 rr.s.low = n0; 156 rr.s.high = n1; 157 *rp = rr.ll; 158 } 159 } 160 else 161 { 162 /* 0q = NN / dd */ 163 164 count_leading_zeros (bm, d1); 165 if (bm == 0) 166 { 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). 170 171 This special case is necessary, not an optimization. */ 172 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) 176 { 177 q0 = 1; 178 sub_ddmmss (n1, n0, n1, n0, d1, d0); 179 } 180 else 181 q0 = 0; 182 183 q1 = 0; 184 185 if (rp != 0) 186 { 187 rr.s.low = n0; 188 rr.s.high = n1; 189 *rp = rr.ll; 190 } 191 } 192 else 193 { 194 UWtype m1, m0; 195 /* Normalize. */ 196 197 b = W_TYPE_SIZE - bm; 198 199 d1 = (d1 << bm) | (d0 >> b); 200 d0 = d0 << bm; 201 n2 = n1 >> b; 202 n1 = (n1 << bm) | (n0 >> b); 203 n0 = n0 << bm; 204 205 udiv_qqrnnd (q1, q0, n1, n2, n1, d1); 206 umul_ppmm (m1, m0, q0, d0); 207 208 if (m1 > n1 || (m1 == n1 && m0 > n0)) 209 { 210 q0--; 211 sub_ddmmss (m1, m0, m1, m0, d1, d0); 212 } 213 214 /* Remainder in (n1n0 - m1m0) >> bm. */ 215 if (rp != 0) 216 { 217 sub_ddmmss (n1, n0, n1, n0, m1, m0); 218 rr.s.low = (n1 << b) | (n0 >> bm); 219 rr.s.high = n1 >> bm; 220 *rp = rr.ll; 221 } 222 } 223 } 224 } 225 226 const DWunion ww = {{.low = q0, .high = q1}}; 227 return ww.ll; 228 } 229 #endif 230 231 #ifdef L_divdi3 232 DWtype 233 __divdi3 (DWtype u, DWtype v) 234 { 235 Wtype c = 0; 236 DWunion uu = {.ll = u}; 237 DWunion vv = {.ll = v}; 238 DWtype w; 239 240 if (uu.s.high < 0) 241 c = ~c, 242 uu.ll = -uu.ll; 243 if (vv.s.high < 0) 244 c = ~c, 245 vv.ll = -vv.ll; 246 247 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0); 248 if (c) 249 w = -w; 250 251 return w; 252 } 253 #endif 254 255 #ifdef L_moddi3 256 DWtype 257 __moddi3 (DWtype u, DWtype v) 258 { 259 Wtype c = 0; 260 DWunion uu = {.ll = u}; 261 DWunion vv = {.ll = v}; 262 DWtype w; 263 264 if (uu.s.high < 0) 265 c = ~c, 266 uu.ll = -uu.ll; 267 if (vv.s.high < 0) 268 vv.ll = -vv.ll; 269 270 (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); 271 if (c) 272 w = -w; 273 274 return w; 275 } 276 #endif 277 278 #ifdef L_umoddi3 279 UDWtype 280 __umoddi3 (UDWtype u, UDWtype v) 281 { 282 UDWtype w; 283 284 (void) __udivmoddi4 (u, v, &w); 285 286 return w; 287 } 288 #endif 289 290 #ifdef L_udivdi3 291 UDWtype 292 __udivdi3 (UDWtype n, UDWtype d) 293 { 294 return __udivmoddi4 (n, d, (UDWtype *) 0); 295 } 296 #endif 297 298 #ifdef L_set_trampoline_parity 299 #undef int 300 extern void __set_trampoline_parity (UWtype *); 301 302 static inline UWtype 303 parity_bit (UWtype x) 304 { 305 x ^= x << 16; 306 x ^= x << 8; 307 x ^= x << 4; 308 x ^= x << 2; 309 x ^= x << 1; 310 return x & ((UWtype) 1 << (W_TYPE_SIZE - 1)); 311 } 312 313 void 314 __set_trampoline_parity (UWtype *addr) 315 { 316 int i; 317 318 for (i = 0; 319 i < (__LIBGCC_TRAMPOLINE_SIZE__ * __CHAR_BIT__) / W_TYPE_SIZE; 320 i++) 321 addr[i] |= parity_bit (addr[i]); 322 } 323 #endif 324 325 #endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */ 326