Annotation of linux/kernel/math/div.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * linux/kernel/math/div.c
                      3:  *
                      4:  * (C) 1991 Linus Torvalds
                      5:  */
                      6: 
                      7: /*
                      8:  * temporary real division routine.
                      9:  */
                     10: 
                     11: #include <linux/math_emu.h>
                     12: 
                     13: static void shift_left(int * c)
                     14: {
                     15:        __asm__ __volatile__("movl (%0),%%eax ; addl %%eax,(%0)\n\t"
                     16:                "movl 4(%0),%%eax ; adcl %%eax,4(%0)\n\t"
                     17:                "movl 8(%0),%%eax ; adcl %%eax,8(%0)\n\t"
                     18:                "movl 12(%0),%%eax ; adcl %%eax,12(%0)"
                     19:                ::"r" ((long) c):"ax");
                     20: }
                     21: 
                     22: static void shift_right(int * c)
                     23: {
                     24:        __asm__("shrl $1,12(%0) ; rcrl $1,8(%0) ; rcrl $1,4(%0) ; rcrl $1,(%0)"
                     25:                ::"r" ((long) c));
                     26: }
                     27: 
                     28: static int try_sub(int * a, int * b)
                     29: {
                     30:        char ok;
                     31: 
                     32:        __asm__ __volatile__("movl (%1),%%eax ; subl %%eax,(%2)\n\t"
                     33:                "movl 4(%1),%%eax ; sbbl %%eax,4(%2)\n\t"
                     34:                "movl 8(%1),%%eax ; sbbl %%eax,8(%2)\n\t"
                     35:                "movl 12(%1),%%eax ; sbbl %%eax,12(%2)\n\t"
                     36:                "setae %%al":"=a" (ok):"c" ((long) a),"d" ((long) b));
                     37:        return ok;
                     38: }
                     39: 
                     40: static void div64(int * a, int * b, int * c)
                     41: {
                     42:        int tmp[4];
                     43:        int i;
                     44:        unsigned int mask = 0;
                     45: 
                     46:        c += 4;
                     47:        for (i = 0 ; i<64 ; i++) {
                     48:                if (!(mask >>= 1)) {
                     49:                        c--;
                     50:                        mask = 0x80000000;
                     51:                }
                     52:                tmp[0] = a[0]; tmp[1] = a[1];
                     53:                tmp[2] = a[2]; tmp[3] = a[3];
                     54:                if (try_sub(b,tmp)) {
                     55:                        *c |= mask;
                     56:                        a[0] = tmp[0]; a[1] = tmp[1];
                     57:                        a[2] = tmp[2]; a[3] = tmp[3];
                     58:                }
                     59:                shift_right(b);
                     60:        }
                     61: }
                     62: 
                     63: void fdiv(const temp_real * src1, const temp_real * src2, temp_real * result)
                     64: {
                     65:        int i,sign;
                     66:        int a[4],b[4],tmp[4] = {0,0,0,0};
                     67: 
                     68:        sign = (src1->exponent ^ src2->exponent) & 0x8000;
                     69:        if (!(src2->a || src2->b)) {
                     70:                set_ZE();
                     71:                return;
                     72:        }
                     73:        i = (src1->exponent & 0x7fff) - (src2->exponent & 0x7fff) + 16383;
                     74:        if (i<0) {
                     75:                set_UE();
                     76:                result->exponent = sign;
                     77:                result->a = result->b = 0;
                     78:                return;
                     79:        }
                     80:        a[0] = a[1] = 0;
                     81:        a[2] = src1->a;
                     82:        a[3] = src1->b;
                     83:        b[0] = b[1] = 0;
                     84:        b[2] = src2->a;
                     85:        b[3] = src2->b;
                     86:        while (b[3] >= 0) {
                     87:                i++;
                     88:                shift_left(b);
                     89:        }
                     90:        div64(a,b,tmp);
                     91:        if (tmp[0] || tmp[1] || tmp[2] || tmp[3]) {
                     92:                while (i && tmp[3] >= 0) {
                     93:                        i--;
                     94:                        shift_left(tmp);
                     95:                }
                     96:                if (tmp[3] >= 0)
                     97:                        set_DE();
                     98:        } else
                     99:                i = 0;
                    100:        if (i>0x7fff) {
                    101:                set_OE();
                    102:                return;
                    103:        }
                    104:        if (tmp[0] || tmp[1])
                    105:                set_PE();
                    106:        result->exponent = i | sign;
                    107:        result->a = tmp[2];
                    108:        result->b = tmp[3];
                    109: }

unix.superglobalmegacorp.com

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