|
|
1.1 ! root 1: @ libgcc1 routines for ARM cpu. ! 2: @ Division and remainder, from Appendix E of the Sparc Version 8 ! 3: @ Architecture Manual, with fixes from Gordon Irlam. ! 4: @ Rewritten for the ARM by Richard Earnshaw ([email protected]) ! 5: ! 6: /* Copyright (C) 1995 Free Software Foundation, Inc. ! 7: ! 8: This file is free software; you can redistribute it and/or modify it ! 9: under the terms of the GNU General Public License as published by the ! 10: Free Software Foundation; either version 2, or (at your option) any ! 11: later version. ! 12: ! 13: In addition to the permissions in the GNU General Public License, the ! 14: Free Software Foundation gives you unlimited permission to link the ! 15: compiled version of this file with other programs, and to distribute ! 16: those programs without any restriction coming from the use of this ! 17: file. (The General Public License restrictions do apply in other ! 18: respects; for example, they cover modification of the file, and ! 19: distribution when not linked into another program.) ! 20: ! 21: This file is distributed in the hope that it will be useful, but ! 22: WITHOUT ANY WARRANTY; without even the implied warranty of ! 23: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 24: General Public License for more details. ! 25: ! 26: You should have received a copy of the GNU General Public License ! 27: along with this program; see the file COPYING. If not, write to ! 28: the Free Software Foundation, 59 Temple Place - Suite 330, ! 29: Boston, MA 02111-1307, USA. */ ! 30: ! 31: /* As a special exception, if you link this library with other files, ! 32: some of which are compiled with GCC, to produce an executable, ! 33: this library does not by itself cause the resulting executable ! 34: to be covered by the GNU General Public License. ! 35: This exception does not however invalidate any other reasons why ! 36: the executable file might be covered by the GNU General Public License. */ ! 37: ! 38: /* ! 39: * Input: dividend and divisor in r0 and r1 respectively. ! 40: * ! 41: * m4 parameters: ! 42: * NAME name of function to generate ! 43: * OP OP=div => r0 / r1; OP=mod => r0 % r1 ! 44: * S S=true => signed; S=false => unsigned ! 45: * ! 46: * Algorithm parameters: ! 47: * N how many bits per iteration we try to get (4) ! 48: * WORDSIZE total number of bits (32) ! 49: * ! 50: * Derived constants: ! 51: * TOPBITS number of bits in the top `decade' of a number ! 52: * ! 53: * Important variables: ! 54: * Q the partial quotient under development (initially 0) ! 55: * R the remainder so far, initially the dividend ! 56: * ITER number of main division loop iterations required; ! 57: * equal to ceil(log2(quotient) / N). Note that this ! 58: * is the log base (2^N) of the quotient. ! 59: * V the current comparand, initially divisor*2^(ITER*N-1) ! 60: * ! 61: * Cost: ! 62: * Current estimate for non-large dividend is ! 63: * ceil(log2(quotient) / N) * (10 + 7N/2) + C ! 64: * A large dividend is one greater than 2^(31-TOPBITS) and takes a ! 65: * different path, as the upper bits of the quotient must be developed ! 66: * one bit at a time. ! 67: */ ! 68: ! 69: /* ! 70: define(N, `4')dnl ! 71: define(WORDSIZE, `32')dnl ! 72: define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N)))dnl ! 73: dnl ! 74: define(dividend, `r0')dnl ! 75: define(divisor, `r1')dnl ! 76: define(Q, `r2')dnl ! 77: define(R, `r3')dnl ! 78: define(ITER, `ip')dnl ! 79: define(V, `lr')dnl ! 80: dnl ! 81: dnl m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d ! 82: define(T, `r4')dnl ! 83: define(SC, `r5')dnl ! 84: ifelse(S, `true', `define(SIGN, `r6')')dnl ! 85: define(REGLIST, `ifelse(S, `true', `{r4, r5, r6,', `{r4, r5,')')dnl ! 86: define(ret, `ldmia sp!, REGLIST pc}')dnl ! 87: dnl ! 88: dnl This is the recursive definition for developing quotient digits. ! 89: dnl ! 90: dnl Parameters: ! 91: dnl $1 the current depth, 1 <= $1 <= N ! 92: dnl $2 the current accumulation of quotient bits ! 93: dnl N max depth ! 94: dnl ! 95: dnl We add a new bit to $2 and either recurse or insert the bits in ! 96: dnl the quotient. R, Q, and V are inputs and outputs as defined above; ! 97: dnl the condition codes are expected to reflect the input R, and are ! 98: dnl modified to reflect the output R. ! 99: dnl ! 100: define(DEVELOP_QUOTIENT_BITS, ! 101: ` @ depth $1, accumulated bits $2 ! 102: mov V, V, lsr #1 ! 103: blt L.$1.eval(2^N+$2+999) ! 104: @ remainder is positive ! 105: subs R, R, V ! 106: ifelse($1, N, ! 107: ` ifelse(eval(2*$2+1<0), `0', ! 108: `add Q, Q, `#'eval($2*2+1)', ! 109: `sub Q, Q, `#'eval(-($2*2+1))') ! 110: ! 111: b 9f ! 112: ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') ! 113: L.$1.eval(2^N+$2+999): ! 114: @ remainder is negative ! 115: adds R, R, V ! 116: ifelse($1, N, ! 117: ` ifelse(eval(2*$2-1<0), `0', ! 118: `add Q, Q, `#'eval($2*2-1)', ! 119: `sub Q, Q, `#'eval(-($2*2-1))') ! 120: b 9f ! 121: ! 122: ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') ! 123: ifelse($1, 1, `9:')')dnl ! 124: ! 125: #include "trap.h" ! 126: ! 127: ip .req r12 ! 128: sp .req r13 ! 129: lr .req r14 ! 130: pc .req r15 ! 131: .text ! 132: .globl NAME ! 133: .align 0 ! 134: NAME: ! 135: stmdb sp!, REGLIST lr} ! 136: ifelse(S, `true', ! 137: ` @ compute sign of result; if neither is negative, no problem ! 138: ifelse(OP, `div', `eor SIGN, divisor, dividend @ compute sign', ! 139: `mov SIGN, dividend') ! 140: cmp divisor, #0 ! 141: rsbmi divisor, divisor, #0 ! 142: beq Ldiv_zero ! 143: mov V, divisor ! 144: movs R, dividend ! 145: rsbmi R, R, #0 @ make dividend nonnegative ! 146: ', ! 147: ` @ Ready to divide. Compute size of quotient; scale comparand. ! 148: movs V, divisor ! 149: mov R, dividend ! 150: beq Ldiv_zero ! 151: ') ! 152: ! 153: cmp R, V @ if divisor exceeds dividend, done ! 154: mov Q, #0 ! 155: bcc Lgot_result @ (and algorithm fails otherwise) ! 156: mov T, `#'(1 << (WORDSIZE - TOPBITS - 1)) ! 157: cmp R, T ! 158: mov ITER, #0 ! 159: bcc Lnot_really_big ! 160: ! 161: @ `Here the dividend is >= 2^(31-N) or so. We must be careful here, ! 162: @ as our usual N-at-a-shot divide step will cause overflow and havoc. ! 163: @ The number of bits in the result here is N*ITER+SC, where SC <= N. ! 164: @ Compute ITER in an unorthodox manner: know we need to shift V into ! 165: @ the top decade: so do not even bother to compare to R.' ! 166: mov SC, #1 ! 167: 1: ! 168: cmp V, T ! 169: bcs 3f ! 170: mov V, V, lsl `#'N ! 171: add ITER, ITER, #1 ! 172: b 1b ! 173: ! 174: @ Now compute SC. ! 175: 2: adds V, V, V ! 176: add SC, SC, #1 ! 177: bcc Lnot_too_big ! 178: ! 179: @ We get here if the divisor overflowed while shifting. ! 180: @ This means that R has the high-order bit set. ! 181: @ Restore V and subtract from R. ! 182: mov T, T, lsl `#'TOPBITS ! 183: mov V, V, lsr #1 ! 184: add V, T, V ! 185: sub SC, SC, #1 ! 186: b Ldo_single_div ! 187: ! 188: Lnot_too_big: ! 189: 3: cmp V, R ! 190: bcc 2b ! 191: @ beq Ldo_single_div ! 192: ! 193: /-* NB: these are commented out in the V8-Sparc manual as well *-/ ! 194: /-* (I do not understand this) *-/ ! 195: @ V > R: went too far: back up 1 step ! 196: @ srl V, 1, V ! 197: @ dec SC ! 198: @ do single-bit divide steps ! 199: @ ! 200: @ We have to be careful here. We know that R >= V, so we can do the ! 201: @ first divide step without thinking. BUT, the others are conditional, ! 202: @ and are only done if R >= 0. Because both R and V may have the high- ! 203: @ order bit set in the first step, just falling into the regular ! 204: @ division loop will mess up the first time around. ! 205: @ So we unroll slightly... ! 206: Ldo_single_div: ! 207: subs SC, SC, #1 ! 208: blt Lend_regular_divide ! 209: sub R, R, V ! 210: mov Q, #1 ! 211: b Lend_single_divloop ! 212: Lsingle_divloop: ! 213: cmp R, #0 ! 214: mov Q, Q, lsl #1 ! 215: mov V, V, lsr #1 ! 216: @ R >= 0 ! 217: subpl R, R, V ! 218: addpl Q, Q, #1 ! 219: @ R < 0 ! 220: addmi R, R, V ! 221: submi Q, Q, #1 ! 222: Lend_single_divloop: ! 223: subs SC, SC, #1 ! 224: bge Lsingle_divloop ! 225: b Lend_regular_divide ! 226: ! 227: 1: ! 228: add ITER, ITER, #1 ! 229: Lnot_really_big: ! 230: mov V, V, lsl `#'N ! 231: cmp V, R ! 232: bls 1b ! 233: @ ! 234: @ HOW CAN ITER EVER BE -1 HERE ????? ! 235: @ ! 236: cmn ITER, #1 ! 237: beq Lgot_result ! 238: ! 239: Ldivloop: ! 240: cmp R, #0 @ set up for initial iteration ! 241: mov Q, Q, lsl `#'N ! 242: DEVELOP_QUOTIENT_BITS(1, 0) ! 243: Lend_regular_divide: ! 244: subs ITER, ITER, #1 ! 245: bge Ldivloop ! 246: cmp R, #0 ! 247: @ non-restoring fixup here (one instruction only!) ! 248: ifelse(OP, `div', ! 249: ` sublt Q, Q, #1 ! 250: ', ` addlt R, divisor, R ! 251: ') ! 252: ! 253: Lgot_result: ! 254: ifelse(S, `true', ! 255: ` @ check to see if answer should be < 0 ! 256: cmp SIGN, #0 ! 257: ifelse(OP, `div', `rsbmi Q, Q, #0', `rsbmi R, R, #0') ! 258: ') ! 259: ifelse(OP, `div', `mov r0, Q', `mov r0, R') ! 260: ret ! 261: ! 262: Ldiv_zero: ! 263: @ Divide by zero trap. If it returns, return 0 (about as ! 264: @ wrong as possible, but that is what SunOS does...). ! 265: bl ___div0 ! 266: mov r0, #0 ! 267: ret ! 268: */ ! 269: ! 270: #ifdef L_udivsi3 ! 271: ! 272: ip .req r12 ! 273: sp .req r13 ! 274: lr .req r14 ! 275: pc .req r15 ! 276: .text ! 277: .globl ___udivsi3 ! 278: .align 0 ! 279: ___udivsi3: ! 280: stmdb sp!, {r4, r5, lr} ! 281: @ Ready to divide. Compute size of quotient; scale comparand. ! 282: movs lr, r1 ! 283: mov r3, r0 ! 284: beq Ldiv_zero ! 285: ! 286: ! 287: cmp r3, lr @ if r1 exceeds r0, done ! 288: mov r2, #0 ! 289: bcc Lgot_result @ (and algorithm fails otherwise) ! 290: mov r4, #(1 << (32 - 4 - 1)) ! 291: cmp r3, r4 ! 292: mov ip, #0 ! 293: bcc Lnot_really_big ! 294: ! 295: @ Here the dividend is >= 2^(31-N) or so. We must be careful here, ! 296: @ as our usual N-at-a-shot divide step will cause overflow and havoc. ! 297: @ The number of bits in the result here is N*ITER+SC, where SC <= N. ! 298: @ Compute ITER in an unorthodox manner: know we need to shift V into ! 299: @ the top decade: so do not even bother to compare to R. ! 300: mov r5, #1 ! 301: 1: ! 302: cmp lr, r4 ! 303: bcs 3f ! 304: mov lr, lr, lsl #4 ! 305: add ip, ip, #1 ! 306: b 1b ! 307: ! 308: @ Now compute r5. ! 309: 2: adds lr, lr, lr ! 310: add r5, r5, #1 ! 311: bcc Lnot_too_big ! 312: ! 313: @ We get here if the r1 overflowed while shifting. ! 314: @ This means that r3 has the high-order bit set. ! 315: @ Restore lr and subtract from r3. ! 316: mov r4, r4, lsl #4 ! 317: mov lr, lr, lsr #1 ! 318: add lr, r4, lr ! 319: sub r5, r5, #1 ! 320: b Ldo_single_div ! 321: ! 322: Lnot_too_big: ! 323: 3: cmp lr, r3 ! 324: bcc 2b ! 325: @ beq Ldo_single_div ! 326: ! 327: /* NB: these are commented out in the V8-Sparc manual as well */ ! 328: /* (I do not understand this) */ ! 329: @ lr > r3: went too far: back up 1 step ! 330: @ srl lr, 1, lr ! 331: @ dec r5 ! 332: @ do single-bit divide steps ! 333: @ ! 334: @ We have to be careful here. We know that r3 >= lr, so we can do the ! 335: @ first divide step without thinking. BUT, the others are conditional, ! 336: @ and are only done if r3 >= 0. Because both r3 and lr may have the high- ! 337: @ order bit set in the first step, just falling into the regular ! 338: @ division loop will mess up the first time around. ! 339: @ So we unroll slightly... ! 340: Ldo_single_div: ! 341: subs r5, r5, #1 ! 342: blt Lend_regular_divide ! 343: sub r3, r3, lr ! 344: mov r2, #1 ! 345: b Lend_single_divloop ! 346: Lsingle_divloop: ! 347: cmp r3, #0 ! 348: mov r2, r2, lsl #1 ! 349: mov lr, lr, lsr #1 ! 350: @ r3 >= 0 ! 351: subpl r3, r3, lr ! 352: addpl r2, r2, #1 ! 353: @ r3 < 0 ! 354: addmi r3, r3, lr ! 355: submi r2, r2, #1 ! 356: Lend_single_divloop: ! 357: subs r5, r5, #1 ! 358: bge Lsingle_divloop ! 359: b Lend_regular_divide ! 360: ! 361: 1: ! 362: add ip, ip, #1 ! 363: Lnot_really_big: ! 364: mov lr, lr, lsl #4 ! 365: cmp lr, r3 ! 366: bls 1b ! 367: @ ! 368: @ HOW CAN ip EVER BE -1 HERE ????? ! 369: @ ! 370: cmn ip, #1 ! 371: beq Lgot_result ! 372: ! 373: Ldivloop: ! 374: cmp r3, #0 @ set up for initial iteration ! 375: mov r2, r2, lsl #4 ! 376: @ depth 1, accumulated bits 0 ! 377: mov lr, lr, lsr #1 ! 378: blt L.1.1015 ! 379: @ remainder is positive ! 380: subs r3, r3, lr ! 381: @ depth 2, accumulated bits 1 ! 382: mov lr, lr, lsr #1 ! 383: blt L.2.1016 ! 384: @ remainder is positive ! 385: subs r3, r3, lr ! 386: @ depth 3, accumulated bits 3 ! 387: mov lr, lr, lsr #1 ! 388: blt L.3.1018 ! 389: @ remainder is positive ! 390: subs r3, r3, lr ! 391: @ depth 4, accumulated bits 7 ! 392: mov lr, lr, lsr #1 ! 393: blt L.4.1022 ! 394: @ remainder is positive ! 395: subs r3, r3, lr ! 396: add r2, r2, #15 ! 397: ! 398: b 9f ! 399: ! 400: L.4.1022: ! 401: @ remainder is negative ! 402: adds r3, r3, lr ! 403: add r2, r2, #13 ! 404: b 9f ! 405: ! 406: ! 407: ! 408: L.3.1018: ! 409: @ remainder is negative ! 410: adds r3, r3, lr ! 411: @ depth 4, accumulated bits 5 ! 412: mov lr, lr, lsr #1 ! 413: blt L.4.1020 ! 414: @ remainder is positive ! 415: subs r3, r3, lr ! 416: add r2, r2, #11 ! 417: ! 418: b 9f ! 419: ! 420: L.4.1020: ! 421: @ remainder is negative ! 422: adds r3, r3, lr ! 423: add r2, r2, #9 ! 424: b 9f ! 425: ! 426: ! 427: ! 428: ! 429: L.2.1016: ! 430: @ remainder is negative ! 431: adds r3, r3, lr ! 432: @ depth 3, accumulated bits 1 ! 433: mov lr, lr, lsr #1 ! 434: blt L.3.1016 ! 435: @ remainder is positive ! 436: subs r3, r3, lr ! 437: @ depth 4, accumulated bits 3 ! 438: mov lr, lr, lsr #1 ! 439: blt L.4.1018 ! 440: @ remainder is positive ! 441: subs r3, r3, lr ! 442: add r2, r2, #7 ! 443: ! 444: b 9f ! 445: ! 446: L.4.1018: ! 447: @ remainder is negative ! 448: adds r3, r3, lr ! 449: add r2, r2, #5 ! 450: b 9f ! 451: ! 452: ! 453: ! 454: L.3.1016: ! 455: @ remainder is negative ! 456: adds r3, r3, lr ! 457: @ depth 4, accumulated bits 1 ! 458: mov lr, lr, lsr #1 ! 459: blt L.4.1016 ! 460: @ remainder is positive ! 461: subs r3, r3, lr ! 462: add r2, r2, #3 ! 463: ! 464: b 9f ! 465: ! 466: L.4.1016: ! 467: @ remainder is negative ! 468: adds r3, r3, lr ! 469: add r2, r2, #1 ! 470: b 9f ! 471: ! 472: ! 473: ! 474: ! 475: ! 476: L.1.1015: ! 477: @ remainder is negative ! 478: adds r3, r3, lr ! 479: @ depth 2, accumulated bits -1 ! 480: mov lr, lr, lsr #1 ! 481: blt L.2.1014 ! 482: @ remainder is positive ! 483: subs r3, r3, lr ! 484: @ depth 3, accumulated bits -1 ! 485: mov lr, lr, lsr #1 ! 486: blt L.3.1014 ! 487: @ remainder is positive ! 488: subs r3, r3, lr ! 489: @ depth 4, accumulated bits -1 ! 490: mov lr, lr, lsr #1 ! 491: blt L.4.1014 ! 492: @ remainder is positive ! 493: subs r3, r3, lr ! 494: sub r2, r2, #1 ! 495: ! 496: b 9f ! 497: ! 498: L.4.1014: ! 499: @ remainder is negative ! 500: adds r3, r3, lr ! 501: sub r2, r2, #3 ! 502: b 9f ! 503: ! 504: ! 505: ! 506: L.3.1014: ! 507: @ remainder is negative ! 508: adds r3, r3, lr ! 509: @ depth 4, accumulated bits -3 ! 510: mov lr, lr, lsr #1 ! 511: blt L.4.1012 ! 512: @ remainder is positive ! 513: subs r3, r3, lr ! 514: sub r2, r2, #5 ! 515: ! 516: b 9f ! 517: ! 518: L.4.1012: ! 519: @ remainder is negative ! 520: adds r3, r3, lr ! 521: sub r2, r2, #7 ! 522: b 9f ! 523: ! 524: ! 525: ! 526: ! 527: L.2.1014: ! 528: @ remainder is negative ! 529: adds r3, r3, lr ! 530: @ depth 3, accumulated bits -3 ! 531: mov lr, lr, lsr #1 ! 532: blt L.3.1012 ! 533: @ remainder is positive ! 534: subs r3, r3, lr ! 535: @ depth 4, accumulated bits -5 ! 536: mov lr, lr, lsr #1 ! 537: blt L.4.1010 ! 538: @ remainder is positive ! 539: subs r3, r3, lr ! 540: sub r2, r2, #9 ! 541: ! 542: b 9f ! 543: ! 544: L.4.1010: ! 545: @ remainder is negative ! 546: adds r3, r3, lr ! 547: sub r2, r2, #11 ! 548: b 9f ! 549: ! 550: ! 551: ! 552: L.3.1012: ! 553: @ remainder is negative ! 554: adds r3, r3, lr ! 555: @ depth 4, accumulated bits -7 ! 556: mov lr, lr, lsr #1 ! 557: blt L.4.1008 ! 558: @ remainder is positive ! 559: subs r3, r3, lr ! 560: sub r2, r2, #13 ! 561: ! 562: b 9f ! 563: ! 564: L.4.1008: ! 565: @ remainder is negative ! 566: adds r3, r3, lr ! 567: sub r2, r2, #15 ! 568: b 9f ! 569: ! 570: ! 571: ! 572: ! 573: ! 574: 9: ! 575: Lend_regular_divide: ! 576: subs ip, ip, #1 ! 577: bge Ldivloop ! 578: cmp r3, #0 ! 579: @ non-restoring fixup here (one instruction only!) ! 580: sublt r2, r2, #1 ! 581: ! 582: ! 583: Lgot_result: ! 584: ! 585: mov r0, r2 ! 586: ldmia sp!, {r4, r5, pc} ! 587: ! 588: Ldiv_zero: ! 589: @ Divide by zero trap. If it returns, return 0 (about as ! 590: @ wrong as possible, but that is what SunOS does...). ! 591: bl ___div0 ! 592: mov r0, #0 ! 593: ldmia sp!, {r4, r5, pc} ! 594: ! 595: #endif /* L_udivsi3 */ ! 596: ! 597: #ifdef L_divsi3 ! 598: ! 599: ip .req r12 ! 600: sp .req r13 ! 601: lr .req r14 ! 602: pc .req r15 ! 603: .text ! 604: .globl ___divsi3 ! 605: .align 0 ! 606: ___divsi3: ! 607: stmdb sp!, {r4, r5, r6, lr} ! 608: @ compute sign of result; if neither is negative, no problem ! 609: eor r6, r1, r0 @ compute sign ! 610: cmp r1, #0 ! 611: rsbmi r1, r1, #0 ! 612: beq Ldiv_zero ! 613: mov lr, r1 ! 614: movs r3, r0 ! 615: rsbmi r3, r3, #0 @ make dividend nonnegative ! 616: ! 617: ! 618: cmp r3, lr @ if r1 exceeds r0, done ! 619: mov r2, #0 ! 620: bcc Lgot_result @ (and algorithm fails otherwise) ! 621: mov r4, #(1 << (32 - 4 - 1)) ! 622: cmp r3, r4 ! 623: mov ip, #0 ! 624: bcc Lnot_really_big ! 625: ! 626: @ Here the dividend is >= 2^(31-N) or so. We must be careful here, ! 627: @ as our usual N-at-a-shot divide step will cause overflow and havoc. ! 628: @ The number of bits in the result here is N*ITER+SC, where SC <= N. ! 629: @ Compute ITER in an unorthodox manner: know we need to shift V into ! 630: @ the top decade: so do not even bother to compare to R. ! 631: mov r5, #1 ! 632: 1: ! 633: cmp lr, r4 ! 634: bcs 3f ! 635: mov lr, lr, lsl #4 ! 636: add ip, ip, #1 ! 637: b 1b ! 638: ! 639: @ Now compute r5. ! 640: 2: adds lr, lr, lr ! 641: add r5, r5, #1 ! 642: bcc Lnot_too_big ! 643: ! 644: @ We get here if the r1 overflowed while shifting. ! 645: @ This means that r3 has the high-order bit set. ! 646: @ Restore lr and subtract from r3. ! 647: mov r4, r4, lsl #4 ! 648: mov lr, lr, lsr #1 ! 649: add lr, r4, lr ! 650: sub r5, r5, #1 ! 651: b Ldo_single_div ! 652: ! 653: Lnot_too_big: ! 654: 3: cmp lr, r3 ! 655: bcc 2b ! 656: @ beq Ldo_single_div ! 657: ! 658: /* NB: these are commented out in the V8-Sparc manual as well */ ! 659: /* (I do not understand this) */ ! 660: @ lr > r3: went too far: back up 1 step ! 661: @ srl lr, 1, lr ! 662: @ dec r5 ! 663: @ do single-bit divide steps ! 664: @ ! 665: @ We have to be careful here. We know that r3 >= lr, so we can do the ! 666: @ first divide step without thinking. BUT, the others are conditional, ! 667: @ and are only done if r3 >= 0. Because both r3 and lr may have the high- ! 668: @ order bit set in the first step, just falling into the regular ! 669: @ division loop will mess up the first time around. ! 670: @ So we unroll slightly... ! 671: Ldo_single_div: ! 672: subs r5, r5, #1 ! 673: blt Lend_regular_divide ! 674: sub r3, r3, lr ! 675: mov r2, #1 ! 676: b Lend_single_divloop ! 677: Lsingle_divloop: ! 678: cmp r3, #0 ! 679: mov r2, r2, lsl #1 ! 680: mov lr, lr, lsr #1 ! 681: @ r3 >= 0 ! 682: subpl r3, r3, lr ! 683: addpl r2, r2, #1 ! 684: @ r3 < 0 ! 685: addmi r3, r3, lr ! 686: submi r2, r2, #1 ! 687: Lend_single_divloop: ! 688: subs r5, r5, #1 ! 689: bge Lsingle_divloop ! 690: b Lend_regular_divide ! 691: ! 692: 1: ! 693: add ip, ip, #1 ! 694: Lnot_really_big: ! 695: mov lr, lr, lsl #4 ! 696: cmp lr, r3 ! 697: bls 1b ! 698: @ ! 699: @ HOW CAN ip EVER BE -1 HERE ????? ! 700: @ ! 701: cmn ip, #1 ! 702: beq Lgot_result ! 703: ! 704: Ldivloop: ! 705: cmp r3, #0 @ set up for initial iteration ! 706: mov r2, r2, lsl #4 ! 707: @ depth 1, accumulated bits 0 ! 708: mov lr, lr, lsr #1 ! 709: blt L.1.1015 ! 710: @ remainder is positive ! 711: subs r3, r3, lr ! 712: @ depth 2, accumulated bits 1 ! 713: mov lr, lr, lsr #1 ! 714: blt L.2.1016 ! 715: @ remainder is positive ! 716: subs r3, r3, lr ! 717: @ depth 3, accumulated bits 3 ! 718: mov lr, lr, lsr #1 ! 719: blt L.3.1018 ! 720: @ remainder is positive ! 721: subs r3, r3, lr ! 722: @ depth 4, accumulated bits 7 ! 723: mov lr, lr, lsr #1 ! 724: blt L.4.1022 ! 725: @ remainder is positive ! 726: subs r3, r3, lr ! 727: add r2, r2, #15 ! 728: ! 729: b 9f ! 730: ! 731: L.4.1022: ! 732: @ remainder is negative ! 733: adds r3, r3, lr ! 734: add r2, r2, #13 ! 735: b 9f ! 736: ! 737: ! 738: ! 739: L.3.1018: ! 740: @ remainder is negative ! 741: adds r3, r3, lr ! 742: @ depth 4, accumulated bits 5 ! 743: mov lr, lr, lsr #1 ! 744: blt L.4.1020 ! 745: @ remainder is positive ! 746: subs r3, r3, lr ! 747: add r2, r2, #11 ! 748: ! 749: b 9f ! 750: ! 751: L.4.1020: ! 752: @ remainder is negative ! 753: adds r3, r3, lr ! 754: add r2, r2, #9 ! 755: b 9f ! 756: ! 757: ! 758: ! 759: ! 760: L.2.1016: ! 761: @ remainder is negative ! 762: adds r3, r3, lr ! 763: @ depth 3, accumulated bits 1 ! 764: mov lr, lr, lsr #1 ! 765: blt L.3.1016 ! 766: @ remainder is positive ! 767: subs r3, r3, lr ! 768: @ depth 4, accumulated bits 3 ! 769: mov lr, lr, lsr #1 ! 770: blt L.4.1018 ! 771: @ remainder is positive ! 772: subs r3, r3, lr ! 773: add r2, r2, #7 ! 774: ! 775: b 9f ! 776: ! 777: L.4.1018: ! 778: @ remainder is negative ! 779: adds r3, r3, lr ! 780: add r2, r2, #5 ! 781: b 9f ! 782: ! 783: ! 784: ! 785: L.3.1016: ! 786: @ remainder is negative ! 787: adds r3, r3, lr ! 788: @ depth 4, accumulated bits 1 ! 789: mov lr, lr, lsr #1 ! 790: blt L.4.1016 ! 791: @ remainder is positive ! 792: subs r3, r3, lr ! 793: add r2, r2, #3 ! 794: ! 795: b 9f ! 796: ! 797: L.4.1016: ! 798: @ remainder is negative ! 799: adds r3, r3, lr ! 800: add r2, r2, #1 ! 801: b 9f ! 802: ! 803: ! 804: ! 805: ! 806: ! 807: L.1.1015: ! 808: @ remainder is negative ! 809: adds r3, r3, lr ! 810: @ depth 2, accumulated bits -1 ! 811: mov lr, lr, lsr #1 ! 812: blt L.2.1014 ! 813: @ remainder is positive ! 814: subs r3, r3, lr ! 815: @ depth 3, accumulated bits -1 ! 816: mov lr, lr, lsr #1 ! 817: blt L.3.1014 ! 818: @ remainder is positive ! 819: subs r3, r3, lr ! 820: @ depth 4, accumulated bits -1 ! 821: mov lr, lr, lsr #1 ! 822: blt L.4.1014 ! 823: @ remainder is positive ! 824: subs r3, r3, lr ! 825: sub r2, r2, #1 ! 826: ! 827: b 9f ! 828: ! 829: L.4.1014: ! 830: @ remainder is negative ! 831: adds r3, r3, lr ! 832: sub r2, r2, #3 ! 833: b 9f ! 834: ! 835: ! 836: ! 837: L.3.1014: ! 838: @ remainder is negative ! 839: adds r3, r3, lr ! 840: @ depth 4, accumulated bits -3 ! 841: mov lr, lr, lsr #1 ! 842: blt L.4.1012 ! 843: @ remainder is positive ! 844: subs r3, r3, lr ! 845: sub r2, r2, #5 ! 846: ! 847: b 9f ! 848: ! 849: L.4.1012: ! 850: @ remainder is negative ! 851: adds r3, r3, lr ! 852: sub r2, r2, #7 ! 853: b 9f ! 854: ! 855: ! 856: ! 857: ! 858: L.2.1014: ! 859: @ remainder is negative ! 860: adds r3, r3, lr ! 861: @ depth 3, accumulated bits -3 ! 862: mov lr, lr, lsr #1 ! 863: blt L.3.1012 ! 864: @ remainder is positive ! 865: subs r3, r3, lr ! 866: @ depth 4, accumulated bits -5 ! 867: mov lr, lr, lsr #1 ! 868: blt L.4.1010 ! 869: @ remainder is positive ! 870: subs r3, r3, lr ! 871: sub r2, r2, #9 ! 872: ! 873: b 9f ! 874: ! 875: L.4.1010: ! 876: @ remainder is negative ! 877: adds r3, r3, lr ! 878: sub r2, r2, #11 ! 879: b 9f ! 880: ! 881: ! 882: ! 883: L.3.1012: ! 884: @ remainder is negative ! 885: adds r3, r3, lr ! 886: @ depth 4, accumulated bits -7 ! 887: mov lr, lr, lsr #1 ! 888: blt L.4.1008 ! 889: @ remainder is positive ! 890: subs r3, r3, lr ! 891: sub r2, r2, #13 ! 892: ! 893: b 9f ! 894: ! 895: L.4.1008: ! 896: @ remainder is negative ! 897: adds r3, r3, lr ! 898: sub r2, r2, #15 ! 899: b 9f ! 900: ! 901: ! 902: ! 903: ! 904: ! 905: 9: ! 906: Lend_regular_divide: ! 907: subs ip, ip, #1 ! 908: bge Ldivloop ! 909: cmp r3, #0 ! 910: @ non-restoring fixup here (one instruction only!) ! 911: sublt r2, r2, #1 ! 912: ! 913: ! 914: Lgot_result: ! 915: @ check to see if answer should be < 0 ! 916: cmp r6, #0 ! 917: rsbmi r2, r2, #0 ! 918: ! 919: mov r0, r2 ! 920: ldmia sp!, {r4, r5, r6, pc} ! 921: ! 922: Ldiv_zero: ! 923: @ Divide by zero trap. If it returns, return 0 (about as ! 924: @ wrong as possible, but that is what SunOS does...). ! 925: bl ___div0 ! 926: mov r0, #0 ! 927: ldmia sp!, {r4, r5, r6, pc} ! 928: ! 929: #endif /* L_divsi3 */ ! 930: ! 931: #ifdef L_umodsi3 ! 932: ! 933: ip .req r12 ! 934: sp .req r13 ! 935: lr .req r14 ! 936: pc .req r15 ! 937: .text ! 938: .globl ___umodsi3 ! 939: .align 0 ! 940: ___umodsi3: ! 941: stmdb sp!, {r4, r5, lr} ! 942: @ Ready to divide. Compute size of quotient; scale comparand. ! 943: movs lr, r1 ! 944: mov r3, r0 ! 945: beq Ldiv_zero ! 946: ! 947: ! 948: cmp r3, lr @ if r1 exceeds r0, done ! 949: mov r2, #0 ! 950: bcc Lgot_result @ (and algorithm fails otherwise) ! 951: mov r4, #(1 << (32 - 4 - 1)) ! 952: cmp r3, r4 ! 953: mov ip, #0 ! 954: bcc Lnot_really_big ! 955: ! 956: @ Here the dividend is >= 2^(31-N) or so. We must be careful here, ! 957: @ as our usual N-at-a-shot divide step will cause overflow and havoc. ! 958: @ The number of bits in the result here is N*ITER+SC, where SC <= N. ! 959: @ Compute ITER in an unorthodox manner: know we need to shift V into ! 960: @ the top decade: so do not even bother to compare to R. ! 961: mov r5, #1 ! 962: 1: ! 963: cmp lr, r4 ! 964: bcs 3f ! 965: mov lr, lr, lsl #4 ! 966: add ip, ip, #1 ! 967: b 1b ! 968: ! 969: @ Now compute r5. ! 970: 2: adds lr, lr, lr ! 971: add r5, r5, #1 ! 972: bcc Lnot_too_big ! 973: ! 974: @ We get here if the r1 overflowed while shifting. ! 975: @ This means that r3 has the high-order bit set. ! 976: @ Restore lr and subtract from r3. ! 977: mov r4, r4, lsl #4 ! 978: mov lr, lr, lsr #1 ! 979: add lr, r4, lr ! 980: sub r5, r5, #1 ! 981: b Ldo_single_div ! 982: ! 983: Lnot_too_big: ! 984: 3: cmp lr, r3 ! 985: bcc 2b ! 986: @ beq Ldo_single_div ! 987: ! 988: /* NB: these are commented out in the V8-Sparc manual as well */ ! 989: /* (I do not understand this) */ ! 990: @ lr > r3: went too far: back up 1 step ! 991: @ srl lr, 1, lr ! 992: @ dec r5 ! 993: @ do single-bit divide steps ! 994: @ ! 995: @ We have to be careful here. We know that r3 >= lr, so we can do the ! 996: @ first divide step without thinking. BUT, the others are conditional, ! 997: @ and are only done if r3 >= 0. Because both r3 and lr may have the high- ! 998: @ order bit set in the first step, just falling into the regular ! 999: @ division loop will mess up the first time around. ! 1000: @ So we unroll slightly... ! 1001: Ldo_single_div: ! 1002: subs r5, r5, #1 ! 1003: blt Lend_regular_divide ! 1004: sub r3, r3, lr ! 1005: mov r2, #1 ! 1006: b Lend_single_divloop ! 1007: Lsingle_divloop: ! 1008: cmp r3, #0 ! 1009: mov r2, r2, lsl #1 ! 1010: mov lr, lr, lsr #1 ! 1011: @ r3 >= 0 ! 1012: subpl r3, r3, lr ! 1013: addpl r2, r2, #1 ! 1014: @ r3 < 0 ! 1015: addmi r3, r3, lr ! 1016: submi r2, r2, #1 ! 1017: Lend_single_divloop: ! 1018: subs r5, r5, #1 ! 1019: bge Lsingle_divloop ! 1020: b Lend_regular_divide ! 1021: ! 1022: 1: ! 1023: add ip, ip, #1 ! 1024: Lnot_really_big: ! 1025: mov lr, lr, lsl #4 ! 1026: cmp lr, r3 ! 1027: bls 1b ! 1028: @ ! 1029: @ HOW CAN ip EVER BE -1 HERE ????? ! 1030: @ ! 1031: cmn ip, #1 ! 1032: beq Lgot_result ! 1033: ! 1034: Ldivloop: ! 1035: cmp r3, #0 @ set up for initial iteration ! 1036: mov r2, r2, lsl #4 ! 1037: @ depth 1, accumulated bits 0 ! 1038: mov lr, lr, lsr #1 ! 1039: blt L.1.1015 ! 1040: @ remainder is positive ! 1041: subs r3, r3, lr ! 1042: @ depth 2, accumulated bits 1 ! 1043: mov lr, lr, lsr #1 ! 1044: blt L.2.1016 ! 1045: @ remainder is positive ! 1046: subs r3, r3, lr ! 1047: @ depth 3, accumulated bits 3 ! 1048: mov lr, lr, lsr #1 ! 1049: blt L.3.1018 ! 1050: @ remainder is positive ! 1051: subs r3, r3, lr ! 1052: @ depth 4, accumulated bits 7 ! 1053: mov lr, lr, lsr #1 ! 1054: blt L.4.1022 ! 1055: @ remainder is positive ! 1056: subs r3, r3, lr ! 1057: add r2, r2, #15 ! 1058: ! 1059: b 9f ! 1060: ! 1061: L.4.1022: ! 1062: @ remainder is negative ! 1063: adds r3, r3, lr ! 1064: add r2, r2, #13 ! 1065: b 9f ! 1066: ! 1067: ! 1068: ! 1069: L.3.1018: ! 1070: @ remainder is negative ! 1071: adds r3, r3, lr ! 1072: @ depth 4, accumulated bits 5 ! 1073: mov lr, lr, lsr #1 ! 1074: blt L.4.1020 ! 1075: @ remainder is positive ! 1076: subs r3, r3, lr ! 1077: add r2, r2, #11 ! 1078: ! 1079: b 9f ! 1080: ! 1081: L.4.1020: ! 1082: @ remainder is negative ! 1083: adds r3, r3, lr ! 1084: add r2, r2, #9 ! 1085: b 9f ! 1086: ! 1087: ! 1088: ! 1089: ! 1090: L.2.1016: ! 1091: @ remainder is negative ! 1092: adds r3, r3, lr ! 1093: @ depth 3, accumulated bits 1 ! 1094: mov lr, lr, lsr #1 ! 1095: blt L.3.1016 ! 1096: @ remainder is positive ! 1097: subs r3, r3, lr ! 1098: @ depth 4, accumulated bits 3 ! 1099: mov lr, lr, lsr #1 ! 1100: blt L.4.1018 ! 1101: @ remainder is positive ! 1102: subs r3, r3, lr ! 1103: add r2, r2, #7 ! 1104: ! 1105: b 9f ! 1106: ! 1107: L.4.1018: ! 1108: @ remainder is negative ! 1109: adds r3, r3, lr ! 1110: add r2, r2, #5 ! 1111: b 9f ! 1112: ! 1113: ! 1114: ! 1115: L.3.1016: ! 1116: @ remainder is negative ! 1117: adds r3, r3, lr ! 1118: @ depth 4, accumulated bits 1 ! 1119: mov lr, lr, lsr #1 ! 1120: blt L.4.1016 ! 1121: @ remainder is positive ! 1122: subs r3, r3, lr ! 1123: add r2, r2, #3 ! 1124: ! 1125: b 9f ! 1126: ! 1127: L.4.1016: ! 1128: @ remainder is negative ! 1129: adds r3, r3, lr ! 1130: add r2, r2, #1 ! 1131: b 9f ! 1132: ! 1133: ! 1134: ! 1135: ! 1136: ! 1137: L.1.1015: ! 1138: @ remainder is negative ! 1139: adds r3, r3, lr ! 1140: @ depth 2, accumulated bits -1 ! 1141: mov lr, lr, lsr #1 ! 1142: blt L.2.1014 ! 1143: @ remainder is positive ! 1144: subs r3, r3, lr ! 1145: @ depth 3, accumulated bits -1 ! 1146: mov lr, lr, lsr #1 ! 1147: blt L.3.1014 ! 1148: @ remainder is positive ! 1149: subs r3, r3, lr ! 1150: @ depth 4, accumulated bits -1 ! 1151: mov lr, lr, lsr #1 ! 1152: blt L.4.1014 ! 1153: @ remainder is positive ! 1154: subs r3, r3, lr ! 1155: sub r2, r2, #1 ! 1156: ! 1157: b 9f ! 1158: ! 1159: L.4.1014: ! 1160: @ remainder is negative ! 1161: adds r3, r3, lr ! 1162: sub r2, r2, #3 ! 1163: b 9f ! 1164: ! 1165: ! 1166: ! 1167: L.3.1014: ! 1168: @ remainder is negative ! 1169: adds r3, r3, lr ! 1170: @ depth 4, accumulated bits -3 ! 1171: mov lr, lr, lsr #1 ! 1172: blt L.4.1012 ! 1173: @ remainder is positive ! 1174: subs r3, r3, lr ! 1175: sub r2, r2, #5 ! 1176: ! 1177: b 9f ! 1178: ! 1179: L.4.1012: ! 1180: @ remainder is negative ! 1181: adds r3, r3, lr ! 1182: sub r2, r2, #7 ! 1183: b 9f ! 1184: ! 1185: ! 1186: ! 1187: ! 1188: L.2.1014: ! 1189: @ remainder is negative ! 1190: adds r3, r3, lr ! 1191: @ depth 3, accumulated bits -3 ! 1192: mov lr, lr, lsr #1 ! 1193: blt L.3.1012 ! 1194: @ remainder is positive ! 1195: subs r3, r3, lr ! 1196: @ depth 4, accumulated bits -5 ! 1197: mov lr, lr, lsr #1 ! 1198: blt L.4.1010 ! 1199: @ remainder is positive ! 1200: subs r3, r3, lr ! 1201: sub r2, r2, #9 ! 1202: ! 1203: b 9f ! 1204: ! 1205: L.4.1010: ! 1206: @ remainder is negative ! 1207: adds r3, r3, lr ! 1208: sub r2, r2, #11 ! 1209: b 9f ! 1210: ! 1211: ! 1212: ! 1213: L.3.1012: ! 1214: @ remainder is negative ! 1215: adds r3, r3, lr ! 1216: @ depth 4, accumulated bits -7 ! 1217: mov lr, lr, lsr #1 ! 1218: blt L.4.1008 ! 1219: @ remainder is positive ! 1220: subs r3, r3, lr ! 1221: sub r2, r2, #13 ! 1222: ! 1223: b 9f ! 1224: ! 1225: L.4.1008: ! 1226: @ remainder is negative ! 1227: adds r3, r3, lr ! 1228: sub r2, r2, #15 ! 1229: b 9f ! 1230: ! 1231: ! 1232: ! 1233: ! 1234: ! 1235: 9: ! 1236: Lend_regular_divide: ! 1237: subs ip, ip, #1 ! 1238: bge Ldivloop ! 1239: cmp r3, #0 ! 1240: @ non-restoring fixup here (one instruction only!) ! 1241: addlt r3, r1, r3 ! 1242: ! 1243: ! 1244: Lgot_result: ! 1245: ! 1246: mov r0, r3 ! 1247: ldmia sp!, {r4, r5, pc} ! 1248: ! 1249: Ldiv_zero: ! 1250: @ Divide by zero trap. If it returns, return 0 (about as ! 1251: @ wrong as possible, but that is what SunOS does...). ! 1252: bl ___div0 ! 1253: mov r0, #0 ! 1254: ldmia sp!, {r4, r5, pc} ! 1255: ! 1256: #endif /* L_umodsi3 */ ! 1257: ! 1258: #ifdef L_modsi3 ! 1259: ! 1260: ip .req r12 ! 1261: sp .req r13 ! 1262: lr .req r14 ! 1263: pc .req r15 ! 1264: .text ! 1265: .globl ___modsi3 ! 1266: .align 0 ! 1267: ___modsi3: ! 1268: stmdb sp!, {r4, r5, r6, lr} ! 1269: @ compute sign of result; if neither is negative, no problem ! 1270: mov r6, r0 ! 1271: cmp r1, #0 ! 1272: rsbmi r1, r1, #0 ! 1273: beq Ldiv_zero ! 1274: mov lr, r1 ! 1275: movs r3, r0 ! 1276: rsbmi r3, r3, #0 @ make dividend nonnegative ! 1277: ! 1278: ! 1279: cmp r3, lr @ if r1 exceeds r0, done ! 1280: mov r2, #0 ! 1281: bcc Lgot_result @ (and algorithm fails otherwise) ! 1282: mov r4, #(1 << (32 - 4 - 1)) ! 1283: cmp r3, r4 ! 1284: mov ip, #0 ! 1285: bcc Lnot_really_big ! 1286: ! 1287: @ Here the dividend is >= 2^(31-N) or so. We must be careful here, ! 1288: @ as our usual N-at-a-shot divide step will cause overflow and havoc. ! 1289: @ The number of bits in the result here is N*ITER+SC, where SC <= N. ! 1290: @ Compute ITER in an unorthodox manner: know we need to shift V into ! 1291: @ the top decade: so do not even bother to compare to R. ! 1292: mov r5, #1 ! 1293: 1: ! 1294: cmp lr, r4 ! 1295: bcs 3f ! 1296: mov lr, lr, lsl #4 ! 1297: add ip, ip, #1 ! 1298: b 1b ! 1299: ! 1300: @ Now compute r5. ! 1301: 2: adds lr, lr, lr ! 1302: add r5, r5, #1 ! 1303: bcc Lnot_too_big ! 1304: ! 1305: @ We get here if the r1 overflowed while shifting. ! 1306: @ This means that r3 has the high-order bit set. ! 1307: @ Restore lr and subtract from r3. ! 1308: mov r4, r4, lsl #4 ! 1309: mov lr, lr, lsr #1 ! 1310: add lr, r4, lr ! 1311: sub r5, r5, #1 ! 1312: b Ldo_single_div ! 1313: ! 1314: Lnot_too_big: ! 1315: 3: cmp lr, r3 ! 1316: bcc 2b ! 1317: @ beq Ldo_single_div ! 1318: ! 1319: /* NB: these are commented out in the V8-Sparc manual as well */ ! 1320: /* (I do not understand this) */ ! 1321: @ lr > r3: went too far: back up 1 step ! 1322: @ srl lr, 1, lr ! 1323: @ dec r5 ! 1324: @ do single-bit divide steps ! 1325: @ ! 1326: @ We have to be careful here. We know that r3 >= lr, so we can do the ! 1327: @ first divide step without thinking. BUT, the others are conditional, ! 1328: @ and are only done if r3 >= 0. Because both r3 and lr may have the high- ! 1329: @ order bit set in the first step, just falling into the regular ! 1330: @ division loop will mess up the first time around. ! 1331: @ So we unroll slightly... ! 1332: Ldo_single_div: ! 1333: subs r5, r5, #1 ! 1334: blt Lend_regular_divide ! 1335: sub r3, r3, lr ! 1336: mov r2, #1 ! 1337: b Lend_single_divloop ! 1338: Lsingle_divloop: ! 1339: cmp r3, #0 ! 1340: mov r2, r2, lsl #1 ! 1341: mov lr, lr, lsr #1 ! 1342: @ r3 >= 0 ! 1343: subpl r3, r3, lr ! 1344: addpl r2, r2, #1 ! 1345: @ r3 < 0 ! 1346: addmi r3, r3, lr ! 1347: submi r2, r2, #1 ! 1348: Lend_single_divloop: ! 1349: subs r5, r5, #1 ! 1350: bge Lsingle_divloop ! 1351: b Lend_regular_divide ! 1352: ! 1353: 1: ! 1354: add ip, ip, #1 ! 1355: Lnot_really_big: ! 1356: mov lr, lr, lsl #4 ! 1357: cmp lr, r3 ! 1358: bls 1b ! 1359: @ ! 1360: @ HOW CAN ip EVER BE -1 HERE ????? ! 1361: @ ! 1362: cmn ip, #1 ! 1363: beq Lgot_result ! 1364: ! 1365: Ldivloop: ! 1366: cmp r3, #0 @ set up for initial iteration ! 1367: mov r2, r2, lsl #4 ! 1368: @ depth 1, accumulated bits 0 ! 1369: mov lr, lr, lsr #1 ! 1370: blt L.1.1015 ! 1371: @ remainder is positive ! 1372: subs r3, r3, lr ! 1373: @ depth 2, accumulated bits 1 ! 1374: mov lr, lr, lsr #1 ! 1375: blt L.2.1016 ! 1376: @ remainder is positive ! 1377: subs r3, r3, lr ! 1378: @ depth 3, accumulated bits 3 ! 1379: mov lr, lr, lsr #1 ! 1380: blt L.3.1018 ! 1381: @ remainder is positive ! 1382: subs r3, r3, lr ! 1383: @ depth 4, accumulated bits 7 ! 1384: mov lr, lr, lsr #1 ! 1385: blt L.4.1022 ! 1386: @ remainder is positive ! 1387: subs r3, r3, lr ! 1388: add r2, r2, #15 ! 1389: ! 1390: b 9f ! 1391: ! 1392: L.4.1022: ! 1393: @ remainder is negative ! 1394: adds r3, r3, lr ! 1395: add r2, r2, #13 ! 1396: b 9f ! 1397: ! 1398: ! 1399: ! 1400: L.3.1018: ! 1401: @ remainder is negative ! 1402: adds r3, r3, lr ! 1403: @ depth 4, accumulated bits 5 ! 1404: mov lr, lr, lsr #1 ! 1405: blt L.4.1020 ! 1406: @ remainder is positive ! 1407: subs r3, r3, lr ! 1408: add r2, r2, #11 ! 1409: ! 1410: b 9f ! 1411: ! 1412: L.4.1020: ! 1413: @ remainder is negative ! 1414: adds r3, r3, lr ! 1415: add r2, r2, #9 ! 1416: b 9f ! 1417: ! 1418: ! 1419: ! 1420: ! 1421: L.2.1016: ! 1422: @ remainder is negative ! 1423: adds r3, r3, lr ! 1424: @ depth 3, accumulated bits 1 ! 1425: mov lr, lr, lsr #1 ! 1426: blt L.3.1016 ! 1427: @ remainder is positive ! 1428: subs r3, r3, lr ! 1429: @ depth 4, accumulated bits 3 ! 1430: mov lr, lr, lsr #1 ! 1431: blt L.4.1018 ! 1432: @ remainder is positive ! 1433: subs r3, r3, lr ! 1434: add r2, r2, #7 ! 1435: ! 1436: b 9f ! 1437: ! 1438: L.4.1018: ! 1439: @ remainder is negative ! 1440: adds r3, r3, lr ! 1441: add r2, r2, #5 ! 1442: b 9f ! 1443: ! 1444: ! 1445: ! 1446: L.3.1016: ! 1447: @ remainder is negative ! 1448: adds r3, r3, lr ! 1449: @ depth 4, accumulated bits 1 ! 1450: mov lr, lr, lsr #1 ! 1451: blt L.4.1016 ! 1452: @ remainder is positive ! 1453: subs r3, r3, lr ! 1454: add r2, r2, #3 ! 1455: ! 1456: b 9f ! 1457: ! 1458: L.4.1016: ! 1459: @ remainder is negative ! 1460: adds r3, r3, lr ! 1461: add r2, r2, #1 ! 1462: b 9f ! 1463: ! 1464: ! 1465: ! 1466: ! 1467: ! 1468: L.1.1015: ! 1469: @ remainder is negative ! 1470: adds r3, r3, lr ! 1471: @ depth 2, accumulated bits -1 ! 1472: mov lr, lr, lsr #1 ! 1473: blt L.2.1014 ! 1474: @ remainder is positive ! 1475: subs r3, r3, lr ! 1476: @ depth 3, accumulated bits -1 ! 1477: mov lr, lr, lsr #1 ! 1478: blt L.3.1014 ! 1479: @ remainder is positive ! 1480: subs r3, r3, lr ! 1481: @ depth 4, accumulated bits -1 ! 1482: mov lr, lr, lsr #1 ! 1483: blt L.4.1014 ! 1484: @ remainder is positive ! 1485: subs r3, r3, lr ! 1486: sub r2, r2, #1 ! 1487: ! 1488: b 9f ! 1489: ! 1490: L.4.1014: ! 1491: @ remainder is negative ! 1492: adds r3, r3, lr ! 1493: sub r2, r2, #3 ! 1494: b 9f ! 1495: ! 1496: ! 1497: ! 1498: L.3.1014: ! 1499: @ remainder is negative ! 1500: adds r3, r3, lr ! 1501: @ depth 4, accumulated bits -3 ! 1502: mov lr, lr, lsr #1 ! 1503: blt L.4.1012 ! 1504: @ remainder is positive ! 1505: subs r3, r3, lr ! 1506: sub r2, r2, #5 ! 1507: ! 1508: b 9f ! 1509: ! 1510: L.4.1012: ! 1511: @ remainder is negative ! 1512: adds r3, r3, lr ! 1513: sub r2, r2, #7 ! 1514: b 9f ! 1515: ! 1516: ! 1517: ! 1518: ! 1519: L.2.1014: ! 1520: @ remainder is negative ! 1521: adds r3, r3, lr ! 1522: @ depth 3, accumulated bits -3 ! 1523: mov lr, lr, lsr #1 ! 1524: blt L.3.1012 ! 1525: @ remainder is positive ! 1526: subs r3, r3, lr ! 1527: @ depth 4, accumulated bits -5 ! 1528: mov lr, lr, lsr #1 ! 1529: blt L.4.1010 ! 1530: @ remainder is positive ! 1531: subs r3, r3, lr ! 1532: sub r2, r2, #9 ! 1533: ! 1534: b 9f ! 1535: ! 1536: L.4.1010: ! 1537: @ remainder is negative ! 1538: adds r3, r3, lr ! 1539: sub r2, r2, #11 ! 1540: b 9f ! 1541: ! 1542: ! 1543: ! 1544: L.3.1012: ! 1545: @ remainder is negative ! 1546: adds r3, r3, lr ! 1547: @ depth 4, accumulated bits -7 ! 1548: mov lr, lr, lsr #1 ! 1549: blt L.4.1008 ! 1550: @ remainder is positive ! 1551: subs r3, r3, lr ! 1552: sub r2, r2, #13 ! 1553: ! 1554: b 9f ! 1555: ! 1556: L.4.1008: ! 1557: @ remainder is negative ! 1558: adds r3, r3, lr ! 1559: sub r2, r2, #15 ! 1560: b 9f ! 1561: ! 1562: ! 1563: ! 1564: ! 1565: ! 1566: 9: ! 1567: Lend_regular_divide: ! 1568: subs ip, ip, #1 ! 1569: bge Ldivloop ! 1570: cmp r3, #0 ! 1571: @ non-restoring fixup here (one instruction only!) ! 1572: addlt r3, r1, r3 ! 1573: ! 1574: ! 1575: Lgot_result: ! 1576: @ check to see if answer should be < 0 ! 1577: cmp r6, #0 ! 1578: rsbmi r3, r3, #0 ! 1579: ! 1580: mov r0, r3 ! 1581: ldmia sp!, {r4, r5, r6, pc} ! 1582: ! 1583: Ldiv_zero: ! 1584: @ Divide by zero trap. If it returns, return 0 (about as ! 1585: @ wrong as possible, but that is what SunOS does...). ! 1586: bl ___div0 ! 1587: mov r0, #0 ! 1588: ldmia sp!, {r4, r5, r6, pc} ! 1589: ! 1590: #endif /* L_modsi3 */ ! 1591: ! 1592: #ifdef L_dvmd_tls ! 1593: ! 1594: .globl ___div0 ! 1595: .align 0 ! 1596: ___div0: ! 1597: mov pc, lr ! 1598: ! 1599: #endif /* L_divmodsi_tools */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.