hw/sd: sd: Only SDSC cards support CMD28/29/30
[qemu/ar7.git] / target / mips / fpu_helper.c
blob6dd853259e2e1150b556f13927f415b3b5260f9e
1 /*
2 * Helpers for emulation of FPU-related MIPS instructions.
4 * Copyright (C) 2004-2005 Jocelyn Mayer
5 * Copyright (C) 2020 Wave Computing, Inc.
6 * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
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"
33 /* Complex FPU operations which may need stack space. */
35 #define FLOAT_TWO32 make_float32(1 << 30)
36 #define FLOAT_TWO64 make_float64(1ULL << 62)
38 #define FP_TO_INT32_OVERFLOW 0x7fffffff
39 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
41 /* convert MIPS rounding mode in FCR31 to IEEE library */
42 const FloatRoundMode ieee_rm[4] = {
43 float_round_nearest_even,
44 float_round_to_zero,
45 float_round_up,
46 float_round_down
49 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
51 target_ulong arg1 = 0;
53 switch (reg) {
54 case 0:
55 arg1 = (int32_t)env->active_fpu.fcr0;
56 break;
57 case 1:
58 /* UFR Support - Read Status FR */
59 if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
60 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
61 arg1 = (int32_t)
62 ((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR);
63 } else {
64 do_raise_exception(env, EXCP_RI, GETPC());
67 break;
68 case 5:
69 /* FRE Support - read Config5.FRE bit */
70 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
71 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
72 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
73 } else {
74 helper_raise_exception(env, EXCP_RI);
77 break;
78 case 25:
79 arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
80 ((env->active_fpu.fcr31 >> 23) & 0x1);
81 break;
82 case 26:
83 arg1 = env->active_fpu.fcr31 & 0x0003f07c;
84 break;
85 case 28:
86 arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
87 ((env->active_fpu.fcr31 >> 22) & 0x4);
88 break;
89 default:
90 arg1 = (int32_t)env->active_fpu.fcr31;
91 break;
94 return arg1;
97 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
99 switch (fs) {
100 case 1:
101 /* UFR Alias - Reset Status FR */
102 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
103 return;
105 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
106 env->CP0_Status &= ~(1 << CP0St_FR);
107 compute_hflags(env);
108 } else {
109 do_raise_exception(env, EXCP_RI, GETPC());
111 break;
112 case 4:
113 /* UNFR Alias - Set Status FR */
114 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
115 return;
117 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
118 env->CP0_Status |= (1 << CP0St_FR);
119 compute_hflags(env);
120 } else {
121 do_raise_exception(env, EXCP_RI, GETPC());
123 break;
124 case 5:
125 /* FRE Support - clear Config5.FRE bit */
126 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
127 return;
129 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
130 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
131 compute_hflags(env);
132 } else {
133 helper_raise_exception(env, EXCP_RI);
135 break;
136 case 6:
137 /* FRE Support - set Config5.FRE bit */
138 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
139 return;
141 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
142 env->CP0_Config5 |= (1 << CP0C5_FRE);
143 compute_hflags(env);
144 } else {
145 helper_raise_exception(env, EXCP_RI);
147 break;
148 case 25:
149 if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) {
150 return;
152 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
153 ((arg1 & 0xfe) << 24) |
154 ((arg1 & 0x1) << 23);
155 break;
156 case 26:
157 if (arg1 & 0x007c0000) {
158 return;
160 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
161 (arg1 & 0x0003f07c);
162 break;
163 case 28:
164 if (arg1 & 0x007c0000) {
165 return;
167 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
168 (arg1 & 0x00000f83) |
169 ((arg1 & 0x4) << 22);
170 break;
171 case 31:
172 env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
173 (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
174 break;
175 default:
176 if (env->insn_flags & ISA_MIPS_R6) {
177 do_raise_exception(env, EXCP_RI, GETPC());
179 return;
181 restore_fp_status(env);
182 set_float_exception_flags(0, &env->active_fpu.fp_status);
183 if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
184 GET_FP_CAUSE(env->active_fpu.fcr31)) {
185 do_raise_exception(env, EXCP_FPE, GETPC());
189 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
191 int mips_xcpt = 0;
193 if (ieee_xcpt & float_flag_invalid) {
194 mips_xcpt |= FP_INVALID;
196 if (ieee_xcpt & float_flag_overflow) {
197 mips_xcpt |= FP_OVERFLOW;
199 if (ieee_xcpt & float_flag_underflow) {
200 mips_xcpt |= FP_UNDERFLOW;
202 if (ieee_xcpt & float_flag_divbyzero) {
203 mips_xcpt |= FP_DIV0;
205 if (ieee_xcpt & float_flag_inexact) {
206 mips_xcpt |= FP_INEXACT;
209 return mips_xcpt;
212 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
214 int ieee_exception_flags = get_float_exception_flags(
215 &env->active_fpu.fp_status);
216 int mips_exception_flags = 0;
218 if (ieee_exception_flags) {
219 mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
222 SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
224 if (mips_exception_flags) {
225 set_float_exception_flags(0, &env->active_fpu.fp_status);
227 if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
228 do_raise_exception(env, EXCP_FPE, pc);
229 } else {
230 UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
236 * Float support.
237 * Single precition routines have a "s" suffix, double precision a
238 * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
239 * paired single lower "pl", paired single upper "pu".
242 /* unary operations, modifying fp status */
243 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
245 fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
246 update_fcr31(env, GETPC());
247 return fdt0;
250 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
252 fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
253 update_fcr31(env, GETPC());
254 return fst0;
257 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
259 uint64_t fdt2;
261 fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
262 update_fcr31(env, GETPC());
263 return fdt2;
266 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
268 uint64_t fdt2;
270 fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
271 update_fcr31(env, GETPC());
272 return fdt2;
275 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
277 uint64_t fdt2;
279 fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
280 update_fcr31(env, GETPC());
281 return fdt2;
284 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
286 uint64_t dt2;
288 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
289 if (get_float_exception_flags(&env->active_fpu.fp_status)
290 & (float_flag_invalid | float_flag_overflow)) {
291 dt2 = FP_TO_INT64_OVERFLOW;
293 update_fcr31(env, GETPC());
294 return dt2;
297 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
299 uint64_t dt2;
301 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
302 if (get_float_exception_flags(&env->active_fpu.fp_status)
303 & (float_flag_invalid | float_flag_overflow)) {
304 dt2 = FP_TO_INT64_OVERFLOW;
306 update_fcr31(env, GETPC());
307 return dt2;
310 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
312 uint32_t fst2;
313 uint32_t fsth2;
315 fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
316 fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
317 update_fcr31(env, GETPC());
318 return ((uint64_t)fsth2 << 32) | fst2;
321 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
323 uint32_t wt2;
324 uint32_t wth2;
325 int excp, excph;
327 wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
328 excp = get_float_exception_flags(&env->active_fpu.fp_status);
329 if (excp & (float_flag_overflow | float_flag_invalid)) {
330 wt2 = FP_TO_INT32_OVERFLOW;
333 set_float_exception_flags(0, &env->active_fpu.fp_status);
334 wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
335 excph = get_float_exception_flags(&env->active_fpu.fp_status);
336 if (excph & (float_flag_overflow | float_flag_invalid)) {
337 wth2 = FP_TO_INT32_OVERFLOW;
340 set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
341 update_fcr31(env, GETPC());
343 return ((uint64_t)wth2 << 32) | wt2;
346 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
348 uint32_t fst2;
350 fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
351 update_fcr31(env, GETPC());
352 return fst2;
355 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
357 uint32_t fst2;
359 fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
360 update_fcr31(env, GETPC());
361 return fst2;
364 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
366 uint32_t fst2;
368 fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
369 update_fcr31(env, GETPC());
370 return fst2;
373 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
375 uint32_t wt2;
377 wt2 = wt0;
378 update_fcr31(env, GETPC());
379 return wt2;
382 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
384 uint32_t wt2;
386 wt2 = wth0;
387 update_fcr31(env, GETPC());
388 return wt2;
391 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
393 uint32_t wt2;
395 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
396 if (get_float_exception_flags(&env->active_fpu.fp_status)
397 & (float_flag_invalid | float_flag_overflow)) {
398 wt2 = FP_TO_INT32_OVERFLOW;
400 update_fcr31(env, GETPC());
401 return wt2;
404 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
406 uint32_t wt2;
408 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
409 if (get_float_exception_flags(&env->active_fpu.fp_status)
410 & (float_flag_invalid | float_flag_overflow)) {
411 wt2 = FP_TO_INT32_OVERFLOW;
413 update_fcr31(env, GETPC());
414 return wt2;
417 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
419 uint64_t dt2;
421 set_float_rounding_mode(float_round_nearest_even,
422 &env->active_fpu.fp_status);
423 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
424 restore_rounding_mode(env);
425 if (get_float_exception_flags(&env->active_fpu.fp_status)
426 & (float_flag_invalid | float_flag_overflow)) {
427 dt2 = FP_TO_INT64_OVERFLOW;
429 update_fcr31(env, GETPC());
430 return dt2;
433 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
435 uint64_t dt2;
437 set_float_rounding_mode(float_round_nearest_even,
438 &env->active_fpu.fp_status);
439 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
440 restore_rounding_mode(env);
441 if (get_float_exception_flags(&env->active_fpu.fp_status)
442 & (float_flag_invalid | float_flag_overflow)) {
443 dt2 = FP_TO_INT64_OVERFLOW;
445 update_fcr31(env, GETPC());
446 return dt2;
449 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
451 uint32_t wt2;
453 set_float_rounding_mode(float_round_nearest_even,
454 &env->active_fpu.fp_status);
455 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
456 restore_rounding_mode(env);
457 if (get_float_exception_flags(&env->active_fpu.fp_status)
458 & (float_flag_invalid | float_flag_overflow)) {
459 wt2 = FP_TO_INT32_OVERFLOW;
461 update_fcr31(env, GETPC());
462 return wt2;
465 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
467 uint32_t wt2;
469 set_float_rounding_mode(float_round_nearest_even,
470 &env->active_fpu.fp_status);
471 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
472 restore_rounding_mode(env);
473 if (get_float_exception_flags(&env->active_fpu.fp_status)
474 & (float_flag_invalid | float_flag_overflow)) {
475 wt2 = FP_TO_INT32_OVERFLOW;
477 update_fcr31(env, GETPC());
478 return wt2;
481 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
483 uint64_t dt2;
485 dt2 = float64_to_int64_round_to_zero(fdt0,
486 &env->active_fpu.fp_status);
487 if (get_float_exception_flags(&env->active_fpu.fp_status)
488 & (float_flag_invalid | float_flag_overflow)) {
489 dt2 = FP_TO_INT64_OVERFLOW;
491 update_fcr31(env, GETPC());
492 return dt2;
495 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
497 uint64_t dt2;
499 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
500 if (get_float_exception_flags(&env->active_fpu.fp_status)
501 & (float_flag_invalid | float_flag_overflow)) {
502 dt2 = FP_TO_INT64_OVERFLOW;
504 update_fcr31(env, GETPC());
505 return dt2;
508 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
510 uint32_t wt2;
512 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
513 if (get_float_exception_flags(&env->active_fpu.fp_status)
514 & (float_flag_invalid | float_flag_overflow)) {
515 wt2 = FP_TO_INT32_OVERFLOW;
517 update_fcr31(env, GETPC());
518 return wt2;
521 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
523 uint32_t wt2;
525 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
526 if (get_float_exception_flags(&env->active_fpu.fp_status)
527 & (float_flag_invalid | float_flag_overflow)) {
528 wt2 = FP_TO_INT32_OVERFLOW;
530 update_fcr31(env, GETPC());
531 return wt2;
534 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
536 uint64_t dt2;
538 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
539 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
540 restore_rounding_mode(env);
541 if (get_float_exception_flags(&env->active_fpu.fp_status)
542 & (float_flag_invalid | float_flag_overflow)) {
543 dt2 = FP_TO_INT64_OVERFLOW;
545 update_fcr31(env, GETPC());
546 return dt2;
549 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
551 uint64_t dt2;
553 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
554 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
555 restore_rounding_mode(env);
556 if (get_float_exception_flags(&env->active_fpu.fp_status)
557 & (float_flag_invalid | float_flag_overflow)) {
558 dt2 = FP_TO_INT64_OVERFLOW;
560 update_fcr31(env, GETPC());
561 return dt2;
564 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
566 uint32_t wt2;
568 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
569 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
570 restore_rounding_mode(env);
571 if (get_float_exception_flags(&env->active_fpu.fp_status)
572 & (float_flag_invalid | float_flag_overflow)) {
573 wt2 = FP_TO_INT32_OVERFLOW;
575 update_fcr31(env, GETPC());
576 return wt2;
579 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
581 uint32_t wt2;
583 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
584 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
585 restore_rounding_mode(env);
586 if (get_float_exception_flags(&env->active_fpu.fp_status)
587 & (float_flag_invalid | float_flag_overflow)) {
588 wt2 = FP_TO_INT32_OVERFLOW;
590 update_fcr31(env, GETPC());
591 return wt2;
594 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
596 uint64_t dt2;
598 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
599 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
600 restore_rounding_mode(env);
601 if (get_float_exception_flags(&env->active_fpu.fp_status)
602 & (float_flag_invalid | float_flag_overflow)) {
603 dt2 = FP_TO_INT64_OVERFLOW;
605 update_fcr31(env, GETPC());
606 return dt2;
609 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
611 uint64_t dt2;
613 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
614 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
615 restore_rounding_mode(env);
616 if (get_float_exception_flags(&env->active_fpu.fp_status)
617 & (float_flag_invalid | float_flag_overflow)) {
618 dt2 = FP_TO_INT64_OVERFLOW;
620 update_fcr31(env, GETPC());
621 return dt2;
624 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
626 uint32_t wt2;
628 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
629 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
630 restore_rounding_mode(env);
631 if (get_float_exception_flags(&env->active_fpu.fp_status)
632 & (float_flag_invalid | float_flag_overflow)) {
633 wt2 = FP_TO_INT32_OVERFLOW;
635 update_fcr31(env, GETPC());
636 return wt2;
639 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
641 uint32_t wt2;
643 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
644 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
645 restore_rounding_mode(env);
646 if (get_float_exception_flags(&env->active_fpu.fp_status)
647 & (float_flag_invalid | float_flag_overflow)) {
648 wt2 = FP_TO_INT32_OVERFLOW;
650 update_fcr31(env, GETPC());
651 return wt2;
654 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
656 uint64_t dt2;
658 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
659 if (get_float_exception_flags(&env->active_fpu.fp_status)
660 & float_flag_invalid) {
661 if (float64_is_any_nan(fdt0)) {
662 dt2 = 0;
665 update_fcr31(env, GETPC());
666 return dt2;
669 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
671 uint64_t dt2;
673 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
674 if (get_float_exception_flags(&env->active_fpu.fp_status)
675 & float_flag_invalid) {
676 if (float32_is_any_nan(fst0)) {
677 dt2 = 0;
680 update_fcr31(env, GETPC());
681 return dt2;
684 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
686 uint32_t wt2;
688 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
689 if (get_float_exception_flags(&env->active_fpu.fp_status)
690 & float_flag_invalid) {
691 if (float64_is_any_nan(fdt0)) {
692 wt2 = 0;
695 update_fcr31(env, GETPC());
696 return wt2;
699 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
701 uint32_t wt2;
703 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
704 if (get_float_exception_flags(&env->active_fpu.fp_status)
705 & float_flag_invalid) {
706 if (float32_is_any_nan(fst0)) {
707 wt2 = 0;
710 update_fcr31(env, GETPC());
711 return wt2;
714 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
716 uint64_t dt2;
718 set_float_rounding_mode(float_round_nearest_even,
719 &env->active_fpu.fp_status);
720 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
721 restore_rounding_mode(env);
722 if (get_float_exception_flags(&env->active_fpu.fp_status)
723 & float_flag_invalid) {
724 if (float64_is_any_nan(fdt0)) {
725 dt2 = 0;
728 update_fcr31(env, GETPC());
729 return dt2;
732 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
734 uint64_t dt2;
736 set_float_rounding_mode(float_round_nearest_even,
737 &env->active_fpu.fp_status);
738 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
739 restore_rounding_mode(env);
740 if (get_float_exception_flags(&env->active_fpu.fp_status)
741 & float_flag_invalid) {
742 if (float32_is_any_nan(fst0)) {
743 dt2 = 0;
746 update_fcr31(env, GETPC());
747 return dt2;
750 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
752 uint32_t wt2;
754 set_float_rounding_mode(float_round_nearest_even,
755 &env->active_fpu.fp_status);
756 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
757 restore_rounding_mode(env);
758 if (get_float_exception_flags(&env->active_fpu.fp_status)
759 & float_flag_invalid) {
760 if (float64_is_any_nan(fdt0)) {
761 wt2 = 0;
764 update_fcr31(env, GETPC());
765 return wt2;
768 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
770 uint32_t wt2;
772 set_float_rounding_mode(float_round_nearest_even,
773 &env->active_fpu.fp_status);
774 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
775 restore_rounding_mode(env);
776 if (get_float_exception_flags(&env->active_fpu.fp_status)
777 & float_flag_invalid) {
778 if (float32_is_any_nan(fst0)) {
779 wt2 = 0;
782 update_fcr31(env, GETPC());
783 return wt2;
786 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
788 uint64_t dt2;
790 dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
791 if (get_float_exception_flags(&env->active_fpu.fp_status)
792 & float_flag_invalid) {
793 if (float64_is_any_nan(fdt0)) {
794 dt2 = 0;
797 update_fcr31(env, GETPC());
798 return dt2;
801 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
803 uint64_t dt2;
805 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
806 if (get_float_exception_flags(&env->active_fpu.fp_status)
807 & float_flag_invalid) {
808 if (float32_is_any_nan(fst0)) {
809 dt2 = 0;
812 update_fcr31(env, GETPC());
813 return dt2;
816 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
818 uint32_t wt2;
820 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
821 if (get_float_exception_flags(&env->active_fpu.fp_status)
822 & float_flag_invalid) {
823 if (float64_is_any_nan(fdt0)) {
824 wt2 = 0;
827 update_fcr31(env, GETPC());
828 return wt2;
831 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
833 uint32_t wt2;
835 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
836 if (get_float_exception_flags(&env->active_fpu.fp_status)
837 & float_flag_invalid) {
838 if (float32_is_any_nan(fst0)) {
839 wt2 = 0;
842 update_fcr31(env, GETPC());
843 return wt2;
846 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
848 uint64_t dt2;
850 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
851 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
852 restore_rounding_mode(env);
853 if (get_float_exception_flags(&env->active_fpu.fp_status)
854 & float_flag_invalid) {
855 if (float64_is_any_nan(fdt0)) {
856 dt2 = 0;
859 update_fcr31(env, GETPC());
860 return dt2;
863 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
865 uint64_t dt2;
867 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
868 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
869 restore_rounding_mode(env);
870 if (get_float_exception_flags(&env->active_fpu.fp_status)
871 & float_flag_invalid) {
872 if (float32_is_any_nan(fst0)) {
873 dt2 = 0;
876 update_fcr31(env, GETPC());
877 return dt2;
880 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
882 uint32_t wt2;
884 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
885 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
886 restore_rounding_mode(env);
887 if (get_float_exception_flags(&env->active_fpu.fp_status)
888 & float_flag_invalid) {
889 if (float64_is_any_nan(fdt0)) {
890 wt2 = 0;
893 update_fcr31(env, GETPC());
894 return wt2;
897 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
899 uint32_t wt2;
901 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
902 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
903 restore_rounding_mode(env);
904 if (get_float_exception_flags(&env->active_fpu.fp_status)
905 & float_flag_invalid) {
906 if (float32_is_any_nan(fst0)) {
907 wt2 = 0;
910 update_fcr31(env, GETPC());
911 return wt2;
914 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
916 uint64_t dt2;
918 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
919 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
920 restore_rounding_mode(env);
921 if (get_float_exception_flags(&env->active_fpu.fp_status)
922 & float_flag_invalid) {
923 if (float64_is_any_nan(fdt0)) {
924 dt2 = 0;
927 update_fcr31(env, GETPC());
928 return dt2;
931 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
933 uint64_t dt2;
935 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
936 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
937 restore_rounding_mode(env);
938 if (get_float_exception_flags(&env->active_fpu.fp_status)
939 & float_flag_invalid) {
940 if (float32_is_any_nan(fst0)) {
941 dt2 = 0;
944 update_fcr31(env, GETPC());
945 return dt2;
948 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
950 uint32_t wt2;
952 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
953 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
954 restore_rounding_mode(env);
955 if (get_float_exception_flags(&env->active_fpu.fp_status)
956 & float_flag_invalid) {
957 if (float64_is_any_nan(fdt0)) {
958 wt2 = 0;
961 update_fcr31(env, GETPC());
962 return wt2;
965 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
967 uint32_t wt2;
969 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
970 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
971 restore_rounding_mode(env);
972 if (get_float_exception_flags(&env->active_fpu.fp_status)
973 & float_flag_invalid) {
974 if (float32_is_any_nan(fst0)) {
975 wt2 = 0;
978 update_fcr31(env, GETPC());
979 return wt2;
982 /* unary operations, not modifying fp status */
984 uint64_t helper_float_abs_d(uint64_t fdt0)
986 return float64_abs(fdt0);
989 uint32_t helper_float_abs_s(uint32_t fst0)
991 return float32_abs(fst0);
994 uint64_t helper_float_abs_ps(uint64_t fdt0)
996 uint32_t wt0;
997 uint32_t wth0;
999 wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
1000 wth0 = float32_abs(fdt0 >> 32);
1001 return ((uint64_t)wth0 << 32) | wt0;
1004 uint64_t helper_float_chs_d(uint64_t fdt0)
1006 return float64_chs(fdt0);
1009 uint32_t helper_float_chs_s(uint32_t fst0)
1011 return float32_chs(fst0);
1014 uint64_t helper_float_chs_ps(uint64_t fdt0)
1016 uint32_t wt0;
1017 uint32_t wth0;
1019 wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
1020 wth0 = float32_chs(fdt0 >> 32);
1021 return ((uint64_t)wth0 << 32) | wt0;
1024 /* MIPS specific unary operations */
1025 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1027 uint64_t fdt2;
1029 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1030 update_fcr31(env, GETPC());
1031 return fdt2;
1034 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1036 uint32_t fst2;
1038 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1039 update_fcr31(env, GETPC());
1040 return fst2;
1043 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1045 uint64_t fdt2;
1047 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1048 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1049 update_fcr31(env, GETPC());
1050 return fdt2;
1053 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1055 uint32_t fst2;
1057 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1058 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1059 update_fcr31(env, GETPC());
1060 return fst2;
1063 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1065 uint64_t fdt2;
1067 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1068 update_fcr31(env, GETPC());
1069 return fdt2;
1072 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1074 uint32_t fst2;
1076 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1077 update_fcr31(env, GETPC());
1078 return fst2;
1081 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1083 uint32_t fstl2;
1084 uint32_t fsth2;
1086 fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
1087 &env->active_fpu.fp_status);
1088 fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
1089 update_fcr31(env, GETPC());
1090 return ((uint64_t)fsth2 << 32) | fstl2;
1093 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1095 uint64_t fdt2;
1097 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1098 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1099 update_fcr31(env, GETPC());
1100 return fdt2;
1103 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1105 uint32_t fst2;
1107 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1108 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1109 update_fcr31(env, GETPC());
1110 return fst2;
1113 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1115 uint32_t fstl2;
1116 uint32_t fsth2;
1118 fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
1119 fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1120 fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
1121 fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
1122 update_fcr31(env, GETPC());
1123 return ((uint64_t)fsth2 << 32) | fstl2;
1126 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1128 uint64_t fdret;
1130 fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1131 update_fcr31(env, GETPC());
1132 return fdret;
1135 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1137 uint32_t fdret;
1139 fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1140 update_fcr31(env, GETPC());
1141 return fdret;
1144 #define FLOAT_CLASS_SIGNALING_NAN 0x001
1145 #define FLOAT_CLASS_QUIET_NAN 0x002
1146 #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1147 #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1148 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1149 #define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1150 #define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1151 #define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1152 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1153 #define FLOAT_CLASS_POSITIVE_ZERO 0x200
1155 uint64_t float_class_d(uint64_t arg, float_status *status)
1157 if (float64_is_signaling_nan(arg, status)) {
1158 return FLOAT_CLASS_SIGNALING_NAN;
1159 } else if (float64_is_quiet_nan(arg, status)) {
1160 return FLOAT_CLASS_QUIET_NAN;
1161 } else if (float64_is_neg(arg)) {
1162 if (float64_is_infinity(arg)) {
1163 return FLOAT_CLASS_NEGATIVE_INFINITY;
1164 } else if (float64_is_zero(arg)) {
1165 return FLOAT_CLASS_NEGATIVE_ZERO;
1166 } else if (float64_is_zero_or_denormal(arg)) {
1167 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1168 } else {
1169 return FLOAT_CLASS_NEGATIVE_NORMAL;
1171 } else {
1172 if (float64_is_infinity(arg)) {
1173 return FLOAT_CLASS_POSITIVE_INFINITY;
1174 } else if (float64_is_zero(arg)) {
1175 return FLOAT_CLASS_POSITIVE_ZERO;
1176 } else if (float64_is_zero_or_denormal(arg)) {
1177 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1178 } else {
1179 return FLOAT_CLASS_POSITIVE_NORMAL;
1184 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1186 return float_class_d(arg, &env->active_fpu.fp_status);
1189 uint32_t float_class_s(uint32_t arg, float_status *status)
1191 if (float32_is_signaling_nan(arg, status)) {
1192 return FLOAT_CLASS_SIGNALING_NAN;
1193 } else if (float32_is_quiet_nan(arg, status)) {
1194 return FLOAT_CLASS_QUIET_NAN;
1195 } else if (float32_is_neg(arg)) {
1196 if (float32_is_infinity(arg)) {
1197 return FLOAT_CLASS_NEGATIVE_INFINITY;
1198 } else if (float32_is_zero(arg)) {
1199 return FLOAT_CLASS_NEGATIVE_ZERO;
1200 } else if (float32_is_zero_or_denormal(arg)) {
1201 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1202 } else {
1203 return FLOAT_CLASS_NEGATIVE_NORMAL;
1205 } else {
1206 if (float32_is_infinity(arg)) {
1207 return FLOAT_CLASS_POSITIVE_INFINITY;
1208 } else if (float32_is_zero(arg)) {
1209 return FLOAT_CLASS_POSITIVE_ZERO;
1210 } else if (float32_is_zero_or_denormal(arg)) {
1211 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1212 } else {
1213 return FLOAT_CLASS_POSITIVE_NORMAL;
1218 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1220 return float_class_s(arg, &env->active_fpu.fp_status);
1223 /* binary operations */
1225 uint64_t helper_float_add_d(CPUMIPSState *env,
1226 uint64_t fdt0, uint64_t fdt1)
1228 uint64_t dt2;
1230 dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1231 update_fcr31(env, GETPC());
1232 return dt2;
1235 uint32_t helper_float_add_s(CPUMIPSState *env,
1236 uint32_t fst0, uint32_t fst1)
1238 uint32_t wt2;
1240 wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
1241 update_fcr31(env, GETPC());
1242 return wt2;
1245 uint64_t helper_float_add_ps(CPUMIPSState *env,
1246 uint64_t fdt0, uint64_t fdt1)
1248 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1249 uint32_t fsth0 = fdt0 >> 32;
1250 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1251 uint32_t fsth1 = fdt1 >> 32;
1252 uint32_t wtl2;
1253 uint32_t wth2;
1255 wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
1256 wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
1257 update_fcr31(env, GETPC());
1258 return ((uint64_t)wth2 << 32) | wtl2;
1261 uint64_t helper_float_sub_d(CPUMIPSState *env,
1262 uint64_t fdt0, uint64_t fdt1)
1264 uint64_t dt2;
1266 dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1267 update_fcr31(env, GETPC());
1268 return dt2;
1271 uint32_t helper_float_sub_s(CPUMIPSState *env,
1272 uint32_t fst0, uint32_t fst1)
1274 uint32_t wt2;
1276 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1277 update_fcr31(env, GETPC());
1278 return wt2;
1281 uint64_t helper_float_sub_ps(CPUMIPSState *env,
1282 uint64_t fdt0, uint64_t fdt1)
1284 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1285 uint32_t fsth0 = fdt0 >> 32;
1286 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1287 uint32_t fsth1 = fdt1 >> 32;
1288 uint32_t wtl2;
1289 uint32_t wth2;
1291 wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1292 wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1293 update_fcr31(env, GETPC());
1294 return ((uint64_t)wth2 << 32) | wtl2;
1297 uint64_t helper_float_mul_d(CPUMIPSState *env,
1298 uint64_t fdt0, uint64_t fdt1)
1300 uint64_t dt2;
1302 dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1303 update_fcr31(env, GETPC());
1304 return dt2;
1307 uint32_t helper_float_mul_s(CPUMIPSState *env,
1308 uint32_t fst0, uint32_t fst1)
1310 uint32_t wt2;
1312 wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1313 update_fcr31(env, GETPC());
1314 return wt2;
1317 uint64_t helper_float_mul_ps(CPUMIPSState *env,
1318 uint64_t fdt0, uint64_t fdt1)
1320 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1321 uint32_t fsth0 = fdt0 >> 32;
1322 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1323 uint32_t fsth1 = fdt1 >> 32;
1324 uint32_t wtl2;
1325 uint32_t wth2;
1327 wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1328 wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1329 update_fcr31(env, GETPC());
1330 return ((uint64_t)wth2 << 32) | wtl2;
1333 uint64_t helper_float_div_d(CPUMIPSState *env,
1334 uint64_t fdt0, uint64_t fdt1)
1336 uint64_t dt2;
1338 dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1339 update_fcr31(env, GETPC());
1340 return dt2;
1343 uint32_t helper_float_div_s(CPUMIPSState *env,
1344 uint32_t fst0, uint32_t fst1)
1346 uint32_t wt2;
1348 wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1349 update_fcr31(env, GETPC());
1350 return wt2;
1353 uint64_t helper_float_div_ps(CPUMIPSState *env,
1354 uint64_t fdt0, uint64_t fdt1)
1356 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1357 uint32_t fsth0 = fdt0 >> 32;
1358 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1359 uint32_t fsth1 = fdt1 >> 32;
1360 uint32_t wtl2;
1361 uint32_t wth2;
1363 wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1364 wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1365 update_fcr31(env, GETPC());
1366 return ((uint64_t)wth2 << 32) | wtl2;
1370 /* MIPS specific binary operations */
1371 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1373 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1374 fdt2 = float64_chs(float64_sub(fdt2, float64_one,
1375 &env->active_fpu.fp_status));
1376 update_fcr31(env, GETPC());
1377 return fdt2;
1380 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1382 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1383 fst2 = float32_chs(float32_sub(fst2, float32_one,
1384 &env->active_fpu.fp_status));
1385 update_fcr31(env, GETPC());
1386 return fst2;
1389 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1391 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1392 uint32_t fsth0 = fdt0 >> 32;
1393 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1394 uint32_t fsth2 = fdt2 >> 32;
1396 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1397 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1398 fstl2 = float32_chs(float32_sub(fstl2, float32_one,
1399 &env->active_fpu.fp_status));
1400 fsth2 = float32_chs(float32_sub(fsth2, float32_one,
1401 &env->active_fpu.fp_status));
1402 update_fcr31(env, GETPC());
1403 return ((uint64_t)fsth2 << 32) | fstl2;
1406 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1408 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1409 fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
1410 fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
1411 &env->active_fpu.fp_status));
1412 update_fcr31(env, GETPC());
1413 return fdt2;
1416 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1418 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1419 fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
1420 fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
1421 &env->active_fpu.fp_status));
1422 update_fcr31(env, GETPC());
1423 return fst2;
1426 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1428 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1429 uint32_t fsth0 = fdt0 >> 32;
1430 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1431 uint32_t fsth2 = fdt2 >> 32;
1433 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1434 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1435 fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
1436 fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1437 fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
1438 &env->active_fpu.fp_status));
1439 fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
1440 &env->active_fpu.fp_status));
1441 update_fcr31(env, GETPC());
1442 return ((uint64_t)fsth2 << 32) | fstl2;
1445 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1447 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1448 uint32_t fsth0 = fdt0 >> 32;
1449 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1450 uint32_t fsth1 = fdt1 >> 32;
1451 uint32_t fstl2;
1452 uint32_t fsth2;
1454 fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1455 fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
1456 update_fcr31(env, GETPC());
1457 return ((uint64_t)fsth2 << 32) | fstl2;
1460 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1462 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1463 uint32_t fsth0 = fdt0 >> 32;
1464 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1465 uint32_t fsth1 = fdt1 >> 32;
1466 uint32_t fstl2;
1467 uint32_t fsth2;
1469 fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1470 fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
1471 update_fcr31(env, GETPC());
1472 return ((uint64_t)fsth2 << 32) | fstl2;
1476 uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1478 uint32_t fdret;
1480 fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
1482 update_fcr31(env, GETPC());
1483 return fdret;
1486 uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1488 uint64_t fdret;
1490 fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
1492 update_fcr31(env, GETPC());
1493 return fdret;
1496 uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1498 uint32_t fdret;
1500 fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
1502 update_fcr31(env, GETPC());
1503 return fdret;
1506 uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1508 uint64_t fdret;
1510 fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
1512 update_fcr31(env, GETPC());
1513 return fdret;
1516 uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1518 uint32_t fdret;
1520 fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
1522 update_fcr31(env, GETPC());
1523 return fdret;
1526 uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1528 uint64_t fdret;
1530 fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
1532 update_fcr31(env, GETPC());
1533 return fdret;
1536 uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1538 uint32_t fdret;
1540 fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
1542 update_fcr31(env, GETPC());
1543 return fdret;
1546 uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1548 uint64_t fdret;
1550 fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
1552 update_fcr31(env, GETPC());
1553 return fdret;
1557 /* ternary operations */
1559 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1560 uint64_t fst1, uint64_t fst2)
1562 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1563 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1565 update_fcr31(env, GETPC());
1566 return fst0;
1569 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1570 uint32_t fst1, uint32_t fst2)
1572 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1573 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1575 update_fcr31(env, GETPC());
1576 return fst0;
1579 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1580 uint64_t fdt1, uint64_t fdt2)
1582 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1583 uint32_t fsth0 = fdt0 >> 32;
1584 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1585 uint32_t fsth1 = fdt1 >> 32;
1586 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1587 uint32_t fsth2 = fdt2 >> 32;
1589 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1590 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1591 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1592 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1594 update_fcr31(env, GETPC());
1595 return ((uint64_t)fsth0 << 32) | fstl0;
1598 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1599 uint64_t fst1, uint64_t fst2)
1601 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1602 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1604 update_fcr31(env, GETPC());
1605 return fst0;
1608 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1609 uint32_t fst1, uint32_t fst2)
1611 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1612 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1614 update_fcr31(env, GETPC());
1615 return fst0;
1618 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1619 uint64_t fdt1, uint64_t fdt2)
1621 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1622 uint32_t fsth0 = fdt0 >> 32;
1623 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1624 uint32_t fsth1 = fdt1 >> 32;
1625 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1626 uint32_t fsth2 = fdt2 >> 32;
1628 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1629 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1630 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1631 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1633 update_fcr31(env, GETPC());
1634 return ((uint64_t)fsth0 << 32) | fstl0;
1637 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1638 uint64_t fst1, uint64_t fst2)
1640 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1641 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1642 fst0 = float64_chs(fst0);
1644 update_fcr31(env, GETPC());
1645 return fst0;
1648 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1649 uint32_t fst1, uint32_t fst2)
1651 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1652 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1653 fst0 = float32_chs(fst0);
1655 update_fcr31(env, GETPC());
1656 return fst0;
1659 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1660 uint64_t fdt1, uint64_t fdt2)
1662 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1663 uint32_t fsth0 = fdt0 >> 32;
1664 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1665 uint32_t fsth1 = fdt1 >> 32;
1666 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1667 uint32_t fsth2 = fdt2 >> 32;
1669 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1670 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1671 fstl0 = float32_chs(fstl0);
1672 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1673 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1674 fsth0 = float32_chs(fsth0);
1676 update_fcr31(env, GETPC());
1677 return ((uint64_t)fsth0 << 32) | fstl0;
1680 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1681 uint64_t fst1, uint64_t fst2)
1683 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1684 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1685 fst0 = float64_chs(fst0);
1687 update_fcr31(env, GETPC());
1688 return fst0;
1691 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1692 uint32_t fst1, uint32_t fst2)
1694 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1695 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1696 fst0 = float32_chs(fst0);
1698 update_fcr31(env, GETPC());
1699 return fst0;
1702 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1703 uint64_t fdt1, uint64_t fdt2)
1705 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1706 uint32_t fsth0 = fdt0 >> 32;
1707 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1708 uint32_t fsth1 = fdt1 >> 32;
1709 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1710 uint32_t fsth2 = fdt2 >> 32;
1712 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1713 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1714 fstl0 = float32_chs(fstl0);
1715 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1716 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1717 fsth0 = float32_chs(fsth0);
1719 update_fcr31(env, GETPC());
1720 return ((uint64_t)fsth0 << 32) | fstl0;
1724 uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
1725 uint32_t ft, uint32_t fd)
1727 uint32_t fdret;
1729 fdret = float32_muladd(fs, ft, fd, 0,
1730 &env->active_fpu.fp_status);
1732 update_fcr31(env, GETPC());
1733 return fdret;
1736 uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
1737 uint64_t ft, uint64_t fd)
1739 uint64_t fdret;
1741 fdret = float64_muladd(fs, ft, fd, 0,
1742 &env->active_fpu.fp_status);
1744 update_fcr31(env, GETPC());
1745 return fdret;
1748 uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
1749 uint32_t ft, uint32_t fd)
1751 uint32_t fdret;
1753 fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
1754 &env->active_fpu.fp_status);
1756 update_fcr31(env, GETPC());
1757 return fdret;
1760 uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
1761 uint64_t ft, uint64_t fd)
1763 uint64_t fdret;
1765 fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
1766 &env->active_fpu.fp_status);
1768 update_fcr31(env, GETPC());
1769 return fdret;
1773 /* compare operations */
1774 #define FOP_COND_D(op, cond) \
1775 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1776 uint64_t fdt1, int cc) \
1778 int c; \
1779 c = cond; \
1780 update_fcr31(env, GETPC()); \
1781 if (c) \
1782 SET_FP_COND(cc, env->active_fpu); \
1783 else \
1784 CLEAR_FP_COND(cc, env->active_fpu); \
1786 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1787 uint64_t fdt1, int cc) \
1789 int c; \
1790 fdt0 = float64_abs(fdt0); \
1791 fdt1 = float64_abs(fdt1); \
1792 c = cond; \
1793 update_fcr31(env, GETPC()); \
1794 if (c) \
1795 SET_FP_COND(cc, env->active_fpu); \
1796 else \
1797 CLEAR_FP_COND(cc, env->active_fpu); \
1801 * NOTE: the comma operator will make "cond" to eval to false,
1802 * but float64_unordered_quiet() is still called.
1804 FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0,
1805 &env->active_fpu.fp_status), 0))
1806 FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0,
1807 &env->active_fpu.fp_status))
1808 FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1,
1809 &env->active_fpu.fp_status))
1810 FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0,
1811 &env->active_fpu.fp_status)
1812 || float64_eq_quiet(fdt0, fdt1,
1813 &env->active_fpu.fp_status))
1814 FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1,
1815 &env->active_fpu.fp_status))
1816 FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0,
1817 &env->active_fpu.fp_status)
1818 || float64_lt_quiet(fdt0, fdt1,
1819 &env->active_fpu.fp_status))
1820 FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1,
1821 &env->active_fpu.fp_status))
1822 FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0,
1823 &env->active_fpu.fp_status)
1824 || float64_le_quiet(fdt0, fdt1,
1825 &env->active_fpu.fp_status))
1827 * NOTE: the comma operator will make "cond" to eval to false,
1828 * but float64_unordered() is still called.
1830 FOP_COND_D(sf, (float64_unordered(fdt1, fdt0,
1831 &env->active_fpu.fp_status), 0))
1832 FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
1833 &env->active_fpu.fp_status))
1834 FOP_COND_D(seq, float64_eq(fdt0, fdt1,
1835 &env->active_fpu.fp_status))
1836 FOP_COND_D(ngl, float64_unordered(fdt1, fdt0,
1837 &env->active_fpu.fp_status)
1838 || float64_eq(fdt0, fdt1,
1839 &env->active_fpu.fp_status))
1840 FOP_COND_D(lt, float64_lt(fdt0, fdt1,
1841 &env->active_fpu.fp_status))
1842 FOP_COND_D(nge, float64_unordered(fdt1, fdt0,
1843 &env->active_fpu.fp_status)
1844 || float64_lt(fdt0, fdt1,
1845 &env->active_fpu.fp_status))
1846 FOP_COND_D(le, float64_le(fdt0, fdt1,
1847 &env->active_fpu.fp_status))
1848 FOP_COND_D(ngt, float64_unordered(fdt1, fdt0,
1849 &env->active_fpu.fp_status)
1850 || float64_le(fdt0, fdt1,
1851 &env->active_fpu.fp_status))
1853 #define FOP_COND_S(op, cond) \
1854 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1855 uint32_t fst1, int cc) \
1857 int c; \
1858 c = cond; \
1859 update_fcr31(env, GETPC()); \
1860 if (c) \
1861 SET_FP_COND(cc, env->active_fpu); \
1862 else \
1863 CLEAR_FP_COND(cc, env->active_fpu); \
1865 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1866 uint32_t fst1, int cc) \
1868 int c; \
1869 fst0 = float32_abs(fst0); \
1870 fst1 = float32_abs(fst1); \
1871 c = cond; \
1872 update_fcr31(env, GETPC()); \
1873 if (c) \
1874 SET_FP_COND(cc, env->active_fpu); \
1875 else \
1876 CLEAR_FP_COND(cc, env->active_fpu); \
1880 * NOTE: the comma operator will make "cond" to eval to false,
1881 * but float32_unordered_quiet() is still called.
1883 FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0,
1884 &env->active_fpu.fp_status), 0))
1885 FOP_COND_S(un, float32_unordered_quiet(fst1, fst0,
1886 &env->active_fpu.fp_status))
1887 FOP_COND_S(eq, float32_eq_quiet(fst0, fst1,
1888 &env->active_fpu.fp_status))
1889 FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0,
1890 &env->active_fpu.fp_status)
1891 || float32_eq_quiet(fst0, fst1,
1892 &env->active_fpu.fp_status))
1893 FOP_COND_S(olt, float32_lt_quiet(fst0, fst1,
1894 &env->active_fpu.fp_status))
1895 FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0,
1896 &env->active_fpu.fp_status)
1897 || float32_lt_quiet(fst0, fst1,
1898 &env->active_fpu.fp_status))
1899 FOP_COND_S(ole, float32_le_quiet(fst0, fst1,
1900 &env->active_fpu.fp_status))
1901 FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0,
1902 &env->active_fpu.fp_status)
1903 || float32_le_quiet(fst0, fst1,
1904 &env->active_fpu.fp_status))
1906 * NOTE: the comma operator will make "cond" to eval to false,
1907 * but float32_unordered() is still called.
1909 FOP_COND_S(sf, (float32_unordered(fst1, fst0,
1910 &env->active_fpu.fp_status), 0))
1911 FOP_COND_S(ngle, float32_unordered(fst1, fst0,
1912 &env->active_fpu.fp_status))
1913 FOP_COND_S(seq, float32_eq(fst0, fst1,
1914 &env->active_fpu.fp_status))
1915 FOP_COND_S(ngl, float32_unordered(fst1, fst0,
1916 &env->active_fpu.fp_status)
1917 || float32_eq(fst0, fst1,
1918 &env->active_fpu.fp_status))
1919 FOP_COND_S(lt, float32_lt(fst0, fst1,
1920 &env->active_fpu.fp_status))
1921 FOP_COND_S(nge, float32_unordered(fst1, fst0,
1922 &env->active_fpu.fp_status)
1923 || float32_lt(fst0, fst1,
1924 &env->active_fpu.fp_status))
1925 FOP_COND_S(le, float32_le(fst0, fst1,
1926 &env->active_fpu.fp_status))
1927 FOP_COND_S(ngt, float32_unordered(fst1, fst0,
1928 &env->active_fpu.fp_status)
1929 || float32_le(fst0, fst1,
1930 &env->active_fpu.fp_status))
1932 #define FOP_COND_PS(op, condl, condh) \
1933 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1934 uint64_t fdt1, int cc) \
1936 uint32_t fst0, fsth0, fst1, fsth1; \
1937 int ch, cl; \
1938 fst0 = fdt0 & 0XFFFFFFFF; \
1939 fsth0 = fdt0 >> 32; \
1940 fst1 = fdt1 & 0XFFFFFFFF; \
1941 fsth1 = fdt1 >> 32; \
1942 cl = condl; \
1943 ch = condh; \
1944 update_fcr31(env, GETPC()); \
1945 if (cl) \
1946 SET_FP_COND(cc, env->active_fpu); \
1947 else \
1948 CLEAR_FP_COND(cc, env->active_fpu); \
1949 if (ch) \
1950 SET_FP_COND(cc + 1, env->active_fpu); \
1951 else \
1952 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1954 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1955 uint64_t fdt1, int cc) \
1957 uint32_t fst0, fsth0, fst1, fsth1; \
1958 int ch, cl; \
1959 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1960 fsth0 = float32_abs(fdt0 >> 32); \
1961 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1962 fsth1 = float32_abs(fdt1 >> 32); \
1963 cl = condl; \
1964 ch = condh; \
1965 update_fcr31(env, GETPC()); \
1966 if (cl) \
1967 SET_FP_COND(cc, env->active_fpu); \
1968 else \
1969 CLEAR_FP_COND(cc, env->active_fpu); \
1970 if (ch) \
1971 SET_FP_COND(cc + 1, env->active_fpu); \
1972 else \
1973 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1977 * NOTE: the comma operator will make "cond" to eval to false,
1978 * but float32_unordered_quiet() is still called.
1980 FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0,
1981 &env->active_fpu.fp_status), 0),
1982 (float32_unordered_quiet(fsth1, fsth0,
1983 &env->active_fpu.fp_status), 0))
1984 FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0,
1985 &env->active_fpu.fp_status),
1986 float32_unordered_quiet(fsth1, fsth0,
1987 &env->active_fpu.fp_status))
1988 FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1,
1989 &env->active_fpu.fp_status),
1990 float32_eq_quiet(fsth0, fsth1,
1991 &env->active_fpu.fp_status))
1992 FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0,
1993 &env->active_fpu.fp_status)
1994 || float32_eq_quiet(fst0, fst1,
1995 &env->active_fpu.fp_status),
1996 float32_unordered_quiet(fsth1, fsth0,
1997 &env->active_fpu.fp_status)
1998 || float32_eq_quiet(fsth0, fsth1,
1999 &env->active_fpu.fp_status))
2000 FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1,
2001 &env->active_fpu.fp_status),
2002 float32_lt_quiet(fsth0, fsth1,
2003 &env->active_fpu.fp_status))
2004 FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0,
2005 &env->active_fpu.fp_status)
2006 || float32_lt_quiet(fst0, fst1,
2007 &env->active_fpu.fp_status),
2008 float32_unordered_quiet(fsth1, fsth0,
2009 &env->active_fpu.fp_status)
2010 || float32_lt_quiet(fsth0, fsth1,
2011 &env->active_fpu.fp_status))
2012 FOP_COND_PS(ole, float32_le_quiet(fst0, fst1,
2013 &env->active_fpu.fp_status),
2014 float32_le_quiet(fsth0, fsth1,
2015 &env->active_fpu.fp_status))
2016 FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0,
2017 &env->active_fpu.fp_status)
2018 || float32_le_quiet(fst0, fst1,
2019 &env->active_fpu.fp_status),
2020 float32_unordered_quiet(fsth1, fsth0,
2021 &env->active_fpu.fp_status)
2022 || float32_le_quiet(fsth0, fsth1,
2023 &env->active_fpu.fp_status))
2025 * NOTE: the comma operator will make "cond" to eval to false,
2026 * but float32_unordered() is still called.
2028 FOP_COND_PS(sf, (float32_unordered(fst1, fst0,
2029 &env->active_fpu.fp_status), 0),
2030 (float32_unordered(fsth1, fsth0,
2031 &env->active_fpu.fp_status), 0))
2032 FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
2033 &env->active_fpu.fp_status),
2034 float32_unordered(fsth1, fsth0,
2035 &env->active_fpu.fp_status))
2036 FOP_COND_PS(seq, float32_eq(fst0, fst1,
2037 &env->active_fpu.fp_status),
2038 float32_eq(fsth0, fsth1,
2039 &env->active_fpu.fp_status))
2040 FOP_COND_PS(ngl, float32_unordered(fst1, fst0,
2041 &env->active_fpu.fp_status)
2042 || float32_eq(fst0, fst1,
2043 &env->active_fpu.fp_status),
2044 float32_unordered(fsth1, fsth0,
2045 &env->active_fpu.fp_status)
2046 || float32_eq(fsth0, fsth1,
2047 &env->active_fpu.fp_status))
2048 FOP_COND_PS(lt, float32_lt(fst0, fst1,
2049 &env->active_fpu.fp_status),
2050 float32_lt(fsth0, fsth1,
2051 &env->active_fpu.fp_status))
2052 FOP_COND_PS(nge, float32_unordered(fst1, fst0,
2053 &env->active_fpu.fp_status)
2054 || float32_lt(fst0, fst1,
2055 &env->active_fpu.fp_status),
2056 float32_unordered(fsth1, fsth0,
2057 &env->active_fpu.fp_status)
2058 || float32_lt(fsth0, fsth1,
2059 &env->active_fpu.fp_status))
2060 FOP_COND_PS(le, float32_le(fst0, fst1,
2061 &env->active_fpu.fp_status),
2062 float32_le(fsth0, fsth1,
2063 &env->active_fpu.fp_status))
2064 FOP_COND_PS(ngt, float32_unordered(fst1, fst0,
2065 &env->active_fpu.fp_status)
2066 || float32_le(fst0, fst1,
2067 &env->active_fpu.fp_status),
2068 float32_unordered(fsth1, fsth0,
2069 &env->active_fpu.fp_status)
2070 || float32_le(fsth0, fsth1,
2071 &env->active_fpu.fp_status))
2073 /* R6 compare operations */
2074 #define FOP_CONDN_D(op, cond) \
2075 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
2076 uint64_t fdt1) \
2078 uint64_t c; \
2079 c = cond; \
2080 update_fcr31(env, GETPC()); \
2081 if (c) { \
2082 return -1; \
2083 } else { \
2084 return 0; \
2089 * NOTE: the comma operator will make "cond" to eval to false,
2090 * but float64_unordered_quiet() is still called.
2092 FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0,
2093 &env->active_fpu.fp_status), 0))
2094 FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0,
2095 &env->active_fpu.fp_status)))
2096 FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1,
2097 &env->active_fpu.fp_status)))
2098 FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
2099 &env->active_fpu.fp_status)
2100 || float64_eq_quiet(fdt0, fdt1,
2101 &env->active_fpu.fp_status)))
2102 FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1,
2103 &env->active_fpu.fp_status)))
2104 FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
2105 &env->active_fpu.fp_status)
2106 || float64_lt_quiet(fdt0, fdt1,
2107 &env->active_fpu.fp_status)))
2108 FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1,
2109 &env->active_fpu.fp_status)))
2110 FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
2111 &env->active_fpu.fp_status)
2112 || float64_le_quiet(fdt0, fdt1,
2113 &env->active_fpu.fp_status)))
2115 * NOTE: the comma operator will make "cond" to eval to false,
2116 * but float64_unordered() is still called.\
2118 FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0,
2119 &env->active_fpu.fp_status), 0))
2120 FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0,
2121 &env->active_fpu.fp_status)))
2122 FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1,
2123 &env->active_fpu.fp_status)))
2124 FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
2125 &env->active_fpu.fp_status)
2126 || float64_eq(fdt0, fdt1,
2127 &env->active_fpu.fp_status)))
2128 FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1,
2129 &env->active_fpu.fp_status)))
2130 FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
2131 &env->active_fpu.fp_status)
2132 || float64_lt(fdt0, fdt1,
2133 &env->active_fpu.fp_status)))
2134 FOP_CONDN_D(sle, (float64_le(fdt0, fdt1,
2135 &env->active_fpu.fp_status)))
2136 FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
2137 &env->active_fpu.fp_status)
2138 || float64_le(fdt0, fdt1,
2139 &env->active_fpu.fp_status)))
2140 FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0,
2141 &env->active_fpu.fp_status)
2142 || float64_le_quiet(fdt0, fdt1,
2143 &env->active_fpu.fp_status)))
2144 FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0,
2145 &env->active_fpu.fp_status)
2146 || float64_lt_quiet(fdt1, fdt0,
2147 &env->active_fpu.fp_status)
2148 || float64_lt_quiet(fdt0, fdt1,
2149 &env->active_fpu.fp_status)))
2150 FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0,
2151 &env->active_fpu.fp_status)
2152 || float64_lt_quiet(fdt0, fdt1,
2153 &env->active_fpu.fp_status)))
2154 FOP_CONDN_D(sor, (float64_le(fdt1, fdt0,
2155 &env->active_fpu.fp_status)
2156 || float64_le(fdt0, fdt1,
2157 &env->active_fpu.fp_status)))
2158 FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
2159 &env->active_fpu.fp_status)
2160 || float64_lt(fdt1, fdt0,
2161 &env->active_fpu.fp_status)
2162 || float64_lt(fdt0, fdt1,
2163 &env->active_fpu.fp_status)))
2164 FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0,
2165 &env->active_fpu.fp_status)
2166 || float64_lt(fdt0, fdt1,
2167 &env->active_fpu.fp_status)))
2169 #define FOP_CONDN_S(op, cond) \
2170 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2171 uint32_t fst1) \
2173 uint64_t c; \
2174 c = cond; \
2175 update_fcr31(env, GETPC()); \
2176 if (c) { \
2177 return -1; \
2178 } else { \
2179 return 0; \
2184 * NOTE: the comma operator will make "cond" to eval to false,
2185 * but float32_unordered_quiet() is still called.
2187 FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0,
2188 &env->active_fpu.fp_status), 0))
2189 FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0,
2190 &env->active_fpu.fp_status)))
2191 FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1,
2192 &env->active_fpu.fp_status)))
2193 FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0,
2194 &env->active_fpu.fp_status)
2195 || float32_eq_quiet(fst0, fst1,
2196 &env->active_fpu.fp_status)))
2197 FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1,
2198 &env->active_fpu.fp_status)))
2199 FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0,
2200 &env->active_fpu.fp_status)
2201 || float32_lt_quiet(fst0, fst1,
2202 &env->active_fpu.fp_status)))
2203 FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1,
2204 &env->active_fpu.fp_status)))
2205 FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0,
2206 &env->active_fpu.fp_status)
2207 || float32_le_quiet(fst0, fst1,
2208 &env->active_fpu.fp_status)))
2210 * NOTE: the comma operator will make "cond" to eval to false,
2211 * but float32_unordered() is still called.
2213 FOP_CONDN_S(saf, (float32_unordered(fst1, fst0,
2214 &env->active_fpu.fp_status), 0))
2215 FOP_CONDN_S(sun, (float32_unordered(fst1, fst0,
2216 &env->active_fpu.fp_status)))
2217 FOP_CONDN_S(seq, (float32_eq(fst0, fst1,
2218 &env->active_fpu.fp_status)))
2219 FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
2220 &env->active_fpu.fp_status)
2221 || float32_eq(fst0, fst1,
2222 &env->active_fpu.fp_status)))
2223 FOP_CONDN_S(slt, (float32_lt(fst0, fst1,
2224 &env->active_fpu.fp_status)))
2225 FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
2226 &env->active_fpu.fp_status)
2227 || float32_lt(fst0, fst1,
2228 &env->active_fpu.fp_status)))
2229 FOP_CONDN_S(sle, (float32_le(fst0, fst1,
2230 &env->active_fpu.fp_status)))
2231 FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
2232 &env->active_fpu.fp_status)
2233 || float32_le(fst0, fst1,
2234 &env->active_fpu.fp_status)))
2235 FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0,
2236 &env->active_fpu.fp_status)
2237 || float32_le_quiet(fst0, fst1,
2238 &env->active_fpu.fp_status)))
2239 FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0,
2240 &env->active_fpu.fp_status)
2241 || float32_lt_quiet(fst1, fst0,
2242 &env->active_fpu.fp_status)
2243 || float32_lt_quiet(fst0, fst1,
2244 &env->active_fpu.fp_status)))
2245 FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0,
2246 &env->active_fpu.fp_status)
2247 || float32_lt_quiet(fst0, fst1,
2248 &env->active_fpu.fp_status)))
2249 FOP_CONDN_S(sor, (float32_le(fst1, fst0,
2250 &env->active_fpu.fp_status)
2251 || float32_le(fst0, fst1,
2252 &env->active_fpu.fp_status)))
2253 FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
2254 &env->active_fpu.fp_status)
2255 || float32_lt(fst1, fst0,
2256 &env->active_fpu.fp_status)
2257 || float32_lt(fst0, fst1,
2258 &env->active_fpu.fp_status)))
2259 FOP_CONDN_S(sne, (float32_lt(fst1, fst0,
2260 &env->active_fpu.fp_status)
2261 || float32_lt(fst0, fst1,
2262 &env->active_fpu.fp_status)))