1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "qemu/osdep.h"
24#include "cpu.h"
25#include "internal.h"
26#include "exec/helper-proto.h"
27#include "exec/exec-all.h"
28#include "exec/cpu_ldst.h"
29#include "fpu/softfloat.h"
30#include "fpu_helper.h"
31
32
33
34
35#define FLOAT_TWO32 make_float32(1 << 30)
36#define FLOAT_TWO64 make_float64(1ULL << 62)
37
38#define FP_TO_INT32_OVERFLOW 0x7fffffff
39#define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
40
41target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
42{
43 target_ulong arg1 = 0;
44
45 switch (reg) {
46 case 0:
47 arg1 = (int32_t)env->active_fpu.fcr0;
48 break;
49 case 1:
50
51 if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
52 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
53 arg1 = (int32_t)
54 ((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR);
55 } else {
56 do_raise_exception(env, EXCP_RI, GETPC());
57 }
58 }
59 break;
60 case 5:
61
62 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
63 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
64 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
65 } else {
66 helper_raise_exception(env, EXCP_RI);
67 }
68 }
69 break;
70 case 25:
71 arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
72 ((env->active_fpu.fcr31 >> 23) & 0x1);
73 break;
74 case 26:
75 arg1 = env->active_fpu.fcr31 & 0x0003f07c;
76 break;
77 case 28:
78 arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
79 ((env->active_fpu.fcr31 >> 22) & 0x4);
80 break;
81 default:
82 arg1 = (int32_t)env->active_fpu.fcr31;
83 break;
84 }
85
86 return arg1;
87}
88
89void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
90{
91 switch (fs) {
92 case 1:
93
94 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
95 return;
96 }
97 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
98 env->CP0_Status &= ~(1 << CP0St_FR);
99 compute_hflags(env);
100 } else {
101 do_raise_exception(env, EXCP_RI, GETPC());
102 }
103 break;
104 case 4:
105
106 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
107 return;
108 }
109 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
110 env->CP0_Status |= (1 << CP0St_FR);
111 compute_hflags(env);
112 } else {
113 do_raise_exception(env, EXCP_RI, GETPC());
114 }
115 break;
116 case 5:
117
118 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
119 return;
120 }
121 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
122 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
123 compute_hflags(env);
124 } else {
125 helper_raise_exception(env, EXCP_RI);
126 }
127 break;
128 case 6:
129
130 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
131 return;
132 }
133 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
134 env->CP0_Config5 |= (1 << CP0C5_FRE);
135 compute_hflags(env);
136 } else {
137 helper_raise_exception(env, EXCP_RI);
138 }
139 break;
140 case 25:
141 if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) {
142 return;
143 }
144 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
145 ((arg1 & 0xfe) << 24) |
146 ((arg1 & 0x1) << 23);
147 break;
148 case 26:
149 if (arg1 & 0x007c0000) {
150 return;
151 }
152 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
153 (arg1 & 0x0003f07c);
154 break;
155 case 28:
156 if (arg1 & 0x007c0000) {
157 return;
158 }
159 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
160 (arg1 & 0x00000f83) |
161 ((arg1 & 0x4) << 22);
162 break;
163 case 31:
164 env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
165 (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
166 break;
167 default:
168 if (env->insn_flags & ISA_MIPS_R6) {
169 do_raise_exception(env, EXCP_RI, GETPC());
170 }
171 return;
172 }
173 restore_fp_status(env);
174 set_float_exception_flags(0, &env->active_fpu.fp_status);
175 if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
176 GET_FP_CAUSE(env->active_fpu.fcr31)) {
177 do_raise_exception(env, EXCP_FPE, GETPC());
178 }
179}
180
181static inline int ieee_to_mips_xcpt(int ieee_xcpt)
182{
183 int mips_xcpt = 0;
184
185 if (ieee_xcpt & float_flag_invalid) {
186 mips_xcpt |= FP_INVALID;
187 }
188 if (ieee_xcpt & float_flag_overflow) {
189 mips_xcpt |= FP_OVERFLOW;
190 }
191 if (ieee_xcpt & float_flag_underflow) {
192 mips_xcpt |= FP_UNDERFLOW;
193 }
194 if (ieee_xcpt & float_flag_divbyzero) {
195 mips_xcpt |= FP_DIV0;
196 }
197 if (ieee_xcpt & float_flag_inexact) {
198 mips_xcpt |= FP_INEXACT;
199 }
200
201 return mips_xcpt;
202}
203
204static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
205{
206 int ieee_exception_flags = get_float_exception_flags(
207 &env->active_fpu.fp_status);
208 int mips_exception_flags = 0;
209
210 if (ieee_exception_flags) {
211 mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
212 }
213
214 SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
215
216 if (mips_exception_flags) {
217 set_float_exception_flags(0, &env->active_fpu.fp_status);
218
219 if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
220 do_raise_exception(env, EXCP_FPE, pc);
221 } else {
222 UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
223 }
224 }
225}
226
227
228
229
230
231
232
233
234
235uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
236{
237 fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
238 update_fcr31(env, GETPC());
239 return fdt0;
240}
241
242uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
243{
244 fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
245 update_fcr31(env, GETPC());
246 return fst0;
247}
248
249uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
250{
251 uint64_t fdt2;
252
253 fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
254 update_fcr31(env, GETPC());
255 return fdt2;
256}
257
258uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
259{
260 uint64_t fdt2;
261
262 fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
263 update_fcr31(env, GETPC());
264 return fdt2;
265}
266
267uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
268{
269 uint64_t fdt2;
270
271 fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
272 update_fcr31(env, GETPC());
273 return fdt2;
274}
275
276uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
277{
278 uint64_t dt2;
279
280 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
281 if (get_float_exception_flags(&env->active_fpu.fp_status)
282 & (float_flag_invalid | float_flag_overflow)) {
283 dt2 = FP_TO_INT64_OVERFLOW;
284 }
285 update_fcr31(env, GETPC());
286 return dt2;
287}
288
289uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
290{
291 uint64_t dt2;
292
293 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
294 if (get_float_exception_flags(&env->active_fpu.fp_status)
295 & (float_flag_invalid | float_flag_overflow)) {
296 dt2 = FP_TO_INT64_OVERFLOW;
297 }
298 update_fcr31(env, GETPC());
299 return dt2;
300}
301
302uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
303{
304 uint32_t fst2;
305 uint32_t fsth2;
306
307 fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
308 fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
309 update_fcr31(env, GETPC());
310 return ((uint64_t)fsth2 << 32) | fst2;
311}
312
313uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
314{
315 uint32_t wt2;
316 uint32_t wth2;
317 int excp, excph;
318
319 wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
320 excp = get_float_exception_flags(&env->active_fpu.fp_status);
321 if (excp & (float_flag_overflow | float_flag_invalid)) {
322 wt2 = FP_TO_INT32_OVERFLOW;
323 }
324
325 set_float_exception_flags(0, &env->active_fpu.fp_status);
326 wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
327 excph = get_float_exception_flags(&env->active_fpu.fp_status);
328 if (excph & (float_flag_overflow | float_flag_invalid)) {
329 wth2 = FP_TO_INT32_OVERFLOW;
330 }
331
332 set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
333 update_fcr31(env, GETPC());
334
335 return ((uint64_t)wth2 << 32) | wt2;
336}
337
338uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
339{
340 uint32_t fst2;
341
342 fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
343 update_fcr31(env, GETPC());
344 return fst2;
345}
346
347uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
348{
349 uint32_t fst2;
350
351 fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
352 update_fcr31(env, GETPC());
353 return fst2;
354}
355
356uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
357{
358 uint32_t fst2;
359
360 fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
361 update_fcr31(env, GETPC());
362 return fst2;
363}
364
365uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
366{
367 uint32_t wt2;
368
369 wt2 = wt0;
370 update_fcr31(env, GETPC());
371 return wt2;
372}
373
374uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
375{
376 uint32_t wt2;
377
378 wt2 = wth0;
379 update_fcr31(env, GETPC());
380 return wt2;
381}
382
383uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
384{
385 uint32_t wt2;
386
387 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
388 if (get_float_exception_flags(&env->active_fpu.fp_status)
389 & (float_flag_invalid | float_flag_overflow)) {
390 wt2 = FP_TO_INT32_OVERFLOW;
391 }
392 update_fcr31(env, GETPC());
393 return wt2;
394}
395
396uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
397{
398 uint32_t wt2;
399
400 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
401 if (get_float_exception_flags(&env->active_fpu.fp_status)
402 & (float_flag_invalid | float_flag_overflow)) {
403 wt2 = FP_TO_INT32_OVERFLOW;
404 }
405 update_fcr31(env, GETPC());
406 return wt2;
407}
408
409uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
410{
411 uint64_t dt2;
412
413 set_float_rounding_mode(float_round_nearest_even,
414 &env->active_fpu.fp_status);
415 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
416 restore_rounding_mode(env);
417 if (get_float_exception_flags(&env->active_fpu.fp_status)
418 & (float_flag_invalid | float_flag_overflow)) {
419 dt2 = FP_TO_INT64_OVERFLOW;
420 }
421 update_fcr31(env, GETPC());
422 return dt2;
423}
424
425uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
426{
427 uint64_t dt2;
428
429 set_float_rounding_mode(float_round_nearest_even,
430 &env->active_fpu.fp_status);
431 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
432 restore_rounding_mode(env);
433 if (get_float_exception_flags(&env->active_fpu.fp_status)
434 & (float_flag_invalid | float_flag_overflow)) {
435 dt2 = FP_TO_INT64_OVERFLOW;
436 }
437 update_fcr31(env, GETPC());
438 return dt2;
439}
440
441uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
442{
443 uint32_t wt2;
444
445 set_float_rounding_mode(float_round_nearest_even,
446 &env->active_fpu.fp_status);
447 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
448 restore_rounding_mode(env);
449 if (get_float_exception_flags(&env->active_fpu.fp_status)
450 & (float_flag_invalid | float_flag_overflow)) {
451 wt2 = FP_TO_INT32_OVERFLOW;
452 }
453 update_fcr31(env, GETPC());
454 return wt2;
455}
456
457uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
458{
459 uint32_t wt2;
460
461 set_float_rounding_mode(float_round_nearest_even,
462 &env->active_fpu.fp_status);
463 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
464 restore_rounding_mode(env);
465 if (get_float_exception_flags(&env->active_fpu.fp_status)
466 & (float_flag_invalid | float_flag_overflow)) {
467 wt2 = FP_TO_INT32_OVERFLOW;
468 }
469 update_fcr31(env, GETPC());
470 return wt2;
471}
472
473uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
474{
475 uint64_t dt2;
476
477 dt2 = float64_to_int64_round_to_zero(fdt0,
478 &env->active_fpu.fp_status);
479 if (get_float_exception_flags(&env->active_fpu.fp_status)
480 & (float_flag_invalid | float_flag_overflow)) {
481 dt2 = FP_TO_INT64_OVERFLOW;
482 }
483 update_fcr31(env, GETPC());
484 return dt2;
485}
486
487uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
488{
489 uint64_t dt2;
490
491 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
492 if (get_float_exception_flags(&env->active_fpu.fp_status)
493 & (float_flag_invalid | float_flag_overflow)) {
494 dt2 = FP_TO_INT64_OVERFLOW;
495 }
496 update_fcr31(env, GETPC());
497 return dt2;
498}
499
500uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
501{
502 uint32_t wt2;
503
504 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
505 if (get_float_exception_flags(&env->active_fpu.fp_status)
506 & (float_flag_invalid | float_flag_overflow)) {
507 wt2 = FP_TO_INT32_OVERFLOW;
508 }
509 update_fcr31(env, GETPC());
510 return wt2;
511}
512
513uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
514{
515 uint32_t wt2;
516
517 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
518 if (get_float_exception_flags(&env->active_fpu.fp_status)
519 & (float_flag_invalid | float_flag_overflow)) {
520 wt2 = FP_TO_INT32_OVERFLOW;
521 }
522 update_fcr31(env, GETPC());
523 return wt2;
524}
525
526uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
527{
528 uint64_t dt2;
529
530 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
531 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
532 restore_rounding_mode(env);
533 if (get_float_exception_flags(&env->active_fpu.fp_status)
534 & (float_flag_invalid | float_flag_overflow)) {
535 dt2 = FP_TO_INT64_OVERFLOW;
536 }
537 update_fcr31(env, GETPC());
538 return dt2;
539}
540
541uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
542{
543 uint64_t dt2;
544
545 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
546 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
547 restore_rounding_mode(env);
548 if (get_float_exception_flags(&env->active_fpu.fp_status)
549 & (float_flag_invalid | float_flag_overflow)) {
550 dt2 = FP_TO_INT64_OVERFLOW;
551 }
552 update_fcr31(env, GETPC());
553 return dt2;
554}
555
556uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
557{
558 uint32_t wt2;
559
560 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
561 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
562 restore_rounding_mode(env);
563 if (get_float_exception_flags(&env->active_fpu.fp_status)
564 & (float_flag_invalid | float_flag_overflow)) {
565 wt2 = FP_TO_INT32_OVERFLOW;
566 }
567 update_fcr31(env, GETPC());
568 return wt2;
569}
570
571uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
572{
573 uint32_t wt2;
574
575 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
576 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
577 restore_rounding_mode(env);
578 if (get_float_exception_flags(&env->active_fpu.fp_status)
579 & (float_flag_invalid | float_flag_overflow)) {
580 wt2 = FP_TO_INT32_OVERFLOW;
581 }
582 update_fcr31(env, GETPC());
583 return wt2;
584}
585
586uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
587{
588 uint64_t dt2;
589
590 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
591 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
592 restore_rounding_mode(env);
593 if (get_float_exception_flags(&env->active_fpu.fp_status)
594 & (float_flag_invalid | float_flag_overflow)) {
595 dt2 = FP_TO_INT64_OVERFLOW;
596 }
597 update_fcr31(env, GETPC());
598 return dt2;
599}
600
601uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
602{
603 uint64_t dt2;
604
605 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
606 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
607 restore_rounding_mode(env);
608 if (get_float_exception_flags(&env->active_fpu.fp_status)
609 & (float_flag_invalid | float_flag_overflow)) {
610 dt2 = FP_TO_INT64_OVERFLOW;
611 }
612 update_fcr31(env, GETPC());
613 return dt2;
614}
615
616uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
617{
618 uint32_t wt2;
619
620 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
621 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
622 restore_rounding_mode(env);
623 if (get_float_exception_flags(&env->active_fpu.fp_status)
624 & (float_flag_invalid | float_flag_overflow)) {
625 wt2 = FP_TO_INT32_OVERFLOW;
626 }
627 update_fcr31(env, GETPC());
628 return wt2;
629}
630
631uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
632{
633 uint32_t wt2;
634
635 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
636 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
637 restore_rounding_mode(env);
638 if (get_float_exception_flags(&env->active_fpu.fp_status)
639 & (float_flag_invalid | float_flag_overflow)) {
640 wt2 = FP_TO_INT32_OVERFLOW;
641 }
642 update_fcr31(env, GETPC());
643 return wt2;
644}
645
646uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
647{
648 uint64_t dt2;
649
650 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
651 if (get_float_exception_flags(&env->active_fpu.fp_status)
652 & float_flag_invalid) {
653 if (float64_is_any_nan(fdt0)) {
654 dt2 = 0;
655 }
656 }
657 update_fcr31(env, GETPC());
658 return dt2;
659}
660
661uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
662{
663 uint64_t dt2;
664
665 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
666 if (get_float_exception_flags(&env->active_fpu.fp_status)
667 & float_flag_invalid) {
668 if (float32_is_any_nan(fst0)) {
669 dt2 = 0;
670 }
671 }
672 update_fcr31(env, GETPC());
673 return dt2;
674}
675
676uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
677{
678 uint32_t wt2;
679
680 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
681 if (get_float_exception_flags(&env->active_fpu.fp_status)
682 & float_flag_invalid) {
683 if (float64_is_any_nan(fdt0)) {
684 wt2 = 0;
685 }
686 }
687 update_fcr31(env, GETPC());
688 return wt2;
689}
690
691uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
692{
693 uint32_t wt2;
694
695 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
696 if (get_float_exception_flags(&env->active_fpu.fp_status)
697 & float_flag_invalid) {
698 if (float32_is_any_nan(fst0)) {
699 wt2 = 0;
700 }
701 }
702 update_fcr31(env, GETPC());
703 return wt2;
704}
705
706uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
707{
708 uint64_t dt2;
709
710 set_float_rounding_mode(float_round_nearest_even,
711 &env->active_fpu.fp_status);
712 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
713 restore_rounding_mode(env);
714 if (get_float_exception_flags(&env->active_fpu.fp_status)
715 & float_flag_invalid) {
716 if (float64_is_any_nan(fdt0)) {
717 dt2 = 0;
718 }
719 }
720 update_fcr31(env, GETPC());
721 return dt2;
722}
723
724uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
725{
726 uint64_t dt2;
727
728 set_float_rounding_mode(float_round_nearest_even,
729 &env->active_fpu.fp_status);
730 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
731 restore_rounding_mode(env);
732 if (get_float_exception_flags(&env->active_fpu.fp_status)
733 & float_flag_invalid) {
734 if (float32_is_any_nan(fst0)) {
735 dt2 = 0;
736 }
737 }
738 update_fcr31(env, GETPC());
739 return dt2;
740}
741
742uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
743{
744 uint32_t wt2;
745
746 set_float_rounding_mode(float_round_nearest_even,
747 &env->active_fpu.fp_status);
748 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
749 restore_rounding_mode(env);
750 if (get_float_exception_flags(&env->active_fpu.fp_status)
751 & float_flag_invalid) {
752 if (float64_is_any_nan(fdt0)) {
753 wt2 = 0;
754 }
755 }
756 update_fcr31(env, GETPC());
757 return wt2;
758}
759
760uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
761{
762 uint32_t wt2;
763
764 set_float_rounding_mode(float_round_nearest_even,
765 &env->active_fpu.fp_status);
766 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
767 restore_rounding_mode(env);
768 if (get_float_exception_flags(&env->active_fpu.fp_status)
769 & float_flag_invalid) {
770 if (float32_is_any_nan(fst0)) {
771 wt2 = 0;
772 }
773 }
774 update_fcr31(env, GETPC());
775 return wt2;
776}
777
778uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
779{
780 uint64_t dt2;
781
782 dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
783 if (get_float_exception_flags(&env->active_fpu.fp_status)
784 & float_flag_invalid) {
785 if (float64_is_any_nan(fdt0)) {
786 dt2 = 0;
787 }
788 }
789 update_fcr31(env, GETPC());
790 return dt2;
791}
792
793uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
794{
795 uint64_t dt2;
796
797 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
798 if (get_float_exception_flags(&env->active_fpu.fp_status)
799 & float_flag_invalid) {
800 if (float32_is_any_nan(fst0)) {
801 dt2 = 0;
802 }
803 }
804 update_fcr31(env, GETPC());
805 return dt2;
806}
807
808uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
809{
810 uint32_t wt2;
811
812 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
813 if (get_float_exception_flags(&env->active_fpu.fp_status)
814 & float_flag_invalid) {
815 if (float64_is_any_nan(fdt0)) {
816 wt2 = 0;
817 }
818 }
819 update_fcr31(env, GETPC());
820 return wt2;
821}
822
823uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
824{
825 uint32_t wt2;
826
827 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
828 if (get_float_exception_flags(&env->active_fpu.fp_status)
829 & float_flag_invalid) {
830 if (float32_is_any_nan(fst0)) {
831 wt2 = 0;
832 }
833 }
834 update_fcr31(env, GETPC());
835 return wt2;
836}
837
838uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
839{
840 uint64_t dt2;
841
842 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
843 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
844 restore_rounding_mode(env);
845 if (get_float_exception_flags(&env->active_fpu.fp_status)
846 & float_flag_invalid) {
847 if (float64_is_any_nan(fdt0)) {
848 dt2 = 0;
849 }
850 }
851 update_fcr31(env, GETPC());
852 return dt2;
853}
854
855uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
856{
857 uint64_t dt2;
858
859 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
860 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
861 restore_rounding_mode(env);
862 if (get_float_exception_flags(&env->active_fpu.fp_status)
863 & float_flag_invalid) {
864 if (float32_is_any_nan(fst0)) {
865 dt2 = 0;
866 }
867 }
868 update_fcr31(env, GETPC());
869 return dt2;
870}
871
872uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
873{
874 uint32_t wt2;
875
876 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
877 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
878 restore_rounding_mode(env);
879 if (get_float_exception_flags(&env->active_fpu.fp_status)
880 & float_flag_invalid) {
881 if (float64_is_any_nan(fdt0)) {
882 wt2 = 0;
883 }
884 }
885 update_fcr31(env, GETPC());
886 return wt2;
887}
888
889uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
890{
891 uint32_t wt2;
892
893 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
894 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
895 restore_rounding_mode(env);
896 if (get_float_exception_flags(&env->active_fpu.fp_status)
897 & float_flag_invalid) {
898 if (float32_is_any_nan(fst0)) {
899 wt2 = 0;
900 }
901 }
902 update_fcr31(env, GETPC());
903 return wt2;
904}
905
906uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
907{
908 uint64_t dt2;
909
910 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
911 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
912 restore_rounding_mode(env);
913 if (get_float_exception_flags(&env->active_fpu.fp_status)
914 & float_flag_invalid) {
915 if (float64_is_any_nan(fdt0)) {
916 dt2 = 0;
917 }
918 }
919 update_fcr31(env, GETPC());
920 return dt2;
921}
922
923uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
924{
925 uint64_t dt2;
926
927 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
928 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
929 restore_rounding_mode(env);
930 if (get_float_exception_flags(&env->active_fpu.fp_status)
931 & float_flag_invalid) {
932 if (float32_is_any_nan(fst0)) {
933 dt2 = 0;
934 }
935 }
936 update_fcr31(env, GETPC());
937 return dt2;
938}
939
940uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
941{
942 uint32_t wt2;
943
944 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
945 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
946 restore_rounding_mode(env);
947 if (get_float_exception_flags(&env->active_fpu.fp_status)
948 & float_flag_invalid) {
949 if (float64_is_any_nan(fdt0)) {
950 wt2 = 0;
951 }
952 }
953 update_fcr31(env, GETPC());
954 return wt2;
955}
956
957uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
958{
959 uint32_t wt2;
960
961 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
962 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
963 restore_rounding_mode(env);
964 if (get_float_exception_flags(&env->active_fpu.fp_status)
965 & float_flag_invalid) {
966 if (float32_is_any_nan(fst0)) {
967 wt2 = 0;
968 }
969 }
970 update_fcr31(env, GETPC());
971 return wt2;
972}
973
974
975
976uint64_t helper_float_abs_d(uint64_t fdt0)
977{
978 return float64_abs(fdt0);
979}
980
981uint32_t helper_float_abs_s(uint32_t fst0)
982{
983 return float32_abs(fst0);
984}
985
986uint64_t helper_float_abs_ps(uint64_t fdt0)
987{
988 uint32_t wt0;
989 uint32_t wth0;
990
991 wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
992 wth0 = float32_abs(fdt0 >> 32);
993 return ((uint64_t)wth0 << 32) | wt0;
994}
995
996uint64_t helper_float_chs_d(uint64_t fdt0)
997{
998 return float64_chs(fdt0);
999}
1000
1001uint32_t helper_float_chs_s(uint32_t fst0)
1002{
1003 return float32_chs(fst0);
1004}
1005
1006uint64_t helper_float_chs_ps(uint64_t fdt0)
1007{
1008 uint32_t wt0;
1009 uint32_t wth0;
1010
1011 wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
1012 wth0 = float32_chs(fdt0 >> 32);
1013 return ((uint64_t)wth0 << 32) | wt0;
1014}
1015
1016
1017uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1018{
1019 uint64_t fdt2;
1020
1021 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1022 update_fcr31(env, GETPC());
1023 return fdt2;
1024}
1025
1026uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1027{
1028 uint32_t fst2;
1029
1030 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1031 update_fcr31(env, GETPC());
1032 return fst2;
1033}
1034
1035uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1036{
1037 uint64_t fdt2;
1038
1039 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1040 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1041 update_fcr31(env, GETPC());
1042 return fdt2;
1043}
1044
1045uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1046{
1047 uint32_t fst2;
1048
1049 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1050 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1051 update_fcr31(env, GETPC());
1052 return fst2;
1053}
1054
1055uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1056{
1057 uint64_t fdt2;
1058
1059 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1060 update_fcr31(env, GETPC());
1061 return fdt2;
1062}
1063
1064uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1065{
1066 uint32_t fst2;
1067
1068 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1069 update_fcr31(env, GETPC());
1070 return fst2;
1071}
1072
1073uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1074{
1075 uint32_t fstl2;
1076 uint32_t fsth2;
1077
1078 fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
1079 &env->active_fpu.fp_status);
1080 fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
1081 update_fcr31(env, GETPC());
1082 return ((uint64_t)fsth2 << 32) | fstl2;
1083}
1084
1085uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1086{
1087 uint64_t fdt2;
1088
1089 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1090 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1091 update_fcr31(env, GETPC());
1092 return fdt2;
1093}
1094
1095uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1096{
1097 uint32_t fst2;
1098
1099 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1100 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1101 update_fcr31(env, GETPC());
1102 return fst2;
1103}
1104
1105uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1106{
1107 uint32_t fstl2;
1108 uint32_t fsth2;
1109
1110 fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
1111 fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1112 fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
1113 fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
1114 update_fcr31(env, GETPC());
1115 return ((uint64_t)fsth2 << 32) | fstl2;
1116}
1117
1118uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1119{
1120 uint64_t fdret;
1121
1122 fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1123 update_fcr31(env, GETPC());
1124 return fdret;
1125}
1126
1127uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1128{
1129 uint32_t fdret;
1130
1131 fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1132 update_fcr31(env, GETPC());
1133 return fdret;
1134}
1135
1136#define FLOAT_CLASS_SIGNALING_NAN 0x001
1137#define FLOAT_CLASS_QUIET_NAN 0x002
1138#define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1139#define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1140#define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1141#define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1142#define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1143#define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1144#define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1145#define FLOAT_CLASS_POSITIVE_ZERO 0x200
1146
1147uint64_t float_class_d(uint64_t arg, float_status *status)
1148{
1149 if (float64_is_signaling_nan(arg, status)) {
1150 return FLOAT_CLASS_SIGNALING_NAN;
1151 } else if (float64_is_quiet_nan(arg, status)) {
1152 return FLOAT_CLASS_QUIET_NAN;
1153 } else if (float64_is_neg(arg)) {
1154 if (float64_is_infinity(arg)) {
1155 return FLOAT_CLASS_NEGATIVE_INFINITY;
1156 } else if (float64_is_zero(arg)) {
1157 return FLOAT_CLASS_NEGATIVE_ZERO;
1158 } else if (float64_is_zero_or_denormal(arg)) {
1159 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1160 } else {
1161 return FLOAT_CLASS_NEGATIVE_NORMAL;
1162 }
1163 } else {
1164 if (float64_is_infinity(arg)) {
1165 return FLOAT_CLASS_POSITIVE_INFINITY;
1166 } else if (float64_is_zero(arg)) {
1167 return FLOAT_CLASS_POSITIVE_ZERO;
1168 } else if (float64_is_zero_or_denormal(arg)) {
1169 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1170 } else {
1171 return FLOAT_CLASS_POSITIVE_NORMAL;
1172 }
1173 }
1174}
1175
1176uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1177{
1178 return float_class_d(arg, &env->active_fpu.fp_status);
1179}
1180
1181uint32_t float_class_s(uint32_t arg, float_status *status)
1182{
1183 if (float32_is_signaling_nan(arg, status)) {
1184 return FLOAT_CLASS_SIGNALING_NAN;
1185 } else if (float32_is_quiet_nan(arg, status)) {
1186 return FLOAT_CLASS_QUIET_NAN;
1187 } else if (float32_is_neg(arg)) {
1188 if (float32_is_infinity(arg)) {
1189 return FLOAT_CLASS_NEGATIVE_INFINITY;
1190 } else if (float32_is_zero(arg)) {
1191 return FLOAT_CLASS_NEGATIVE_ZERO;
1192 } else if (float32_is_zero_or_denormal(arg)) {
1193 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1194 } else {
1195 return FLOAT_CLASS_NEGATIVE_NORMAL;
1196 }
1197 } else {
1198 if (float32_is_infinity(arg)) {
1199 return FLOAT_CLASS_POSITIVE_INFINITY;
1200 } else if (float32_is_zero(arg)) {
1201 return FLOAT_CLASS_POSITIVE_ZERO;
1202 } else if (float32_is_zero_or_denormal(arg)) {
1203 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1204 } else {
1205 return FLOAT_CLASS_POSITIVE_NORMAL;
1206 }
1207 }
1208}
1209
1210uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1211{
1212 return float_class_s(arg, &env->active_fpu.fp_status);
1213}
1214
1215
1216
1217uint64_t helper_float_add_d(CPUMIPSState *env,
1218 uint64_t fdt0, uint64_t fdt1)
1219{
1220 uint64_t dt2;
1221
1222 dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1223 update_fcr31(env, GETPC());
1224 return dt2;
1225}
1226
1227uint32_t helper_float_add_s(CPUMIPSState *env,
1228 uint32_t fst0, uint32_t fst1)
1229{
1230 uint32_t wt2;
1231
1232 wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
1233 update_fcr31(env, GETPC());
1234 return wt2;
1235}
1236
1237uint64_t helper_float_add_ps(CPUMIPSState *env,
1238 uint64_t fdt0, uint64_t fdt1)
1239{
1240 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1241 uint32_t fsth0 = fdt0 >> 32;
1242 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1243 uint32_t fsth1 = fdt1 >> 32;
1244 uint32_t wtl2;
1245 uint32_t wth2;
1246
1247 wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
1248 wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
1249 update_fcr31(env, GETPC());
1250 return ((uint64_t)wth2 << 32) | wtl2;
1251}
1252
1253uint64_t helper_float_sub_d(CPUMIPSState *env,
1254 uint64_t fdt0, uint64_t fdt1)
1255{
1256 uint64_t dt2;
1257
1258 dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1259 update_fcr31(env, GETPC());
1260 return dt2;
1261}
1262
1263uint32_t helper_float_sub_s(CPUMIPSState *env,
1264 uint32_t fst0, uint32_t fst1)
1265{
1266 uint32_t wt2;
1267
1268 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1269 update_fcr31(env, GETPC());
1270 return wt2;
1271}
1272
1273uint64_t helper_float_sub_ps(CPUMIPSState *env,
1274 uint64_t fdt0, uint64_t fdt1)
1275{
1276 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1277 uint32_t fsth0 = fdt0 >> 32;
1278 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1279 uint32_t fsth1 = fdt1 >> 32;
1280 uint32_t wtl2;
1281 uint32_t wth2;
1282
1283 wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1284 wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1285 update_fcr31(env, GETPC());
1286 return ((uint64_t)wth2 << 32) | wtl2;
1287}
1288
1289uint64_t helper_float_mul_d(CPUMIPSState *env,
1290 uint64_t fdt0, uint64_t fdt1)
1291{
1292 uint64_t dt2;
1293
1294 dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1295 update_fcr31(env, GETPC());
1296 return dt2;
1297}
1298
1299uint32_t helper_float_mul_s(CPUMIPSState *env,
1300 uint32_t fst0, uint32_t fst1)
1301{
1302 uint32_t wt2;
1303
1304 wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1305 update_fcr31(env, GETPC());
1306 return wt2;
1307}
1308
1309uint64_t helper_float_mul_ps(CPUMIPSState *env,
1310 uint64_t fdt0, uint64_t fdt1)
1311{
1312 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1313 uint32_t fsth0 = fdt0 >> 32;
1314 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1315 uint32_t fsth1 = fdt1 >> 32;
1316 uint32_t wtl2;
1317 uint32_t wth2;
1318
1319 wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1320 wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1321 update_fcr31(env, GETPC());
1322 return ((uint64_t)wth2 << 32) | wtl2;
1323}
1324
1325uint64_t helper_float_div_d(CPUMIPSState *env,
1326 uint64_t fdt0, uint64_t fdt1)
1327{
1328 uint64_t dt2;
1329
1330 dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1331 update_fcr31(env, GETPC());
1332 return dt2;
1333}
1334
1335uint32_t helper_float_div_s(CPUMIPSState *env,
1336 uint32_t fst0, uint32_t fst1)
1337{
1338 uint32_t wt2;
1339
1340 wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1341 update_fcr31(env, GETPC());
1342 return wt2;
1343}
1344
1345uint64_t helper_float_div_ps(CPUMIPSState *env,
1346 uint64_t fdt0, uint64_t fdt1)
1347{
1348 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1349 uint32_t fsth0 = fdt0 >> 32;
1350 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1351 uint32_t fsth1 = fdt1 >> 32;
1352 uint32_t wtl2;
1353 uint32_t wth2;
1354
1355 wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1356 wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1357 update_fcr31(env, GETPC());
1358 return ((uint64_t)wth2 << 32) | wtl2;
1359}
1360
1361
1362
1363uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1364{
1365 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1366 fdt2 = float64_chs(float64_sub(fdt2, float64_one,
1367 &env->active_fpu.fp_status));
1368 update_fcr31(env, GETPC());
1369 return fdt2;
1370}
1371
1372uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1373{
1374 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1375 fst2 = float32_chs(float32_sub(fst2, float32_one,
1376 &env->active_fpu.fp_status));
1377 update_fcr31(env, GETPC());
1378 return fst2;
1379}
1380
1381uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1382{
1383 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1384 uint32_t fsth0 = fdt0 >> 32;
1385 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1386 uint32_t fsth2 = fdt2 >> 32;
1387
1388 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1389 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1390 fstl2 = float32_chs(float32_sub(fstl2, float32_one,
1391 &env->active_fpu.fp_status));
1392 fsth2 = float32_chs(float32_sub(fsth2, float32_one,
1393 &env->active_fpu.fp_status));
1394 update_fcr31(env, GETPC());
1395 return ((uint64_t)fsth2 << 32) | fstl2;
1396}
1397
1398uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1399{
1400 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1401 fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
1402 fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
1403 &env->active_fpu.fp_status));
1404 update_fcr31(env, GETPC());
1405 return fdt2;
1406}
1407
1408uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1409{
1410 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1411 fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
1412 fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
1413 &env->active_fpu.fp_status));
1414 update_fcr31(env, GETPC());
1415 return fst2;
1416}
1417
1418uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1419{
1420 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1421 uint32_t fsth0 = fdt0 >> 32;
1422 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1423 uint32_t fsth2 = fdt2 >> 32;
1424
1425 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1426 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1427 fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
1428 fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1429 fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
1430 &env->active_fpu.fp_status));
1431 fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
1432 &env->active_fpu.fp_status));
1433 update_fcr31(env, GETPC());
1434 return ((uint64_t)fsth2 << 32) | fstl2;
1435}
1436
1437uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1438{
1439 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1440 uint32_t fsth0 = fdt0 >> 32;
1441 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1442 uint32_t fsth1 = fdt1 >> 32;
1443 uint32_t fstl2;
1444 uint32_t fsth2;
1445
1446 fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1447 fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
1448 update_fcr31(env, GETPC());
1449 return ((uint64_t)fsth2 << 32) | fstl2;
1450}
1451
1452uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1453{
1454 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1455 uint32_t fsth0 = fdt0 >> 32;
1456 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1457 uint32_t fsth1 = fdt1 >> 32;
1458 uint32_t fstl2;
1459 uint32_t fsth2;
1460
1461 fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1462 fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
1463 update_fcr31(env, GETPC());
1464 return ((uint64_t)fsth2 << 32) | fstl2;
1465}
1466
1467
1468uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1469{
1470 uint32_t fdret;
1471
1472 fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
1473
1474 update_fcr31(env, GETPC());
1475 return fdret;
1476}
1477
1478uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1479{
1480 uint64_t fdret;
1481
1482 fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
1483
1484 update_fcr31(env, GETPC());
1485 return fdret;
1486}
1487
1488uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1489{
1490 uint32_t fdret;
1491
1492 fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
1493
1494 update_fcr31(env, GETPC());
1495 return fdret;
1496}
1497
1498uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1499{
1500 uint64_t fdret;
1501
1502 fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
1503
1504 update_fcr31(env, GETPC());
1505 return fdret;
1506}
1507
1508uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1509{
1510 uint32_t fdret;
1511
1512 fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
1513
1514 update_fcr31(env, GETPC());
1515 return fdret;
1516}
1517
1518uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1519{
1520 uint64_t fdret;
1521
1522 fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
1523
1524 update_fcr31(env, GETPC());
1525 return fdret;
1526}
1527
1528uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1529{
1530 uint32_t fdret;
1531
1532 fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
1533
1534 update_fcr31(env, GETPC());
1535 return fdret;
1536}
1537
1538uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1539{
1540 uint64_t fdret;
1541
1542 fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
1543
1544 update_fcr31(env, GETPC());
1545 return fdret;
1546}
1547
1548
1549
1550
1551uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1552 uint64_t fst1, uint64_t fst2)
1553{
1554 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1555 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1556
1557 update_fcr31(env, GETPC());
1558 return fst0;
1559}
1560
1561uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1562 uint32_t fst1, uint32_t fst2)
1563{
1564 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1565 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1566
1567 update_fcr31(env, GETPC());
1568 return fst0;
1569}
1570
1571uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1572 uint64_t fdt1, uint64_t fdt2)
1573{
1574 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1575 uint32_t fsth0 = fdt0 >> 32;
1576 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1577 uint32_t fsth1 = fdt1 >> 32;
1578 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1579 uint32_t fsth2 = fdt2 >> 32;
1580
1581 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1582 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1583 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1584 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1585
1586 update_fcr31(env, GETPC());
1587 return ((uint64_t)fsth0 << 32) | fstl0;
1588}
1589
1590uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1591 uint64_t fst1, uint64_t fst2)
1592{
1593 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1594 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1595
1596 update_fcr31(env, GETPC());
1597 return fst0;
1598}
1599
1600uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1601 uint32_t fst1, uint32_t fst2)
1602{
1603 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1604 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1605
1606 update_fcr31(env, GETPC());
1607 return fst0;
1608}
1609
1610uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1611 uint64_t fdt1, uint64_t fdt2)
1612{
1613 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1614 uint32_t fsth0 = fdt0 >> 32;
1615 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1616 uint32_t fsth1 = fdt1 >> 32;
1617 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1618 uint32_t fsth2 = fdt2 >> 32;
1619
1620 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1621 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1622 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1623 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1624
1625 update_fcr31(env, GETPC());
1626 return ((uint64_t)fsth0 << 32) | fstl0;
1627}
1628
1629uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1630 uint64_t fst1, uint64_t fst2)
1631{
1632 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1633 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1634 fst0 = float64_chs(fst0);
1635
1636 update_fcr31(env, GETPC());
1637 return fst0;
1638}
1639
1640uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1641 uint32_t fst1, uint32_t fst2)
1642{
1643 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1644 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1645 fst0 = float32_chs(fst0);
1646
1647 update_fcr31(env, GETPC());
1648 return fst0;
1649}
1650
1651uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1652 uint64_t fdt1, uint64_t fdt2)
1653{
1654 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1655 uint32_t fsth0 = fdt0 >> 32;
1656 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1657 uint32_t fsth1 = fdt1 >> 32;
1658 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1659 uint32_t fsth2 = fdt2 >> 32;
1660
1661 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1662 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1663 fstl0 = float32_chs(fstl0);
1664 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1665 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1666 fsth0 = float32_chs(fsth0);
1667
1668 update_fcr31(env, GETPC());
1669 return ((uint64_t)fsth0 << 32) | fstl0;
1670}
1671
1672uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1673 uint64_t fst1, uint64_t fst2)
1674{
1675 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1676 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1677 fst0 = float64_chs(fst0);
1678
1679 update_fcr31(env, GETPC());
1680 return fst0;
1681}
1682
1683uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1684 uint32_t fst1, uint32_t fst2)
1685{
1686 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1687 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1688 fst0 = float32_chs(fst0);
1689
1690 update_fcr31(env, GETPC());
1691 return fst0;
1692}
1693
1694uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1695 uint64_t fdt1, uint64_t fdt2)
1696{
1697 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1698 uint32_t fsth0 = fdt0 >> 32;
1699 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1700 uint32_t fsth1 = fdt1 >> 32;
1701 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1702 uint32_t fsth2 = fdt2 >> 32;
1703
1704 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1705 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1706 fstl0 = float32_chs(fstl0);
1707 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1708 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1709 fsth0 = float32_chs(fsth0);
1710
1711 update_fcr31(env, GETPC());
1712 return ((uint64_t)fsth0 << 32) | fstl0;
1713}
1714
1715
1716uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
1717 uint32_t ft, uint32_t fd)
1718{
1719 uint32_t fdret;
1720
1721 fdret = float32_muladd(fs, ft, fd, 0,
1722 &env->active_fpu.fp_status);
1723
1724 update_fcr31(env, GETPC());
1725 return fdret;
1726}
1727
1728uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
1729 uint64_t ft, uint64_t fd)
1730{
1731 uint64_t fdret;
1732
1733 fdret = float64_muladd(fs, ft, fd, 0,
1734 &env->active_fpu.fp_status);
1735
1736 update_fcr31(env, GETPC());
1737 return fdret;
1738}
1739
1740uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
1741 uint32_t ft, uint32_t fd)
1742{
1743 uint32_t fdret;
1744
1745 fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
1746 &env->active_fpu.fp_status);
1747
1748 update_fcr31(env, GETPC());
1749 return fdret;
1750}
1751
1752uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
1753 uint64_t ft, uint64_t fd)
1754{
1755 uint64_t fdret;
1756
1757 fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
1758 &env->active_fpu.fp_status);
1759
1760 update_fcr31(env, GETPC());
1761 return fdret;
1762}
1763
1764
1765
1766#define FOP_COND_D(op, cond) \
1767void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1768 uint64_t fdt1, int cc) \
1769{ \
1770 int c; \
1771 c = cond; \
1772 update_fcr31(env, GETPC()); \
1773 if (c) \
1774 SET_FP_COND(cc, env->active_fpu); \
1775 else \
1776 CLEAR_FP_COND(cc, env->active_fpu); \
1777} \
1778void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1779 uint64_t fdt1, int cc) \
1780{ \
1781 int c; \
1782 fdt0 = float64_abs(fdt0); \
1783 fdt1 = float64_abs(fdt1); \
1784 c = cond; \
1785 update_fcr31(env, GETPC()); \
1786 if (c) \
1787 SET_FP_COND(cc, env->active_fpu); \
1788 else \
1789 CLEAR_FP_COND(cc, env->active_fpu); \
1790}
1791
1792
1793
1794
1795
1796FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0,
1797 &env->active_fpu.fp_status), 0))
1798FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0,
1799 &env->active_fpu.fp_status))
1800FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1,
1801 &env->active_fpu.fp_status))
1802FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0,
1803 &env->active_fpu.fp_status)
1804 || float64_eq_quiet(fdt0, fdt1,
1805 &env->active_fpu.fp_status))
1806FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1,
1807 &env->active_fpu.fp_status))
1808FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0,
1809 &env->active_fpu.fp_status)
1810 || float64_lt_quiet(fdt0, fdt1,
1811 &env->active_fpu.fp_status))
1812FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1,
1813 &env->active_fpu.fp_status))
1814FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0,
1815 &env->active_fpu.fp_status)
1816 || float64_le_quiet(fdt0, fdt1,
1817 &env->active_fpu.fp_status))
1818
1819
1820
1821
1822FOP_COND_D(sf, (float64_unordered(fdt1, fdt0,
1823 &env->active_fpu.fp_status), 0))
1824FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
1825 &env->active_fpu.fp_status))
1826FOP_COND_D(seq, float64_eq(fdt0, fdt1,
1827 &env->active_fpu.fp_status))
1828FOP_COND_D(ngl, float64_unordered(fdt1, fdt0,
1829 &env->active_fpu.fp_status)
1830 || float64_eq(fdt0, fdt1,
1831 &env->active_fpu.fp_status))
1832FOP_COND_D(lt, float64_lt(fdt0, fdt1,
1833 &env->active_fpu.fp_status))
1834FOP_COND_D(nge, float64_unordered(fdt1, fdt0,
1835 &env->active_fpu.fp_status)
1836 || float64_lt(fdt0, fdt1,
1837 &env->active_fpu.fp_status))
1838FOP_COND_D(le, float64_le(fdt0, fdt1,
1839 &env->active_fpu.fp_status))
1840FOP_COND_D(ngt, float64_unordered(fdt1, fdt0,
1841 &env->active_fpu.fp_status)
1842 || float64_le(fdt0, fdt1,
1843 &env->active_fpu.fp_status))
1844
1845#define FOP_COND_S(op, cond) \
1846void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1847 uint32_t fst1, int cc) \
1848{ \
1849 int c; \
1850 c = cond; \
1851 update_fcr31(env, GETPC()); \
1852 if (c) \
1853 SET_FP_COND(cc, env->active_fpu); \
1854 else \
1855 CLEAR_FP_COND(cc, env->active_fpu); \
1856} \
1857void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1858 uint32_t fst1, int cc) \
1859{ \
1860 int c; \
1861 fst0 = float32_abs(fst0); \
1862 fst1 = float32_abs(fst1); \
1863 c = cond; \
1864 update_fcr31(env, GETPC()); \
1865 if (c) \
1866 SET_FP_COND(cc, env->active_fpu); \
1867 else \
1868 CLEAR_FP_COND(cc, env->active_fpu); \
1869}
1870
1871
1872
1873
1874
1875FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0,
1876 &env->active_fpu.fp_status), 0))
1877FOP_COND_S(un, float32_unordered_quiet(fst1, fst0,
1878 &env->active_fpu.fp_status))
1879FOP_COND_S(eq, float32_eq_quiet(fst0, fst1,
1880 &env->active_fpu.fp_status))
1881FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0,
1882 &env->active_fpu.fp_status)
1883 || float32_eq_quiet(fst0, fst1,
1884 &env->active_fpu.fp_status))
1885FOP_COND_S(olt, float32_lt_quiet(fst0, fst1,
1886 &env->active_fpu.fp_status))
1887FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0,
1888 &env->active_fpu.fp_status)
1889 || float32_lt_quiet(fst0, fst1,
1890 &env->active_fpu.fp_status))
1891FOP_COND_S(ole, float32_le_quiet(fst0, fst1,
1892 &env->active_fpu.fp_status))
1893FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0,
1894 &env->active_fpu.fp_status)
1895 || float32_le_quiet(fst0, fst1,
1896 &env->active_fpu.fp_status))
1897
1898
1899
1900
1901FOP_COND_S(sf, (float32_unordered(fst1, fst0,
1902 &env->active_fpu.fp_status), 0))
1903FOP_COND_S(ngle, float32_unordered(fst1, fst0,
1904 &env->active_fpu.fp_status))
1905FOP_COND_S(seq, float32_eq(fst0, fst1,
1906 &env->active_fpu.fp_status))
1907FOP_COND_S(ngl, float32_unordered(fst1, fst0,
1908 &env->active_fpu.fp_status)
1909 || float32_eq(fst0, fst1,
1910 &env->active_fpu.fp_status))
1911FOP_COND_S(lt, float32_lt(fst0, fst1,
1912 &env->active_fpu.fp_status))
1913FOP_COND_S(nge, float32_unordered(fst1, fst0,
1914 &env->active_fpu.fp_status)
1915 || float32_lt(fst0, fst1,
1916 &env->active_fpu.fp_status))
1917FOP_COND_S(le, float32_le(fst0, fst1,
1918 &env->active_fpu.fp_status))
1919FOP_COND_S(ngt, float32_unordered(fst1, fst0,
1920 &env->active_fpu.fp_status)
1921 || float32_le(fst0, fst1,
1922 &env->active_fpu.fp_status))
1923
1924#define FOP_COND_PS(op, condl, condh) \
1925void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1926 uint64_t fdt1, int cc) \
1927{ \
1928 uint32_t fst0, fsth0, fst1, fsth1; \
1929 int ch, cl; \
1930 fst0 = fdt0 & 0XFFFFFFFF; \
1931 fsth0 = fdt0 >> 32; \
1932 fst1 = fdt1 & 0XFFFFFFFF; \
1933 fsth1 = fdt1 >> 32; \
1934 cl = condl; \
1935 ch = condh; \
1936 update_fcr31(env, GETPC()); \
1937 if (cl) \
1938 SET_FP_COND(cc, env->active_fpu); \
1939 else \
1940 CLEAR_FP_COND(cc, env->active_fpu); \
1941 if (ch) \
1942 SET_FP_COND(cc + 1, env->active_fpu); \
1943 else \
1944 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1945} \
1946void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1947 uint64_t fdt1, int cc) \
1948{ \
1949 uint32_t fst0, fsth0, fst1, fsth1; \
1950 int ch, cl; \
1951 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1952 fsth0 = float32_abs(fdt0 >> 32); \
1953 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1954 fsth1 = float32_abs(fdt1 >> 32); \
1955 cl = condl; \
1956 ch = condh; \
1957 update_fcr31(env, GETPC()); \
1958 if (cl) \
1959 SET_FP_COND(cc, env->active_fpu); \
1960 else \
1961 CLEAR_FP_COND(cc, env->active_fpu); \
1962 if (ch) \
1963 SET_FP_COND(cc + 1, env->active_fpu); \
1964 else \
1965 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1966}
1967
1968
1969
1970
1971
1972FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0,
1973 &env->active_fpu.fp_status), 0),
1974 (float32_unordered_quiet(fsth1, fsth0,
1975 &env->active_fpu.fp_status), 0))
1976FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0,
1977 &env->active_fpu.fp_status),
1978 float32_unordered_quiet(fsth1, fsth0,
1979 &env->active_fpu.fp_status))
1980FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1,
1981 &env->active_fpu.fp_status),
1982 float32_eq_quiet(fsth0, fsth1,
1983 &env->active_fpu.fp_status))
1984FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0,
1985 &env->active_fpu.fp_status)
1986 || float32_eq_quiet(fst0, fst1,
1987 &env->active_fpu.fp_status),
1988 float32_unordered_quiet(fsth1, fsth0,
1989 &env->active_fpu.fp_status)
1990 || float32_eq_quiet(fsth0, fsth1,
1991 &env->active_fpu.fp_status))
1992FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1,
1993 &env->active_fpu.fp_status),
1994 float32_lt_quiet(fsth0, fsth1,
1995 &env->active_fpu.fp_status))
1996FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0,
1997 &env->active_fpu.fp_status)
1998 || float32_lt_quiet(fst0, fst1,
1999 &env->active_fpu.fp_status),
2000 float32_unordered_quiet(fsth1, fsth0,
2001 &env->active_fpu.fp_status)
2002 || float32_lt_quiet(fsth0, fsth1,
2003 &env->active_fpu.fp_status))
2004FOP_COND_PS(ole, float32_le_quiet(fst0, fst1,
2005 &env->active_fpu.fp_status),
2006 float32_le_quiet(fsth0, fsth1,
2007 &env->active_fpu.fp_status))
2008FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0,
2009 &env->active_fpu.fp_status)
2010 || float32_le_quiet(fst0, fst1,
2011 &env->active_fpu.fp_status),
2012 float32_unordered_quiet(fsth1, fsth0,
2013 &env->active_fpu.fp_status)
2014 || float32_le_quiet(fsth0, fsth1,
2015 &env->active_fpu.fp_status))
2016
2017
2018
2019
2020FOP_COND_PS(sf, (float32_unordered(fst1, fst0,
2021 &env->active_fpu.fp_status), 0),
2022 (float32_unordered(fsth1, fsth0,
2023 &env->active_fpu.fp_status), 0))
2024FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
2025 &env->active_fpu.fp_status),
2026 float32_unordered(fsth1, fsth0,
2027 &env->active_fpu.fp_status))
2028FOP_COND_PS(seq, float32_eq(fst0, fst1,
2029 &env->active_fpu.fp_status),
2030 float32_eq(fsth0, fsth1,
2031 &env->active_fpu.fp_status))
2032FOP_COND_PS(ngl, float32_unordered(fst1, fst0,
2033 &env->active_fpu.fp_status)
2034 || float32_eq(fst0, fst1,
2035 &env->active_fpu.fp_status),
2036 float32_unordered(fsth1, fsth0,
2037 &env->active_fpu.fp_status)
2038 || float32_eq(fsth0, fsth1,
2039 &env->active_fpu.fp_status))
2040FOP_COND_PS(lt, float32_lt(fst0, fst1,
2041 &env->active_fpu.fp_status),
2042 float32_lt(fsth0, fsth1,
2043 &env->active_fpu.fp_status))
2044FOP_COND_PS(nge, float32_unordered(fst1, fst0,
2045 &env->active_fpu.fp_status)
2046 || float32_lt(fst0, fst1,
2047 &env->active_fpu.fp_status),
2048 float32_unordered(fsth1, fsth0,
2049 &env->active_fpu.fp_status)
2050 || float32_lt(fsth0, fsth1,
2051 &env->active_fpu.fp_status))
2052FOP_COND_PS(le, float32_le(fst0, fst1,
2053 &env->active_fpu.fp_status),
2054 float32_le(fsth0, fsth1,
2055 &env->active_fpu.fp_status))
2056FOP_COND_PS(ngt, float32_unordered(fst1, fst0,
2057 &env->active_fpu.fp_status)
2058 || float32_le(fst0, fst1,
2059 &env->active_fpu.fp_status),
2060 float32_unordered(fsth1, fsth0,
2061 &env->active_fpu.fp_status)
2062 || float32_le(fsth0, fsth1,
2063 &env->active_fpu.fp_status))
2064
2065
2066#define FOP_CONDN_D(op, cond) \
2067uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
2068 uint64_t fdt1) \
2069{ \
2070 uint64_t c; \
2071 c = cond; \
2072 update_fcr31(env, GETPC()); \
2073 if (c) { \
2074 return -1; \
2075 } else { \
2076 return 0; \
2077 } \
2078}
2079
2080
2081
2082
2083
2084FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0,
2085 &env->active_fpu.fp_status), 0))
2086FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0,
2087 &env->active_fpu.fp_status)))
2088FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1,
2089 &env->active_fpu.fp_status)))
2090FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
2091 &env->active_fpu.fp_status)
2092 || float64_eq_quiet(fdt0, fdt1,
2093 &env->active_fpu.fp_status)))
2094FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1,
2095 &env->active_fpu.fp_status)))
2096FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
2097 &env->active_fpu.fp_status)
2098 || float64_lt_quiet(fdt0, fdt1,
2099 &env->active_fpu.fp_status)))
2100FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1,
2101 &env->active_fpu.fp_status)))
2102FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
2103 &env->active_fpu.fp_status)
2104 || float64_le_quiet(fdt0, fdt1,
2105 &env->active_fpu.fp_status)))
2106
2107
2108
2109
2110FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0,
2111 &env->active_fpu.fp_status), 0))
2112FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0,
2113 &env->active_fpu.fp_status)))
2114FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1,
2115 &env->active_fpu.fp_status)))
2116FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
2117 &env->active_fpu.fp_status)
2118 || float64_eq(fdt0, fdt1,
2119 &env->active_fpu.fp_status)))
2120FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1,
2121 &env->active_fpu.fp_status)))
2122FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
2123 &env->active_fpu.fp_status)
2124 || float64_lt(fdt0, fdt1,
2125 &env->active_fpu.fp_status)))
2126FOP_CONDN_D(sle, (float64_le(fdt0, fdt1,
2127 &env->active_fpu.fp_status)))
2128FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
2129 &env->active_fpu.fp_status)
2130 || float64_le(fdt0, fdt1,
2131 &env->active_fpu.fp_status)))
2132FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0,
2133 &env->active_fpu.fp_status)
2134 || float64_le_quiet(fdt0, fdt1,
2135 &env->active_fpu.fp_status)))
2136FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0,
2137 &env->active_fpu.fp_status)
2138 || float64_lt_quiet(fdt1, fdt0,
2139 &env->active_fpu.fp_status)
2140 || float64_lt_quiet(fdt0, fdt1,
2141 &env->active_fpu.fp_status)))
2142FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0,
2143 &env->active_fpu.fp_status)
2144 || float64_lt_quiet(fdt0, fdt1,
2145 &env->active_fpu.fp_status)))
2146FOP_CONDN_D(sor, (float64_le(fdt1, fdt0,
2147 &env->active_fpu.fp_status)
2148 || float64_le(fdt0, fdt1,
2149 &env->active_fpu.fp_status)))
2150FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
2151 &env->active_fpu.fp_status)
2152 || float64_lt(fdt1, fdt0,
2153 &env->active_fpu.fp_status)
2154 || float64_lt(fdt0, fdt1,
2155 &env->active_fpu.fp_status)))
2156FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0,
2157 &env->active_fpu.fp_status)
2158 || float64_lt(fdt0, fdt1,
2159 &env->active_fpu.fp_status)))
2160
2161#define FOP_CONDN_S(op, cond) \
2162uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2163 uint32_t fst1) \
2164{ \
2165 uint64_t c; \
2166 c = cond; \
2167 update_fcr31(env, GETPC()); \
2168 if (c) { \
2169 return -1; \
2170 } else { \
2171 return 0; \
2172 } \
2173}
2174
2175
2176
2177
2178
2179FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0,
2180 &env->active_fpu.fp_status), 0))
2181FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0,
2182 &env->active_fpu.fp_status)))
2183FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1,
2184 &env->active_fpu.fp_status)))
2185FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0,
2186 &env->active_fpu.fp_status)
2187 || float32_eq_quiet(fst0, fst1,
2188 &env->active_fpu.fp_status)))
2189FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1,
2190 &env->active_fpu.fp_status)))
2191FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0,
2192 &env->active_fpu.fp_status)
2193 || float32_lt_quiet(fst0, fst1,
2194 &env->active_fpu.fp_status)))
2195FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1,
2196 &env->active_fpu.fp_status)))
2197FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0,
2198 &env->active_fpu.fp_status)
2199 || float32_le_quiet(fst0, fst1,
2200 &env->active_fpu.fp_status)))
2201
2202
2203
2204
2205FOP_CONDN_S(saf, (float32_unordered(fst1, fst0,
2206 &env->active_fpu.fp_status), 0))
2207FOP_CONDN_S(sun, (float32_unordered(fst1, fst0,
2208 &env->active_fpu.fp_status)))
2209FOP_CONDN_S(seq, (float32_eq(fst0, fst1,
2210 &env->active_fpu.fp_status)))
2211FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
2212 &env->active_fpu.fp_status)
2213 || float32_eq(fst0, fst1,
2214 &env->active_fpu.fp_status)))
2215FOP_CONDN_S(slt, (float32_lt(fst0, fst1,
2216 &env->active_fpu.fp_status)))
2217FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
2218 &env->active_fpu.fp_status)
2219 || float32_lt(fst0, fst1,
2220 &env->active_fpu.fp_status)))
2221FOP_CONDN_S(sle, (float32_le(fst0, fst1,
2222 &env->active_fpu.fp_status)))
2223FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
2224 &env->active_fpu.fp_status)
2225 || float32_le(fst0, fst1,
2226 &env->active_fpu.fp_status)))
2227FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0,
2228 &env->active_fpu.fp_status)
2229 || float32_le_quiet(fst0, fst1,
2230 &env->active_fpu.fp_status)))
2231FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0,
2232 &env->active_fpu.fp_status)
2233 || float32_lt_quiet(fst1, fst0,
2234 &env->active_fpu.fp_status)
2235 || float32_lt_quiet(fst0, fst1,
2236 &env->active_fpu.fp_status)))
2237FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0,
2238 &env->active_fpu.fp_status)
2239 || float32_lt_quiet(fst0, fst1,
2240 &env->active_fpu.fp_status)))
2241FOP_CONDN_S(sor, (float32_le(fst1, fst0,
2242 &env->active_fpu.fp_status)
2243 || float32_le(fst0, fst1,
2244 &env->active_fpu.fp_status)))
2245FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
2246 &env->active_fpu.fp_status)
2247 || float32_lt(fst1, fst0,
2248 &env->active_fpu.fp_status)
2249 || float32_lt(fst0, fst1,
2250 &env->active_fpu.fp_status)))
2251FOP_CONDN_S(sne, (float32_lt(fst1, fst0,
2252 &env->active_fpu.fp_status)
2253 || float32_lt(fst0, fst1,
2254 &env->active_fpu.fp_status)))
2255