hw/mips/cps: Expose input clock and connect it to CPU cores
[qemu/ar7.git] / target / mips / fpu_helper.c
blob6cc956c023d9cc93ac29a6968b9fb925aed46939
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 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 "qemu/main-loop.h"
25 #include "cpu.h"
26 #include "internal.h"
27 #include "qemu/host-utils.h"
28 #include "exec/helper-proto.h"
29 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "exec/memop.h"
32 #include "sysemu/kvm.h"
33 #include "fpu/softfloat.h"
36 /* Complex FPU operations which may need stack space. */
38 #define FLOAT_TWO32 make_float32(1 << 30)
39 #define FLOAT_TWO64 make_float64(1ULL << 62)
41 #define FP_TO_INT32_OVERFLOW 0x7fffffff
42 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
44 /* convert MIPS rounding mode in FCR31 to IEEE library */
45 unsigned int ieee_rm[] = {
46 float_round_nearest_even,
47 float_round_to_zero,
48 float_round_up,
49 float_round_down
52 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
54 target_ulong arg1 = 0;
56 switch (reg) {
57 case 0:
58 arg1 = (int32_t)env->active_fpu.fcr0;
59 break;
60 case 1:
61 /* UFR Support - Read Status FR */
62 if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
63 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
64 arg1 = (int32_t)
65 ((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR);
66 } else {
67 do_raise_exception(env, EXCP_RI, GETPC());
70 break;
71 case 5:
72 /* FRE Support - read Config5.FRE bit */
73 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
74 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
75 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
76 } else {
77 helper_raise_exception(env, EXCP_RI);
80 break;
81 case 25:
82 arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
83 ((env->active_fpu.fcr31 >> 23) & 0x1);
84 break;
85 case 26:
86 arg1 = env->active_fpu.fcr31 & 0x0003f07c;
87 break;
88 case 28:
89 arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
90 ((env->active_fpu.fcr31 >> 22) & 0x4);
91 break;
92 default:
93 arg1 = (int32_t)env->active_fpu.fcr31;
94 break;
97 return arg1;
100 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
102 switch (fs) {
103 case 1:
104 /* UFR Alias - Reset Status FR */
105 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
106 return;
108 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
109 env->CP0_Status &= ~(1 << CP0St_FR);
110 compute_hflags(env);
111 } else {
112 do_raise_exception(env, EXCP_RI, GETPC());
114 break;
115 case 4:
116 /* UNFR Alias - Set Status FR */
117 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
118 return;
120 if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
121 env->CP0_Status |= (1 << CP0St_FR);
122 compute_hflags(env);
123 } else {
124 do_raise_exception(env, EXCP_RI, GETPC());
126 break;
127 case 5:
128 /* FRE Support - clear Config5.FRE bit */
129 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
130 return;
132 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
133 env->CP0_Config5 &= ~(1 << CP0C5_FRE);
134 compute_hflags(env);
135 } else {
136 helper_raise_exception(env, EXCP_RI);
138 break;
139 case 6:
140 /* FRE Support - set Config5.FRE bit */
141 if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
142 return;
144 if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
145 env->CP0_Config5 |= (1 << CP0C5_FRE);
146 compute_hflags(env);
147 } else {
148 helper_raise_exception(env, EXCP_RI);
150 break;
151 case 25:
152 if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
153 return;
155 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
156 ((arg1 & 0xfe) << 24) |
157 ((arg1 & 0x1) << 23);
158 break;
159 case 26:
160 if (arg1 & 0x007c0000) {
161 return;
163 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
164 (arg1 & 0x0003f07c);
165 break;
166 case 28:
167 if (arg1 & 0x007c0000) {
168 return;
170 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
171 (arg1 & 0x00000f83) |
172 ((arg1 & 0x4) << 22);
173 break;
174 case 31:
175 env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
176 (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
177 break;
178 default:
179 if (env->insn_flags & ISA_MIPS32R6) {
180 do_raise_exception(env, EXCP_RI, GETPC());
182 return;
184 restore_fp_status(env);
185 set_float_exception_flags(0, &env->active_fpu.fp_status);
186 if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
187 GET_FP_CAUSE(env->active_fpu.fcr31)) {
188 do_raise_exception(env, EXCP_FPE, GETPC());
192 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
194 int mips_xcpt = 0;
196 if (ieee_xcpt & float_flag_invalid) {
197 mips_xcpt |= FP_INVALID;
199 if (ieee_xcpt & float_flag_overflow) {
200 mips_xcpt |= FP_OVERFLOW;
202 if (ieee_xcpt & float_flag_underflow) {
203 mips_xcpt |= FP_UNDERFLOW;
205 if (ieee_xcpt & float_flag_divbyzero) {
206 mips_xcpt |= FP_DIV0;
208 if (ieee_xcpt & float_flag_inexact) {
209 mips_xcpt |= FP_INEXACT;
212 return mips_xcpt;
215 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
217 int ieee_exception_flags = get_float_exception_flags(
218 &env->active_fpu.fp_status);
219 int mips_exception_flags = 0;
221 if (ieee_exception_flags) {
222 mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
225 SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
227 if (mips_exception_flags) {
228 set_float_exception_flags(0, &env->active_fpu.fp_status);
230 if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
231 do_raise_exception(env, EXCP_FPE, pc);
232 } else {
233 UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
239 * Float support.
240 * Single precition routines have a "s" suffix, double precision a
241 * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
242 * paired single lower "pl", paired single upper "pu".
245 /* unary operations, modifying fp status */
246 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
248 fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
249 update_fcr31(env, GETPC());
250 return fdt0;
253 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
255 fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
256 update_fcr31(env, GETPC());
257 return fst0;
260 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
262 uint64_t fdt2;
264 fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
265 update_fcr31(env, GETPC());
266 return fdt2;
269 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
271 uint64_t fdt2;
273 fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
274 update_fcr31(env, GETPC());
275 return fdt2;
278 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
280 uint64_t fdt2;
282 fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
283 update_fcr31(env, GETPC());
284 return fdt2;
287 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
289 uint64_t dt2;
291 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
292 if (get_float_exception_flags(&env->active_fpu.fp_status)
293 & (float_flag_invalid | float_flag_overflow)) {
294 dt2 = FP_TO_INT64_OVERFLOW;
296 update_fcr31(env, GETPC());
297 return dt2;
300 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
302 uint64_t dt2;
304 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
305 if (get_float_exception_flags(&env->active_fpu.fp_status)
306 & (float_flag_invalid | float_flag_overflow)) {
307 dt2 = FP_TO_INT64_OVERFLOW;
309 update_fcr31(env, GETPC());
310 return dt2;
313 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
315 uint32_t fst2;
316 uint32_t fsth2;
318 fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
319 fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
320 update_fcr31(env, GETPC());
321 return ((uint64_t)fsth2 << 32) | fst2;
324 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
326 uint32_t wt2;
327 uint32_t wth2;
328 int excp, excph;
330 wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
331 excp = get_float_exception_flags(&env->active_fpu.fp_status);
332 if (excp & (float_flag_overflow | float_flag_invalid)) {
333 wt2 = FP_TO_INT32_OVERFLOW;
336 set_float_exception_flags(0, &env->active_fpu.fp_status);
337 wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
338 excph = get_float_exception_flags(&env->active_fpu.fp_status);
339 if (excph & (float_flag_overflow | float_flag_invalid)) {
340 wth2 = FP_TO_INT32_OVERFLOW;
343 set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
344 update_fcr31(env, GETPC());
346 return ((uint64_t)wth2 << 32) | wt2;
349 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
351 uint32_t fst2;
353 fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
354 update_fcr31(env, GETPC());
355 return fst2;
358 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
360 uint32_t fst2;
362 fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
363 update_fcr31(env, GETPC());
364 return fst2;
367 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
369 uint32_t fst2;
371 fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
372 update_fcr31(env, GETPC());
373 return fst2;
376 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
378 uint32_t wt2;
380 wt2 = wt0;
381 update_fcr31(env, GETPC());
382 return wt2;
385 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
387 uint32_t wt2;
389 wt2 = wth0;
390 update_fcr31(env, GETPC());
391 return wt2;
394 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
396 uint32_t wt2;
398 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
399 if (get_float_exception_flags(&env->active_fpu.fp_status)
400 & (float_flag_invalid | float_flag_overflow)) {
401 wt2 = FP_TO_INT32_OVERFLOW;
403 update_fcr31(env, GETPC());
404 return wt2;
407 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
409 uint32_t wt2;
411 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
412 if (get_float_exception_flags(&env->active_fpu.fp_status)
413 & (float_flag_invalid | float_flag_overflow)) {
414 wt2 = FP_TO_INT32_OVERFLOW;
416 update_fcr31(env, GETPC());
417 return wt2;
420 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
422 uint64_t dt2;
424 set_float_rounding_mode(float_round_nearest_even,
425 &env->active_fpu.fp_status);
426 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
427 restore_rounding_mode(env);
428 if (get_float_exception_flags(&env->active_fpu.fp_status)
429 & (float_flag_invalid | float_flag_overflow)) {
430 dt2 = FP_TO_INT64_OVERFLOW;
432 update_fcr31(env, GETPC());
433 return dt2;
436 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
438 uint64_t dt2;
440 set_float_rounding_mode(float_round_nearest_even,
441 &env->active_fpu.fp_status);
442 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
443 restore_rounding_mode(env);
444 if (get_float_exception_flags(&env->active_fpu.fp_status)
445 & (float_flag_invalid | float_flag_overflow)) {
446 dt2 = FP_TO_INT64_OVERFLOW;
448 update_fcr31(env, GETPC());
449 return dt2;
452 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
454 uint32_t wt2;
456 set_float_rounding_mode(float_round_nearest_even,
457 &env->active_fpu.fp_status);
458 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
459 restore_rounding_mode(env);
460 if (get_float_exception_flags(&env->active_fpu.fp_status)
461 & (float_flag_invalid | float_flag_overflow)) {
462 wt2 = FP_TO_INT32_OVERFLOW;
464 update_fcr31(env, GETPC());
465 return wt2;
468 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
470 uint32_t wt2;
472 set_float_rounding_mode(float_round_nearest_even,
473 &env->active_fpu.fp_status);
474 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
475 restore_rounding_mode(env);
476 if (get_float_exception_flags(&env->active_fpu.fp_status)
477 & (float_flag_invalid | float_flag_overflow)) {
478 wt2 = FP_TO_INT32_OVERFLOW;
480 update_fcr31(env, GETPC());
481 return wt2;
484 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
486 uint64_t dt2;
488 dt2 = float64_to_int64_round_to_zero(fdt0,
489 &env->active_fpu.fp_status);
490 if (get_float_exception_flags(&env->active_fpu.fp_status)
491 & (float_flag_invalid | float_flag_overflow)) {
492 dt2 = FP_TO_INT64_OVERFLOW;
494 update_fcr31(env, GETPC());
495 return dt2;
498 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
500 uint64_t dt2;
502 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
503 if (get_float_exception_flags(&env->active_fpu.fp_status)
504 & (float_flag_invalid | float_flag_overflow)) {
505 dt2 = FP_TO_INT64_OVERFLOW;
507 update_fcr31(env, GETPC());
508 return dt2;
511 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
513 uint32_t wt2;
515 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
516 if (get_float_exception_flags(&env->active_fpu.fp_status)
517 & (float_flag_invalid | float_flag_overflow)) {
518 wt2 = FP_TO_INT32_OVERFLOW;
520 update_fcr31(env, GETPC());
521 return wt2;
524 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
526 uint32_t wt2;
528 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
529 if (get_float_exception_flags(&env->active_fpu.fp_status)
530 & (float_flag_invalid | float_flag_overflow)) {
531 wt2 = FP_TO_INT32_OVERFLOW;
533 update_fcr31(env, GETPC());
534 return wt2;
537 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
539 uint64_t dt2;
541 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
542 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
543 restore_rounding_mode(env);
544 if (get_float_exception_flags(&env->active_fpu.fp_status)
545 & (float_flag_invalid | float_flag_overflow)) {
546 dt2 = FP_TO_INT64_OVERFLOW;
548 update_fcr31(env, GETPC());
549 return dt2;
552 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
554 uint64_t dt2;
556 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
557 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
558 restore_rounding_mode(env);
559 if (get_float_exception_flags(&env->active_fpu.fp_status)
560 & (float_flag_invalid | float_flag_overflow)) {
561 dt2 = FP_TO_INT64_OVERFLOW;
563 update_fcr31(env, GETPC());
564 return dt2;
567 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
569 uint32_t wt2;
571 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
572 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
573 restore_rounding_mode(env);
574 if (get_float_exception_flags(&env->active_fpu.fp_status)
575 & (float_flag_invalid | float_flag_overflow)) {
576 wt2 = FP_TO_INT32_OVERFLOW;
578 update_fcr31(env, GETPC());
579 return wt2;
582 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
584 uint32_t wt2;
586 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
587 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
588 restore_rounding_mode(env);
589 if (get_float_exception_flags(&env->active_fpu.fp_status)
590 & (float_flag_invalid | float_flag_overflow)) {
591 wt2 = FP_TO_INT32_OVERFLOW;
593 update_fcr31(env, GETPC());
594 return wt2;
597 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
599 uint64_t dt2;
601 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
602 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
603 restore_rounding_mode(env);
604 if (get_float_exception_flags(&env->active_fpu.fp_status)
605 & (float_flag_invalid | float_flag_overflow)) {
606 dt2 = FP_TO_INT64_OVERFLOW;
608 update_fcr31(env, GETPC());
609 return dt2;
612 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
614 uint64_t dt2;
616 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
617 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
618 restore_rounding_mode(env);
619 if (get_float_exception_flags(&env->active_fpu.fp_status)
620 & (float_flag_invalid | float_flag_overflow)) {
621 dt2 = FP_TO_INT64_OVERFLOW;
623 update_fcr31(env, GETPC());
624 return dt2;
627 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
629 uint32_t wt2;
631 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
632 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
633 restore_rounding_mode(env);
634 if (get_float_exception_flags(&env->active_fpu.fp_status)
635 & (float_flag_invalid | float_flag_overflow)) {
636 wt2 = FP_TO_INT32_OVERFLOW;
638 update_fcr31(env, GETPC());
639 return wt2;
642 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
644 uint32_t wt2;
646 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
647 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
648 restore_rounding_mode(env);
649 if (get_float_exception_flags(&env->active_fpu.fp_status)
650 & (float_flag_invalid | float_flag_overflow)) {
651 wt2 = FP_TO_INT32_OVERFLOW;
653 update_fcr31(env, GETPC());
654 return wt2;
657 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
659 uint64_t dt2;
661 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
662 if (get_float_exception_flags(&env->active_fpu.fp_status)
663 & float_flag_invalid) {
664 if (float64_is_any_nan(fdt0)) {
665 dt2 = 0;
668 update_fcr31(env, GETPC());
669 return dt2;
672 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
674 uint64_t dt2;
676 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
677 if (get_float_exception_flags(&env->active_fpu.fp_status)
678 & float_flag_invalid) {
679 if (float32_is_any_nan(fst0)) {
680 dt2 = 0;
683 update_fcr31(env, GETPC());
684 return dt2;
687 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
689 uint32_t wt2;
691 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
692 if (get_float_exception_flags(&env->active_fpu.fp_status)
693 & float_flag_invalid) {
694 if (float64_is_any_nan(fdt0)) {
695 wt2 = 0;
698 update_fcr31(env, GETPC());
699 return wt2;
702 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
704 uint32_t wt2;
706 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
707 if (get_float_exception_flags(&env->active_fpu.fp_status)
708 & float_flag_invalid) {
709 if (float32_is_any_nan(fst0)) {
710 wt2 = 0;
713 update_fcr31(env, GETPC());
714 return wt2;
717 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
719 uint64_t dt2;
721 set_float_rounding_mode(float_round_nearest_even,
722 &env->active_fpu.fp_status);
723 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
724 restore_rounding_mode(env);
725 if (get_float_exception_flags(&env->active_fpu.fp_status)
726 & float_flag_invalid) {
727 if (float64_is_any_nan(fdt0)) {
728 dt2 = 0;
731 update_fcr31(env, GETPC());
732 return dt2;
735 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
737 uint64_t dt2;
739 set_float_rounding_mode(float_round_nearest_even,
740 &env->active_fpu.fp_status);
741 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
742 restore_rounding_mode(env);
743 if (get_float_exception_flags(&env->active_fpu.fp_status)
744 & float_flag_invalid) {
745 if (float32_is_any_nan(fst0)) {
746 dt2 = 0;
749 update_fcr31(env, GETPC());
750 return dt2;
753 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
755 uint32_t wt2;
757 set_float_rounding_mode(float_round_nearest_even,
758 &env->active_fpu.fp_status);
759 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
760 restore_rounding_mode(env);
761 if (get_float_exception_flags(&env->active_fpu.fp_status)
762 & float_flag_invalid) {
763 if (float64_is_any_nan(fdt0)) {
764 wt2 = 0;
767 update_fcr31(env, GETPC());
768 return wt2;
771 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
773 uint32_t wt2;
775 set_float_rounding_mode(float_round_nearest_even,
776 &env->active_fpu.fp_status);
777 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
778 restore_rounding_mode(env);
779 if (get_float_exception_flags(&env->active_fpu.fp_status)
780 & float_flag_invalid) {
781 if (float32_is_any_nan(fst0)) {
782 wt2 = 0;
785 update_fcr31(env, GETPC());
786 return wt2;
789 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
791 uint64_t dt2;
793 dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
794 if (get_float_exception_flags(&env->active_fpu.fp_status)
795 & float_flag_invalid) {
796 if (float64_is_any_nan(fdt0)) {
797 dt2 = 0;
800 update_fcr31(env, GETPC());
801 return dt2;
804 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
806 uint64_t dt2;
808 dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
809 if (get_float_exception_flags(&env->active_fpu.fp_status)
810 & float_flag_invalid) {
811 if (float32_is_any_nan(fst0)) {
812 dt2 = 0;
815 update_fcr31(env, GETPC());
816 return dt2;
819 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
821 uint32_t wt2;
823 wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
824 if (get_float_exception_flags(&env->active_fpu.fp_status)
825 & float_flag_invalid) {
826 if (float64_is_any_nan(fdt0)) {
827 wt2 = 0;
830 update_fcr31(env, GETPC());
831 return wt2;
834 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
836 uint32_t wt2;
838 wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
839 if (get_float_exception_flags(&env->active_fpu.fp_status)
840 & float_flag_invalid) {
841 if (float32_is_any_nan(fst0)) {
842 wt2 = 0;
845 update_fcr31(env, GETPC());
846 return wt2;
849 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
851 uint64_t dt2;
853 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
854 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
855 restore_rounding_mode(env);
856 if (get_float_exception_flags(&env->active_fpu.fp_status)
857 & float_flag_invalid) {
858 if (float64_is_any_nan(fdt0)) {
859 dt2 = 0;
862 update_fcr31(env, GETPC());
863 return dt2;
866 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
868 uint64_t dt2;
870 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
871 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
872 restore_rounding_mode(env);
873 if (get_float_exception_flags(&env->active_fpu.fp_status)
874 & float_flag_invalid) {
875 if (float32_is_any_nan(fst0)) {
876 dt2 = 0;
879 update_fcr31(env, GETPC());
880 return dt2;
883 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
885 uint32_t wt2;
887 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
888 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
889 restore_rounding_mode(env);
890 if (get_float_exception_flags(&env->active_fpu.fp_status)
891 & float_flag_invalid) {
892 if (float64_is_any_nan(fdt0)) {
893 wt2 = 0;
896 update_fcr31(env, GETPC());
897 return wt2;
900 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
902 uint32_t wt2;
904 set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
905 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
906 restore_rounding_mode(env);
907 if (get_float_exception_flags(&env->active_fpu.fp_status)
908 & float_flag_invalid) {
909 if (float32_is_any_nan(fst0)) {
910 wt2 = 0;
913 update_fcr31(env, GETPC());
914 return wt2;
917 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
919 uint64_t dt2;
921 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
922 dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
923 restore_rounding_mode(env);
924 if (get_float_exception_flags(&env->active_fpu.fp_status)
925 & float_flag_invalid) {
926 if (float64_is_any_nan(fdt0)) {
927 dt2 = 0;
930 update_fcr31(env, GETPC());
931 return dt2;
934 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
936 uint64_t dt2;
938 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
939 dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
940 restore_rounding_mode(env);
941 if (get_float_exception_flags(&env->active_fpu.fp_status)
942 & float_flag_invalid) {
943 if (float32_is_any_nan(fst0)) {
944 dt2 = 0;
947 update_fcr31(env, GETPC());
948 return dt2;
951 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
953 uint32_t wt2;
955 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
956 wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
957 restore_rounding_mode(env);
958 if (get_float_exception_flags(&env->active_fpu.fp_status)
959 & float_flag_invalid) {
960 if (float64_is_any_nan(fdt0)) {
961 wt2 = 0;
964 update_fcr31(env, GETPC());
965 return wt2;
968 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
970 uint32_t wt2;
972 set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
973 wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
974 restore_rounding_mode(env);
975 if (get_float_exception_flags(&env->active_fpu.fp_status)
976 & float_flag_invalid) {
977 if (float32_is_any_nan(fst0)) {
978 wt2 = 0;
981 update_fcr31(env, GETPC());
982 return wt2;
985 /* unary operations, not modifying fp status */
987 uint64_t helper_float_abs_d(uint64_t fdt0)
989 return float64_abs(fdt0);
992 uint32_t helper_float_abs_s(uint32_t fst0)
994 return float32_abs(fst0);
997 uint64_t helper_float_abs_ps(uint64_t fdt0)
999 uint32_t wt0;
1000 uint32_t wth0;
1002 wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
1003 wth0 = float32_abs(fdt0 >> 32);
1004 return ((uint64_t)wth0 << 32) | wt0;
1007 uint64_t helper_float_chs_d(uint64_t fdt0)
1009 return float64_chs(fdt0);
1012 uint32_t helper_float_chs_s(uint32_t fst0)
1014 return float32_chs(fst0);
1017 uint64_t helper_float_chs_ps(uint64_t fdt0)
1019 uint32_t wt0;
1020 uint32_t wth0;
1022 wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
1023 wth0 = float32_chs(fdt0 >> 32);
1024 return ((uint64_t)wth0 << 32) | wt0;
1027 /* MIPS specific unary operations */
1028 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1030 uint64_t fdt2;
1032 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1033 update_fcr31(env, GETPC());
1034 return fdt2;
1037 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1039 uint32_t fst2;
1041 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1042 update_fcr31(env, GETPC());
1043 return fst2;
1046 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1048 uint64_t fdt2;
1050 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1051 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1052 update_fcr31(env, GETPC());
1053 return fdt2;
1056 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1058 uint32_t fst2;
1060 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1061 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1062 update_fcr31(env, GETPC());
1063 return fst2;
1066 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1068 uint64_t fdt2;
1070 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1071 update_fcr31(env, GETPC());
1072 return fdt2;
1075 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1077 uint32_t fst2;
1079 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1080 update_fcr31(env, GETPC());
1081 return fst2;
1084 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1086 uint32_t fstl2;
1087 uint32_t fsth2;
1089 fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
1090 &env->active_fpu.fp_status);
1091 fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
1092 update_fcr31(env, GETPC());
1093 return ((uint64_t)fsth2 << 32) | fstl2;
1096 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1098 uint64_t fdt2;
1100 fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
1101 fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
1102 update_fcr31(env, GETPC());
1103 return fdt2;
1106 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1108 uint32_t fst2;
1110 fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
1111 fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
1112 update_fcr31(env, GETPC());
1113 return fst2;
1116 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1118 uint32_t fstl2;
1119 uint32_t fsth2;
1121 fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
1122 fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1123 fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
1124 fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
1125 update_fcr31(env, GETPC());
1126 return ((uint64_t)fsth2 << 32) | fstl2;
1129 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1131 uint64_t fdret;
1133 fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1134 update_fcr31(env, GETPC());
1135 return fdret;
1138 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1140 uint32_t fdret;
1142 fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1143 update_fcr31(env, GETPC());
1144 return fdret;
1147 #define FLOAT_CLASS_SIGNALING_NAN 0x001
1148 #define FLOAT_CLASS_QUIET_NAN 0x002
1149 #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1150 #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1151 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1152 #define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1153 #define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1154 #define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1155 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1156 #define FLOAT_CLASS_POSITIVE_ZERO 0x200
1158 uint64_t float_class_d(uint64_t arg, float_status *status)
1160 if (float64_is_signaling_nan(arg, status)) {
1161 return FLOAT_CLASS_SIGNALING_NAN;
1162 } else if (float64_is_quiet_nan(arg, status)) {
1163 return FLOAT_CLASS_QUIET_NAN;
1164 } else if (float64_is_neg(arg)) {
1165 if (float64_is_infinity(arg)) {
1166 return FLOAT_CLASS_NEGATIVE_INFINITY;
1167 } else if (float64_is_zero(arg)) {
1168 return FLOAT_CLASS_NEGATIVE_ZERO;
1169 } else if (float64_is_zero_or_denormal(arg)) {
1170 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1171 } else {
1172 return FLOAT_CLASS_NEGATIVE_NORMAL;
1174 } else {
1175 if (float64_is_infinity(arg)) {
1176 return FLOAT_CLASS_POSITIVE_INFINITY;
1177 } else if (float64_is_zero(arg)) {
1178 return FLOAT_CLASS_POSITIVE_ZERO;
1179 } else if (float64_is_zero_or_denormal(arg)) {
1180 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1181 } else {
1182 return FLOAT_CLASS_POSITIVE_NORMAL;
1187 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1189 return float_class_d(arg, &env->active_fpu.fp_status);
1192 uint32_t float_class_s(uint32_t arg, float_status *status)
1194 if (float32_is_signaling_nan(arg, status)) {
1195 return FLOAT_CLASS_SIGNALING_NAN;
1196 } else if (float32_is_quiet_nan(arg, status)) {
1197 return FLOAT_CLASS_QUIET_NAN;
1198 } else if (float32_is_neg(arg)) {
1199 if (float32_is_infinity(arg)) {
1200 return FLOAT_CLASS_NEGATIVE_INFINITY;
1201 } else if (float32_is_zero(arg)) {
1202 return FLOAT_CLASS_NEGATIVE_ZERO;
1203 } else if (float32_is_zero_or_denormal(arg)) {
1204 return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
1205 } else {
1206 return FLOAT_CLASS_NEGATIVE_NORMAL;
1208 } else {
1209 if (float32_is_infinity(arg)) {
1210 return FLOAT_CLASS_POSITIVE_INFINITY;
1211 } else if (float32_is_zero(arg)) {
1212 return FLOAT_CLASS_POSITIVE_ZERO;
1213 } else if (float32_is_zero_or_denormal(arg)) {
1214 return FLOAT_CLASS_POSITIVE_SUBNORMAL;
1215 } else {
1216 return FLOAT_CLASS_POSITIVE_NORMAL;
1221 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1223 return float_class_s(arg, &env->active_fpu.fp_status);
1226 /* binary operations */
1228 uint64_t helper_float_add_d(CPUMIPSState *env,
1229 uint64_t fdt0, uint64_t fdt1)
1231 uint64_t dt2;
1233 dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1234 update_fcr31(env, GETPC());
1235 return dt2;
1238 uint32_t helper_float_add_s(CPUMIPSState *env,
1239 uint32_t fst0, uint32_t fst1)
1241 uint32_t wt2;
1243 wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
1244 update_fcr31(env, GETPC());
1245 return wt2;
1248 uint64_t helper_float_add_ps(CPUMIPSState *env,
1249 uint64_t fdt0, uint64_t fdt1)
1251 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1252 uint32_t fsth0 = fdt0 >> 32;
1253 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1254 uint32_t fsth1 = fdt1 >> 32;
1255 uint32_t wtl2;
1256 uint32_t wth2;
1258 wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
1259 wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
1260 update_fcr31(env, GETPC());
1261 return ((uint64_t)wth2 << 32) | wtl2;
1264 uint64_t helper_float_sub_d(CPUMIPSState *env,
1265 uint64_t fdt0, uint64_t fdt1)
1267 uint64_t dt2;
1269 dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1270 update_fcr31(env, GETPC());
1271 return dt2;
1274 uint32_t helper_float_sub_s(CPUMIPSState *env,
1275 uint32_t fst0, uint32_t fst1)
1277 uint32_t wt2;
1279 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1280 update_fcr31(env, GETPC());
1281 return wt2;
1284 uint64_t helper_float_sub_ps(CPUMIPSState *env,
1285 uint64_t fdt0, uint64_t fdt1)
1287 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1288 uint32_t fsth0 = fdt0 >> 32;
1289 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1290 uint32_t fsth1 = fdt1 >> 32;
1291 uint32_t wtl2;
1292 uint32_t wth2;
1294 wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1295 wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1296 update_fcr31(env, GETPC());
1297 return ((uint64_t)wth2 << 32) | wtl2;
1300 uint64_t helper_float_mul_d(CPUMIPSState *env,
1301 uint64_t fdt0, uint64_t fdt1)
1303 uint64_t dt2;
1305 dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1306 update_fcr31(env, GETPC());
1307 return dt2;
1310 uint32_t helper_float_mul_s(CPUMIPSState *env,
1311 uint32_t fst0, uint32_t fst1)
1313 uint32_t wt2;
1315 wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1316 update_fcr31(env, GETPC());
1317 return wt2;
1320 uint64_t helper_float_mul_ps(CPUMIPSState *env,
1321 uint64_t fdt0, uint64_t fdt1)
1323 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1324 uint32_t fsth0 = fdt0 >> 32;
1325 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1326 uint32_t fsth1 = fdt1 >> 32;
1327 uint32_t wtl2;
1328 uint32_t wth2;
1330 wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1331 wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1332 update_fcr31(env, GETPC());
1333 return ((uint64_t)wth2 << 32) | wtl2;
1336 uint64_t helper_float_div_d(CPUMIPSState *env,
1337 uint64_t fdt0, uint64_t fdt1)
1339 uint64_t dt2;
1341 dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1342 update_fcr31(env, GETPC());
1343 return dt2;
1346 uint32_t helper_float_div_s(CPUMIPSState *env,
1347 uint32_t fst0, uint32_t fst1)
1349 uint32_t wt2;
1351 wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1352 update_fcr31(env, GETPC());
1353 return wt2;
1356 uint64_t helper_float_div_ps(CPUMIPSState *env,
1357 uint64_t fdt0, uint64_t fdt1)
1359 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1360 uint32_t fsth0 = fdt0 >> 32;
1361 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1362 uint32_t fsth1 = fdt1 >> 32;
1363 uint32_t wtl2;
1364 uint32_t wth2;
1366 wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1367 wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1368 update_fcr31(env, GETPC());
1369 return ((uint64_t)wth2 << 32) | wtl2;
1373 /* MIPS specific binary operations */
1374 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1376 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1377 fdt2 = float64_chs(float64_sub(fdt2, float64_one,
1378 &env->active_fpu.fp_status));
1379 update_fcr31(env, GETPC());
1380 return fdt2;
1383 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1385 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1386 fst2 = float32_chs(float32_sub(fst2, float32_one,
1387 &env->active_fpu.fp_status));
1388 update_fcr31(env, GETPC());
1389 return fst2;
1392 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1394 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1395 uint32_t fsth0 = fdt0 >> 32;
1396 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1397 uint32_t fsth2 = fdt2 >> 32;
1399 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1400 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1401 fstl2 = float32_chs(float32_sub(fstl2, float32_one,
1402 &env->active_fpu.fp_status));
1403 fsth2 = float32_chs(float32_sub(fsth2, float32_one,
1404 &env->active_fpu.fp_status));
1405 update_fcr31(env, GETPC());
1406 return ((uint64_t)fsth2 << 32) | fstl2;
1409 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1411 fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
1412 fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
1413 fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
1414 &env->active_fpu.fp_status));
1415 update_fcr31(env, GETPC());
1416 return fdt2;
1419 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1421 fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
1422 fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
1423 fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
1424 &env->active_fpu.fp_status));
1425 update_fcr31(env, GETPC());
1426 return fst2;
1429 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1431 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1432 uint32_t fsth0 = fdt0 >> 32;
1433 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1434 uint32_t fsth2 = fdt2 >> 32;
1436 fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
1437 fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1438 fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
1439 fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1440 fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
1441 &env->active_fpu.fp_status));
1442 fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
1443 &env->active_fpu.fp_status));
1444 update_fcr31(env, GETPC());
1445 return ((uint64_t)fsth2 << 32) | fstl2;
1448 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1450 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1451 uint32_t fsth0 = fdt0 >> 32;
1452 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1453 uint32_t fsth1 = fdt1 >> 32;
1454 uint32_t fstl2;
1455 uint32_t fsth2;
1457 fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1458 fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
1459 update_fcr31(env, GETPC());
1460 return ((uint64_t)fsth2 << 32) | fstl2;
1463 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1465 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1466 uint32_t fsth0 = fdt0 >> 32;
1467 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1468 uint32_t fsth1 = fdt1 >> 32;
1469 uint32_t fstl2;
1470 uint32_t fsth2;
1472 fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1473 fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
1474 update_fcr31(env, GETPC());
1475 return ((uint64_t)fsth2 << 32) | fstl2;
1479 uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1481 uint32_t fdret;
1483 fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
1485 update_fcr31(env, GETPC());
1486 return fdret;
1489 uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1491 uint64_t fdret;
1493 fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
1495 update_fcr31(env, GETPC());
1496 return fdret;
1499 uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1501 uint32_t fdret;
1503 fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
1505 update_fcr31(env, GETPC());
1506 return fdret;
1509 uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1511 uint64_t fdret;
1513 fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
1515 update_fcr31(env, GETPC());
1516 return fdret;
1519 uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1521 uint32_t fdret;
1523 fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
1525 update_fcr31(env, GETPC());
1526 return fdret;
1529 uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1531 uint64_t fdret;
1533 fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
1535 update_fcr31(env, GETPC());
1536 return fdret;
1539 uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1541 uint32_t fdret;
1543 fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
1545 update_fcr31(env, GETPC());
1546 return fdret;
1549 uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1551 uint64_t fdret;
1553 fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
1555 update_fcr31(env, GETPC());
1556 return fdret;
1560 /* ternary operations */
1562 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1563 uint64_t fst1, uint64_t fst2)
1565 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1566 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1568 update_fcr31(env, GETPC());
1569 return fst0;
1572 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1573 uint32_t fst1, uint32_t fst2)
1575 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1576 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1578 update_fcr31(env, GETPC());
1579 return fst0;
1582 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1583 uint64_t fdt1, uint64_t fdt2)
1585 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1586 uint32_t fsth0 = fdt0 >> 32;
1587 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1588 uint32_t fsth1 = fdt1 >> 32;
1589 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1590 uint32_t fsth2 = fdt2 >> 32;
1592 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1593 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1594 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1595 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1597 update_fcr31(env, GETPC());
1598 return ((uint64_t)fsth0 << 32) | fstl0;
1601 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1602 uint64_t fst1, uint64_t fst2)
1604 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1605 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1607 update_fcr31(env, GETPC());
1608 return fst0;
1611 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1612 uint32_t fst1, uint32_t fst2)
1614 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1615 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1617 update_fcr31(env, GETPC());
1618 return fst0;
1621 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1622 uint64_t fdt1, uint64_t fdt2)
1624 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1625 uint32_t fsth0 = fdt0 >> 32;
1626 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1627 uint32_t fsth1 = fdt1 >> 32;
1628 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1629 uint32_t fsth2 = fdt2 >> 32;
1631 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1632 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1633 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1634 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1636 update_fcr31(env, GETPC());
1637 return ((uint64_t)fsth0 << 32) | fstl0;
1640 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1641 uint64_t fst1, uint64_t fst2)
1643 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1644 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1645 fst0 = float64_chs(fst0);
1647 update_fcr31(env, GETPC());
1648 return fst0;
1651 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1652 uint32_t fst1, uint32_t fst2)
1654 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1655 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1656 fst0 = float32_chs(fst0);
1658 update_fcr31(env, GETPC());
1659 return fst0;
1662 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1663 uint64_t fdt1, uint64_t fdt2)
1665 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1666 uint32_t fsth0 = fdt0 >> 32;
1667 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1668 uint32_t fsth1 = fdt1 >> 32;
1669 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1670 uint32_t fsth2 = fdt2 >> 32;
1672 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1673 fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
1674 fstl0 = float32_chs(fstl0);
1675 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1676 fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
1677 fsth0 = float32_chs(fsth0);
1679 update_fcr31(env, GETPC());
1680 return ((uint64_t)fsth0 << 32) | fstl0;
1683 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1684 uint64_t fst1, uint64_t fst2)
1686 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1687 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1688 fst0 = float64_chs(fst0);
1690 update_fcr31(env, GETPC());
1691 return fst0;
1694 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1695 uint32_t fst1, uint32_t fst2)
1697 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1698 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1699 fst0 = float32_chs(fst0);
1701 update_fcr31(env, GETPC());
1702 return fst0;
1705 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1706 uint64_t fdt1, uint64_t fdt2)
1708 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1709 uint32_t fsth0 = fdt0 >> 32;
1710 uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1711 uint32_t fsth1 = fdt1 >> 32;
1712 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1713 uint32_t fsth2 = fdt2 >> 32;
1715 fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1716 fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1717 fstl0 = float32_chs(fstl0);
1718 fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1719 fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1720 fsth0 = float32_chs(fsth0);
1722 update_fcr31(env, GETPC());
1723 return ((uint64_t)fsth0 << 32) | fstl0;
1727 uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
1728 uint32_t ft, uint32_t fd)
1730 uint32_t fdret;
1732 fdret = float32_muladd(fs, ft, fd, 0,
1733 &env->active_fpu.fp_status);
1735 update_fcr31(env, GETPC());
1736 return fdret;
1739 uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
1740 uint64_t ft, uint64_t fd)
1742 uint64_t fdret;
1744 fdret = float64_muladd(fs, ft, fd, 0,
1745 &env->active_fpu.fp_status);
1747 update_fcr31(env, GETPC());
1748 return fdret;
1751 uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
1752 uint32_t ft, uint32_t fd)
1754 uint32_t fdret;
1756 fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
1757 &env->active_fpu.fp_status);
1759 update_fcr31(env, GETPC());
1760 return fdret;
1763 uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
1764 uint64_t ft, uint64_t fd)
1766 uint64_t fdret;
1768 fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
1769 &env->active_fpu.fp_status);
1771 update_fcr31(env, GETPC());
1772 return fdret;
1776 /* compare operations */
1777 #define FOP_COND_D(op, cond) \
1778 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1779 uint64_t fdt1, int cc) \
1781 int c; \
1782 c = cond; \
1783 update_fcr31(env, GETPC()); \
1784 if (c) \
1785 SET_FP_COND(cc, env->active_fpu); \
1786 else \
1787 CLEAR_FP_COND(cc, env->active_fpu); \
1789 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1790 uint64_t fdt1, int cc) \
1792 int c; \
1793 fdt0 = float64_abs(fdt0); \
1794 fdt1 = float64_abs(fdt1); \
1795 c = cond; \
1796 update_fcr31(env, GETPC()); \
1797 if (c) \
1798 SET_FP_COND(cc, env->active_fpu); \
1799 else \
1800 CLEAR_FP_COND(cc, env->active_fpu); \
1804 * NOTE: the comma operator will make "cond" to eval to false,
1805 * but float64_unordered_quiet() is still called.
1807 FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0,
1808 &env->active_fpu.fp_status), 0))
1809 FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0,
1810 &env->active_fpu.fp_status))
1811 FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1,
1812 &env->active_fpu.fp_status))
1813 FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0,
1814 &env->active_fpu.fp_status)
1815 || float64_eq_quiet(fdt0, fdt1,
1816 &env->active_fpu.fp_status))
1817 FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1,
1818 &env->active_fpu.fp_status))
1819 FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0,
1820 &env->active_fpu.fp_status)
1821 || float64_lt_quiet(fdt0, fdt1,
1822 &env->active_fpu.fp_status))
1823 FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1,
1824 &env->active_fpu.fp_status))
1825 FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0,
1826 &env->active_fpu.fp_status)
1827 || float64_le_quiet(fdt0, fdt1,
1828 &env->active_fpu.fp_status))
1830 * NOTE: the comma operator will make "cond" to eval to false,
1831 * but float64_unordered() is still called.
1833 FOP_COND_D(sf, (float64_unordered(fdt1, fdt0,
1834 &env->active_fpu.fp_status), 0))
1835 FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
1836 &env->active_fpu.fp_status))
1837 FOP_COND_D(seq, float64_eq(fdt0, fdt1,
1838 &env->active_fpu.fp_status))
1839 FOP_COND_D(ngl, float64_unordered(fdt1, fdt0,
1840 &env->active_fpu.fp_status)
1841 || float64_eq(fdt0, fdt1,
1842 &env->active_fpu.fp_status))
1843 FOP_COND_D(lt, float64_lt(fdt0, fdt1,
1844 &env->active_fpu.fp_status))
1845 FOP_COND_D(nge, float64_unordered(fdt1, fdt0,
1846 &env->active_fpu.fp_status)
1847 || float64_lt(fdt0, fdt1,
1848 &env->active_fpu.fp_status))
1849 FOP_COND_D(le, float64_le(fdt0, fdt1,
1850 &env->active_fpu.fp_status))
1851 FOP_COND_D(ngt, float64_unordered(fdt1, fdt0,
1852 &env->active_fpu.fp_status)
1853 || float64_le(fdt0, fdt1,
1854 &env->active_fpu.fp_status))
1856 #define FOP_COND_S(op, cond) \
1857 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1858 uint32_t fst1, int cc) \
1860 int c; \
1861 c = cond; \
1862 update_fcr31(env, GETPC()); \
1863 if (c) \
1864 SET_FP_COND(cc, env->active_fpu); \
1865 else \
1866 CLEAR_FP_COND(cc, env->active_fpu); \
1868 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1869 uint32_t fst1, int cc) \
1871 int c; \
1872 fst0 = float32_abs(fst0); \
1873 fst1 = float32_abs(fst1); \
1874 c = cond; \
1875 update_fcr31(env, GETPC()); \
1876 if (c) \
1877 SET_FP_COND(cc, env->active_fpu); \
1878 else \
1879 CLEAR_FP_COND(cc, env->active_fpu); \
1883 * NOTE: the comma operator will make "cond" to eval to false,
1884 * but float32_unordered_quiet() is still called.
1886 FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0,
1887 &env->active_fpu.fp_status), 0))
1888 FOP_COND_S(un, float32_unordered_quiet(fst1, fst0,
1889 &env->active_fpu.fp_status))
1890 FOP_COND_S(eq, float32_eq_quiet(fst0, fst1,
1891 &env->active_fpu.fp_status))
1892 FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0,
1893 &env->active_fpu.fp_status)
1894 || float32_eq_quiet(fst0, fst1,
1895 &env->active_fpu.fp_status))
1896 FOP_COND_S(olt, float32_lt_quiet(fst0, fst1,
1897 &env->active_fpu.fp_status))
1898 FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0,
1899 &env->active_fpu.fp_status)
1900 || float32_lt_quiet(fst0, fst1,
1901 &env->active_fpu.fp_status))
1902 FOP_COND_S(ole, float32_le_quiet(fst0, fst1,
1903 &env->active_fpu.fp_status))
1904 FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0,
1905 &env->active_fpu.fp_status)
1906 || float32_le_quiet(fst0, fst1,
1907 &env->active_fpu.fp_status))
1909 * NOTE: the comma operator will make "cond" to eval to false,
1910 * but float32_unordered() is still called.
1912 FOP_COND_S(sf, (float32_unordered(fst1, fst0,
1913 &env->active_fpu.fp_status), 0))
1914 FOP_COND_S(ngle, float32_unordered(fst1, fst0,
1915 &env->active_fpu.fp_status))
1916 FOP_COND_S(seq, float32_eq(fst0, fst1,
1917 &env->active_fpu.fp_status))
1918 FOP_COND_S(ngl, float32_unordered(fst1, fst0,
1919 &env->active_fpu.fp_status)
1920 || float32_eq(fst0, fst1,
1921 &env->active_fpu.fp_status))
1922 FOP_COND_S(lt, float32_lt(fst0, fst1,
1923 &env->active_fpu.fp_status))
1924 FOP_COND_S(nge, float32_unordered(fst1, fst0,
1925 &env->active_fpu.fp_status)
1926 || float32_lt(fst0, fst1,
1927 &env->active_fpu.fp_status))
1928 FOP_COND_S(le, float32_le(fst0, fst1,
1929 &env->active_fpu.fp_status))
1930 FOP_COND_S(ngt, float32_unordered(fst1, fst0,
1931 &env->active_fpu.fp_status)
1932 || float32_le(fst0, fst1,
1933 &env->active_fpu.fp_status))
1935 #define FOP_COND_PS(op, condl, condh) \
1936 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1937 uint64_t fdt1, int cc) \
1939 uint32_t fst0, fsth0, fst1, fsth1; \
1940 int ch, cl; \
1941 fst0 = fdt0 & 0XFFFFFFFF; \
1942 fsth0 = fdt0 >> 32; \
1943 fst1 = fdt1 & 0XFFFFFFFF; \
1944 fsth1 = fdt1 >> 32; \
1945 cl = condl; \
1946 ch = condh; \
1947 update_fcr31(env, GETPC()); \
1948 if (cl) \
1949 SET_FP_COND(cc, env->active_fpu); \
1950 else \
1951 CLEAR_FP_COND(cc, env->active_fpu); \
1952 if (ch) \
1953 SET_FP_COND(cc + 1, env->active_fpu); \
1954 else \
1955 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1957 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1958 uint64_t fdt1, int cc) \
1960 uint32_t fst0, fsth0, fst1, fsth1; \
1961 int ch, cl; \
1962 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1963 fsth0 = float32_abs(fdt0 >> 32); \
1964 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1965 fsth1 = float32_abs(fdt1 >> 32); \
1966 cl = condl; \
1967 ch = condh; \
1968 update_fcr31(env, GETPC()); \
1969 if (cl) \
1970 SET_FP_COND(cc, env->active_fpu); \
1971 else \
1972 CLEAR_FP_COND(cc, env->active_fpu); \
1973 if (ch) \
1974 SET_FP_COND(cc + 1, env->active_fpu); \
1975 else \
1976 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1980 * NOTE: the comma operator will make "cond" to eval to false,
1981 * but float32_unordered_quiet() is still called.
1983 FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0,
1984 &env->active_fpu.fp_status), 0),
1985 (float32_unordered_quiet(fsth1, fsth0,
1986 &env->active_fpu.fp_status), 0))
1987 FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0,
1988 &env->active_fpu.fp_status),
1989 float32_unordered_quiet(fsth1, fsth0,
1990 &env->active_fpu.fp_status))
1991 FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1,
1992 &env->active_fpu.fp_status),
1993 float32_eq_quiet(fsth0, fsth1,
1994 &env->active_fpu.fp_status))
1995 FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0,
1996 &env->active_fpu.fp_status)
1997 || float32_eq_quiet(fst0, fst1,
1998 &env->active_fpu.fp_status),
1999 float32_unordered_quiet(fsth1, fsth0,
2000 &env->active_fpu.fp_status)
2001 || float32_eq_quiet(fsth0, fsth1,
2002 &env->active_fpu.fp_status))
2003 FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1,
2004 &env->active_fpu.fp_status),
2005 float32_lt_quiet(fsth0, fsth1,
2006 &env->active_fpu.fp_status))
2007 FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0,
2008 &env->active_fpu.fp_status)
2009 || float32_lt_quiet(fst0, fst1,
2010 &env->active_fpu.fp_status),
2011 float32_unordered_quiet(fsth1, fsth0,
2012 &env->active_fpu.fp_status)
2013 || float32_lt_quiet(fsth0, fsth1,
2014 &env->active_fpu.fp_status))
2015 FOP_COND_PS(ole, float32_le_quiet(fst0, fst1,
2016 &env->active_fpu.fp_status),
2017 float32_le_quiet(fsth0, fsth1,
2018 &env->active_fpu.fp_status))
2019 FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0,
2020 &env->active_fpu.fp_status)
2021 || float32_le_quiet(fst0, fst1,
2022 &env->active_fpu.fp_status),
2023 float32_unordered_quiet(fsth1, fsth0,
2024 &env->active_fpu.fp_status)
2025 || float32_le_quiet(fsth0, fsth1,
2026 &env->active_fpu.fp_status))
2028 * NOTE: the comma operator will make "cond" to eval to false,
2029 * but float32_unordered() is still called.
2031 FOP_COND_PS(sf, (float32_unordered(fst1, fst0,
2032 &env->active_fpu.fp_status), 0),
2033 (float32_unordered(fsth1, fsth0,
2034 &env->active_fpu.fp_status), 0))
2035 FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
2036 &env->active_fpu.fp_status),
2037 float32_unordered(fsth1, fsth0,
2038 &env->active_fpu.fp_status))
2039 FOP_COND_PS(seq, float32_eq(fst0, fst1,
2040 &env->active_fpu.fp_status),
2041 float32_eq(fsth0, fsth1,
2042 &env->active_fpu.fp_status))
2043 FOP_COND_PS(ngl, float32_unordered(fst1, fst0,
2044 &env->active_fpu.fp_status)
2045 || float32_eq(fst0, fst1,
2046 &env->active_fpu.fp_status),
2047 float32_unordered(fsth1, fsth0,
2048 &env->active_fpu.fp_status)
2049 || float32_eq(fsth0, fsth1,
2050 &env->active_fpu.fp_status))
2051 FOP_COND_PS(lt, float32_lt(fst0, fst1,
2052 &env->active_fpu.fp_status),
2053 float32_lt(fsth0, fsth1,
2054 &env->active_fpu.fp_status))
2055 FOP_COND_PS(nge, float32_unordered(fst1, fst0,
2056 &env->active_fpu.fp_status)
2057 || float32_lt(fst0, fst1,
2058 &env->active_fpu.fp_status),
2059 float32_unordered(fsth1, fsth0,
2060 &env->active_fpu.fp_status)
2061 || float32_lt(fsth0, fsth1,
2062 &env->active_fpu.fp_status))
2063 FOP_COND_PS(le, float32_le(fst0, fst1,
2064 &env->active_fpu.fp_status),
2065 float32_le(fsth0, fsth1,
2066 &env->active_fpu.fp_status))
2067 FOP_COND_PS(ngt, float32_unordered(fst1, fst0,
2068 &env->active_fpu.fp_status)
2069 || float32_le(fst0, fst1,
2070 &env->active_fpu.fp_status),
2071 float32_unordered(fsth1, fsth0,
2072 &env->active_fpu.fp_status)
2073 || float32_le(fsth0, fsth1,
2074 &env->active_fpu.fp_status))
2076 /* R6 compare operations */
2077 #define FOP_CONDN_D(op, cond) \
2078 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
2079 uint64_t fdt1) \
2081 uint64_t c; \
2082 c = cond; \
2083 update_fcr31(env, GETPC()); \
2084 if (c) { \
2085 return -1; \
2086 } else { \
2087 return 0; \
2092 * NOTE: the comma operator will make "cond" to eval to false,
2093 * but float64_unordered_quiet() is still called.
2095 FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0,
2096 &env->active_fpu.fp_status), 0))
2097 FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0,
2098 &env->active_fpu.fp_status)))
2099 FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1,
2100 &env->active_fpu.fp_status)))
2101 FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
2102 &env->active_fpu.fp_status)
2103 || float64_eq_quiet(fdt0, fdt1,
2104 &env->active_fpu.fp_status)))
2105 FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1,
2106 &env->active_fpu.fp_status)))
2107 FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
2108 &env->active_fpu.fp_status)
2109 || float64_lt_quiet(fdt0, fdt1,
2110 &env->active_fpu.fp_status)))
2111 FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1,
2112 &env->active_fpu.fp_status)))
2113 FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
2114 &env->active_fpu.fp_status)
2115 || float64_le_quiet(fdt0, fdt1,
2116 &env->active_fpu.fp_status)))
2118 * NOTE: the comma operator will make "cond" to eval to false,
2119 * but float64_unordered() is still called.\
2121 FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0,
2122 &env->active_fpu.fp_status), 0))
2123 FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0,
2124 &env->active_fpu.fp_status)))
2125 FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1,
2126 &env->active_fpu.fp_status)))
2127 FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
2128 &env->active_fpu.fp_status)
2129 || float64_eq(fdt0, fdt1,
2130 &env->active_fpu.fp_status)))
2131 FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1,
2132 &env->active_fpu.fp_status)))
2133 FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
2134 &env->active_fpu.fp_status)
2135 || float64_lt(fdt0, fdt1,
2136 &env->active_fpu.fp_status)))
2137 FOP_CONDN_D(sle, (float64_le(fdt0, fdt1,
2138 &env->active_fpu.fp_status)))
2139 FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
2140 &env->active_fpu.fp_status)
2141 || float64_le(fdt0, fdt1,
2142 &env->active_fpu.fp_status)))
2143 FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0,
2144 &env->active_fpu.fp_status)
2145 || float64_le_quiet(fdt0, fdt1,
2146 &env->active_fpu.fp_status)))
2147 FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0,
2148 &env->active_fpu.fp_status)
2149 || float64_lt_quiet(fdt1, fdt0,
2150 &env->active_fpu.fp_status)
2151 || float64_lt_quiet(fdt0, fdt1,
2152 &env->active_fpu.fp_status)))
2153 FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0,
2154 &env->active_fpu.fp_status)
2155 || float64_lt_quiet(fdt0, fdt1,
2156 &env->active_fpu.fp_status)))
2157 FOP_CONDN_D(sor, (float64_le(fdt1, fdt0,
2158 &env->active_fpu.fp_status)
2159 || float64_le(fdt0, fdt1,
2160 &env->active_fpu.fp_status)))
2161 FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
2162 &env->active_fpu.fp_status)
2163 || float64_lt(fdt1, fdt0,
2164 &env->active_fpu.fp_status)
2165 || float64_lt(fdt0, fdt1,
2166 &env->active_fpu.fp_status)))
2167 FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0,
2168 &env->active_fpu.fp_status)
2169 || float64_lt(fdt0, fdt1,
2170 &env->active_fpu.fp_status)))
2172 #define FOP_CONDN_S(op, cond) \
2173 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2174 uint32_t fst1) \
2176 uint64_t c; \
2177 c = cond; \
2178 update_fcr31(env, GETPC()); \
2179 if (c) { \
2180 return -1; \
2181 } else { \
2182 return 0; \
2187 * NOTE: the comma operator will make "cond" to eval to false,
2188 * but float32_unordered_quiet() is still called.
2190 FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0,
2191 &env->active_fpu.fp_status), 0))
2192 FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0,
2193 &env->active_fpu.fp_status)))
2194 FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1,
2195 &env->active_fpu.fp_status)))
2196 FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0,
2197 &env->active_fpu.fp_status)
2198 || float32_eq_quiet(fst0, fst1,
2199 &env->active_fpu.fp_status)))
2200 FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1,
2201 &env->active_fpu.fp_status)))
2202 FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0,
2203 &env->active_fpu.fp_status)
2204 || float32_lt_quiet(fst0, fst1,
2205 &env->active_fpu.fp_status)))
2206 FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1,
2207 &env->active_fpu.fp_status)))
2208 FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0,
2209 &env->active_fpu.fp_status)
2210 || float32_le_quiet(fst0, fst1,
2211 &env->active_fpu.fp_status)))
2213 * NOTE: the comma operator will make "cond" to eval to false,
2214 * but float32_unordered() is still called.
2216 FOP_CONDN_S(saf, (float32_unordered(fst1, fst0,
2217 &env->active_fpu.fp_status), 0))
2218 FOP_CONDN_S(sun, (float32_unordered(fst1, fst0,
2219 &env->active_fpu.fp_status)))
2220 FOP_CONDN_S(seq, (float32_eq(fst0, fst1,
2221 &env->active_fpu.fp_status)))
2222 FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
2223 &env->active_fpu.fp_status)
2224 || float32_eq(fst0, fst1,
2225 &env->active_fpu.fp_status)))
2226 FOP_CONDN_S(slt, (float32_lt(fst0, fst1,
2227 &env->active_fpu.fp_status)))
2228 FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
2229 &env->active_fpu.fp_status)
2230 || float32_lt(fst0, fst1,
2231 &env->active_fpu.fp_status)))
2232 FOP_CONDN_S(sle, (float32_le(fst0, fst1,
2233 &env->active_fpu.fp_status)))
2234 FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
2235 &env->active_fpu.fp_status)
2236 || float32_le(fst0, fst1,
2237 &env->active_fpu.fp_status)))
2238 FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0,
2239 &env->active_fpu.fp_status)
2240 || float32_le_quiet(fst0, fst1,
2241 &env->active_fpu.fp_status)))
2242 FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0,
2243 &env->active_fpu.fp_status)
2244 || float32_lt_quiet(fst1, fst0,
2245 &env->active_fpu.fp_status)
2246 || float32_lt_quiet(fst0, fst1,
2247 &env->active_fpu.fp_status)))
2248 FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0,
2249 &env->active_fpu.fp_status)
2250 || float32_lt_quiet(fst0, fst1,
2251 &env->active_fpu.fp_status)))
2252 FOP_CONDN_S(sor, (float32_le(fst1, fst0,
2253 &env->active_fpu.fp_status)
2254 || float32_le(fst0, fst1,
2255 &env->active_fpu.fp_status)))
2256 FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
2257 &env->active_fpu.fp_status)
2258 || float32_lt(fst1, fst0,
2259 &env->active_fpu.fp_status)
2260 || float32_lt(fst0, fst1,
2261 &env->active_fpu.fp_status)))
2262 FOP_CONDN_S(sne, (float32_lt(fst1, fst0,
2263 &env->active_fpu.fp_status)
2264 || float32_lt(fst0, fst1,
2265 &env->active_fpu.fp_status)))