4 * SH4 CPU definition and disassembly functions
6 * Copyright (c) 2005 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
23 #define UNIMP(ir) snprintf( buf, len, "??? " )
26 const struct reg_desc_struct sh4_reg_map[] =
27 { {"R0", REG_INT, &sh4r.r[0]}, {"R1", REG_INT, &sh4r.r[1]},
28 {"R2", REG_INT, &sh4r.r[2]}, {"R3", REG_INT, &sh4r.r[3]},
29 {"R4", REG_INT, &sh4r.r[4]}, {"R5", REG_INT, &sh4r.r[5]},
30 {"R6", REG_INT, &sh4r.r[6]}, {"R7", REG_INT, &sh4r.r[7]},
31 {"R8", REG_INT, &sh4r.r[8]}, {"R9", REG_INT, &sh4r.r[9]},
32 {"R10",REG_INT, &sh4r.r[10]}, {"R11",REG_INT, &sh4r.r[11]},
33 {"R12",REG_INT, &sh4r.r[12]}, {"R13",REG_INT, &sh4r.r[13]},
34 {"R14",REG_INT, &sh4r.r[14]}, {"R15",REG_INT, &sh4r.r[15]},
35 {"SR", REG_INT, &sh4r.sr}, {"GBR", REG_INT, &sh4r.gbr},
36 {"SSR",REG_INT, &sh4r.ssr}, {"SPC", REG_INT, &sh4r.spc},
37 {"SGR",REG_INT, &sh4r.sgr}, {"DBR", REG_INT, &sh4r.dbr},
38 {"VBR",REG_INT, &sh4r.vbr},
39 {"PC", REG_INT, &sh4r.pc}, {"PR", REG_INT, &sh4r.pr},
40 {"MACL",REG_INT, &sh4r.mac},{"MACH",REG_INT, ((uint32_t *)&sh4r.mac)+1},
41 {"FPUL", REG_INT, &sh4r.fpul}, {"FPSCR", REG_INT, &sh4r.fpscr},
45 const struct cpu_desc_struct sh4_cpu_desc =
46 { "SH4", sh4_disasm_instruction, sh4_execute_instruction, mem_has_page,
47 sh4_set_breakpoint, sh4_clear_breakpoint, sh4_get_breakpoint, 2,
48 (char *)&sh4r, sizeof(sh4r), sh4_reg_map,
51 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
53 uint16_t ir = sh4_read_word(pc);
55 #define UNDEF(ir) snprintf( buf, len, "???? " );
56 #define RN(ir) ((ir&0x0F00)>>8)
57 #define RN_BANK(ir) ((ir&0x0070)>>4)
58 #define RM(ir) ((ir&0x00F0)>>4)
59 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */
60 #define DISP8(ir) (ir&0x00FF)
61 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
62 #define UIMM8(ir) (ir&0x00FF)
63 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
64 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
65 #define FVN(ir) ((ir&0x0C00)>>10)
66 #define FVM(ir) ((ir&0x0300)>>8)
68 sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );
70 switch( (ir&0xF000) >> 12 ) {
74 switch( (ir&0x80) >> 7 ) {
76 switch( (ir&0x70) >> 4 ) {
79 uint32_t Rn = ((ir>>8)&0xF);
80 snprintf( buf, len, "STC SR, R%d", Rn );
85 uint32_t Rn = ((ir>>8)&0xF);
86 snprintf( buf, len, "STC GBR, R%d", Rn );
91 uint32_t Rn = ((ir>>8)&0xF);
92 snprintf( buf, len, "STC VBR, R%d", Rn );
97 uint32_t Rn = ((ir>>8)&0xF);
98 snprintf( buf, len, "STC SSR, R%d", Rn );
103 uint32_t Rn = ((ir>>8)&0xF);
104 snprintf( buf, len, "STC SPC, R%d", Rn );
113 { /* STC Rm_BANK, Rn */
114 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
115 snprintf( buf, len, "STC R%d_BANK, R%d", Rm_BANK, Rn );
121 switch( (ir&0xF0) >> 4 ) {
124 uint32_t Rn = ((ir>>8)&0xF);
125 snprintf( buf, len, "BSRF R%d", Rn );
130 uint32_t Rn = ((ir>>8)&0xF);
131 snprintf( buf, len, "BRAF R%d", Rn );
136 uint32_t Rn = ((ir>>8)&0xF);
137 snprintf( buf, len, "PREF R%d", Rn );
142 uint32_t Rn = ((ir>>8)&0xF);
143 snprintf( buf, len, "OCBI @R%d", Rn );
148 uint32_t Rn = ((ir>>8)&0xF);
149 snprintf( buf, len, "OCBP @R%d", Rn );
154 uint32_t Rn = ((ir>>8)&0xF);
155 snprintf( buf, len, "OCBWB @R%d", Rn );
159 { /* MOVCA.L R0, @Rn */
160 uint32_t Rn = ((ir>>8)&0xF);
161 snprintf( buf, len, "MOVCA.L R0, @R%d", Rn );
170 { /* MOV.B Rm, @(R0, Rn) */
171 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
172 snprintf( buf, len, "MOV.B R%d, @(R0, R%d)", Rm, Rn );
176 { /* MOV.W Rm, @(R0, Rn) */
177 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
178 snprintf( buf, len, "MOV.W R%d, @(R0, R%d)", Rm, Rn );
182 { /* MOV.L Rm, @(R0, Rn) */
183 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
184 snprintf( buf, len, "MOV.L R%d, @(R0, R%d)", Rm, Rn );
189 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
190 snprintf( buf, len, "MUL.L R%d, R%d", Rm, Rn );
194 switch( (ir&0xFF0) >> 4 ) {
197 snprintf( buf, len, "CLRT " );
202 snprintf( buf, len, "SETT " );
207 snprintf( buf, len, "CLRMAC " );
212 snprintf( buf, len, "LDTLB " );
217 snprintf( buf, len, "CLRS " );
222 snprintf( buf, len, "SETS " );
231 switch( (ir&0xF0) >> 4 ) {
234 snprintf( buf, len, "NOP " );
239 snprintf( buf, len, "DIV0U " );
244 uint32_t Rn = ((ir>>8)&0xF);
245 snprintf( buf, len, "MOVT R%d", Rn );
254 switch( (ir&0xF0) >> 4 ) {
257 uint32_t Rn = ((ir>>8)&0xF);
258 snprintf( buf, len, "STS MACH, R%d", Rn );
263 uint32_t Rn = ((ir>>8)&0xF);
264 snprintf( buf, len, "STS MACL, R%d", Rn );
269 uint32_t Rn = ((ir>>8)&0xF);
270 snprintf( buf, len, "STS PR, R%d", Rn );
275 uint32_t Rn = ((ir>>8)&0xF);
276 snprintf( buf, len, "STC SGR, R%d", Rn );
281 uint32_t Rn = ((ir>>8)&0xF);
282 snprintf( buf, len, "STS FPUL, R%d", Rn );
286 { /* STS FPSCR, Rn */
287 uint32_t Rn = ((ir>>8)&0xF);
288 snprintf( buf, len, "STS FPSCR, R%d", Rn );
293 uint32_t Rn = ((ir>>8)&0xF);
294 snprintf( buf, len, "STC DBR, R%d", Rn );
303 switch( (ir&0xFF0) >> 4 ) {
306 snprintf( buf, len, "RTS " );
311 snprintf( buf, len, "SLEEP " );
316 snprintf( buf, len, "RTE " );
325 { /* MOV.B @(R0, Rm), Rn */
326 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
327 snprintf( buf, len, "MOV.B @(R0, R%d), R%d", Rm, Rn );
331 { /* MOV.W @(R0, Rm), Rn */
332 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
333 snprintf( buf, len, "MOV.W @(R0, R%d), R%d", Rm, Rn );
337 { /* MOV.L @(R0, Rm), Rn */
338 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
339 snprintf( buf, len, "MOV.L @(R0, R%d), R%d", Rm, Rn );
343 { /* MAC.L @Rm+, @Rn+ */
344 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
345 snprintf( buf, len, "MAC.L @R%d+, @R%d+", Rm, Rn );
354 { /* MOV.L Rm, @(disp, Rn) */
355 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
356 snprintf( buf, len, "MOV.L R%d, @(%d, R%d)", Rm, disp, Rn );
362 { /* MOV.B Rm, @Rn */
363 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
364 snprintf( buf, len, "MOV.B R%d, @R%d", Rm, Rn );
368 { /* MOV.W Rm, @Rn */
369 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
370 snprintf( buf, len, "MOV.W R%d, @R%d", Rm, Rn );
374 { /* MOV.L Rm, @Rn */
375 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
376 snprintf( buf, len, "MOV.L R%d, @R%d", Rm, Rn );
380 { /* MOV.B Rm, @-Rn */
381 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
382 snprintf( buf, len, "MOV.B R%d, @-R%d", Rm, Rn );
386 { /* MOV.W Rm, @-Rn */
387 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
388 snprintf( buf, len, "MOV.W R%d, @-R%d", Rm, Rn );
392 { /* MOV.L Rm, @-Rn */
393 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
394 snprintf( buf, len, "MOV.L R%d, @-R%d", Rm, Rn );
399 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
400 snprintf( buf, len, "DIV0S R%d, R%d", Rm, Rn );
405 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
406 snprintf( buf, len, "TST R%d, R%d", Rm, Rn );
411 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
412 snprintf( buf, len, "AND R%d, R%d", Rm, Rn );
417 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
418 snprintf( buf, len, "XOR R%d, R%d", Rm, Rn );
423 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
424 snprintf( buf, len, "OR R%d, R%d", Rm, Rn );
428 { /* CMP/STR Rm, Rn */
429 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
430 snprintf( buf, len, "CMP/STR R%d, R%d", Rm, Rn );
435 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
436 snprintf( buf, len, "XTRCT R%d, R%d", Rm, Rn );
440 { /* MULU.W Rm, Rn */
441 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
442 snprintf( buf, len, "MULU.W R%d, R%d", Rm, Rn );
446 { /* MULS.W Rm, Rn */
447 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
448 snprintf( buf, len, "MULS.W R%d, R%d", Rm, Rn );
459 { /* CMP/EQ Rm, Rn */
460 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
461 snprintf( buf, len, "CMP/EQ R%d, R%d", Rm, Rn );
465 { /* CMP/HS Rm, Rn */
466 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
467 snprintf( buf, len, "CMP/HS R%d, R%d", Rm, Rn );
471 { /* CMP/GE Rm, Rn */
472 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
473 snprintf( buf, len, "CMP/GE R%d, R%d", Rm, Rn );
478 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
479 snprintf( buf, len, "DIV1 R%d, R%d", Rm, Rn );
483 { /* DMULU.L Rm, Rn */
484 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
485 snprintf( buf, len, "DMULU.L R%d, R%d", Rm, Rn );
489 { /* CMP/HI Rm, Rn */
490 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
491 snprintf( buf, len, "CMP/HI R%d, R%d", Rm, Rn );
495 { /* CMP/GT Rm, Rn */
496 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
497 snprintf( buf, len, "CMP/GT R%d, R%d", Rm, Rn );
502 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
503 snprintf( buf, len, "SUB R%d, R%d", Rm, Rn );
508 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
509 snprintf( buf, len, "SUBC R%d, R%d", Rm, Rn );
514 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
515 snprintf( buf, len, "SUBV R%d, R%d", Rm, Rn );
520 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
521 snprintf( buf, len, "ADD R%d, R%d", Rm, Rn );
525 { /* DMULS.L Rm, Rn */
526 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
527 snprintf( buf, len, "DMULS.L R%d, R%d", Rm, Rn );
532 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
533 snprintf( buf, len, "ADDC R%d, R%d", Rm, Rn );
538 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
539 snprintf( buf, len, "ADDV R%d, R%d", Rm, Rn );
550 switch( (ir&0xF0) >> 4 ) {
553 uint32_t Rn = ((ir>>8)&0xF);
554 snprintf( buf, len, "SHLL R%d", Rn );
559 uint32_t Rn = ((ir>>8)&0xF);
560 snprintf( buf, len, "DT R%d", Rn );
565 uint32_t Rn = ((ir>>8)&0xF);
566 snprintf( buf, len, "SHAL R%d", Rn );
575 switch( (ir&0xF0) >> 4 ) {
578 uint32_t Rn = ((ir>>8)&0xF);
579 snprintf( buf, len, "SHLR R%d", Rn );
584 uint32_t Rn = ((ir>>8)&0xF);
585 snprintf( buf, len, "CMP/PZ R%d", Rn );
590 uint32_t Rn = ((ir>>8)&0xF);
591 snprintf( buf, len, "SHAR R%d", Rn );
600 switch( (ir&0xF0) >> 4 ) {
602 { /* STS.L MACH, @-Rn */
603 uint32_t Rn = ((ir>>8)&0xF);
604 snprintf( buf, len, "STS.L MACH, @-R%d", Rn );
608 { /* STS.L MACL, @-Rn */
609 uint32_t Rn = ((ir>>8)&0xF);
610 snprintf( buf, len, "STS.L MACL, @-R%d", Rn );
614 { /* STS.L PR, @-Rn */
615 uint32_t Rn = ((ir>>8)&0xF);
616 snprintf( buf, len, "STS.L PR, @-R%d", Rn );
620 { /* STC.L SGR, @-Rn */
621 uint32_t Rn = ((ir>>8)&0xF);
622 snprintf( buf, len, "STC.L SGR, @-R%d", Rn );
626 { /* STS.L FPUL, @-Rn */
627 uint32_t Rn = ((ir>>8)&0xF);
628 snprintf( buf, len, "STS.L FPUL, @-R%d", Rn );
632 { /* STS.L FPSCR, @-Rn */
633 uint32_t Rn = ((ir>>8)&0xF);
634 snprintf( buf, len, "STS.L FPSCR, @-R%d", Rn );
638 { /* STC.L DBR, @-Rn */
639 uint32_t Rn = ((ir>>8)&0xF);
640 snprintf( buf, len, "STC.L DBR, @-R%d", Rn );
649 switch( (ir&0x80) >> 7 ) {
651 switch( (ir&0x70) >> 4 ) {
653 { /* STC.L SR, @-Rn */
654 uint32_t Rn = ((ir>>8)&0xF);
655 snprintf( buf, len, "STC.L SR, @-R%d", Rn );
659 { /* STC.L GBR, @-Rn */
660 uint32_t Rn = ((ir>>8)&0xF);
661 snprintf( buf, len, "STC.L GBR, @-R%d", Rn );
665 { /* STC.L VBR, @-Rn */
666 uint32_t Rn = ((ir>>8)&0xF);
667 snprintf( buf, len, "STC.L VBR, @-R%d", Rn );
671 { /* STC.L SSR, @-Rn */
672 uint32_t Rn = ((ir>>8)&0xF);
673 snprintf( buf, len, "STC.L SSR, @-R%d", Rn );
677 { /* STC.L SPC, @-Rn */
678 uint32_t Rn = ((ir>>8)&0xF);
679 snprintf( buf, len, "STC.L SPC, @-R%d", Rn );
688 { /* STC.L Rm_BANK, @-Rn */
689 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
690 snprintf( buf, len, "STC.L @-R%d_BANK, @-R%d", Rm_BANK, Rn );
696 switch( (ir&0xF0) >> 4 ) {
699 uint32_t Rn = ((ir>>8)&0xF);
700 snprintf( buf, len, "ROTL R%d", Rn );
705 uint32_t Rn = ((ir>>8)&0xF);
706 snprintf( buf, len, "ROTCL R%d", Rn );
715 switch( (ir&0xF0) >> 4 ) {
718 uint32_t Rn = ((ir>>8)&0xF);
719 snprintf( buf, len, "ROTR R%d", Rn );
724 uint32_t Rn = ((ir>>8)&0xF);
725 snprintf( buf, len, "CMP/PL R%d", Rn );
730 uint32_t Rn = ((ir>>8)&0xF);
731 snprintf( buf, len, "ROTCR R%d", Rn );
740 switch( (ir&0xF0) >> 4 ) {
742 { /* LDS.L @Rm+, MACH */
743 uint32_t Rm = ((ir>>8)&0xF);
744 snprintf( buf, len, "LDS.L @R%d+, MACH", Rm );
748 { /* LDS.L @Rm+, MACL */
749 uint32_t Rm = ((ir>>8)&0xF);
750 snprintf( buf, len, "LDS.L @R%d+, MACL", Rm );
754 { /* LDS.L @Rm+, PR */
755 uint32_t Rm = ((ir>>8)&0xF);
756 snprintf( buf, len, "LDS.L @R%d+, PR", Rm );
760 { /* LDC.L @Rm+, SGR */
761 uint32_t Rm = ((ir>>8)&0xF);
762 snprintf( buf, len, "LDC.L @R%d+, SGR", Rm );
766 { /* LDS.L @Rm+, FPUL */
767 uint32_t Rm = ((ir>>8)&0xF);
768 snprintf( buf, len, "LDS.L @R%d+, FPUL", Rm );
772 { /* LDS.L @Rm+, FPSCR */
773 uint32_t Rm = ((ir>>8)&0xF);
774 snprintf( buf, len, "LDS.L @R%d+, FPSCR", Rm );
778 { /* LDC.L @Rm+, DBR */
779 uint32_t Rm = ((ir>>8)&0xF);
780 snprintf( buf, len, "LDC.L @R%d+, DBR", Rm );
789 switch( (ir&0x80) >> 7 ) {
791 switch( (ir&0x70) >> 4 ) {
793 { /* LDC.L @Rm+, SR */
794 uint32_t Rm = ((ir>>8)&0xF);
795 snprintf( buf, len, "LDC.L @R%d+, SR", Rm );
799 { /* LDC.L @Rm+, GBR */
800 uint32_t Rm = ((ir>>8)&0xF);
801 snprintf( buf, len, "LDC.L @R%d+, GBR", Rm );
805 { /* LDC.L @Rm+, VBR */
806 uint32_t Rm = ((ir>>8)&0xF);
807 snprintf( buf, len, "LDC.L @R%d+, VBR", Rm );
811 { /* LDC.L @Rm+, SSR */
812 uint32_t Rm = ((ir>>8)&0xF);
813 snprintf( buf, len, "LDC.L @R%d+, SSR", Rm );
817 { /* LDC.L @Rm+, SPC */
818 uint32_t Rm = ((ir>>8)&0xF);
819 snprintf( buf, len, "LDC.L @R%d+, SPC", Rm );
828 { /* LDC.L @Rm+, Rn_BANK */
829 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
830 snprintf( buf, len, "LDC.L @R%d+, @R%d+_BANK", Rm, Rn_BANK );
836 switch( (ir&0xF0) >> 4 ) {
839 uint32_t Rn = ((ir>>8)&0xF);
840 snprintf( buf, len, "SHLL2 R%d", Rn );
845 uint32_t Rn = ((ir>>8)&0xF);
846 snprintf( buf, len, "SHLL8 R%d", Rn );
851 uint32_t Rn = ((ir>>8)&0xF);
852 snprintf( buf, len, "SHLL16 R%d", Rn );
861 switch( (ir&0xF0) >> 4 ) {
864 uint32_t Rn = ((ir>>8)&0xF);
865 snprintf( buf, len, "SHLR2 R%d", Rn );
870 uint32_t Rn = ((ir>>8)&0xF);
871 snprintf( buf, len, "SHLR8 R%d", Rn );
876 uint32_t Rn = ((ir>>8)&0xF);
877 snprintf( buf, len, "SHLR16 R%d", Rn );
886 switch( (ir&0xF0) >> 4 ) {
889 uint32_t Rm = ((ir>>8)&0xF);
890 snprintf( buf, len, "LDS R%d, MACH", Rm );
895 uint32_t Rm = ((ir>>8)&0xF);
896 snprintf( buf, len, "LDS R%d, MACL", Rm );
901 uint32_t Rm = ((ir>>8)&0xF);
902 snprintf( buf, len, "LDS R%d, PR", Rm );
907 uint32_t Rm = ((ir>>8)&0xF);
908 snprintf( buf, len, "LDC R%d, SGR", Rm );
913 uint32_t Rm = ((ir>>8)&0xF);
914 snprintf( buf, len, "LDS R%d, FPUL", Rm );
918 { /* LDS Rm, FPSCR */
919 uint32_t Rm = ((ir>>8)&0xF);
920 snprintf( buf, len, "LDS R%d, FPSCR", Rm );
925 uint32_t Rm = ((ir>>8)&0xF);
926 snprintf( buf, len, "LDC R%d, DBR", Rm );
935 switch( (ir&0xF0) >> 4 ) {
938 uint32_t Rn = ((ir>>8)&0xF);
939 snprintf( buf, len, "JSR @R%d", Rn );
944 uint32_t Rn = ((ir>>8)&0xF);
945 snprintf( buf, len, "TAS.B R%d", Rn );
950 uint32_t Rn = ((ir>>8)&0xF);
951 snprintf( buf, len, "JMP @R%d", Rn );
961 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
962 snprintf( buf, len, "SHAD R%d, R%d", Rm, Rn );
967 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
968 snprintf( buf, len, "SHLD R%d, R%d", Rm, Rn );
972 switch( (ir&0x80) >> 7 ) {
974 switch( (ir&0x70) >> 4 ) {
977 uint32_t Rm = ((ir>>8)&0xF);
978 snprintf( buf, len, "LDC R%d, SR", Rm );
983 uint32_t Rm = ((ir>>8)&0xF);
984 snprintf( buf, len, "LDC R%d, GBR", Rm );
989 uint32_t Rm = ((ir>>8)&0xF);
990 snprintf( buf, len, "LDC R%d, VBR", Rm );
995 uint32_t Rm = ((ir>>8)&0xF);
996 snprintf( buf, len, "LDC R%d, SSR", Rm );
1001 uint32_t Rm = ((ir>>8)&0xF);
1002 snprintf( buf, len, "LDC R%d, SPC", Rm );
1011 { /* LDC Rm, Rn_BANK */
1012 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1013 snprintf( buf, len, "LDC R%d, R%d_BANK", Rm, Rn_BANK );
1019 { /* MAC.W @Rm+, @Rn+ */
1020 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1021 snprintf( buf, len, "MAC.W @R%d+, @R%d+", Rm, Rn );
1027 { /* MOV.L @(disp, Rm), Rn */
1028 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1029 snprintf( buf, len, "MOV.L @(%d, R%d), R%d", disp, Rm, Rn );
1035 { /* MOV.B @Rm, Rn */
1036 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1037 snprintf( buf, len, "MOV.B @R%d, R%d", Rm, Rn );
1041 { /* MOV.W @Rm, Rn */
1042 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1043 snprintf( buf, len, "MOV.W @R%d, R%d", Rm, Rn );
1047 { /* MOV.L @Rm, Rn */
1048 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1049 snprintf( buf, len, "MOV.L @R%d, R%d", Rm, Rn );
1054 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1055 snprintf( buf, len, "MOV R%d, R%d", Rm, Rn );
1059 { /* MOV.B @Rm+, Rn */
1060 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1061 snprintf( buf, len, "MOV.B @R%d+, R%d", Rm, Rn );
1065 { /* MOV.W @Rm+, Rn */
1066 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1067 snprintf( buf, len, "MOV.W @R%d+, R%d", Rm, Rn );
1071 { /* MOV.L @Rm+, Rn */
1072 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1073 snprintf( buf, len, "MOV.L @R%d+, R%d", Rm, Rn );
1078 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1079 snprintf( buf, len, "NOT R%d, R%d", Rm, Rn );
1083 { /* SWAP.B Rm, Rn */
1084 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1085 snprintf( buf, len, "SWAP.B R%d, R%d", Rm, Rn );
1089 { /* SWAP.W Rm, Rn */
1090 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1091 snprintf( buf, len, "SWAP.W R%d, R%d", Rm, Rn );
1096 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1097 snprintf( buf, len, "NEGC R%d, R%d", Rm, Rn );
1102 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1103 snprintf( buf, len, "NEG R%d, R%d", Rm, Rn );
1107 { /* EXTU.B Rm, Rn */
1108 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1109 snprintf( buf, len, "EXTU.B R%d, R%d", Rm, Rn );
1113 { /* EXTU.W Rm, Rn */
1114 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1115 snprintf( buf, len, "EXTU.W R%d, R%d", Rm, Rn );
1119 { /* EXTS.B Rm, Rn */
1120 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1121 snprintf( buf, len, "EXTS.B R%d, R%d", Rm, Rn );
1125 { /* EXTS.W Rm, Rn */
1126 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1127 snprintf( buf, len, "EXTS.W R%d, R%d", Rm, Rn );
1133 { /* ADD #imm, Rn */
1134 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1135 snprintf( buf, len, "ADD #%d, R%d", imm, Rn );
1139 switch( (ir&0xF00) >> 8 ) {
1141 { /* MOV.B R0, @(disp, Rn) */
1142 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1143 snprintf( buf, len, "MOV.B R0, @(%d, R%d)", disp, Rn );
1147 { /* MOV.W R0, @(disp, Rn) */
1148 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1149 snprintf( buf, len, "MOV.W R0, @(%d, R%d)", disp, Rn );
1153 { /* MOV.B @(disp, Rm), R0 */
1154 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1155 snprintf( buf, len, "MOV.B @(%d, R%d), R0", disp, Rm );
1159 { /* MOV.W @(disp, Rm), R0 */
1160 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1161 snprintf( buf, len, "MOV.W @(%d, R%d), R0", disp, Rm );
1165 { /* CMP/EQ #imm, R0 */
1166 int32_t imm = SIGNEXT8(ir&0xFF);
1167 snprintf( buf, len, "CMP/EQ #%d, R0", imm );
1172 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1173 snprintf( buf, len, "BT $%xh", disp+pc+4 );
1178 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1179 snprintf( buf, len, "BF $%xh", disp+pc+4 );
1184 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1185 snprintf( buf, len, "BT/S $%xh", disp+pc+4 );
1190 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1191 snprintf( buf, len, "BF/S $%xh", disp+pc+4 );
1200 { /* MOV.W @(disp, PC), Rn */
1201 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1202 snprintf( buf, len, "MOV.W @($%xh), R%d ; <- #%08x", disp + pc + 4, Rn, sh4_read_word(disp+pc+4) );
1207 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1208 snprintf( buf, len, "BRA $%xh", disp+pc+4 );
1213 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1214 snprintf( buf, len, "BSR $%xh", disp+pc+4 );
1218 switch( (ir&0xF00) >> 8 ) {
1220 { /* MOV.B R0, @(disp, GBR) */
1221 uint32_t disp = (ir&0xFF);
1222 snprintf( buf, len, "MOV.B R0, @(%d, GBR)", disp );
1226 { /* MOV.W R0, @(disp, GBR) */
1227 uint32_t disp = (ir&0xFF)<<1;
1228 snprintf( buf, len, "MOV.W R0, @(%d, GBR)", disp);
1232 { /* MOV.L R0, @(disp, GBR) */
1233 uint32_t disp = (ir&0xFF)<<2;
1234 snprintf( buf, len, "MOV.L R0, @(%d, GBR)", disp );
1239 uint32_t imm = (ir&0xFF);
1240 snprintf( buf, len, "TRAPA #%d", imm );
1244 { /* MOV.B @(disp, GBR), R0 */
1245 uint32_t disp = (ir&0xFF);
1246 snprintf( buf, len, "MOV.B @(%d, GBR), R0", disp );
1250 { /* MOV.W @(disp, GBR), R0 */
1251 uint32_t disp = (ir&0xFF)<<1;
1252 snprintf( buf, len, "MOV.W @(%d, GBR), R0", disp );
1256 { /* MOV.L @(disp, GBR), R0 */
1257 uint32_t disp = (ir&0xFF)<<2;
1258 snprintf( buf, len, "MOV.L @(%d, GBR), R0",disp );
1262 { /* MOVA @(disp, PC), R0 */
1263 uint32_t disp = (ir&0xFF)<<2;
1264 snprintf( buf, len, "MOVA @($%xh), R0", disp + (pc&0xFFFFFFFC) + 4 );
1268 { /* TST #imm, R0 */
1269 uint32_t imm = (ir&0xFF);
1270 snprintf( buf, len, "TST #%d, R0", imm );
1274 { /* AND #imm, R0 */
1275 uint32_t imm = (ir&0xFF);
1276 snprintf( buf, len, "ADD #%d, R0", imm );
1280 { /* XOR #imm, R0 */
1281 uint32_t imm = (ir&0xFF);
1282 snprintf( buf, len, "XOR #%d, R0", imm );
1287 uint32_t imm = (ir&0xFF);
1288 snprintf( buf, len, "OR #%d, R0", imm );
1292 { /* TST.B #imm, @(R0, GBR) */
1293 uint32_t imm = (ir&0xFF);
1294 snprintf( buf, len, "TST.B #%d, @(R0, GBR)", imm );
1298 { /* AND.B #imm, @(R0, GBR) */
1299 uint32_t imm = (ir&0xFF);
1300 snprintf( buf, len, "AND.B #%d, @(R0, GBR)", imm );
1304 { /* XOR.B #imm, @(R0, GBR) */
1305 uint32_t imm = (ir&0xFF);
1306 snprintf( buf, len, "XOR.B #%d, @(R0, GBR)", imm );
1310 { /* OR.B #imm, @(R0, GBR) */
1311 uint32_t imm = (ir&0xFF);
1312 snprintf( buf, len, "OR.B #%d, @(R0, GBR)", imm );
1318 { /* MOV.L @(disp, PC), Rn */
1319 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
1320 snprintf( buf, len, "MOV.L @($%xh), R%d ; <- #%08x", disp + (pc & 0xFFFFFFFC) + 4, Rn, sh4_read_long(disp+(pc&0xFFFFFFFC)+4) );
1324 { /* MOV #imm, Rn */
1325 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1326 snprintf( buf, len, "MOV #%d, R%d", imm, Rn );
1332 { /* FADD FRm, FRn */
1333 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1334 snprintf( buf, len, "FADD FR%d, FR%d", FRm, FRn );
1338 { /* FSUB FRm, FRn */
1339 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1340 snprintf( buf, len, "FSUB FR%d, FR%d", FRm, FRn );
1344 { /* FMUL FRm, FRn */
1345 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1346 snprintf( buf, len, "FMUL FR%d, FR%d", FRm, FRn );
1350 { /* FDIV FRm, FRn */
1351 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1352 snprintf( buf, len, "FDIV FR%d, FR%d", FRm, FRn );
1356 { /* FCMP/EQ FRm, FRn */
1357 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1358 snprintf( buf, len, "FCMP/EQ FR%d, FR%d", FRm, FRn );
1362 { /* FCMP/GT FRm, FRn */
1363 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1364 snprintf( buf, len, "FCMP/QT FR%d, FR%d", FRm, FRn );
1368 { /* FMOV @(R0, Rm), FRn */
1369 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1370 snprintf( buf, len, "FMOV @(R0, R%d), FR%d", Rm, FRn );
1374 { /* FMOV FRm, @(R0, Rn) */
1375 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1376 snprintf( buf, len, "FMOV FR%d, @(R0, R%d)", FRm, Rn );
1380 { /* FMOV @Rm, FRn */
1381 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1382 snprintf( buf, len, "FMOV @R%d, FR%d", Rm, FRn );
1386 { /* FMOV @Rm+, FRn */
1387 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1388 snprintf( buf, len, "FMOV @R%d+, FR%d", Rm, FRn );
1392 { /* FMOV FRm, @Rn */
1393 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1394 snprintf( buf, len, "FMOV FR%d, @R%d", FRm, Rn );
1398 { /* FMOV FRm, @-Rn */
1399 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1400 snprintf( buf, len, "FMOV FR%d, @-R%d", FRm, Rn );
1404 { /* FMOV FRm, FRn */
1405 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1406 snprintf( buf, len, "FMOV FR%d, FR%d", FRm, FRn );
1410 switch( (ir&0xF0) >> 4 ) {
1412 { /* FSTS FPUL, FRn */
1413 uint32_t FRn = ((ir>>8)&0xF);
1414 snprintf( buf, len, "FSTS FPUL, FR%d", FRn );
1418 { /* FLDS FRm, FPUL */
1419 uint32_t FRm = ((ir>>8)&0xF);
1420 snprintf( buf, len, "FLDS FR%d, FPUL", FRm );
1424 { /* FLOAT FPUL, FRn */
1425 uint32_t FRn = ((ir>>8)&0xF);
1426 snprintf( buf, len, "FLOAT FPUL, FR%d", FRn );
1430 { /* FTRC FRm, FPUL */
1431 uint32_t FRm = ((ir>>8)&0xF);
1432 snprintf( buf, len, "FTRC FR%d, FPUL", FRm );
1437 uint32_t FRn = ((ir>>8)&0xF);
1438 snprintf( buf, len, "FNEG FR%d", FRn );
1443 uint32_t FRn = ((ir>>8)&0xF);
1444 snprintf( buf, len, "FABS FR%d", FRn );
1449 uint32_t FRn = ((ir>>8)&0xF);
1450 snprintf( buf, len, "FSQRT FR%d", FRn );
1455 uint32_t FRn = ((ir>>8)&0xF);
1456 snprintf( buf, len, "FSRRA FR%d", FRn );
1461 uint32_t FRn = ((ir>>8)&0xF);
1462 snprintf( buf, len, "FLDI0 FR%d", FRn );
1467 uint32_t FRn = ((ir>>8)&0xF);
1468 snprintf( buf, len, "FLDI1 FR%d", FRn );
1472 { /* FCNVSD FPUL, FRn */
1473 uint32_t FRn = ((ir>>8)&0xF);
1474 snprintf( buf, len, "FCNVSD FPUL, FR%d", FRn );
1478 { /* FCNVDS FRm, FPUL */
1479 uint32_t FRm = ((ir>>8)&0xF);
1480 snprintf( buf, len, "FCNVDS FR%d, FPUL", FRm );
1484 { /* FIPR FVm, FVn */
1485 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
1486 snprintf( buf, len, "FIPR FV%d, FV%d", FVm, FVn );
1490 switch( (ir&0x100) >> 8 ) {
1492 { /* FSCA FPUL, FRn */
1493 uint32_t FRn = ((ir>>9)&0x7)<<1;
1494 snprintf( buf, len, "FSCA FPUL, FR%d", FRn );
1498 switch( (ir&0x200) >> 9 ) {
1500 { /* FTRV XMTRX, FVn */
1501 uint32_t FVn = ((ir>>10)&0x3);
1502 snprintf( buf, len, "FTRV XMTRX, FV%d", FVn );
1506 switch( (ir&0xC00) >> 10 ) {
1509 snprintf( buf, len, "FSCHG " );
1514 snprintf( buf, len, "FRCHG " );
1519 snprintf( buf, len, "UNDEF " );
1537 { /* FMAC FR0, FRm, FRn */
1538 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1539 snprintf( buf, len, "FMAC FR0, FR%d, FR%d", FRm, FRn );
1553 void sh4_disasm_region( FILE *f, int from, int to )
1559 for( pc = from; pc < to; pc+=2 ) {
1561 sh4_disasm_instruction( pc,
1562 buf, sizeof(buf), opcode );
1563 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );
.