1 /*
2 * Helpers for emulation of FPU-related MIPS instructions.
3 *
4 * Copyright (C) 2004-2005 Jocelyn Mayer
5 * Copyright (C) 2020 Wave Computing, Inc.
6 * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
7 *
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.
12 *
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.
17 *
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/>.
20 *
21 */
22
23 #include "qemu/osdep.h"
24 #include "cpu.h"
25 #include "internal.h"
26 #include "exec/helper-proto.h"
27 #include "exec/exec-all.h"
28 #include "exec/cpu_ldst.h"
29 #include "fpu/softfloat.h"
30 #include "fpu_helper.h"
31
32
33 /* Complex FPU operations which may need stack space. */
34
35 #define FLOAT_TWO32 make_float32(1 << 30)
36 #define FLOAT_TWO64 make_float64(1ULL << 62)
37
38 #define FP_TO_INT32_OVERFLOW 0x7fffffff
39 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
40
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
47 };
48
helper_cfc1(CPUMIPSState * env,uint32_t reg)49 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
50 {
51 target_ulong arg1 = 0;
52
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());
65 }
66 }
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);
75 }
76 }
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;
92 }
93
94 return arg1;
95 }
96
helper_ctc1(CPUMIPSState * env,target_ulong arg1,uint32_t fs,uint32_t rt)97 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
98 {
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;
104 }
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());
110 }
111 break;
112 case 4:
113 /* UNFR Alias - Set Status FR */
114 if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
115 return;
116 }
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());
122 }
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;
128 }
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);
134 }
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;
140 }
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);
146 }
147 break;
148 case 25:
149 if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) {
150 return;
151 }
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;
159 }
160 env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
161 (arg1 & 0x0003f07c);
162 break;
163 case 28:
164 if (arg1 & 0x007c0000) {
165 return;
166 }
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());
178 }
179 return;
180 }
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());
186 }
187 }
188
ieee_to_mips_xcpt(int ieee_xcpt)189 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
190 {
191 int mips_xcpt = 0;
192
193 if (ieee_xcpt & float_flag_invalid) {
194 mips_xcpt |= FP_INVALID;
195 }
196 if (ieee_xcpt & float_flag_overflow) {
197 mips_xcpt |= FP_OVERFLOW;
198 }
199 if (ieee_xcpt & float_flag_underflow) {
200 mips_xcpt |= FP_UNDERFLOW;
201 }
202 if (ieee_xcpt & float_flag_divbyzero) {
203 mips_xcpt |= FP_DIV0;
204 }
205 if (ieee_xcpt & float_flag_inexact) {
206 mips_xcpt |= FP_INEXACT;
207 }
208
209 return mips_xcpt;
210 }
211
update_fcr31(CPUMIPSState * env,uintptr_t pc)212 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
213 {
214 int ieee_exception_flags = get_float_exception_flags(
215 &env->active_fpu.fp_status);
216 int mips_exception_flags = 0;
217
218 if (ieee_exception_flags) {
219 mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
220 }
221
222 SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
223
224 if (mips_exception_flags) {
225 set_float_exception_flags(0, &env->active_fpu.fp_status);
226
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);
231 }
232 }
233 }
234
235 /*
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".
240 */
241
242 /* unary operations, modifying fp status */
helper_float_sqrt_d(CPUMIPSState * env,uint64_t fdt0)243 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
244 {
245 fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
246 update_fcr31(env, GETPC());
247 return fdt0;
248 }
249
helper_float_sqrt_s(CPUMIPSState * env,uint32_t fst0)250 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
251 {
252 fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
253 update_fcr31(env, GETPC());
254 return fst0;
255 }
256
helper_float_cvtd_s(CPUMIPSState * env,uint32_t fst0)257 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
258 {
259 uint64_t fdt2;
260
261 fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
262 update_fcr31(env, GETPC());
263 return fdt2;
264 }
265
helper_float_cvtd_w(CPUMIPSState * env,uint32_t wt0)266 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
267 {
268 uint64_t fdt2;
269
270 fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
271 update_fcr31(env, GETPC());
272 return fdt2;
273 }
274
helper_float_cvtd_l(CPUMIPSState * env,uint64_t dt0)275 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
276 {
277 uint64_t fdt2;
278
279 fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
280 update_fcr31(env, GETPC());
281 return fdt2;
282 }
283
helper_float_cvt_l_d(CPUMIPSState * env,uint64_t fdt0)284 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
285 {
286 uint64_t dt2;
287
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;
292 }
293 update_fcr31(env, GETPC());
294 return dt2;
295 }
296
helper_float_cvt_l_s(CPUMIPSState * env,uint32_t fst0)297 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
298 {
299 uint64_t dt2;
300
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;
305 }
306 update_fcr31(env, GETPC());
307 return dt2;
308 }
309
helper_float_cvtps_pw(CPUMIPSState * env,uint64_t dt0)310 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
311 {
312 uint32_t fst2;
313 uint32_t fsth2;
314
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;
319 }
320
helper_float_cvtpw_ps(CPUMIPSState * env,uint64_t fdt0)321 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
322 {
323 uint32_t wt2;
324 uint32_t wth2;
325 int excp, excph;
326
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;
331 }
332
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;
338 }
339
340 set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
341 update_fcr31(env, GETPC());
342
343 return ((uint64_t)wth2 << 32) | wt2;
344 }
345
helper_float_cvts_d(CPUMIPSState * env,uint64_t fdt0)346 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
347 {
348 uint32_t fst2;
349
350 fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
351 update_fcr31(env, GETPC());
352 return fst2;
353 }
354
helper_float_cvts_w(CPUMIPSState * env,uint32_t wt0)355 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
356 {
357 uint32_t fst2;
358
359 fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
360 update_fcr31(env, GETPC());
361 return fst2;
362 }
363
helper_float_cvts_l(CPUMIPSState * env,uint64_t dt0)364 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
365 {
366 uint32_t fst2;
367
368 fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
369 update_fcr31(env, GETPC());
370 return fst2;
371 }
372
helper_float_cvts_pl(CPUMIPSState * env,uint32_t wt0)373 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
374 {
375 uint32_t wt2;
376
377 wt2 = wt0;
378 update_fcr31(env, GETPC());
379 return wt2;
380 }
381
helper_float_cvts_pu(CPUMIPSState * env,uint32_t wth0)382 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
383 {
384 uint32_t wt2;
385
386 wt2 = wth0;
387 update_fcr31(env, GETPC());
388 return wt2;
389 }
390
helper_float_cvt_w_s(CPUMIPSState * env,uint32_t fst0)391 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
392 {
393 uint32_t wt2;
394
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;
399 }
400 update_fcr31(env, GETPC());
401 return wt2;
402 }
403
helper_float_cvt_w_d(CPUMIPSState * env,uint64_t fdt0)404 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
405 {
406 uint32_t wt2;
407
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;
412 }
413 update_fcr31(env, GETPC());
414 return wt2;
415 }
416
helper_float_round_l_d(CPUMIPSState * env,uint64_t fdt0)417 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
418 {
419 uint64_t dt2;
420
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;
428 }
429 update_fcr31(env, GETPC());
430 return dt2;
431 }
432
helper_float_round_l_s(CPUMIPSState * env,uint32_t fst0)433 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
434 {
435 uint64_t dt2;
436
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;
444 }
445 update_fcr31(env, GETPC());
446 return dt2;
447 }
448
helper_float_round_w_d(CPUMIPSState * env,uint64_t fdt0)449 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
450 {
451 uint32_t wt2;
452
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;
460 }
461 update_fcr31(env, GETPC());
462 return wt2;
463 }
464
helper_float_round_w_s(CPUMIPSState * env,uint32_t fst0)465 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
466 {
467 uint32_t wt2;
468
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;
476 }
477 update_fcr31(env, GETPC());
478 return wt2;
479 }
480
helper_float_trunc_l_d(CPUMIPSState * env,uint64_t fdt0)481 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
482 {
483 uint64_t dt2;
484
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;
490 }
491 update_fcr31(env, GETPC());
492 return dt2;
493 }
494
helper_float_trunc_l_s(CPUMIPSState * env,uint32_t fst0)495 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
496 {
497 uint64_t dt2;
498
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;
503 }
504 update_fcr31(env, GETPC());
505 return dt2;
506 }
507
helper_float_trunc_w_d(CPUMIPSState * env,uint64_t fdt0)508 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
509 {
510 uint32_t wt2;
511
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;
516 }
517 update_fcr31(env, GETPC());
518 return wt2;
519 }
520
helper_float_trunc_w_s(CPUMIPSState * env,uint32_t fst0)521 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
522 {
523 uint32_t wt2;
524
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;
529 }
530 update_fcr31(env, GETPC());
531 return wt2;
532 }
533
helper_float_ceil_l_d(CPUMIPSState * env,uint64_t fdt0)534 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
535 {
536 uint64_t dt2;
537
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;
544 }
545 update_fcr31(env, GETPC());
546 return dt2;
547 }
548
helper_float_ceil_l_s(CPUMIPSState * env,uint32_t fst0)549 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
550 {
551 uint64_t dt2;
552
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;
559 }
560 update_fcr31(env, GETPC());
561 return dt2;
562 }
563
helper_float_ceil_w_d(CPUMIPSState * env,uint64_t fdt0)564 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
565 {
566 uint32_t wt2;
567
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;
574 }
575 update_fcr31(env, GETPC());
576 return wt2;
577 }
578
helper_float_ceil_w_s(CPUMIPSState * env,uint32_t fst0)579 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
580 {
581 uint32_t wt2;
582
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;
589 }
590 update_fcr31(env, GETPC());
591 return wt2;
592 }
593
helper_float_floor_l_d(CPUMIPSState * env,uint64_t fdt0)594 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
595 {
596 uint64_t dt2;
597
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;
604 }
605 update_fcr31(env, GETPC());
606 return dt2;
607 }
608
helper_float_floor_l_s(CPUMIPSState * env,uint32_t fst0)609 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
610 {
611 uint64_t dt2;
612
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;
619 }
620 update_fcr31(env, GETPC());
621 return dt2;
622 }
623
helper_float_floor_w_d(CPUMIPSState * env,uint64_t fdt0)624 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
625 {
626 uint32_t wt2;
627
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;
634 }
635 update_fcr31(env, GETPC());
636 return wt2;
637 }
638
helper_float_floor_w_s(CPUMIPSState * env,uint32_t fst0)639 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
640 {
641 uint32_t wt2;
642
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;
649 }
650 update_fcr31(env, GETPC());
651 return wt2;
652 }
653
helper_float_cvt_2008_l_d(CPUMIPSState * env,uint64_t fdt0)654 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
655 {
656 uint64_t dt2;
657
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;
663 }
664 }
665 update_fcr31(env, GETPC());
666 return dt2;
667 }
668
helper_float_cvt_2008_l_s(CPUMIPSState * env,uint32_t fst0)669 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
670 {
671 uint64_t dt2;
672
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;
678 }
679 }
680 update_fcr31(env, GETPC());
681 return dt2;
682 }
683
helper_float_cvt_2008_w_d(CPUMIPSState * env,uint64_t fdt0)684 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
685 {
686 uint32_t wt2;
687
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;
693 }
694 }
695 update_fcr31(env, GETPC());
696 return wt2;
697 }
698
helper_float_cvt_2008_w_s(CPUMIPSState * env,uint32_t fst0)699 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
700 {
701 uint32_t wt2;
702
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;
708 }
709 }
710 update_fcr31(env, GETPC());
711 return wt2;
712 }
713
helper_float_round_2008_l_d(CPUMIPSState * env,uint64_t fdt0)714 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
715 {
716 uint64_t dt2;
717
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;
726 }
727 }
728 update_fcr31(env, GETPC());
729 return dt2;
730 }
731
helper_float_round_2008_l_s(CPUMIPSState * env,uint32_t fst0)732 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
733 {
734 uint64_t dt2;
735
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;
744 }
745 }
746 update_fcr31(env, GETPC());
747 return dt2;
748 }
749
helper_float_round_2008_w_d(CPUMIPSState * env,uint64_t fdt0)750 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
751 {
752 uint32_t wt2;
753
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;
762 }
763 }
764 update_fcr31(env, GETPC());
765 return wt2;
766 }
767
helper_float_round_2008_w_s(CPUMIPSState * env,uint32_t fst0)768 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
769 {
770 uint32_t wt2;
771
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;
780 }
781 }
782 update_fcr31(env, GETPC());
783 return wt2;
784 }
785
helper_float_trunc_2008_l_d(CPUMIPSState * env,uint64_t fdt0)786 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
787 {
788 uint64_t dt2;
789
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;
795 }
796 }
797 update_fcr31(env, GETPC());
798 return dt2;
799 }
800
helper_float_trunc_2008_l_s(CPUMIPSState * env,uint32_t fst0)801 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
802 {
803 uint64_t dt2;
804
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;
810 }
811 }
812 update_fcr31(env, GETPC());
813 return dt2;
814 }
815
helper_float_trunc_2008_w_d(CPUMIPSState * env,uint64_t fdt0)816 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
817 {
818 uint32_t wt2;
819
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;
825 }
826 }
827 update_fcr31(env, GETPC());
828 return wt2;
829 }
830
helper_float_trunc_2008_w_s(CPUMIPSState * env,uint32_t fst0)831 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
832 {
833 uint32_t wt2;
834
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;
840 }
841 }
842 update_fcr31(env, GETPC());
843 return wt2;
844 }
845
helper_float_ceil_2008_l_d(CPUMIPSState * env,uint64_t fdt0)846 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
847 {
848 uint64_t dt2;
849
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;
857 }
858 }
859 update_fcr31(env, GETPC());
860 return dt2;
861 }
862
helper_float_ceil_2008_l_s(CPUMIPSState * env,uint32_t fst0)863 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
864 {
865 uint64_t dt2;
866
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;
874 }
875 }
876 update_fcr31(env, GETPC());
877 return dt2;
878 }
879
helper_float_ceil_2008_w_d(CPUMIPSState * env,uint64_t fdt0)880 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
881 {
882 uint32_t wt2;
883
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;
891 }
892 }
893 update_fcr31(env, GETPC());
894 return wt2;
895 }
896
helper_float_ceil_2008_w_s(CPUMIPSState * env,uint32_t fst0)897 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
898 {
899 uint32_t wt2;
900
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;
908 }
909 }
910 update_fcr31(env, GETPC());
911 return wt2;
912 }
913
helper_float_floor_2008_l_d(CPUMIPSState * env,uint64_t fdt0)914 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
915 {
916 uint64_t dt2;
917
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;
925 }
926 }
927 update_fcr31(env, GETPC());
928 return dt2;
929 }
930
helper_float_floor_2008_l_s(CPUMIPSState * env,uint32_t fst0)931 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
932 {
933 uint64_t dt2;
934
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;
942 }
943 }
944 update_fcr31(env, GETPC());
945 return dt2;
946 }
947
helper_float_floor_2008_w_d(CPUMIPSState * env,uint64_t fdt0)948 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
949 {
950 uint32_t wt2;
951
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;
959 }
960 }
961 update_fcr31(env, GETPC());
962 return wt2;
963 }
964
helper_float_floor_2008_w_s(CPUMIPSState * env,uint32_t fst0)965 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
966 {
967 uint32_t wt2;
968
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;
976 }
977 }
978 update_fcr31(env, GETPC());
979 return wt2;
980 }
981
982 /* unary operations, not modifying fp status */
983
helper_float_abs_d(uint64_t fdt0)984 uint64_t helper_float_abs_d(uint64_t fdt0)
985 {
986 return float64_abs(fdt0);
987 }
988
helper_float_abs_s(uint32_t fst0)989 uint32_t helper_float_abs_s(uint32_t fst0)
990 {
991 return float32_abs(fst0);
992 }
993
helper_float_abs_ps(uint64_t fdt0)994 uint64_t helper_float_abs_ps(uint64_t fdt0)
995 {
996 uint32_t wt0;
997 uint32_t wth0;
998
999 wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
1000 wth0 = float32_abs(fdt0 >> 32);
1001 return ((uint64_t)wth0 << 32) | wt0;
1002 }
1003
helper_float_chs_d(uint64_t fdt0)1004 uint64_t helper_float_chs_d(uint64_t fdt0)
1005 {
1006 return float64_chs(fdt0);
1007 }
1008
helper_float_chs_s(uint32_t fst0)1009 uint32_t helper_float_chs_s(uint32_t fst0)
1010 {
1011 return float32_chs(fst0);
1012 }
1013
helper_float_chs_ps(uint64_t fdt0)1014 uint64_t helper_float_chs_ps(uint64_t fdt0)
1015 {
1016 uint32_t wt0;
1017 uint32_t wth0;
1018
1019 wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
1020 wth0 = float32_chs(fdt0 >> 32);
1021 return ((uint64_t)wth0 << 32) | wt0;
1022 }
1023
1024 /* MIPS specific unary operations */
helper_float_recip_d(CPUMIPSState * env,uint64_t fdt0)1025 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
1026 {
1027 uint64_t fdt2;
1028
1029 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1030 update_fcr31(env, GETPC());
1031 return fdt2;
1032 }
1033
helper_float_recip_s(CPUMIPSState * env,uint32_t fst0)1034 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
1035 {
1036 uint32_t fst2;
1037
1038 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1039 update_fcr31(env, GETPC());
1040 return fst2;
1041 }
1042
helper_float_rsqrt_d(CPUMIPSState * env,uint64_t fdt0)1043 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
1044 {
1045 uint64_t fdt2;
1046
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;
1051 }
1052
helper_float_rsqrt_s(CPUMIPSState * env,uint32_t fst0)1053 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
1054 {
1055 uint32_t fst2;
1056
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;
1061 }
1062
helper_float_recip1_d(CPUMIPSState * env,uint64_t fdt0)1063 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
1064 {
1065 uint64_t fdt2;
1066
1067 fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
1068 update_fcr31(env, GETPC());
1069 return fdt2;
1070 }
1071
helper_float_recip1_s(CPUMIPSState * env,uint32_t fst0)1072 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
1073 {
1074 uint32_t fst2;
1075
1076 fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
1077 update_fcr31(env, GETPC());
1078 return fst2;
1079 }
1080
helper_float_recip1_ps(CPUMIPSState * env,uint64_t fdt0)1081 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
1082 {
1083 uint32_t fstl2;
1084 uint32_t fsth2;
1085
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;
1091 }
1092
helper_float_rsqrt1_d(CPUMIPSState * env,uint64_t fdt0)1093 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
1094 {
1095 uint64_t fdt2;
1096
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;
1101 }
1102
helper_float_rsqrt1_s(CPUMIPSState * env,uint32_t fst0)1103 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
1104 {
1105 uint32_t fst2;
1106
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;
1111 }
1112
helper_float_rsqrt1_ps(CPUMIPSState * env,uint64_t fdt0)1113 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
1114 {
1115 uint32_t fstl2;
1116 uint32_t fsth2;
1117
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;
1124 }
1125
helper_float_rint_d(CPUMIPSState * env,uint64_t fs)1126 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1127 {
1128 uint64_t fdret;
1129
1130 fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1131 update_fcr31(env, GETPC());
1132 return fdret;
1133 }
1134
helper_float_rint_s(CPUMIPSState * env,uint32_t fs)1135 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1136 {
1137 uint32_t fdret;
1138
1139 fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1140 update_fcr31(env, GETPC());
1141 return fdret;
1142 }
1143
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
1154
float_class_d(uint64_t arg,float_status * status)1155 uint64_t float_class_d(uint64_t arg, float_status *status)
1156 {
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;
1170 }
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;
1180 }
1181 }
1182 }
1183
helper_float_class_d(CPUMIPSState * env,uint64_t arg)1184 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
1185 {
1186 return float_class_d(arg, &env->active_fpu.fp_status);
1187 }
1188
float_class_s(uint32_t arg,float_status * status)1189 uint32_t float_class_s(uint32_t arg, float_status *status)
1190 {
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;
1204 }
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;
1214 }
1215 }
1216 }
1217
helper_float_class_s(CPUMIPSState * env,uint32_t arg)1218 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
1219 {
1220 return float_class_s(arg, &env->active_fpu.fp_status);
1221 }
1222
1223 /* binary operations */
1224
helper_float_add_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1225 uint64_t helper_float_add_d(CPUMIPSState *env,
1226 uint64_t fdt0, uint64_t fdt1)
1227 {
1228 uint64_t dt2;
1229
1230 dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
1231 update_fcr31(env, GETPC());
1232 return dt2;
1233 }
1234
helper_float_add_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1235 uint32_t helper_float_add_s(CPUMIPSState *env,
1236 uint32_t fst0, uint32_t fst1)
1237 {
1238 uint32_t wt2;
1239
1240 wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
1241 update_fcr31(env, GETPC());
1242 return wt2;
1243 }
1244
helper_float_add_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1245 uint64_t helper_float_add_ps(CPUMIPSState *env,
1246 uint64_t fdt0, uint64_t fdt1)
1247 {
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;
1254
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;
1259 }
1260
helper_float_sub_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1261 uint64_t helper_float_sub_d(CPUMIPSState *env,
1262 uint64_t fdt0, uint64_t fdt1)
1263 {
1264 uint64_t dt2;
1265
1266 dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1267 update_fcr31(env, GETPC());
1268 return dt2;
1269 }
1270
helper_float_sub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1271 uint32_t helper_float_sub_s(CPUMIPSState *env,
1272 uint32_t fst0, uint32_t fst1)
1273 {
1274 uint32_t wt2;
1275
1276 wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1277 update_fcr31(env, GETPC());
1278 return wt2;
1279 }
1280
helper_float_sub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1281 uint64_t helper_float_sub_ps(CPUMIPSState *env,
1282 uint64_t fdt0, uint64_t fdt1)
1283 {
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;
1290
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;
1295 }
1296
helper_float_mul_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1297 uint64_t helper_float_mul_d(CPUMIPSState *env,
1298 uint64_t fdt0, uint64_t fdt1)
1299 {
1300 uint64_t dt2;
1301
1302 dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
1303 update_fcr31(env, GETPC());
1304 return dt2;
1305 }
1306
helper_float_mul_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1307 uint32_t helper_float_mul_s(CPUMIPSState *env,
1308 uint32_t fst0, uint32_t fst1)
1309 {
1310 uint32_t wt2;
1311
1312 wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1313 update_fcr31(env, GETPC());
1314 return wt2;
1315 }
1316
helper_float_mul_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1317 uint64_t helper_float_mul_ps(CPUMIPSState *env,
1318 uint64_t fdt0, uint64_t fdt1)
1319 {
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;
1326
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;
1331 }
1332
helper_float_div_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1333 uint64_t helper_float_div_d(CPUMIPSState *env,
1334 uint64_t fdt0, uint64_t fdt1)
1335 {
1336 uint64_t dt2;
1337
1338 dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1339 update_fcr31(env, GETPC());
1340 return dt2;
1341 }
1342
helper_float_div_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1)1343 uint32_t helper_float_div_s(CPUMIPSState *env,
1344 uint32_t fst0, uint32_t fst1)
1345 {
1346 uint32_t wt2;
1347
1348 wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1349 update_fcr31(env, GETPC());
1350 return wt2;
1351 }
1352
helper_float_div_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1353 uint64_t helper_float_div_ps(CPUMIPSState *env,
1354 uint64_t fdt0, uint64_t fdt1)
1355 {
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;
1362
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;
1367 }
1368
1369
1370 /* MIPS specific binary operations */
helper_float_recip2_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1371 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1372 {
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;
1378 }
1379
helper_float_recip2_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst2)1380 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1381 {
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;
1387 }
1388
helper_float_recip2_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1389 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1390 {
1391 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1392 uint32_t fsth0 = fdt0 >> 32;
1393 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1394 uint32_t fsth2 = fdt2 >> 32;
1395
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;
1404 }
1405
helper_float_rsqrt2_d(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1406 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1407 {
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;
1414 }
1415
helper_float_rsqrt2_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst2)1416 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
1417 {
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;
1424 }
1425
helper_float_rsqrt2_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt2)1426 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
1427 {
1428 uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1429 uint32_t fsth0 = fdt0 >> 32;
1430 uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1431 uint32_t fsth2 = fdt2 >> 32;
1432
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;
1443 }
1444
helper_float_addr_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1445 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1446 {
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;
1453
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;
1458 }
1459
helper_float_mulr_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1)1460 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
1461 {
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;
1468
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;
1473 }
1474
1475
helper_float_max_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1476 uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1477 {
1478 uint32_t fdret;
1479
1480 fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
1481
1482 update_fcr31(env, GETPC());
1483 return fdret;
1484 }
1485
helper_float_max_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1486 uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1487 {
1488 uint64_t fdret;
1489
1490 fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
1491
1492 update_fcr31(env, GETPC());
1493 return fdret;
1494 }
1495
helper_float_maxa_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1496 uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1497 {
1498 uint32_t fdret;
1499
1500 fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
1501
1502 update_fcr31(env, GETPC());
1503 return fdret;
1504 }
1505
helper_float_maxa_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1506 uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1507 {
1508 uint64_t fdret;
1509
1510 fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
1511
1512 update_fcr31(env, GETPC());
1513 return fdret;
1514 }
1515
helper_float_min_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1516 uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1517 {
1518 uint32_t fdret;
1519
1520 fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
1521
1522 update_fcr31(env, GETPC());
1523 return fdret;
1524 }
1525
helper_float_min_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1526 uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1527 {
1528 uint64_t fdret;
1529
1530 fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
1531
1532 update_fcr31(env, GETPC());
1533 return fdret;
1534 }
1535
helper_float_mina_s(CPUMIPSState * env,uint32_t fs,uint32_t ft)1536 uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
1537 {
1538 uint32_t fdret;
1539
1540 fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
1541
1542 update_fcr31(env, GETPC());
1543 return fdret;
1544 }
1545
helper_float_mina_d(CPUMIPSState * env,uint64_t fs,uint64_t ft)1546 uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
1547 {
1548 uint64_t fdret;
1549
1550 fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
1551
1552 update_fcr31(env, GETPC());
1553 return fdret;
1554 }
1555
1556
1557 /* ternary operations */
1558
helper_float_madd_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1559 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
1560 uint64_t fst1, uint64_t fst2)
1561 {
1562 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1563 fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
1564
1565 update_fcr31(env, GETPC());
1566 return fst0;
1567 }
1568
helper_float_madd_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1569 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
1570 uint32_t fst1, uint32_t fst2)
1571 {
1572 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1573 fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
1574
1575 update_fcr31(env, GETPC());
1576 return fst0;
1577 }
1578
helper_float_madd_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1579 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
1580 uint64_t fdt1, uint64_t fdt2)
1581 {
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;
1588
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);
1593
1594 update_fcr31(env, GETPC());
1595 return ((uint64_t)fsth0 << 32) | fstl0;
1596 }
1597
helper_float_msub_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1598 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1599 uint64_t fst1, uint64_t fst2)
1600 {
1601 fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1602 fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1603
1604 update_fcr31(env, GETPC());
1605 return fst0;
1606 }
1607
helper_float_msub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1608 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1609 uint32_t fst1, uint32_t fst2)
1610 {
1611 fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1612 fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1613
1614 update_fcr31(env, GETPC());
1615 return fst0;
1616 }
1617
helper_float_msub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1618 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1619 uint64_t fdt1, uint64_t fdt2)
1620 {
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;
1627
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);
1632
1633 update_fcr31(env, GETPC());
1634 return ((uint64_t)fsth0 << 32) | fstl0;
1635 }
1636
helper_float_nmadd_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1637 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
1638 uint64_t fst1, uint64_t fst2)
1639 {
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);
1643
1644 update_fcr31(env, GETPC());
1645 return fst0;
1646 }
1647
helper_float_nmadd_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1648 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
1649 uint32_t fst1, uint32_t fst2)
1650 {
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);
1654
1655 update_fcr31(env, GETPC());
1656 return fst0;
1657 }
1658
helper_float_nmadd_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1659 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
1660 uint64_t fdt1, uint64_t fdt2)
1661 {
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;
1668
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);
1675
1676 update_fcr31(env, GETPC());
1677 return ((uint64_t)fsth0 << 32) | fstl0;
1678 }
1679
helper_float_nmsub_d(CPUMIPSState * env,uint64_t fst0,uint64_t fst1,uint64_t fst2)1680 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
1681 uint64_t fst1, uint64_t fst2)
1682 {
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);
1686
1687 update_fcr31(env, GETPC());
1688 return fst0;
1689 }
1690
helper_float_nmsub_s(CPUMIPSState * env,uint32_t fst0,uint32_t fst1,uint32_t fst2)1691 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
1692 uint32_t fst1, uint32_t fst2)
1693 {
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);
1697
1698 update_fcr31(env, GETPC());
1699 return fst0;
1700 }
1701
helper_float_nmsub_ps(CPUMIPSState * env,uint64_t fdt0,uint64_t fdt1,uint64_t fdt2)1702 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
1703 uint64_t fdt1, uint64_t fdt2)
1704 {
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;
1711
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);
1718
1719 update_fcr31(env, GETPC());
1720 return ((uint64_t)fsth0 << 32) | fstl0;
1721 }
1722
1723
helper_float_maddf_s(CPUMIPSState * env,uint32_t fs,uint32_t ft,uint32_t fd)1724 uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
1725 uint32_t ft, uint32_t fd)
1726 {
1727 uint32_t fdret;
1728
1729 fdret = float32_muladd(fs, ft, fd, 0,
1730 &env->active_fpu.fp_status);
1731
1732 update_fcr31(env, GETPC());
1733 return fdret;
1734 }
1735
helper_float_maddf_d(CPUMIPSState * env,uint64_t fs,uint64_t ft,uint64_t fd)1736 uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
1737 uint64_t ft, uint64_t fd)
1738 {
1739 uint64_t fdret;
1740
1741 fdret = float64_muladd(fs, ft, fd, 0,
1742 &env->active_fpu.fp_status);
1743
1744 update_fcr31(env, GETPC());
1745 return fdret;
1746 }
1747
helper_float_msubf_s(CPUMIPSState * env,uint32_t fs,uint32_t ft,uint32_t fd)1748 uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
1749 uint32_t ft, uint32_t fd)
1750 {
1751 uint32_t fdret;
1752
1753 fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
1754 &env->active_fpu.fp_status);
1755
1756 update_fcr31(env, GETPC());
1757 return fdret;
1758 }
1759
helper_float_msubf_d(CPUMIPSState * env,uint64_t fs,uint64_t ft,uint64_t fd)1760 uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
1761 uint64_t ft, uint64_t fd)
1762 {
1763 uint64_t fdret;
1764
1765 fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
1766 &env->active_fpu.fp_status);
1767
1768 update_fcr31(env, GETPC());
1769 return fdret;
1770 }
1771
1772
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) \
1777 { \
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); \
1785 } \
1786 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1787 uint64_t fdt1, int cc) \
1788 { \
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); \
1798 }
1799
1800 /*
1801 * NOTE: the comma operator will make "cond" to eval to false,
1802 * but float64_unordered_quiet() is still called.
1803 */
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))
1826 /*
1827 * NOTE: the comma operator will make "cond" to eval to false,
1828 * but float64_unordered() is still called.
1829 */
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))
1852
1853 #define FOP_COND_S(op, cond) \
1854 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1855 uint32_t fst1, int cc) \
1856 { \
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); \
1864 } \
1865 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1866 uint32_t fst1, int cc) \
1867 { \
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); \
1877 }
1878
1879 /*
1880 * NOTE: the comma operator will make "cond" to eval to false,
1881 * but float32_unordered_quiet() is still called.
1882 */
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))
1905 /*
1906 * NOTE: the comma operator will make "cond" to eval to false,
1907 * but float32_unordered() is still called.
1908 */
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))
1931
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) \
1935 { \
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); \
1953 } \
1954 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1955 uint64_t fdt1, int cc) \
1956 { \
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); \
1974 }
1975
1976 /*
1977 * NOTE: the comma operator will make "cond" to eval to false,
1978 * but float32_unordered_quiet() is still called.
1979 */
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))
2024 /*
2025 * NOTE: the comma operator will make "cond" to eval to false,
2026 * but float32_unordered() is still called.
2027 */
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))
2072
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) \
2077 { \
2078 uint64_t c; \
2079 c = cond; \
2080 update_fcr31(env, GETPC()); \
2081 if (c) { \
2082 return -1; \
2083 } else { \
2084 return 0; \
2085 } \
2086 }
2087
2088 /*
2089 * NOTE: the comma operator will make "cond" to eval to false,
2090 * but float64_unordered_quiet() is still called.
2091 */
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)))
2114 /*
2115 * NOTE: the comma operator will make "cond" to eval to false,
2116 * but float64_unordered() is still called.\
2117 */
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)))
2168
2169 #define FOP_CONDN_S(op, cond) \
2170 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2171 uint32_t fst1) \
2172 { \
2173 uint64_t c; \
2174 c = cond; \
2175 update_fcr31(env, GETPC()); \
2176 if (c) { \
2177 return -1; \
2178 } else { \
2179 return 0; \
2180 } \
2181 }
2182
2183 /*
2184 * NOTE: the comma operator will make "cond" to eval to false,
2185 * but float32_unordered_quiet() is still called.
2186 */
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)))
2209 /*
2210 * NOTE: the comma operator will make "cond" to eval to false,
2211 * but float32_unordered() is still called.
2212 */
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)))
2263