[BACK]Return to divsi3.S CVS log [TXT][DIR] Up to [local] / funnyos / libkern

Annotation of funnyos/libkern/divsi3.S, Revision 1.1

1.1     ! init        1: /*  $Id: divsi3.S,v 1.1.1.1 2007/10/12 08:40:42 init Exp $ */
        !             2: /*     $OpenBSD: divsi3.S,v 1.2 2004/02/01 05:47:10 drahn Exp $        */
        !             3: /*     $NetBSD: divsi3.S,v 1.2 2001/11/13 20:06:40 chris Exp $ */
        !             4: /*
        !             5:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
        !             6:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !             7:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !             8:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
        !             9:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            10:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            11:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            12:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            13:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            14:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            15:  * SUCH DAMAGE.
        !            16:  */
        !            17:
        !            18: #include <libkern/asm.h>
        !            19:
        !            20: /*
        !            21:  * stack is aligned as there's a possibility of branching to L_overflow
        !            22:  * which makes a C call
        !            23:  */
        !            24:
        !            25: ENTRY(__umodsi3)
        !            26:        stmfd   sp!, {lr}
        !            27:        sub     sp, sp, #4      /* align stack */
        !            28:        bl      L_udivide
        !            29:        add     sp, sp, #4      /* unalign stack */
        !            30:        mov     r0, r1
        !            31: #ifdef __APCS_26__
        !            32:        ldmfd   sp!, {pc}^
        !            33: #else /* APCS-32 */
        !            34:        ldmfd   sp!, {pc}
        !            35: #endif
        !            36:
        !            37: ENTRY(__modsi3)
        !            38:        stmfd   sp!, {lr}
        !            39:        sub     sp, sp, #4      /* align stack */
        !            40:        bl      L_divide
        !            41:        add     sp, sp, #4      /* unalign stack */
        !            42:        mov     r0, r1
        !            43: #ifdef __APCS_26__
        !            44:        ldmfd   sp!, {pc}^
        !            45: #else
        !            46:        ldmfd   sp!, {pc}
        !            47: #endif
        !            48:
        !            49: L_overflow:
        !            50: #if !defined(_KERNEL) && !defined(_STANDALONE)
        !            51:        mov     r0, #8                  /* SIGFPE */
        !            52: #if 0
        !            53:        bl      PIC_SYM(_C_LABEL(raise), PLT)   /* raise it */
        !            54: #endif
        !            55:        mov     r0, #0
        !            56: #else
        !            57:        /* XXX should cause a fatal error */
        !            58:        mvn     r0, #0
        !            59: #endif
        !            60: #ifdef __APCS_26__
        !            61:        movs    pc, lr
        !            62: #else
        !            63:        mov     pc, lr
        !            64: #endif
        !            65:
        !            66: ENTRY(__udivsi3)
        !            67: L_udivide:                             /* r0 = r0 / r1; r1 = r0 % r1 */
        !            68:        eor     r0, r1, r0
        !            69:        eor     r1, r0, r1
        !            70:        eor     r0, r1, r0
        !            71:                                        /* r0 = r1 / r0; r1 = r1 % r0 */
        !            72:        cmp     r0, #1
        !            73:        bcc     L_overflow
        !            74:        beq     L_divide_l0
        !            75:        mov     ip, #0
        !            76:        movs    r1, r1
        !            77:        bpl     L_divide_l1
        !            78:        orr     ip, ip, #0x20000000     /* ip bit 0x20000000 = -ve r1 */
        !            79:        movs    r1, r1, lsr #1
        !            80:        orrcs   ip, ip, #0x10000000     /* ip bit 0x10000000 = bit 0 of r1 */
        !            81:        b       L_divide_l1
        !            82:
        !            83: L_divide_l0:                           /* r0 == 1 */
        !            84:        mov     r0, r1
        !            85:        mov     r1, #0
        !            86: #ifdef __APCS_26__
        !            87:        movs    pc, lr
        !            88: #else
        !            89:        mov     pc, lr
        !            90: #endif
        !            91:
        !            92: ENTRY(__divsi3)
        !            93: L_divide:                              /* r0 = r0 / r1; r1 = r0 % r1 */
        !            94:        eor     r0, r1, r0
        !            95:        eor     r1, r0, r1
        !            96:        eor     r0, r1, r0
        !            97:                                        /* r0 = r1 / r0; r1 = r1 % r0 */
        !            98:        cmp     r0, #1
        !            99:        bcc     L_overflow
        !           100:        beq     L_divide_l0
        !           101:        ands    ip, r0, #0x80000000
        !           102:        rsbmi   r0, r0, #0
        !           103:        ands    r2, r1, #0x80000000
        !           104:        eor     ip, ip, r2
        !           105:        rsbmi   r1, r1, #0
        !           106:        orr     ip, r2, ip, lsr #1      /* ip bit 0x40000000 = -ve division */
        !           107:                                        /* ip bit 0x80000000 = -ve remainder */
        !           108:
        !           109: L_divide_l1:
        !           110:        mov     r2, #1
        !           111:        mov     r3, #0
        !           112:
        !           113:        /*
        !           114:         * If the highest bit of the dividend is set, we have to be
        !           115:         * careful when shifting the divisor. Test this.
        !           116:         */
        !           117:        movs    r1,r1
        !           118:        bpl     L_old_code
        !           119:
        !           120:        /*
        !           121:         * At this point, the highest bit of r1 is known to be set.
        !           122:         * We abuse this below in the tst instructions.
        !           123:         */
        !           124:        tst     r1, r0 /*, lsl #0 */
        !           125:        bmi     L_divide_b1
        !           126:        tst     r1, r0, lsl #1
        !           127:        bmi     L_divide_b2
        !           128:        tst     r1, r0, lsl #2
        !           129:        bmi     L_divide_b3
        !           130:        tst     r1, r0, lsl #3
        !           131:        bmi     L_divide_b4
        !           132:        tst     r1, r0, lsl #4
        !           133:        bmi     L_divide_b5
        !           134:        tst     r1, r0, lsl #5
        !           135:        bmi     L_divide_b6
        !           136:        tst     r1, r0, lsl #6
        !           137:        bmi     L_divide_b7
        !           138:        tst     r1, r0, lsl #7
        !           139:        bmi     L_divide_b8
        !           140:        tst     r1, r0, lsl #8
        !           141:        bmi     L_divide_b9
        !           142:        tst     r1, r0, lsl #9
        !           143:        bmi     L_divide_b10
        !           144:        tst     r1, r0, lsl #10
        !           145:        bmi     L_divide_b11
        !           146:        tst     r1, r0, lsl #11
        !           147:        bmi     L_divide_b12
        !           148:        tst     r1, r0, lsl #12
        !           149:        bmi     L_divide_b13
        !           150:        tst     r1, r0, lsl #13
        !           151:        bmi     L_divide_b14
        !           152:        tst     r1, r0, lsl #14
        !           153:        bmi     L_divide_b15
        !           154:        tst     r1, r0, lsl #15
        !           155:        bmi     L_divide_b16
        !           156:        tst     r1, r0, lsl #16
        !           157:        bmi     L_divide_b17
        !           158:        tst     r1, r0, lsl #17
        !           159:        bmi     L_divide_b18
        !           160:        tst     r1, r0, lsl #18
        !           161:        bmi     L_divide_b19
        !           162:        tst     r1, r0, lsl #19
        !           163:        bmi     L_divide_b20
        !           164:        tst     r1, r0, lsl #20
        !           165:        bmi     L_divide_b21
        !           166:        tst     r1, r0, lsl #21
        !           167:        bmi     L_divide_b22
        !           168:        tst     r1, r0, lsl #22
        !           169:        bmi     L_divide_b23
        !           170:        tst     r1, r0, lsl #23
        !           171:        bmi     L_divide_b24
        !           172:        tst     r1, r0, lsl #24
        !           173:        bmi     L_divide_b25
        !           174:        tst     r1, r0, lsl #25
        !           175:        bmi     L_divide_b26
        !           176:        tst     r1, r0, lsl #26
        !           177:        bmi     L_divide_b27
        !           178:        tst     r1, r0, lsl #27
        !           179:        bmi     L_divide_b28
        !           180:        tst     r1, r0, lsl #28
        !           181:        bmi     L_divide_b29
        !           182:        tst     r1, r0, lsl #29
        !           183:        bmi     L_divide_b30
        !           184:        tst     r1, r0, lsl #30
        !           185:        bmi     L_divide_b31
        !           186: /*
        !           187:  * instead of:
        !           188:  *     tst     r1, r0, lsl #31
        !           189:  *     bmi     L_divide_b32
        !           190:  */
        !           191:        b       L_divide_b32
        !           192:
        !           193: L_old_code:
        !           194:        cmp     r1, r0
        !           195:        bcc     L_divide_b0
        !           196:        cmp     r1, r0, lsl #1
        !           197:        bcc     L_divide_b1
        !           198:        cmp     r1, r0, lsl #2
        !           199:        bcc     L_divide_b2
        !           200:        cmp     r1, r0, lsl #3
        !           201:        bcc     L_divide_b3
        !           202:        cmp     r1, r0, lsl #4
        !           203:        bcc     L_divide_b4
        !           204:        cmp     r1, r0, lsl #5
        !           205:        bcc     L_divide_b5
        !           206:        cmp     r1, r0, lsl #6
        !           207:        bcc     L_divide_b6
        !           208:        cmp     r1, r0, lsl #7
        !           209:        bcc     L_divide_b7
        !           210:        cmp     r1, r0, lsl #8
        !           211:        bcc     L_divide_b8
        !           212:        cmp     r1, r0, lsl #9
        !           213:        bcc     L_divide_b9
        !           214:        cmp     r1, r0, lsl #10
        !           215:        bcc     L_divide_b10
        !           216:        cmp     r1, r0, lsl #11
        !           217:        bcc     L_divide_b11
        !           218:        cmp     r1, r0, lsl #12
        !           219:        bcc     L_divide_b12
        !           220:        cmp     r1, r0, lsl #13
        !           221:        bcc     L_divide_b13
        !           222:        cmp     r1, r0, lsl #14
        !           223:        bcc     L_divide_b14
        !           224:        cmp     r1, r0, lsl #15
        !           225:        bcc     L_divide_b15
        !           226:        cmp     r1, r0, lsl #16
        !           227:        bcc     L_divide_b16
        !           228:        cmp     r1, r0, lsl #17
        !           229:        bcc     L_divide_b17
        !           230:        cmp     r1, r0, lsl #18
        !           231:        bcc     L_divide_b18
        !           232:        cmp     r1, r0, lsl #19
        !           233:        bcc     L_divide_b19
        !           234:        cmp     r1, r0, lsl #20
        !           235:        bcc     L_divide_b20
        !           236:        cmp     r1, r0, lsl #21
        !           237:        bcc     L_divide_b21
        !           238:        cmp     r1, r0, lsl #22
        !           239:        bcc     L_divide_b22
        !           240:        cmp     r1, r0, lsl #23
        !           241:        bcc     L_divide_b23
        !           242:        cmp     r1, r0, lsl #24
        !           243:        bcc     L_divide_b24
        !           244:        cmp     r1, r0, lsl #25
        !           245:        bcc     L_divide_b25
        !           246:        cmp     r1, r0, lsl #26
        !           247:        bcc     L_divide_b26
        !           248:        cmp     r1, r0, lsl #27
        !           249:        bcc     L_divide_b27
        !           250:        cmp     r1, r0, lsl #28
        !           251:        bcc     L_divide_b28
        !           252:        cmp     r1, r0, lsl #29
        !           253:        bcc     L_divide_b29
        !           254:        cmp     r1, r0, lsl #30
        !           255:        bcc     L_divide_b30
        !           256: L_divide_b32:
        !           257:        cmp     r1, r0, lsl #31
        !           258:        subhs   r1, r1,r0, lsl #31
        !           259:        addhs   r3, r3,r2, lsl #31
        !           260: L_divide_b31:
        !           261:        cmp     r1, r0, lsl #30
        !           262:        subhs   r1, r1,r0, lsl #30
        !           263:        addhs   r3, r3,r2, lsl #30
        !           264: L_divide_b30:
        !           265:        cmp     r1, r0, lsl #29
        !           266:        subhs   r1, r1,r0, lsl #29
        !           267:        addhs   r3, r3,r2, lsl #29
        !           268: L_divide_b29:
        !           269:        cmp     r1, r0, lsl #28
        !           270:        subhs   r1, r1,r0, lsl #28
        !           271:        addhs   r3, r3,r2, lsl #28
        !           272: L_divide_b28:
        !           273:        cmp     r1, r0, lsl #27
        !           274:        subhs   r1, r1,r0, lsl #27
        !           275:        addhs   r3, r3,r2, lsl #27
        !           276: L_divide_b27:
        !           277:        cmp     r1, r0, lsl #26
        !           278:        subhs   r1, r1,r0, lsl #26
        !           279:        addhs   r3, r3,r2, lsl #26
        !           280: L_divide_b26:
        !           281:        cmp     r1, r0, lsl #25
        !           282:        subhs   r1, r1,r0, lsl #25
        !           283:        addhs   r3, r3,r2, lsl #25
        !           284: L_divide_b25:
        !           285:        cmp     r1, r0, lsl #24
        !           286:        subhs   r1, r1,r0, lsl #24
        !           287:        addhs   r3, r3,r2, lsl #24
        !           288: L_divide_b24:
        !           289:        cmp     r1, r0, lsl #23
        !           290:        subhs   r1, r1,r0, lsl #23
        !           291:        addhs   r3, r3,r2, lsl #23
        !           292: L_divide_b23:
        !           293:        cmp     r1, r0, lsl #22
        !           294:        subhs   r1, r1,r0, lsl #22
        !           295:        addhs   r3, r3,r2, lsl #22
        !           296: L_divide_b22:
        !           297:        cmp     r1, r0, lsl #21
        !           298:        subhs   r1, r1,r0, lsl #21
        !           299:        addhs   r3, r3,r2, lsl #21
        !           300: L_divide_b21:
        !           301:        cmp     r1, r0, lsl #20
        !           302:        subhs   r1, r1,r0, lsl #20
        !           303:        addhs   r3, r3,r2, lsl #20
        !           304: L_divide_b20:
        !           305:        cmp     r1, r0, lsl #19
        !           306:        subhs   r1, r1,r0, lsl #19
        !           307:        addhs   r3, r3,r2, lsl #19
        !           308: L_divide_b19:
        !           309:        cmp     r1, r0, lsl #18
        !           310:        subhs   r1, r1,r0, lsl #18
        !           311:        addhs   r3, r3,r2, lsl #18
        !           312: L_divide_b18:
        !           313:        cmp     r1, r0, lsl #17
        !           314:        subhs   r1, r1,r0, lsl #17
        !           315:        addhs   r3, r3,r2, lsl #17
        !           316: L_divide_b17:
        !           317:        cmp     r1, r0, lsl #16
        !           318:        subhs   r1, r1,r0, lsl #16
        !           319:        addhs   r3, r3,r2, lsl #16
        !           320: L_divide_b16:
        !           321:        cmp     r1, r0, lsl #15
        !           322:        subhs   r1, r1,r0, lsl #15
        !           323:        addhs   r3, r3,r2, lsl #15
        !           324: L_divide_b15:
        !           325:        cmp     r1, r0, lsl #14
        !           326:        subhs   r1, r1,r0, lsl #14
        !           327:        addhs   r3, r3,r2, lsl #14
        !           328: L_divide_b14:
        !           329:        cmp     r1, r0, lsl #13
        !           330:        subhs   r1, r1,r0, lsl #13
        !           331:        addhs   r3, r3,r2, lsl #13
        !           332: L_divide_b13:
        !           333:        cmp     r1, r0, lsl #12
        !           334:        subhs   r1, r1,r0, lsl #12
        !           335:        addhs   r3, r3,r2, lsl #12
        !           336: L_divide_b12:
        !           337:        cmp     r1, r0, lsl #11
        !           338:        subhs   r1, r1,r0, lsl #11
        !           339:        addhs   r3, r3,r2, lsl #11
        !           340: L_divide_b11:
        !           341:        cmp     r1, r0, lsl #10
        !           342:        subhs   r1, r1,r0, lsl #10
        !           343:        addhs   r3, r3,r2, lsl #10
        !           344: L_divide_b10:
        !           345:        cmp     r1, r0, lsl #9
        !           346:        subhs   r1, r1,r0, lsl #9
        !           347:        addhs   r3, r3,r2, lsl #9
        !           348: L_divide_b9:
        !           349:        cmp     r1, r0, lsl #8
        !           350:        subhs   r1, r1,r0, lsl #8
        !           351:        addhs   r3, r3,r2, lsl #8
        !           352: L_divide_b8:
        !           353:        cmp     r1, r0, lsl #7
        !           354:        subhs   r1, r1,r0, lsl #7
        !           355:        addhs   r3, r3,r2, lsl #7
        !           356: L_divide_b7:
        !           357:        cmp     r1, r0, lsl #6
        !           358:        subhs   r1, r1,r0, lsl #6
        !           359:        addhs   r3, r3,r2, lsl #6
        !           360: L_divide_b6:
        !           361:        cmp     r1, r0, lsl #5
        !           362:        subhs   r1, r1,r0, lsl #5
        !           363:        addhs   r3, r3,r2, lsl #5
        !           364: L_divide_b5:
        !           365:        cmp     r1, r0, lsl #4
        !           366:        subhs   r1, r1,r0, lsl #4
        !           367:        addhs   r3, r3,r2, lsl #4
        !           368: L_divide_b4:
        !           369:        cmp     r1, r0, lsl #3
        !           370:        subhs   r1, r1,r0, lsl #3
        !           371:        addhs   r3, r3,r2, lsl #3
        !           372: L_divide_b3:
        !           373:        cmp     r1, r0, lsl #2
        !           374:        subhs   r1, r1,r0, lsl #2
        !           375:        addhs   r3, r3,r2, lsl #2
        !           376: L_divide_b2:
        !           377:        cmp     r1, r0, lsl #1
        !           378:        subhs   r1, r1,r0, lsl #1
        !           379:        addhs   r3, r3,r2, lsl #1
        !           380: L_divide_b1:
        !           381:        cmp     r1, r0
        !           382:        subhs   r1, r1, r0
        !           383:        addhs   r3, r3, r2
        !           384: L_divide_b0:
        !           385:
        !           386:        tst     ip, #0x20000000
        !           387:        bne     L_udivide_l1
        !           388:        mov     r0, r3
        !           389:        cmp     ip, #0
        !           390:        rsbmi   r1, r1, #0
        !           391:        movs    ip, ip, lsl #1
        !           392:        bicmi   r0, r0, #0x80000000     /* Fix incase we divided 0x80000000 */
        !           393:        rsbmi   r0, r0, #0
        !           394: #ifdef __APCS_26__
        !           395:        movs    pc, lr
        !           396: #else
        !           397:        mov     pc, lr
        !           398: #endif
        !           399:
        !           400: L_udivide_l1:
        !           401:        tst     ip, #0x10000000
        !           402:        mov     r1, r1, lsl #1
        !           403:        orrne   r1, r1, #1
        !           404:        mov     r3, r3, lsl #1
        !           405:        cmp     r1, r0
        !           406:        subhs   r1, r1, r0
        !           407:        addhs   r3, r3, r2
        !           408:        mov     r0, r3
        !           409: #ifdef __APCS_26__
        !           410:        movs    pc, lr
        !           411: #else
        !           412:        mov     pc, lr
        !           413: #endif

CVSweb