1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "qemu/osdep.h"
19#include "tcg/tcg-op.h"
20#include "exec/helper-gen.h"
21#include "translate.h"
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
357enum {
358 OPC_MXU__POOL00 = 0x03,
359 OPC_MXU_D16MUL = 0x08,
360 OPC_MXU_D16MAC = 0x0A,
361 OPC_MXU__POOL04 = 0x10,
362 OPC_MXU_S8LDD = 0x22,
363 OPC_MXU__POOL16 = 0x27,
364 OPC_MXU_S32M2I = 0x2E,
365 OPC_MXU_S32I2M = 0x2F,
366 OPC_MXU__POOL19 = 0x38,
367};
368
369
370
371
372
373enum {
374 OPC_MXU_S32MAX = 0x00,
375 OPC_MXU_S32MIN = 0x01,
376 OPC_MXU_D16MAX = 0x02,
377 OPC_MXU_D16MIN = 0x03,
378 OPC_MXU_Q8MAX = 0x04,
379 OPC_MXU_Q8MIN = 0x05,
380};
381
382
383
384
385enum {
386 OPC_MXU_S32LDD = 0x00,
387 OPC_MXU_S32LDDR = 0x01,
388};
389
390
391
392
393enum {
394 OPC_MXU_S32ALNI = 0x02,
395 OPC_MXU_S32NOR = 0x04,
396 OPC_MXU_S32AND = 0x05,
397 OPC_MXU_S32OR = 0x06,
398 OPC_MXU_S32XOR = 0x07,
399};
400
401
402
403
404enum {
405 OPC_MXU_Q8MUL = 0x00,
406 OPC_MXU_Q8MULSU = 0x01,
407};
408
409
410#define MXU_APTN1_A 0
411#define MXU_APTN1_S 1
412
413
414#define MXU_APTN2_AA 0
415#define MXU_APTN2_AS 1
416#define MXU_APTN2_SA 2
417#define MXU_APTN2_SS 3
418
419
420#define MXU_EPTN2_AA 0
421#define MXU_EPTN2_AS 1
422#define MXU_EPTN2_SA 2
423#define MXU_EPTN2_SS 3
424
425
426#define MXU_OPTN2_PTN0 0
427#define MXU_OPTN2_PTN1 1
428#define MXU_OPTN2_PTN2 2
429#define MXU_OPTN2_PTN3 3
430
431#define MXU_OPTN2_WW 0
432#define MXU_OPTN2_LW 1
433#define MXU_OPTN2_HW 2
434#define MXU_OPTN2_XW 3
435
436
437#define MXU_OPTN3_PTN0 0
438#define MXU_OPTN3_PTN1 1
439#define MXU_OPTN3_PTN2 2
440#define MXU_OPTN3_PTN3 3
441#define MXU_OPTN3_PTN4 4
442#define MXU_OPTN3_PTN5 5
443#define MXU_OPTN3_PTN6 6
444#define MXU_OPTN3_PTN7 7
445
446
447static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
448static TCGv mxu_CR;
449
450static const char mxuregnames[][4] = {
451 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
452 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "XCR",
453};
454
455void mxu_translate_init(void)
456{
457 for (unsigned i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
458 mxu_gpr[i] = tcg_global_mem_new(cpu_env,
459 offsetof(CPUMIPSState, active_tc.mxu_gpr[i]),
460 mxuregnames[i]);
461 }
462
463 mxu_CR = tcg_global_mem_new(cpu_env,
464 offsetof(CPUMIPSState, active_tc.mxu_cr),
465 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
466}
467
468
469static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
470{
471 if (reg == 0) {
472 tcg_gen_movi_tl(t, 0);
473 } else if (reg <= 15) {
474 tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
475 }
476}
477
478static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
479{
480 if (reg > 0 && reg <= 15) {
481 tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
482 }
483}
484
485
486static inline void gen_load_mxu_cr(TCGv t)
487{
488 tcg_gen_mov_tl(t, mxu_CR);
489}
490
491static inline void gen_store_mxu_cr(TCGv t)
492{
493
494 tcg_gen_mov_tl(mxu_CR, t);
495}
496
497
498
499
500static void gen_mxu_s32i2m(DisasContext *ctx)
501{
502 TCGv t0;
503 uint32_t XRa, Rb;
504
505 t0 = tcg_temp_new();
506
507 XRa = extract32(ctx->opcode, 6, 5);
508 Rb = extract32(ctx->opcode, 16, 5);
509
510 gen_load_gpr(t0, Rb);
511 if (XRa <= 15) {
512 gen_store_mxu_gpr(t0, XRa);
513 } else if (XRa == 16) {
514 gen_store_mxu_cr(t0);
515 }
516}
517
518
519
520
521static void gen_mxu_s32m2i(DisasContext *ctx)
522{
523 TCGv t0;
524 uint32_t XRa, Rb;
525
526 t0 = tcg_temp_new();
527
528 XRa = extract32(ctx->opcode, 6, 5);
529 Rb = extract32(ctx->opcode, 16, 5);
530
531 if (XRa <= 15) {
532 gen_load_mxu_gpr(t0, XRa);
533 } else if (XRa == 16) {
534 gen_load_mxu_cr(t0);
535 }
536
537 gen_store_gpr(t0, Rb);
538}
539
540
541
542
543static void gen_mxu_s8ldd(DisasContext *ctx)
544{
545 TCGv t0, t1;
546 uint32_t XRa, Rb, s8, optn3;
547
548 t0 = tcg_temp_new();
549 t1 = tcg_temp_new();
550
551 XRa = extract32(ctx->opcode, 6, 4);
552 s8 = extract32(ctx->opcode, 10, 8);
553 optn3 = extract32(ctx->opcode, 18, 3);
554 Rb = extract32(ctx->opcode, 21, 5);
555
556 gen_load_gpr(t0, Rb);
557 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
558
559 switch (optn3) {
560
561 case MXU_OPTN3_PTN0:
562 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
563 gen_load_mxu_gpr(t0, XRa);
564 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
565 break;
566
567 case MXU_OPTN3_PTN1:
568 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
569 gen_load_mxu_gpr(t0, XRa);
570 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
571 break;
572
573 case MXU_OPTN3_PTN2:
574 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
575 gen_load_mxu_gpr(t0, XRa);
576 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
577 break;
578
579 case MXU_OPTN3_PTN3:
580 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
581 gen_load_mxu_gpr(t0, XRa);
582 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
583 break;
584
585 case MXU_OPTN3_PTN4:
586 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
587 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
588 break;
589
590 case MXU_OPTN3_PTN5:
591 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
592 tcg_gen_shli_tl(t1, t1, 8);
593 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
594 break;
595
596 case MXU_OPTN3_PTN6:
597 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
598 tcg_gen_mov_tl(t0, t1);
599 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
600 tcg_gen_shli_tl(t1, t1, 16);
601 tcg_gen_or_tl(t0, t0, t1);
602 break;
603
604 case MXU_OPTN3_PTN7:
605 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
606 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
607 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
608 break;
609 }
610
611 gen_store_mxu_gpr(t0, XRa);
612}
613
614
615
616
617static void gen_mxu_d16mul(DisasContext *ctx)
618{
619 TCGv t0, t1, t2, t3;
620 uint32_t XRa, XRb, XRc, XRd, optn2;
621
622 t0 = tcg_temp_new();
623 t1 = tcg_temp_new();
624 t2 = tcg_temp_new();
625 t3 = tcg_temp_new();
626
627 XRa = extract32(ctx->opcode, 6, 4);
628 XRb = extract32(ctx->opcode, 10, 4);
629 XRc = extract32(ctx->opcode, 14, 4);
630 XRd = extract32(ctx->opcode, 18, 4);
631 optn2 = extract32(ctx->opcode, 22, 2);
632
633 gen_load_mxu_gpr(t1, XRb);
634 tcg_gen_sextract_tl(t0, t1, 0, 16);
635 tcg_gen_sextract_tl(t1, t1, 16, 16);
636 gen_load_mxu_gpr(t3, XRc);
637 tcg_gen_sextract_tl(t2, t3, 0, 16);
638 tcg_gen_sextract_tl(t3, t3, 16, 16);
639
640 switch (optn2) {
641 case MXU_OPTN2_WW:
642 tcg_gen_mul_tl(t3, t1, t3);
643 tcg_gen_mul_tl(t2, t0, t2);
644 break;
645 case MXU_OPTN2_LW:
646 tcg_gen_mul_tl(t3, t0, t3);
647 tcg_gen_mul_tl(t2, t0, t2);
648 break;
649 case MXU_OPTN2_HW:
650 tcg_gen_mul_tl(t3, t1, t3);
651 tcg_gen_mul_tl(t2, t1, t2);
652 break;
653 case MXU_OPTN2_XW:
654 tcg_gen_mul_tl(t3, t0, t3);
655 tcg_gen_mul_tl(t2, t1, t2);
656 break;
657 }
658 gen_store_mxu_gpr(t3, XRa);
659 gen_store_mxu_gpr(t2, XRd);
660}
661
662
663
664
665
666static void gen_mxu_d16mac(DisasContext *ctx)
667{
668 TCGv t0, t1, t2, t3;
669 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
670
671 t0 = tcg_temp_new();
672 t1 = tcg_temp_new();
673 t2 = tcg_temp_new();
674 t3 = tcg_temp_new();
675
676 XRa = extract32(ctx->opcode, 6, 4);
677 XRb = extract32(ctx->opcode, 10, 4);
678 XRc = extract32(ctx->opcode, 14, 4);
679 XRd = extract32(ctx->opcode, 18, 4);
680 optn2 = extract32(ctx->opcode, 22, 2);
681 aptn2 = extract32(ctx->opcode, 24, 2);
682
683 gen_load_mxu_gpr(t1, XRb);
684 tcg_gen_sextract_tl(t0, t1, 0, 16);
685 tcg_gen_sextract_tl(t1, t1, 16, 16);
686
687 gen_load_mxu_gpr(t3, XRc);
688 tcg_gen_sextract_tl(t2, t3, 0, 16);
689 tcg_gen_sextract_tl(t3, t3, 16, 16);
690
691 switch (optn2) {
692 case MXU_OPTN2_WW:
693 tcg_gen_mul_tl(t3, t1, t3);
694 tcg_gen_mul_tl(t2, t0, t2);
695 break;
696 case MXU_OPTN2_LW:
697 tcg_gen_mul_tl(t3, t0, t3);
698 tcg_gen_mul_tl(t2, t0, t2);
699 break;
700 case MXU_OPTN2_HW:
701 tcg_gen_mul_tl(t3, t1, t3);
702 tcg_gen_mul_tl(t2, t1, t2);
703 break;
704 case MXU_OPTN2_XW:
705 tcg_gen_mul_tl(t3, t0, t3);
706 tcg_gen_mul_tl(t2, t1, t2);
707 break;
708 }
709 gen_load_mxu_gpr(t0, XRa);
710 gen_load_mxu_gpr(t1, XRd);
711
712 switch (aptn2) {
713 case MXU_APTN2_AA:
714 tcg_gen_add_tl(t3, t0, t3);
715 tcg_gen_add_tl(t2, t1, t2);
716 break;
717 case MXU_APTN2_AS:
718 tcg_gen_add_tl(t3, t0, t3);
719 tcg_gen_sub_tl(t2, t1, t2);
720 break;
721 case MXU_APTN2_SA:
722 tcg_gen_sub_tl(t3, t0, t3);
723 tcg_gen_add_tl(t2, t1, t2);
724 break;
725 case MXU_APTN2_SS:
726 tcg_gen_sub_tl(t3, t0, t3);
727 tcg_gen_sub_tl(t2, t1, t2);
728 break;
729 }
730 gen_store_mxu_gpr(t3, XRa);
731 gen_store_mxu_gpr(t2, XRd);
732}
733
734
735
736
737
738static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
739{
740 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
741 uint32_t XRa, XRb, XRc, XRd, sel;
742
743 t0 = tcg_temp_new();
744 t1 = tcg_temp_new();
745 t2 = tcg_temp_new();
746 t3 = tcg_temp_new();
747 t4 = tcg_temp_new();
748 t5 = tcg_temp_new();
749 t6 = tcg_temp_new();
750 t7 = tcg_temp_new();
751
752 XRa = extract32(ctx->opcode, 6, 4);
753 XRb = extract32(ctx->opcode, 10, 4);
754 XRc = extract32(ctx->opcode, 14, 4);
755 XRd = extract32(ctx->opcode, 18, 4);
756 sel = extract32(ctx->opcode, 22, 2);
757
758 gen_load_mxu_gpr(t3, XRb);
759 gen_load_mxu_gpr(t7, XRc);
760
761 if (sel == 0x2) {
762
763 tcg_gen_ext8s_tl(t0, t3);
764 tcg_gen_shri_tl(t3, t3, 8);
765 tcg_gen_ext8s_tl(t1, t3);
766 tcg_gen_shri_tl(t3, t3, 8);
767 tcg_gen_ext8s_tl(t2, t3);
768 tcg_gen_shri_tl(t3, t3, 8);
769 tcg_gen_ext8s_tl(t3, t3);
770 } else {
771
772 tcg_gen_ext8u_tl(t0, t3);
773 tcg_gen_shri_tl(t3, t3, 8);
774 tcg_gen_ext8u_tl(t1, t3);
775 tcg_gen_shri_tl(t3, t3, 8);
776 tcg_gen_ext8u_tl(t2, t3);
777 tcg_gen_shri_tl(t3, t3, 8);
778 tcg_gen_ext8u_tl(t3, t3);
779 }
780
781 tcg_gen_ext8u_tl(t4, t7);
782 tcg_gen_shri_tl(t7, t7, 8);
783 tcg_gen_ext8u_tl(t5, t7);
784 tcg_gen_shri_tl(t7, t7, 8);
785 tcg_gen_ext8u_tl(t6, t7);
786 tcg_gen_shri_tl(t7, t7, 8);
787 tcg_gen_ext8u_tl(t7, t7);
788
789 tcg_gen_mul_tl(t0, t0, t4);
790 tcg_gen_mul_tl(t1, t1, t5);
791 tcg_gen_mul_tl(t2, t2, t6);
792 tcg_gen_mul_tl(t3, t3, t7);
793
794 tcg_gen_andi_tl(t0, t0, 0xFFFF);
795 tcg_gen_andi_tl(t1, t1, 0xFFFF);
796 tcg_gen_andi_tl(t2, t2, 0xFFFF);
797 tcg_gen_andi_tl(t3, t3, 0xFFFF);
798
799 tcg_gen_shli_tl(t1, t1, 16);
800 tcg_gen_shli_tl(t3, t3, 16);
801
802 tcg_gen_or_tl(t0, t0, t1);
803 tcg_gen_or_tl(t1, t2, t3);
804
805 gen_store_mxu_gpr(t0, XRd);
806 gen_store_mxu_gpr(t1, XRa);
807}
808
809
810
811
812
813static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
814{
815 TCGv t0, t1;
816 uint32_t XRa, Rb, s12, sel;
817
818 t0 = tcg_temp_new();
819 t1 = tcg_temp_new();
820
821 XRa = extract32(ctx->opcode, 6, 4);
822 s12 = extract32(ctx->opcode, 10, 10);
823 sel = extract32(ctx->opcode, 20, 1);
824 Rb = extract32(ctx->opcode, 21, 5);
825
826 gen_load_gpr(t0, Rb);
827
828 tcg_gen_movi_tl(t1, s12);
829 tcg_gen_shli_tl(t1, t1, 2);
830 if (s12 & 0x200) {
831 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
832 }
833 tcg_gen_add_tl(t1, t0, t1);
834 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_TESL ^ (sel * MO_BSWAP));
835
836 gen_store_mxu_gpr(t1, XRa);
837}
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852static void gen_mxu_S32NOR(DisasContext *ctx)
853{
854 uint32_t pad, XRc, XRb, XRa;
855
856 pad = extract32(ctx->opcode, 21, 5);
857 XRc = extract32(ctx->opcode, 14, 4);
858 XRb = extract32(ctx->opcode, 10, 4);
859 XRa = extract32(ctx->opcode, 6, 4);
860
861 if (unlikely(pad != 0)) {
862
863 } else if (unlikely(XRa == 0)) {
864
865 } else if (unlikely((XRb == 0) && (XRc == 0))) {
866
867 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
868 } else if (unlikely(XRb == 0)) {
869
870 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
871 } else if (unlikely(XRc == 0)) {
872
873 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
874 } else if (unlikely(XRb == XRc)) {
875
876 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
877 } else {
878
879 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
880 }
881}
882
883
884
885
886
887
888static void gen_mxu_S32AND(DisasContext *ctx)
889{
890 uint32_t pad, XRc, XRb, XRa;
891
892 pad = extract32(ctx->opcode, 21, 5);
893 XRc = extract32(ctx->opcode, 14, 4);
894 XRb = extract32(ctx->opcode, 10, 4);
895 XRa = extract32(ctx->opcode, 6, 4);
896
897 if (unlikely(pad != 0)) {
898
899 } else if (unlikely(XRa == 0)) {
900
901 } else if (unlikely((XRb == 0) || (XRc == 0))) {
902
903 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
904 } else if (unlikely(XRb == XRc)) {
905
906 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
907 } else {
908
909 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
910 }
911}
912
913
914
915
916
917
918static void gen_mxu_S32OR(DisasContext *ctx)
919{
920 uint32_t pad, XRc, XRb, XRa;
921
922 pad = extract32(ctx->opcode, 21, 5);
923 XRc = extract32(ctx->opcode, 14, 4);
924 XRb = extract32(ctx->opcode, 10, 4);
925 XRa = extract32(ctx->opcode, 6, 4);
926
927 if (unlikely(pad != 0)) {
928
929 } else if (unlikely(XRa == 0)) {
930
931 } else if (unlikely((XRb == 0) && (XRc == 0))) {
932
933 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
934 } else if (unlikely(XRb == 0)) {
935
936 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
937 } else if (unlikely(XRc == 0)) {
938
939 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
940 } else if (unlikely(XRb == XRc)) {
941
942 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
943 } else {
944
945 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
946 }
947}
948
949
950
951
952
953
954static void gen_mxu_S32XOR(DisasContext *ctx)
955{
956 uint32_t pad, XRc, XRb, XRa;
957
958 pad = extract32(ctx->opcode, 21, 5);
959 XRc = extract32(ctx->opcode, 14, 4);
960 XRb = extract32(ctx->opcode, 10, 4);
961 XRa = extract32(ctx->opcode, 6, 4);
962
963 if (unlikely(pad != 0)) {
964
965 } else if (unlikely(XRa == 0)) {
966
967 } else if (unlikely((XRb == 0) && (XRc == 0))) {
968
969 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
970 } else if (unlikely(XRb == 0)) {
971
972 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
973 } else if (unlikely(XRc == 0)) {
974
975 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
976 } else if (unlikely(XRb == XRc)) {
977
978 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
979 } else {
980
981 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
982 }
983}
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
1004{
1005 uint32_t pad, opc, XRc, XRb, XRa;
1006
1007 pad = extract32(ctx->opcode, 21, 5);
1008 opc = extract32(ctx->opcode, 18, 3);
1009 XRc = extract32(ctx->opcode, 14, 4);
1010 XRb = extract32(ctx->opcode, 10, 4);
1011 XRa = extract32(ctx->opcode, 6, 4);
1012
1013 if (unlikely(pad != 0)) {
1014
1015 } else if (unlikely(XRa == 0)) {
1016
1017 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1018
1019 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1020 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1021
1022 uint32_t XRx = XRb ? XRb : XRc;
1023
1024 if (opc == OPC_MXU_S32MAX) {
1025 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1026 } else {
1027 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1028 }
1029 } else if (unlikely(XRb == XRc)) {
1030
1031 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1032 } else {
1033
1034 if (opc == OPC_MXU_S32MAX) {
1035 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1036 mxu_gpr[XRc - 1]);
1037 } else {
1038 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1039 mxu_gpr[XRc - 1]);
1040 }
1041 }
1042}
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
1054{
1055 uint32_t pad, opc, XRc, XRb, XRa;
1056
1057 pad = extract32(ctx->opcode, 21, 5);
1058 opc = extract32(ctx->opcode, 18, 3);
1059 XRc = extract32(ctx->opcode, 14, 4);
1060 XRb = extract32(ctx->opcode, 10, 4);
1061 XRa = extract32(ctx->opcode, 6, 4);
1062
1063 if (unlikely(pad != 0)) {
1064
1065 } else if (unlikely(XRa == 0)) {
1066
1067 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1068
1069 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1070 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1071
1072 uint32_t XRx = XRb ? XRb : XRc;
1073
1074 TCGv_i32 t0 = tcg_temp_new();
1075 TCGv_i32 t1 = tcg_constant_i32(0);
1076
1077
1078 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
1079 if (opc == OPC_MXU_D16MAX) {
1080 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1081 } else {
1082 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1083 }
1084
1085
1086 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
1087
1088 tcg_gen_shli_i32(t0, t0, 16);
1089
1090 if (opc == OPC_MXU_D16MAX) {
1091 tcg_gen_smax_i32(t0, t0, t1);
1092 } else {
1093 tcg_gen_smin_i32(t0, t0, t1);
1094 }
1095
1096 tcg_gen_shri_i32(t0, t0, 16);
1097
1098 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1099 } else if (unlikely(XRb == XRc)) {
1100
1101 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1102 } else {
1103
1104 TCGv_i32 t0 = tcg_temp_new();
1105 TCGv_i32 t1 = tcg_temp_new();
1106
1107
1108 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
1109 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1110 if (opc == OPC_MXU_D16MAX) {
1111 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1112 } else {
1113 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1114 }
1115
1116
1117 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1118 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
1119
1120 tcg_gen_shli_i32(t0, t0, 16);
1121 tcg_gen_shli_i32(t1, t1, 16);
1122
1123 if (opc == OPC_MXU_D16MAX) {
1124 tcg_gen_smax_i32(t0, t0, t1);
1125 } else {
1126 tcg_gen_smin_i32(t0, t0, t1);
1127 }
1128
1129 tcg_gen_shri_i32(t0, t0, 16);
1130
1131 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1132 }
1133}
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
1145{
1146 uint32_t pad, opc, XRc, XRb, XRa;
1147
1148 pad = extract32(ctx->opcode, 21, 5);
1149 opc = extract32(ctx->opcode, 18, 3);
1150 XRc = extract32(ctx->opcode, 14, 4);
1151 XRb = extract32(ctx->opcode, 10, 4);
1152 XRa = extract32(ctx->opcode, 6, 4);
1153
1154 if (unlikely(pad != 0)) {
1155
1156 } else if (unlikely(XRa == 0)) {
1157
1158 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1159
1160 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1161 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1162
1163 uint32_t XRx = XRb ? XRb : XRc;
1164
1165 TCGv_i32 t0 = tcg_temp_new();
1166 TCGv_i32 t1 = tcg_constant_i32(0);
1167 int32_t i;
1168
1169
1170 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
1171 if (opc == OPC_MXU_Q8MAX) {
1172 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1173 } else {
1174 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1175 }
1176
1177
1178 for (i = 2; i >= 0; i--) {
1179
1180 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
1181
1182 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1183
1184 if (opc == OPC_MXU_Q8MAX) {
1185 tcg_gen_smax_i32(t0, t0, t1);
1186 } else {
1187 tcg_gen_smin_i32(t0, t0, t1);
1188 }
1189
1190 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1191
1192 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1193 }
1194 } else if (unlikely(XRb == XRc)) {
1195
1196 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1197 } else {
1198
1199 TCGv_i32 t0 = tcg_temp_new();
1200 TCGv_i32 t1 = tcg_temp_new();
1201 int32_t i;
1202
1203
1204 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
1205 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1206 if (opc == OPC_MXU_Q8MAX) {
1207 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1208 } else {
1209 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1210 }
1211
1212
1213 for (i = 2; i >= 0; i--) {
1214
1215 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
1216 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
1217
1218 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1219 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
1220
1221 if (opc == OPC_MXU_Q8MAX) {
1222 tcg_gen_smax_i32(t0, t0, t1);
1223 } else {
1224 tcg_gen_smin_i32(t0, t0, t1);
1225 }
1226
1227 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1228
1229 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1230 }
1231 }
1232}
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247static void gen_mxu_S32ALNI(DisasContext *ctx)
1248{
1249 uint32_t optn3, pad, XRc, XRb, XRa;
1250
1251 optn3 = extract32(ctx->opcode, 23, 3);
1252 pad = extract32(ctx->opcode, 21, 2);
1253 XRc = extract32(ctx->opcode, 14, 4);
1254 XRb = extract32(ctx->opcode, 10, 4);
1255 XRa = extract32(ctx->opcode, 6, 4);
1256
1257 if (unlikely(pad != 0)) {
1258
1259 } else if (unlikely(XRa == 0)) {
1260
1261 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1262
1263 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1264 } else if (unlikely(XRb == 0)) {
1265
1266 switch (optn3) {
1267 case MXU_OPTN3_PTN0:
1268 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1269 break;
1270 case MXU_OPTN3_PTN1:
1271 case MXU_OPTN3_PTN2:
1272 case MXU_OPTN3_PTN3:
1273 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
1274 8 * (4 - optn3));
1275 break;
1276 case MXU_OPTN3_PTN4:
1277 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1278 break;
1279 }
1280 } else if (unlikely(XRc == 0)) {
1281
1282 switch (optn3) {
1283 case MXU_OPTN3_PTN0:
1284 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1285 break;
1286 case MXU_OPTN3_PTN1:
1287 case MXU_OPTN3_PTN2:
1288 case MXU_OPTN3_PTN3:
1289 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1290 break;
1291 case MXU_OPTN3_PTN4:
1292 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1293 break;
1294 }
1295 } else if (unlikely(XRb == XRc)) {
1296
1297 switch (optn3) {
1298 case MXU_OPTN3_PTN0:
1299 case MXU_OPTN3_PTN4:
1300 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1301 break;
1302 case MXU_OPTN3_PTN1:
1303 case MXU_OPTN3_PTN2:
1304 case MXU_OPTN3_PTN3:
1305 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1306 break;
1307 }
1308 } else {
1309
1310 switch (optn3) {
1311 case MXU_OPTN3_PTN0:
1312 {
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1323 }
1324 break;
1325 case MXU_OPTN3_PTN1:
1326 {
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336 TCGv_i32 t0 = tcg_temp_new();
1337 TCGv_i32 t1 = tcg_temp_new();
1338
1339 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
1340 tcg_gen_shli_i32(t0, t0, 8);
1341
1342 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1343 tcg_gen_shri_i32(t1, t1, 24);
1344
1345 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1346 }
1347 break;
1348 case MXU_OPTN3_PTN2:
1349 {
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359 TCGv_i32 t0 = tcg_temp_new();
1360 TCGv_i32 t1 = tcg_temp_new();
1361
1362 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1363 tcg_gen_shli_i32(t0, t0, 16);
1364
1365 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1366 tcg_gen_shri_i32(t1, t1, 16);
1367
1368 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1369 }
1370 break;
1371 case MXU_OPTN3_PTN3:
1372 {
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382 TCGv_i32 t0 = tcg_temp_new();
1383 TCGv_i32 t1 = tcg_temp_new();
1384
1385 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
1386 tcg_gen_shli_i32(t0, t0, 24);
1387
1388 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
1389 tcg_gen_shri_i32(t1, t1, 8);
1390
1391 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1392 }
1393 break;
1394 case MXU_OPTN3_PTN4:
1395 {
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1406 }
1407 break;
1408 }
1409 }
1410}
1411
1412
1413
1414
1415
1416
1417
1418static void decode_opc_mxu__pool00(DisasContext *ctx)
1419{
1420 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1421
1422 switch (opcode) {
1423 case OPC_MXU_S32MAX:
1424 case OPC_MXU_S32MIN:
1425 gen_mxu_S32MAX_S32MIN(ctx);
1426 break;
1427 case OPC_MXU_D16MAX:
1428 case OPC_MXU_D16MIN:
1429 gen_mxu_D16MAX_D16MIN(ctx);
1430 break;
1431 case OPC_MXU_Q8MAX:
1432 case OPC_MXU_Q8MIN:
1433 gen_mxu_Q8MAX_Q8MIN(ctx);
1434 break;
1435 default:
1436 MIPS_INVAL("decode_opc_mxu");
1437 gen_reserved_instruction(ctx);
1438 break;
1439 }
1440}
1441
1442static void decode_opc_mxu__pool04(DisasContext *ctx)
1443{
1444 uint32_t opcode = extract32(ctx->opcode, 20, 1);
1445
1446 switch (opcode) {
1447 case OPC_MXU_S32LDD:
1448 case OPC_MXU_S32LDDR:
1449 gen_mxu_s32ldd_s32lddr(ctx);
1450 break;
1451 default:
1452 MIPS_INVAL("decode_opc_mxu");
1453 gen_reserved_instruction(ctx);
1454 break;
1455 }
1456}
1457
1458static void decode_opc_mxu__pool16(DisasContext *ctx)
1459{
1460 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1461
1462 switch (opcode) {
1463 case OPC_MXU_S32ALNI:
1464 gen_mxu_S32ALNI(ctx);
1465 break;
1466 case OPC_MXU_S32NOR:
1467 gen_mxu_S32NOR(ctx);
1468 break;
1469 case OPC_MXU_S32AND:
1470 gen_mxu_S32AND(ctx);
1471 break;
1472 case OPC_MXU_S32OR:
1473 gen_mxu_S32OR(ctx);
1474 break;
1475 case OPC_MXU_S32XOR:
1476 gen_mxu_S32XOR(ctx);
1477 break;
1478 default:
1479 MIPS_INVAL("decode_opc_mxu");
1480 gen_reserved_instruction(ctx);
1481 break;
1482 }
1483}
1484
1485static void decode_opc_mxu__pool19(DisasContext *ctx)
1486{
1487 uint32_t opcode = extract32(ctx->opcode, 22, 2);
1488
1489 switch (opcode) {
1490 case OPC_MXU_Q8MUL:
1491 case OPC_MXU_Q8MULSU:
1492 gen_mxu_q8mul_q8mulsu(ctx);
1493 break;
1494 default:
1495 MIPS_INVAL("decode_opc_mxu");
1496 gen_reserved_instruction(ctx);
1497 break;
1498 }
1499}
1500
1501bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
1502{
1503 uint32_t opcode = extract32(insn, 0, 6);
1504
1505 if (opcode == OPC_MXU_S32M2I) {
1506 gen_mxu_s32m2i(ctx);
1507 return true;
1508 }
1509
1510 if (opcode == OPC_MXU_S32I2M) {
1511 gen_mxu_s32i2m(ctx);
1512 return true;
1513 }
1514
1515 {
1516 TCGv t_mxu_cr = tcg_temp_new();
1517 TCGLabel *l_exit = gen_new_label();
1518
1519 gen_load_mxu_cr(t_mxu_cr);
1520 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
1521 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
1522
1523 switch (opcode) {
1524 case OPC_MXU__POOL00:
1525 decode_opc_mxu__pool00(ctx);
1526 break;
1527 case OPC_MXU_D16MUL:
1528 gen_mxu_d16mul(ctx);
1529 break;
1530 case OPC_MXU_D16MAC:
1531 gen_mxu_d16mac(ctx);
1532 break;
1533 case OPC_MXU__POOL04:
1534 decode_opc_mxu__pool04(ctx);
1535 break;
1536 case OPC_MXU_S8LDD:
1537 gen_mxu_s8ldd(ctx);
1538 break;
1539 case OPC_MXU__POOL16:
1540 decode_opc_mxu__pool16(ctx);
1541 break;
1542 case OPC_MXU__POOL19:
1543 decode_opc_mxu__pool19(ctx);
1544 break;
1545 default:
1546 MIPS_INVAL("decode_opc_mxu");
1547 gen_reserved_instruction(ctx);
1548 }
1549
1550 gen_set_label(l_exit);
1551 }
1552
1553 return true;
1554}
1555