Annotation of gcc/config/arm/lib1funcs.asm, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.