[BACK]Return to divrem.m4 CVS log [TXT][DIR] Up to [local] / sys / lib / libkern / arch / alpha

Annotation of sys/lib/libkern/arch/alpha/divrem.m4, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: divrem.m4,v 1.3 1996/10/31 00:43:17 niklas Exp $      */
        !             2: /*     $NetBSD: divrem.m4,v 1.5 1996/10/17 04:26:25 cgd Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1994, 1995 Carnegie-Mellon University.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Author: Chris G. Demetriou
        !             9:  *
        !            10:  * Permission to use, copy, modify and distribute this software and
        !            11:  * its documentation is hereby granted, provided that both the copyright
        !            12:  * notice and this permission notice appear in all copies of the
        !            13:  * software, derivative works or modified versions, and any portions
        !            14:  * thereof, and that both notices appear in supporting documentation.
        !            15:  *
        !            16:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            17:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
        !            18:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            19:  *
        !            20:  * Carnegie Mellon requests users of this software to return to
        !            21:  *
        !            22:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
        !            23:  *  School of Computer Science
        !            24:  *  Carnegie Mellon University
        !            25:  *  Pittsburgh PA 15213-3890
        !            26:  *
        !            27:  * any improvements or extensions that they make and grant Carnegie the
        !            28:  * rights to redistribute these changes.
        !            29:  */
        !            30:
        !            31: /*
        !            32:  * Division and remainder.
        !            33:  *
        !            34:  * The use of m4 is modeled after the sparc code, but the algorithm is
        !            35:  * simple binary long division.
        !            36:  *
        !            37:  * Note that the loops could probably benefit from unrolling.
        !            38:  */
        !            39:
        !            40: /*
        !            41:  * M4 Parameters
        !            42:  * NAME                name of function to generate
        !            43:  * OP          OP=div: t10 / t11 -> t12; OP=rem: t10 % t11 -> t12
        !            44:  * S           S=true: signed; S=false: unsigned
        !            45:  * WORDSIZE    total number of bits
        !            46:  */
        !            47:
        !            48: define(A, `t10')
        !            49: define(B, `t11')
        !            50: define(RESULT, `t12')
        !            51:
        !            52: define(BIT, `t0')
        !            53: define(I, `t1')
        !            54: define(CC, `t2')
        !            55: define(T_0, `t3')
        !            56: ifelse(S, `true', `define(NEG, `t4')')
        !            57:
        !            58: #include <machine/asm.h>
        !            59:
        !            60: LEAF(NAME, 0)                                  /* XXX */
        !            61:        lda     sp, -64(sp)
        !            62:        stq     BIT, 0(sp)
        !            63:        stq     I, 8(sp)
        !            64:        stq     CC, 16(sp)
        !            65:        stq     T_0, 24(sp)
        !            66: ifelse(S, `true',
        !            67: `      stq     NEG, 32(sp)')
        !            68:        stq     A, 40(sp)
        !            69:        stq     B, 48(sp)
        !            70:        mov     zero, RESULT                    /* Initialize result to zero */
        !            71:
        !            72: ifelse(S, `true',
        !            73: `
        !            74:        /* Compute sign of result.  If either is negative, this is easy.  */
        !            75:        or      A, B, NEG                       /* not the sign, but... */
        !            76:        srl     NEG, WORDSIZE - 1, NEG          /* rather, or of high bits */
        !            77:        blbc    NEG, Ldoit                      /* neither negative? do it! */
        !            78:
        !            79: ifelse(OP, `div',
        !            80: `      xor     A, B, NEG                       /* THIS is the sign! */
        !            81: ', `   mov     A, NEG                          /* sign follows A. */
        !            82: ')
        !            83:        srl     NEG, WORDSIZE - 1, NEG          /* make negation the low bit. */
        !            84:
        !            85:        srl     A, WORDSIZE - 1, I              /* is A negative? */
        !            86:        blbc    I, LnegB                        /* no. */
        !            87:        /* A is negative; flip it. */
        !            88: ifelse(WORDSIZE, `32', `
        !            89:        /* top 32 bits may be random junk */
        !            90:        zap     A, 0xf0, A
        !            91: ')
        !            92:        subq    zero, A, A
        !            93:        srl     B, WORDSIZE - 1, I              /* is B negative? */
        !            94:        blbc    I, Ldoit                        /* no. */
        !            95: LnegB:
        !            96:        /* B is definitely negative, no matter how we got here. */
        !            97: ifelse(WORDSIZE, `32', `
        !            98:        /* top 32 bits may be random junk */
        !            99:        zap     B, 0xf0, B
        !           100: ')
        !           101:        subq    zero, B, B
        !           102: Ldoit:
        !           103: ')
        !           104: ifelse(WORDSIZE, `32', `
        !           105:        /*
        !           106:         * Clear the top 32 bits of each operand, as they may
        !           107:         * sign extension (if negated above), or random junk.
        !           108:         */
        !           109:        zap     A, 0xf0, A
        !           110:        zap     B, 0xf0, B
        !           111: ')
        !           112:
        !           113:        /* kill the special cases. */
        !           114:        beq     B, Ldotrap                      /* division by zero! */
        !           115:
        !           116:        cmpult  A, B, CC                        /* A < B? */
        !           117:        /* RESULT is already zero, from above.  A is untouched. */
        !           118:        bne     CC, Lret_result
        !           119:
        !           120:        cmpeq   A, B, CC                        /* A == B? */
        !           121:        cmovne  CC, 1, RESULT
        !           122:        cmovne  CC, zero, A
        !           123:        bne     CC, Lret_result
        !           124:
        !           125:        /*
        !           126:         * Find out how many bits of zeros are at the beginning of the divisor.
        !           127:         */
        !           128: LBbits:
        !           129:        ldiq    T_0, 1                          /* I = 0; BIT = 1<<WORDSIZE-1 */
        !           130:        mov     zero, I
        !           131:        sll     T_0, WORDSIZE-1, BIT
        !           132: LBloop:
        !           133:        and     B, BIT, CC                      /* if bit in B is set, done. */
        !           134:        bne     CC, LAbits
        !           135:        addq    I, 1, I                         /* increment I, shift bit */
        !           136:        srl     BIT, 1, BIT
        !           137:        cmplt   I, WORDSIZE-1, CC               /* if I leaves one bit, done. */
        !           138:        bne     CC, LBloop
        !           139:
        !           140: LAbits:
        !           141:        beq     I, Ldodiv                       /* If I = 0, divide now.  */
        !           142:        ldiq    T_0, 1                          /* BIT = 1<<WORDSIZE-1 */
        !           143:        sll     T_0, WORDSIZE-1, BIT
        !           144:
        !           145: LAloop:
        !           146:        and     A, BIT, CC                      /* if bit in A is set, done. */
        !           147:        bne     CC, Ldodiv
        !           148:        subq    I, 1, I                         /* decrement I, shift bit */
        !           149:        srl     BIT, 1, BIT
        !           150:        bne     I, LAloop                       /* If I != 0, loop again */
        !           151:
        !           152: Ldodiv:
        !           153:        sll     B, I, B                         /* B <<= i */
        !           154:        ldiq    T_0, 1
        !           155:        sll     T_0, I, BIT
        !           156:
        !           157: Ldivloop:
        !           158:        cmpult  A, B, CC
        !           159:        or      RESULT, BIT, T_0
        !           160:        cmoveq  CC, T_0, RESULT
        !           161:        subq    A, B, T_0
        !           162:        cmoveq  CC, T_0, A
        !           163:        srl     BIT, 1, BIT
        !           164:        srl     B, 1, B
        !           165:        beq     A, Lret_result
        !           166:        bne     BIT, Ldivloop
        !           167:
        !           168: Lret_result:
        !           169: ifelse(OP, `div',
        !           170: `', `  mov     A, RESULT
        !           171: ')
        !           172: ifelse(S, `true',
        !           173: `
        !           174:        /* Check to see if we should negate it. */
        !           175:        subqv   zero, RESULT, T_0
        !           176:        cmovlbs NEG, T_0, RESULT
        !           177: ')
        !           178:
        !           179:        ldq     BIT, 0(sp)
        !           180:        ldq     I, 8(sp)
        !           181:        ldq     CC, 16(sp)
        !           182:        ldq     T_0, 24(sp)
        !           183: ifelse(S, `true',
        !           184: `      ldq     NEG, 32(sp)')
        !           185:        ldq     A, 40(sp)
        !           186:        ldq     B, 48(sp)
        !           187:        lda     sp, 64(sp)
        !           188:        ret     zero, (t9), 1
        !           189:
        !           190: Ldotrap:
        !           191:        ldiq    a0, -2                  /* This is the signal to SIGFPE! */
        !           192:        call_pal PAL_gentrap
        !           193: ifelse(OP, `div',
        !           194: `', `  mov     zero, A                 /* so that zero will be returned */
        !           195: ')
        !           196:        br      zero, Lret_result
        !           197:
        !           198: END(NAME)

CVSweb