PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
mipsdis.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "srxfixup_internal.h"
12#include <stdint.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16
17static void getrs(unsigned int data, Operand *opr);
18static void getrt(unsigned int data, Operand *opr);
19static void getrd(unsigned int data, Operand *opr);
20static void getc0rd_iop(unsigned int data, Operand *opr);
21static void getc0rd_ee(unsigned int data, Operand *opr);
22static void getczrd(unsigned int data, Operand *opr);
23static void getshamt(unsigned int data, Operand *opr);
24static void getfs(unsigned int data, Operand *opr);
25static void getft(unsigned int data, Operand *opr);
26static void getfd(unsigned int data, Operand *opr);
27static void getczfs(unsigned int data, Operand *opr);
28static void getbroff(unsigned int addr, unsigned int data, Operand *opr);
29static void Rs(Disasm_result *result);
30static void Rd(Disasm_result *result);
31static void Rdrs(Disasm_result *result);
32static void Rsrt(Disasm_result *result);
33static void Rtc0rd_iop(Disasm_result *result);
34static void Rtc0rd_ee(Disasm_result *result);
35static void Rtczrd(Disasm_result *result);
36static void Rdrsrt(Disasm_result *result);
37static void Rdrtrs(Disasm_result *result);
38static void Rdrtshamt(Disasm_result *result);
39static void Rsseimm(Disasm_result *result);
40static void Rtrsseimm(Disasm_result *result);
41static void Rtrsimm(Disasm_result *result);
42#if 0
43static void Rdimm(Disasm_result *result);
44static void Rsimm(Disasm_result *result);
45#endif
46static void Rtimm(Disasm_result *result);
47static void Rsrtbroff(Disasm_result *result);
48static void Rsbroff(Disasm_result *result);
49static void Rtoffbase(Disasm_result *result);
50static void Fdfs(Disasm_result *result);
51static void Fsft(Disasm_result *result);
52static void Fdfsft(Disasm_result *result);
53static void Rtczfs(Disasm_result *result);
54static void Code20(Disasm_result *result);
55static void Jtarget(Disasm_result *result);
56static void Cofun(Disasm_result *result);
57static void Bcft(Disasm_result *result);
58
59// clang-format off
60static int regnmsw[5] = { 1, 1, 0, 1, 0 };
61static const char * const REGNAME[2][32] =
62{
63 {
64 "$0",
65 "$at",
66 "$2",
67 "$3",
68 "$4",
69 "$5",
70 "$6",
71 "$7",
72 "$8",
73 "$9",
74 "$10",
75 "$11",
76 "$12",
77 "$13",
78 "$14",
79 "$15",
80 "$16",
81 "$17",
82 "$18",
83 "$19",
84 "$20",
85 "$21",
86 "$22",
87 "$23",
88 "$24",
89 "$25",
90 "$26",
91 "$27",
92 "$gp",
93 "$sp",
94 "$30",
95 "$31"
96 },
97 {
98 "zero",
99 "at",
100 "v0",
101 "v1",
102 "a0",
103 "a1",
104 "a2",
105 "a3",
106 "t0",
107 "t1",
108 "t2",
109 "t3",
110 "t4",
111 "t5",
112 "t6",
113 "t7",
114 "s0",
115 "s1",
116 "s2",
117 "s3",
118 "s4",
119 "s5",
120 "s6",
121 "s7",
122 "t8",
123 "t9",
124 "k0",
125 "k1",
126 "gp",
127 "sp",
128 "fp",
129 "ra"
130 }
131};
132static const char * const REGC0_iop[2][32] =
133{
134 {
135 "$0",
136 "$1",
137 "$2",
138 "$3",
139 "$4",
140 "$5",
141 "$6",
142 "$7",
143 "$8",
144 "$9",
145 "$10",
146 "$11",
147 "$12",
148 "$13",
149 "$14",
150 "$15",
151 "$16",
152 "$17",
153 "$18",
154 "$19",
155 "$20",
156 "$21",
157 "$22",
158 "$23",
159 "$24",
160 "$25",
161 "$26",
162 "$27",
163 "$28",
164 "$29",
165 "$30",
166 "$31"
167 },
168 {
169 "$0",
170 "$1",
171 "$2",
172 "$bpc",
173 "$4",
174 "$bda",
175 "$tar",
176 "$dcic",
177 "$bada",
178 "$bdam",
179 "$10",
180 "$bpcm",
181 "$sr",
182 "$cause",
183 "$epc",
184 "$prid",
185 "$16",
186 "$17",
187 "$18",
188 "$19",
189 "$20",
190 "$21",
191 "$22",
192 "$23",
193 "$24",
194 "$25",
195 "$26",
196 "$27",
197 "$28",
198 "$29",
199 "$30",
200 "$31"
201 }
202};
203static const char * const REGC0_ee[2][32] =
204{
205 {
206 "$0",
207 "$1",
208 "$2",
209 "$3",
210 "$4",
211 "$5",
212 "$6",
213 "$7",
214 "$8",
215 "$9",
216 "$10",
217 "$11",
218 "$12",
219 "$13",
220 "$14",
221 "$15",
222 "$16",
223 "$17",
224 "$18",
225 "$19",
226 "$20",
227 "$21",
228 "$22",
229 "$23",
230 "$24",
231 "$25",
232 "$26",
233 "$27",
234 "$28",
235 "$29",
236 "$30",
237 "$31"
238 },
239 {
240 "$index",
241 "$random",
242 "$entrylo0",
243 "$entrylo1",
244 "$context",
245 "$pagemask",
246 "$wired",
247 "$7",
248 "$badvaddr",
249 "$count",
250 "$entryhi",
251 "$compare",
252 "$status",
253 "$cause",
254 "$epc",
255 "$prid",
256 "$config",
257 "$17",
258 "$18",
259 "$19",
260 "$20",
261 "$21",
262 "$22",
263 "$badpaddr",
264 "$hwbk",
265 "$pccr",
266 "$26",
267 "$27",
268 "$taglo",
269 "$taghi",
270 "$errorepc",
271 "$31"
272 }
273};
274static const char * const REGC1[2][32] =
275{
276 {
277 "$f0",
278 "$f1",
279 "$f2",
280 "$f3",
281 "$f4",
282 "$f5",
283 "$f6",
284 "$f7",
285 "$f8",
286 "$f9",
287 "$f10",
288 "$f11",
289 "$f12",
290 "$f13",
291 "$f14",
292 "$f15",
293 "$f16",
294 "$f17",
295 "$f18",
296 "$f19",
297 "$f20",
298 "$f21",
299 "$f22",
300 "$f23",
301 "$f24",
302 "$f25",
303 "$f26",
304 "$f27",
305 "$f28",
306 "$f29",
307 "$f30",
308 "$f31"
309 },
310 {
311 "$fv0",
312 "$fv1",
313 "$ft0",
314 "$ft1",
315 "$ft2",
316 "$ft3",
317 "$ft4",
318 "$ft5",
319 "$ft6",
320 "$ft7",
321 "$ft8",
322 "$ft9",
323 "$fa0",
324 "$fa1",
325 "$fa2",
326 "$fa3",
327 "$fa4",
328 "$fa5",
329 "$fa6",
330 "$fa7",
331 "$fs0",
332 "$fs1",
333 "$fs2",
334 "$fs3",
335 "$fs4",
336 "$fs5",
337 "$fs6",
338 "$fs7",
339 "$fs8",
340 "$fs9",
341 "$fs10",
342 "$fs11"
343 }
344};
345// clang-format on
346
347typedef void (*Operand_func)(Disasm_result *result);
349{
350 const char *mnemonic;
351 const struct opcode_table_ *subtable;
352 Operand_func opfunc;
354typedef struct opcode_table_
355{
356 int bit_pos;
357 unsigned int bit_mask;
358 const Opcode_table_entry *entries;
360
361static void getrs(unsigned int data, Operand *opr)
362{
363 opr->tag = OprTag_reg;
364 opr->reg = (data >> 21) & 0x1F;
365}
366
367static void getrt(unsigned int data, Operand *opr)
368{
369 opr->tag = OprTag_reg;
370 opr->reg = (data >> 16) & 0x1F;
371}
372
373static void getrd(unsigned int data, Operand *opr)
374{
375 opr->tag = OprTag_reg;
376 opr->reg = (data >> 11) & 0x1F;
377}
378
379static void getc0rd_iop(unsigned int data, Operand *opr)
380{
381 opr->tag = OprTag_c0reg_iop;
382 opr->reg = (data >> 11) & 0x1F;
383}
384
385static void getc0rd_ee(unsigned int data, Operand *opr)
386{
387 opr->tag = OprTag_c0reg_ee;
388 opr->reg = (data >> 11) & 0x1F;
389}
390
391static void getczrd(unsigned int data, Operand *opr)
392{
393 opr->tag = OprTag_czreg;
394 opr->reg = (data >> 11) & 0x1F;
395}
396
397static void getshamt(unsigned int data, Operand *opr)
398{
399 opr->tag = OprTag_shamt;
400 opr->data = (data >> 6) & 0x1F;
401}
402
403static void getfs(unsigned int data, Operand *opr)
404{
405 opr->tag = OprTag_c1reg;
406 opr->reg = (data >> 11) & 0x1F;
407}
408
409static void getft(unsigned int data, Operand *opr)
410{
411 opr->tag = OprTag_c1reg;
412 opr->reg = (data >> 16) & 0x1F;
413}
414
415static void getfd(unsigned int data, Operand *opr)
416{
417 opr->tag = OprTag_c1reg;
418 opr->reg = (data >> 6) & 0x1F;
419}
420
421static void getczfs(unsigned int data, Operand *opr)
422{
423 opr->tag = OprTag_c1reg;
424 opr->reg = (data >> 11) & 0x1F;
425}
426
427static void getbroff(unsigned int addr, unsigned int data, Operand *opr)
428{
429 opr->tag = OprTag_jtarget;
430 if ( (data & 0x8000) != 0 )
431 {
432 opr->data = 4 * (uint16_t)data - 0x40000;
433 }
434 else
435 {
436 opr->data = 4 * (uint16_t)data;
437 }
438 opr->data += 4 + addr;
439}
440
441static void Rs(Disasm_result *result)
442{
443 getrs(result->data, result->operands);
444}
445
446static void Rd(Disasm_result *result)
447{
448 getrd(result->data, result->operands);
449}
450
451static void Rdrs(Disasm_result *result)
452{
453 getrd(result->data, result->operands);
454 getrs(result->data, &result->operands[1]);
455}
456
457static void Rsrt(Disasm_result *result)
458{
459 getrs(result->data, result->operands);
460 getrt(result->data, &result->operands[1]);
461}
462
463static void Rtc0rd_iop(Disasm_result *result)
464{
465 getrt(result->data, result->operands);
466 getc0rd_iop(result->data, &result->operands[1]);
467}
468
469static void Rtc0rd_ee(Disasm_result *result)
470{
471 getrt(result->data, result->operands);
472 getc0rd_ee(result->data, &result->operands[1]);
473}
474
475static void Rtczrd(Disasm_result *result)
476{
477 getrt(result->data, result->operands);
478 getczrd(result->data, &result->operands[1]);
479}
480
481static void Rdrsrt(Disasm_result *result)
482{
483 getrd(result->data, result->operands);
484 getrs(result->data, &result->operands[1]);
485 getrt(result->data, &result->operands[2]);
486}
487
488static void Rdrtrs(Disasm_result *result)
489{
490 getrd(result->data, result->operands);
491 getrt(result->data, &result->operands[1]);
492 getrs(result->data, &result->operands[2]);
493}
494
495static void Rdrtshamt(Disasm_result *result)
496{
497 getrd(result->data, result->operands);
498 getrt(result->data, &result->operands[1]);
499 getshamt(result->data, &result->operands[2]);
500}
501
502static void Rsseimm(Disasm_result *result)
503{
504 unsigned int imm;
505
506 getrs(result->data, result->operands);
507 if ( (int16_t)(result->data & 0xFFFF) < 0 )
508 {
509 imm = (result->data & 0xFFFF) - 0x10000;
510 }
511 else
512 {
513 imm = (result->data & 0xFFFF);
514 }
515 result->operands[1].tag = OprTag_imm;
516 result->operands[1].data = imm;
517}
518
519static void Rtrsseimm(Disasm_result *result)
520{
521 unsigned int imm;
522
523 getrt(result->data, result->operands);
524 getrs(result->data, &result->operands[1]);
525 if ( (int16_t)(result->data & 0xFFFF) < 0 )
526 {
527 imm = (result->data & 0xFFFF) - 0x10000;
528 }
529 else
530 {
531 imm = (result->data & 0xFFFF);
532 }
533 result->operands[2].tag = OprTag_imm;
534 result->operands[2].data = imm;
535}
536
537static void Rtrsimm(Disasm_result *result)
538{
539 getrt(result->data, result->operands);
540 getrs(result->data, &result->operands[1]);
541 result->operands[2].tag = OprTag_imm;
542 result->operands[2].data = (result->data & 0xFFFF);
543}
544
545#if 0
546static void Rdimm(Disasm_result *result)
547{
548 getrd(result->data, result->operands);
549 result->operands[1].tag = OprTag_imm;
550 result->operands[1].data = (result->data & 0xFFFF);
551}
552
553static void Rsimm(Disasm_result *result)
554{
555 getrs(result->data, result->operands);
556 result->operands[1].tag = OprTag_imm;
557 result->operands[1].data = (result->data & 0xFFFF);
558}
559#endif
560
561static void Rtimm(Disasm_result *result)
562{
563 getrt(result->data, result->operands);
564 result->operands[1].tag = OprTag_imm;
565 result->operands[1].data = (result->data & 0xFFFF);
566}
567
568static void Rsrtbroff(Disasm_result *result)
569{
570 getrs(result->data, result->operands);
571 getrt(result->data, &result->operands[1]);
572 getbroff(result->addr, result->data, &result->operands[2]);
573}
574
575static void Rsbroff(Disasm_result *result)
576{
577 getrs(result->data, result->operands);
578 getbroff(result->addr, result->data, &result->operands[1]);
579}
580
581static void Rtoffbase(Disasm_result *result)
582{
583 unsigned int off;
584
585 if ( (int16_t)(result->data & 0xFFFF) < 0 )
586 {
587 off = (result->data & 0xFFFF) - 0x10000;
588 }
589 else
590 {
591 off = (result->data & 0xFFFF);
592 }
593 getrt(result->data, result->operands);
594 result->operands[1].tag = OprTag_regoffset;
595 result->operands[1].data = off;
596 result->operands[1].reg = (result->data >> 21) & 0x1F;
597}
598
599static void Fdfs(Disasm_result *result)
600{
601 getfd(result->data, result->operands);
602 getfs(result->data, &result->operands[1]);
603}
604
605static void Fsft(Disasm_result *result)
606{
607 getfs(result->data, result->operands);
608 getft(result->data, &result->operands[1]);
609}
610
611static void Fdfsft(Disasm_result *result)
612{
613 getfd(result->data, result->operands);
614 getfs(result->data, &result->operands[1]);
615 getft(result->data, &result->operands[2]);
616}
617
618static void Rtczfs(Disasm_result *result)
619{
620 getrt(result->data, result->operands);
621 getczfs(result->data, &result->operands[1]);
622}
623
624static void Code20(Disasm_result *result)
625{
626 result->operands[0].tag = OprTag_code20;
627 result->operands[0].data = (result->data >> 6) & 0xFFFFF;
628}
629
630static void Jtarget(Disasm_result *result)
631{
632 result->operands[0].tag = OprTag_jtarget;
633 result->operands[0].data = (4 * (result->data & 0x3FFFFFF)) | (result->addr & 0xF0000000);
634}
635
636static void Cofun(Disasm_result *result)
637{
638 result->operands[0].tag = OprTag_code25;
639 result->operands[0].data = result->data & 0x1FFFFFF;
640}
641
642static void Bcft(Disasm_result *result)
643{
644 result->mnemonic[0] = 'b';
645 result->mnemonic[1] = 'c';
646 result->mnemonic[2] = result->mnemonic[3];
647 if ( (result->data & 0x10000) != 0 )
648 {
649 result->mnemonic[3] = 't';
650 }
651 else
652 {
653 result->mnemonic[3] = 'f';
654 }
655 if ( (result->data & 0x20000) != 0 )
656 {
657 result->mnemonic[4] = 'l';
658 }
659 else
660 {
661 result->mnemonic[4] = '\x00';
662 }
663 result->mnemonic[5] = '\x00';
664 getbroff(result->addr, result->data, result->operands);
665}
666
667// clang-format off
668static const Opcode_table_entry iop_SPECIAL_entries[] =
669{
670 { "sll", NULL, &Rdrtshamt },
671 { NULL, NULL, NULL },
672 { "srl", NULL, &Rdrtshamt },
673 { "sra", NULL, &Rdrtshamt },
674 { "sllv", NULL, &Rdrtrs },
675 { NULL, NULL, NULL },
676 { "srlv", NULL, &Rdrtrs },
677 { "srav", NULL, &Rdrtrs },
678 { "jr", NULL, &Rs },
679 { "jalr", NULL, &Rdrs },
680 { NULL, NULL, NULL },
681 { NULL, NULL, NULL },
682 { "syscall", NULL, &Code20 },
683 { "break", NULL, &Code20 },
684 { NULL, NULL, NULL },
685 { NULL, NULL, NULL },
686 { "mfhi", NULL, &Rd },
687 { "mthi", NULL, &Rs },
688 { "mflo", NULL, &Rd },
689 { "mtlo", NULL, &Rs },
690 { NULL, NULL, NULL },
691 { NULL, NULL, NULL },
692 { NULL, NULL, NULL },
693 { NULL, NULL, NULL },
694 { "mult", NULL, &Rsrt },
695 { "multu", NULL, &Rsrt },
696 { "div", NULL, &Rsrt },
697 { "divu", NULL, &Rsrt },
698 { NULL, NULL, NULL },
699 { NULL, NULL, NULL },
700 { NULL, NULL, NULL },
701 { NULL, NULL, NULL },
702 { "add", NULL, &Rdrsrt },
703 { "addu", NULL, &Rdrsrt },
704 { "sub", NULL, &Rdrsrt },
705 { "subu", NULL, &Rdrsrt },
706 { "and", NULL, &Rdrsrt },
707 { "or", NULL, &Rdrsrt },
708 { "xor", NULL, &Rdrsrt },
709 { "nor", NULL, &Rdrsrt },
710 { NULL, NULL, NULL },
711 { NULL, NULL, NULL },
712 { "slt", NULL, &Rdrsrt },
713 { "sltu", NULL, &Rdrsrt },
714 { NULL, NULL, NULL },
715 { NULL, NULL, NULL },
716 { NULL, NULL, NULL },
717 { NULL, NULL, NULL },
718 { NULL, NULL, NULL },
719 { NULL, NULL, NULL },
720 { NULL, NULL, NULL },
721 { NULL, NULL, NULL },
722 { NULL, NULL, NULL },
723 { NULL, NULL, NULL },
724 { NULL, NULL, NULL },
725 { NULL, NULL, NULL },
726 { NULL, NULL, NULL },
727 { NULL, NULL, NULL },
728 { NULL, NULL, NULL },
729 { NULL, NULL, NULL },
730 { NULL, NULL, NULL },
731 { NULL, NULL, NULL },
732 { NULL, NULL, NULL },
733 { NULL, NULL, NULL }
734};
735static const Opcode_table iop_SPECIAL = { 0, 63, iop_SPECIAL_entries };
736static const Opcode_table_entry ee_SPECIAL_entries[] =
737{
738 { "sll", NULL, &Rdrtshamt },
739 { NULL, NULL, NULL },
740 { "srl", NULL, &Rdrtshamt },
741 { "sra", NULL, &Rdrtshamt },
742 { "sllv", NULL, &Rdrtrs },
743 { NULL, NULL, NULL },
744 { "srlv", NULL, &Rdrtrs },
745 { "srav", NULL, &Rdrtrs },
746 { "jr", NULL, &Rs },
747 { "jalr", NULL, &Rdrs },
748 { "movz", NULL, &Rdrtrs },
749 { "movn", NULL, &Rdrtrs },
750 { "syscall", NULL, &Code20 },
751 { "break", NULL, &Code20 },
752 { NULL, NULL, NULL },
753 { "sync", NULL, NULL },
754 { "mfhi", NULL, &Rd },
755 { "mthi", NULL, &Rs },
756 { "mflo", NULL, &Rd },
757 { "mtlo", NULL, &Rs },
758 { "dsllv", NULL, &Rdrtrs },
759 { NULL, NULL, NULL },
760 { "dsrlv", NULL, &Rdrtrs },
761 { "dsrav", NULL, &Rdrtrs },
762 { "mult", NULL, &Rsrt },
763 { "multu", NULL, &Rsrt },
764 { "div", NULL, &Rsrt },
765 { "divu", NULL, &Rsrt },
766 { NULL, NULL, NULL },
767 { NULL, NULL, NULL },
768 { NULL, NULL, NULL },
769 { NULL, NULL, NULL },
770 { "add", NULL, &Rdrsrt },
771 { "addu", NULL, &Rdrsrt },
772 { "sub", NULL, &Rdrsrt },
773 { "subu", NULL, &Rdrsrt },
774 { "and", NULL, &Rdrsrt },
775 { "or", NULL, &Rdrsrt },
776 { "xor", NULL, &Rdrsrt },
777 { "nor", NULL, &Rdrsrt },
778 { "mfsa", NULL, &Rd },
779 { "mtsa", NULL, &Rs },
780 { "slt", NULL, &Rdrsrt },
781 { "sltu", NULL, &Rdrsrt },
782 { "dadd", NULL, &Rdrsrt },
783 { "daddu", NULL, &Rdrsrt },
784 { "dsub", NULL, &Rdrsrt },
785 { "dsubu", NULL, &Rdrsrt },
786 { "tge", NULL, &Rsrt },
787 { "tgeu", NULL, &Rsrt },
788 { "tlt", NULL, &Rsrt },
789 { "tltu", NULL, &Rsrt },
790 { "teq", NULL, &Rsrt },
791 { NULL, NULL, NULL },
792 { "tne", NULL, &Rsrt },
793 { NULL, NULL, NULL },
794 { "dsll", NULL, &Rdrtshamt },
795 { NULL, NULL, NULL },
796 { "dsrl", NULL, &Rdrtshamt },
797 { "dsra", NULL, &Rdrtshamt },
798 { "dsll32", NULL, &Rdrtshamt },
799 { NULL, NULL, NULL },
800 { "dsrl32", NULL, &Rdrtshamt },
801 { "dsra32", NULL, &Rdrtshamt }
802};
803static const Opcode_table ee_SPECIAL = { 0, 63, ee_SPECIAL_entries };
804static const Opcode_table_entry BCOND_entries[] =
805{
806 { "bltz", NULL, &Rsbroff },
807 { "bgez", NULL, &Rsbroff },
808 { NULL, NULL, NULL },
809 { NULL, NULL, NULL },
810 { NULL, NULL, NULL },
811 { NULL, NULL, NULL },
812 { NULL, NULL, NULL },
813 { NULL, NULL, NULL },
814 { NULL, NULL, NULL },
815 { NULL, NULL, NULL },
816 { NULL, NULL, NULL },
817 { NULL, NULL, NULL },
818 { NULL, NULL, NULL },
819 { NULL, NULL, NULL },
820 { NULL, NULL, NULL },
821 { NULL, NULL, NULL },
822 { "bltzal", NULL, &Rsbroff },
823 { "bgezal", NULL, &Rsbroff },
824 { NULL, NULL, NULL },
825 { NULL, NULL, NULL },
826 { NULL, NULL, NULL },
827 { NULL, NULL, NULL },
828 { NULL, NULL, NULL },
829 { NULL, NULL, NULL },
830 { NULL, NULL, NULL },
831 { NULL, NULL, NULL },
832 { NULL, NULL, NULL },
833 { NULL, NULL, NULL },
834 { NULL, NULL, NULL },
835 { NULL, NULL, NULL },
836 { NULL, NULL, NULL },
837 { NULL, NULL, NULL }
838};
839static const Opcode_table BCOND = { 16, 31, BCOND_entries };
840static const Opcode_table_entry ee_REGIMM_entries[] =
841{
842 { "bltz", NULL, &Rsbroff },
843 { "bgez", NULL, &Rsbroff },
844 { "bltzl", NULL, &Rsbroff },
845 { "bgezl", NULL, &Rsbroff },
846 { NULL, NULL, NULL },
847 { NULL, NULL, NULL },
848 { NULL, NULL, NULL },
849 { NULL, NULL, NULL },
850 { "tgei", NULL, &Rsseimm },
851 { "tgeiu", NULL, &Rsseimm },
852 { "tlti", NULL, &Rsseimm },
853 { "tltiu", NULL, &Rsseimm },
854 { "teqi", NULL, &Rsseimm },
855 { NULL, NULL, NULL },
856 { "tnei", NULL, &Rsseimm },
857 { NULL, NULL, NULL },
858 { "bltzal", NULL, &Rsbroff },
859 { "bgezal", NULL, &Rsbroff },
860 { "bltzall", NULL, &Rsbroff },
861 { "bgezall", NULL, &Rsbroff },
862 { NULL, NULL, NULL },
863 { NULL, NULL, NULL },
864 { NULL, NULL, NULL },
865 { NULL, NULL, NULL },
866 { "mtsab", NULL, &Rsseimm },
867 { "mtsah", NULL, &Rsseimm },
868 { NULL, NULL, NULL },
869 { NULL, NULL, NULL },
870 { NULL, NULL, NULL },
871 { NULL, NULL, NULL },
872 { NULL, NULL, NULL },
873 { NULL, NULL, NULL }
874};
875static const Opcode_table ee_REGIMM = { 16, 31, ee_REGIMM_entries };
876static const Opcode_table_entry iop_COP0CO_entries[] =
877{
878 { NULL, NULL, NULL },
879 { "tlbr", NULL, NULL },
880 { "tlbwi", NULL, NULL },
881 { NULL, NULL, NULL },
882 { NULL, NULL, NULL },
883 { NULL, NULL, NULL },
884 { "tlbwr", NULL, NULL },
885 { NULL, NULL, NULL },
886 { "tlbp", NULL, NULL },
887 { NULL, NULL, NULL },
888 { NULL, NULL, NULL },
889 { NULL, NULL, NULL },
890 { NULL, NULL, NULL },
891 { NULL, NULL, NULL },
892 { NULL, NULL, NULL },
893 { NULL, NULL, NULL },
894 { "rfe", NULL, NULL },
895 { NULL, NULL, NULL },
896 { NULL, NULL, NULL },
897 { NULL, NULL, NULL },
898 { NULL, NULL, NULL },
899 { NULL, NULL, NULL },
900 { NULL, NULL, NULL },
901 { NULL, NULL, NULL },
902 { NULL, NULL, NULL },
903 { NULL, NULL, NULL },
904 { NULL, NULL, NULL },
905 { NULL, NULL, NULL },
906 { NULL, NULL, NULL },
907 { NULL, NULL, NULL },
908 { NULL, NULL, NULL },
909 { NULL, NULL, NULL },
910 { NULL, NULL, NULL },
911 { NULL, NULL, NULL },
912 { NULL, NULL, NULL },
913 { NULL, NULL, NULL },
914 { NULL, NULL, NULL },
915 { NULL, NULL, NULL },
916 { NULL, NULL, NULL },
917 { NULL, NULL, NULL },
918 { NULL, NULL, NULL },
919 { NULL, NULL, NULL },
920 { NULL, NULL, NULL },
921 { NULL, NULL, NULL },
922 { NULL, NULL, NULL },
923 { NULL, NULL, NULL },
924 { NULL, NULL, NULL },
925 { NULL, NULL, NULL },
926 { NULL, NULL, NULL },
927 { NULL, NULL, NULL },
928 { NULL, NULL, NULL },
929 { NULL, NULL, NULL },
930 { NULL, NULL, NULL },
931 { NULL, NULL, NULL },
932 { NULL, NULL, NULL },
933 { NULL, NULL, NULL },
934 { NULL, NULL, NULL },
935 { NULL, NULL, NULL },
936 { NULL, NULL, NULL },
937 { NULL, NULL, NULL },
938 { NULL, NULL, NULL },
939 { NULL, NULL, NULL },
940 { NULL, NULL, NULL },
941 { NULL, NULL, NULL }
942};
943static const Opcode_table iop_COP0CO = { 0, 63, iop_COP0CO_entries };
944static const Opcode_table_entry ee_COP0CO_entries[] =
945{
946 { NULL, NULL, NULL },
947 { "tlbr", NULL, NULL },
948 { "tlbwi", NULL, NULL },
949 { NULL, NULL, NULL },
950 { NULL, NULL, NULL },
951 { NULL, NULL, NULL },
952 { "tlbwr", NULL, NULL },
953 { NULL, NULL, NULL },
954 { "tlbp", NULL, NULL },
955 { NULL, NULL, NULL },
956 { NULL, NULL, NULL },
957 { NULL, NULL, NULL },
958 { NULL, NULL, NULL },
959 { NULL, NULL, NULL },
960 { NULL, NULL, NULL },
961 { NULL, NULL, NULL },
962 { NULL, NULL, NULL },
963 { NULL, NULL, NULL },
964 { NULL, NULL, NULL },
965 { NULL, NULL, NULL },
966 { NULL, NULL, NULL },
967 { NULL, NULL, NULL },
968 { NULL, NULL, NULL },
969 { NULL, NULL, NULL },
970 { "eret", NULL, NULL },
971 { NULL, NULL, NULL },
972 { NULL, NULL, NULL },
973 { NULL, NULL, NULL },
974 { NULL, NULL, NULL },
975 { NULL, NULL, NULL },
976 { NULL, NULL, NULL },
977 { NULL, NULL, NULL },
978 { NULL, NULL, NULL },
979 { NULL, NULL, NULL },
980 { NULL, NULL, NULL },
981 { NULL, NULL, NULL },
982 { NULL, NULL, NULL },
983 { NULL, NULL, NULL },
984 { NULL, NULL, NULL },
985 { NULL, NULL, NULL },
986 { NULL, NULL, NULL },
987 { NULL, NULL, NULL },
988 { NULL, NULL, NULL },
989 { NULL, NULL, NULL },
990 { NULL, NULL, NULL },
991 { NULL, NULL, NULL },
992 { NULL, NULL, NULL },
993 { NULL, NULL, NULL },
994 { NULL, NULL, NULL },
995 { NULL, NULL, NULL },
996 { NULL, NULL, NULL },
997 { NULL, NULL, NULL },
998 { NULL, NULL, NULL },
999 { NULL, NULL, NULL },
1000 { NULL, NULL, NULL },
1001 { NULL, NULL, NULL },
1002 { "ei", NULL, NULL },
1003 { "di", NULL, NULL },
1004 { NULL, NULL, NULL },
1005 { NULL, NULL, NULL },
1006 { NULL, NULL, NULL },
1007 { NULL, NULL, NULL },
1008 { NULL, NULL, NULL },
1009 { NULL, NULL, NULL }
1010};
1011static const Opcode_table ee_COP0CO = { 0, 63, ee_COP0CO_entries };
1012static const Opcode_table_entry iop_COP0_entries[] =
1013{
1014 { "mfc0", NULL, &Rtc0rd_iop },
1015 { NULL, NULL, NULL },
1016 { "cfc0", NULL, &Rtc0rd_iop },
1017 { NULL, NULL, NULL },
1018 { "mtc0", NULL, &Rtc0rd_iop },
1019 { NULL, NULL, NULL },
1020 { "ctc0", NULL, &Rtc0rd_iop },
1021 { NULL, NULL, NULL },
1022 { "cop0", NULL, &Bcft },
1023 { NULL, NULL, NULL },
1024 { NULL, NULL, NULL },
1025 { NULL, NULL, NULL },
1026 { "cop0", NULL, &Bcft },
1027 { NULL, NULL, NULL },
1028 { NULL, NULL, NULL },
1029 { NULL, NULL, NULL },
1030 { NULL, &iop_COP0CO, NULL },
1031 { NULL, &iop_COP0CO, NULL },
1032 { NULL, &iop_COP0CO, NULL },
1033 { NULL, &iop_COP0CO, NULL },
1034 { NULL, &iop_COP0CO, NULL },
1035 { NULL, &iop_COP0CO, NULL },
1036 { NULL, &iop_COP0CO, NULL },
1037 { NULL, &iop_COP0CO, NULL },
1038 { NULL, &iop_COP0CO, NULL },
1039 { NULL, &iop_COP0CO, NULL },
1040 { NULL, &iop_COP0CO, NULL },
1041 { NULL, &iop_COP0CO, NULL },
1042 { NULL, &iop_COP0CO, NULL },
1043 { NULL, &iop_COP0CO, NULL },
1044 { NULL, &iop_COP0CO, NULL },
1045 { NULL, &iop_COP0CO, NULL }
1046};
1047static const Opcode_table iop_COP0 = { 21, 31, iop_COP0_entries };
1048static const Opcode_table_entry ee_COP0_entries[] =
1049{
1050 { "mfc0", NULL, &Rtc0rd_ee },
1051 { NULL, NULL, NULL },
1052 { "cfc0", NULL, &Rtc0rd_ee },
1053 { NULL, NULL, NULL },
1054 { "mtc0", NULL, &Rtc0rd_ee },
1055 { NULL, NULL, NULL },
1056 { "ctc0", NULL, &Rtc0rd_ee },
1057 { NULL, NULL, NULL },
1058 { "cop0", NULL, &Bcft },
1059 { NULL, NULL, NULL },
1060 { NULL, NULL, NULL },
1061 { NULL, NULL, NULL },
1062 { "cop0", NULL, &Bcft },
1063 { NULL, NULL, NULL },
1064 { NULL, NULL, NULL },
1065 { NULL, NULL, NULL },
1066 { NULL, &ee_COP0CO, NULL },
1067 { NULL, &ee_COP0CO, NULL },
1068 { NULL, &ee_COP0CO, NULL },
1069 { NULL, &ee_COP0CO, NULL },
1070 { NULL, &ee_COP0CO, NULL },
1071 { NULL, &ee_COP0CO, NULL },
1072 { NULL, &ee_COP0CO, NULL },
1073 { NULL, &ee_COP0CO, NULL },
1074 { NULL, &ee_COP0CO, NULL },
1075 { NULL, &ee_COP0CO, NULL },
1076 { NULL, &ee_COP0CO, NULL },
1077 { NULL, &ee_COP0CO, NULL },
1078 { NULL, &ee_COP0CO, NULL },
1079 { NULL, &ee_COP0CO, NULL },
1080 { NULL, &ee_COP0CO, NULL },
1081 { NULL, &ee_COP0CO, NULL }
1082};
1083static const Opcode_table ee_COP0 = { 21, 31, ee_COP0_entries };
1084static const Opcode_table_entry ee_COP1CO_entries[] =
1085{
1086 { "add.s", NULL, &Fdfsft },
1087 { "sub.s", NULL, &Fdfsft },
1088 { "mul.s", NULL, &Fdfsft },
1089 { "div.s", NULL, &Fdfsft },
1090 { "sqrt.s", NULL, &Fdfs },
1091 { "abs.s", NULL, &Fdfs },
1092 { "mov.s", NULL, &Fdfs },
1093 { "neg.s", NULL, &Fdfs },
1094 { NULL, NULL, NULL },
1095 { NULL, NULL, NULL },
1096 { NULL, NULL, NULL },
1097 { NULL, NULL, NULL },
1098 { NULL, NULL, NULL },
1099 { NULL, NULL, NULL },
1100 { NULL, NULL, NULL },
1101 { NULL, NULL, NULL },
1102 { NULL, NULL, NULL },
1103 { NULL, NULL, NULL },
1104 { NULL, NULL, NULL },
1105 { NULL, NULL, NULL },
1106 { NULL, NULL, NULL },
1107 { NULL, NULL, NULL },
1108 { "rsqrt.s", NULL, &Fdfs },
1109 { NULL, NULL, NULL },
1110 { "adda.s", NULL, &Fsft },
1111 { "suba.s", NULL, &Fsft },
1112 { "mula.s", NULL, &Fsft },
1113 { NULL, NULL, NULL },
1114 { "madd.s", NULL, &Fdfsft },
1115 { "msub.s", NULL, &Fdfsft },
1116 { "madda.s", NULL, &Fsft },
1117 { "msuba.s", NULL, &Fsft },
1118 { "cvt", NULL, &Fdfs },
1119 { NULL, NULL, NULL },
1120 { NULL, NULL, NULL },
1121 { NULL, NULL, NULL },
1122 { "cvt", NULL, &Fdfs },
1123 { NULL, NULL, NULL },
1124 { NULL, NULL, NULL },
1125 { NULL, NULL, NULL },
1126 { "max.s", NULL, &Fdfs },
1127 { "min.s", NULL, &Fdfs },
1128 { NULL, NULL, NULL },
1129 { NULL, NULL, NULL },
1130 { NULL, NULL, NULL },
1131 { NULL, NULL, NULL },
1132 { NULL, NULL, NULL },
1133 { NULL, NULL, NULL },
1134 { "c.f.s", NULL, &Fsft },
1135 { NULL, NULL, NULL },
1136 { "c.eq.s", NULL, &Fsft },
1137 { NULL, NULL, NULL },
1138 { "c.lt.s", NULL, &Fsft },
1139 { NULL, NULL, NULL },
1140 { "c.le.s", NULL, &Fsft },
1141 { NULL, NULL, NULL },
1142 { NULL, NULL, NULL },
1143 { NULL, NULL, NULL },
1144 { NULL, NULL, NULL },
1145 { NULL, NULL, NULL },
1146 { NULL, NULL, NULL },
1147 { NULL, NULL, NULL },
1148 { NULL, NULL, NULL },
1149 { NULL, NULL, NULL }
1150};
1151static const Opcode_table ee_COP1CO = { 0, 63, ee_COP1CO_entries };
1152static const Opcode_table_entry iop_COP1_entries[] =
1153{
1154 { "mfc1", NULL, &Rtczrd },
1155 { NULL, NULL, NULL },
1156 { "cfc1", NULL, &Rtczrd },
1157 { NULL, NULL, NULL },
1158 { "mtc1", NULL, &Rtczrd },
1159 { NULL, NULL, NULL },
1160 { "ctc1", NULL, &Rtczrd },
1161 { NULL, NULL, NULL },
1162 { "cop1", NULL, &Bcft },
1163 { NULL, NULL, NULL },
1164 { NULL, NULL, NULL },
1165 { NULL, NULL, NULL },
1166 { "cop1", NULL, &Bcft },
1167 { NULL, NULL, NULL },
1168 { NULL, NULL, NULL },
1169 { NULL, NULL, NULL },
1170 { "cop1", NULL, &Cofun },
1171 { "cop1", NULL, &Cofun },
1172 { "cop1", NULL, &Cofun },
1173 { "cop1", NULL, &Cofun },
1174 { "cop1", NULL, &Cofun },
1175 { "cop1", NULL, &Cofun },
1176 { "cop1", NULL, &Cofun },
1177 { "cop1", NULL, &Cofun },
1178 { "cop1", NULL, &Cofun },
1179 { "cop1", NULL, &Cofun },
1180 { "cop1", NULL, &Cofun },
1181 { "cop1", NULL, &Cofun },
1182 { "cop1", NULL, &Cofun },
1183 { "cop1", NULL, &Cofun },
1184 { "cop1", NULL, &Cofun },
1185 { "cop1", NULL, &Cofun }
1186};
1187static const Opcode_table iop_COP1 = { 21, 31, iop_COP1_entries };
1188static const Opcode_table_entry ee_COP1_entries[] =
1189{
1190 { "mfc1", NULL, &Rtczfs },
1191 { NULL, NULL, NULL },
1192 { "cfc1", NULL, &Rtczfs },
1193 { NULL, NULL, NULL },
1194 { "mtc1", NULL, &Rtczfs },
1195 { NULL, NULL, NULL },
1196 { "ctc1", NULL, &Rtczfs },
1197 { NULL, NULL, NULL },
1198 { "cop1", NULL, &Bcft },
1199 { NULL, NULL, NULL },
1200 { NULL, NULL, NULL },
1201 { NULL, NULL, NULL },
1202 { "cop1", NULL, &Bcft },
1203 { NULL, NULL, NULL },
1204 { NULL, NULL, NULL },
1205 { NULL, NULL, NULL },
1206 { NULL, &ee_COP1CO, NULL },
1207 { NULL, &ee_COP1CO, NULL },
1208 { NULL, &ee_COP1CO, NULL },
1209 { NULL, &ee_COP1CO, NULL },
1210 { NULL, &ee_COP1CO, NULL },
1211 { NULL, &ee_COP1CO, NULL },
1212 { NULL, &ee_COP1CO, NULL },
1213 { NULL, &ee_COP1CO, NULL },
1214 { NULL, &ee_COP1CO, NULL },
1215 { NULL, &ee_COP1CO, NULL },
1216 { NULL, &ee_COP1CO, NULL },
1217 { NULL, &ee_COP1CO, NULL },
1218 { NULL, &ee_COP1CO, NULL },
1219 { NULL, &ee_COP1CO, NULL },
1220 { NULL, &ee_COP1CO, NULL },
1221 { NULL, &ee_COP1CO, NULL }
1222};
1223static const Opcode_table ee_COP1 = { 21, 31, ee_COP1_entries };
1224static const Opcode_table_entry iop_COP2_entries[] =
1225{
1226 { "mfc2", NULL, &Rtczrd },
1227 { NULL, NULL, NULL },
1228 { "cfc2", NULL, &Rtczrd },
1229 { NULL, NULL, NULL },
1230 { "mtc2", NULL, &Rtczrd },
1231 { NULL, NULL, NULL },
1232 { "ctc2", NULL, &Rtczrd },
1233 { NULL, NULL, NULL },
1234 { "cop2", NULL, &Bcft },
1235 { NULL, NULL, NULL },
1236 { NULL, NULL, NULL },
1237 { NULL, NULL, NULL },
1238 { "cop2", NULL, &Bcft },
1239 { NULL, NULL, NULL },
1240 { NULL, NULL, NULL },
1241 { NULL, NULL, NULL },
1242 { "cop2", NULL, &Cofun },
1243 { "cop2", NULL, &Cofun },
1244 { "cop2", NULL, &Cofun },
1245 { "cop2", NULL, &Cofun },
1246 { "cop2", NULL, &Cofun },
1247 { "cop2", NULL, &Cofun },
1248 { "cop2", NULL, &Cofun },
1249 { "cop2", NULL, &Cofun },
1250 { "cop2", NULL, &Cofun },
1251 { "cop2", NULL, &Cofun },
1252 { "cop2", NULL, &Cofun },
1253 { "cop2", NULL, &Cofun },
1254 { "cop2", NULL, &Cofun },
1255 { "cop2", NULL, &Cofun },
1256 { "cop2", NULL, &Cofun },
1257 { "cop2", NULL, &Cofun }
1258};
1259static const Opcode_table iop_COP2 = { 21, 31, iop_COP2_entries };
1260static const Opcode_table_entry ee_COP2_entries[] =
1261{
1262 { "mfc2", NULL, &Rtczrd },
1263 { "qmfc2", NULL, &Rtczrd },
1264 { "cfc2", NULL, &Rtczrd },
1265 { NULL, NULL, NULL },
1266 { "mtc2", NULL, &Rtczrd },
1267 { "qmtc2", NULL, &Rtczrd },
1268 { "ctc2", NULL, &Rtczrd },
1269 { NULL, NULL, NULL },
1270 { "cop2", NULL, &Bcft },
1271 { NULL, NULL, NULL },
1272 { NULL, NULL, NULL },
1273 { NULL, NULL, NULL },
1274 { "cop2", NULL, &Bcft },
1275 { NULL, NULL, NULL },
1276 { NULL, NULL, NULL },
1277 { NULL, NULL, NULL },
1278 { "cop2", NULL, &Cofun },
1279 { "cop2", NULL, &Cofun },
1280 { "cop2", NULL, &Cofun },
1281 { "cop2", NULL, &Cofun },
1282 { "cop2", NULL, &Cofun },
1283 { "cop2", NULL, &Cofun },
1284 { "cop2", NULL, &Cofun },
1285 { "cop2", NULL, &Cofun },
1286 { "cop2", NULL, &Cofun },
1287 { "cop2", NULL, &Cofun },
1288 { "cop2", NULL, &Cofun },
1289 { "cop2", NULL, &Cofun },
1290 { "cop2", NULL, &Cofun },
1291 { "cop2", NULL, &Cofun },
1292 { "cop2", NULL, &Cofun },
1293 { "cop2", NULL, &Cofun }
1294};
1295static const Opcode_table ee_COP2 = { 21, 31, ee_COP2_entries };
1296static const Opcode_table_entry COP3_entries[] =
1297{
1298 { "mfc3", NULL, &Rtczrd },
1299 { NULL, NULL, NULL },
1300 { "cfc3", NULL, &Rtczrd },
1301 { NULL, NULL, NULL },
1302 { "mtc3", NULL, &Rtczrd },
1303 { NULL, NULL, NULL },
1304 { "ctc3", NULL, &Rtczrd },
1305 { NULL, NULL, NULL },
1306 { "cop3", NULL, &Bcft },
1307 { NULL, NULL, NULL },
1308 { NULL, NULL, NULL },
1309 { NULL, NULL, NULL },
1310 { "cop3", NULL, &Bcft },
1311 { NULL, NULL, NULL },
1312 { NULL, NULL, NULL },
1313 { NULL, NULL, NULL },
1314 { "cop3", NULL, &Cofun },
1315 { "cop3", NULL, &Cofun },
1316 { "cop3", NULL, &Cofun },
1317 { "cop3", NULL, &Cofun },
1318 { "cop3", NULL, &Cofun },
1319 { "cop3", NULL, &Cofun },
1320 { "cop3", NULL, &Cofun },
1321 { "cop3", NULL, &Cofun },
1322 { "cop3", NULL, &Cofun },
1323 { "cop3", NULL, &Cofun },
1324 { "cop3", NULL, &Cofun },
1325 { "cop3", NULL, &Cofun },
1326 { "cop3", NULL, &Cofun },
1327 { "cop3", NULL, &Cofun },
1328 { "cop3", NULL, &Cofun },
1329 { "cop3", NULL, &Cofun }
1330};
1331static const Opcode_table COP3 = { 21, 31, COP3_entries };
1332static const Opcode_table_entry iop_opcode_root_table_entries[] =
1333{
1334 { NULL, &iop_SPECIAL, NULL },
1335 { NULL, &BCOND, NULL },
1336 { "j", NULL, &Jtarget },
1337 { "jal", NULL, &Jtarget },
1338 { "beq", NULL, &Rsrtbroff },
1339 { "bne", NULL, &Rsrtbroff },
1340 { "blez", NULL, &Rsbroff },
1341 { "bgtz", NULL, &Rsbroff },
1342 { "addi", NULL, &Rtrsseimm },
1343 { "addiu", NULL, &Rtrsseimm },
1344 { "slti", NULL, &Rtrsseimm },
1345 { "sltiu", NULL, &Rtrsseimm },
1346 { "andi", NULL, &Rtrsimm },
1347 { "ori", NULL, &Rtrsimm },
1348 { "xori", NULL, &Rtrsimm },
1349 { "lui", NULL, &Rtimm },
1350 { NULL, &iop_COP0, NULL },
1351 { NULL, &iop_COP1, NULL },
1352 { NULL, &iop_COP2, NULL },
1353 { NULL, &COP3, NULL },
1354 { NULL, NULL, NULL },
1355 { NULL, NULL, NULL },
1356 { NULL, NULL, NULL },
1357 { NULL, NULL, NULL },
1358 { NULL, NULL, NULL },
1359 { NULL, NULL, NULL },
1360 { NULL, NULL, NULL },
1361 { NULL, NULL, NULL },
1362 { NULL, NULL, NULL },
1363 { NULL, NULL, NULL },
1364 { NULL, NULL, NULL },
1365 { NULL, NULL, NULL },
1366 { "lb", NULL, &Rtoffbase },
1367 { "lh", NULL, &Rtoffbase },
1368 { "lwl", NULL, &Rtoffbase },
1369 { "lw", NULL, &Rtoffbase },
1370 { "lbu", NULL, &Rtoffbase },
1371 { "lhu", NULL, &Rtoffbase },
1372 { "lwr", NULL, &Rtoffbase },
1373 { NULL, NULL, NULL },
1374 { "sb", NULL, &Rtoffbase },
1375 { "sh", NULL, &Rtoffbase },
1376 { "swl", NULL, &Rtoffbase },
1377 { "sw", NULL, &Rtoffbase },
1378 { NULL, NULL, NULL },
1379 { NULL, NULL, NULL },
1380 { "swr", NULL, &Rtoffbase },
1381 { NULL, NULL, NULL },
1382 { "lwc0", NULL, &Rtoffbase },
1383 { "lwc1", NULL, &Rtoffbase },
1384 { "lwc2", NULL, &Rtoffbase },
1385 { "lwc3", NULL, &Rtoffbase },
1386 { NULL, NULL, NULL },
1387 { NULL, NULL, NULL },
1388 { NULL, NULL, NULL },
1389 { NULL, NULL, NULL },
1390 { "swc0", NULL, &Rtoffbase },
1391 { "swc1", NULL, &Rtoffbase },
1392 { "swc2", NULL, &Rtoffbase },
1393 { "swc3", NULL, &Rtoffbase },
1394 { NULL, NULL, NULL },
1395 { NULL, NULL, NULL },
1396 { NULL, NULL, NULL },
1397 { NULL, NULL, NULL }
1398};
1399static const Opcode_table_entry ee_opcode_root_table_entries[] =
1400{
1401 { NULL, &ee_SPECIAL, NULL },
1402 { NULL, &ee_REGIMM, NULL },
1403 { "j", NULL, &Jtarget },
1404 { "jal", NULL, &Jtarget },
1405 { "beq", NULL, &Rsrtbroff },
1406 { "bne", NULL, &Rsrtbroff },
1407 { "blez", NULL, &Rsbroff },
1408 { "bgtz", NULL, &Rsbroff },
1409 { "addi", NULL, &Rtrsseimm },
1410 { "addiu", NULL, &Rtrsseimm },
1411 { "slti", NULL, &Rtrsseimm },
1412 { "sltiu", NULL, &Rtrsseimm },
1413 { "andi", NULL, &Rtrsimm },
1414 { "ori", NULL, &Rtrsimm },
1415 { "xori", NULL, &Rtrsimm },
1416 { "lui", NULL, &Rtimm },
1417 { NULL, &ee_COP0, NULL },
1418 { NULL, &ee_COP1, NULL },
1419 { NULL, &ee_COP2, NULL },
1420 { NULL, &COP3, NULL },
1421 { "beql", NULL, &Rsrtbroff },
1422 { "bnel", NULL, &Rsrtbroff },
1423 { "blezl", NULL, &Rsbroff },
1424 { "bgtzl", NULL, &Rsbroff },
1425 { "daddi", NULL, &Rtrsseimm },
1426 { "daddiu", NULL, &Rtrsseimm },
1427 { "ldl", NULL, &Rtoffbase },
1428 { "ldr", NULL, &Rtoffbase },
1429 { "mmi", NULL, NULL },
1430 { NULL, NULL, NULL },
1431 { "lq", NULL, &Rtoffbase },
1432 { "sq", NULL, &Rtoffbase },
1433 { "lb", NULL, &Rtoffbase },
1434 { "lh", NULL, &Rtoffbase },
1435 { "lwl", NULL, &Rtoffbase },
1436 { "lw", NULL, &Rtoffbase },
1437 { "lbu", NULL, &Rtoffbase },
1438 { "lhu", NULL, &Rtoffbase },
1439 { "lwr", NULL, &Rtoffbase },
1440 { NULL, NULL, NULL },
1441 { "sb", NULL, &Rtoffbase },
1442 { "sh", NULL, &Rtoffbase },
1443 { "swl", NULL, &Rtoffbase },
1444 { "sw", NULL, &Rtoffbase },
1445 { "sdl", NULL, &Rtoffbase },
1446 { "sdr", NULL, &Rtoffbase },
1447 { "swr", NULL, &Rtoffbase },
1448 { "cache", NULL, NULL },
1449 { "lwc0", NULL, &Rtoffbase },
1450 { "lwc1", NULL, &Rtoffbase },
1451 { "lwc2", NULL, &Rtoffbase },
1452 { "pref", NULL, &Rtoffbase },
1453 { NULL, NULL, NULL },
1454 { NULL, NULL, NULL },
1455 { "lqc2", NULL, &Rtoffbase },
1456 { "ld", NULL, &Rtoffbase },
1457 { "swc0", NULL, &Rtoffbase },
1458 { "swc1", NULL, &Rtoffbase },
1459 { "swc2", NULL, &Rtoffbase },
1460 { "swc3", NULL, &Rtoffbase },
1461 { NULL, NULL, NULL },
1462 { NULL, NULL, NULL },
1463 { "sqc2", NULL, &Rtoffbase },
1464 { "sd", NULL, &Rtoffbase }
1465};
1466static const Opcode_table iop_opcode_root_table = { 26, 63, iop_opcode_root_table_entries };
1467static const Opcode_table ee_opcode_root_table = { 26, 63, ee_opcode_root_table_entries };
1468static const Opcode_table * opcode_root_table = &iop_opcode_root_table;
1469// clang-format on
1470
1471void gen_asmmacro(Disasm_result *result)
1472{
1473 if ( result->data )
1474 {
1475 if (
1476 !strcmp("beq", result->mnemonic) && result->operands[0].tag == OprTag_reg && result->operands[1].tag == OprTag_reg
1477 && result->operands[1].reg == result->operands[0].reg )
1478 {
1479 strcpy(result->mnemonic, "b");
1480 result->operands[0] = result->operands[2];
1481 result->operands[1].tag = OprTag_none;
1482 }
1483 else if ( !strcmp("bgezal", result->mnemonic) && result->operands[0].tag == OprTag_reg && !result->operands[0].reg )
1484 {
1485 strcpy(result->mnemonic, "bal");
1486 result->operands[0] = result->operands[1];
1487 result->operands[1].tag = OprTag_none;
1488 }
1489 else if ( !strcmp("cvt", result->mnemonic) )
1490 {
1491 if ( ((result->data >> 21) & 0x1F) == 20 )
1492 {
1493 strcpy(result->mnemonic, "cvt.s.w");
1494 }
1495 else if ( ((result->data >> 21) & 0x1F) == 16 )
1496 {
1497 strcpy(result->mnemonic, "cvt.w.s");
1498 }
1499 }
1500 }
1501 else
1502 {
1503 strcpy(result->mnemonic, "nop");
1504 result->operands[0].tag = OprTag_none;
1505 }
1506}
1507
1508void initdisasm(int arch, int regform0, int regform1, int regform2, int regform3)
1509{
1510 switch ( arch )
1511 {
1512 case 1:
1513 opcode_root_table = &iop_opcode_root_table;
1514 break;
1515 case 2:
1516 opcode_root_table = &ee_opcode_root_table;
1517 break;
1518 default:
1519 break;
1520 }
1521 if ( regform0 != -1 )
1522 {
1523 if ( !regform0 || regform0 == 1 )
1524 {
1525 regnmsw[0] = regform0;
1526 }
1527 if ( !regform1 || regform1 == 1 )
1528 {
1529 regnmsw[1] = regform0;
1530 }
1531 if ( !regform2 || regform2 == 1 )
1532 {
1533 regnmsw[2] = regform0;
1534 }
1535 if ( !regform3 || regform3 == 1 )
1536 {
1537 regnmsw[3] = regform3;
1538 }
1539 }
1540}
1541
1542Disasm_result *disassemble(unsigned int addr, unsigned int data)
1543{
1544 Disasm_result *v3;
1545 const Opcode_table_entry *op;
1546 const Opcode_table *optable;
1547
1548 optable = opcode_root_table;
1549 v3 = (Disasm_result *)calloc(1, sizeof(Disasm_result));
1550 for ( ;; )
1551 {
1552 op = &optable->entries[(data >> optable->bit_pos) & optable->bit_mask];
1553 if ( !op->subtable )
1554 {
1555 break;
1556 }
1557 optable = op->subtable;
1558 }
1559 v3->addr = addr;
1560 v3->data = data;
1561 if ( op->mnemonic )
1562 {
1563 strcpy(v3->mnemonic, op->mnemonic);
1564 if ( op->opfunc )
1565 {
1566 op->opfunc(v3);
1567 }
1568 }
1569 return v3;
1570}
1571
1572void shex(char *buf, unsigned int data)
1573{
1574 if ( (data & 0x80000000) != 0 )
1575 {
1576 sprintf(buf, "-0x%x", -data);
1577 }
1578 else
1579 {
1580 sprintf(buf, "0x%x", data);
1581 }
1582}
1583
1584void format_operand(const Operand *opr, char *buf)
1585{
1586 switch ( opr->tag )
1587 {
1588 case OprTag_reg:
1589 strcpy(buf, REGNAME[regnmsw[0]][opr->reg]);
1590 break;
1591 case OprTag_c0reg_iop:
1592 strcpy(buf, REGC0_iop[regnmsw[0]][opr->reg]);
1593 break;
1594 case OprTag_c0reg_ee:
1595 strcpy(buf, REGC0_ee[regnmsw[0]][opr->reg]);
1596 break;
1597 case OprTag_czreg:
1598 sprintf(buf, "$%d", opr->reg);
1599 break;
1600 case OprTag_c1reg:
1601 strcpy(buf, REGC1[regnmsw[1]][opr->reg]);
1602 break;
1603 case OprTag_imm:
1604 case OprTag_jtarget:
1605 shex(buf, opr->data);
1606 break;
1607 case OprTag_shamt:
1608 sprintf(buf, "%d", (int)(opr->data));
1609 break;
1610 case OprTag_regoffset:
1611 shex(buf, opr->data);
1612 sprintf(&buf[strlen(buf)], "(%s)", REGNAME[regnmsw[0]][opr->reg]);
1613 break;
1614 case OprTag_code20:
1615 case OprTag_code25:
1616 sprintf(buf, "0x%x", opr->data);
1617 break;
1618 default:
1619 sprintf(buf, "?type?(0x%x)", opr->tag);
1620 fprintf(stderr, "Panic unknown oprand type 0x%x\n", opr->tag);
1621 break;
1622 }
1623}
1624
1625void format_disasm(Disasm_result *dis, char *buf)
1626{
1627 char *s;
1628
1629 sprintf(buf, "%08x: %08x", dis->addr, dis->data);
1630 s = &buf[strlen(buf)];
1631 if ( dis->mnemonic[0] )
1632 {
1633 int i;
1634 char *sa;
1635
1636 sprintf(s, " %-8s", dis->mnemonic);
1637 sa = &s[strlen(s)];
1638 for ( i = 0; dis->operands[i].tag; i += 1 )
1639 {
1640 format_operand(&dis->operands[i], sa);
1641 if ( dis->operands[i + 1].tag )
1642 {
1643 strcat(sa, ", ");
1644 }
1645 sa += strlen(sa);
1646 }
1647 }
1648}
Definition mipsdis.c:349