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 tcg_temp_free(t0);
518}
519
520
521
522
523static void gen_mxu_s32m2i(DisasContext *ctx)
524{
525 TCGv t0;
526 uint32_t XRa, Rb;
527
528 t0 = tcg_temp_new();
529
530 XRa = extract32(ctx->opcode, 6, 5);
531 Rb = extract32(ctx->opcode, 16, 5);
532
533 if (XRa <= 15) {
534 gen_load_mxu_gpr(t0, XRa);
535 } else if (XRa == 16) {
536 gen_load_mxu_cr(t0);
537 }
538
539 gen_store_gpr(t0, Rb);
540
541 tcg_temp_free(t0);
542}
543
544
545
546
547static void gen_mxu_s8ldd(DisasContext *ctx)
548{
549 TCGv t0, t1;
550 uint32_t XRa, Rb, s8, optn3;
551
552 t0 = tcg_temp_new();
553 t1 = tcg_temp_new();
554
555 XRa = extract32(ctx->opcode, 6, 4);
556 s8 = extract32(ctx->opcode, 10, 8);
557 optn3 = extract32(ctx->opcode, 18, 3);
558 Rb = extract32(ctx->opcode, 21, 5);
559
560 gen_load_gpr(t0, Rb);
561 tcg_gen_addi_tl(t0, t0, (int8_t)s8);
562
563 switch (optn3) {
564
565 case MXU_OPTN3_PTN0:
566 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
567 gen_load_mxu_gpr(t0, XRa);
568 tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
569 break;
570
571 case MXU_OPTN3_PTN1:
572 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
573 gen_load_mxu_gpr(t0, XRa);
574 tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
575 break;
576
577 case MXU_OPTN3_PTN2:
578 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
579 gen_load_mxu_gpr(t0, XRa);
580 tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
581 break;
582
583 case MXU_OPTN3_PTN3:
584 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
585 gen_load_mxu_gpr(t0, XRa);
586 tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
587 break;
588
589 case MXU_OPTN3_PTN4:
590 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
591 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
592 break;
593
594 case MXU_OPTN3_PTN5:
595 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
596 tcg_gen_shli_tl(t1, t1, 8);
597 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
598 break;
599
600 case MXU_OPTN3_PTN6:
601 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
602 tcg_gen_mov_tl(t0, t1);
603 tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
604 tcg_gen_shli_tl(t1, t1, 16);
605 tcg_gen_or_tl(t0, t0, t1);
606 break;
607
608 case MXU_OPTN3_PTN7:
609 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
610 tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
611 tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
612 break;
613 }
614
615 gen_store_mxu_gpr(t0, XRa);
616
617 tcg_temp_free(t0);
618 tcg_temp_free(t1);
619}
620
621
622
623
624static void gen_mxu_d16mul(DisasContext *ctx)
625{
626 TCGv t0, t1, t2, t3;
627 uint32_t XRa, XRb, XRc, XRd, optn2;
628
629 t0 = tcg_temp_new();
630 t1 = tcg_temp_new();
631 t2 = tcg_temp_new();
632 t3 = tcg_temp_new();
633
634 XRa = extract32(ctx->opcode, 6, 4);
635 XRb = extract32(ctx->opcode, 10, 4);
636 XRc = extract32(ctx->opcode, 14, 4);
637 XRd = extract32(ctx->opcode, 18, 4);
638 optn2 = extract32(ctx->opcode, 22, 2);
639
640 gen_load_mxu_gpr(t1, XRb);
641 tcg_gen_sextract_tl(t0, t1, 0, 16);
642 tcg_gen_sextract_tl(t1, t1, 16, 16);
643 gen_load_mxu_gpr(t3, XRc);
644 tcg_gen_sextract_tl(t2, t3, 0, 16);
645 tcg_gen_sextract_tl(t3, t3, 16, 16);
646
647 switch (optn2) {
648 case MXU_OPTN2_WW:
649 tcg_gen_mul_tl(t3, t1, t3);
650 tcg_gen_mul_tl(t2, t0, t2);
651 break;
652 case MXU_OPTN2_LW:
653 tcg_gen_mul_tl(t3, t0, t3);
654 tcg_gen_mul_tl(t2, t0, t2);
655 break;
656 case MXU_OPTN2_HW:
657 tcg_gen_mul_tl(t3, t1, t3);
658 tcg_gen_mul_tl(t2, t1, t2);
659 break;
660 case MXU_OPTN2_XW:
661 tcg_gen_mul_tl(t3, t0, t3);
662 tcg_gen_mul_tl(t2, t1, t2);
663 break;
664 }
665 gen_store_mxu_gpr(t3, XRa);
666 gen_store_mxu_gpr(t2, XRd);
667
668 tcg_temp_free(t0);
669 tcg_temp_free(t1);
670 tcg_temp_free(t2);
671 tcg_temp_free(t3);
672}
673
674
675
676
677
678static void gen_mxu_d16mac(DisasContext *ctx)
679{
680 TCGv t0, t1, t2, t3;
681 uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
682
683 t0 = tcg_temp_new();
684 t1 = tcg_temp_new();
685 t2 = tcg_temp_new();
686 t3 = tcg_temp_new();
687
688 XRa = extract32(ctx->opcode, 6, 4);
689 XRb = extract32(ctx->opcode, 10, 4);
690 XRc = extract32(ctx->opcode, 14, 4);
691 XRd = extract32(ctx->opcode, 18, 4);
692 optn2 = extract32(ctx->opcode, 22, 2);
693 aptn2 = extract32(ctx->opcode, 24, 2);
694
695 gen_load_mxu_gpr(t1, XRb);
696 tcg_gen_sextract_tl(t0, t1, 0, 16);
697 tcg_gen_sextract_tl(t1, t1, 16, 16);
698
699 gen_load_mxu_gpr(t3, XRc);
700 tcg_gen_sextract_tl(t2, t3, 0, 16);
701 tcg_gen_sextract_tl(t3, t3, 16, 16);
702
703 switch (optn2) {
704 case MXU_OPTN2_WW:
705 tcg_gen_mul_tl(t3, t1, t3);
706 tcg_gen_mul_tl(t2, t0, t2);
707 break;
708 case MXU_OPTN2_LW:
709 tcg_gen_mul_tl(t3, t0, t3);
710 tcg_gen_mul_tl(t2, t0, t2);
711 break;
712 case MXU_OPTN2_HW:
713 tcg_gen_mul_tl(t3, t1, t3);
714 tcg_gen_mul_tl(t2, t1, t2);
715 break;
716 case MXU_OPTN2_XW:
717 tcg_gen_mul_tl(t3, t0, t3);
718 tcg_gen_mul_tl(t2, t1, t2);
719 break;
720 }
721 gen_load_mxu_gpr(t0, XRa);
722 gen_load_mxu_gpr(t1, XRd);
723
724 switch (aptn2) {
725 case MXU_APTN2_AA:
726 tcg_gen_add_tl(t3, t0, t3);
727 tcg_gen_add_tl(t2, t1, t2);
728 break;
729 case MXU_APTN2_AS:
730 tcg_gen_add_tl(t3, t0, t3);
731 tcg_gen_sub_tl(t2, t1, t2);
732 break;
733 case MXU_APTN2_SA:
734 tcg_gen_sub_tl(t3, t0, t3);
735 tcg_gen_add_tl(t2, t1, t2);
736 break;
737 case MXU_APTN2_SS:
738 tcg_gen_sub_tl(t3, t0, t3);
739 tcg_gen_sub_tl(t2, t1, t2);
740 break;
741 }
742 gen_store_mxu_gpr(t3, XRa);
743 gen_store_mxu_gpr(t2, XRd);
744
745 tcg_temp_free(t0);
746 tcg_temp_free(t1);
747 tcg_temp_free(t2);
748 tcg_temp_free(t3);
749}
750
751
752
753
754
755static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
756{
757 TCGv t0, t1, t2, t3, t4, t5, t6, t7;
758 uint32_t XRa, XRb, XRc, XRd, sel;
759
760 t0 = tcg_temp_new();
761 t1 = tcg_temp_new();
762 t2 = tcg_temp_new();
763 t3 = tcg_temp_new();
764 t4 = tcg_temp_new();
765 t5 = tcg_temp_new();
766 t6 = tcg_temp_new();
767 t7 = tcg_temp_new();
768
769 XRa = extract32(ctx->opcode, 6, 4);
770 XRb = extract32(ctx->opcode, 10, 4);
771 XRc = extract32(ctx->opcode, 14, 4);
772 XRd = extract32(ctx->opcode, 18, 4);
773 sel = extract32(ctx->opcode, 22, 2);
774
775 gen_load_mxu_gpr(t3, XRb);
776 gen_load_mxu_gpr(t7, XRc);
777
778 if (sel == 0x2) {
779
780 tcg_gen_ext8s_tl(t0, t3);
781 tcg_gen_shri_tl(t3, t3, 8);
782 tcg_gen_ext8s_tl(t1, t3);
783 tcg_gen_shri_tl(t3, t3, 8);
784 tcg_gen_ext8s_tl(t2, t3);
785 tcg_gen_shri_tl(t3, t3, 8);
786 tcg_gen_ext8s_tl(t3, t3);
787 } else {
788
789 tcg_gen_ext8u_tl(t0, t3);
790 tcg_gen_shri_tl(t3, t3, 8);
791 tcg_gen_ext8u_tl(t1, t3);
792 tcg_gen_shri_tl(t3, t3, 8);
793 tcg_gen_ext8u_tl(t2, t3);
794 tcg_gen_shri_tl(t3, t3, 8);
795 tcg_gen_ext8u_tl(t3, t3);
796 }
797
798 tcg_gen_ext8u_tl(t4, t7);
799 tcg_gen_shri_tl(t7, t7, 8);
800 tcg_gen_ext8u_tl(t5, t7);
801 tcg_gen_shri_tl(t7, t7, 8);
802 tcg_gen_ext8u_tl(t6, t7);
803 tcg_gen_shri_tl(t7, t7, 8);
804 tcg_gen_ext8u_tl(t7, t7);
805
806 tcg_gen_mul_tl(t0, t0, t4);
807 tcg_gen_mul_tl(t1, t1, t5);
808 tcg_gen_mul_tl(t2, t2, t6);
809 tcg_gen_mul_tl(t3, t3, t7);
810
811 tcg_gen_andi_tl(t0, t0, 0xFFFF);
812 tcg_gen_andi_tl(t1, t1, 0xFFFF);
813 tcg_gen_andi_tl(t2, t2, 0xFFFF);
814 tcg_gen_andi_tl(t3, t3, 0xFFFF);
815
816 tcg_gen_shli_tl(t1, t1, 16);
817 tcg_gen_shli_tl(t3, t3, 16);
818
819 tcg_gen_or_tl(t0, t0, t1);
820 tcg_gen_or_tl(t1, t2, t3);
821
822 gen_store_mxu_gpr(t0, XRd);
823 gen_store_mxu_gpr(t1, XRa);
824
825 tcg_temp_free(t0);
826 tcg_temp_free(t1);
827 tcg_temp_free(t2);
828 tcg_temp_free(t3);
829 tcg_temp_free(t4);
830 tcg_temp_free(t5);
831 tcg_temp_free(t6);
832 tcg_temp_free(t7);
833}
834
835
836
837
838
839static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
840{
841 TCGv t0, t1;
842 uint32_t XRa, Rb, s12, sel;
843
844 t0 = tcg_temp_new();
845 t1 = tcg_temp_new();
846
847 XRa = extract32(ctx->opcode, 6, 4);
848 s12 = extract32(ctx->opcode, 10, 10);
849 sel = extract32(ctx->opcode, 20, 1);
850 Rb = extract32(ctx->opcode, 21, 5);
851
852 gen_load_gpr(t0, Rb);
853
854 tcg_gen_movi_tl(t1, s12);
855 tcg_gen_shli_tl(t1, t1, 2);
856 if (s12 & 0x200) {
857 tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
858 }
859 tcg_gen_add_tl(t1, t0, t1);
860 tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_TESL ^ (sel * MO_BSWAP));
861
862 gen_store_mxu_gpr(t1, XRa);
863
864 tcg_temp_free(t0);
865 tcg_temp_free(t1);
866}
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881static void gen_mxu_S32NOR(DisasContext *ctx)
882{
883 uint32_t pad, XRc, XRb, XRa;
884
885 pad = extract32(ctx->opcode, 21, 5);
886 XRc = extract32(ctx->opcode, 14, 4);
887 XRb = extract32(ctx->opcode, 10, 4);
888 XRa = extract32(ctx->opcode, 6, 4);
889
890 if (unlikely(pad != 0)) {
891
892 } else if (unlikely(XRa == 0)) {
893
894 } else if (unlikely((XRb == 0) && (XRc == 0))) {
895
896 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
897 } else if (unlikely(XRb == 0)) {
898
899 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
900 } else if (unlikely(XRc == 0)) {
901
902 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
903 } else if (unlikely(XRb == XRc)) {
904
905 tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
906 } else {
907
908 tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
909 }
910}
911
912
913
914
915
916
917static void gen_mxu_S32AND(DisasContext *ctx)
918{
919 uint32_t pad, XRc, XRb, XRa;
920
921 pad = extract32(ctx->opcode, 21, 5);
922 XRc = extract32(ctx->opcode, 14, 4);
923 XRb = extract32(ctx->opcode, 10, 4);
924 XRa = extract32(ctx->opcode, 6, 4);
925
926 if (unlikely(pad != 0)) {
927
928 } else if (unlikely(XRa == 0)) {
929
930 } else if (unlikely((XRb == 0) || (XRc == 0))) {
931
932 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
933 } else if (unlikely(XRb == XRc)) {
934
935 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
936 } else {
937
938 tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
939 }
940}
941
942
943
944
945
946
947static void gen_mxu_S32OR(DisasContext *ctx)
948{
949 uint32_t pad, XRc, XRb, XRa;
950
951 pad = extract32(ctx->opcode, 21, 5);
952 XRc = extract32(ctx->opcode, 14, 4);
953 XRb = extract32(ctx->opcode, 10, 4);
954 XRa = extract32(ctx->opcode, 6, 4);
955
956 if (unlikely(pad != 0)) {
957
958 } else if (unlikely(XRa == 0)) {
959
960 } else if (unlikely((XRb == 0) && (XRc == 0))) {
961
962 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
963 } else if (unlikely(XRb == 0)) {
964
965 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
966 } else if (unlikely(XRc == 0)) {
967
968 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
969 } else if (unlikely(XRb == XRc)) {
970
971 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
972 } else {
973
974 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
975 }
976}
977
978
979
980
981
982
983static void gen_mxu_S32XOR(DisasContext *ctx)
984{
985 uint32_t pad, XRc, XRb, XRa;
986
987 pad = extract32(ctx->opcode, 21, 5);
988 XRc = extract32(ctx->opcode, 14, 4);
989 XRb = extract32(ctx->opcode, 10, 4);
990 XRa = extract32(ctx->opcode, 6, 4);
991
992 if (unlikely(pad != 0)) {
993
994 } else if (unlikely(XRa == 0)) {
995
996 } else if (unlikely((XRb == 0) && (XRc == 0))) {
997
998 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
999 } else if (unlikely(XRb == 0)) {
1000
1001 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1002 } else if (unlikely(XRc == 0)) {
1003
1004 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1005 } else if (unlikely(XRb == XRc)) {
1006
1007 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1008 } else {
1009
1010 tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
1011 }
1012}
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
1033{
1034 uint32_t pad, opc, XRc, XRb, XRa;
1035
1036 pad = extract32(ctx->opcode, 21, 5);
1037 opc = extract32(ctx->opcode, 18, 3);
1038 XRc = extract32(ctx->opcode, 14, 4);
1039 XRb = extract32(ctx->opcode, 10, 4);
1040 XRa = extract32(ctx->opcode, 6, 4);
1041
1042 if (unlikely(pad != 0)) {
1043
1044 } else if (unlikely(XRa == 0)) {
1045
1046 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1047
1048 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1049 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1050
1051 uint32_t XRx = XRb ? XRb : XRc;
1052
1053 if (opc == OPC_MXU_S32MAX) {
1054 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1055 } else {
1056 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
1057 }
1058 } else if (unlikely(XRb == XRc)) {
1059
1060 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1061 } else {
1062
1063 if (opc == OPC_MXU_S32MAX) {
1064 tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1065 mxu_gpr[XRc - 1]);
1066 } else {
1067 tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
1068 mxu_gpr[XRc - 1]);
1069 }
1070 }
1071}
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
1083{
1084 uint32_t pad, opc, XRc, XRb, XRa;
1085
1086 pad = extract32(ctx->opcode, 21, 5);
1087 opc = extract32(ctx->opcode, 18, 3);
1088 XRc = extract32(ctx->opcode, 14, 4);
1089 XRb = extract32(ctx->opcode, 10, 4);
1090 XRa = extract32(ctx->opcode, 6, 4);
1091
1092 if (unlikely(pad != 0)) {
1093
1094 } else if (unlikely(XRa == 0)) {
1095
1096 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1097
1098 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1099 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1100
1101 uint32_t XRx = XRb ? XRb : XRc;
1102
1103 TCGv_i32 t0 = tcg_temp_new();
1104 TCGv_i32 t1 = tcg_const_i32(0);
1105
1106
1107 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
1108 if (opc == OPC_MXU_D16MAX) {
1109 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1110 } else {
1111 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1112 }
1113
1114
1115 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
1116
1117 tcg_gen_shli_i32(t0, t0, 16);
1118
1119 if (opc == OPC_MXU_D16MAX) {
1120 tcg_gen_smax_i32(t0, t0, t1);
1121 } else {
1122 tcg_gen_smin_i32(t0, t0, t1);
1123 }
1124
1125 tcg_gen_shri_i32(t0, t0, 16);
1126
1127 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1128
1129 tcg_temp_free(t1);
1130 tcg_temp_free(t0);
1131 } else if (unlikely(XRb == XRc)) {
1132
1133 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1134 } else {
1135
1136 TCGv_i32 t0 = tcg_temp_new();
1137 TCGv_i32 t1 = tcg_temp_new();
1138
1139
1140 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
1141 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1142 if (opc == OPC_MXU_D16MAX) {
1143 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1144 } else {
1145 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1146 }
1147
1148
1149 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1150 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
1151
1152 tcg_gen_shli_i32(t0, t0, 16);
1153 tcg_gen_shli_i32(t1, t1, 16);
1154
1155 if (opc == OPC_MXU_D16MAX) {
1156 tcg_gen_smax_i32(t0, t0, t1);
1157 } else {
1158 tcg_gen_smin_i32(t0, t0, t1);
1159 }
1160
1161 tcg_gen_shri_i32(t0, t0, 16);
1162
1163 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1164
1165 tcg_temp_free(t1);
1166 tcg_temp_free(t0);
1167 }
1168}
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
1180{
1181 uint32_t pad, opc, XRc, XRb, XRa;
1182
1183 pad = extract32(ctx->opcode, 21, 5);
1184 opc = extract32(ctx->opcode, 18, 3);
1185 XRc = extract32(ctx->opcode, 14, 4);
1186 XRb = extract32(ctx->opcode, 10, 4);
1187 XRa = extract32(ctx->opcode, 6, 4);
1188
1189 if (unlikely(pad != 0)) {
1190
1191 } else if (unlikely(XRa == 0)) {
1192
1193 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1194
1195 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1196 } else if (unlikely((XRb == 0) || (XRc == 0))) {
1197
1198 uint32_t XRx = XRb ? XRb : XRc;
1199
1200 TCGv_i32 t0 = tcg_temp_new();
1201 TCGv_i32 t1 = tcg_const_i32(0);
1202 int32_t i;
1203
1204
1205 tcg_gen_andi_i32(t0, mxu_gpr[XRx - 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[XRx - 1], 0xFF << (8 * i));
1216
1217 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1218
1219 if (opc == OPC_MXU_Q8MAX) {
1220 tcg_gen_smax_i32(t0, t0, t1);
1221 } else {
1222 tcg_gen_smin_i32(t0, t0, t1);
1223 }
1224
1225 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1226
1227 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1228 }
1229
1230 tcg_temp_free(t1);
1231 tcg_temp_free(t0);
1232 } else if (unlikely(XRb == XRc)) {
1233
1234 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1235 } else {
1236
1237 TCGv_i32 t0 = tcg_temp_new();
1238 TCGv_i32 t1 = tcg_temp_new();
1239 int32_t i;
1240
1241
1242 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
1243 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1244 if (opc == OPC_MXU_Q8MAX) {
1245 tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
1246 } else {
1247 tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
1248 }
1249
1250
1251 for (i = 2; i >= 0; i--) {
1252
1253 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
1254 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
1255
1256 tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
1257 tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
1258
1259 if (opc == OPC_MXU_Q8MAX) {
1260 tcg_gen_smax_i32(t0, t0, t1);
1261 } else {
1262 tcg_gen_smin_i32(t0, t0, t1);
1263 }
1264
1265 tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
1266
1267 tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
1268 }
1269
1270 tcg_temp_free(t1);
1271 tcg_temp_free(t0);
1272 }
1273}
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288static void gen_mxu_S32ALNI(DisasContext *ctx)
1289{
1290 uint32_t optn3, pad, XRc, XRb, XRa;
1291
1292 optn3 = extract32(ctx->opcode, 23, 3);
1293 pad = extract32(ctx->opcode, 21, 2);
1294 XRc = extract32(ctx->opcode, 14, 4);
1295 XRb = extract32(ctx->opcode, 10, 4);
1296 XRa = extract32(ctx->opcode, 6, 4);
1297
1298 if (unlikely(pad != 0)) {
1299
1300 } else if (unlikely(XRa == 0)) {
1301
1302 } else if (unlikely((XRb == 0) && (XRc == 0))) {
1303
1304 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1305 } else if (unlikely(XRb == 0)) {
1306
1307 switch (optn3) {
1308 case MXU_OPTN3_PTN0:
1309 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1310 break;
1311 case MXU_OPTN3_PTN1:
1312 case MXU_OPTN3_PTN2:
1313 case MXU_OPTN3_PTN3:
1314 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
1315 8 * (4 - optn3));
1316 break;
1317 case MXU_OPTN3_PTN4:
1318 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1319 break;
1320 }
1321 } else if (unlikely(XRc == 0)) {
1322
1323 switch (optn3) {
1324 case MXU_OPTN3_PTN0:
1325 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1326 break;
1327 case MXU_OPTN3_PTN1:
1328 case MXU_OPTN3_PTN2:
1329 case MXU_OPTN3_PTN3:
1330 tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1331 break;
1332 case MXU_OPTN3_PTN4:
1333 tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
1334 break;
1335 }
1336 } else if (unlikely(XRb == XRc)) {
1337
1338 switch (optn3) {
1339 case MXU_OPTN3_PTN0:
1340 case MXU_OPTN3_PTN4:
1341 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1342 break;
1343 case MXU_OPTN3_PTN1:
1344 case MXU_OPTN3_PTN2:
1345 case MXU_OPTN3_PTN3:
1346 tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
1347 break;
1348 }
1349 } else {
1350
1351 switch (optn3) {
1352 case MXU_OPTN3_PTN0:
1353 {
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
1364 }
1365 break;
1366 case MXU_OPTN3_PTN1:
1367 {
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377 TCGv_i32 t0 = tcg_temp_new();
1378 TCGv_i32 t1 = tcg_temp_new();
1379
1380 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
1381 tcg_gen_shli_i32(t0, t0, 8);
1382
1383 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
1384 tcg_gen_shri_i32(t1, t1, 24);
1385
1386 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1387
1388 tcg_temp_free(t1);
1389 tcg_temp_free(t0);
1390 }
1391 break;
1392 case MXU_OPTN3_PTN2:
1393 {
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 TCGv_i32 t0 = tcg_temp_new();
1404 TCGv_i32 t1 = tcg_temp_new();
1405
1406 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
1407 tcg_gen_shli_i32(t0, t0, 16);
1408
1409 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
1410 tcg_gen_shri_i32(t1, t1, 16);
1411
1412 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1413
1414 tcg_temp_free(t1);
1415 tcg_temp_free(t0);
1416 }
1417 break;
1418 case MXU_OPTN3_PTN3:
1419 {
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429 TCGv_i32 t0 = tcg_temp_new();
1430 TCGv_i32 t1 = tcg_temp_new();
1431
1432 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
1433 tcg_gen_shli_i32(t0, t0, 24);
1434
1435 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
1436 tcg_gen_shri_i32(t1, t1, 8);
1437
1438 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
1439
1440 tcg_temp_free(t1);
1441 tcg_temp_free(t0);
1442 }
1443 break;
1444 case MXU_OPTN3_PTN4:
1445 {
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
1456 }
1457 break;
1458 }
1459 }
1460}
1461
1462
1463
1464
1465
1466
1467
1468static void decode_opc_mxu__pool00(DisasContext *ctx)
1469{
1470 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1471
1472 switch (opcode) {
1473 case OPC_MXU_S32MAX:
1474 case OPC_MXU_S32MIN:
1475 gen_mxu_S32MAX_S32MIN(ctx);
1476 break;
1477 case OPC_MXU_D16MAX:
1478 case OPC_MXU_D16MIN:
1479 gen_mxu_D16MAX_D16MIN(ctx);
1480 break;
1481 case OPC_MXU_Q8MAX:
1482 case OPC_MXU_Q8MIN:
1483 gen_mxu_Q8MAX_Q8MIN(ctx);
1484 break;
1485 default:
1486 MIPS_INVAL("decode_opc_mxu");
1487 gen_reserved_instruction(ctx);
1488 break;
1489 }
1490}
1491
1492static void decode_opc_mxu__pool04(DisasContext *ctx)
1493{
1494 uint32_t opcode = extract32(ctx->opcode, 20, 1);
1495
1496 switch (opcode) {
1497 case OPC_MXU_S32LDD:
1498 case OPC_MXU_S32LDDR:
1499 gen_mxu_s32ldd_s32lddr(ctx);
1500 break;
1501 default:
1502 MIPS_INVAL("decode_opc_mxu");
1503 gen_reserved_instruction(ctx);
1504 break;
1505 }
1506}
1507
1508static void decode_opc_mxu__pool16(DisasContext *ctx)
1509{
1510 uint32_t opcode = extract32(ctx->opcode, 18, 3);
1511
1512 switch (opcode) {
1513 case OPC_MXU_S32ALNI:
1514 gen_mxu_S32ALNI(ctx);
1515 break;
1516 case OPC_MXU_S32NOR:
1517 gen_mxu_S32NOR(ctx);
1518 break;
1519 case OPC_MXU_S32AND:
1520 gen_mxu_S32AND(ctx);
1521 break;
1522 case OPC_MXU_S32OR:
1523 gen_mxu_S32OR(ctx);
1524 break;
1525 case OPC_MXU_S32XOR:
1526 gen_mxu_S32XOR(ctx);
1527 break;
1528 default:
1529 MIPS_INVAL("decode_opc_mxu");
1530 gen_reserved_instruction(ctx);
1531 break;
1532 }
1533}
1534
1535static void decode_opc_mxu__pool19(DisasContext *ctx)
1536{
1537 uint32_t opcode = extract32(ctx->opcode, 22, 2);
1538
1539 switch (opcode) {
1540 case OPC_MXU_Q8MUL:
1541 case OPC_MXU_Q8MULSU:
1542 gen_mxu_q8mul_q8mulsu(ctx);
1543 break;
1544 default:
1545 MIPS_INVAL("decode_opc_mxu");
1546 gen_reserved_instruction(ctx);
1547 break;
1548 }
1549}
1550
1551bool decode_ase_mxu(DisasContext *ctx, uint32_t insn)
1552{
1553 uint32_t opcode = extract32(insn, 0, 6);
1554
1555 if (opcode == OPC_MXU_S32M2I) {
1556 gen_mxu_s32m2i(ctx);
1557 return true;
1558 }
1559
1560 if (opcode == OPC_MXU_S32I2M) {
1561 gen_mxu_s32i2m(ctx);
1562 return true;
1563 }
1564
1565 {
1566 TCGv t_mxu_cr = tcg_temp_new();
1567 TCGLabel *l_exit = gen_new_label();
1568
1569 gen_load_mxu_cr(t_mxu_cr);
1570 tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
1571 tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
1572
1573 switch (opcode) {
1574 case OPC_MXU__POOL00:
1575 decode_opc_mxu__pool00(ctx);
1576 break;
1577 case OPC_MXU_D16MUL:
1578 gen_mxu_d16mul(ctx);
1579 break;
1580 case OPC_MXU_D16MAC:
1581 gen_mxu_d16mac(ctx);
1582 break;
1583 case OPC_MXU__POOL04:
1584 decode_opc_mxu__pool04(ctx);
1585 break;
1586 case OPC_MXU_S8LDD:
1587 gen_mxu_s8ldd(ctx);
1588 break;
1589 case OPC_MXU__POOL16:
1590 decode_opc_mxu__pool16(ctx);
1591 break;
1592 case OPC_MXU__POOL19:
1593 decode_opc_mxu__pool19(ctx);
1594 break;
1595 default:
1596 MIPS_INVAL("decode_opc_mxu");
1597 gen_reserved_instruction(ctx);
1598 }
1599
1600 gen_set_label(l_exit);
1601 tcg_temp_free(t_mxu_cr);
1602 }
1603
1604 return true;
1605}
1606