Annotation of GNUtools/cctools/as/flonum-mult.c, revision 1.1

1.1     ! root        1: /* flonum_multip.c - multiply two flonums
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of Gas, the GNU Assembler.
        !             5: 
        !             6: The GNU assembler is distributed in the hope that it will be
        !             7: useful, but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: accepts responsibility to anyone for the consequences of using it
        !             9: or for whether it serves any particular purpose or works at all,
        !            10: unless he says so in writing.  Refer to the GNU Assembler General
        !            11: Public License for full details.
        !            12: 
        !            13: Everyone is granted permission to copy, modify and redistribute
        !            14: the GNU Assembler, but only under the conditions described in the
        !            15: GNU Assembler General Public License.  A copy of this license is
        !            16: supposed to have been given to you along with the GNU Assembler
        !            17: so you can know your rights and responsibilities.  It should be
        !            18: in a file named COPYING.  Among other things, the copyright
        !            19: notice and this notice must be preserved on all copies.  */
        !            20: 
        !            21: #include "flonum.h"
        !            22: 
        !            23: /*     plan for a . b => p(roduct)
        !            24: 
        !            25: 
        !            26:        +-------+-------+-/   /-+-------+-------+
        !            27:        | a     | a     |  ...  | a     | a     |
        !            28:        |  A    |  A-1  |       |  1    |  0    |
        !            29:        +-------+-------+-/   /-+-------+-------+
        !            30: 
        !            31: 
        !            32:        +-------+-------+-/   /-+-------+-------+
        !            33:        | b     | b     |  ...  | b     | b     |
        !            34:        |  B    |  B-1  |       |  1    |  0    |
        !            35:        +-------+-------+-/   /-+-------+-------+
        !            36: 
        !            37: 
        !            38:        +-------+-------+-/   /-+-------+-/   /-+-------+-------+
        !            39:        | p     | p     |  ...  | p     |  ...  | p     | p     |
        !            40:        |  A+B+1|  A+B  |       |  N    |       |  1    |  0    |
        !            41:        +-------+-------+-/   /-+-------+-/   /-+-------+-------+
        !            42: 
        !            43:                                   /^\
        !            44:         (carry) a .b      ...      |      ...   a .b    a .b
        !            45:                  A  B              |             0  1    0  0
        !            46:                                    |
        !            47:                           ...      |      ...   a .b
        !            48:                                    |             1  0
        !            49:                                    |
        !            50:                                    |      ...
        !            51:                                    |
        !            52:                                    |
        !            53:                                    |
        !            54:                                    |             ___
        !            55:                                    |             \
        !            56:                                    +-----  P  =   >  a .b
        !            57:                                             N    /__  i  j
        !            58: 
        !            59:                                        N = 0 ... A+B
        !            60: 
        !            61:                                        for all i,j where i+j=N
        !            62:                                        [i,j integers > 0]
        !            63: 
        !            64: a[], b[], p[] may not intersect.
        !            65: Zero length factors signify 0 significant bits: treat as 0.0.
        !            66: 0.0 factors do the right thing.
        !            67: Zero length product OK.
        !            68: 
        !            69: I chose the ForTran accent "foo[bar]" instead of the C accent "*garply"
        !            70: because I felt the ForTran way was more intuitive. The C way would
        !            71: probably yield better code on most C compilers. Dean Elsner.
        !            72: (C style also gives deeper insight [to me] ... oh well ...)
        !            73: */
        !            74: 
        !            75: void
        !            76: flonum_multip(
        !            77: const_FLONUM_TYPE *a,
        !            78: FLONUM_TYPE *b,
        !            79: FLONUM_TYPE *product)
        !            80: {
        !            81:   int                  size_of_a;              /* 0 origin */
        !            82:   int                  size_of_b;              /* 0 origin */
        !            83:   int                  size_of_product;        /* 0 origin */
        !            84:   int                  size_of_sum;            /* 0 origin */
        !            85:   int                  extra_product_positions;/* 1 origin */
        !            86:   unsigned long int    work;
        !            87:   unsigned long int    carry;
        !            88:   long int             exponent;
        !            89:   LITTLENUM_TYPE *     q;
        !            90:   long int             significant;            /* TRUE when we emit a non-0 littlenum  */
        !            91:                                /* ForTran accent follows. */
        !            92:   int                  P;      /* Scan product low-order -> high. */
        !            93:   int                  N;      /* As in sum above.  */
        !            94:   int                  A;      /* Which [] of a? */
        !            95:   int                  B;      /* Which [] of b? */
        !            96: 
        !            97:   if((a->sign!='-' && a->sign!='+') || (b->sign!='-' && b->sign!='+')) {
        !            98:     /* ...
        !            99:     Got to fail somehow.  Any suggestions? */
        !           100:     product->sign=0;
        !           101:     return;
        !           102:   }
        !           103:   product -> sign = (a->sign == b->sign) ? '+' : '-';
        !           104:   size_of_a            = a       -> leader     -  a       -> low;
        !           105:   size_of_b            = b       -> leader     -  b       -> low;
        !           106:   exponent             = a       -> exponent   +  b       -> exponent;
        !           107:   size_of_product      = product -> high       -  product -> low;
        !           108:   size_of_sum          = size_of_a             +  size_of_b;
        !           109:   extra_product_positions  =  size_of_product  -  size_of_sum;
        !           110:   if (extra_product_positions < 0)
        !           111:     {
        !           112:       P = extra_product_positions; /* P < 0 */
        !           113:       exponent -= extra_product_positions; /* Increases exponent. */
        !           114:     }
        !           115:   else
        !           116:     {
        !           117:       P = 0;
        !           118:     }
        !           119:   carry = 0;
        !           120:   significant = 0;
        !           121:   for (N = 0;
        !           122:        N <= size_of_sum;
        !           123:        N++)
        !           124:     {
        !           125:       work = carry;
        !           126:       carry = 0;
        !           127:       for (A = 0;
        !           128:           A <= N;
        !           129:           A ++)
        !           130:        {
        !           131:          B = N - A;
        !           132:          if (A <= size_of_a   &&   B <= size_of_b  &&  B >= 0)
        !           133:            {
        !           134: #ifdef TRACE
        !           135: printf("a:low[%d.]=%04x b:low[%d.]=%04x work_before=%08x\n", A, a->low[A], B, b->low[B], work);
        !           136: #endif
        !           137:              work += a -> low [A]   *   b -> low [B];
        !           138:              carry += work >> LITTLENUM_NUMBER_OF_BITS;
        !           139:              work &= LITTLENUM_MASK;
        !           140: #ifdef TRACE
        !           141: printf("work=%08x carry=%04x\n", work, carry);
        !           142: #endif
        !           143:            }
        !           144:        }
        !           145:       significant |= work;
        !           146:       if (significant || P<0)
        !           147:        {
        !           148:          if (P >= 0)
        !           149:            {
        !           150:              product -> low [P] = work;
        !           151: #ifdef TRACE
        !           152: printf("P=%d. work[p]:=%04x\n", P, work);
        !           153: #endif
        !           154:            }
        !           155:          P ++;
        !           156:        }
        !           157:       else
        !           158:        {
        !           159:          extra_product_positions ++;
        !           160:          exponent ++;
        !           161:        }
        !           162:     }
        !           163:   /*
        !           164:    * [P]-> position # size_of_sum + 1.
        !           165:    * This is where 'carry' should go.
        !           166:    */
        !           167: #ifdef TRACE
        !           168: printf("final carry =%04x\n", carry);
        !           169: #endif
        !           170:   if (carry)
        !           171:     {
        !           172:       if (extra_product_positions > 0)
        !           173:        {
        !           174:          product -> low [P] = carry;
        !           175:        }
        !           176:       else
        !           177:        {
        !           178:          /* No room at high order for carry littlenum. */
        !           179:          /* Shift right 1 to make room for most significant littlenum. */
        !           180:          exponent ++;
        !           181:          P --;
        !           182:          for (q  = product -> low + P;
        !           183:               q >= product -> low;
        !           184:               q --)
        !           185:            {
        !           186:              work = * q;
        !           187:              * q = carry;
        !           188:              carry = work;
        !           189:            }
        !           190:        }
        !           191:     }
        !           192:   else
        !           193:     {
        !           194:       P --;
        !           195:     }
        !           196:   product -> leader    = product -> low + P;
        !           197:   product -> exponent  = exponent;
        !           198: }
        !           199: 
        !           200: /* end: flonum_multip.c */

unix.superglobalmegacorp.com

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