This source file includes following definitions.
- compare
- compare_st_data
- compare_st_st
- compare_u_st_st
- fcom_st
- fcompst
- fcompp
- fucom_
- fucomp
- fucompp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include "fpu_system.h"
17 #include "exception.h"
18 #include "fpu_emu.h"
19 #include "status_w.h"
20
21
22 int compare(FPU_REG *b)
23 {
24 int diff;
25
26 if ( FPU_st0_ptr->tag | b->tag )
27 {
28 if ( FPU_st0_ptr->tag == TW_Zero )
29 {
30 if ( b->tag == TW_Zero ) return COMP_A_EQ_B;
31 if ( b->tag == TW_Valid )
32 {
33 return (b->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B ;
34 }
35 }
36 else if ( b->tag == TW_Zero )
37 {
38 if ( FPU_st0_ptr->tag == TW_Valid )
39 {
40 return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
41 }
42 }
43
44 if ( FPU_st0_ptr->tag == TW_Infinity )
45 {
46 if ( (b->tag == TW_Valid) || (b->tag == TW_Zero) )
47 {
48 return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
49 }
50 else if ( b->tag == TW_Infinity )
51 {
52
53 return (FPU_st0_ptr->sign == b->sign) ? COMP_A_EQ_B :
54 ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B);
55 }
56
57 }
58 else if ( b->tag == TW_Infinity )
59 {
60 if ( (FPU_st0_ptr->tag == TW_Valid) || (FPU_st0_ptr->tag == TW_Zero) )
61 {
62 return (b->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B;
63 }
64
65 }
66
67
68
69 if ( (FPU_st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN) )
70 {
71 if ( ((FPU_st0_ptr->tag == TW_NaN) && !(FPU_st0_ptr->sigh & 0x40000000))
72 || ((b->tag == TW_NaN) && !(b->sigh & 0x40000000)) )
73
74 return COMP_NOCOMP | COMP_SNAN | COMP_NAN;
75 else
76
77 return COMP_NOCOMP | COMP_NAN;
78 }
79
80 EXCEPTION(EX_Invalid);
81 }
82
83 #ifdef PARANOID
84 if (!(FPU_st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
85 if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
86 #endif PARANOID
87
88 if (FPU_st0_ptr->sign != b->sign)
89 return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
90
91 diff = FPU_st0_ptr->exp - b->exp;
92 if ( diff == 0 )
93 {
94 diff = FPU_st0_ptr->sigh - b->sigh;
95 if ( diff == 0 )
96 diff = FPU_st0_ptr->sigl - b->sigl;
97 }
98
99 if ( diff > 0 )
100 return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
101 if ( diff < 0 )
102 return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B ;
103 return COMP_A_EQ_B;
104
105 }
106
107
108 void compare_st_data(void)
109 {
110 int f;
111 int c = compare(&FPU_loaded_data);
112
113 if (c & COMP_NAN)
114 {
115 EXCEPTION(EX_Invalid);
116 f = SW_C3 | SW_C2 | SW_C0;
117 }
118 else
119 switch (c)
120 {
121 case COMP_A_LT_B:
122 f = SW_C0;
123 break;
124 case COMP_A_EQ_B:
125 f = SW_C3;
126 break;
127 case COMP_A_GT_B:
128 f = 0;
129 break;
130 case COMP_NOCOMP:
131 f = SW_C3 | SW_C2 | SW_C0;
132 break;
133 #ifdef PARANOID
134 default:
135 EXCEPTION(EX_INTERNAL|0x121);
136 f = SW_C3 | SW_C2 | SW_C0;
137 break;
138 #endif PARANOID
139 }
140 setcc(f);
141 }
142
143
144 static void compare_st_st(int nr)
145 {
146 int c = compare(&st(nr));
147 int f;
148 if (c & COMP_NAN)
149 {
150 EXCEPTION(EX_Invalid);
151 f = SW_C3 | SW_C2 | SW_C0;
152 }
153 else
154 switch (c)
155 {
156 case COMP_A_LT_B:
157 f = SW_C0;
158 break;
159 case COMP_A_EQ_B:
160 f = SW_C3;
161 break;
162 case COMP_A_GT_B:
163 f = 0;
164 break;
165 case COMP_NOCOMP:
166 f = SW_C3 | SW_C2 | SW_C0;
167 break;
168 #ifdef PARANOID
169 default:
170 EXCEPTION(EX_INTERNAL|0x122);
171 f = SW_C3 | SW_C2 | SW_C0;
172 break;
173 #endif PARANOID
174 }
175 setcc(f);
176 }
177
178
179 static void compare_u_st_st(int nr)
180 {
181 int f;
182 int c = compare(&st(nr));
183 if (c & COMP_NAN)
184 {
185 if (c & COMP_SNAN)
186
187 EXCEPTION(EX_Invalid);
188 f = SW_C3 | SW_C2 | SW_C0;
189 }
190 else
191 switch (c)
192 {
193 case COMP_A_LT_B:
194 f = SW_C0;
195 break;
196 case COMP_A_EQ_B:
197 f = SW_C3;
198 break;
199 case COMP_A_GT_B:
200 f = 0;
201 break;
202 case COMP_NOCOMP:
203 f = SW_C3 | SW_C2 | SW_C0;
204 break;
205 #ifdef PARANOID
206 default:
207 EXCEPTION(EX_INTERNAL|0x123);
208 f = SW_C3 | SW_C2 | SW_C0;
209 break;
210 #endif PARANOID
211 }
212 setcc(f);
213 }
214
215
216
217 void fcom_st()
218 {
219
220 compare_st_st(FPU_rm);
221 }
222
223
224 void fcompst()
225 {
226
227 compare_st_st(FPU_rm);
228 pop();
229 }
230
231
232 void fcompp()
233 {
234
235 if (FPU_rm != 1)
236 return Un_impl();
237 compare_st_st(1);
238 pop(); FPU_st0_ptr = &st(0);
239 pop();
240 }
241
242
243 void fucom_()
244 {
245
246 compare_u_st_st(FPU_rm);
247 }
248
249
250 void fucomp()
251 {
252
253 compare_u_st_st(FPU_rm);
254 pop();
255 }
256
257
258 void fucompp()
259 {
260
261 if (FPU_rm == 1)
262 {
263 compare_u_st_st(1);
264 pop(); FPU_st0_ptr = &st(0);
265 pop();
266 }
267 else
268 Un_impl();
269 }