filename | src/sh4/sh4dasm.c |
changeset | 54:d8b73031289c |
prev | 43:0cf3e339cc59 |
next | 302:96b5cc24309c |
author | nkeynes |
date | Wed Jan 03 09:00:17 2007 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Adjust timers when they're read rather than waiting until the next time slice. Also temporarily cut the CPU time by 4. Initialize the FRQCR register to 0x0E0A for convenience |
view | annotate | diff | log | raw |
1 /**
2 * $Id: sh4dasm.c,v 1.9 2006-01-01 08:08:40 nkeynes Exp $
3 *
4 * SH4 CPU definition and disassembly functions
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
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.
12 *
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.
17 */
19 #include "sh4core.h"
20 #include "sh4dasm.h"
21 #include "mem.h"
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},
42 {NULL, 0, NULL} };
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,
49 &sh4r.pc, &sh4r.icount };
51 uint32_t sh4_disasm_instruction( uint32_t pc, char *buf, int len, char *opcode )
52 {
53 uint16_t ir = sh4_read_word(pc);
55 #define RN(ir) ((ir&0x0F00)>>8)
56 #define RN_BANK(ir) ((ir&0x0070)>>4)
57 #define RM(ir) ((ir&0x00F0)>>4)
58 #define DISP4(ir) (ir&0x000F) /* 4-bit displacements are *not* sign extended */
59 #define DISP8(ir) (ir&0x00FF)
60 #define PCDISP8(ir) SIGNEXT8(ir&0x00FF)
61 #define UIMM8(ir) (ir&0x00FF)
62 #define IMM8(ir) SIGNEXT8(ir&0x00FF)
63 #define DISP12(ir) SIGNEXT12(ir&0x0FFF)
64 #define FVN(ir) ((ir&0x0C00)>>10)
65 #define FVM(ir) ((ir&0x0300)>>8)
67 sprintf( opcode, "%02X %02X", ir&0xFF, ir>>8 );
69 switch( (ir&0xF000)>>12 ) {
70 case 0: /* 0000nnnnmmmmxxxx */
71 switch( ir&0x000F ) {
72 case 2:
73 switch( (ir&0x00F0)>>4 ) {
74 case 0: snprintf( buf, len, "STC SR, R%d", RN(ir) ); break;
75 case 1: snprintf( buf, len, "STC GBR, R%d", RN(ir) ); break;
76 case 2: snprintf( buf, len, "STC VBR, R%d", RN(ir) ); break;
77 case 3: snprintf( buf, len, "STC SSR, R%d", RN(ir) ); break;
78 case 4: snprintf( buf, len, "STC SPC, R%d", RN(ir) ); break;
79 case 8: case 9: case 10: case 11: case 12: case 13: case 14:
80 case 15:snprintf( buf, len, "STC R%d_bank, R%d", RN_BANK(ir), RN(ir) ); break;
81 default: UNIMP(ir);
82 }
83 break;
84 case 3:
85 switch( (ir&0x00F0)>>4 ) {
86 case 0: snprintf( buf, len, "BSRF R%d", RN(ir) ); break;
87 case 2: snprintf( buf, len, "BRAF R%d", RN(ir) ); break;
88 case 8: snprintf( buf, len, "PREF [R%d]", RN(ir) ); break;
89 case 9: snprintf( buf, len, "OCBI [R%d]", RN(ir) ); break;
90 case 10:snprintf( buf, len, "OCBP [R%d]", RN(ir) ); break;
91 case 11:snprintf( buf, len, "OCBWB [R%d]", RN(ir) ); break;
92 case 12:snprintf( buf, len, "MOVCA.L R0, [R%d]", RN(ir) ); break;
93 default: UNIMP(ir);
94 }
95 break;
96 case 4: snprintf( buf, len, "MOV.B R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
97 case 5: snprintf( buf, len, "MOV.W R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
98 case 6: snprintf( buf, len, "MOV.L R%d, [R0+R%d]", RM(ir), RN(ir) ); break;
99 case 7: snprintf( buf, len, "MUL.L R%d, R%d", RM(ir), RN(ir) ); break;
100 case 8:
101 switch( (ir&0x0FF0)>>4 ) {
102 case 0: snprintf( buf, len, "CLRT " ); break;
103 case 1: snprintf( buf, len, "SETT " ); break;
104 case 2: snprintf( buf, len, "CLRMAC " ); break;
105 case 3: snprintf( buf, len, "LDTLB " ); break;
106 case 4: snprintf( buf, len, "CLRS " ); break;
107 case 5: snprintf( buf, len, "SETS " ); break;
108 default: UNIMP(ir);
109 }
110 break;
111 case 9:
112 if( (ir&0x00F0) == 0x20 )
113 snprintf( buf, len, "MOVT R%d", RN(ir) );
114 else if( ir == 0x0019 )
115 snprintf( buf, len, "DIV0U " );
116 else if( ir == 0x0009 )
117 snprintf( buf, len, "NOP " );
118 else UNIMP(ir);
119 break;
120 case 10:
121 switch( (ir&0x00F0) >> 4 ) {
122 case 0: snprintf( buf, len, "STS MACH, R%d", RN(ir) ); break;
123 case 1: snprintf( buf, len, "STS MACL, R%d", RN(ir) ); break;
124 case 2: snprintf( buf, len, "STS PR, R%d", RN(ir) ); break;
125 case 3: snprintf( buf, len, "STC SGR, R%d", RN(ir) ); break;
126 case 5: snprintf( buf, len, "STS FPUL, R%d", RN(ir) ); break;
127 case 6: snprintf( buf, len, "STS FPSCR, R%d", RN(ir) ); break;
128 case 15:snprintf( buf, len, "STC DBR, R%d", RN(ir) ); break;
129 default: UNIMP(ir);
130 }
131 break;
132 case 11:
133 switch( (ir&0x0FF0)>>4 ) {
134 case 0: snprintf( buf, len, "RTS " ); break;
135 case 1: snprintf( buf, len, "SLEEP " ); break;
136 case 2: snprintf( buf, len, "RTE " ); break;
137 default:UNIMP(ir);
138 }
139 break;
140 case 12:snprintf( buf, len, "MOV.B [R0+R%d], R%d", RM(ir), RN(ir) ); break;
141 case 13:snprintf( buf, len, "MOV.W [R0+R%d], R%d", RM(ir), RN(ir) ); break;
142 case 14:snprintf( buf, len, "MOV.L [R0+R%d], R%d", RM(ir), RN(ir) ); break;
143 case 15:snprintf( buf, len, "MAC.L [R%d++], [R%d++]", RM(ir), RN(ir) ); break;
144 default: UNIMP(ir);
145 }
146 break;
147 case 1: /* 0001nnnnmmmmdddd */
148 snprintf( buf, len, "MOV.L R%d, [R%d%+d]", RM(ir), RN(ir), DISP4(ir)<<2 ); break;
149 case 2: /* 0010nnnnmmmmxxxx */
150 switch( ir&0x000F ) {
151 case 0: snprintf( buf, len, "MOV.B R%d, [R%d]", RM(ir), RN(ir) ); break;
152 case 1: snprintf( buf, len, "MOV.W R%d, [R%d]", RM(ir), RN(ir) ); break;
153 case 2: snprintf( buf, len, "MOV.L R%d, [R%d]", RM(ir), RN(ir) ); break;
154 case 3: UNIMP(ir); break;
155 case 4: snprintf( buf, len, "MOV.B R%d, [--R%d]", RM(ir), RN(ir) ); break;
156 case 5: snprintf( buf, len, "MOV.W R%d, [--R%d]", RM(ir), RN(ir) ); break;
157 case 6: snprintf( buf, len, "MOV.L R%d, [--R%d]", RM(ir), RN(ir) ); break;
158 case 7: snprintf( buf, len, "DIV0S R%d, R%d", RM(ir), RN(ir) ); break;
159 case 8: snprintf( buf, len, "TST R%d, R%d", RM(ir), RN(ir) ); break;
160 case 9: snprintf( buf, len, "AND R%d, R%d", RM(ir), RN(ir) ); break;
161 case 10:snprintf( buf, len, "XOR R%d, R%d", RM(ir), RN(ir) ); break;
162 case 11:snprintf( buf, len, "OR R%d, R%d", RM(ir), RN(ir) ); break;
163 case 12:snprintf( buf, len, "CMP/STR R%d, R%d", RM(ir), RN(ir) ); break;
164 case 13:snprintf( buf, len, "XTRCT R%d, R%d", RM(ir), RN(ir) ); break;
165 case 14:snprintf( buf, len, "MULU.W R%d, R%d", RM(ir), RN(ir) ); break;
166 case 15:snprintf( buf, len, "MULS.W R%d, R%d", RM(ir), RN(ir) ); break;
167 }
168 break;
169 case 3: /* 0011nnnnmmmmxxxx */
170 switch( ir&0x000F ) {
171 case 0: snprintf( buf, len, "CMP/EQ R%d, R%d", RM(ir), RN(ir) ); break;
172 case 2: snprintf( buf, len, "CMP/HS R%d, R%d", RM(ir), RN(ir) ); break;
173 case 3: snprintf( buf, len, "CMP/GE R%d, R%d", RM(ir), RN(ir) ); break;
174 case 4: snprintf( buf, len, "DIV1 R%d, R%d", RM(ir), RN(ir) ); break;
175 case 5: snprintf( buf, len, "DMULU.L R%d, R%d", RM(ir), RN(ir) ); break;
176 case 6: snprintf( buf, len, "CMP/HI R%d, R%d", RM(ir), RN(ir) ); break;
177 case 7: snprintf( buf, len, "CMP/GT R%d, R%d", RM(ir), RN(ir) ); break;
178 case 8: snprintf( buf, len, "SUB R%d, R%d", RM(ir), RN(ir) ); break;
179 case 10:snprintf( buf, len, "SUBC R%d, R%d", RM(ir), RN(ir) ); break;
180 case 11:snprintf( buf, len, "SUBV R%d, R%d", RM(ir), RN(ir) ); break;
181 case 12:snprintf( buf, len, "ADD R%d, R%d", RM(ir), RN(ir) ); break;
182 case 13:snprintf( buf, len, "DMULS.L R%d, R%d", RM(ir), RN(ir) ); break;
183 case 14:snprintf( buf, len, "ADDC R%d, R%d", RM(ir), RN(ir) ); break;
184 case 15:snprintf( buf, len, "ADDV R%d, R%d", RM(ir), RN(ir) ); break;
185 default: UNIMP(ir);
186 }
187 break;
188 case 4: /* 0100nnnnxxxxxxxx */
189 switch( ir&0x00FF ) {
190 case 0x00: snprintf( buf, len, "SHLL R%d", RN(ir) ); break;
191 case 0x01: snprintf( buf, len, "SHLR R%d", RN(ir) ); break;
192 case 0x02: snprintf( buf, len, "STS.L MACH, [--R%d]", RN(ir) ); break;
193 case 0x03: snprintf( buf, len, "STC.L SR, [--R%d]", RN(ir) ); break;
194 case 0x04: snprintf( buf, len, "ROTL R%d", RN(ir) ); break;
195 case 0x05: snprintf( buf, len, "ROTR R%d", RN(ir) ); break;
196 case 0x06: snprintf( buf, len, "LDS.L [R%d++], MACH", RN(ir) ); break;
197 case 0x07: snprintf( buf, len, "LDC.L [R%d++], SR", RN(ir) ); break;
198 case 0x08: snprintf( buf, len, "SHLL2 R%d", RN(ir) ); break;
199 case 0x09: snprintf( buf, len, "SHLR2 R%d", RN(ir) ); break;
200 case 0x0A: snprintf( buf, len, "LDS R%d, MACH", RN(ir) ); break;
201 case 0x0B: snprintf( buf, len, "JSR [R%d]", RN(ir) ); break;
202 case 0x0E: snprintf( buf, len, "LDC R%d, SR", RN(ir) ); break;
203 case 0x10: snprintf( buf, len, "DT R%d", RN(ir) ); break;
204 case 0x11: snprintf( buf, len, "CMP/PZ R%d", RN(ir) ); break;
205 case 0x12: snprintf( buf, len, "STS.L MACL, [--R%d]", RN(ir) ); break;
206 case 0x13: snprintf( buf, len, "STC.L GBR, [--R%d]", RN(ir) ); break;
207 case 0x15: snprintf( buf, len, "CMP/PL R%d", RN(ir) ); break;
208 case 0x16: snprintf( buf, len, "LDS.L [R%d++], MACL", RN(ir) ); break;
209 case 0x17: snprintf( buf, len, "LDC.L [R%d++], GBR", RN(ir) ); break;
210 case 0x18: snprintf( buf, len, "SHLL8 R%d", RN(ir) ); break;
211 case 0x19: snprintf( buf, len, "SHLR8 R%d", RN(ir) ); break;
212 case 0x1A: snprintf( buf, len, "LDS R%d, MACL", RN(ir) ); break;
213 case 0x1B: snprintf( buf, len, "TAS.B [R%d]", RN(ir) ); break;
214 case 0x1E: snprintf( buf, len, "LDC R%d, GBR", RN(ir) ); break;
215 case 0x20: snprintf( buf, len, "SHAL R%d", RN(ir) ); break;
216 case 0x21: snprintf( buf, len, "SHAR R%d", RN(ir) ); break;
217 case 0x22: snprintf( buf, len, "STS.L PR, [--R%d]", RN(ir) ); break;
218 case 0x23: snprintf( buf, len, "STC.L VBR, [--R%d]", RN(ir) ); break;
219 case 0x24: snprintf( buf, len, "ROTCL R%d", RN(ir) ); break;
220 case 0x25: snprintf( buf, len, "ROTCR R%d", RN(ir) ); break;
221 case 0x26: snprintf( buf, len, "LDS.L [R%d++], PR", RN(ir) ); break;
222 case 0x27: snprintf( buf, len, "LDC.L [R%d++], VBR", RN(ir) ); break;
223 case 0x28: snprintf( buf, len, "SHLL16 R%d", RN(ir) ); break;
224 case 0x29: snprintf( buf, len, "SHLR16 R%d", RN(ir) ); break;
225 case 0x2A: snprintf( buf, len, "LDS R%d, PR", RN(ir) ); break;
226 case 0x2B: snprintf( buf, len, "JMP [R%d]", RN(ir) ); break;
227 case 0x2E: snprintf( buf, len, "LDC R%d, VBR", RN(ir) ); break;
228 case 0x32: snprintf( buf, len, "STC.L SGR, [--R%d]", RN(ir) ); break;
229 case 0x33: snprintf( buf, len, "STC.L SSR, [--R%d]", RN(ir) ); break;
230 case 0x37: snprintf( buf, len, "LDC.L [R%d++], SSR", RN(ir) ); break;
231 case 0x3E: snprintf( buf, len, "LDC R%d, SSR", RN(ir) ); break;
232 case 0x43: snprintf( buf, len, "STC.L SPC, [--R%d]", RN(ir) ); break;
233 case 0x47: snprintf( buf, len, "LDC.L [R%d++], SPC", RN(ir) ); break;
234 case 0x4E: snprintf( buf, len, "LDC R%d, SPC", RN(ir) ); break;
235 case 0x52: snprintf( buf, len, "STS.L FPUL, [--R%d]", RN(ir) ); break;
236 case 0x56: snprintf( buf, len, "LDS.L [R%d++], FPUL", RN(ir) ); break;
237 case 0x5A: snprintf( buf, len, "LDS R%d, FPUL", RN(ir) ); break;
238 case 0x62: snprintf( buf, len, "STS.L FPSCR, [--R%d]", RN(ir) ); break;
239 case 0x66: snprintf( buf, len, "LDS.L [R%d++], FPSCR", RN(ir) ); break;
240 case 0x6A: snprintf( buf, len, "LDS R%d, FPSCR", RN(ir) ); break;
241 case 0xF2: snprintf( buf, len, "STC.L DBR, [--R%d]", RN(ir) ); break;
242 case 0xF6: snprintf( buf, len, "LDC.L [R%d++], DBR", RN(ir) ); break;
243 case 0xFA: snprintf( buf, len, "LDC R%d, DBR", RN(ir) ); break;
244 case 0x83: case 0x93: case 0xA3: case 0xB3: case 0xC3: case 0xD3: case 0xE3:
245 case 0xF3: snprintf( buf, len, "STC.L R%d_BANK, [--R%d]", RN_BANK(ir), RN(ir) ); break;
246 case 0x87: case 0x97: case 0xA7: case 0xB7: case 0xC7: case 0xD7: case 0xE7:
247 case 0xF7: snprintf( buf, len, "LDC.L [R%d++], R%d_BANK", RN(ir), RN_BANK(ir) ); break;
248 case 0x8E: case 0x9E: case 0xAE: case 0xBE: case 0xCE: case 0xDE: case 0xEE:
249 case 0xFE: snprintf( buf, len, "LDC R%d, R%d_BANK", RN(ir), RN_BANK(ir) ); break;
250 default:
251 if( (ir&0x000F) == 0x0F ) {
252 snprintf( buf, len, "MAC.W [R%d++], [R%d++]", RM(ir), RN(ir) );
253 } else if( (ir&0x000F) == 0x0C ) {
254 snprintf( buf, len, "SHAD R%d, R%d", RM(ir), RN(ir) );
255 } else if( (ir&0x000F) == 0x0D ) {
256 snprintf( buf, len, "SHLD R%d, R%d", RM(ir), RN(ir) );
257 } else UNIMP(ir);
258 }
259 break;
260 case 5: /* 0101nnnnmmmmdddd */
261 snprintf( buf, len, "MOV.L [R%d%+d], R%d", RM(ir), DISP4(ir)<<2, RN(ir) ); break;
262 case 6: /* 0110xxxxxxxxxxxx */
263 switch( ir&0x000f ) {
264 case 0: snprintf( buf, len, "MOV.B [R%d], R%d", RM(ir), RN(ir) ); break;
265 case 1: snprintf( buf, len, "MOV.W [R%d], R%d", RM(ir), RN(ir) ); break;
266 case 2: snprintf( buf, len, "MOV.L [R%d], R%d", RM(ir), RN(ir) ); break;
267 case 3: snprintf( buf, len, "MOV R%d, R%d", RM(ir), RN(ir) ); break;
268 case 4: snprintf( buf, len, "MOV.B [R%d++], R%d", RM(ir), RN(ir) ); break;
269 case 5: snprintf( buf, len, "MOV.W [R%d++], R%d", RM(ir), RN(ir) ); break;
270 case 6: snprintf( buf, len, "MOV.L [R%d++], R%d", RM(ir), RN(ir) ); break;
271 case 7: snprintf( buf, len, "NOT R%d, R%d", RM(ir), RN(ir) ); break;
272 case 8: snprintf( buf, len, "SWAP.B R%d, R%d", RM(ir), RN(ir) ); break;
273 case 9: snprintf( buf, len, "SWAP.W R%d, R%d", RM(ir), RN(ir) ); break;
274 case 10:snprintf( buf, len, "NEGC R%d, R%d", RM(ir), RN(ir) ); break;
275 case 11:snprintf( buf, len, "NEG R%d, R%d", RM(ir), RN(ir) ); break;
276 case 12:snprintf( buf, len, "EXTU.B R%d, R%d", RM(ir), RN(ir) ); break;
277 case 13:snprintf( buf, len, "EXTU.W R%d, R%d", RM(ir), RN(ir) ); break;
278 case 14:snprintf( buf, len, "EXTS.B R%d, R%d", RM(ir), RN(ir) ); break;
279 case 15:snprintf( buf, len, "EXTS.W R%d, R%d", RM(ir), RN(ir) ); break;
280 }
281 break;
282 case 7: /* 0111nnnniiiiiiii */
283 snprintf( buf, len, "ADD #%d, R%d", SIGNEXT8(ir&0x00FF), RN(ir) ); break;
284 case 8: /* 1000xxxxxxxxxxxx */
285 switch( (ir&0x0F00) >> 8 ) {
286 case 0: snprintf( buf, len, "MOV.B R0, [R%d%+d]", RM(ir), DISP4(ir) ); break;
287 case 1: snprintf( buf, len, "MOV.W R0, [R%d%+d]", RM(ir), DISP4(ir)<<1 ); break;
288 case 4: snprintf( buf, len, "MOV.B [R%d%+d], R0", RM(ir), DISP4(ir) ); break;
289 case 5: snprintf( buf, len, "MOV.W [R%d%+d], R0", RM(ir), DISP4(ir)<<1 ); break;
290 case 8: snprintf( buf, len, "CMP/EQ #%d, R0", IMM8(ir) ); break;
291 case 9: snprintf( buf, len, "BT $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
292 case 11:snprintf( buf, len, "BF $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
293 case 13:snprintf( buf, len, "BT/S $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
294 case 15:snprintf( buf, len, "BF/S $%xh", (PCDISP8(ir)<<1)+pc+4 ); break;
295 default: UNIMP(ir);
296 }
297 break;
298 case 9: /* 1001xxxxxxxxxxxx */
299 snprintf( buf, len, "MOV.W [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<1)+pc+4, RN(ir),
300 sh4_read_word( (DISP8(ir)<<1)+pc+4 ) ); break;
301 case 10:/* 1010xxxxxxxxxxxx */
302 snprintf( buf, len, "BRA $%xh", (DISP12(ir)<<1)+pc+4 ); break;
303 case 11:/* 1011xxxxxxxxxxxx */
304 snprintf( buf, len, "BSR $%xh", (DISP12(ir)<<1)+pc+4 ); break;
305 case 12:/* 1100xxxxdddddddd */
306 switch( (ir&0x0F00)>>8 ) {
307 case 0: snprintf( buf, len, "MOV.B R0, [GBR%+d]", DISP8(ir) ); break;
308 case 1: snprintf( buf, len, "MOV.W R0, [GBR%+d]", DISP8(ir)<<1 ); break;
309 case 2: snprintf( buf, len, "MOV.L R0, [GBR%+d]", DISP8(ir)<<2 ); break;
310 case 3: snprintf( buf, len, "TRAPA #%d", UIMM8(ir) ); break;
311 case 4: snprintf( buf, len, "MOV.B [GBR%+d], R0", DISP8(ir) ); break;
312 case 5: snprintf( buf, len, "MOV.W [GBR%+d], R0", DISP8(ir)<<1 ); break;
313 case 6: snprintf( buf, len, "MOV.L [GBR%+d], R0", DISP8(ir)<<2 ); break;
314 case 7: snprintf( buf, len, "MOVA $%xh, R0", (DISP8(ir)<<2)+(pc&~3)+4 ); break;
315 case 8: snprintf( buf, len, "TST #%02Xh, R0", UIMM8(ir) ); break;
316 case 9: snprintf( buf, len, "AND #%02Xh, R0", UIMM8(ir) ); break;
317 case 10:snprintf( buf, len, "XOR #%02Xh, R0", UIMM8(ir) ); break;
318 case 11:snprintf( buf, len, "OR #%02Xh, R0", UIMM8(ir) ); break;
319 case 12:snprintf( buf, len, "TST.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
320 case 13:snprintf( buf, len, "AND.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
321 case 14:snprintf( buf, len, "XOR.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
322 case 15:snprintf( buf, len, "OR.B #%02Xh, [R0+GBR]", UIMM8(ir) ); break;
323 }
324 break;
325 case 13:/* 1101xxxxxxxxxxxx */
326 snprintf( buf, len, "MOV.L [$%xh], R%-2d ; <- #%08x", (DISP8(ir)<<2)+(pc&~3)+4, RN(ir),
327 sh4_read_long( (DISP8(ir)<<2)+(pc&~3)+4 ) ); break;
328 case 14:/* 1110xxxxxxxxxxxx */
329 snprintf( buf, len, "MOV #%d, R%d", DISP8(ir), RN(ir)); break;
330 case 15:/* 1111xxxxxxxxxxxx */
331 switch( ir&0x000F ) {
332 case 0: snprintf( buf, len, "FADD FR%d, FR%d", RM(ir), RN(ir) ); break;
333 case 1: snprintf( buf, len, "FSUB FR%d, FR%d", RM(ir), RN(ir) ); break;
334 case 2: snprintf( buf, len, "FMUL FR%d, FR%d", RM(ir), RN(ir) ); break;
335 case 3: snprintf( buf, len, "FDIV FR%d, FR%d", RM(ir), RN(ir) ); break;
336 case 4: snprintf( buf, len, "FCMP/EQ FR%d, FR%d", RM(ir), RN(ir) ); break;
337 case 5: snprintf( buf, len, "FCMP/GT FR%d, FR%d", RM(ir), RN(ir) ); break;
338 case 6: snprintf( buf, len, "FMOV.S [R%d+R0], FR%d", RM(ir), RN(ir) ); break;
339 case 7: snprintf( buf, len, "FMOV.S FR%d, [R%d+R0]", RM(ir), RN(ir) ); break;
340 case 8: snprintf( buf, len, "FMOV.S [R%d], FR%d", RM(ir), RN(ir) ); break;
341 case 9: snprintf( buf, len, "FMOV.S [R%d++], FR%d", RM(ir), RN(ir) ); break;
342 case 10:snprintf( buf, len, "FMOV.S FR%d, [R%d]", RM(ir), RN(ir) ); break;
343 case 11:snprintf( buf, len, "FMOV.S FR%d, [--R%d]", RM(ir), RN(ir) ); break;
344 case 12:snprintf( buf, len, "FMOV FR%d, FR%d", RM(ir), RN(ir) ); break;
345 case 13:
346 switch( (ir&0x00F0) >> 4 ) {
347 case 0: snprintf( buf, len, "FSTS FPUL, FR%d", RN(ir) ); break;
348 case 1: snprintf( buf, len, "FLDS FR%d, FPUL", RN(ir) ); break;
349 case 2: snprintf( buf, len, "FLOAT FPUL, FR%d", RN(ir) ); break;
350 case 3: snprintf( buf, len, "FTRC FR%d, FPUL", RN(ir) ); break;
351 case 4: snprintf( buf, len, "FNEG FR%d", RN(ir) ); break;
352 case 5: snprintf( buf, len, "FABS FR%d", RN(ir) ); break;
353 case 6: snprintf( buf, len, "FSQRT FR%d", RN(ir) ); break;
354 case 7: snprintf( buf, len, "FSRRA FR%d", RN(ir) ); break;
355 case 8: snprintf( buf, len, "FLDI0 FR%d", RN(ir) ); break;
356 case 9: snprintf( buf, len, "FLDI1 FR%d", RN(ir) ); break;
357 case 10:snprintf( buf, len, "FCNVSD FPUL, DR%d", RN(ir)>>1 ); break;
358 case 11:snprintf( buf, len, "FCNVDS DR%d, FPUL", RN(ir)>>1 ); break;
359 case 14:snprintf( buf, len, "FIPR FV%d, FV%d", FVM(ir), FVN(ir) ); break;
360 case 15:
361 if( (ir & 0x0300) == 0x0100 )
362 snprintf( buf, len, "FTRV XMTRX,FV%d", FVN(ir) );
363 else if( (ir & 0x0100) == 0 )
364 snprintf( buf, len, "FSCA FPUL, DR%d", RN(ir) );
365 else if( ir == 0xFBFD )
366 snprintf( buf, len, "FRCHG " );
367 else if( ir == 0xF3FD )
368 snprintf( buf, len, "FSCHG " );
369 else UNIMP(ir);
370 break;
371 default: UNIMP(ir);
372 }
373 break;
374 case 14:snprintf( buf, len, "FMAC FR0, FR%d, FR%d", RM(ir), RN(ir) ); break;
375 default: UNIMP(ir);
376 }
377 break;
378 }
379 return pc+2;
380 }
383 void sh4_disasm_region( const gchar *filename, int from, int to )
384 {
385 int pc;
386 char buf[80];
387 char opcode[16];
388 FILE *f;
390 f = fopen( filename, "w" );
391 for( pc = from; pc < to; pc+=2 ) {
392 buf[0] = '\0';
393 sh4_disasm_instruction( pc,
394 buf, sizeof(buf), opcode );
395 fprintf( f, " %08x: %s %s\n", pc, opcode, buf );
396 }
397 fclose(f);
398 }
.