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