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