1/* 2 * sdiv.S: This routine was taken from glibc-1.09 and is covered 3 * by the GNU Library General Public License Version 2. 4 */ 5 6 7/* This file is generated from divrem.m4; DO NOT EDIT! */ 8/* 9 * Division and remainder, from Appendix E of the Sparc Version 8 10 * Architecture Manual, with fixes from Gordon Irlam. 11 */ 12 13/* 14 * Input: dividend and divisor in %o0 and %o1 respectively. 15 * 16 * m4 parameters: 17 * .div name of function to generate 18 * div div=div => %o0 / %o1; div=rem => %o0 % %o1 19 * true true=true => signed; true=false => unsigned 20 * 21 * Algorithm parameters: 22 * N how many bits per iteration we try to get (4) 23 * WORDSIZE total number of bits (32) 24 * 25 * Derived constants: 26 * TOPBITS number of bits in the top decade of a number 27 * 28 * Important variables: 29 * Q the partial quotient under development (initially 0) 30 * R the remainder so far, initially the dividend 31 * ITER number of main division loop iterations required; 32 * equal to ceil(log2(quotient) / N). Note that this 33 * is the log base (2^N) of the quotient. 34 * V the current comparand, initially divisor*2^(ITER*N-1) 35 * 36 * Cost: 37 * Current estimate for non-large dividend is 38 * ceil(log2(quotient) / N) * (10 + 7N/2) + C 39 * A large dividend is one greater than 2^(31-TOPBITS) and takes a 40 * different path, as the upper bits of the quotient must be developed 41 * one bit at a time. 42 */ 43 44 45 .globl .div 46 .globl _Div 47.div: 48_Div: /* needed for export */ 49 ! compute sign of result; if neither is negative, no problem 50 orcc %o1, %o0, %g0 ! either negative? 51 bge 2f ! no, go do the divide 52 xor %o1, %o0, %g2 ! compute sign in any case 53 54 tst %o1 55 bge 1f 56 tst %o0 57 ! %o1 is definitely negative; %o0 might also be negative 58 bge 2f ! if %o0 not negative... 59 sub %g0, %o1, %o1 ! in any case, make %o1 nonneg 601: ! %o0 is negative, %o1 is nonnegative 61 sub %g0, %o0, %o0 ! make %o0 nonnegative 622: 63 64 ! Ready to divide. Compute size of quotient; scale comparand. 65 orcc %o1, %g0, %o5 66 bne 1f 67 mov %o0, %o3 68 69 ! Divide by zero trap. If it returns, return 0 (about as 70 ! wrong as possible, but that is what SunOS does...). 71 ta ST_DIV0 72 retl 73 clr %o0 74 751: 76 cmp %o3, %o5 ! if %o1 exceeds %o0, done 77 blu Lgot_result ! (and algorithm fails otherwise) 78 clr %o2 79 80 sethi %hi(1 << (32 - 4 - 1)), %g1 81 82 cmp %o3, %g1 83 blu Lnot_really_big 84 clr %o4 85 86 ! Here the dividend is >= 2**(31-N) or so. We must be careful here, 87 ! as our usual N-at-a-shot divide step will cause overflow and havoc. 88 ! The number of bits in the result here is N*ITER+SC, where SC <= N. 89 ! Compute ITER in an unorthodox manner: know we need to shift V into 90 ! the top decade: so do not even bother to compare to R. 91 1: 92 cmp %o5, %g1 93 bgeu 3f 94 mov 1, %g7 95 96 sll %o5, 4, %o5 97 98 b 1b 99 add %o4, 1, %o4 100 101 ! Now compute %g7. 102 2: 103 addcc %o5, %o5, %o5 104 bcc Lnot_too_big 105 add %g7, 1, %g7 106 107 ! We get here if the %o1 overflowed while shifting. 108 ! This means that %o3 has the high-order bit set. 109 ! Restore %o5 and subtract from %o3. 110 sll %g1, 4, %g1 ! high order bit 111 srl %o5, 1, %o5 ! rest of %o5 112 add %o5, %g1, %o5 113 114 b Ldo_single_div 115 sub %g7, 1, %g7 116 117 Lnot_too_big: 118 3: 119 cmp %o5, %o3 120 blu 2b 121 nop 122 123 be Ldo_single_div 124 nop 125 /* NB: these are commented out in the V8-Sparc manual as well */ 126 /* (I do not understand this) */ 127 ! %o5 > %o3: went too far: back up 1 step 128 ! srl %o5, 1, %o5 129 ! dec %g7 130 ! do single-bit divide steps 131 ! 132 ! We have to be careful here. We know that %o3 >= %o5, so we can do the 133 ! first divide step without thinking. BUT, the others are conditional, 134 ! and are only done if %o3 >= 0. Because both %o3 and %o5 may have the high- 135 ! order bit set in the first step, just falling into the regular 136 ! division loop will mess up the first time around. 137 ! So we unroll slightly... 138 Ldo_single_div: 139 subcc %g7, 1, %g7 140 bl Lend_regular_divide 141 nop 142 143 sub %o3, %o5, %o3 144 mov 1, %o2 145 146 b Lend_single_divloop 147 nop 148 Lsingle_divloop: 149 sll %o2, 1, %o2 150 151 bl 1f 152 srl %o5, 1, %o5 153 ! %o3 >= 0 154 sub %o3, %o5, %o3 155 156 b 2f 157 add %o2, 1, %o2 158 1: ! %o3 < 0 159 add %o3, %o5, %o3 160 sub %o2, 1, %o2 161 2: 162 Lend_single_divloop: 163 subcc %g7, 1, %g7 164 bge Lsingle_divloop 165 tst %o3 166 167 b,a Lend_regular_divide 168 169Lnot_really_big: 1701: 171 sll %o5, 4, %o5 172 cmp %o5, %o3 173 bleu 1b 174 addcc %o4, 1, %o4 175 176 be Lgot_result 177 sub %o4, 1, %o4 178 179 tst %o3 ! set up for initial iteration 180Ldivloop: 181 sll %o2, 4, %o2 182 ! depth 1, accumulated bits 0 183 bl L.1.16 184 srl %o5,1,%o5 185 ! remainder is positive 186 subcc %o3,%o5,%o3 187 ! depth 2, accumulated bits 1 188 bl L.2.17 189 srl %o5,1,%o5 190 ! remainder is positive 191 subcc %o3,%o5,%o3 192 ! depth 3, accumulated bits 3 193 bl L.3.19 194 srl %o5,1,%o5 195 ! remainder is positive 196 subcc %o3,%o5,%o3 197 ! depth 4, accumulated bits 7 198 bl L.4.23 199 srl %o5,1,%o5 200 ! remainder is positive 201 subcc %o3,%o5,%o3 202 b 9f 203 add %o2, (7*2+1), %o2 204 205L.4.23: 206 ! remainder is negative 207 addcc %o3,%o5,%o3 208 b 9f 209 add %o2, (7*2-1), %o2 210 211L.3.19: 212 ! remainder is negative 213 addcc %o3,%o5,%o3 214 ! depth 4, accumulated bits 5 215 bl L.4.21 216 srl %o5,1,%o5 217 ! remainder is positive 218 subcc %o3,%o5,%o3 219 b 9f 220 add %o2, (5*2+1), %o2 221 222L.4.21: 223 ! remainder is negative 224 addcc %o3,%o5,%o3 225 b 9f 226 add %o2, (5*2-1), %o2 227 228L.2.17: 229 ! remainder is negative 230 addcc %o3,%o5,%o3 231 ! depth 3, accumulated bits 1 232 bl L.3.17 233 srl %o5,1,%o5 234 ! remainder is positive 235 subcc %o3,%o5,%o3 236 ! depth 4, accumulated bits 3 237 bl L.4.19 238 srl %o5,1,%o5 239 ! remainder is positive 240 subcc %o3,%o5,%o3 241 b 9f 242 add %o2, (3*2+1), %o2 243 244L.4.19: 245 ! remainder is negative 246 addcc %o3,%o5,%o3 247 b 9f 248 add %o2, (3*2-1), %o2 249 250 251L.3.17: 252 ! remainder is negative 253 addcc %o3,%o5,%o3 254 ! depth 4, accumulated bits 1 255 bl L.4.17 256 srl %o5,1,%o5 257 ! remainder is positive 258 subcc %o3,%o5,%o3 259 b 9f 260 add %o2, (1*2+1), %o2 261 262L.4.17: 263 ! remainder is negative 264 addcc %o3,%o5,%o3 265 b 9f 266 add %o2, (1*2-1), %o2 267 268L.1.16: 269 ! remainder is negative 270 addcc %o3,%o5,%o3 271 ! depth 2, accumulated bits -1 272 bl L.2.15 273 srl %o5,1,%o5 274 ! remainder is positive 275 subcc %o3,%o5,%o3 276 ! depth 3, accumulated bits -1 277 bl L.3.15 278 srl %o5,1,%o5 279 ! remainder is positive 280 subcc %o3,%o5,%o3 281 ! depth 4, accumulated bits -1 282 bl L.4.15 283 srl %o5,1,%o5 284 ! remainder is positive 285 subcc %o3,%o5,%o3 286 b 9f 287 add %o2, (-1*2+1), %o2 288 289L.4.15: 290 ! remainder is negative 291 addcc %o3,%o5,%o3 292 b 9f 293 add %o2, (-1*2-1), %o2 294 295L.3.15: 296 ! remainder is negative 297 addcc %o3,%o5,%o3 298 ! depth 4, accumulated bits -3 299 bl L.4.13 300 srl %o5,1,%o5 301 ! remainder is positive 302 subcc %o3,%o5,%o3 303 b 9f 304 add %o2, (-3*2+1), %o2 305 306L.4.13: 307 ! remainder is negative 308 addcc %o3,%o5,%o3 309 b 9f 310 add %o2, (-3*2-1), %o2 311 312L.2.15: 313 ! remainder is negative 314 addcc %o3,%o5,%o3 315 ! depth 3, accumulated bits -3 316 bl L.3.13 317 srl %o5,1,%o5 318 ! remainder is positive 319 subcc %o3,%o5,%o3 320 ! depth 4, accumulated bits -5 321 bl L.4.11 322 srl %o5,1,%o5 323 ! remainder is positive 324 subcc %o3,%o5,%o3 325 b 9f 326 add %o2, (-5*2+1), %o2 327 328L.4.11: 329 ! remainder is negative 330 addcc %o3,%o5,%o3 331 b 9f 332 add %o2, (-5*2-1), %o2 333 334L.3.13: 335 ! remainder is negative 336 addcc %o3,%o5,%o3 337 ! depth 4, accumulated bits -7 338 bl L.4.9 339 srl %o5,1,%o5 340 ! remainder is positive 341 subcc %o3,%o5,%o3 342 b 9f 343 add %o2, (-7*2+1), %o2 344 345L.4.9: 346 ! remainder is negative 347 addcc %o3,%o5,%o3 348 b 9f 349 add %o2, (-7*2-1), %o2 350 351 9: 352Lend_regular_divide: 353 subcc %o4, 1, %o4 354 bge Ldivloop 355 tst %o3 356 357 bl,a Lgot_result 358 ! non-restoring fixup here (one instruction only!) 359 sub %o2, 1, %o2 360 361Lgot_result: 362 ! check to see if answer should be < 0 363 tst %g2 364 bl,a 1f 365 sub %g0, %o2, %o2 3661: 367 retl 368 mov %o2, %o0 369 370 .globl .div_patch 371.div_patch: 372 sra %o0, 0x1f, %o2 373 wr %o2, 0x0, %y 374 nop 375 nop 376 nop 377 sdivcc %o0, %o1, %o0 378 bvs,a 1f 379 xnor %o0, %g0, %o0 3801: retl 381 nop 382