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.
19 #include "sh4/sh4core.h"
20 #include "sh4/sh4dasm.h"
26 #define UNIMP(ir) snprintf( buf, len, "??? " )
28 uint32_t sh4_disasm_instruction( sh4vma_t pc, char *buf, int len, char *opcode )
30 sh4addr_t addr = mmu_vma_to_phys_disasm(pc);
33 if( addr == MMU_VMA_ERROR ) {
34 sprintf( opcode, "?? ??" );
35 snprintf( buf, len, "???" );
39 uint16_t ir = ext_address_space[addr>>12]->read_word(addr);
41 #define UNDEF(ir) snprintf( buf, len, "???? " );
42 #define RN(ir) ((ir&0x0F00)>>8)
43 #define RN_BANK(ir) ((ir&0x0070)>>4)
44 #define RM(ir) ((ir&0x00F0)>>4)
45 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */
46 #define DISP8(ir) (ir&0x00FF)
47 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
48 #define UIMM8(ir) (ir&0x00FF)
49 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
50 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
51 #define FVN(ir) ((ir&0x0C00)>>10)
52 #define FVM(ir) ((ir&0x0300)>>8)
54 sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );
57 ADD Rm, Rn {: snprintf( buf, len, "ADD R%d, R%d", Rm, Rn ); :}
58 ADD #imm, Rn {: snprintf( buf, len, "ADD #%d, R%d", imm, Rn ); :}
59 ADDC Rm, Rn {: snprintf( buf, len, "ADDC R%d, R%d", Rm, Rn ); :}
60 ADDV Rm, Rn {: snprintf( buf, len, "ADDV R%d, R%d", Rm, Rn ); :}
61 AND Rm, Rn {: snprintf( buf, len, "AND R%d, R%d", Rm, Rn ); :}
62 AND #imm, R0 {: snprintf( buf, len, "AND #%d, R0", imm ); :}
63 AND.B #imm, @(R0, GBR) {: snprintf( buf, len, "AND.B #%d, @(R0, GBR)", imm ); :}
64 BF disp {: snprintf( buf, len, "BF $%xh", disp+pc+4 ); :}
65 BF/S disp {: snprintf( buf, len, "BF/S $%xh", disp+pc+4 ); :}
66 BRA disp {: snprintf( buf, len, "BRA $%xh", disp+pc+4 ); :}
67 BRAF Rn {: snprintf( buf, len, "BRAF R%d", Rn ); :}
68 BSR disp {: snprintf( buf, len, "BSR $%xh", disp+pc+4 ); :}
69 BSRF Rn {: snprintf( buf, len, "BSRF R%d", Rn ); :}
70 BT disp {: snprintf( buf, len, "BT $%xh", disp+pc+4 ); :}
71 BT/S disp {: snprintf( buf, len, "BT/S $%xh", disp+pc+4 ); :}
72 CLRMAC {: snprintf( buf, len, "CLRMAC " ); :}
73 CLRS {: snprintf( buf, len, "CLRS " ); :}
74 CLRT {: snprintf( buf, len, "CLRT " ); :}
75 CMP/EQ Rm, Rn {: snprintf( buf, len, "CMP/EQ R%d, R%d", Rm, Rn ); :}
76 CMP/EQ #imm, R0 {: snprintf( buf, len, "CMP/EQ #%d, R0", imm ); :}
77 CMP/GE Rm, Rn {: snprintf( buf, len, "CMP/GE R%d, R%d", Rm, Rn ); :}
78 CMP/GT Rm, Rn {: snprintf( buf, len, "CMP/GT R%d, R%d", Rm, Rn ); :}
79 CMP/HI Rm, Rn {: snprintf( buf, len, "CMP/HI R%d, R%d", Rm, Rn ); :}
80 CMP/HS Rm, Rn {: snprintf( buf, len, "CMP/HS R%d, R%d", Rm, Rn ); :}
81 CMP/PL Rn {: snprintf( buf, len, "CMP/PL R%d", Rn ); :}
82 CMP/PZ Rn {: snprintf( buf, len, "CMP/PZ R%d", Rn ); :}
83 CMP/STR Rm, Rn {: snprintf( buf, len, "CMP/STR R%d, R%d", Rm, Rn ); :}
84 DIV0S Rm, Rn {: snprintf( buf, len, "DIV0S R%d, R%d", Rm, Rn ); :}
85 DIV0U {: snprintf( buf, len, "DIV0U " ); :}
86 DIV1 Rm, Rn {: snprintf( buf, len, "DIV1 R%d, R%d", Rm, Rn ); :}
87 DMULS.L Rm, Rn {: snprintf( buf, len, "DMULS.L R%d, R%d", Rm, Rn ); :}
88 DMULU.L RM, Rn {: snprintf( buf, len, "DMULU.L R%d, R%d", Rm, Rn ); :}
89 DT Rn {: snprintf( buf, len, "DT R%d", Rn ); :}
90 EXTS.B Rm, Rn {: snprintf( buf, len, "EXTS.B R%d, R%d", Rm, Rn ); :}
91 EXTS.W Rm, Rn {: snprintf( buf, len, "EXTS.W R%d, R%d", Rm, Rn ); :}
92 EXTU.B Rm, Rn {: snprintf( buf, len, "EXTU.B R%d, R%d", Rm, Rn ); :}
93 EXTU.W Rm, Rn {: snprintf( buf, len, "EXTU.W R%d, R%d", Rm, Rn ); :}
94 FABS FRn {: snprintf( buf, len, "FABS FR%d", FRn ); :}
95 FADD FRm, FRn {: snprintf( buf, len, "FADD FR%d, FR%d", FRm, FRn ); :}
96 FCMP/EQ FRm, FRn {: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", FRm, FRn ); :}
97 FCMP/GT FRm, FRn {: snprintf( buf, len, "FCMP/GT FR%d, FR%d", FRm, FRn ); :}
98 FCNVDS FRm, FPUL {: snprintf( buf, len, "FCNVDS FR%d, FPUL", FRm ); :}
99 FCNVSD FPUL, FRn {: snprintf( buf, len, "FCNVSD FPUL, FR%d", FRn ); :}
100 FDIV FRm, FRn {: snprintf( buf, len, "FDIV FR%d, FR%d", FRm, FRn ); :}
101 FIPR FVm, FVn {: snprintf( buf, len, "FIPR FV%d, FV%d", FVm, FVn ); :}
102 FLDS FRm, FPUL {: snprintf( buf, len, "FLDS FR%d, FPUL", FRm ); :}
103 FLDI0 FRn {: snprintf( buf, len, "FLDI0 FR%d", FRn ); :}
104 FLDI1 FRn {: snprintf( buf, len, "FLDI1 FR%d", FRn ); :}
105 FLOAT FPUL, FRn {: snprintf( buf, len, "FLOAT FPUL, FR%d", FRn ); :}
106 FMAC FR0, FRm, FRn {: snprintf( buf, len, "FMAC FR0, FR%d, FR%d", FRm, FRn ); :}
107 FMOV FRm, FRn {: snprintf( buf, len, "FMOV FR%d, FR%d", FRm, FRn ); :}
108 FMOV FRm, @Rn {: snprintf( buf, len, "FMOV FR%d, @R%d", FRm, Rn ); :}
109 FMOV FRm, @-Rn {: snprintf( buf, len, "FMOV FR%d, @-R%d", FRm, Rn ); :}
110 FMOV FRm, @(R0, Rn) {: snprintf( buf, len, "FMOV FR%d, @(R0, R%d)", FRm, Rn ); :}
111 FMOV @Rm, FRn {: snprintf( buf, len, "FMOV @R%d, FR%d", Rm, FRn ); :}
112 FMOV @Rm+, FRn {: snprintf( buf, len, "FMOV @R%d+, FR%d", Rm, FRn ); :}
113 FMOV @(R0, Rm), FRn {: snprintf( buf, len, "FMOV @(R0, R%d), FR%d", Rm, FRn ); :}
114 FMUL FRm, FRn {: snprintf( buf, len, "FMUL FR%d, FR%d", FRm, FRn ); :}
115 FNEG FRn {: snprintf( buf, len, "FNEG FR%d", FRn ); :}
116 FRCHG {: snprintf( buf, len, "FRCHG " ); :}
117 FSCA FPUL, FRn {: snprintf( buf, len, "FSCA FPUL, FR%d", FRn ); :}
118 FSCHG {: snprintf( buf, len, "FSCHG " ); :}
119 FSQRT FRn {: snprintf( buf, len, "FSQRT FR%d", FRn ); :}
120 FSRRA FRn {: snprintf( buf, len, "FSRRA FR%d", FRn ); :}
121 FSTS FPUL, FRn {: snprintf( buf, len, "FSTS FPUL, FR%d", FRn ); :}
122 FSUB FRm, FRn {: snprintf( buf, len, "FSUB FR%d, FR%d", FRm, FRn ); :}
123 FTRC FRm, FPUL {: snprintf( buf, len, "FTRC FR%d, FPUL", FRm ); :}
124 FTRV XMTRX, FVn {: snprintf( buf, len, "FTRV XMTRX, FV%d", FVn ); :}
125 JMP @Rn {: snprintf( buf, len, "JMP @R%d", Rn ); :}
126 JSR @Rn {: snprintf( buf, len, "JSR @R%d", Rn ); :}
127 LDC Rm, GBR {: snprintf( buf, len, "LDC R%d, GBR", Rm ); :}
128 LDC Rm, SR {: snprintf( buf, len, "LDC R%d, SR", Rm ); :}
129 LDC Rm, VBR {: snprintf( buf, len, "LDC R%d, VBR", Rm ); :}
130 LDC Rm, SSR {: snprintf( buf, len, "LDC R%d, SSR", Rm ); :}
131 LDC Rm, SGR {: snprintf( buf, len, "LDC R%d, SGR", Rm ); :}
132 LDC Rm, SPC {: snprintf( buf, len, "LDC R%d, SPC", Rm ); :}
133 LDC Rm, DBR {: snprintf( buf, len, "LDC R%d, DBR", Rm ); :}
134 LDC Rm, Rn_BANK {: snprintf( buf, len, "LDC R%d, R%d_BANK", Rm, Rn_BANK ); :}
135 LDS Rm, FPSCR {: snprintf( buf, len, "LDS R%d, FPSCR", Rm ); :}
136 LDS Rm, FPUL {: snprintf( buf, len, "LDS R%d, FPUL", Rm ); :}
137 LDS Rm, MACH {: snprintf( buf, len, "LDS R%d, MACH", Rm ); :}
138 LDS Rm, MACL {: snprintf( buf, len, "LDS R%d, MACL", Rm ); :}
139 LDS Rm, PR {: snprintf( buf, len, "LDS R%d, PR", Rm ); :}
140 LDC.L @Rm+, GBR {: snprintf( buf, len, "LDC.L @R%d+, GBR", Rm ); :}
141 LDC.L @Rm+, SR {: snprintf( buf, len, "LDC.L @R%d+, SR", Rm ); :}
142 LDC.L @Rm+, VBR {: snprintf( buf, len, "LDC.L @R%d+, VBR", Rm ); :}
143 LDC.L @Rm+, SSR {: snprintf( buf, len, "LDC.L @R%d+, SSR", Rm ); :}
144 LDC.L @Rm+, SGR {: snprintf( buf, len, "LDC.L @R%d+, SGR", Rm ); :}
145 LDC.L @Rm+, SPC {: snprintf( buf, len, "LDC.L @R%d+, SPC", Rm ); :}
146 LDC.L @Rm+, DBR {: snprintf( buf, len, "LDC.L @R%d+, DBR", Rm ); :}
147 LDC.L @Rm+, Rn_BANK{: snprintf( buf, len, "LDC.L @R%d+, @R%d+_BANK", Rm, Rn_BANK ); :}
148 LDS.L @Rm+, FPSCR{: snprintf( buf, len, "LDS.L @R%d+, FPSCR", Rm ); :}
149 LDS.L @Rm+, FPUL {: snprintf( buf, len, "LDS.L @R%d+, FPUL", Rm ); :}
150 LDS.L @Rm+, MACH {: snprintf( buf, len, "LDS.L @R%d+, MACH", Rm ); :}
151 LDS.L @Rm+, MACL {: snprintf( buf, len, "LDS.L @R%d+, MACL", Rm ); :}
152 LDS.L @Rm+, PR {: snprintf( buf, len, "LDS.L @R%d+, PR", Rm ); :}
153 LDTLB {: snprintf( buf, len, "LDTLB " ); :}
154 MAC.L @Rm+, @Rn+ {: snprintf( buf, len, "MAC.L @R%d+, @R%d+", Rm, Rn ); :}
155 MAC.W @Rm+, @Rn+ {: snprintf( buf, len, "MAC.W @R%d+, @R%d+", Rm, Rn ); :}
156 MOV Rm, Rn {: snprintf( buf, len, "MOV R%d, R%d", Rm, Rn ); :}
157 MOV #imm, Rn {: snprintf( buf, len, "MOV #%d, R%d", imm, Rn ); :}
158 MOV.B Rm, @Rn {: snprintf( buf, len, "MOV.B R%d, @R%d", Rm, Rn ); :}
159 MOV.B Rm, @-Rn {: snprintf( buf, len, "MOV.B R%d, @-R%d", Rm, Rn ); :}
160 MOV.B Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.B R%d, @(R0, R%d)", Rm, Rn ); :}
161 MOV.B R0, @(disp, GBR) {: snprintf( buf, len, "MOV.B R0, @(%d, GBR)", disp ); :}
162 MOV.B R0, @(disp, Rn) {: snprintf( buf, len, "MOV.B R0, @(%d, R%d)", disp, Rn ); :}
163 MOV.B @Rm, Rn {: snprintf( buf, len, "MOV.B @R%d, R%d", Rm, Rn ); :}
164 MOV.B @Rm+, Rn {: snprintf( buf, len, "MOV.B @R%d+, R%d", Rm, Rn ); :}
165 MOV.B @(R0, Rm), Rn {: snprintf( buf, len, "MOV.B @(R0, R%d), R%d", Rm, Rn ); :}
166 MOV.B @(disp, GBR), R0{: snprintf( buf, len, "MOV.B @(%d, GBR), R0", disp ); :}
167 MOV.B @(disp, Rm), R0 {: snprintf( buf, len, "MOV.B @(%d, R%d), R0", disp, Rm ); :}
168 MOV.L Rm, @Rn {: snprintf( buf, len, "MOV.L R%d, @R%d", Rm, Rn ); :}
169 MOV.L Rm, @-Rn {: snprintf( buf, len, "MOV.L R%d, @-R%d", Rm, Rn ); :}
170 MOV.L Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.L R%d, @(R0, R%d)", Rm, Rn ); :}
171 MOV.L R0, @(disp, GBR) {: snprintf( buf, len, "MOV.L R0, @(%d, GBR)", disp ); :}
172 MOV.L Rm, @(disp, Rn) {: snprintf( buf, len, "MOV.L R%d, @(%d, R%d)", Rm, disp, Rn ); :}
173 MOV.L @Rm, Rn {: snprintf( buf, len, "MOV.L @R%d, R%d", Rm, Rn ); :}
174 MOV.L @Rm+, Rn {: snprintf( buf, len, "MOV.L @R%d+, R%d", Rm, Rn ); :}
175 MOV.L @(R0, Rm), Rn {: snprintf( buf, len, "MOV.L @(R0, R%d), R%d", Rm, Rn ); :}
176 MOV.L @(disp, GBR), R0 {: snprintf( buf, len, "MOV.L @(%d, GBR), R0",disp ); :}
177 MOV.L @(disp, PC), Rn {:
178 tmp = mmu_vma_to_phys_disasm(disp + (pc&0xFFFFFFFC) + 4);
179 snprintf( buf, len, "MOV.L @($%xh), R%d ; <- #%08x", disp + (pc&0xFFFFFFFC)+4, Rn, ext_address_space[tmp>>12]->read_long(tmp) );
181 MOV.L @(disp, Rm), Rn {: snprintf( buf, len, "MOV.L @(%d, R%d), R%d", disp, Rm, Rn ); :}
182 MOV.W Rm, @Rn {: snprintf( buf, len, "MOV.W R%d, @R%d", Rm, Rn ); :}
183 MOV.W Rm, @-Rn {: snprintf( buf, len, "MOV.W R%d, @-R%d", Rm, Rn ); :}
184 MOV.W Rm, @(R0, Rn) {: snprintf( buf, len, "MOV.W R%d, @(R0, R%d)", Rm, Rn ); :}
185 MOV.W R0, @(disp, GBR) {: snprintf( buf, len, "MOV.W R0, @(%d, GBR)", disp); :}
186 MOV.W R0, @(disp, Rn) {: snprintf( buf, len, "MOV.W R0, @(%d, R%d)", disp, Rn ); :}
187 MOV.W @Rm, Rn {: snprintf( buf, len, "MOV.W @R%d, R%d", Rm, Rn ); :}
188 MOV.W @Rm+, Rn {: snprintf( buf, len, "MOV.W @R%d+, R%d", Rm, Rn ); :}
189 MOV.W @(R0, Rm), Rn {: snprintf( buf, len, "MOV.W @(R0, R%d), R%d", Rm, Rn ); :}
190 MOV.W @(disp, GBR), R0 {: snprintf( buf, len, "MOV.W @(%d, GBR), R0", disp ); :}
191 MOV.W @(disp, PC), Rn {:
192 tmp = mmu_vma_to_phys_disasm(disp+pc+4);
193 snprintf( buf, len, "MOV.W @($%xh), R%d ; <- #%08x", disp+pc+4, Rn, ext_address_space[tmp>>12]->read_word(tmp) );
195 MOV.W @(disp, Rm), R0 {: snprintf( buf, len, "MOV.W @(%d, R%d), R0", disp, Rm ); :}
196 MOVA @(disp, PC), R0 {: snprintf( buf, len, "MOVA @($%xh), R0", disp + (pc&0xFFFFFFFC) + 4 ); :}
197 MOVCA.L R0, @Rn {: snprintf( buf, len, "MOVCA.L R0, @R%d", Rn ); :}
198 MOVT Rn {: snprintf( buf, len, "MOVT R%d", Rn ); :}
199 MUL.L Rm, Rn {: snprintf( buf, len, "MUL.L R%d, R%d", Rm, Rn ); :}
200 MULS.W Rm, Rn {: snprintf( buf, len, "MULS.W R%d, R%d", Rm, Rn ); :}
201 MULU.W Rm, Rn {: snprintf( buf, len, "MULU.W R%d, R%d", Rm, Rn ); :}
202 NEG Rm, Rn {: snprintf( buf, len, "NEG R%d, R%d", Rm, Rn ); :}
203 NEGC Rm, Rn {: snprintf( buf, len, "NEGC R%d, R%d", Rm, Rn ); :}
204 NOP {: snprintf( buf, len, "NOP " ); :}
205 NOT Rm, Rn {: snprintf( buf, len, "NOT R%d, R%d", Rm, Rn ); :}
206 OCBI @Rn {: snprintf( buf, len, "OCBI @R%d", Rn ); :}
207 OCBP @Rn {: snprintf( buf, len, "OCBP @R%d", Rn ); :}
208 OCBWB @Rn {: snprintf( buf, len, "OCBWB @R%d", Rn ); :}
209 OR Rm, Rn {: snprintf( buf, len, "OR R%d, R%d", Rm, Rn ); :}
210 OR #imm, R0 {: snprintf( buf, len, "OR #%d, R0", imm ); :}
211 OR.B #imm, @(R0, GBR) {: snprintf( buf, len, "OR.B #%d, @(R0, GBR)", imm ); :}
212 PREF @Rn {: snprintf( buf, len, "PREF R%d", Rn ); :}
213 ROTCL Rn {: snprintf( buf, len, "ROTCL R%d", Rn ); :}
214 ROTCR Rn {: snprintf( buf, len, "ROTCR R%d", Rn ); :}
215 ROTL Rn {: snprintf( buf, len, "ROTL R%d", Rn ); :}
216 ROTR Rn {: snprintf( buf, len, "ROTR R%d", Rn ); :}
217 RTE {: snprintf( buf, len, "RTE " ); :}
218 RTS {: snprintf( buf, len, "RTS " ); :}
219 SETS {: snprintf( buf, len, "SETS " ); :}
220 SETT {: snprintf( buf, len, "SETT " ); :}
221 SHAD Rm, Rn {: snprintf( buf, len, "SHAD R%d, R%d", Rm, Rn ); :}
222 SHAL Rn {: snprintf( buf, len, "SHAL R%d", Rn ); :}
223 SHAR Rn {: snprintf( buf, len, "SHAR R%d", Rn ); :}
224 SHLD Rm, Rn {: snprintf( buf, len, "SHLD R%d, R%d", Rm, Rn ); :}
225 SHLL Rn {: snprintf( buf, len, "SHLL R%d", Rn ); :}
226 SHLL2 Rn {: snprintf( buf, len, "SHLL2 R%d", Rn ); :}
227 SHLL8 Rn {: snprintf( buf, len, "SHLL8 R%d", Rn ); :}
228 SHLL16 Rn {: snprintf( buf, len, "SHLL16 R%d", Rn ); :}
229 SHLR Rn {: snprintf( buf, len, "SHLR R%d", Rn ); :}
230 SHLR2 Rn {: snprintf( buf, len, "SHLR2 R%d", Rn ); :}
231 SHLR8 Rn {: snprintf( buf, len, "SHLR8 R%d", Rn ); :}
232 SHLR16 Rn {: snprintf( buf, len, "SHLR16 R%d", Rn ); :}
233 SLEEP {: snprintf( buf, len, "SLEEP " ); :}
234 STC SR, Rn {: snprintf( buf, len, "STC SR, R%d", Rn ); :}
235 STC GBR, Rn {: snprintf( buf, len, "STC GBR, R%d", Rn ); :}
236 STC VBR, Rn {: snprintf( buf, len, "STC VBR, R%d", Rn ); :}
237 STC SSR, Rn {: snprintf( buf, len, "STC SSR, R%d", Rn ); :}
238 STC SPC, Rn {: snprintf( buf, len, "STC SPC, R%d", Rn ); :}
239 STC SGR, Rn {: snprintf( buf, len, "STC SGR, R%d", Rn ); :}
240 STC DBR, Rn {: snprintf( buf, len, "STC DBR, R%d", Rn ); :}
241 STC Rm_BANK, Rn {: snprintf( buf, len, "STC R%d_BANK, R%d", Rm_BANK, Rn ); :}
242 STS FPSCR, Rn {: snprintf( buf, len, "STS FPSCR, R%d", Rn ); :}
243 STS FPUL, Rn {: snprintf( buf, len, "STS FPUL, R%d", Rn ); :}
244 STS MACH, Rn {: snprintf( buf, len, "STS MACH, R%d", Rn ); :}
245 STS MACL, Rn {: snprintf( buf, len, "STS MACL, R%d", Rn ); :}
246 STS PR, Rn {: snprintf( buf, len, "STS PR, R%d", Rn ); :}
247 STC.L SR, @-Rn {: snprintf( buf, len, "STC.L SR, @-R%d", Rn ); :}
248 STC.L GBR, @-Rn {: snprintf( buf, len, "STC.L GBR, @-R%d", Rn ); :}
249 STC.L VBR, @-Rn {: snprintf( buf, len, "STC.L VBR, @-R%d", Rn ); :}
250 STC.L SSR, @-Rn {: snprintf( buf, len, "STC.L SSR, @-R%d", Rn ); :}
251 STC.L SPC, @-Rn {: snprintf( buf, len, "STC.L SPC, @-R%d", Rn ); :}
252 STC.L SGR, @-Rn {: snprintf( buf, len, "STC.L SGR, @-R%d", Rn ); :}
253 STC.L DBR, @-Rn {: snprintf( buf, len, "STC.L DBR, @-R%d", Rn ); :}
254 STC.L Rm_BANK, @-Rn {: snprintf( buf, len, "STC.L @-R%d_BANK, @-R%d", Rm_BANK, Rn ); :}
255 STS.L FPSCR, @-Rn{: snprintf( buf, len, "STS.L FPSCR, @-R%d", Rn ); :}
256 STS.L FPUL, @-Rn {: snprintf( buf, len, "STS.L FPUL, @-R%d", Rn ); :}
257 STS.L MACH, @-Rn {: snprintf( buf, len, "STS.L MACH, @-R%d", Rn ); :}
258 STS.L MACL, @-Rn {: snprintf( buf, len, "STS.L MACL, @-R%d", Rn ); :}
259 STS.L PR, @-Rn {: snprintf( buf, len, "STS.L PR, @-R%d", Rn ); :}
260 SUB Rm, Rn {: snprintf( buf, len, "SUB R%d, R%d", Rm, Rn ); :}
261 SUBC Rm, Rn {: snprintf( buf, len, "SUBC R%d, R%d", Rm, Rn ); :}
262 SUBV Rm, Rn {: snprintf( buf, len, "SUBV R%d, R%d", Rm, Rn ); :}
263 SWAP.B Rm, Rn {: snprintf( buf, len, "SWAP.B R%d, R%d", Rm, Rn ); :}
264 SWAP.W Rm, Rn {: snprintf( buf, len, "SWAP.W R%d, R%d", Rm, Rn ); :}
265 TAS.B @Rn {: snprintf( buf, len, "TAS.B R%d", Rn ); :}
266 TRAPA #imm {: snprintf( buf, len, "TRAPA #%d", imm ); :}
267 TST Rm, Rn {: snprintf( buf, len, "TST R%d, R%d", Rm, Rn ); :}
268 TST #imm, R0 {: snprintf( buf, len, "TST #%d, R0", imm ); :}
269 TST.B #imm, @(R0, GBR) {: snprintf( buf, len, "TST.B #%d, @(R0, GBR)", imm ); :}
270 XOR Rm, Rn {: snprintf( buf, len, "XOR R%d, R%d", Rm, Rn ); :}
271 XOR #imm, R0 {: snprintf( buf, len, "XOR #%d, R0", imm ); :}
272 XOR.B #imm, @(R0, GBR) {: snprintf( buf, len, "XOR.B #%d, @(R0, GBR)", imm ); :}
273 XTRCT Rm, Rn {: snprintf( buf, len, "XTRCT R%d, R%d", Rm, Rn ); :}
274 UNDEF {: snprintf( buf, len, "UNDEF " ); :}
280 static struct sh4_symbol *sh4_symbol_table = NULL;
281 static unsigned sh4_symbol_table_size = 0;
282 static sh4_symtab_destroy_cb sh4_symbol_table_cb = NULL;
285 static void swap_symbol( struct sh4_symbol *a, struct sh4_symbol *b ) {
286 struct sh4_symbol tmp;
289 memcpy( &tmp, a, sizeof( struct sh4_symbol ) );
290 memcpy( a, b, sizeof( struct sh4_symbol ) );
291 memcpy( b, &tmp, sizeof( struct sh4_symbol ) );
294 static unsigned sort_symtab( struct sh4_symbol *table, unsigned numSymtabEntries ) {
295 /* Implement via simple selection sort for now; usually we don't have very
296 * large symbol tables.
298 for( unsigned i = 0; i < numSymtabEntries; i++ ) {
299 struct sh4_symbol *next_entry = &table[i];
300 for( unsigned j = i + 1; j < numSymtabEntries; ) {
301 if( table[j].address < next_entry->address ) {
302 next_entry = &table[j];
304 } else if( table[j].address == next_entry->address ) {
305 /* Duplicate - kill it */
306 swap_symbol( &table[j], &table[--numSymtabEntries] );
311 swap_symbol( &table[i], next_entry );
313 return numSymtabEntries;
316 const char *sh4_disasm_get_symbol( sh4addr_t addr )
318 int l = 0, h = sh4_symbol_table_size;
321 int iaddr = sh4_symbol_table[i].address;
322 if( iaddr == addr ) {
323 return sh4_symbol_table[i].name;
324 } else if( iaddr > addr ) {
326 } else { /* iaddr < addr */
333 void sh4_set_symbol_table( struct sh4_symbol *table, unsigned size, sh4_symtab_destroy_cb callback )
335 if( sh4_symbol_table_cb != NULL ) {
336 sh4_symbol_table_cb(sh4_symbol_table, sh4_symbol_table_size);
338 sh4_symbol_table = table;
339 sh4_symbol_table_cb = callback;
340 if( table == NULL ) {
341 sh4_symbol_table_size = 0;
343 sh4_symbol_table_size = sort_symtab(table, size);
348 void sh4_disasm_region( FILE *f, int from, int to )
354 for( pc = from; pc < to; pc+=2 ) {
356 sh4_disasm_instruction( pc,
357 buf, sizeof(buf), opcode );
358 const char *sym = sh4_disasm_get_symbol( pc );
360 fprintf( f, "%s:\n", sym );
362 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );
366 void sh4_dump_region( int from, int to )
368 sh4_disasm_region( stdout, from, to );
.