1 /* Signed and unsigned multiplication and division and modulus for CRIS. 2 Contributed by Axis Communications. 3 Written by Hans-Peter Nilsson <hp@axis.se>, c:a 1992. 4 5 Copyright (C) 1998-2013 Free Software Foundation, Inc. 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it 10 under the terms of the GNU General Public License as published by the 11 Free Software Foundation; either version 3, or (at your option) any 12 later version. 13 14 This file is distributed in the hope that it will be useful, but 15 WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 General Public License for more details. 18 19 Under Section 7 of GPL version 3, you are granted additional 20 permissions described in the GCC Runtime Library Exception, version 21 3.1, as published by the Free Software Foundation. 22 23 You should have received a copy of the GNU General Public License and 24 a copy of the GCC Runtime Library Exception along with this program; 25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 26 <http://www.gnu.org/licenses/>. */ 27 28 29 /* Note that we provide prototypes for all "const" functions, to attach 30 the const attribute. This is necessary in 2.7.2 - adding the 31 attribute to the function *definition* is a syntax error. 32 This did not work with e.g. 2.1; back then, the return type had to 33 be "const". */ 34 35 #include "config.h" 36 37 #if defined (__CRIS_arch_version) && __CRIS_arch_version >= 3 38 #define LZ(v) __builtin_clz (v) 39 #endif 40 41 42 #if defined (L_udivsi3) || defined (L_divsi3) || defined (L_umodsi3) \ 43 || defined (L_modsi3) 44 /* Result type of divmod worker function. */ 45 struct quot_rem 46 { 47 long quot; 48 long rem; 49 }; 50 51 /* This is the worker function for div and mod. It is inlined into the 52 respective library function. Parameter A must have bit 31 == 0. */ 53 54 static __inline__ struct quot_rem 55 do_31div (unsigned long a, unsigned long b) 56 __attribute__ ((__const__, __always_inline__)); 57 58 static __inline__ struct quot_rem 59 do_31div (unsigned long a, unsigned long b) 60 { 61 /* Adjust operands and result if a is 31 bits. */ 62 long extra = 0; 63 int quot_digits = 0; 64 65 if (b == 0) 66 { 67 struct quot_rem ret; 68 ret.quot = 0xffffffff; 69 ret.rem = 0xffffffff; 70 return ret; 71 } 72 73 if (a < b) 74 return (struct quot_rem) { 0, a }; 75 76 #ifdef LZ 77 if (b <= a) 78 { 79 quot_digits = LZ (b) - LZ (a); 80 quot_digits += (a >= (b << quot_digits)); 81 b <<= quot_digits; 82 } 83 #else 84 while (b <= a) 85 { 86 b <<= 1; 87 quot_digits++; 88 } 89 #endif 90 91 /* Is a 31 bits? Note that bit 31 is handled by the caller. */ 92 if (a & 0x40000000) 93 { 94 /* Then make b:s highest bit max 0x40000000, because it must have 95 been 0x80000000 to be 1 bit higher than a. */ 96 b >>= 1; 97 98 /* Adjust a to be maximum 0x3fffffff, i.e. two upper bits zero. */ 99 if (a >= b) 100 { 101 a -= b; 102 extra = 1 << (quot_digits - 1); 103 } 104 else 105 { 106 a -= b >> 1; 107 108 /* Remember that we adjusted a by subtracting b * 2 ** Something. */ 109 extra = 1 << quot_digits; 110 } 111 112 /* The number of quotient digits will be one less, because 113 we just adjusted b. */ 114 quot_digits--; 115 } 116 117 /* Now do the division part. */ 118 119 /* Subtract b and add ones to the right when a >= b 120 i.e. "a - (b - 1) == (a - b) + 1". */ 121 b--; 122 123 #define DS __asm__ ("dstep %2,%0" : "=r" (a) : "0" (a), "r" (b)) 124 125 switch (quot_digits) 126 { 127 case 32: DS; case 31: DS; case 30: DS; case 29: DS; 128 case 28: DS; case 27: DS; case 26: DS; case 25: DS; 129 case 24: DS; case 23: DS; case 22: DS; case 21: DS; 130 case 20: DS; case 19: DS; case 18: DS; case 17: DS; 131 case 16: DS; case 15: DS; case 14: DS; case 13: DS; 132 case 12: DS; case 11: DS; case 10: DS; case 9: DS; 133 case 8: DS; case 7: DS; case 6: DS; case 5: DS; 134 case 4: DS; case 3: DS; case 2: DS; case 1: DS; 135 case 0:; 136 } 137 138 { 139 struct quot_rem ret; 140 ret.quot = (a & ((1 << quot_digits) - 1)) + extra; 141 ret.rem = a >> quot_digits; 142 return ret; 143 } 144 } 145 146 #ifdef L_udivsi3 147 unsigned long 148 __Udiv (unsigned long a, unsigned long b) __attribute__ ((__const__)); 149 150 unsigned long 151 __Udiv (unsigned long a, unsigned long b) 152 { 153 long extra = 0; 154 155 /* Adjust operands and result, if a and/or b is 32 bits. */ 156 /* Effectively: b & 0x80000000. */ 157 if ((long) b < 0) 158 return a >= b; 159 160 /* Effectively: a & 0x80000000. */ 161 if ((long) a < 0) 162 { 163 int tmp = 0; 164 165 if (b == 0) 166 return 0xffffffff; 167 #ifdef LZ 168 tmp = LZ (b); 169 #else 170 for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) 171 ; 172 173 tmp = 31 - tmp; 174 #endif 175 176 if ((b << tmp) > a) 177 { 178 extra = 1 << (tmp-1); 179 a -= b << (tmp - 1); 180 } 181 else 182 { 183 extra = 1 << tmp; 184 a -= b << tmp; 185 } 186 } 187 188 return do_31div (a, b).quot+extra; 189 } 190 #endif /* L_udivsi3 */ 191 192 #ifdef L_divsi3 193 long 194 __Div (long a, long b) __attribute__ ((__const__)); 195 196 long 197 __Div (long a, long b) 198 { 199 long extra = 0; 200 long sign = (b < 0) ? -1 : 1; 201 202 /* We need to handle a == -2147483648 as expected and must while 203 doing that avoid producing a sequence like "abs (a) < 0" as GCC 204 may optimize out the test. That sequence may not be obvious as 205 we call inline functions. Testing for a being negative and 206 handling (presumably much rarer than positive) enables us to get 207 a bit of optimization for an (accumulated) reduction of the 208 penalty of the 0x80000000 special-case. */ 209 if (a < 0) 210 { 211 sign = -sign; 212 213 if ((a & 0x7fffffff) == 0) 214 { 215 /* We're at 0x80000000. Tread carefully. */ 216 a -= b * sign; 217 extra = sign; 218 } 219 a = -a; 220 } 221 222 /* We knowingly penalize pre-v10 models by multiplication with the 223 sign. */ 224 return sign * do_31div (a, __builtin_labs (b)).quot + extra; 225 } 226 #endif /* L_divsi3 */ 227 228 229 #ifdef L_umodsi3 230 unsigned long 231 __Umod (unsigned long a, unsigned long b) __attribute__ ((__const__)); 232 233 unsigned long 234 __Umod (unsigned long a, unsigned long b) 235 { 236 /* Adjust operands and result if a and/or b is 32 bits. */ 237 if ((long) b < 0) 238 return a >= b ? a - b : a; 239 240 if ((long) a < 0) 241 { 242 int tmp = 0; 243 244 if (b == 0) 245 return a; 246 #ifdef LZ 247 tmp = LZ (b); 248 #else 249 for (tmp = 31; (((long) b & (1 << tmp)) == 0); tmp--) 250 ; 251 tmp = 31 - tmp; 252 #endif 253 254 if ((b << tmp) > a) 255 { 256 a -= b << (tmp - 1); 257 } 258 else 259 { 260 a -= b << tmp; 261 } 262 } 263 264 return do_31div (a, b).rem; 265 } 266 #endif /* L_umodsi3 */ 267 268 #ifdef L_modsi3 269 long 270 __Mod (long a, long b) __attribute__ ((__const__)); 271 272 long 273 __Mod (long a, long b) 274 { 275 long sign = 1; 276 277 /* We need to handle a == -2147483648 as expected and must while 278 doing that avoid producing a sequence like "abs (a) < 0" as GCC 279 may optimize out the test. That sequence may not be obvious as 280 we call inline functions. Testing for a being negative and 281 handling (presumably much rarer than positive) enables us to get 282 a bit of optimization for an (accumulated) reduction of the 283 penalty of the 0x80000000 special-case. */ 284 if (a < 0) 285 { 286 sign = -1; 287 if ((a & 0x7fffffff) == 0) 288 /* We're at 0x80000000. Tread carefully. */ 289 a += __builtin_labs (b); 290 a = -a; 291 } 292 293 return sign * do_31div (a, __builtin_labs (b)).rem; 294 } 295 #endif /* L_modsi3 */ 296 #endif /* L_udivsi3 || L_divsi3 || L_umodsi3 || L_modsi3 */ 297 298 /* 299 * Local variables: 300 * eval: (c-set-style "gnu") 301 * indent-tabs-mode: t 302 * End: 303 */ 304