Annotation of coherent/b/kernel/emulator/reg_mul.c, revision 1.1.1.1

1.1       root        1: /*---------------------------------------------------------------------------+
                      2:  |  reg_mul.c                                                                |
                      3:  |                                                                           |
                      4:  | Multiply one FPU_REG by another, put the result in a destination FPU_REG. |
                      5:  |                                                                           |
                      6:  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
                      7:  |                       Australia.  E-mail [email protected]    |
                      8:  |                                                                           |
                      9:  |                                                                           |
                     10:  +---------------------------------------------------------------------------*/
                     11: 
                     12: /*---------------------------------------------------------------------------+
                     13:  | The destination may be any FPU_REG, including one of the source FPU_REGs. |
                     14:  +---------------------------------------------------------------------------*/
                     15: 
                     16: #include "fpu_system.h"
                     17: #include "exception.h"
                     18: #include "reg_constant.h"
                     19: #include "fpu_emu.h"
                     20: 
                     21: 
                     22: /* This routine must be called with non-empty registers */
                     23: void reg_mul(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
                     24: {
                     25:   if (!(a->tag | b->tag))
                     26:     {
                     27:       /* This should be the most common case */
                     28:       reg_u_mul(a, b, dest);
                     29:       dest->exp += - EXP_BIAS + 1;
                     30:       dest->sign = (a->sign ^ b->sign);
                     31:       dest->tag = TW_Valid;
                     32:       if ( dest->exp <= EXP_UNDER )
                     33:        { arith_underflow(FPU_st0_ptr); }
                     34:       else if ( dest->exp >= EXP_OVER )
                     35:        { arith_overflow(FPU_st0_ptr); }
                     36:       return;
                     37:     }
                     38:   else if ((a->tag <= TW_Zero) && (b->tag <= TW_Zero))
                     39:     {
                     40:       /* Must have either both arguments == zero, or
                     41:         one valid and the other zero.
                     42:         The result is therefore zero. */
                     43:       reg_move(&CONST_Z, dest);
                     44:     }
                     45:   else if ((a->tag <= TW_Denormal) && (b->tag <= TW_Denormal))
                     46:     {
                     47:       /* One or both arguments are de-normalized */
                     48:       /* Internal de-normalized numbers are not supported yet */
                     49:       EXCEPTION(EX_INTERNAL|0x105);
                     50:       reg_move(&CONST_Z, dest);
                     51:     }
                     52:   else
                     53:     {
                     54:       /* Must have infinities, NaNs, etc */
                     55:       if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
                     56:        { real_2op_NaN(a, b, dest); return; }
                     57:       else if (a->tag == TW_Infinity)
                     58:        {
                     59:          if (b->tag == TW_Zero)
                     60:            { arith_invalid(dest); return; }
                     61:          else
                     62:            {
                     63:              reg_move(a, dest);
                     64:              dest->sign = a->sign == b->sign ? SIGN_POS : SIGN_NEG;
                     65:            }
                     66:        }
                     67:       else if (b->tag == TW_Infinity)
                     68:        {
                     69:          if (a->tag == TW_Zero)
                     70:            { arith_invalid(dest); return; }
                     71:          else
                     72:            {
                     73:              reg_move(b, dest);
                     74:              dest->sign = a->sign == b->sign ? SIGN_POS : SIGN_NEG;
                     75:            }
                     76:        }
                     77: #ifdef PARANOID
                     78:       else
                     79:        {
                     80:          EXCEPTION(EX_INTERNAL|0x102);
                     81:        }
                     82: #endif PARANOID
                     83:       dest->sign = (a->sign ^ b->sign);
                     84:     }
                     85: }

unix.superglobalmegacorp.com

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