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