1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "cpu.h"
22#include "internal.h"
23#include "exec/exec-all.h"
24#include "exec/helper-proto.h"
25
26
27#define DF_BITS(df) (1 << ((df) + 3))
28
29#define DF_MAX_INT(df) (int64_t)((1LL << (DF_BITS(df) - 1)) - 1)
30#define M_MAX_INT(m) (int64_t)((1LL << ((m) - 1)) - 1)
31
32#define DF_MIN_INT(df) (int64_t)(-(1LL << (DF_BITS(df) - 1)))
33#define M_MIN_INT(m) (int64_t)(-(1LL << ((m) - 1)))
34
35#define DF_MAX_UINT(df) (uint64_t)(-1ULL >> (64 - DF_BITS(df)))
36#define M_MAX_UINT(m) (uint64_t)(-1ULL >> (64 - (m)))
37
38#define UNSIGNED(x, df) ((x) & DF_MAX_UINT(df))
39#define SIGNED(x, df) \
40 ((((int64_t)x) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df)))
41
42
43#define DF_ELEMENTS(df) (MSA_WRLEN / DF_BITS(df))
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530static inline void msa_move_v(wr_t *pwd, wr_t *pws)
531{
532 uint32_t i;
533
534 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
535 pwd->d[i] = pws->d[i];
536 }
537}
538
539#define MSA_FN_IMM8(FUNC, DEST, OPERATION) \
540void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws, \
541 uint32_t i8) \
542{ \
543 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
544 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
545 uint32_t i; \
546 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
547 DEST = OPERATION; \
548 } \
549}
550
551MSA_FN_IMM8(andi_b, pwd->b[i], pws->b[i] & i8)
552MSA_FN_IMM8(ori_b, pwd->b[i], pws->b[i] | i8)
553MSA_FN_IMM8(nori_b, pwd->b[i], ~(pws->b[i] | i8))
554MSA_FN_IMM8(xori_b, pwd->b[i], pws->b[i] ^ i8)
555
556#define BIT_MOVE_IF_NOT_ZERO(dest, arg1, arg2, df) \
557 UNSIGNED(((dest & (~arg2)) | (arg1 & arg2)), df)
558MSA_FN_IMM8(bmnzi_b, pwd->b[i],
559 BIT_MOVE_IF_NOT_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
560
561#define BIT_MOVE_IF_ZERO(dest, arg1, arg2, df) \
562 UNSIGNED((dest & arg2) | (arg1 & (~arg2)), df)
563MSA_FN_IMM8(bmzi_b, pwd->b[i],
564 BIT_MOVE_IF_ZERO(pwd->b[i], pws->b[i], i8, DF_BYTE))
565
566#define BIT_SELECT(dest, arg1, arg2, df) \
567 UNSIGNED((arg1 & (~dest)) | (arg2 & dest), df)
568MSA_FN_IMM8(bseli_b, pwd->b[i],
569 BIT_SELECT(pwd->b[i], pws->b[i], i8, DF_BYTE))
570
571#undef MSA_FN_IMM8
572
573#define SHF_POS(i, imm) (((i) & 0xfc) + (((imm) >> (2 * ((i) & 0x03))) & 0x03))
574
575void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
576 uint32_t ws, uint32_t imm)
577{
578 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
579 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
580 wr_t wx, *pwx = &wx;
581 uint32_t i;
582
583 switch (df) {
584 case DF_BYTE:
585 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
586 pwx->b[i] = pws->b[SHF_POS(i, imm)];
587 }
588 break;
589 case DF_HALF:
590 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
591 pwx->h[i] = pws->h[SHF_POS(i, imm)];
592 }
593 break;
594 case DF_WORD:
595 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
596 pwx->w[i] = pws->w[SHF_POS(i, imm)];
597 }
598 break;
599 default:
600 assert(0);
601 }
602 msa_move_v(pwd, pwx);
603}
604
605#define MSA_FN_VECTOR(FUNC, DEST, OPERATION) \
606void helper_msa_ ## FUNC(CPUMIPSState *env, uint32_t wd, uint32_t ws, \
607 uint32_t wt) \
608{ \
609 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
610 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
611 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
612 uint32_t i; \
613 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
614 DEST = OPERATION; \
615 } \
616}
617
618MSA_FN_VECTOR(bmnz_v, pwd->d[i],
619 BIT_MOVE_IF_NOT_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
620MSA_FN_VECTOR(bmz_v, pwd->d[i],
621 BIT_MOVE_IF_ZERO(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
622MSA_FN_VECTOR(bsel_v, pwd->d[i],
623 BIT_SELECT(pwd->d[i], pws->d[i], pwt->d[i], DF_DOUBLE))
624#undef BIT_MOVE_IF_NOT_ZERO
625#undef BIT_MOVE_IF_ZERO
626#undef BIT_SELECT
627#undef MSA_FN_VECTOR
628
629void helper_msa_and_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
630{
631 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
632 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
633 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
634
635 pwd->d[0] = pws->d[0] & pwt->d[0];
636 pwd->d[1] = pws->d[1] & pwt->d[1];
637}
638
639void helper_msa_or_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
640{
641 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
642 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
643 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
644
645 pwd->d[0] = pws->d[0] | pwt->d[0];
646 pwd->d[1] = pws->d[1] | pwt->d[1];
647}
648
649void helper_msa_nor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
650{
651 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
652 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
653 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
654
655 pwd->d[0] = ~(pws->d[0] | pwt->d[0]);
656 pwd->d[1] = ~(pws->d[1] | pwt->d[1]);
657}
658
659void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
660{
661 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
662 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
663 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
664
665 pwd->d[0] = pws->d[0] ^ pwt->d[0];
666 pwd->d[1] = pws->d[1] ^ pwt->d[1];
667}
668
669static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
670{
671 return arg1 + arg2;
672}
673
674static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
675{
676 return arg1 - arg2;
677}
678
679static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
680{
681 return arg1 == arg2 ? -1 : 0;
682}
683
684static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
685{
686 return arg1 <= arg2 ? -1 : 0;
687}
688
689static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
690{
691 uint64_t u_arg1 = UNSIGNED(arg1, df);
692 uint64_t u_arg2 = UNSIGNED(arg2, df);
693 return u_arg1 <= u_arg2 ? -1 : 0;
694}
695
696static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
697{
698 return arg1 < arg2 ? -1 : 0;
699}
700
701static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
702{
703 uint64_t u_arg1 = UNSIGNED(arg1, df);
704 uint64_t u_arg2 = UNSIGNED(arg2, df);
705 return u_arg1 < u_arg2 ? -1 : 0;
706}
707
708static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
709{
710 return arg1 > arg2 ? arg1 : arg2;
711}
712
713static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
714{
715 uint64_t u_arg1 = UNSIGNED(arg1, df);
716 uint64_t u_arg2 = UNSIGNED(arg2, df);
717 return u_arg1 > u_arg2 ? arg1 : arg2;
718}
719
720static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
721{
722 return arg1 < arg2 ? arg1 : arg2;
723}
724
725static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
726{
727 uint64_t u_arg1 = UNSIGNED(arg1, df);
728 uint64_t u_arg2 = UNSIGNED(arg2, df);
729 return u_arg1 < u_arg2 ? arg1 : arg2;
730}
731
732#define MSA_BINOP_IMM_DF(helper, func) \
733void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
734 uint32_t wd, uint32_t ws, int32_t u5) \
735{ \
736 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
737 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
738 uint32_t i; \
739 \
740 switch (df) { \
741 case DF_BYTE: \
742 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
743 pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5); \
744 } \
745 break; \
746 case DF_HALF: \
747 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
748 pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5); \
749 } \
750 break; \
751 case DF_WORD: \
752 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
753 pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5); \
754 } \
755 break; \
756 case DF_DOUBLE: \
757 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
758 pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5); \
759 } \
760 break; \
761 default: \
762 assert(0); \
763 } \
764}
765
766MSA_BINOP_IMM_DF(addvi, addv)
767MSA_BINOP_IMM_DF(subvi, subv)
768MSA_BINOP_IMM_DF(ceqi, ceq)
769MSA_BINOP_IMM_DF(clei_s, cle_s)
770MSA_BINOP_IMM_DF(clei_u, cle_u)
771MSA_BINOP_IMM_DF(clti_s, clt_s)
772MSA_BINOP_IMM_DF(clti_u, clt_u)
773MSA_BINOP_IMM_DF(maxi_s, max_s)
774MSA_BINOP_IMM_DF(maxi_u, max_u)
775MSA_BINOP_IMM_DF(mini_s, min_s)
776MSA_BINOP_IMM_DF(mini_u, min_u)
777#undef MSA_BINOP_IMM_DF
778
779void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
780 int32_t s10)
781{
782 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
783 uint32_t i;
784
785 switch (df) {
786 case DF_BYTE:
787 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
788 pwd->b[i] = (int8_t)s10;
789 }
790 break;
791 case DF_HALF:
792 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
793 pwd->h[i] = (int16_t)s10;
794 }
795 break;
796 case DF_WORD:
797 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
798 pwd->w[i] = (int32_t)s10;
799 }
800 break;
801 case DF_DOUBLE:
802 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
803 pwd->d[i] = (int64_t)s10;
804 }
805 break;
806 default:
807 assert(0);
808 }
809}
810
811
812#define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
813
814static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
815{
816 int32_t b_arg2 = BIT_POSITION(arg2, df);
817 return arg1 << b_arg2;
818}
819
820static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
821{
822 int32_t b_arg2 = BIT_POSITION(arg2, df);
823 return arg1 >> b_arg2;
824}
825
826static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
827{
828 uint64_t u_arg1 = UNSIGNED(arg1, df);
829 int32_t b_arg2 = BIT_POSITION(arg2, df);
830 return u_arg1 >> b_arg2;
831}
832
833static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
834{
835 int32_t b_arg2 = BIT_POSITION(arg2, df);
836 return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
837}
838
839static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
840 int64_t arg2)
841{
842 int32_t b_arg2 = BIT_POSITION(arg2, df);
843 return UNSIGNED(arg1 | (1LL << b_arg2), df);
844}
845
846static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
847{
848 int32_t b_arg2 = BIT_POSITION(arg2, df);
849 return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
850}
851
852static inline int64_t msa_binsl_df(uint32_t df, int64_t dest, int64_t arg1,
853 int64_t arg2)
854{
855 uint64_t u_arg1 = UNSIGNED(arg1, df);
856 uint64_t u_dest = UNSIGNED(dest, df);
857 int32_t sh_d = BIT_POSITION(arg2, df) + 1;
858 int32_t sh_a = DF_BITS(df) - sh_d;
859 if (sh_d == DF_BITS(df)) {
860 return u_arg1;
861 } else {
862 return UNSIGNED(UNSIGNED(u_dest << sh_d, df) >> sh_d, df) |
863 UNSIGNED(UNSIGNED(u_arg1 >> sh_a, df) << sh_a, df);
864 }
865}
866
867static inline int64_t msa_binsr_df(uint32_t df, int64_t dest, int64_t arg1,
868 int64_t arg2)
869{
870 uint64_t u_arg1 = UNSIGNED(arg1, df);
871 uint64_t u_dest = UNSIGNED(dest, df);
872 int32_t sh_d = BIT_POSITION(arg2, df) + 1;
873 int32_t sh_a = DF_BITS(df) - sh_d;
874 if (sh_d == DF_BITS(df)) {
875 return u_arg1;
876 } else {
877 return UNSIGNED(UNSIGNED(u_dest >> sh_d, df) << sh_d, df) |
878 UNSIGNED(UNSIGNED(u_arg1 << sh_a, df) >> sh_a, df);
879 }
880}
881
882static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
883{
884 return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
885 arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
886 arg;
887}
888
889static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
890{
891 uint64_t u_arg = UNSIGNED(arg, df);
892 return u_arg < M_MAX_UINT(m + 1) ? u_arg :
893 M_MAX_UINT(m + 1);
894}
895
896static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
897{
898 int32_t b_arg2 = BIT_POSITION(arg2, df);
899 if (b_arg2 == 0) {
900 return arg1;
901 } else {
902 int64_t r_bit = (arg1 >> (b_arg2 - 1)) & 1;
903 return (arg1 >> b_arg2) + r_bit;
904 }
905}
906
907static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
908{
909 uint64_t u_arg1 = UNSIGNED(arg1, df);
910 int32_t b_arg2 = BIT_POSITION(arg2, df);
911 if (b_arg2 == 0) {
912 return u_arg1;
913 } else {
914 uint64_t r_bit = (u_arg1 >> (b_arg2 - 1)) & 1;
915 return (u_arg1 >> b_arg2) + r_bit;
916 }
917}
918
919#define MSA_BINOP_IMMU_DF(helper, func) \
920void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
921 uint32_t ws, uint32_t u5) \
922{ \
923 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
924 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
925 uint32_t i; \
926 \
927 switch (df) { \
928 case DF_BYTE: \
929 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
930 pwd->b[i] = msa_ ## func ## _df(df, pws->b[i], u5); \
931 } \
932 break; \
933 case DF_HALF: \
934 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
935 pwd->h[i] = msa_ ## func ## _df(df, pws->h[i], u5); \
936 } \
937 break; \
938 case DF_WORD: \
939 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
940 pwd->w[i] = msa_ ## func ## _df(df, pws->w[i], u5); \
941 } \
942 break; \
943 case DF_DOUBLE: \
944 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
945 pwd->d[i] = msa_ ## func ## _df(df, pws->d[i], u5); \
946 } \
947 break; \
948 default: \
949 assert(0); \
950 } \
951}
952
953MSA_BINOP_IMMU_DF(slli, sll)
954MSA_BINOP_IMMU_DF(srai, sra)
955MSA_BINOP_IMMU_DF(srli, srl)
956MSA_BINOP_IMMU_DF(bclri, bclr)
957MSA_BINOP_IMMU_DF(bseti, bset)
958MSA_BINOP_IMMU_DF(bnegi, bneg)
959MSA_BINOP_IMMU_DF(sat_s, sat_s)
960MSA_BINOP_IMMU_DF(sat_u, sat_u)
961MSA_BINOP_IMMU_DF(srari, srar)
962MSA_BINOP_IMMU_DF(srlri, srlr)
963#undef MSA_BINOP_IMMU_DF
964
965#define MSA_TEROP_IMMU_DF(helper, func) \
966void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
967 uint32_t wd, uint32_t ws, uint32_t u5) \
968{ \
969 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
970 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
971 uint32_t i; \
972 \
973 switch (df) { \
974 case DF_BYTE: \
975 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) { \
976 pwd->b[i] = msa_ ## func ## _df(df, pwd->b[i], pws->b[i], \
977 u5); \
978 } \
979 break; \
980 case DF_HALF: \
981 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) { \
982 pwd->h[i] = msa_ ## func ## _df(df, pwd->h[i], pws->h[i], \
983 u5); \
984 } \
985 break; \
986 case DF_WORD: \
987 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { \
988 pwd->w[i] = msa_ ## func ## _df(df, pwd->w[i], pws->w[i], \
989 u5); \
990 } \
991 break; \
992 case DF_DOUBLE: \
993 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) { \
994 pwd->d[i] = msa_ ## func ## _df(df, pwd->d[i], pws->d[i], \
995 u5); \
996 } \
997 break; \
998 default: \
999 assert(0); \
1000 } \
1001}
1002
1003MSA_TEROP_IMMU_DF(binsli, binsl)
1004MSA_TEROP_IMMU_DF(binsri, binsr)
1005#undef MSA_TEROP_IMMU_DF
1006
1007static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
1008{
1009 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1010 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1011 return abs_arg1 > abs_arg2 ? arg1 : arg2;
1012}
1013
1014static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
1015{
1016 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1017 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1018 return abs_arg1 < abs_arg2 ? arg1 : arg2;
1019}
1020
1021static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
1022{
1023 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1024 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1025 return abs_arg1 + abs_arg2;
1026}
1027
1028static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
1029{
1030 uint64_t max_int = (uint64_t)DF_MAX_INT(df);
1031 uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
1032 uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
1033 if (abs_arg1 > max_int || abs_arg2 > max_int) {
1034 return (int64_t)max_int;
1035 } else {
1036 return (abs_arg1 < max_int - abs_arg2) ? abs_arg1 + abs_arg2 : max_int;
1037 }
1038}
1039
1040static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1041{
1042 int64_t max_int = DF_MAX_INT(df);
1043 int64_t min_int = DF_MIN_INT(df);
1044 if (arg1 < 0) {
1045 return (min_int - arg1 < arg2) ? arg1 + arg2 : min_int;
1046 } else {
1047 return (arg2 < max_int - arg1) ? arg1 + arg2 : max_int;
1048 }
1049}
1050
1051static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1052{
1053 uint64_t max_uint = DF_MAX_UINT(df);
1054 uint64_t u_arg1 = UNSIGNED(arg1, df);
1055 uint64_t u_arg2 = UNSIGNED(arg2, df);
1056 return (u_arg1 < max_uint - u_arg2) ? u_arg1 + u_arg2 : max_uint;
1057}
1058
1059static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1060{
1061
1062 return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
1063}
1064
1065static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1066{
1067 uint64_t u_arg1 = UNSIGNED(arg1, df);
1068 uint64_t u_arg2 = UNSIGNED(arg2, df);
1069
1070 return (u_arg1 >> 1) + (u_arg2 >> 1) + (u_arg1 & u_arg2 & 1);
1071}
1072
1073static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1074{
1075
1076 return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
1077}
1078
1079static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1080{
1081 uint64_t u_arg1 = UNSIGNED(arg1, df);
1082 uint64_t u_arg2 = UNSIGNED(arg2, df);
1083
1084 return (u_arg1 >> 1) + (u_arg2 >> 1) + ((u_arg1 | u_arg2) & 1);
1085}
1086
1087static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1088{
1089 int64_t max_int = DF_MAX_INT(df);
1090 int64_t min_int = DF_MIN_INT(df);
1091 if (arg2 > 0) {
1092 return (min_int + arg2 < arg1) ? arg1 - arg2 : min_int;
1093 } else {
1094 return (arg1 < max_int + arg2) ? arg1 - arg2 : max_int;
1095 }
1096}
1097
1098static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1099{
1100 uint64_t u_arg1 = UNSIGNED(arg1, df);
1101 uint64_t u_arg2 = UNSIGNED(arg2, df);
1102 return (u_arg1 > u_arg2) ? u_arg1 - u_arg2 : 0;
1103}
1104
1105static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1106{
1107 uint64_t u_arg1 = UNSIGNED(arg1, df);
1108 uint64_t max_uint = DF_MAX_UINT(df);
1109 if (arg2 >= 0) {
1110 uint64_t u_arg2 = (uint64_t)arg2;
1111 return (u_arg1 > u_arg2) ?
1112 (int64_t)(u_arg1 - u_arg2) :
1113 0;
1114 } else {
1115 uint64_t u_arg2 = (uint64_t)(-arg2);
1116 return (u_arg1 < max_uint - u_arg2) ?
1117 (int64_t)(u_arg1 + u_arg2) :
1118 (int64_t)max_uint;
1119 }
1120}
1121
1122static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1123{
1124 uint64_t u_arg1 = UNSIGNED(arg1, df);
1125 uint64_t u_arg2 = UNSIGNED(arg2, df);
1126 int64_t max_int = DF_MAX_INT(df);
1127 int64_t min_int = DF_MIN_INT(df);
1128 if (u_arg1 > u_arg2) {
1129 return u_arg1 - u_arg2 < (uint64_t)max_int ?
1130 (int64_t)(u_arg1 - u_arg2) :
1131 max_int;
1132 } else {
1133 return u_arg2 - u_arg1 < (uint64_t)(-min_int) ?
1134 (int64_t)(u_arg1 - u_arg2) :
1135 min_int;
1136 }
1137}
1138
1139static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1140{
1141
1142 return (arg1 < arg2) ?
1143 (uint64_t)(arg2 - arg1) : (uint64_t)(arg1 - arg2);
1144}
1145
1146static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
1147{
1148 uint64_t u_arg1 = UNSIGNED(arg1, df);
1149 uint64_t u_arg2 = UNSIGNED(arg2, df);
1150
1151 return (u_arg1 < u_arg2) ?
1152 (uint64_t)(u_arg2 - u_arg1) : (uint64_t)(u_arg1 - u_arg2);
1153}
1154
1155static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
1156{
1157 return arg1 * arg2;
1158}
1159
1160static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1161{
1162 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
1163 return DF_MIN_INT(df);
1164 }
1165 return arg2 ? arg1 / arg2
1166 : arg1 >= 0 ? -1 : 1;
1167}
1168
1169static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1170{
1171 uint64_t u_arg1 = UNSIGNED(arg1, df);
1172 uint64_t u_arg2 = UNSIGNED(arg2, df);
1173 return arg2 ? u_arg1 / u_arg2 : -1;
1174}
1175
1176static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1177{
1178 if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
1179 return 0;
1180 }
1181 return arg2 ? arg1 % arg2 : arg1;
1182}
1183
1184static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1185{
1186 uint64_t u_arg1 = UNSIGNED(arg1, df);
1187 uint64_t u_arg2 = UNSIGNED(arg2, df);
1188 return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
1189}
1190
1191#define SIGNED_EVEN(a, df) \
1192 ((((int64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1193
1194#define UNSIGNED_EVEN(a, df) \
1195 ((((uint64_t)(a)) << (64 - DF_BITS(df) / 2)) >> (64 - DF_BITS(df) / 2))
1196
1197#define SIGNED_ODD(a, df) \
1198 ((((int64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1199
1200#define UNSIGNED_ODD(a, df) \
1201 ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
1202
1203#define SIGNED_EXTRACT(e, o, a, df) \
1204 do { \
1205 e = SIGNED_EVEN(a, df); \
1206 o = SIGNED_ODD(a, df); \
1207 } while (0)
1208
1209#define UNSIGNED_EXTRACT(e, o, a, df) \
1210 do { \
1211 e = UNSIGNED_EVEN(a, df); \
1212 o = UNSIGNED_ODD(a, df); \
1213 } while (0)
1214
1215static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1216{
1217 int64_t even_arg1;
1218 int64_t even_arg2;
1219 int64_t odd_arg1;
1220 int64_t odd_arg2;
1221 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1222 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1223 return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1224}
1225
1226static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1227{
1228 int64_t even_arg1;
1229 int64_t even_arg2;
1230 int64_t odd_arg1;
1231 int64_t odd_arg2;
1232 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1233 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1234 return (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1235}
1236
1237#define CONCATENATE_AND_SLIDE(s, k) \
1238 do { \
1239 for (i = 0; i < s; i++) { \
1240 v[i] = pws->b[s * k + i]; \
1241 v[i + s] = pwd->b[s * k + i]; \
1242 } \
1243 for (i = 0; i < s; i++) { \
1244 pwd->b[s * k + i] = v[i + n]; \
1245 } \
1246 } while (0)
1247
1248static inline void msa_sld_df(uint32_t df, wr_t *pwd,
1249 wr_t *pws, target_ulong rt)
1250{
1251 uint32_t n = rt % DF_ELEMENTS(df);
1252 uint8_t v[64];
1253 uint32_t i, k;
1254
1255 switch (df) {
1256 case DF_BYTE:
1257 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_BYTE), 0);
1258 break;
1259 case DF_HALF:
1260 for (k = 0; k < 2; k++) {
1261 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_HALF), k);
1262 }
1263 break;
1264 case DF_WORD:
1265 for (k = 0; k < 4; k++) {
1266 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_WORD), k);
1267 }
1268 break;
1269 case DF_DOUBLE:
1270 for (k = 0; k < 8; k++) {
1271 CONCATENATE_AND_SLIDE(DF_ELEMENTS(DF_DOUBLE), k);
1272 }
1273 break;
1274 default:
1275 assert(0);
1276 }
1277}
1278
1279static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1280{
1281 return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
1282}
1283
1284static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1285{
1286 return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
1287}
1288
1289static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
1290{
1291 return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
1292}
1293
1294static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
1295{
1296 return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
1297}
1298
1299static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
1300{
1301 int64_t q_min = DF_MIN_INT(df);
1302 int64_t q_max = DF_MAX_INT(df);
1303
1304 if (arg1 == q_min && arg2 == q_min) {
1305 return q_max;
1306 }
1307 return (arg1 * arg2) >> (DF_BITS(df) - 1);
1308}
1309
1310static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
1311{
1312 int64_t q_min = DF_MIN_INT(df);
1313 int64_t q_max = DF_MAX_INT(df);
1314 int64_t r_bit = 1 << (DF_BITS(df) - 2);
1315
1316 if (arg1 == q_min && arg2 == q_min) {
1317 return q_max;
1318 }
1319 return (arg1 * arg2 + r_bit) >> (DF_BITS(df) - 1);
1320}
1321
1322#define MSA_BINOP_DF(func) \
1323void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
1324 uint32_t wd, uint32_t ws, uint32_t wt) \
1325{ \
1326 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
1327 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
1328 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
1329 \
1330 switch (df) { \
1331 case DF_BYTE: \
1332 pwd->b[0] = msa_ ## func ## _df(df, pws->b[0], pwt->b[0]); \
1333 pwd->b[1] = msa_ ## func ## _df(df, pws->b[1], pwt->b[1]); \
1334 pwd->b[2] = msa_ ## func ## _df(df, pws->b[2], pwt->b[2]); \
1335 pwd->b[3] = msa_ ## func ## _df(df, pws->b[3], pwt->b[3]); \
1336 pwd->b[4] = msa_ ## func ## _df(df, pws->b[4], pwt->b[4]); \
1337 pwd->b[5] = msa_ ## func ## _df(df, pws->b[5], pwt->b[5]); \
1338 pwd->b[6] = msa_ ## func ## _df(df, pws->b[6], pwt->b[6]); \
1339 pwd->b[7] = msa_ ## func ## _df(df, pws->b[7], pwt->b[7]); \
1340 pwd->b[8] = msa_ ## func ## _df(df, pws->b[8], pwt->b[8]); \
1341 pwd->b[9] = msa_ ## func ## _df(df, pws->b[9], pwt->b[9]); \
1342 pwd->b[10] = msa_ ## func ## _df(df, pws->b[10], pwt->b[10]); \
1343 pwd->b[11] = msa_ ## func ## _df(df, pws->b[11], pwt->b[11]); \
1344 pwd->b[12] = msa_ ## func ## _df(df, pws->b[12], pwt->b[12]); \
1345 pwd->b[13] = msa_ ## func ## _df(df, pws->b[13], pwt->b[13]); \
1346 pwd->b[14] = msa_ ## func ## _df(df, pws->b[14], pwt->b[14]); \
1347 pwd->b[15] = msa_ ## func ## _df(df, pws->b[15], pwt->b[15]); \
1348 break; \
1349 case DF_HALF: \
1350 pwd->h[0] = msa_ ## func ## _df(df, pws->h[0], pwt->h[0]); \
1351 pwd->h[1] = msa_ ## func ## _df(df, pws->h[1], pwt->h[1]); \
1352 pwd->h[2] = msa_ ## func ## _df(df, pws->h[2], pwt->h[2]); \
1353 pwd->h[3] = msa_ ## func ## _df(df, pws->h[3], pwt->h[3]); \
1354 pwd->h[4] = msa_ ## func ## _df(df, pws->h[4], pwt->h[4]); \
1355 pwd->h[5] = msa_ ## func ## _df(df, pws->h[5], pwt->h[5]); \
1356 pwd->h[6] = msa_ ## func ## _df(df, pws->h[6], pwt->h[6]); \
1357 pwd->h[7] = msa_ ## func ## _df(df, pws->h[7], pwt->h[7]); \
1358 break; \
1359 case DF_WORD: \
1360 pwd->w[0] = msa_ ## func ## _df(df, pws->w[0], pwt->w[0]); \
1361 pwd->w[1] = msa_ ## func ## _df(df, pws->w[1], pwt->w[1]); \
1362 pwd->w[2] = msa_ ## func ## _df(df, pws->w[2], pwt->w[2]); \
1363 pwd->w[3] = msa_ ## func ## _df(df, pws->w[3], pwt->w[3]); \
1364 break; \
1365 case DF_DOUBLE: \
1366 pwd->d[0] = msa_ ## func ## _df(df, pws->d[0], pwt->d[0]); \
1367 pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]); \
1368 break; \
1369 default: \
1370 assert(0); \
1371 } \
1372}
1373
1374MSA_BINOP_DF(sll)
1375MSA_BINOP_DF(sra)
1376MSA_BINOP_DF(srl)
1377MSA_BINOP_DF(bclr)
1378MSA_BINOP_DF(bset)
1379MSA_BINOP_DF(bneg)
1380MSA_BINOP_DF(addv)
1381MSA_BINOP_DF(subv)
1382MSA_BINOP_DF(max_s)
1383MSA_BINOP_DF(max_u)
1384MSA_BINOP_DF(min_s)
1385MSA_BINOP_DF(min_u)
1386MSA_BINOP_DF(max_a)
1387MSA_BINOP_DF(min_a)
1388MSA_BINOP_DF(ceq)
1389MSA_BINOP_DF(clt_s)
1390MSA_BINOP_DF(clt_u)
1391MSA_BINOP_DF(cle_s)
1392MSA_BINOP_DF(cle_u)
1393MSA_BINOP_DF(add_a)
1394MSA_BINOP_DF(adds_a)
1395MSA_BINOP_DF(adds_s)
1396MSA_BINOP_DF(adds_u)
1397MSA_BINOP_DF(ave_s)
1398MSA_BINOP_DF(ave_u)
1399MSA_BINOP_DF(aver_s)
1400MSA_BINOP_DF(aver_u)
1401MSA_BINOP_DF(subs_s)
1402MSA_BINOP_DF(subs_u)
1403MSA_BINOP_DF(subsus_u)
1404MSA_BINOP_DF(subsuu_s)
1405MSA_BINOP_DF(asub_s)
1406MSA_BINOP_DF(asub_u)
1407MSA_BINOP_DF(mulv)
1408MSA_BINOP_DF(div_s)
1409MSA_BINOP_DF(div_u)
1410MSA_BINOP_DF(mod_s)
1411MSA_BINOP_DF(mod_u)
1412MSA_BINOP_DF(dotp_s)
1413MSA_BINOP_DF(dotp_u)
1414MSA_BINOP_DF(srar)
1415MSA_BINOP_DF(srlr)
1416MSA_BINOP_DF(hadd_s)
1417MSA_BINOP_DF(hadd_u)
1418MSA_BINOP_DF(hsub_s)
1419MSA_BINOP_DF(hsub_u)
1420
1421MSA_BINOP_DF(mul_q)
1422MSA_BINOP_DF(mulr_q)
1423#undef MSA_BINOP_DF
1424
1425void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1426 uint32_t ws, uint32_t rt)
1427{
1428 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1429 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1430
1431 msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
1432}
1433
1434static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
1435 int64_t arg2)
1436{
1437 return dest + arg1 * arg2;
1438}
1439
1440static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
1441 int64_t arg2)
1442{
1443 return dest - arg1 * arg2;
1444}
1445
1446static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
1447 int64_t arg2)
1448{
1449 int64_t even_arg1;
1450 int64_t even_arg2;
1451 int64_t odd_arg1;
1452 int64_t odd_arg2;
1453 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1454 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1455 return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1456}
1457
1458static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
1459 int64_t arg2)
1460{
1461 int64_t even_arg1;
1462 int64_t even_arg2;
1463 int64_t odd_arg1;
1464 int64_t odd_arg2;
1465 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1466 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1467 return dest + (even_arg1 * even_arg2) + (odd_arg1 * odd_arg2);
1468}
1469
1470static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
1471 int64_t arg2)
1472{
1473 int64_t even_arg1;
1474 int64_t even_arg2;
1475 int64_t odd_arg1;
1476 int64_t odd_arg2;
1477 SIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1478 SIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1479 return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
1480}
1481
1482static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
1483 int64_t arg2)
1484{
1485 int64_t even_arg1;
1486 int64_t even_arg2;
1487 int64_t odd_arg1;
1488 int64_t odd_arg2;
1489 UNSIGNED_EXTRACT(even_arg1, odd_arg1, arg1, df);
1490 UNSIGNED_EXTRACT(even_arg2, odd_arg2, arg2, df);
1491 return dest - ((even_arg1 * even_arg2) + (odd_arg1 * odd_arg2));
1492}
1493
1494static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
1495 int64_t arg2)
1496{
1497 int64_t q_prod, q_ret;
1498
1499 int64_t q_max = DF_MAX_INT(df);
1500 int64_t q_min = DF_MIN_INT(df);
1501
1502 q_prod = arg1 * arg2;
1503 q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod) >> (DF_BITS(df) - 1);
1504
1505 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1506}
1507
1508static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
1509 int64_t arg2)
1510{
1511 int64_t q_prod, q_ret;
1512
1513 int64_t q_max = DF_MAX_INT(df);
1514 int64_t q_min = DF_MIN_INT(df);
1515
1516 q_prod = arg1 * arg2;
1517 q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod) >> (DF_BITS(df) - 1);
1518
1519 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1520}
1521
1522static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
1523 int64_t arg2)
1524{
1525 int64_t q_prod, q_ret;
1526
1527 int64_t q_max = DF_MAX_INT(df);
1528 int64_t q_min = DF_MIN_INT(df);
1529 int64_t r_bit = 1 << (DF_BITS(df) - 2);
1530
1531 q_prod = arg1 * arg2;
1532 q_ret = ((dest << (DF_BITS(df) - 1)) + q_prod + r_bit) >> (DF_BITS(df) - 1);
1533
1534 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1535}
1536
1537static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
1538 int64_t arg2)
1539{
1540 int64_t q_prod, q_ret;
1541
1542 int64_t q_max = DF_MAX_INT(df);
1543 int64_t q_min = DF_MIN_INT(df);
1544 int64_t r_bit = 1 << (DF_BITS(df) - 2);
1545
1546 q_prod = arg1 * arg2;
1547 q_ret = ((dest << (DF_BITS(df) - 1)) - q_prod + r_bit) >> (DF_BITS(df) - 1);
1548
1549 return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
1550}
1551
1552#define MSA_TEROP_DF(func) \
1553void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
1554 uint32_t ws, uint32_t wt) \
1555{ \
1556 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
1557 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
1558 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
1559 \
1560 switch (df) { \
1561 case DF_BYTE: \
1562 pwd->b[0] = msa_ ## func ## _df(df, pwd->b[0], pws->b[0], \
1563 pwt->b[0]); \
1564 pwd->b[1] = msa_ ## func ## _df(df, pwd->b[1], pws->b[1], \
1565 pwt->b[1]); \
1566 pwd->b[2] = msa_ ## func ## _df(df, pwd->b[2], pws->b[2], \
1567 pwt->b[2]); \
1568 pwd->b[3] = msa_ ## func ## _df(df, pwd->b[3], pws->b[3], \
1569 pwt->b[3]); \
1570 pwd->b[4] = msa_ ## func ## _df(df, pwd->b[4], pws->b[4], \
1571 pwt->b[4]); \
1572 pwd->b[5] = msa_ ## func ## _df(df, pwd->b[5], pws->b[5], \
1573 pwt->b[5]); \
1574 pwd->b[6] = msa_ ## func ## _df(df, pwd->b[6], pws->b[6], \
1575 pwt->b[6]); \
1576 pwd->b[7] = msa_ ## func ## _df(df, pwd->b[7], pws->b[7], \
1577 pwt->b[7]); \
1578 pwd->b[8] = msa_ ## func ## _df(df, pwd->b[8], pws->b[8], \
1579 pwt->b[8]); \
1580 pwd->b[9] = msa_ ## func ## _df(df, pwd->b[9], pws->b[9], \
1581 pwt->b[9]); \
1582 pwd->b[10] = msa_ ## func ## _df(df, pwd->b[10], pws->b[10], \
1583 pwt->b[10]); \
1584 pwd->b[11] = msa_ ## func ## _df(df, pwd->b[11], pws->b[11], \
1585 pwt->b[11]); \
1586 pwd->b[12] = msa_ ## func ## _df(df, pwd->b[12], pws->b[12], \
1587 pwt->b[12]); \
1588 pwd->b[13] = msa_ ## func ## _df(df, pwd->b[13], pws->b[13], \
1589 pwt->b[13]); \
1590 pwd->b[14] = msa_ ## func ## _df(df, pwd->b[14], pws->b[14], \
1591 pwt->b[14]); \
1592 pwd->b[15] = msa_ ## func ## _df(df, pwd->b[15], pws->b[15], \
1593 pwt->b[15]); \
1594 break; \
1595 case DF_HALF: \
1596 pwd->h[0] = msa_ ## func ## _df(df, pwd->h[0], pws->h[0], pwt->h[0]); \
1597 pwd->h[1] = msa_ ## func ## _df(df, pwd->h[1], pws->h[1], pwt->h[1]); \
1598 pwd->h[2] = msa_ ## func ## _df(df, pwd->h[2], pws->h[2], pwt->h[2]); \
1599 pwd->h[3] = msa_ ## func ## _df(df, pwd->h[3], pws->h[3], pwt->h[3]); \
1600 pwd->h[4] = msa_ ## func ## _df(df, pwd->h[4], pws->h[4], pwt->h[4]); \
1601 pwd->h[5] = msa_ ## func ## _df(df, pwd->h[5], pws->h[5], pwt->h[5]); \
1602 pwd->h[6] = msa_ ## func ## _df(df, pwd->h[6], pws->h[6], pwt->h[6]); \
1603 pwd->h[7] = msa_ ## func ## _df(df, pwd->h[7], pws->h[7], pwt->h[7]); \
1604 break; \
1605 case DF_WORD: \
1606 pwd->w[0] = msa_ ## func ## _df(df, pwd->w[0], pws->w[0], pwt->w[0]); \
1607 pwd->w[1] = msa_ ## func ## _df(df, pwd->w[1], pws->w[1], pwt->w[1]); \
1608 pwd->w[2] = msa_ ## func ## _df(df, pwd->w[2], pws->w[2], pwt->w[2]); \
1609 pwd->w[3] = msa_ ## func ## _df(df, pwd->w[3], pws->w[3], pwt->w[3]); \
1610 break; \
1611 case DF_DOUBLE: \
1612 pwd->d[0] = msa_ ## func ## _df(df, pwd->d[0], pws->d[0], pwt->d[0]); \
1613 pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
1614 break; \
1615 default: \
1616 assert(0); \
1617 } \
1618}
1619
1620MSA_TEROP_DF(maddv)
1621MSA_TEROP_DF(msubv)
1622MSA_TEROP_DF(dpadd_s)
1623MSA_TEROP_DF(dpadd_u)
1624MSA_TEROP_DF(dpsub_s)
1625MSA_TEROP_DF(dpsub_u)
1626MSA_TEROP_DF(binsl)
1627MSA_TEROP_DF(binsr)
1628MSA_TEROP_DF(madd_q)
1629MSA_TEROP_DF(msub_q)
1630MSA_TEROP_DF(maddr_q)
1631MSA_TEROP_DF(msubr_q)
1632#undef MSA_TEROP_DF
1633
1634static inline void msa_splat_df(uint32_t df, wr_t *pwd,
1635 wr_t *pws, target_ulong rt)
1636{
1637 uint32_t n = rt % DF_ELEMENTS(df);
1638 uint32_t i;
1639
1640 switch (df) {
1641 case DF_BYTE:
1642 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
1643 pwd->b[i] = pws->b[n];
1644 }
1645 break;
1646 case DF_HALF:
1647 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
1648 pwd->h[i] = pws->h[n];
1649 }
1650 break;
1651 case DF_WORD:
1652 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
1653 pwd->w[i] = pws->w[n];
1654 }
1655 break;
1656 case DF_DOUBLE:
1657 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
1658 pwd->d[i] = pws->d[n];
1659 }
1660 break;
1661 default:
1662 assert(0);
1663 }
1664}
1665
1666void helper_msa_splat_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1667 uint32_t ws, uint32_t rt)
1668{
1669 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1670 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1671
1672 msa_splat_df(df, pwd, pws, env->active_tc.gpr[rt]);
1673}
1674
1675#define MSA_DO_B MSA_DO(b)
1676#define MSA_DO_H MSA_DO(h)
1677#define MSA_DO_W MSA_DO(w)
1678#define MSA_DO_D MSA_DO(d)
1679
1680#define MSA_LOOP_B MSA_LOOP(B)
1681#define MSA_LOOP_H MSA_LOOP(H)
1682#define MSA_LOOP_W MSA_LOOP(W)
1683#define MSA_LOOP_D MSA_LOOP(D)
1684
1685#define MSA_LOOP_COND_B MSA_LOOP_COND(DF_BYTE)
1686#define MSA_LOOP_COND_H MSA_LOOP_COND(DF_HALF)
1687#define MSA_LOOP_COND_W MSA_LOOP_COND(DF_WORD)
1688#define MSA_LOOP_COND_D MSA_LOOP_COND(DF_DOUBLE)
1689
1690#define MSA_LOOP(DF) \
1691 do { \
1692 for (i = 0; i < (MSA_LOOP_COND_ ## DF) ; i++) { \
1693 MSA_DO_ ## DF; \
1694 } \
1695 } while (0)
1696
1697#define MSA_FN_DF(FUNC) \
1698void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
1699 uint32_t ws, uint32_t wt) \
1700{ \
1701 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
1702 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
1703 wr_t *pwt = &(env->active_fpu.fpr[wt].wr); \
1704 wr_t wx, *pwx = &wx; \
1705 uint32_t i; \
1706 switch (df) { \
1707 case DF_BYTE: \
1708 MSA_LOOP_B; \
1709 break; \
1710 case DF_HALF: \
1711 MSA_LOOP_H; \
1712 break; \
1713 case DF_WORD: \
1714 MSA_LOOP_W; \
1715 break; \
1716 case DF_DOUBLE: \
1717 MSA_LOOP_D; \
1718 break; \
1719 default: \
1720 assert(0); \
1721 } \
1722 msa_move_v(pwd, pwx); \
1723}
1724
1725#define MSA_LOOP_COND(DF) \
1726 (DF_ELEMENTS(DF) / 2)
1727
1728#define Rb(pwr, i) (pwr->b[i])
1729#define Lb(pwr, i) (pwr->b[i + DF_ELEMENTS(DF_BYTE) / 2])
1730#define Rh(pwr, i) (pwr->h[i])
1731#define Lh(pwr, i) (pwr->h[i + DF_ELEMENTS(DF_HALF) / 2])
1732#define Rw(pwr, i) (pwr->w[i])
1733#define Lw(pwr, i) (pwr->w[i + DF_ELEMENTS(DF_WORD) / 2])
1734#define Rd(pwr, i) (pwr->d[i])
1735#define Ld(pwr, i) (pwr->d[i + DF_ELEMENTS(DF_DOUBLE) / 2])
1736
1737#undef MSA_LOOP_COND
1738
1739#define MSA_LOOP_COND(DF) \
1740 (DF_ELEMENTS(DF))
1741
1742#define MSA_DO(DF) \
1743 do { \
1744 uint32_t n = DF_ELEMENTS(df); \
1745 uint32_t k = (pwd->DF[i] & 0x3f) % (2 * n); \
1746 pwx->DF[i] = \
1747 (pwd->DF[i] & 0xc0) ? 0 : k < n ? pwt->DF[k] : pws->DF[k - n]; \
1748 } while (0)
1749MSA_FN_DF(vshf_df)
1750#undef MSA_DO
1751#undef MSA_LOOP_COND
1752#undef MSA_FN_DF
1753
1754
1755void helper_msa_ilvev_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1756 uint32_t ws, uint32_t wt)
1757{
1758 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1759 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1760 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1761
1762 switch (df) {
1763 case DF_BYTE:
1764#if defined(HOST_WORDS_BIGENDIAN)
1765 pwd->b[8] = pws->b[9];
1766 pwd->b[9] = pwt->b[9];
1767 pwd->b[10] = pws->b[11];
1768 pwd->b[11] = pwt->b[11];
1769 pwd->b[12] = pws->b[13];
1770 pwd->b[13] = pwt->b[13];
1771 pwd->b[14] = pws->b[15];
1772 pwd->b[15] = pwt->b[15];
1773 pwd->b[0] = pws->b[1];
1774 pwd->b[1] = pwt->b[1];
1775 pwd->b[2] = pws->b[3];
1776 pwd->b[3] = pwt->b[3];
1777 pwd->b[4] = pws->b[5];
1778 pwd->b[5] = pwt->b[5];
1779 pwd->b[6] = pws->b[7];
1780 pwd->b[7] = pwt->b[7];
1781#else
1782 pwd->b[15] = pws->b[14];
1783 pwd->b[14] = pwt->b[14];
1784 pwd->b[13] = pws->b[12];
1785 pwd->b[12] = pwt->b[12];
1786 pwd->b[11] = pws->b[10];
1787 pwd->b[10] = pwt->b[10];
1788 pwd->b[9] = pws->b[8];
1789 pwd->b[8] = pwt->b[8];
1790 pwd->b[7] = pws->b[6];
1791 pwd->b[6] = pwt->b[6];
1792 pwd->b[5] = pws->b[4];
1793 pwd->b[4] = pwt->b[4];
1794 pwd->b[3] = pws->b[2];
1795 pwd->b[2] = pwt->b[2];
1796 pwd->b[1] = pws->b[0];
1797 pwd->b[0] = pwt->b[0];
1798#endif
1799 break;
1800 case DF_HALF:
1801#if defined(HOST_WORDS_BIGENDIAN)
1802 pwd->h[4] = pws->h[5];
1803 pwd->h[5] = pwt->h[5];
1804 pwd->h[6] = pws->h[7];
1805 pwd->h[7] = pwt->h[7];
1806 pwd->h[0] = pws->h[1];
1807 pwd->h[1] = pwt->h[1];
1808 pwd->h[2] = pws->h[3];
1809 pwd->h[3] = pwt->h[3];
1810#else
1811 pwd->h[7] = pws->h[6];
1812 pwd->h[6] = pwt->h[6];
1813 pwd->h[5] = pws->h[4];
1814 pwd->h[4] = pwt->h[4];
1815 pwd->h[3] = pws->h[2];
1816 pwd->h[2] = pwt->h[2];
1817 pwd->h[1] = pws->h[0];
1818 pwd->h[0] = pwt->h[0];
1819#endif
1820 break;
1821 case DF_WORD:
1822#if defined(HOST_WORDS_BIGENDIAN)
1823 pwd->w[2] = pws->w[3];
1824 pwd->w[3] = pwt->w[3];
1825 pwd->w[0] = pws->w[1];
1826 pwd->w[1] = pwt->w[1];
1827#else
1828 pwd->w[3] = pws->w[2];
1829 pwd->w[2] = pwt->w[2];
1830 pwd->w[1] = pws->w[0];
1831 pwd->w[0] = pwt->w[0];
1832#endif
1833 break;
1834 case DF_DOUBLE:
1835 pwd->d[1] = pws->d[0];
1836 pwd->d[0] = pwt->d[0];
1837 break;
1838 default:
1839 assert(0);
1840 }
1841}
1842
1843void helper_msa_ilvod_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1844 uint32_t ws, uint32_t wt)
1845{
1846 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1847 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1848 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1849
1850 switch (df) {
1851 case DF_BYTE:
1852#if defined(HOST_WORDS_BIGENDIAN)
1853 pwd->b[7] = pwt->b[6];
1854 pwd->b[6] = pws->b[6];
1855 pwd->b[5] = pwt->b[4];
1856 pwd->b[4] = pws->b[4];
1857 pwd->b[3] = pwt->b[2];
1858 pwd->b[2] = pws->b[2];
1859 pwd->b[1] = pwt->b[0];
1860 pwd->b[0] = pws->b[0];
1861 pwd->b[15] = pwt->b[14];
1862 pwd->b[14] = pws->b[14];
1863 pwd->b[13] = pwt->b[12];
1864 pwd->b[12] = pws->b[12];
1865 pwd->b[11] = pwt->b[10];
1866 pwd->b[10] = pws->b[10];
1867 pwd->b[9] = pwt->b[8];
1868 pwd->b[8] = pws->b[8];
1869#else
1870 pwd->b[0] = pwt->b[1];
1871 pwd->b[1] = pws->b[1];
1872 pwd->b[2] = pwt->b[3];
1873 pwd->b[3] = pws->b[3];
1874 pwd->b[4] = pwt->b[5];
1875 pwd->b[5] = pws->b[5];
1876 pwd->b[6] = pwt->b[7];
1877 pwd->b[7] = pws->b[7];
1878 pwd->b[8] = pwt->b[9];
1879 pwd->b[9] = pws->b[9];
1880 pwd->b[10] = pwt->b[11];
1881 pwd->b[11] = pws->b[11];
1882 pwd->b[12] = pwt->b[13];
1883 pwd->b[13] = pws->b[13];
1884 pwd->b[14] = pwt->b[15];
1885 pwd->b[15] = pws->b[15];
1886#endif
1887 break;
1888 case DF_HALF:
1889#if defined(HOST_WORDS_BIGENDIAN)
1890 pwd->h[3] = pwt->h[2];
1891 pwd->h[2] = pws->h[2];
1892 pwd->h[1] = pwt->h[0];
1893 pwd->h[0] = pws->h[0];
1894 pwd->h[7] = pwt->h[6];
1895 pwd->h[6] = pws->h[6];
1896 pwd->h[5] = pwt->h[4];
1897 pwd->h[4] = pws->h[4];
1898#else
1899 pwd->h[0] = pwt->h[1];
1900 pwd->h[1] = pws->h[1];
1901 pwd->h[2] = pwt->h[3];
1902 pwd->h[3] = pws->h[3];
1903 pwd->h[4] = pwt->h[5];
1904 pwd->h[5] = pws->h[5];
1905 pwd->h[6] = pwt->h[7];
1906 pwd->h[7] = pws->h[7];
1907#endif
1908 break;
1909 case DF_WORD:
1910#if defined(HOST_WORDS_BIGENDIAN)
1911 pwd->w[1] = pwt->w[0];
1912 pwd->w[0] = pws->w[0];
1913 pwd->w[3] = pwt->w[2];
1914 pwd->w[2] = pws->w[2];
1915#else
1916 pwd->w[0] = pwt->w[1];
1917 pwd->w[1] = pws->w[1];
1918 pwd->w[2] = pwt->w[3];
1919 pwd->w[3] = pws->w[3];
1920#endif
1921 break;
1922 case DF_DOUBLE:
1923 pwd->d[0] = pwt->d[1];
1924 pwd->d[1] = pws->d[1];
1925 break;
1926 default:
1927 assert(0);
1928 }
1929}
1930
1931void helper_msa_ilvl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
1932 uint32_t ws, uint32_t wt)
1933{
1934 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
1935 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
1936 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
1937
1938 switch (df) {
1939 case DF_BYTE:
1940#if defined(HOST_WORDS_BIGENDIAN)
1941 pwd->b[7] = pwt->b[15];
1942 pwd->b[6] = pws->b[15];
1943 pwd->b[5] = pwt->b[14];
1944 pwd->b[4] = pws->b[14];
1945 pwd->b[3] = pwt->b[13];
1946 pwd->b[2] = pws->b[13];
1947 pwd->b[1] = pwt->b[12];
1948 pwd->b[0] = pws->b[12];
1949 pwd->b[15] = pwt->b[11];
1950 pwd->b[14] = pws->b[11];
1951 pwd->b[13] = pwt->b[10];
1952 pwd->b[12] = pws->b[10];
1953 pwd->b[11] = pwt->b[9];
1954 pwd->b[10] = pws->b[9];
1955 pwd->b[9] = pwt->b[8];
1956 pwd->b[8] = pws->b[8];
1957#else
1958 pwd->b[0] = pwt->b[8];
1959 pwd->b[1] = pws->b[8];
1960 pwd->b[2] = pwt->b[9];
1961 pwd->b[3] = pws->b[9];
1962 pwd->b[4] = pwt->b[10];
1963 pwd->b[5] = pws->b[10];
1964 pwd->b[6] = pwt->b[11];
1965 pwd->b[7] = pws->b[11];
1966 pwd->b[8] = pwt->b[12];
1967 pwd->b[9] = pws->b[12];
1968 pwd->b[10] = pwt->b[13];
1969 pwd->b[11] = pws->b[13];
1970 pwd->b[12] = pwt->b[14];
1971 pwd->b[13] = pws->b[14];
1972 pwd->b[14] = pwt->b[15];
1973 pwd->b[15] = pws->b[15];
1974#endif
1975 break;
1976 case DF_HALF:
1977#if defined(HOST_WORDS_BIGENDIAN)
1978 pwd->h[3] = pwt->h[7];
1979 pwd->h[2] = pws->h[7];
1980 pwd->h[1] = pwt->h[6];
1981 pwd->h[0] = pws->h[6];
1982 pwd->h[7] = pwt->h[5];
1983 pwd->h[6] = pws->h[5];
1984 pwd->h[5] = pwt->h[4];
1985 pwd->h[4] = pws->h[4];
1986#else
1987 pwd->h[0] = pwt->h[4];
1988 pwd->h[1] = pws->h[4];
1989 pwd->h[2] = pwt->h[5];
1990 pwd->h[3] = pws->h[5];
1991 pwd->h[4] = pwt->h[6];
1992 pwd->h[5] = pws->h[6];
1993 pwd->h[6] = pwt->h[7];
1994 pwd->h[7] = pws->h[7];
1995#endif
1996 break;
1997 case DF_WORD:
1998#if defined(HOST_WORDS_BIGENDIAN)
1999 pwd->w[1] = pwt->w[3];
2000 pwd->w[0] = pws->w[3];
2001 pwd->w[3] = pwt->w[2];
2002 pwd->w[2] = pws->w[2];
2003#else
2004 pwd->w[0] = pwt->w[2];
2005 pwd->w[1] = pws->w[2];
2006 pwd->w[2] = pwt->w[3];
2007 pwd->w[3] = pws->w[3];
2008#endif
2009 break;
2010 case DF_DOUBLE:
2011 pwd->d[0] = pwt->d[1];
2012 pwd->d[1] = pws->d[1];
2013 break;
2014 default:
2015 assert(0);
2016 }
2017}
2018
2019void helper_msa_ilvr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2020 uint32_t ws, uint32_t wt)
2021{
2022 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2023 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2024 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2025
2026 switch (df) {
2027 case DF_BYTE:
2028#if defined(HOST_WORDS_BIGENDIAN)
2029 pwd->b[8] = pws->b[0];
2030 pwd->b[9] = pwt->b[0];
2031 pwd->b[10] = pws->b[1];
2032 pwd->b[11] = pwt->b[1];
2033 pwd->b[12] = pws->b[2];
2034 pwd->b[13] = pwt->b[2];
2035 pwd->b[14] = pws->b[3];
2036 pwd->b[15] = pwt->b[3];
2037 pwd->b[0] = pws->b[4];
2038 pwd->b[1] = pwt->b[4];
2039 pwd->b[2] = pws->b[5];
2040 pwd->b[3] = pwt->b[5];
2041 pwd->b[4] = pws->b[6];
2042 pwd->b[5] = pwt->b[6];
2043 pwd->b[6] = pws->b[7];
2044 pwd->b[7] = pwt->b[7];
2045#else
2046 pwd->b[15] = pws->b[7];
2047 pwd->b[14] = pwt->b[7];
2048 pwd->b[13] = pws->b[6];
2049 pwd->b[12] = pwt->b[6];
2050 pwd->b[11] = pws->b[5];
2051 pwd->b[10] = pwt->b[5];
2052 pwd->b[9] = pws->b[4];
2053 pwd->b[8] = pwt->b[4];
2054 pwd->b[7] = pws->b[3];
2055 pwd->b[6] = pwt->b[3];
2056 pwd->b[5] = pws->b[2];
2057 pwd->b[4] = pwt->b[2];
2058 pwd->b[3] = pws->b[1];
2059 pwd->b[2] = pwt->b[1];
2060 pwd->b[1] = pws->b[0];
2061 pwd->b[0] = pwt->b[0];
2062#endif
2063 break;
2064 case DF_HALF:
2065#if defined(HOST_WORDS_BIGENDIAN)
2066 pwd->h[4] = pws->h[0];
2067 pwd->h[5] = pwt->h[0];
2068 pwd->h[6] = pws->h[1];
2069 pwd->h[7] = pwt->h[1];
2070 pwd->h[0] = pws->h[2];
2071 pwd->h[1] = pwt->h[2];
2072 pwd->h[2] = pws->h[3];
2073 pwd->h[3] = pwt->h[3];
2074#else
2075 pwd->h[7] = pws->h[3];
2076 pwd->h[6] = pwt->h[3];
2077 pwd->h[5] = pws->h[2];
2078 pwd->h[4] = pwt->h[2];
2079 pwd->h[3] = pws->h[1];
2080 pwd->h[2] = pwt->h[1];
2081 pwd->h[1] = pws->h[0];
2082 pwd->h[0] = pwt->h[0];
2083#endif
2084 break;
2085 case DF_WORD:
2086#if defined(HOST_WORDS_BIGENDIAN)
2087 pwd->w[2] = pws->w[0];
2088 pwd->w[3] = pwt->w[0];
2089 pwd->w[0] = pws->w[1];
2090 pwd->w[1] = pwt->w[1];
2091#else
2092 pwd->w[3] = pws->w[1];
2093 pwd->w[2] = pwt->w[1];
2094 pwd->w[1] = pws->w[0];
2095 pwd->w[0] = pwt->w[0];
2096#endif
2097 break;
2098 case DF_DOUBLE:
2099 pwd->d[1] = pws->d[0];
2100 pwd->d[0] = pwt->d[0];
2101 break;
2102 default:
2103 assert(0);
2104 }
2105}
2106
2107void helper_msa_pckev_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2108 uint32_t ws, uint32_t wt)
2109{
2110 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2111 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2112 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2113
2114 switch (df) {
2115 case DF_BYTE:
2116#if defined(HOST_WORDS_BIGENDIAN)
2117 pwd->b[8] = pws->b[9];
2118 pwd->b[10] = pws->b[13];
2119 pwd->b[12] = pws->b[1];
2120 pwd->b[14] = pws->b[5];
2121 pwd->b[0] = pwt->b[9];
2122 pwd->b[2] = pwt->b[13];
2123 pwd->b[4] = pwt->b[1];
2124 pwd->b[6] = pwt->b[5];
2125 pwd->b[9] = pws->b[11];
2126 pwd->b[13] = pws->b[3];
2127 pwd->b[1] = pwt->b[11];
2128 pwd->b[5] = pwt->b[3];
2129 pwd->b[11] = pws->b[15];
2130 pwd->b[3] = pwt->b[15];
2131 pwd->b[15] = pws->b[7];
2132 pwd->b[7] = pwt->b[7];
2133#else
2134 pwd->b[15] = pws->b[14];
2135 pwd->b[13] = pws->b[10];
2136 pwd->b[11] = pws->b[6];
2137 pwd->b[9] = pws->b[2];
2138 pwd->b[7] = pwt->b[14];
2139 pwd->b[5] = pwt->b[10];
2140 pwd->b[3] = pwt->b[6];
2141 pwd->b[1] = pwt->b[2];
2142 pwd->b[14] = pws->b[12];
2143 pwd->b[10] = pws->b[4];
2144 pwd->b[6] = pwt->b[12];
2145 pwd->b[2] = pwt->b[4];
2146 pwd->b[12] = pws->b[8];
2147 pwd->b[4] = pwt->b[8];
2148 pwd->b[8] = pws->b[0];
2149 pwd->b[0] = pwt->b[0];
2150#endif
2151 break;
2152 case DF_HALF:
2153#if defined(HOST_WORDS_BIGENDIAN)
2154 pwd->h[4] = pws->h[5];
2155 pwd->h[6] = pws->h[1];
2156 pwd->h[0] = pwt->h[5];
2157 pwd->h[2] = pwt->h[1];
2158 pwd->h[5] = pws->h[7];
2159 pwd->h[1] = pwt->h[7];
2160 pwd->h[7] = pws->h[3];
2161 pwd->h[3] = pwt->h[3];
2162#else
2163 pwd->h[7] = pws->h[6];
2164 pwd->h[5] = pws->h[2];
2165 pwd->h[3] = pwt->h[6];
2166 pwd->h[1] = pwt->h[2];
2167 pwd->h[6] = pws->h[4];
2168 pwd->h[2] = pwt->h[4];
2169 pwd->h[4] = pws->h[0];
2170 pwd->h[0] = pwt->h[0];
2171#endif
2172 break;
2173 case DF_WORD:
2174#if defined(HOST_WORDS_BIGENDIAN)
2175 pwd->w[2] = pws->w[3];
2176 pwd->w[0] = pwt->w[3];
2177 pwd->w[3] = pws->w[1];
2178 pwd->w[1] = pwt->w[1];
2179#else
2180 pwd->w[3] = pws->w[2];
2181 pwd->w[1] = pwt->w[2];
2182 pwd->w[2] = pws->w[0];
2183 pwd->w[0] = pwt->w[0];
2184#endif
2185 break;
2186 case DF_DOUBLE:
2187 pwd->d[1] = pws->d[0];
2188 pwd->d[0] = pwt->d[0];
2189 break;
2190 default:
2191 assert(0);
2192 }
2193}
2194
2195void helper_msa_pckod_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2196 uint32_t ws, uint32_t wt)
2197{
2198 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2199 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2200 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
2201
2202 switch (df) {
2203 case DF_BYTE:
2204#if defined(HOST_WORDS_BIGENDIAN)
2205 pwd->b[7] = pwt->b[6];
2206 pwd->b[5] = pwt->b[2];
2207 pwd->b[3] = pwt->b[14];
2208 pwd->b[1] = pwt->b[10];
2209 pwd->b[15] = pws->b[6];
2210 pwd->b[13] = pws->b[2];
2211 pwd->b[11] = pws->b[14];
2212 pwd->b[9] = pws->b[10];
2213 pwd->b[6] = pwt->b[4];
2214 pwd->b[2] = pwt->b[12];
2215 pwd->b[14] = pws->b[4];
2216 pwd->b[10] = pws->b[12];
2217 pwd->b[4] = pwt->b[0];
2218 pwd->b[12] = pws->b[0];
2219 pwd->b[0] = pwt->b[8];
2220 pwd->b[8] = pws->b[8];
2221#else
2222 pwd->b[0] = pwt->b[1];
2223 pwd->b[2] = pwt->b[5];
2224 pwd->b[4] = pwt->b[9];
2225 pwd->b[6] = pwt->b[13];
2226 pwd->b[8] = pws->b[1];
2227 pwd->b[10] = pws->b[5];
2228 pwd->b[12] = pws->b[9];
2229 pwd->b[14] = pws->b[13];
2230 pwd->b[1] = pwt->b[3];
2231 pwd->b[5] = pwt->b[11];
2232 pwd->b[9] = pws->b[3];
2233 pwd->b[13] = pws->b[11];
2234 pwd->b[3] = pwt->b[7];
2235 pwd->b[11] = pws->b[7];
2236 pwd->b[7] = pwt->b[15];
2237 pwd->b[15] = pws->b[15];
2238#endif
2239 break;
2240 case DF_HALF:
2241#if defined(HOST_WORDS_BIGENDIAN)
2242 pwd->h[3] = pwt->h[2];
2243 pwd->h[1] = pwt->h[6];
2244 pwd->h[7] = pws->h[2];
2245 pwd->h[5] = pws->h[6];
2246 pwd->h[2] = pwt->h[0];
2247 pwd->h[6] = pws->h[0];
2248 pwd->h[0] = pwt->h[4];
2249 pwd->h[4] = pws->h[4];
2250#else
2251 pwd->h[0] = pwt->h[1];
2252 pwd->h[2] = pwt->h[5];
2253 pwd->h[4] = pws->h[1];
2254 pwd->h[6] = pws->h[5];
2255 pwd->h[1] = pwt->h[3];
2256 pwd->h[5] = pws->h[3];
2257 pwd->h[3] = pwt->h[7];
2258 pwd->h[7] = pws->h[7];
2259#endif
2260 break;
2261 case DF_WORD:
2262#if defined(HOST_WORDS_BIGENDIAN)
2263 pwd->w[1] = pwt->w[0];
2264 pwd->w[3] = pws->w[0];
2265 pwd->w[0] = pwt->w[2];
2266 pwd->w[2] = pws->w[2];
2267#else
2268 pwd->w[0] = pwt->w[1];
2269 pwd->w[2] = pws->w[1];
2270 pwd->w[1] = pwt->w[3];
2271 pwd->w[3] = pws->w[3];
2272#endif
2273 break;
2274 case DF_DOUBLE:
2275 pwd->d[0] = pwt->d[1];
2276 pwd->d[1] = pws->d[1];
2277 break;
2278 default:
2279 assert(0);
2280 }
2281}
2282
2283
2284void helper_msa_sldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2285 uint32_t ws, uint32_t n)
2286{
2287 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2288 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2289
2290 msa_sld_df(df, pwd, pws, n);
2291}
2292
2293void helper_msa_splati_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2294 uint32_t ws, uint32_t n)
2295{
2296 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2297 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2298
2299 msa_splat_df(df, pwd, pws, n);
2300}
2301
2302void helper_msa_copy_s_b(CPUMIPSState *env, uint32_t rd,
2303 uint32_t ws, uint32_t n)
2304{
2305 n %= 16;
2306#if defined(HOST_WORDS_BIGENDIAN)
2307 if (n < 8) {
2308 n = 8 - n - 1;
2309 } else {
2310 n = 24 - n - 1;
2311 }
2312#endif
2313 env->active_tc.gpr[rd] = (int8_t)env->active_fpu.fpr[ws].wr.b[n];
2314}
2315
2316void helper_msa_copy_s_h(CPUMIPSState *env, uint32_t rd,
2317 uint32_t ws, uint32_t n)
2318{
2319 n %= 8;
2320#if defined(HOST_WORDS_BIGENDIAN)
2321 if (n < 4) {
2322 n = 4 - n - 1;
2323 } else {
2324 n = 12 - n - 1;
2325 }
2326#endif
2327 env->active_tc.gpr[rd] = (int16_t)env->active_fpu.fpr[ws].wr.h[n];
2328}
2329
2330void helper_msa_copy_s_w(CPUMIPSState *env, uint32_t rd,
2331 uint32_t ws, uint32_t n)
2332{
2333 n %= 4;
2334#if defined(HOST_WORDS_BIGENDIAN)
2335 if (n < 2) {
2336 n = 2 - n - 1;
2337 } else {
2338 n = 6 - n - 1;
2339 }
2340#endif
2341 env->active_tc.gpr[rd] = (int32_t)env->active_fpu.fpr[ws].wr.w[n];
2342}
2343
2344void helper_msa_copy_s_d(CPUMIPSState *env, uint32_t rd,
2345 uint32_t ws, uint32_t n)
2346{
2347 n %= 2;
2348 env->active_tc.gpr[rd] = (int64_t)env->active_fpu.fpr[ws].wr.d[n];
2349}
2350
2351void helper_msa_copy_u_b(CPUMIPSState *env, uint32_t rd,
2352 uint32_t ws, uint32_t n)
2353{
2354 n %= 16;
2355#if defined(HOST_WORDS_BIGENDIAN)
2356 if (n < 8) {
2357 n = 8 - n - 1;
2358 } else {
2359 n = 24 - n - 1;
2360 }
2361#endif
2362 env->active_tc.gpr[rd] = (uint8_t)env->active_fpu.fpr[ws].wr.b[n];
2363}
2364
2365void helper_msa_copy_u_h(CPUMIPSState *env, uint32_t rd,
2366 uint32_t ws, uint32_t n)
2367{
2368 n %= 8;
2369#if defined(HOST_WORDS_BIGENDIAN)
2370 if (n < 4) {
2371 n = 4 - n - 1;
2372 } else {
2373 n = 12 - n - 1;
2374 }
2375#endif
2376 env->active_tc.gpr[rd] = (uint16_t)env->active_fpu.fpr[ws].wr.h[n];
2377}
2378
2379void helper_msa_copy_u_w(CPUMIPSState *env, uint32_t rd,
2380 uint32_t ws, uint32_t n)
2381{
2382 n %= 4;
2383#if defined(HOST_WORDS_BIGENDIAN)
2384 if (n < 2) {
2385 n = 2 - n - 1;
2386 } else {
2387 n = 6 - n - 1;
2388 }
2389#endif
2390 env->active_tc.gpr[rd] = (uint32_t)env->active_fpu.fpr[ws].wr.w[n];
2391}
2392
2393void helper_msa_insert_b(CPUMIPSState *env, uint32_t wd,
2394 uint32_t rs_num, uint32_t n)
2395{
2396 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2397 target_ulong rs = env->active_tc.gpr[rs_num];
2398 n %= 16;
2399#if defined(HOST_WORDS_BIGENDIAN)
2400 if (n < 8) {
2401 n = 8 - n - 1;
2402 } else {
2403 n = 24 - n - 1;
2404 }
2405#endif
2406 pwd->b[n] = (int8_t)rs;
2407}
2408
2409void helper_msa_insert_h(CPUMIPSState *env, uint32_t wd,
2410 uint32_t rs_num, uint32_t n)
2411{
2412 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2413 target_ulong rs = env->active_tc.gpr[rs_num];
2414 n %= 8;
2415#if defined(HOST_WORDS_BIGENDIAN)
2416 if (n < 4) {
2417 n = 4 - n - 1;
2418 } else {
2419 n = 12 - n - 1;
2420 }
2421#endif
2422 pwd->h[n] = (int16_t)rs;
2423}
2424
2425void helper_msa_insert_w(CPUMIPSState *env, uint32_t wd,
2426 uint32_t rs_num, uint32_t n)
2427{
2428 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2429 target_ulong rs = env->active_tc.gpr[rs_num];
2430 n %= 4;
2431#if defined(HOST_WORDS_BIGENDIAN)
2432 if (n < 2) {
2433 n = 2 - n - 1;
2434 } else {
2435 n = 6 - n - 1;
2436 }
2437#endif
2438 pwd->w[n] = (int32_t)rs;
2439}
2440
2441void helper_msa_insert_d(CPUMIPSState *env, uint32_t wd,
2442 uint32_t rs_num, uint32_t n)
2443{
2444 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2445 target_ulong rs = env->active_tc.gpr[rs_num];
2446 n %= 2;
2447 pwd->d[n] = (int64_t)rs;
2448}
2449
2450void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2451 uint32_t ws, uint32_t n)
2452{
2453 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2454 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2455
2456 switch (df) {
2457 case DF_BYTE:
2458 pwd->b[n] = (int8_t)pws->b[0];
2459 break;
2460 case DF_HALF:
2461 pwd->h[n] = (int16_t)pws->h[0];
2462 break;
2463 case DF_WORD:
2464 pwd->w[n] = (int32_t)pws->w[0];
2465 break;
2466 case DF_DOUBLE:
2467 pwd->d[n] = (int64_t)pws->d[0];
2468 break;
2469 default:
2470 assert(0);
2471 }
2472}
2473
2474void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
2475{
2476 switch (cd) {
2477 case 0:
2478 break;
2479 case 1:
2480 env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK;
2481 restore_msa_fp_status(env);
2482
2483 if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)
2484 & GET_FP_CAUSE(env->active_tc.msacsr)) {
2485 do_raise_exception(env, EXCP_MSAFPE, GETPC());
2486 }
2487 break;
2488 }
2489}
2490
2491target_ulong helper_msa_cfcmsa(CPUMIPSState *env, uint32_t cs)
2492{
2493 switch (cs) {
2494 case 0:
2495 return env->msair;
2496 case 1:
2497 return env->active_tc.msacsr & MSACSR_MASK;
2498 }
2499 return 0;
2500}
2501
2502void helper_msa_move_v(CPUMIPSState *env, uint32_t wd, uint32_t ws)
2503{
2504 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2505 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
2506
2507 msa_move_v(pwd, pws);
2508}
2509
2510static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
2511{
2512 uint64_t x;
2513
2514 x = UNSIGNED(arg, df);
2515
2516 x = (x & 0x5555555555555555ULL) + ((x >> 1) & 0x5555555555555555ULL);
2517 x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
2518 x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL);
2519 x = (x & 0x00FF00FF00FF00FFULL) + ((x >> 8) & 0x00FF00FF00FF00FFULL);
2520 x = (x & 0x0000FFFF0000FFFFULL) + ((x >> 16) & 0x0000FFFF0000FFFFULL);
2521 x = (x & 0x00000000FFFFFFFFULL) + ((x >> 32));
2522
2523 return x;
2524}
2525
2526static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
2527{
2528 uint64_t x, y;
2529 int n, c;
2530
2531 x = UNSIGNED(arg, df);
2532 n = DF_BITS(df);
2533 c = DF_BITS(df) / 2;
2534
2535 do {
2536 y = x >> c;
2537 if (y != 0) {
2538 n = n - c;
2539 x = y;
2540 }
2541 c = c >> 1;
2542 } while (c != 0);
2543
2544 return n - x;
2545}
2546
2547static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
2548{
2549 return msa_nlzc_df(df, UNSIGNED((~arg), df));
2550}
2551
2552void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
2553 uint32_t rs)
2554{
2555 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
2556 uint32_t i;
2557
2558 switch (df) {
2559 case DF_BYTE:
2560 for (i = 0; i < DF_ELEMENTS(DF_BYTE); i++) {
2561 pwd->b[i] = (int8_t)env->active_tc.gpr[rs];
2562 }
2563 break;
2564 case DF_HALF:
2565 for (i = 0; i < DF_ELEMENTS(DF_HALF); i++) {
2566 pwd->h[i] = (int16_t)env->active_tc.gpr[rs];
2567 }
2568 break;
2569 case DF_WORD:
2570 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
2571 pwd->w[i] = (int32_t)env->active_tc.gpr[rs];
2572 }
2573 break;
2574 case DF_DOUBLE:
2575 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
2576 pwd->d[i] = (int64_t)env->active_tc.gpr[rs];
2577 }
2578 break;
2579 default:
2580 assert(0);
2581 }
2582}
2583
2584#define MSA_UNOP_DF(func) \
2585void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
2586 uint32_t wd, uint32_t ws) \
2587{ \
2588 wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
2589 wr_t *pws = &(env->active_fpu.fpr[ws].wr); \
2590 \
2591 switch (df) { \
2592 case DF_BYTE: \
2593 pwd->b[0] = msa_ ## func ## _df(df, pws->b[0]); \
2594 pwd->b[1] = msa_ ## func ## _df(df, pws->b[1]); \
2595 pwd->b[2] = msa_ ## func ## _df(df, pws->b[2]); \
2596 pwd->b[3] = msa_ ## func ## _df(df, pws->b[3]); \
2597 pwd->b[4] = msa_ ## func ## _df(df, pws->b[4]); \
2598 pwd->b[5] = msa_ ## func ## _df(df, pws->b[5]); \
2599 pwd->b[6] = msa_ ## func ## _df(df, pws->b[6]); \
2600 pwd->b[7] = msa_ ## func ## _df(df, pws->b[7]); \
2601 pwd->b[8] = msa_ ## func ## _df(df, pws->b[8]); \
2602 pwd->b[9] = msa_ ## func ## _df(df, pws->b[9]); \
2603 pwd->b[10] = msa_ ## func ## _df(df, pws->b[10]); \
2604 pwd->b[11] = msa_ ## func ## _df(df, pws->b[11]); \
2605 pwd->b[12] = msa_ ## func ## _df(df, pws->b[12]); \
2606 pwd->b[13] = msa_ ## func ## _df(df, pws->b[13]); \
2607 pwd->b[14] = msa_ ## func ## _df(df, pws->b[14]); \
2608 pwd->b[15] = msa_ ## func ## _df(df, pws->b[15]); \
2609 break; \
2610 case DF_HALF: \
2611 pwd->h[0] = msa_ ## func ## _df(df, pws->h[0]); \
2612 pwd->h[1] = msa_ ## func ## _df(df, pws->h[1]); \
2613 pwd->h[2] = msa_ ## func ## _df(df, pws->h[2]); \
2614 pwd->h[3] = msa_ ## func ## _df(df, pws->h[3]); \
2615 pwd->h[4] = msa_ ## func ## _df(df, pws->h[4]); \
2616 pwd->h[5] = msa_ ## func ## _df(df, pws->h[5]); \
2617 pwd->h[6] = msa_ ## func ## _df(df, pws->h[6]); \
2618 pwd->h[7] = msa_ ## func ## _df(df, pws->h[7]); \
2619 break; \
2620 case DF_WORD: \
2621 pwd->w[0] = msa_ ## func ## _df(df, pws->w[0]); \
2622 pwd->w[1] = msa_ ## func ## _df(df, pws->w[1]); \
2623 pwd->w[2] = msa_ ## func ## _df(df, pws->w[2]); \
2624 pwd->w[3] = msa_ ## func ## _df(df, pws->w[3]); \
2625 break; \
2626 case DF_DOUBLE: \
2627 pwd->d[0] = msa_ ## func ## _df(df, pws->d[0]); \
2628 pwd->d[1] = msa_ ## func ## _df(df, pws->d[1]); \
2629 break; \
2630 default: \
2631 assert(0); \
2632 } \
2633}
2634
2635MSA_UNOP_DF(nlzc)
2636MSA_UNOP_DF(nloc)
2637MSA_UNOP_DF(pcnt)
2638#undef MSA_UNOP_DF
2639
2640#define FLOAT_ONE32 make_float32(0x3f8 << 20)
2641#define FLOAT_ONE64 make_float64(0x3ffULL << 52)
2642
2643#define FLOAT_SNAN16(s) (float16_default_nan(s) ^ 0x0220)
2644
2645#define FLOAT_SNAN32(s) (float32_default_nan(s) ^ 0x00400020)
2646
2647#define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
2648
2649
2650static inline void clear_msacsr_cause(CPUMIPSState *env)
2651{
2652 SET_FP_CAUSE(env->active_tc.msacsr, 0);
2653}
2654
2655static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
2656{
2657 if ((GET_FP_CAUSE(env->active_tc.msacsr) &
2658 (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
2659 UPDATE_FP_FLAGS(env->active_tc.msacsr,
2660 GET_FP_CAUSE(env->active_tc.msacsr));
2661 } else {
2662 do_raise_exception(env, EXCP_MSAFPE, retaddr);
2663 }
2664}
2665
2666
2667#define CLEAR_FS_UNDERFLOW 1
2668#define CLEAR_IS_INEXACT 2
2669#define RECIPROCAL_INEXACT 4
2670
2671static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
2672{
2673 int ieee_ex;
2674
2675 int c;
2676 int cause;
2677 int enable;
2678
2679 ieee_ex = get_float_exception_flags(&env->active_tc.msa_fp_status);
2680
2681
2682 if (denormal) {
2683 ieee_ex |= float_flag_underflow;
2684 }
2685
2686 c = ieee_ex_to_mips(ieee_ex);
2687 enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
2688
2689
2690 if ((ieee_ex & float_flag_input_denormal) &&
2691 (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
2692 if (action & CLEAR_IS_INEXACT) {
2693 c &= ~FP_INEXACT;
2694 } else {
2695 c |= FP_INEXACT;
2696 }
2697 }
2698
2699
2700 if ((ieee_ex & float_flag_output_denormal) &&
2701 (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
2702 c |= FP_INEXACT;
2703 if (action & CLEAR_FS_UNDERFLOW) {
2704 c &= ~FP_UNDERFLOW;
2705 } else {
2706 c |= FP_UNDERFLOW;
2707 }
2708 }
2709
2710
2711 if ((c & FP_OVERFLOW) != 0 && (enable & FP_OVERFLOW) == 0) {
2712 c |= FP_INEXACT;
2713 }
2714
2715
2716 if ((c & FP_UNDERFLOW) != 0 && (enable & FP_UNDERFLOW) == 0 &&
2717 (c & FP_INEXACT) == 0) {
2718 c &= ~FP_UNDERFLOW;
2719 }
2720
2721
2722
2723
2724
2725 if ((action & RECIPROCAL_INEXACT) &&
2726 (c & (FP_INVALID | FP_DIV0)) == 0) {
2727 c = FP_INEXACT;
2728 }
2729
2730 cause = c & enable;
2731
2732 if (cause == 0) {
2733
2734
2735
2736
2737 SET_FP_CAUSE(env->active_tc.msacsr,
2738 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
2739 } else {
2740
2741 if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
2742
2743
2744
2745
2746 SET_FP_CAUSE(env->active_tc.msacsr,
2747 (GET_FP_CAUSE(env->active_tc.msacsr) | c));
2748 }
2749 }
2750
2751 return c;
2752}
2753
2754static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
2755{
2756 int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
2757 return c & enable;
2758}
2759
2760static inline float16 float16_from_float32(int32_t a, flag ieee,
2761 float_status *status)
2762{
2763 float16 f_val;
2764
2765 f_val = float32_to_float16((float32)a, ieee, status);
2766
2767 return a < 0 ? (f_val | (1 << 15)) : f_val;
2768}
2769
2770static inline float32 float32_from_float64(int64_t a, float_status *status)
2771{
2772 float32 f_val;
2773
2774 f_val = float64_to_float32((float64)a, status);
2775
2776 return a < 0 ? (f_val | (1 << 31)) : f_val;
2777}
2778
2779static inline float32 float32_from_float16(int16_t a, flag ieee,
2780 float_status *status)
2781{
2782 float32 f_val;
2783
2784 f_val = float16_to_float32((float16)a, ieee, status);
2785
2786 return a < 0 ? (f_val | (1 << 31)) : f_val;
2787}
2788
2789static inline float64 float64_from_float32(int32_t a, float_status *status)
2790{
2791 float64 f_val;
2792
2793 f_val = float32_to_float64((float64)a, status);
2794
2795 return a < 0 ? (f_val | (1ULL << 63)) : f_val;
2796}
2797
2798static inline float32 float32_from_q16(int16_t a, float_status *status)
2799{
2800 float32 f_val;
2801
2802
2803 f_val = int32_to_float32(a, status);
2804 f_val = float32_scalbn(f_val, -15, status);
2805
2806 return f_val;
2807}
2808
2809static inline float64 float64_from_q32(int32_t a, float_status *status)
2810{
2811 float64 f_val;
2812
2813
2814 f_val = int32_to_float64(a, status);
2815 f_val = float64_scalbn(f_val, -31, status);
2816
2817 return f_val;
2818}
2819
2820static inline int16_t float32_to_q16(float32 a, float_status *status)
2821{
2822 int32_t q_val;
2823 int32_t q_min = 0xffff8000;
2824 int32_t q_max = 0x00007fff;
2825
2826 int ieee_ex;
2827
2828 if (float32_is_any_nan(a)) {
2829 float_raise(float_flag_invalid, status);
2830 return 0;
2831 }
2832
2833
2834 a = float32_scalbn(a, 15, status);
2835
2836 ieee_ex = get_float_exception_flags(status);
2837 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2838 , status);
2839
2840 if (ieee_ex & float_flag_overflow) {
2841 float_raise(float_flag_inexact, status);
2842 return (int32_t)a < 0 ? q_min : q_max;
2843 }
2844
2845
2846 q_val = float32_to_int32(a, status);
2847
2848 ieee_ex = get_float_exception_flags(status);
2849 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2850 , status);
2851
2852 if (ieee_ex & float_flag_invalid) {
2853 set_float_exception_flags(ieee_ex & (~float_flag_invalid)
2854 , status);
2855 float_raise(float_flag_overflow | float_flag_inexact, status);
2856 return (int32_t)a < 0 ? q_min : q_max;
2857 }
2858
2859 if (q_val < q_min) {
2860 float_raise(float_flag_overflow | float_flag_inexact, status);
2861 return (int16_t)q_min;
2862 }
2863
2864 if (q_max < q_val) {
2865 float_raise(float_flag_overflow | float_flag_inexact, status);
2866 return (int16_t)q_max;
2867 }
2868
2869 return (int16_t)q_val;
2870}
2871
2872static inline int32_t float64_to_q32(float64 a, float_status *status)
2873{
2874 int64_t q_val;
2875 int64_t q_min = 0xffffffff80000000LL;
2876 int64_t q_max = 0x000000007fffffffLL;
2877
2878 int ieee_ex;
2879
2880 if (float64_is_any_nan(a)) {
2881 float_raise(float_flag_invalid, status);
2882 return 0;
2883 }
2884
2885
2886 a = float64_scalbn(a, 31, status);
2887
2888 ieee_ex = get_float_exception_flags(status);
2889 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2890 , status);
2891
2892 if (ieee_ex & float_flag_overflow) {
2893 float_raise(float_flag_inexact, status);
2894 return (int64_t)a < 0 ? q_min : q_max;
2895 }
2896
2897
2898 q_val = float64_to_int64(a, status);
2899
2900 ieee_ex = get_float_exception_flags(status);
2901 set_float_exception_flags(ieee_ex & (~float_flag_underflow)
2902 , status);
2903
2904 if (ieee_ex & float_flag_invalid) {
2905 set_float_exception_flags(ieee_ex & (~float_flag_invalid)
2906 , status);
2907 float_raise(float_flag_overflow | float_flag_inexact, status);
2908 return (int64_t)a < 0 ? q_min : q_max;
2909 }
2910
2911 if (q_val < q_min) {
2912 float_raise(float_flag_overflow | float_flag_inexact, status);
2913 return (int32_t)q_min;
2914 }
2915
2916 if (q_max < q_val) {
2917 float_raise(float_flag_overflow | float_flag_inexact, status);
2918 return (int32_t)q_max;
2919 }
2920
2921 return (int32_t)q_val;
2922}
2923
2924#define MSA_FLOAT_COND(DEST, OP, ARG1, ARG2, BITS, QUIET) \
2925 do { \
2926 float_status *status = &env->active_tc.msa_fp_status; \
2927 int c; \
2928 int64_t cond; \
2929 set_float_exception_flags(0, status); \
2930 if (!QUIET) { \
2931 cond = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
2932 } else { \
2933 cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status); \
2934 } \
2935 DEST = cond ? M_MAX_UINT(BITS) : 0; \
2936 c = update_msacsr(env, CLEAR_IS_INEXACT, 0); \
2937 \
2938 if (get_enabled_exceptions(env, c)) { \
2939 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
2940 } \
2941 } while (0)
2942
2943#define MSA_FLOAT_AF(DEST, ARG1, ARG2, BITS, QUIET) \
2944 do { \
2945 MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET); \
2946 if ((DEST & M_MAX_UINT(BITS)) == M_MAX_UINT(BITS)) { \
2947 DEST = 0; \
2948 } \
2949 } while (0)
2950
2951#define MSA_FLOAT_UEQ(DEST, ARG1, ARG2, BITS, QUIET) \
2952 do { \
2953 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
2954 if (DEST == 0) { \
2955 MSA_FLOAT_COND(DEST, eq, ARG1, ARG2, BITS, QUIET); \
2956 } \
2957 } while (0)
2958
2959#define MSA_FLOAT_NE(DEST, ARG1, ARG2, BITS, QUIET) \
2960 do { \
2961 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
2962 if (DEST == 0) { \
2963 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET); \
2964 } \
2965 } while (0)
2966
2967#define MSA_FLOAT_UNE(DEST, ARG1, ARG2, BITS, QUIET) \
2968 do { \
2969 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
2970 if (DEST == 0) { \
2971 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
2972 if (DEST == 0) { \
2973 MSA_FLOAT_COND(DEST, lt, ARG2, ARG1, BITS, QUIET); \
2974 } \
2975 } \
2976 } while (0)
2977
2978#define MSA_FLOAT_ULE(DEST, ARG1, ARG2, BITS, QUIET) \
2979 do { \
2980 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
2981 if (DEST == 0) { \
2982 MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET); \
2983 } \
2984 } while (0)
2985
2986#define MSA_FLOAT_ULT(DEST, ARG1, ARG2, BITS, QUIET) \
2987 do { \
2988 MSA_FLOAT_COND(DEST, unordered, ARG1, ARG2, BITS, QUIET); \
2989 if (DEST == 0) { \
2990 MSA_FLOAT_COND(DEST, lt, ARG1, ARG2, BITS, QUIET); \
2991 } \
2992 } while (0)
2993
2994#define MSA_FLOAT_OR(DEST, ARG1, ARG2, BITS, QUIET) \
2995 do { \
2996 MSA_FLOAT_COND(DEST, le, ARG1, ARG2, BITS, QUIET); \
2997 if (DEST == 0) { \
2998 MSA_FLOAT_COND(DEST, le, ARG2, ARG1, BITS, QUIET); \
2999 } \
3000 } while (0)
3001
3002static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3003 wr_t *pwt, uint32_t df, int quiet,
3004 uintptr_t retaddr)
3005{
3006 wr_t wx, *pwx = &wx;
3007 uint32_t i;
3008
3009 clear_msacsr_cause(env);
3010
3011 switch (df) {
3012 case DF_WORD:
3013 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3014 MSA_FLOAT_AF(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3015 }
3016 break;
3017 case DF_DOUBLE:
3018 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3019 MSA_FLOAT_AF(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3020 }
3021 break;
3022 default:
3023 assert(0);
3024 }
3025
3026 check_msacsr_cause(env, retaddr);
3027
3028 msa_move_v(pwd, pwx);
3029}
3030
3031static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3032 wr_t *pwt, uint32_t df, int quiet,
3033 uintptr_t retaddr)
3034{
3035 wr_t wx, *pwx = &wx;
3036 uint32_t i;
3037
3038 clear_msacsr_cause(env);
3039
3040 switch (df) {
3041 case DF_WORD:
3042 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3043 MSA_FLOAT_COND(pwx->w[i], unordered, pws->w[i], pwt->w[i], 32,
3044 quiet);
3045 }
3046 break;
3047 case DF_DOUBLE:
3048 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3049 MSA_FLOAT_COND(pwx->d[i], unordered, pws->d[i], pwt->d[i], 64,
3050 quiet);
3051 }
3052 break;
3053 default:
3054 assert(0);
3055 }
3056
3057 check_msacsr_cause(env, retaddr);
3058
3059 msa_move_v(pwd, pwx);
3060}
3061
3062static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3063 wr_t *pwt, uint32_t df, int quiet,
3064 uintptr_t retaddr)
3065{
3066 wr_t wx, *pwx = &wx;
3067 uint32_t i;
3068
3069 clear_msacsr_cause(env);
3070
3071 switch (df) {
3072 case DF_WORD:
3073 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3074 MSA_FLOAT_COND(pwx->w[i], eq, pws->w[i], pwt->w[i], 32, quiet);
3075 }
3076 break;
3077 case DF_DOUBLE:
3078 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3079 MSA_FLOAT_COND(pwx->d[i], eq, pws->d[i], pwt->d[i], 64, quiet);
3080 }
3081 break;
3082 default:
3083 assert(0);
3084 }
3085
3086 check_msacsr_cause(env, retaddr);
3087
3088 msa_move_v(pwd, pwx);
3089}
3090
3091static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3092 wr_t *pwt, uint32_t df, int quiet,
3093 uintptr_t retaddr)
3094{
3095 wr_t wx, *pwx = &wx;
3096 uint32_t i;
3097
3098 clear_msacsr_cause(env);
3099
3100 switch (df) {
3101 case DF_WORD:
3102 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3103 MSA_FLOAT_UEQ(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3104 }
3105 break;
3106 case DF_DOUBLE:
3107 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3108 MSA_FLOAT_UEQ(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3109 }
3110 break;
3111 default:
3112 assert(0);
3113 }
3114
3115 check_msacsr_cause(env, retaddr);
3116
3117 msa_move_v(pwd, pwx);
3118}
3119
3120static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3121 wr_t *pwt, uint32_t df, int quiet,
3122 uintptr_t retaddr)
3123{
3124 wr_t wx, *pwx = &wx;
3125 uint32_t i;
3126
3127 clear_msacsr_cause(env);
3128
3129 switch (df) {
3130 case DF_WORD:
3131 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3132 MSA_FLOAT_COND(pwx->w[i], lt, pws->w[i], pwt->w[i], 32, quiet);
3133 }
3134 break;
3135 case DF_DOUBLE:
3136 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3137 MSA_FLOAT_COND(pwx->d[i], lt, pws->d[i], pwt->d[i], 64, quiet);
3138 }
3139 break;
3140 default:
3141 assert(0);
3142 }
3143
3144 check_msacsr_cause(env, retaddr);
3145
3146 msa_move_v(pwd, pwx);
3147}
3148
3149static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3150 wr_t *pwt, uint32_t df, int quiet,
3151 uintptr_t retaddr)
3152{
3153 wr_t wx, *pwx = &wx;
3154 uint32_t i;
3155
3156 clear_msacsr_cause(env);
3157
3158 switch (df) {
3159 case DF_WORD:
3160 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3161 MSA_FLOAT_ULT(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3162 }
3163 break;
3164 case DF_DOUBLE:
3165 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3166 MSA_FLOAT_ULT(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3167 }
3168 break;
3169 default:
3170 assert(0);
3171 }
3172
3173 check_msacsr_cause(env, retaddr);
3174
3175 msa_move_v(pwd, pwx);
3176}
3177
3178static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3179 wr_t *pwt, uint32_t df, int quiet,
3180 uintptr_t retaddr)
3181{
3182 wr_t wx, *pwx = &wx;
3183 uint32_t i;
3184
3185 clear_msacsr_cause(env);
3186
3187 switch (df) {
3188 case DF_WORD:
3189 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3190 MSA_FLOAT_COND(pwx->w[i], le, pws->w[i], pwt->w[i], 32, quiet);
3191 }
3192 break;
3193 case DF_DOUBLE:
3194 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3195 MSA_FLOAT_COND(pwx->d[i], le, pws->d[i], pwt->d[i], 64, quiet);
3196 }
3197 break;
3198 default:
3199 assert(0);
3200 }
3201
3202 check_msacsr_cause(env, retaddr);
3203
3204 msa_move_v(pwd, pwx);
3205}
3206
3207static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3208 wr_t *pwt, uint32_t df, int quiet,
3209 uintptr_t retaddr)
3210{
3211 wr_t wx, *pwx = &wx;
3212 uint32_t i;
3213
3214 clear_msacsr_cause(env);
3215
3216 switch (df) {
3217 case DF_WORD:
3218 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3219 MSA_FLOAT_ULE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3220 }
3221 break;
3222 case DF_DOUBLE:
3223 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3224 MSA_FLOAT_ULE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3225 }
3226 break;
3227 default:
3228 assert(0);
3229 }
3230
3231 check_msacsr_cause(env, retaddr);
3232
3233 msa_move_v(pwd, pwx);
3234}
3235
3236static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3237 wr_t *pwt, uint32_t df, int quiet,
3238 uintptr_t retaddr)
3239{
3240 wr_t wx, *pwx = &wx;
3241 uint32_t i;
3242
3243 clear_msacsr_cause(env);
3244
3245 switch (df) {
3246 case DF_WORD:
3247 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3248 MSA_FLOAT_OR(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3249 }
3250 break;
3251 case DF_DOUBLE:
3252 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3253 MSA_FLOAT_OR(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3254 }
3255 break;
3256 default:
3257 assert(0);
3258 }
3259
3260 check_msacsr_cause(env, retaddr);
3261
3262 msa_move_v(pwd, pwx);
3263}
3264
3265static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3266 wr_t *pwt, uint32_t df, int quiet,
3267 uintptr_t retaddr)
3268{
3269 wr_t wx, *pwx = &wx;
3270 uint32_t i;
3271
3272 clear_msacsr_cause(env);
3273
3274 switch (df) {
3275 case DF_WORD:
3276 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3277 MSA_FLOAT_UNE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3278 }
3279 break;
3280 case DF_DOUBLE:
3281 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3282 MSA_FLOAT_UNE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3283 }
3284 break;
3285 default:
3286 assert(0);
3287 }
3288
3289 check_msacsr_cause(env, retaddr);
3290
3291 msa_move_v(pwd, pwx);
3292}
3293
3294static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
3295 wr_t *pwt, uint32_t df, int quiet,
3296 uintptr_t retaddr)
3297{
3298 wr_t wx, *pwx = &wx;
3299 uint32_t i;
3300
3301 clear_msacsr_cause(env);
3302
3303 switch (df) {
3304 case DF_WORD:
3305 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3306 MSA_FLOAT_NE(pwx->w[i], pws->w[i], pwt->w[i], 32, quiet);
3307 }
3308 break;
3309 case DF_DOUBLE:
3310 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3311 MSA_FLOAT_NE(pwx->d[i], pws->d[i], pwt->d[i], 64, quiet);
3312 }
3313 break;
3314 default:
3315 assert(0);
3316 }
3317
3318 check_msacsr_cause(env, retaddr);
3319
3320 msa_move_v(pwd, pwx);
3321}
3322
3323void helper_msa_fcaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3324 uint32_t ws, uint32_t wt)
3325{
3326 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3327 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3328 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3329 compare_af(env, pwd, pws, pwt, df, 1, GETPC());
3330}
3331
3332void helper_msa_fcun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3333 uint32_t ws, uint32_t wt)
3334{
3335 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3336 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3337 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3338 compare_un(env, pwd, pws, pwt, df, 1, GETPC());
3339}
3340
3341void helper_msa_fceq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3342 uint32_t ws, uint32_t wt)
3343{
3344 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3345 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3346 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3347 compare_eq(env, pwd, pws, pwt, df, 1, GETPC());
3348}
3349
3350void helper_msa_fcueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3351 uint32_t ws, uint32_t wt)
3352{
3353 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3354 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3355 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3356 compare_ueq(env, pwd, pws, pwt, df, 1, GETPC());
3357}
3358
3359void helper_msa_fclt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3360 uint32_t ws, uint32_t wt)
3361{
3362 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3363 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3364 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3365 compare_lt(env, pwd, pws, pwt, df, 1, GETPC());
3366}
3367
3368void helper_msa_fcult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3369 uint32_t ws, uint32_t wt)
3370{
3371 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3372 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3373 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3374 compare_ult(env, pwd, pws, pwt, df, 1, GETPC());
3375}
3376
3377void helper_msa_fcle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3378 uint32_t ws, uint32_t wt)
3379{
3380 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3381 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3382 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3383 compare_le(env, pwd, pws, pwt, df, 1, GETPC());
3384}
3385
3386void helper_msa_fcule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3387 uint32_t ws, uint32_t wt)
3388{
3389 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3390 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3391 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3392 compare_ule(env, pwd, pws, pwt, df, 1, GETPC());
3393}
3394
3395void helper_msa_fsaf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3396 uint32_t ws, uint32_t wt)
3397{
3398 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3399 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3400 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3401 compare_af(env, pwd, pws, pwt, df, 0, GETPC());
3402}
3403
3404void helper_msa_fsun_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3405 uint32_t ws, uint32_t wt)
3406{
3407 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3408 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3409 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3410 compare_un(env, pwd, pws, pwt, df, 0, GETPC());
3411}
3412
3413void helper_msa_fseq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3414 uint32_t ws, uint32_t wt)
3415{
3416 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3417 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3418 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3419 compare_eq(env, pwd, pws, pwt, df, 0, GETPC());
3420}
3421
3422void helper_msa_fsueq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3423 uint32_t ws, uint32_t wt)
3424{
3425 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3426 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3427 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3428 compare_ueq(env, pwd, pws, pwt, df, 0, GETPC());
3429}
3430
3431void helper_msa_fslt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3432 uint32_t ws, uint32_t wt)
3433{
3434 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3435 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3436 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3437 compare_lt(env, pwd, pws, pwt, df, 0, GETPC());
3438}
3439
3440void helper_msa_fsult_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3441 uint32_t ws, uint32_t wt)
3442{
3443 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3444 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3445 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3446 compare_ult(env, pwd, pws, pwt, df, 0, GETPC());
3447}
3448
3449void helper_msa_fsle_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3450 uint32_t ws, uint32_t wt)
3451{
3452 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3453 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3454 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3455 compare_le(env, pwd, pws, pwt, df, 0, GETPC());
3456}
3457
3458void helper_msa_fsule_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3459 uint32_t ws, uint32_t wt)
3460{
3461 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3462 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3463 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3464 compare_ule(env, pwd, pws, pwt, df, 0, GETPC());
3465}
3466
3467void helper_msa_fcor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3468 uint32_t ws, uint32_t wt)
3469{
3470 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3471 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3472 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3473 compare_or(env, pwd, pws, pwt, df, 1, GETPC());
3474}
3475
3476void helper_msa_fcune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3477 uint32_t ws, uint32_t wt)
3478{
3479 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3480 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3481 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3482 compare_une(env, pwd, pws, pwt, df, 1, GETPC());
3483}
3484
3485void helper_msa_fcne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3486 uint32_t ws, uint32_t wt)
3487{
3488 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3489 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3490 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3491 compare_ne(env, pwd, pws, pwt, df, 1, GETPC());
3492}
3493
3494void helper_msa_fsor_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3495 uint32_t ws, uint32_t wt)
3496{
3497 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3498 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3499 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3500 compare_or(env, pwd, pws, pwt, df, 0, GETPC());
3501}
3502
3503void helper_msa_fsune_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3504 uint32_t ws, uint32_t wt)
3505{
3506 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3507 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3508 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3509 compare_une(env, pwd, pws, pwt, df, 0, GETPC());
3510}
3511
3512void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3513 uint32_t ws, uint32_t wt)
3514{
3515 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3516 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3517 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3518 compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
3519}
3520
3521#define float16_is_zero(ARG) 0
3522#define float16_is_zero_or_denormal(ARG) 0
3523
3524#define IS_DENORMAL(ARG, BITS) \
3525 (!float ## BITS ## _is_zero(ARG) \
3526 && float ## BITS ## _is_zero_or_denormal(ARG))
3527
3528#define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS) \
3529 do { \
3530 float_status *status = &env->active_tc.msa_fp_status; \
3531 int c; \
3532 \
3533 set_float_exception_flags(0, status); \
3534 DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
3535 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
3536 \
3537 if (get_enabled_exceptions(env, c)) { \
3538 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
3539 } \
3540 } while (0)
3541
3542void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3543 uint32_t ws, uint32_t wt)
3544{
3545 wr_t wx, *pwx = &wx;
3546 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3547 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3548 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3549 uint32_t i;
3550
3551 clear_msacsr_cause(env);
3552
3553 switch (df) {
3554 case DF_WORD:
3555 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3556 MSA_FLOAT_BINOP(pwx->w[i], add, pws->w[i], pwt->w[i], 32);
3557 }
3558 break;
3559 case DF_DOUBLE:
3560 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3561 MSA_FLOAT_BINOP(pwx->d[i], add, pws->d[i], pwt->d[i], 64);
3562 }
3563 break;
3564 default:
3565 assert(0);
3566 }
3567
3568 check_msacsr_cause(env, GETPC());
3569 msa_move_v(pwd, pwx);
3570}
3571
3572void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3573 uint32_t ws, uint32_t wt)
3574{
3575 wr_t wx, *pwx = &wx;
3576 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3577 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3578 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3579 uint32_t i;
3580
3581 clear_msacsr_cause(env);
3582
3583 switch (df) {
3584 case DF_WORD:
3585 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3586 MSA_FLOAT_BINOP(pwx->w[i], sub, pws->w[i], pwt->w[i], 32);
3587 }
3588 break;
3589 case DF_DOUBLE:
3590 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3591 MSA_FLOAT_BINOP(pwx->d[i], sub, pws->d[i], pwt->d[i], 64);
3592 }
3593 break;
3594 default:
3595 assert(0);
3596 }
3597
3598 check_msacsr_cause(env, GETPC());
3599 msa_move_v(pwd, pwx);
3600}
3601
3602void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3603 uint32_t ws, uint32_t wt)
3604{
3605 wr_t wx, *pwx = &wx;
3606 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3607 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3608 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3609 uint32_t i;
3610
3611 clear_msacsr_cause(env);
3612
3613 switch (df) {
3614 case DF_WORD:
3615 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3616 MSA_FLOAT_BINOP(pwx->w[i], mul, pws->w[i], pwt->w[i], 32);
3617 }
3618 break;
3619 case DF_DOUBLE:
3620 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3621 MSA_FLOAT_BINOP(pwx->d[i], mul, pws->d[i], pwt->d[i], 64);
3622 }
3623 break;
3624 default:
3625 assert(0);
3626 }
3627
3628 check_msacsr_cause(env, GETPC());
3629
3630 msa_move_v(pwd, pwx);
3631}
3632
3633void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3634 uint32_t ws, uint32_t wt)
3635{
3636 wr_t wx, *pwx = &wx;
3637 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3638 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3639 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3640 uint32_t i;
3641
3642 clear_msacsr_cause(env);
3643
3644 switch (df) {
3645 case DF_WORD:
3646 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3647 MSA_FLOAT_BINOP(pwx->w[i], div, pws->w[i], pwt->w[i], 32);
3648 }
3649 break;
3650 case DF_DOUBLE:
3651 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3652 MSA_FLOAT_BINOP(pwx->d[i], div, pws->d[i], pwt->d[i], 64);
3653 }
3654 break;
3655 default:
3656 assert(0);
3657 }
3658
3659 check_msacsr_cause(env, GETPC());
3660
3661 msa_move_v(pwd, pwx);
3662}
3663
3664#define MSA_FLOAT_MULADD(DEST, ARG1, ARG2, ARG3, NEGATE, BITS) \
3665 do { \
3666 float_status *status = &env->active_tc.msa_fp_status; \
3667 int c; \
3668 \
3669 set_float_exception_flags(0, status); \
3670 DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status); \
3671 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
3672 \
3673 if (get_enabled_exceptions(env, c)) { \
3674 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
3675 } \
3676 } while (0)
3677
3678void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3679 uint32_t ws, uint32_t wt)
3680{
3681 wr_t wx, *pwx = &wx;
3682 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3683 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3684 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3685 uint32_t i;
3686
3687 clear_msacsr_cause(env);
3688
3689 switch (df) {
3690 case DF_WORD:
3691 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3692 MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
3693 pws->w[i], pwt->w[i], 0, 32);
3694 }
3695 break;
3696 case DF_DOUBLE:
3697 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3698 MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
3699 pws->d[i], pwt->d[i], 0, 64);
3700 }
3701 break;
3702 default:
3703 assert(0);
3704 }
3705
3706 check_msacsr_cause(env, GETPC());
3707
3708 msa_move_v(pwd, pwx);
3709}
3710
3711void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3712 uint32_t ws, uint32_t wt)
3713{
3714 wr_t wx, *pwx = &wx;
3715 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3716 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3717 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3718 uint32_t i;
3719
3720 clear_msacsr_cause(env);
3721
3722 switch (df) {
3723 case DF_WORD:
3724 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3725 MSA_FLOAT_MULADD(pwx->w[i], pwd->w[i],
3726 pws->w[i], pwt->w[i],
3727 float_muladd_negate_product, 32);
3728 }
3729 break;
3730 case DF_DOUBLE:
3731 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3732 MSA_FLOAT_MULADD(pwx->d[i], pwd->d[i],
3733 pws->d[i], pwt->d[i],
3734 float_muladd_negate_product, 64);
3735 }
3736 break;
3737 default:
3738 assert(0);
3739 }
3740
3741 check_msacsr_cause(env, GETPC());
3742
3743 msa_move_v(pwd, pwx);
3744}
3745
3746void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3747 uint32_t ws, uint32_t wt)
3748{
3749 wr_t wx, *pwx = &wx;
3750 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3751 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3752 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3753 uint32_t i;
3754
3755 clear_msacsr_cause(env);
3756
3757 switch (df) {
3758 case DF_WORD:
3759 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3760 MSA_FLOAT_BINOP(pwx->w[i], scalbn, pws->w[i],
3761 pwt->w[i] > 0x200 ? 0x200 :
3762 pwt->w[i] < -0x200 ? -0x200 : pwt->w[i],
3763 32);
3764 }
3765 break;
3766 case DF_DOUBLE:
3767 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3768 MSA_FLOAT_BINOP(pwx->d[i], scalbn, pws->d[i],
3769 pwt->d[i] > 0x1000 ? 0x1000 :
3770 pwt->d[i] < -0x1000 ? -0x1000 : pwt->d[i],
3771 64);
3772 }
3773 break;
3774 default:
3775 assert(0);
3776 }
3777
3778 check_msacsr_cause(env, GETPC());
3779
3780 msa_move_v(pwd, pwx);
3781}
3782
3783#define MSA_FLOAT_UNOP(DEST, OP, ARG, BITS) \
3784 do { \
3785 float_status *status = &env->active_tc.msa_fp_status; \
3786 int c; \
3787 \
3788 set_float_exception_flags(0, status); \
3789 DEST = float ## BITS ## _ ## OP(ARG, status); \
3790 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
3791 \
3792 if (get_enabled_exceptions(env, c)) { \
3793 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
3794 } \
3795 } while (0)
3796
3797void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3798 uint32_t ws, uint32_t wt)
3799{
3800 wr_t wx, *pwx = &wx;
3801 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3802 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3803 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3804 uint32_t i;
3805
3806 clear_msacsr_cause(env);
3807
3808 switch (df) {
3809 case DF_WORD:
3810 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3811
3812
3813
3814
3815
3816 flag ieee = 1;
3817
3818 MSA_FLOAT_BINOP(Lh(pwx, i), from_float32, pws->w[i], ieee, 16);
3819 MSA_FLOAT_BINOP(Rh(pwx, i), from_float32, pwt->w[i], ieee, 16);
3820 }
3821 break;
3822 case DF_DOUBLE:
3823 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3824 MSA_FLOAT_UNOP(Lw(pwx, i), from_float64, pws->d[i], 32);
3825 MSA_FLOAT_UNOP(Rw(pwx, i), from_float64, pwt->d[i], 32);
3826 }
3827 break;
3828 default:
3829 assert(0);
3830 }
3831
3832 check_msacsr_cause(env, GETPC());
3833 msa_move_v(pwd, pwx);
3834}
3835
3836#define MSA_FLOAT_UNOP_XD(DEST, OP, ARG, BITS, XBITS) \
3837 do { \
3838 float_status *status = &env->active_tc.msa_fp_status; \
3839 int c; \
3840 \
3841 set_float_exception_flags(0, status); \
3842 DEST = float ## BITS ## _ ## OP(ARG, status); \
3843 c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
3844 \
3845 if (get_enabled_exceptions(env, c)) { \
3846 DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c; \
3847 } \
3848 } while (0)
3849
3850void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3851 uint32_t ws, uint32_t wt)
3852{
3853 wr_t wx, *pwx = &wx;
3854 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3855 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3856 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3857 uint32_t i;
3858
3859 clear_msacsr_cause(env);
3860
3861 switch (df) {
3862 case DF_WORD:
3863 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
3864 MSA_FLOAT_UNOP_XD(Lh(pwx, i), to_q16, pws->w[i], 32, 16);
3865 MSA_FLOAT_UNOP_XD(Rh(pwx, i), to_q16, pwt->w[i], 32, 16);
3866 }
3867 break;
3868 case DF_DOUBLE:
3869 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
3870 MSA_FLOAT_UNOP_XD(Lw(pwx, i), to_q32, pws->d[i], 64, 32);
3871 MSA_FLOAT_UNOP_XD(Rw(pwx, i), to_q32, pwt->d[i], 64, 32);
3872 }
3873 break;
3874 default:
3875 assert(0);
3876 }
3877
3878 check_msacsr_cause(env, GETPC());
3879
3880 msa_move_v(pwd, pwx);
3881}
3882
3883#define NUMBER_QNAN_PAIR(ARG1, ARG2, BITS, STATUS) \
3884 !float ## BITS ## _is_any_nan(ARG1) \
3885 && float ## BITS ## _is_quiet_nan(ARG2, STATUS)
3886
3887#define MSA_FLOAT_MAXOP(DEST, OP, ARG1, ARG2, BITS) \
3888 do { \
3889 float_status *status = &env->active_tc.msa_fp_status; \
3890 int c; \
3891 \
3892 set_float_exception_flags(0, status); \
3893 DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status); \
3894 c = update_msacsr(env, 0, 0); \
3895 \
3896 if (get_enabled_exceptions(env, c)) { \
3897 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
3898 } \
3899 } while (0)
3900
3901#define FMAXMIN_A(F, G, X, _S, _T, BITS, STATUS) \
3902 do { \
3903 uint## BITS ##_t S = _S, T = _T; \
3904 uint## BITS ##_t as, at, xs, xt, xd; \
3905 if (NUMBER_QNAN_PAIR(S, T, BITS, STATUS)) { \
3906 T = S; \
3907 } \
3908 else if (NUMBER_QNAN_PAIR(T, S, BITS, STATUS)) { \
3909 S = T; \
3910 } \
3911 as = float## BITS ##_abs(S); \
3912 at = float## BITS ##_abs(T); \
3913 MSA_FLOAT_MAXOP(xs, F, S, T, BITS); \
3914 MSA_FLOAT_MAXOP(xt, G, S, T, BITS); \
3915 MSA_FLOAT_MAXOP(xd, F, as, at, BITS); \
3916 X = (as == at || xd == float## BITS ##_abs(xs)) ? xs : xt; \
3917 } while (0)
3918
3919void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3920 uint32_t ws, uint32_t wt)
3921{
3922 float_status *status = &env->active_tc.msa_fp_status;
3923 wr_t wx, *pwx = &wx;
3924 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3925 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
3926 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
3927
3928 clear_msacsr_cause(env);
3929
3930 if (df == DF_WORD) {
3931
3932 if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
3933 MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pws->w[0], 32);
3934 } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
3935 MSA_FLOAT_MAXOP(pwx->w[0], min, pwt->w[0], pwt->w[0], 32);
3936 } else {
3937 MSA_FLOAT_MAXOP(pwx->w[0], min, pws->w[0], pwt->w[0], 32);
3938 }
3939
3940 if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
3941 MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pws->w[1], 32);
3942 } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
3943 MSA_FLOAT_MAXOP(pwx->w[1], min, pwt->w[1], pwt->w[1], 32);
3944 } else {
3945 MSA_FLOAT_MAXOP(pwx->w[1], min, pws->w[1], pwt->w[1], 32);
3946 }
3947
3948 if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
3949 MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pws->w[2], 32);
3950 } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
3951 MSA_FLOAT_MAXOP(pwx->w[2], min, pwt->w[2], pwt->w[2], 32);
3952 } else {
3953 MSA_FLOAT_MAXOP(pwx->w[2], min, pws->w[2], pwt->w[2], 32);
3954 }
3955
3956 if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
3957 MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pws->w[3], 32);
3958 } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
3959 MSA_FLOAT_MAXOP(pwx->w[3], min, pwt->w[3], pwt->w[3], 32);
3960 } else {
3961 MSA_FLOAT_MAXOP(pwx->w[3], min, pws->w[3], pwt->w[3], 32);
3962 }
3963
3964 } else if (df == DF_DOUBLE) {
3965
3966 if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
3967 MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pws->d[0], 64);
3968 } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
3969 MSA_FLOAT_MAXOP(pwx->d[0], min, pwt->d[0], pwt->d[0], 64);
3970 } else {
3971 MSA_FLOAT_MAXOP(pwx->d[0], min, pws->d[0], pwt->d[0], 64);
3972 }
3973
3974 if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
3975 MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pws->d[1], 64);
3976 } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
3977 MSA_FLOAT_MAXOP(pwx->d[1], min, pwt->d[1], pwt->d[1], 64);
3978 } else {
3979 MSA_FLOAT_MAXOP(pwx->d[1], min, pws->d[1], pwt->d[1], 64);
3980 }
3981
3982 } else {
3983
3984 assert(0);
3985
3986 }
3987
3988 check_msacsr_cause(env, GETPC());
3989
3990 msa_move_v(pwd, pwx);
3991}
3992
3993void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
3994 uint32_t ws, uint32_t wt)
3995{
3996 float_status *status = &env->active_tc.msa_fp_status;
3997 wr_t wx, *pwx = &wx;
3998 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
3999 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4000 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4001
4002 clear_msacsr_cause(env);
4003
4004 if (df == DF_WORD) {
4005 FMAXMIN_A(min, max, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
4006 FMAXMIN_A(min, max, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
4007 FMAXMIN_A(min, max, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
4008 FMAXMIN_A(min, max, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
4009 } else if (df == DF_DOUBLE) {
4010 FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
4011 FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
4012 } else {
4013 assert(0);
4014 }
4015
4016 check_msacsr_cause(env, GETPC());
4017
4018 msa_move_v(pwd, pwx);
4019}
4020
4021void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4022 uint32_t ws, uint32_t wt)
4023{
4024 float_status *status = &env->active_tc.msa_fp_status;
4025 wr_t wx, *pwx = &wx;
4026 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4027 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4028 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4029
4030 clear_msacsr_cause(env);
4031
4032 if (df == DF_WORD) {
4033
4034 if (NUMBER_QNAN_PAIR(pws->w[0], pwt->w[0], 32, status)) {
4035 MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pws->w[0], 32);
4036 } else if (NUMBER_QNAN_PAIR(pwt->w[0], pws->w[0], 32, status)) {
4037 MSA_FLOAT_MAXOP(pwx->w[0], max, pwt->w[0], pwt->w[0], 32);
4038 } else {
4039 MSA_FLOAT_MAXOP(pwx->w[0], max, pws->w[0], pwt->w[0], 32);
4040 }
4041
4042 if (NUMBER_QNAN_PAIR(pws->w[1], pwt->w[1], 32, status)) {
4043 MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pws->w[1], 32);
4044 } else if (NUMBER_QNAN_PAIR(pwt->w[1], pws->w[1], 32, status)) {
4045 MSA_FLOAT_MAXOP(pwx->w[1], max, pwt->w[1], pwt->w[1], 32);
4046 } else {
4047 MSA_FLOAT_MAXOP(pwx->w[1], max, pws->w[1], pwt->w[1], 32);
4048 }
4049
4050 if (NUMBER_QNAN_PAIR(pws->w[2], pwt->w[2], 32, status)) {
4051 MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pws->w[2], 32);
4052 } else if (NUMBER_QNAN_PAIR(pwt->w[2], pws->w[2], 32, status)) {
4053 MSA_FLOAT_MAXOP(pwx->w[2], max, pwt->w[2], pwt->w[2], 32);
4054 } else {
4055 MSA_FLOAT_MAXOP(pwx->w[2], max, pws->w[2], pwt->w[2], 32);
4056 }
4057
4058 if (NUMBER_QNAN_PAIR(pws->w[3], pwt->w[3], 32, status)) {
4059 MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pws->w[3], 32);
4060 } else if (NUMBER_QNAN_PAIR(pwt->w[3], pws->w[3], 32, status)) {
4061 MSA_FLOAT_MAXOP(pwx->w[3], max, pwt->w[3], pwt->w[3], 32);
4062 } else {
4063 MSA_FLOAT_MAXOP(pwx->w[3], max, pws->w[3], pwt->w[3], 32);
4064 }
4065
4066 } else if (df == DF_DOUBLE) {
4067
4068 if (NUMBER_QNAN_PAIR(pws->d[0], pwt->d[0], 64, status)) {
4069 MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pws->d[0], 64);
4070 } else if (NUMBER_QNAN_PAIR(pwt->d[0], pws->d[0], 64, status)) {
4071 MSA_FLOAT_MAXOP(pwx->d[0], max, pwt->d[0], pwt->d[0], 64);
4072 } else {
4073 MSA_FLOAT_MAXOP(pwx->d[0], max, pws->d[0], pwt->d[0], 64);
4074 }
4075
4076 if (NUMBER_QNAN_PAIR(pws->d[1], pwt->d[1], 64, status)) {
4077 MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pws->d[1], 64);
4078 } else if (NUMBER_QNAN_PAIR(pwt->d[1], pws->d[1], 64, status)) {
4079 MSA_FLOAT_MAXOP(pwx->d[1], max, pwt->d[1], pwt->d[1], 64);
4080 } else {
4081 MSA_FLOAT_MAXOP(pwx->d[1], max, pws->d[1], pwt->d[1], 64);
4082 }
4083
4084 } else {
4085
4086 assert(0);
4087
4088 }
4089
4090 check_msacsr_cause(env, GETPC());
4091
4092 msa_move_v(pwd, pwx);
4093}
4094
4095void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4096 uint32_t ws, uint32_t wt)
4097{
4098 float_status *status = &env->active_tc.msa_fp_status;
4099 wr_t wx, *pwx = &wx;
4100 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4101 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4102 wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
4103
4104 clear_msacsr_cause(env);
4105
4106 if (df == DF_WORD) {
4107 FMAXMIN_A(max, min, pwx->w[0], pws->w[0], pwt->w[0], 32, status);
4108 FMAXMIN_A(max, min, pwx->w[1], pws->w[1], pwt->w[1], 32, status);
4109 FMAXMIN_A(max, min, pwx->w[2], pws->w[2], pwt->w[2], 32, status);
4110 FMAXMIN_A(max, min, pwx->w[3], pws->w[3], pwt->w[3], 32, status);
4111 } else if (df == DF_DOUBLE) {
4112 FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
4113 FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
4114 } else {
4115 assert(0);
4116 }
4117
4118 check_msacsr_cause(env, GETPC());
4119
4120 msa_move_v(pwd, pwx);
4121}
4122
4123void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
4124 uint32_t wd, uint32_t ws)
4125{
4126 float_status *status = &env->active_tc.msa_fp_status;
4127
4128 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4129 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4130 if (df == DF_WORD) {
4131 pwd->w[0] = float_class_s(pws->w[0], status);
4132 pwd->w[1] = float_class_s(pws->w[1], status);
4133 pwd->w[2] = float_class_s(pws->w[2], status);
4134 pwd->w[3] = float_class_s(pws->w[3], status);
4135 } else if (df == DF_DOUBLE) {
4136 pwd->d[0] = float_class_d(pws->d[0], status);
4137 pwd->d[1] = float_class_d(pws->d[1], status);
4138 } else {
4139 assert(0);
4140 }
4141}
4142
4143#define MSA_FLOAT_UNOP0(DEST, OP, ARG, BITS) \
4144 do { \
4145 float_status *status = &env->active_tc.msa_fp_status; \
4146 int c; \
4147 \
4148 set_float_exception_flags(0, status); \
4149 DEST = float ## BITS ## _ ## OP(ARG, status); \
4150 c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0); \
4151 \
4152 if (get_enabled_exceptions(env, c)) { \
4153 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
4154 } else if (float ## BITS ## _is_any_nan(ARG)) { \
4155 DEST = 0; \
4156 } \
4157 } while (0)
4158
4159void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4160 uint32_t ws)
4161{
4162 wr_t wx, *pwx = &wx;
4163 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4164 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4165 uint32_t i;
4166
4167 clear_msacsr_cause(env);
4168
4169 switch (df) {
4170 case DF_WORD:
4171 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4172 MSA_FLOAT_UNOP0(pwx->w[i], to_int32_round_to_zero, pws->w[i], 32);
4173 }
4174 break;
4175 case DF_DOUBLE:
4176 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4177 MSA_FLOAT_UNOP0(pwx->d[i], to_int64_round_to_zero, pws->d[i], 64);
4178 }
4179 break;
4180 default:
4181 assert(0);
4182 }
4183
4184 check_msacsr_cause(env, GETPC());
4185
4186 msa_move_v(pwd, pwx);
4187}
4188
4189void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4190 uint32_t ws)
4191{
4192 wr_t wx, *pwx = &wx;
4193 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4194 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4195 uint32_t i;
4196
4197 clear_msacsr_cause(env);
4198
4199 switch (df) {
4200 case DF_WORD:
4201 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4202 MSA_FLOAT_UNOP0(pwx->w[i], to_uint32_round_to_zero, pws->w[i], 32);
4203 }
4204 break;
4205 case DF_DOUBLE:
4206 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4207 MSA_FLOAT_UNOP0(pwx->d[i], to_uint64_round_to_zero, pws->d[i], 64);
4208 }
4209 break;
4210 default:
4211 assert(0);
4212 }
4213
4214 check_msacsr_cause(env, GETPC());
4215
4216 msa_move_v(pwd, pwx);
4217}
4218
4219void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4220 uint32_t ws)
4221{
4222 wr_t wx, *pwx = &wx;
4223 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4224 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4225 uint32_t i;
4226
4227 clear_msacsr_cause(env);
4228
4229 switch (df) {
4230 case DF_WORD:
4231 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4232 MSA_FLOAT_UNOP(pwx->w[i], sqrt, pws->w[i], 32);
4233 }
4234 break;
4235 case DF_DOUBLE:
4236 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4237 MSA_FLOAT_UNOP(pwx->d[i], sqrt, pws->d[i], 64);
4238 }
4239 break;
4240 default:
4241 assert(0);
4242 }
4243
4244 check_msacsr_cause(env, GETPC());
4245
4246 msa_move_v(pwd, pwx);
4247}
4248
4249#define MSA_FLOAT_RECIPROCAL(DEST, ARG, BITS) \
4250 do { \
4251 float_status *status = &env->active_tc.msa_fp_status; \
4252 int c; \
4253 \
4254 set_float_exception_flags(0, status); \
4255 DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status); \
4256 c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) || \
4257 float ## BITS ## _is_quiet_nan(DEST, status) ? \
4258 0 : RECIPROCAL_INEXACT, \
4259 IS_DENORMAL(DEST, BITS)); \
4260 \
4261 if (get_enabled_exceptions(env, c)) { \
4262 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
4263 } \
4264 } while (0)
4265
4266void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4267 uint32_t ws)
4268{
4269 wr_t wx, *pwx = &wx;
4270 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4271 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4272 uint32_t i;
4273
4274 clear_msacsr_cause(env);
4275
4276 switch (df) {
4277 case DF_WORD:
4278 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4279 MSA_FLOAT_RECIPROCAL(pwx->w[i], float32_sqrt(pws->w[i],
4280 &env->active_tc.msa_fp_status), 32);
4281 }
4282 break;
4283 case DF_DOUBLE:
4284 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4285 MSA_FLOAT_RECIPROCAL(pwx->d[i], float64_sqrt(pws->d[i],
4286 &env->active_tc.msa_fp_status), 64);
4287 }
4288 break;
4289 default:
4290 assert(0);
4291 }
4292
4293 check_msacsr_cause(env, GETPC());
4294
4295 msa_move_v(pwd, pwx);
4296}
4297
4298void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4299 uint32_t ws)
4300{
4301 wr_t wx, *pwx = &wx;
4302 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4303 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4304 uint32_t i;
4305
4306 clear_msacsr_cause(env);
4307
4308 switch (df) {
4309 case DF_WORD:
4310 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4311 MSA_FLOAT_RECIPROCAL(pwx->w[i], pws->w[i], 32);
4312 }
4313 break;
4314 case DF_DOUBLE:
4315 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4316 MSA_FLOAT_RECIPROCAL(pwx->d[i], pws->d[i], 64);
4317 }
4318 break;
4319 default:
4320 assert(0);
4321 }
4322
4323 check_msacsr_cause(env, GETPC());
4324
4325 msa_move_v(pwd, pwx);
4326}
4327
4328void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4329 uint32_t ws)
4330{
4331 wr_t wx, *pwx = &wx;
4332 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4333 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4334 uint32_t i;
4335
4336 clear_msacsr_cause(env);
4337
4338 switch (df) {
4339 case DF_WORD:
4340 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4341 MSA_FLOAT_UNOP(pwx->w[i], round_to_int, pws->w[i], 32);
4342 }
4343 break;
4344 case DF_DOUBLE:
4345 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4346 MSA_FLOAT_UNOP(pwx->d[i], round_to_int, pws->d[i], 64);
4347 }
4348 break;
4349 default:
4350 assert(0);
4351 }
4352
4353 check_msacsr_cause(env, GETPC());
4354
4355 msa_move_v(pwd, pwx);
4356}
4357
4358#define MSA_FLOAT_LOGB(DEST, ARG, BITS) \
4359 do { \
4360 float_status *status = &env->active_tc.msa_fp_status; \
4361 int c; \
4362 \
4363 set_float_exception_flags(0, status); \
4364 set_float_rounding_mode(float_round_down, status); \
4365 DEST = float ## BITS ## _ ## log2(ARG, status); \
4366 DEST = float ## BITS ## _ ## round_to_int(DEST, status); \
4367 set_float_rounding_mode(ieee_rm[(env->active_tc.msacsr & \
4368 MSACSR_RM_MASK) >> MSACSR_RM], \
4369 status); \
4370 \
4371 set_float_exception_flags(get_float_exception_flags(status) & \
4372 (~float_flag_inexact), \
4373 status); \
4374 \
4375 c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS)); \
4376 \
4377 if (get_enabled_exceptions(env, c)) { \
4378 DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c; \
4379 } \
4380 } while (0)
4381
4382void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4383 uint32_t ws)
4384{
4385 wr_t wx, *pwx = &wx;
4386 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4387 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4388 uint32_t i;
4389
4390 clear_msacsr_cause(env);
4391
4392 switch (df) {
4393 case DF_WORD:
4394 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4395 MSA_FLOAT_LOGB(pwx->w[i], pws->w[i], 32);
4396 }
4397 break;
4398 case DF_DOUBLE:
4399 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4400 MSA_FLOAT_LOGB(pwx->d[i], pws->d[i], 64);
4401 }
4402 break;
4403 default:
4404 assert(0);
4405 }
4406
4407 check_msacsr_cause(env, GETPC());
4408
4409 msa_move_v(pwd, pwx);
4410}
4411
4412void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4413 uint32_t ws)
4414{
4415 wr_t wx, *pwx = &wx;
4416 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4417 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4418 uint32_t i;
4419
4420 clear_msacsr_cause(env);
4421
4422 switch (df) {
4423 case DF_WORD:
4424 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4425
4426
4427
4428
4429
4430 flag ieee = 1;
4431
4432 MSA_FLOAT_BINOP(pwx->w[i], from_float16, Lh(pws, i), ieee, 32);
4433 }
4434 break;
4435 case DF_DOUBLE:
4436 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4437 MSA_FLOAT_UNOP(pwx->d[i], from_float32, Lw(pws, i), 64);
4438 }
4439 break;
4440 default:
4441 assert(0);
4442 }
4443
4444 check_msacsr_cause(env, GETPC());
4445 msa_move_v(pwd, pwx);
4446}
4447
4448void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4449 uint32_t ws)
4450{
4451 wr_t wx, *pwx = &wx;
4452 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4453 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4454 uint32_t i;
4455
4456 clear_msacsr_cause(env);
4457
4458 switch (df) {
4459 case DF_WORD:
4460 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4461
4462
4463
4464
4465
4466 flag ieee = 1;
4467
4468 MSA_FLOAT_BINOP(pwx->w[i], from_float16, Rh(pws, i), ieee, 32);
4469 }
4470 break;
4471 case DF_DOUBLE:
4472 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4473 MSA_FLOAT_UNOP(pwx->d[i], from_float32, Rw(pws, i), 64);
4474 }
4475 break;
4476 default:
4477 assert(0);
4478 }
4479
4480 check_msacsr_cause(env, GETPC());
4481 msa_move_v(pwd, pwx);
4482}
4483
4484void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4485 uint32_t ws)
4486{
4487 wr_t wx, *pwx = &wx;
4488 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4489 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4490 uint32_t i;
4491
4492 switch (df) {
4493 case DF_WORD:
4494 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4495 MSA_FLOAT_UNOP(pwx->w[i], from_q16, Lh(pws, i), 32);
4496 }
4497 break;
4498 case DF_DOUBLE:
4499 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4500 MSA_FLOAT_UNOP(pwx->d[i], from_q32, Lw(pws, i), 64);
4501 }
4502 break;
4503 default:
4504 assert(0);
4505 }
4506
4507 msa_move_v(pwd, pwx);
4508}
4509
4510void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4511 uint32_t ws)
4512{
4513 wr_t wx, *pwx = &wx;
4514 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4515 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4516 uint32_t i;
4517
4518 switch (df) {
4519 case DF_WORD:
4520 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4521 MSA_FLOAT_UNOP(pwx->w[i], from_q16, Rh(pws, i), 32);
4522 }
4523 break;
4524 case DF_DOUBLE:
4525 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4526 MSA_FLOAT_UNOP(pwx->d[i], from_q32, Rw(pws, i), 64);
4527 }
4528 break;
4529 default:
4530 assert(0);
4531 }
4532
4533 msa_move_v(pwd, pwx);
4534}
4535
4536void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4537 uint32_t ws)
4538{
4539 wr_t wx, *pwx = &wx;
4540 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4541 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4542 uint32_t i;
4543
4544 clear_msacsr_cause(env);
4545
4546 switch (df) {
4547 case DF_WORD:
4548 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4549 MSA_FLOAT_UNOP0(pwx->w[i], to_int32, pws->w[i], 32);
4550 }
4551 break;
4552 case DF_DOUBLE:
4553 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4554 MSA_FLOAT_UNOP0(pwx->d[i], to_int64, pws->d[i], 64);
4555 }
4556 break;
4557 default:
4558 assert(0);
4559 }
4560
4561 check_msacsr_cause(env, GETPC());
4562
4563 msa_move_v(pwd, pwx);
4564}
4565
4566void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4567 uint32_t ws)
4568{
4569 wr_t wx, *pwx = &wx;
4570 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4571 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4572 uint32_t i;
4573
4574 clear_msacsr_cause(env);
4575
4576 switch (df) {
4577 case DF_WORD:
4578 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4579 MSA_FLOAT_UNOP0(pwx->w[i], to_uint32, pws->w[i], 32);
4580 }
4581 break;
4582 case DF_DOUBLE:
4583 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4584 MSA_FLOAT_UNOP0(pwx->d[i], to_uint64, pws->d[i], 64);
4585 }
4586 break;
4587 default:
4588 assert(0);
4589 }
4590
4591 check_msacsr_cause(env, GETPC());
4592
4593 msa_move_v(pwd, pwx);
4594}
4595
4596#define float32_from_int32 int32_to_float32
4597#define float32_from_uint32 uint32_to_float32
4598
4599#define float64_from_int64 int64_to_float64
4600#define float64_from_uint64 uint64_to_float64
4601
4602void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4603 uint32_t ws)
4604{
4605 wr_t wx, *pwx = &wx;
4606 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4607 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4608 uint32_t i;
4609
4610 clear_msacsr_cause(env);
4611
4612 switch (df) {
4613 case DF_WORD:
4614 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4615 MSA_FLOAT_UNOP(pwx->w[i], from_int32, pws->w[i], 32);
4616 }
4617 break;
4618 case DF_DOUBLE:
4619 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4620 MSA_FLOAT_UNOP(pwx->d[i], from_int64, pws->d[i], 64);
4621 }
4622 break;
4623 default:
4624 assert(0);
4625 }
4626
4627 check_msacsr_cause(env, GETPC());
4628
4629 msa_move_v(pwd, pwx);
4630}
4631
4632void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
4633 uint32_t ws)
4634{
4635 wr_t wx, *pwx = &wx;
4636 wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
4637 wr_t *pws = &(env->active_fpu.fpr[ws].wr);
4638 uint32_t i;
4639
4640 clear_msacsr_cause(env);
4641
4642 switch (df) {
4643 case DF_WORD:
4644 for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {
4645 MSA_FLOAT_UNOP(pwx->w[i], from_uint32, pws->w[i], 32);
4646 }
4647 break;
4648 case DF_DOUBLE:
4649 for (i = 0; i < DF_ELEMENTS(DF_DOUBLE); i++) {
4650 MSA_FLOAT_UNOP(pwx->d[i], from_uint64, pws->d[i], 64);
4651 }
4652 break;
4653 default:
4654 assert(0);
4655 }
4656
4657 check_msacsr_cause(env, GETPC());
4658
4659 msa_move_v(pwd, pwx);
4660}
4661