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

1.1       root        1: /*
                      2:  * linux/kernel/math/add.c
                      3:  *
1.1.1.2 ! root        4:  * Copyright (C) 1991, 1992 Linus Torvalds
1.1       root        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.