1 /*###################################################################################################
2 **
3 **
4 ** 4600dasm.c
5 ** Disassembler for the portable R4600 emulator.
6 ** Written by Aaron Giles
7 **
8 **
9 **#################################################################################################*/
10
11 #include <stdio.h>
12
13 #include "driver.h"
14 #include "r3000.h"
15
16
17 static const char *reg[32] =
18 {
19 "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
20 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
21 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
22 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
23 };
24
25
26 static const char *cpreg[4][32] =
27 {
28 {
29 "Index","Random","EntryLo0","EntryLo1","Context","PageMask","Wired","Error",
30 "BadVAddr","Count","EntryHi","Compare","SR","Cause","EPC","PRId",
31 "Config","LLAddr","WatchLo","WatchHi","XContext","cpr21","cpr22","cpr23",
32 "cpr24","cpr25","ECC","CacheError","TagLo","TagHi","ErrorEPC","cpr31"
33 },
34 {
35 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
36 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
37 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
38 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
39 },
40 {
41 "cpr0", "cpr1", "cpr2", "cpr3", "cpr4", "cpr5", "cpr6", "cpr7",
42 "cpr8", "cpr9", "cpr10","cpr11","cpr12","cpr13","cpr14","cpr15",
43 "cpr16","cpr17","cpr18","cpr19","cpr20","cpr21","cpr22","cpr23",
44 "cpr24","cpr25","cpr26","cpr27","cpr28","cpr29","cpr30","cpr31"
45 },
46 {
47 "cpr0", "cpr1", "cpr2", "cpr3", "cpr4", "cpr5", "cpr6", "cpr7",
48 "cpr8", "cpr9", "cpr10","cpr11","cpr12","cpr13","cpr14","cpr15",
49 "cpr16","cpr17","cpr18","cpr19","cpr20","cpr21","cpr22","cpr23",
50 "cpr24","cpr25","cpr26","cpr27","cpr28","cpr29","cpr30","cpr31"
51 }
52 };
53
54
55 static const char *ccreg[4][32] =
56 {
57 {
58 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
59 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
60 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
61 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
62 },
63 {
64 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
65 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
66 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
67 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
68 },
69 {
70 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
71 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
72 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
73 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
74 },
75 {
76 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
77 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
78 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
79 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
80 }
81 };
82
83
84 /*###################################################################################################
85 ** MEMORY ACCESSORS
86 **#################################################################################################*/
87
88 #define ROPCODE(pc) cpu_readop32(pc)
89
90
91 /*###################################################################################################
92 ** CODE CODE
93 **#################################################################################################*/
94
signed_16bit(INT16 val)95 static INLINE char *signed_16bit(INT16 val)
96 {
97 static char temp[10];
98 if (val < 0)
99 sprintf(temp, "-$%x", -val);
100 else
101 sprintf(temp, "$%x", val);
102 return temp;
103 }
104
dasm_cop0(UINT32 pc,UINT32 op,char * buffer)105 static void dasm_cop0(UINT32 pc, UINT32 op, char *buffer)
106 {
107 int rt = (op >> 16) & 31;
108 int rd = (op >> 11) & 31;
109
110 switch ((op >> 21) & 31)
111 {
112 case 0x00: sprintf(buffer, "mfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
113 case 0x01: sprintf(buffer, "dmfc0 %s,%s", reg[rt], cpreg[0][rd]); break;
114 case 0x02: sprintf(buffer, "cfc0 %s,%s", reg[rt], ccreg[0][rd]); break;
115 case 0x04: sprintf(buffer, "mtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
116 case 0x05: sprintf(buffer, "dmtc0 %s,%s", reg[rt], cpreg[0][rd]); break;
117 case 0x06: sprintf(buffer, "ctc0 %s,%s", reg[rt], ccreg[0][rd]); break;
118 case 0x08: /* BC */
119 switch (rt)
120 {
121 case 0x00: sprintf(buffer, "bc0f $%08x", pc + 4 + ((INT16)op << 2)); break;
122 case 0x01: sprintf(buffer, "bc0t $%08x", pc + 4 + ((INT16)op << 2)); break;
123 case 0x02: sprintf(buffer, "bc0fl [invalid]"); break;
124 case 0x03: sprintf(buffer, "bc0tl [invalid]"); break;
125 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
126 }
127 break;
128 case 0x10:
129 case 0x11:
130 case 0x12:
131 case 0x13:
132 case 0x14:
133 case 0x15:
134 case 0x16:
135 case 0x17:
136 case 0x18:
137 case 0x19:
138 case 0x1a:
139 case 0x1b:
140 case 0x1c:
141 case 0x1d:
142 case 0x1e:
143 case 0x1f: /* COP */
144 switch (op & 0x01ffffff)
145 {
146 case 0x01: sprintf(buffer, "tlbr"); break;
147 case 0x02: sprintf(buffer, "tlbwi"); break;
148 case 0x06: sprintf(buffer, "tlbwr"); break;
149 case 0x08: sprintf(buffer, "tlbp"); break;
150 case 0x10: sprintf(buffer, "rfe"); break;
151 case 0x18: sprintf(buffer, "eret [invalid]"); break;
152 default: sprintf(buffer, "cop0 $%07x", op & 0x01ffffff); break;
153 }
154 break;
155 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
156 }
157 }
158
dasm_cop1(UINT32 pc,UINT32 op,char * buffer)159 static void dasm_cop1(UINT32 pc, UINT32 op, char *buffer)
160 {
161 static const char *format_table[] =
162 {
163 "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
164 "s","d","?","?","w","l","?","?","?","?","?","?","?","?","?","?"
165 };
166 const char *fmt = format_table[(op >> 21) & 31];
167 int ft = (op >> 16) & 31;
168 int fs = (op >> 11) & 31;
169 int fd = (op >> 6) & 31;
170 int rt = (op >> 16) & 31;
171 int rd = (op >> 11) & 31;
172
173 switch ((op >> 21) & 31)
174 {
175 case 0x00: sprintf(buffer, "mfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
176 case 0x01: sprintf(buffer, "dmfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
177 case 0x02: sprintf(buffer, "cfc1 %s,%s", reg[rt], ccreg[1][rd]); break;
178 case 0x04: sprintf(buffer, "mtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
179 case 0x05: sprintf(buffer, "dmtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
180 case 0x06: sprintf(buffer, "ctc1 %s,%s", reg[rt], ccreg[1][rd]); break;
181 case 0x08: /* BC */
182 switch (rt & 3)
183 {
184 case 0x00: sprintf(buffer, "bc1f $%08x,%d", pc + 4 + ((INT16)op << 2), (op >> 18) & 7); break;
185 case 0x01: sprintf(buffer, "bc1t $%08x,%d", pc + 4 + ((INT16)op << 2), (op >> 18) & 7); break;
186 case 0x02: sprintf(buffer, "bc1fl $%08x,%d", pc + 4 + ((INT16)op << 2), (op >> 18) & 7); break;
187 case 0x03: sprintf(buffer, "bc1tl $%08x,%d", pc + 4 + ((INT16)op << 2), (op >> 18) & 7); break;
188 }
189 break;
190 default: /* COP */
191 switch (op & 0x3f)
192 {
193 case 0x00: sprintf(buffer, "add.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
194 case 0x01: sprintf(buffer, "sub.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
195 case 0x02: sprintf(buffer, "mul.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
196 case 0x03: sprintf(buffer, "div.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
197 case 0x04: sprintf(buffer, "sqrt.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
198 case 0x05: sprintf(buffer, "abs.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
199 case 0x06: sprintf(buffer, "mov.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
200 case 0x07: sprintf(buffer, "neg.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
201 case 0x08: sprintf(buffer, "round.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
202 case 0x09: sprintf(buffer, "trunc.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
203 case 0x0a: sprintf(buffer, "ceil.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
204 case 0x0b: sprintf(buffer, "floor.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
205 case 0x0c: sprintf(buffer, "round.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
206 case 0x0d: sprintf(buffer, "trunc.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
207 case 0x0e: sprintf(buffer, "ceil.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
208 case 0x0f: sprintf(buffer, "floor.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
209 case 0x11: sprintf(buffer, "mov%c.%s %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', fmt, cpreg[1][fd], cpreg[1][fs], (op >> 18) & 7); break;
210 case 0x12: sprintf(buffer, "movz.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
211 case 0x13: sprintf(buffer, "movn.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
212 case 0x15: sprintf(buffer, "recip.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
213 case 0x16: sprintf(buffer, "rsqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
214 case 0x20: sprintf(buffer, "cvt.s.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
215 case 0x21: sprintf(buffer, "cvt.d.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
216 case 0x24: sprintf(buffer, "cvt.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
217 case 0x25: sprintf(buffer, "cvt.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
218 case 0x30: sprintf(buffer, "c.f.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
219 case 0x31: sprintf(buffer, "c.un.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
220 case 0x32: sprintf(buffer, "c.eq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
221 case 0x33: sprintf(buffer, "c.ueq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
222 case 0x34: sprintf(buffer, "c.olt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
223 case 0x35: sprintf(buffer, "c.ult.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
224 case 0x36: sprintf(buffer, "c.ole.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
225 case 0x37: sprintf(buffer, "c.ule.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
226 case 0x38: sprintf(buffer, "c.sf.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
227 case 0x39: sprintf(buffer, "c.ngle.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7);break;
228 case 0x3a: sprintf(buffer, "c.seq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
229 case 0x3b: sprintf(buffer, "c.ngl.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
230 case 0x3c: sprintf(buffer, "c.lt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
231 case 0x3d: sprintf(buffer, "c.nge.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
232 case 0x3e: sprintf(buffer, "c.le.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
233 case 0x3f: sprintf(buffer, "c.ngt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
234 default: sprintf(buffer, "cop1 $%07x", op & 0x01ffffff); break;
235 }
236 break;
237 }
238 }
239
dasm_cop1x(UINT32 pc,UINT32 op,char * buffer)240 static void dasm_cop1x(UINT32 pc, UINT32 op, char *buffer)
241 {
242 static const char *format3_table[] =
243 {
244 "s","d","?","?","w","l","?","?"
245 };
246 const char *fmt3 = format3_table[op & 7];
247 int fr = (op >> 21) & 31;
248 int ft = (op >> 16) & 31;
249 int fs = (op >> 11) & 31;
250 int fd = (op >> 6) & 31;
251 int rs = (op >> 21) & 31;
252 int rt = (op >> 16) & 31;
253 int rd = (op >> 11) & 31;
254
255 switch (op & 0x3f)
256 {
257 case 0x00: sprintf(buffer, "lwxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
258 case 0x01: sprintf(buffer, "ldxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
259 case 0x08: sprintf(buffer, "swxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
260 case 0x09: sprintf(buffer, "sdxc1 %s,%s(%s)", cpreg[1][fd], reg[rt], reg[rs]); break;
261 case 0x0f: sprintf(buffer, "prefx %d,%s(%s)", rd, reg[rt], reg[rs]); break;
262 case 0x20:
263 case 0x21:
264 case 0x22:
265 case 0x23:
266 case 0x24:
267 case 0x25:
268 case 0x26:
269 case 0x27: sprintf(buffer, "madd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
270 case 0x28:
271 case 0x29:
272 case 0x2a:
273 case 0x2b:
274 case 0x2c:
275 case 0x2d:
276 case 0x2e:
277 case 0x2f: sprintf(buffer, "msub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
278 case 0x30:
279 case 0x31:
280 case 0x32:
281 case 0x33:
282 case 0x34:
283 case 0x35:
284 case 0x36:
285 case 0x37: sprintf(buffer, "nmadd.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
286 case 0x38:
287 case 0x39:
288 case 0x3a:
289 case 0x3b:
290 case 0x3c:
291 case 0x3d:
292 case 0x3e:
293 case 0x3f: sprintf(buffer, "nmsub.%s %s,%s,%s,%s", fmt3, cpreg[1][fd], cpreg[1][fr], cpreg[1][fs], cpreg[1][ft]); break;
294 default: sprintf(buffer, "cop1 $%07x", op & 0x01ffffff); break;
295 }
296 }
297
dasm_cop2(UINT32 pc,UINT32 op,char * buffer)298 static void dasm_cop2(UINT32 pc, UINT32 op, char *buffer)
299 {
300 int rt = (op >> 16) & 31;
301 int rd = (op >> 11) & 31;
302
303 switch ((op >> 21) & 31)
304 {
305 case 0x00: sprintf(buffer, "mfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
306 case 0x01: sprintf(buffer, "dmfc2 %s,%s", reg[rt], cpreg[2][rd]); break;
307 case 0x02: sprintf(buffer, "cfc2 %s,%s", reg[rt], ccreg[2][rd]); break;
308 case 0x04: sprintf(buffer, "mtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
309 case 0x05: sprintf(buffer, "dmtc2 %s,%s", reg[rt], cpreg[2][rd]); break;
310 case 0x06: sprintf(buffer, "ctc2 %s,%s", reg[rt], ccreg[2][rd]); break;
311 case 0x08: /* BC */
312 switch (rt)
313 {
314 case 0x00: sprintf(buffer, "bc2f $%08x", pc + 4 + ((INT16)op << 2)); break;
315 case 0x01: sprintf(buffer, "bc2t $%08x", pc + 4 + ((INT16)op << 2)); break;
316 case 0x02: sprintf(buffer, "bc2fl [invalid]"); break;
317 case 0x03: sprintf(buffer, "bc2tl [invalid]"); break;
318 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
319 }
320 break;
321 case 0x10:
322 case 0x11:
323 case 0x12:
324 case 0x13:
325 case 0x14:
326 case 0x15:
327 case 0x16:
328 case 0x17:
329 case 0x18:
330 case 0x19:
331 case 0x1a:
332 case 0x1b:
333 case 0x1c:
334 case 0x1d:
335 case 0x1e:
336 case 0x1f: /* COP */
337 sprintf(buffer, "cop2 $%07x", op & 0x01ffffff);
338 break;
339 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
340 }
341 }
342
dasmmips3(char * buffer,unsigned pc)343 unsigned dasmmips3(char *buffer, unsigned pc)
344 {
345 UINT32 op = ROPCODE(pc);
346 int rs = (op >> 21) & 31;
347 int rt = (op >> 16) & 31;
348 int rd = (op >> 11) & 31;
349 int shift = (op >> 6) & 31;
350
351 switch (op >> 26)
352 {
353 case 0x00: /* SPECIAL */
354 switch (op & 63)
355 {
356 case 0x00: if (op == 0)
357 sprintf(buffer, "nop");
358 else
359 sprintf(buffer, "sll %s,%s,%d", reg[rd], reg[rt], shift); break;
360 case 0x01: sprintf(buffer, "mov%c %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', reg[rd], reg[rt], (op >> 18) & 7); break;
361 case 0x02: sprintf(buffer, "srl %s,%s,%d", reg[rd], reg[rt], shift); break;
362 case 0x03: sprintf(buffer, "sra %s,%s,%d", reg[rd], reg[rt], shift); break;
363 case 0x04: sprintf(buffer, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
364 case 0x06: sprintf(buffer, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
365 case 0x07: sprintf(buffer, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
366 case 0x08: sprintf(buffer, "jr %s", reg[rs]); break;
367 case 0x09: if (rd == 31)
368 sprintf(buffer, "jalr %s", reg[rs]);
369 else
370 sprintf(buffer, "jalr %s,%s", reg[rs], reg[rd]); break;
371 case 0x0a: sprintf(buffer, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
372 case 0x0b: sprintf(buffer, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
373 case 0x0c: sprintf(buffer, "syscall"); break;
374 case 0x0d: sprintf(buffer, "break"); break;
375 case 0x0f: sprintf(buffer, "sync"); break;
376 case 0x10: sprintf(buffer, "mfhi %s", reg[rd]); break;
377 case 0x11: sprintf(buffer, "mthi %s", reg[rs]); break;
378 case 0x12: sprintf(buffer, "mflo %s", reg[rd]); break;
379 case 0x13: sprintf(buffer, "mtlo %s", reg[rs]); break;
380 case 0x14: sprintf(buffer, "dsllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
381 case 0x16: sprintf(buffer, "dsrlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
382 case 0x17: sprintf(buffer, "dsrav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
383 case 0x18: sprintf(buffer, "mult %s,%s", reg[rs], reg[rt]); break;
384 case 0x19: sprintf(buffer, "multu %s,%s", reg[rs], reg[rt]); break;
385 case 0x1a: sprintf(buffer, "div %s,%s", reg[rs], reg[rt]); break;
386 case 0x1b: sprintf(buffer, "divu %s,%s", reg[rs], reg[rt]); break;
387 case 0x1c: sprintf(buffer, "dmult %s,%s", reg[rs], reg[rt]); break;
388 case 0x1d: sprintf(buffer, "dmultu %s,%s", reg[rs], reg[rt]); break;
389 case 0x1e: sprintf(buffer, "ddiv %s,%s", reg[rs], reg[rt]); break;
390 case 0x1f: sprintf(buffer, "ddivu %s,%s", reg[rs], reg[rt]); break;
391 case 0x20: sprintf(buffer, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
392 case 0x21: sprintf(buffer, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
393 case 0x22: sprintf(buffer, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
394 case 0x23: sprintf(buffer, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
395 case 0x24: sprintf(buffer, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
396 case 0x25: sprintf(buffer, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
397 case 0x26: sprintf(buffer, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
398 case 0x27: sprintf(buffer, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
399 case 0x2a: sprintf(buffer, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
400 case 0x2b: sprintf(buffer, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
401 case 0x2c: sprintf(buffer, "dadd %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
402 case 0x2d: sprintf(buffer, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
403 case 0x2e: sprintf(buffer, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
404 case 0x2f: sprintf(buffer, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
405 case 0x30: sprintf(buffer, "tge %s,%s", reg[rs], reg[rt]); break;
406 case 0x31: sprintf(buffer, "tgeu %s,%s", reg[rs], reg[rt]); break;
407 case 0x32: sprintf(buffer, "tlt %s,%s", reg[rs], reg[rt]); break;
408 case 0x33: sprintf(buffer, "tltu %s,%s", reg[rs], reg[rt]); break;
409 case 0x34: sprintf(buffer, "teq %s,%s", reg[rs], reg[rt]); break;
410 case 0x36: sprintf(buffer, "tne %s,%s", reg[rs], reg[rt]); break;
411 case 0x38: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break;
412 case 0x3a: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break;
413 case 0x3b: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break;
414 case 0x3c: sprintf(buffer, "dsll %s,%s,%d", reg[rd], reg[rt], shift+32); break;
415 case 0x3e: sprintf(buffer, "dsrl %s,%s,%d", reg[rd], reg[rt], shift+32); break;
416 case 0x3f: sprintf(buffer, "dsra %s,%s,%d", reg[rd], reg[rt], shift+32); break;
417 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
418 }
419 break;
420
421 case 0x01: /* REGIMM */
422 switch ((op >> 16) & 31)
423 {
424 case 0x00: sprintf(buffer, "bltz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
425 case 0x01: sprintf(buffer, "bgez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
426 case 0x02: sprintf(buffer, "bltzl %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
427 case 0x03: sprintf(buffer, "bgezl %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
428 case 0x08: sprintf(buffer, "tgei %s,%s", reg[rs], signed_16bit(op)); break;
429 case 0x09: sprintf(buffer, "tgeiu %s,%s", reg[rs], signed_16bit(op)); break;
430 case 0x0a: sprintf(buffer, "tlti %s,%s", reg[rs], signed_16bit(op)); break;
431 case 0x0b: sprintf(buffer, "tltiu %s,%s", reg[rs], signed_16bit(op)); break;
432 case 0x0c: sprintf(buffer, "teqi %s,%s", reg[rs], signed_16bit(op)); break;
433 case 0x0e: sprintf(buffer, "tnei %s,%s", reg[rs], signed_16bit(op)); break;
434 case 0x10: sprintf(buffer, "bltzal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
435 case 0x11: sprintf(buffer, "bgezal %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
436 case 0x12: sprintf(buffer, "bltzall %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2));break;
437 case 0x13: sprintf(buffer, "bgezall %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2));break;
438 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
439 }
440 break;
441
442 case 0x02: sprintf(buffer, "j $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break;
443 case 0x03: sprintf(buffer, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break;
444 case 0x04: if (rs == 0 && rt == 0)
445 sprintf(buffer, "b $%08x", pc + 4 + ((INT16)op << 2));
446 else
447 sprintf(buffer, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
448 case 0x05: sprintf(buffer, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
449 case 0x06: sprintf(buffer, "blez %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
450 case 0x07: sprintf(buffer, "bgtz %s,$%08x", reg[rs], pc + 4 + ((INT16)op << 2)); break;
451 case 0x08: sprintf(buffer, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
452 case 0x09: sprintf(buffer, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
453 case 0x0a: sprintf(buffer, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
454 case 0x0b: sprintf(buffer, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
455 case 0x0c: sprintf(buffer, "andi %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break;
456 case 0x0d: sprintf(buffer, "ori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break;
457 case 0x0e: sprintf(buffer, "xori %s,%s,$%04x", reg[rt], reg[rs], (UINT16)op); break;
458 case 0x0f: sprintf(buffer, "lui %s,$%04x", reg[rt], (UINT16)op); break;
459 case 0x10: dasm_cop0(pc, op, buffer); break;
460 case 0x11: dasm_cop1(pc, op, buffer); break;
461 case 0x12: dasm_cop2(pc, op, buffer); break;
462 case 0x13: dasm_cop1x(pc, op, buffer); break;
463 case 0x14: sprintf(buffer, "beql %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
464 case 0x15: sprintf(buffer, "bnel %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
465 case 0x16: sprintf(buffer, "blezl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
466 case 0x17: sprintf(buffer, "bgtzl %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((INT16)op << 2));break;
467 case 0x18: sprintf(buffer, "daddi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
468 case 0x19: sprintf(buffer, "daddiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
469 case 0x1a: sprintf(buffer, "ldl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
470 case 0x1b: sprintf(buffer, "ldr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
471 case 0x20: sprintf(buffer, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
472 case 0x21: sprintf(buffer, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
473 case 0x22: sprintf(buffer, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
474 case 0x23: sprintf(buffer, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
475 case 0x24: sprintf(buffer, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
476 case 0x25: sprintf(buffer, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
477 case 0x26: sprintf(buffer, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
478 case 0x27: sprintf(buffer, "lwu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
479 case 0x28: sprintf(buffer, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
480 case 0x29: sprintf(buffer, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
481 case 0x2a: sprintf(buffer, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
482 case 0x2b: sprintf(buffer, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
483 case 0x2c: sprintf(buffer, "sdl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
484 case 0x2d: sprintf(buffer, "sdr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
485 case 0x2e: sprintf(buffer, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
486 case 0x2f: sprintf(buffer, "cache %s(%s)", reg[rs], signed_16bit(op)); break;
487 case 0x30: sprintf(buffer, "ll %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
488 case 0x31: sprintf(buffer, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
489 case 0x32: sprintf(buffer, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
490 case 0x33: sprintf(buffer, "pref $%x,%s(%s)", rt, signed_16bit(op), reg[rs]); break;
491 case 0x34: sprintf(buffer, "lld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
492 case 0x35: sprintf(buffer, "ldc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
493 case 0x36: sprintf(buffer, "ldc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
494 case 0x37: sprintf(buffer, "ld %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
495 case 0x38: sprintf(buffer, "sc %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
496 case 0x39: sprintf(buffer, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
497 case 0x3a: sprintf(buffer, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
498 case 0x3c: sprintf(buffer, "scd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
499 case 0x3d: sprintf(buffer, "sdc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
500 case 0x3e: sprintf(buffer, "sdc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
501 case 0x3f: sprintf(buffer, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
502 default: sprintf(buffer, "dc.l $%08x [invalid]", op); break;
503 }
504 return 4;
505 }
506