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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i386/] [math-emu/] [fpu_etc.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*---------------------------------------------------------------------------+
2
 |  fpu_etc.c                                                                |
3
 |                                                                           |
4
 | Implement a few FPU instructions.                                         |
5
 |                                                                           |
6
 | Copyright (C) 1992,1993,1994                                              |
7
 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
8
 |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
9
 |                                                                           |
10
 |                                                                           |
11
 +---------------------------------------------------------------------------*/
12
 
13
#include "fpu_system.h"
14
#include "exception.h"
15
#include "fpu_emu.h"
16
#include "status_w.h"
17
#include "reg_constant.h"
18
 
19
 
20
static void fchs(FPU_REG *st0_ptr)
21
{
22
  if ( st0_ptr->tag ^ TW_Empty )
23
    {
24
      st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
25
      clear_C1();
26
    }
27
  else
28
    stack_underflow();
29
}
30
 
31
static void fabs(FPU_REG *st0_ptr)
32
{
33
  if ( st0_ptr->tag ^ TW_Empty )
34
    {
35
      st0_ptr->sign = SIGN_POS;
36
      clear_C1();
37
    }
38
  else
39
    stack_underflow();
40
}
41
 
42
 
43
static void ftst_(FPU_REG *st0_ptr)
44
{
45
  switch (st0_ptr->tag)
46
    {
47
    case TW_Zero:
48
      setcc(SW_C3);
49
      break;
50
    case TW_Valid:
51
      if (st0_ptr->sign == SIGN_POS)
52
        setcc(0);
53
      else
54
        setcc(SW_C0);
55
 
56
#ifdef DENORM_OPERAND
57
      if ( (st0_ptr->exp <= EXP_UNDER) && (denormal_operand()) )
58
        {
59
#ifdef PECULIAR_486
60
          /* This is weird! */
61
          if (st0_ptr->sign == SIGN_POS)
62
            setcc(SW_C3);
63
#endif PECULIAR_486
64
          return;
65
        }
66
#endif DENORM_OPERAND
67
 
68
      break;
69
    case TW_NaN:
70
      setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */
71
      EXCEPTION(EX_Invalid);
72
      break;
73
    case TW_Infinity:
74
      if (st0_ptr->sign == SIGN_POS)
75
        setcc(0);
76
      else
77
        setcc(SW_C0);
78
      break;
79
    case TW_Empty:
80
      setcc(SW_C0|SW_C2|SW_C3);
81
      EXCEPTION(EX_StackUnder);
82
      break;
83
    default:
84
      setcc(SW_C0|SW_C2|SW_C3);   /* Operand is not comparable */
85
      EXCEPTION(EX_INTERNAL|0x14);
86
      break;
87
    }
88
}
89
 
90
static void fxam(FPU_REG *st0_ptr)
91
{
92
  int c=0;
93
  switch (st0_ptr->tag)
94
    {
95
    case TW_Empty:
96
      c = SW_C3|SW_C0;
97
      break;
98
    case TW_Zero:
99
      c = SW_C3;
100
      break;
101
    case TW_Valid:
102
      /* This will need to be changed if TW_Denormal is ever used. */
103
      if ( st0_ptr->exp <= EXP_UNDER )
104
        c = SW_C2|SW_C3;  /* Denormal */
105
      else
106
        c = SW_C2;
107
      break;
108
    case TW_NaN:
109
      c = SW_C0;
110
      break;
111
    case TW_Infinity:
112
      c = SW_C2|SW_C0;
113
      break;
114
    }
115
  if (st0_ptr->sign == SIGN_NEG)
116
    c |= SW_C1;
117
  setcc(c);
118
}
119
 
120
 
121
static FUNC_ST0 const fp_etc_table[] = {
122
  fchs, fabs, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal,
123
  ftst_, fxam, (FUNC_ST0)FPU_illegal, (FUNC_ST0)FPU_illegal
124
};
125
 
126
void fp_etc()
127
{
128
  (fp_etc_table[FPU_rm])(&st(0));
129
}

powered by: WebSVN 2.1.0

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