Annotation of coherent/b/kernel/emulator/reg_mul.c, revision 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.