1 /*---------------------------------------------------------------------------+
2  |  fpu_tags.c                                                               |
3  |                                                                           |
4  |  Set FPU register tags.                                                   |
5  |                                                                           |
6  | Copyright (C) 1997                                                        |
7  |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
8  |                  E-mail   billm@jacobi.maths.monash.edu.au                |
9  |                                                                           |
10  |                                                                           |
11  +---------------------------------------------------------------------------*/
12 
13 #include "fpu_emu.h"
14 #include "fpu_system.h"
15 #include "exception.h"
16 
17 
FPU_pop(void)18 void FPU_pop(void)
19 {
20   fpu_tag_word |= 3 << ((top & 7)*2);
21   top++;
22 }
23 
24 
FPU_gettag0(void)25 int FPU_gettag0(void)
26 {
27   return (fpu_tag_word >> ((top & 7)*2)) & 3;
28 }
29 
30 
FPU_gettagi(int stnr)31 int FPU_gettagi(int stnr)
32 {
33   return (fpu_tag_word >> (((top+stnr) & 7)*2)) & 3;
34 }
35 
36 
FPU_gettag(int regnr)37 int FPU_gettag(int regnr)
38 {
39   return (fpu_tag_word >> ((regnr & 7)*2)) & 3;
40 }
41 
42 
FPU_settag0(int tag)43 void FPU_settag0(int tag)
44 {
45   int regnr = top;
46   regnr &= 7;
47   fpu_tag_word &= ~(3 << (regnr*2));
48   fpu_tag_word |= (tag & 3) << (regnr*2);
49 }
50 
51 
FPU_settagi(int stnr,int tag)52 void FPU_settagi(int stnr, int tag)
53 {
54   int regnr = stnr+top;
55   regnr &= 7;
56   fpu_tag_word &= ~(3 << (regnr*2));
57   fpu_tag_word |= (tag & 3) << (regnr*2);
58 }
59 
60 
FPU_settag(int regnr,int tag)61 void FPU_settag(int regnr, int tag)
62 {
63   regnr &= 7;
64   fpu_tag_word &= ~(3 << (regnr*2));
65   fpu_tag_word |= (tag & 3) << (regnr*2);
66 }
67 
68 
FPU_Special(FPU_REG const * ptr)69 int FPU_Special(FPU_REG const *ptr)
70 {
71   int exp = exponent(ptr);
72 
73   if ( exp == EXP_BIAS+EXP_UNDER )
74     return TW_Denormal;
75   else if ( exp != EXP_BIAS+EXP_OVER )
76     return TW_NaN;
77   else if ( (ptr->sigh == 0x80000000) && (ptr->sigl == 0) )
78     return TW_Infinity;
79   return TW_NaN;
80 }
81 
82 
isNaN(FPU_REG const * ptr)83 int isNaN(FPU_REG const *ptr)
84 {
85   return ( (exponent(ptr) == EXP_BIAS+EXP_OVER)
86 	   && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0)) );
87 }
88 
89 
FPU_empty_i(int stnr)90 int FPU_empty_i(int stnr)
91 {
92   int regnr = (top+stnr) & 7;
93 
94   return ((fpu_tag_word >> (regnr*2)) & 3) == TAG_Empty;
95 }
96 
97 
FPU_stackoverflow(FPU_REG ** st_new_ptr)98 int FPU_stackoverflow(FPU_REG **st_new_ptr)
99 {
100   *st_new_ptr = &st(-1);
101 
102   return ((fpu_tag_word >> (((top - 1) & 7)*2)) & 3) != TAG_Empty;
103 }
104 
105 
FPU_copy_to_regi(FPU_REG const * r,u_char tag,int stnr)106 void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr)
107 {
108   reg_copy(r, &st(stnr));
109   FPU_settagi(stnr, tag);
110 }
111 
FPU_copy_to_reg1(FPU_REG const * r,u_char tag)112 void FPU_copy_to_reg1(FPU_REG const *r, u_char tag)
113 {
114   reg_copy(r, &st(1));
115   FPU_settagi(1, tag);
116 }
117 
FPU_copy_to_reg0(FPU_REG const * r,u_char tag)118 void FPU_copy_to_reg0(FPU_REG const *r, u_char tag)
119 {
120   int regnr = top;
121   regnr &= 7;
122 
123   reg_copy(r, &st(0));
124 
125   fpu_tag_word &= ~(3 << (regnr*2));
126   fpu_tag_word |= (tag & 3) << (regnr*2);
127 }
128