OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i386/] [math-emu/] [reg_mul.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*---------------------------------------------------------------------------+
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,1993                                                   |
7
 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
8
 |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
9
 |                                                                           |
10
 |                                                                           |
11
 +---------------------------------------------------------------------------*/
12
 
13
/*---------------------------------------------------------------------------+
14
 | The destination may be any FPU_REG, including one of the source FPU_REGs. |
15
 +---------------------------------------------------------------------------*/
16
 
17
#include "exception.h"
18
#include "reg_constant.h"
19
#include "fpu_emu.h"
20
#include "fpu_system.h"
21
 
22
 
23
/* This routine must be called with non-empty source registers */
24
int reg_mul(FPU_REG const *a, FPU_REG const *b,
25
            FPU_REG *dest, unsigned int control_w)
26
{
27
  char saved_sign = dest->sign;
28
  char sign = (a->sign ^ b->sign);
29
 
30
  if (!(a->tag | b->tag))
31
    {
32
      /* Both regs Valid, this should be the most common case. */
33
      dest->sign = sign;
34
      if ( reg_u_mul(a, b, dest, control_w) )
35
        {
36
          dest->sign = saved_sign;
37
          return 1;
38
        }
39
      return 0;
40
    }
41
  else if ((a->tag <= TW_Zero) && (b->tag <= TW_Zero))
42
    {
43
#ifdef DENORM_OPERAND
44
      if ( ((b->tag == TW_Valid) && (b->exp <= EXP_UNDER)) ||
45
          ((a->tag == TW_Valid) && (a->exp <= EXP_UNDER)) )
46
        {
47
          if ( denormal_operand() ) return 1;
48
        }
49
#endif DENORM_OPERAND
50
      /* Must have either both arguments == zero, or
51
         one valid and the other zero.
52
         The result is therefore zero. */
53
      reg_move(&CONST_Z, dest);
54
      /* The 80486 book says that the answer is +0, but a real
55
         80486 behaves this way.
56
         IEEE-754 apparently says it should be this way. */
57
      dest->sign = sign;
58
      return 0;
59
    }
60
  else
61
    {
62
      /* Must have infinities, NaNs, etc */
63
      if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )
64
        { return real_2op_NaN(a, b, dest); }
65
      else if (a->tag == TW_Infinity)
66
        {
67
          if (b->tag == TW_Zero)
68
            { return arith_invalid(dest); }  /* Zero*Infinity is invalid */
69
          else
70
            {
71
#ifdef DENORM_OPERAND
72
              if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&
73
                  denormal_operand() )
74
                return 1;
75
#endif DENORM_OPERAND
76
              reg_move(a, dest);
77
              dest->sign = sign;
78
            }
79
          return 0;
80
        }
81
      else if (b->tag == TW_Infinity)
82
        {
83
          if (a->tag == TW_Zero)
84
            { return arith_invalid(dest); }  /* Zero*Infinity is invalid */
85
          else
86
            {
87
#ifdef DENORM_OPERAND
88
              if ( (a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&
89
                  denormal_operand() )
90
                return 1;
91
#endif DENORM_OPERAND
92
              reg_move(b, dest);
93
              dest->sign = sign;
94
            }
95
          return 0;
96
        }
97
#ifdef PARANOID
98
      else
99
        {
100
          EXCEPTION(EX_INTERNAL|0x102);
101
          return 1;
102
        }
103
#endif PARANOID
104
    }
105
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.