Annotation of linux/kernel/math/add.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * linux/kernel/math/add.c
        !             3:  *
        !             4:  * (C) 1991 Linus Torvalds
        !             5:  */
        !             6: 
        !             7: /*
        !             8:  * temporary real addition routine.
        !             9:  *
        !            10:  * NOTE! These aren't exact: they are only 62 bits wide, and don't do
        !            11:  * correct rounding. Fast hack. The reason is that we shift right the
        !            12:  * values by two, in order not to have overflow (1 bit), and to be able
        !            13:  * to move the sign into the mantissa (1 bit). Much simpler algorithms,
        !            14:  * and 62 bits (61 really - no rounding) accuracy is usually enough. The
        !            15:  * only time you should notice anything weird is when adding 64-bit
        !            16:  * integers together. When using doubles (52 bits accuracy), the
        !            17:  * 61-bit accuracy never shows at all.
        !            18:  */
        !            19: 
        !            20: #include <linux/math_emu.h>
        !            21: 
        !            22: #define NEGINT(a) \
        !            23: __asm__("notl %0 ; notl %1 ; addl $1,%0 ; adcl $0,%1" \
        !            24:        :"=r" (a->a),"=r" (a->b) \
        !            25:        :"0" (a->a),"1" (a->b))
        !            26: 
        !            27: static void signify(temp_real * a)
        !            28: {
        !            29:        a->exponent += 2;
        !            30:        __asm__("shrdl $2,%1,%0 ; shrl $2,%1"
        !            31:                :"=r" (a->a),"=r" (a->b)
        !            32:                :"0" (a->a),"1" (a->b));
        !            33:        if (a->exponent < 0)
        !            34:                NEGINT(a);
        !            35:        a->exponent &= 0x7fff;
        !            36: }
        !            37: 
        !            38: static void unsignify(temp_real * a)
        !            39: {
        !            40:        if (!(a->a || a->b)) {
        !            41:                a->exponent = 0;
        !            42:                return;
        !            43:        }
        !            44:        a->exponent &= 0x7fff;
        !            45:        if (a->b < 0) {
        !            46:                NEGINT(a);
        !            47:                a->exponent |= 0x8000;
        !            48:        }
        !            49:        while (a->b >= 0) {
        !            50:                a->exponent--;
        !            51:                __asm__("addl %0,%0 ; adcl %1,%1"
        !            52:                        :"=r" (a->a),"=r" (a->b)
        !            53:                        :"0" (a->a),"1" (a->b));
        !            54:        }
        !            55: }
        !            56: 
        !            57: void fadd(const temp_real * src1, const temp_real * src2, temp_real * result)
        !            58: {
        !            59:        temp_real a,b;
        !            60:        int x1,x2,shift;
        !            61: 
        !            62:        x1 = src1->exponent & 0x7fff;
        !            63:        x2 = src2->exponent & 0x7fff;
        !            64:        if (x1 > x2) {
        !            65:                a = *src1;
        !            66:                b = *src2;
        !            67:                shift = x1-x2;
        !            68:        } else {
        !            69:                a = *src2;
        !            70:                b = *src1;
        !            71:                shift = x2-x1;
        !            72:        }
        !            73:        if (shift >= 64) {
        !            74:                *result = a;
        !            75:                return;
        !            76:        }
        !            77:        if (shift >= 32) {
        !            78:                b.a = b.b;
        !            79:                b.b = 0;
        !            80:                shift -= 32;
        !            81:        }
        !            82:        __asm__("shrdl %4,%1,%0 ; shrl %4,%1"
        !            83:                :"=r" (b.a),"=r" (b.b)
        !            84:                :"0" (b.a),"1" (b.b),"c" ((char) shift));
        !            85:        signify(&a);
        !            86:        signify(&b);
        !            87:        __asm__("addl %4,%0 ; adcl %5,%1"
        !            88:                :"=r" (a.a),"=r" (a.b)
        !            89:                :"0" (a.a),"1" (a.b),"g" (b.a),"g" (b.b));
        !            90:        unsignify(&a);
        !            91:        *result = a;
        !            92: }

unix.superglobalmegacorp.com

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