1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 r3kdasm.c
6 Disassembler for the portable R3000 emulator.
7 Written by Aaron Giles
8
9 ***************************************************************************/
10
11 #include "emu.h"
12 #include "mips1dsm.h"
13
14 const char *const mips1_disassembler::reg[32] =
15 {
16 "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
17 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
18 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
19 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
20 };
21
22
23 const char *const mips1_disassembler::cpreg[4][32] =
24 {
25 {
26 "Index","Random","EntryLo","cpr3", "Context", "cpr5", "cpr6", "cpr7",
27 "BadVAddr", "cpr9", "EntryHi","cpr11","SR","Cause","EPC","PRId",
28 "cpr16","cpr17","cpr18","cpr19","cpr20","cpr21","cpr22","cpr23",
29 "cpr24","cpr25","cpr26","cpr27","cpr28","cpr29","cpr30","cpr31"
30 },
31 {
32 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
33 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
34 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
35 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
36 },
37 {
38 "cpr0", "cpr1", "cpr2", "cpr3", "cpr4", "cpr5", "cpr6", "cpr7",
39 "cpr8", "cpr9", "cpr10","cpr11","cpr12","cpr13","cpr14","cpr15",
40 "cpr16","cpr17","cpr18","cpr19","cpr20","cpr21","cpr22","cpr23",
41 "cpr24","cpr25","cpr26","cpr27","cpr28","cpr29","cpr30","cpr31"
42 },
43 {
44 "cpr0", "cpr1", "cpr2", "cpr3", "cpr4", "cpr5", "cpr6", "cpr7",
45 "cpr8", "cpr9", "cpr10","cpr11","cpr12","cpr13","cpr14","cpr15",
46 "cpr16","cpr17","cpr18","cpr19","cpr20","cpr21","cpr22","cpr23",
47 "cpr24","cpr25","cpr26","cpr27","cpr28","cpr29","cpr30","cpr31"
48 }
49 };
50
51
52 const char *const mips1_disassembler::ccreg[4][32] =
53 {
54 {
55 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
56 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
57 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
58 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
59 },
60 {
61 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
62 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
63 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
64 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
65 },
66 {
67 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
68 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
69 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
70 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
71 },
72 {
73 "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7",
74 "ccr8", "ccr9", "ccr10","ccr11","ccr12","ccr13","ccr14","ccr15",
75 "ccr16","ccr17","ccr18","ccr19","ccr20","ccr21","ccr22","ccr23",
76 "ccr24","ccr25","ccr26","ccr27","ccr28","ccr29","ccr30","ccr31"
77 }
78 };
79
80
81 /***************************************************************************
82 CODE CODE
83 ***************************************************************************/
84
signed_16bit(int16_t val)85 std::string mips1_disassembler::signed_16bit(int16_t val)
86 {
87 if (val < 0)
88 return util::string_format("-$%x", -val);
89 else
90 return util::string_format("$%x", val);
91 }
92
dasm_cop(uint32_t pc,int cop,uint32_t op,std::ostream & stream)93 uint32_t mips1_disassembler::dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream)
94 {
95 int rt = (op >> 16) & 31;
96 int rd = (op >> 11) & 31;
97 uint32_t flags = 0;
98
99 switch ((op >> 21) & 31)
100 {
101 case 0x00: util::stream_format(stream, "mfc%d %s,%s", cop, reg[rt], cpreg[cop][rd]); break;
102 case 0x02: util::stream_format(stream, "cfc%d %s,%s", cop, reg[rt], ccreg[cop][rd]); break;
103 case 0x04: util::stream_format(stream, "mtc%d %s,%s", cop, reg[rt], cpreg[cop][rd]); break;
104 case 0x06: util::stream_format(stream, "ctc%d %s,%s", cop, reg[rt], ccreg[cop][rd]); break;
105 case 0x08: /* BC */
106 switch (rt)
107 {
108 case 0x00: util::stream_format(stream, "bc%df $%08x", cop, pc + 4 + ((int16_t)op << 2)); break;
109 case 0x01: util::stream_format(stream, "bc%dt $%08x", cop, pc + 4 + ((int16_t)op << 2)); break;
110 case 0x02: util::stream_format(stream, "bc%dfl [invalid]", cop); break;
111 case 0x03: util::stream_format(stream, "bc%dtl [invalid]", cop); break;
112 default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
113 }
114 break;
115 case 0x10:
116 case 0x11:
117 case 0x12:
118 case 0x13:
119 case 0x14:
120 case 0x15:
121 case 0x16:
122 case 0x17:
123 case 0x18:
124 case 0x19:
125 case 0x1a:
126 case 0x1b:
127 case 0x1c:
128 case 0x1d:
129 case 0x1e:
130 case 0x1f: /* COP */
131 if (cop == 0)
132 {
133 switch (op & 0x01ffffff)
134 {
135 case 0x01: util::stream_format(stream, "tlbr"); break;
136 case 0x02: util::stream_format(stream, "tlbwi"); break;
137 case 0x06: util::stream_format(stream, "tlbwr"); break;
138 case 0x08: util::stream_format(stream, "tlbp"); break;
139 case 0x10: util::stream_format(stream, "rfe"); break;
140 case 0x18: util::stream_format(stream, "eret [invalid]"); break;
141 default: util::stream_format(stream, "cop%d $%07x", cop, op & 0x01ffffff); break;
142 }
143 }
144 else
145 util::stream_format(stream, "cop%d $%07x", cop, op & 0x01ffffff);
146 break;
147 default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
148 }
149
150 return flags;
151 }
152
dasm_cop1(uint32_t pc,uint32_t op,std::ostream & stream)153 uint32_t mips1_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream)
154 {
155 static const char *const format_table[] =
156 {
157 "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
158 "s","d","?","?","w","l","?","?","?","?","?","?","?","?","?","?"
159 };
160 const char *fmt = format_table[(op >> 21) & 31];
161 int ft = (op >> 16) & 31;
162 int fs = (op >> 11) & 31;
163 int fd = (op >> 6) & 31;
164 int rt = (op >> 16) & 31;
165 int rd = (op >> 11) & 31;
166 uint32_t flags = 0;
167
168 switch ((op >> 21) & 31)
169 {
170 case 0x00: util::stream_format(stream, "mfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
171 case 0x01: util::stream_format(stream, "dmfc1 %s,%s", reg[rt], cpreg[1][rd]); break;
172 case 0x02: util::stream_format(stream, "cfc1 %s,%s", reg[rt], ccreg[1][rd]); break;
173 case 0x04: util::stream_format(stream, "mtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
174 case 0x05: util::stream_format(stream, "dmtc1 %s,%s", reg[rt], cpreg[1][rd]); break;
175 case 0x06: util::stream_format(stream, "ctc1 %s,%s", reg[rt], ccreg[1][rd]); break;
176 case 0x08: /* BC */
177 switch (rt & 3)
178 {
179 case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
180 case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break;
181 case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
182 case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break;
183 }
184 break;
185 default: /* COP */
186 switch (op & 0x3f)
187 {
188 case 0x00: util::stream_format(stream, "add.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
189 case 0x01: util::stream_format(stream, "sub.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
190 case 0x02: util::stream_format(stream, "mul.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
191 case 0x03: util::stream_format(stream, "div.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], cpreg[1][ft]); break;
192 case 0x04: util::stream_format(stream, "sqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
193 case 0x05: util::stream_format(stream, "abs.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
194 case 0x06: util::stream_format(stream, "mov.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
195 case 0x07: util::stream_format(stream, "neg.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
196 case 0x08: util::stream_format(stream, "round.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
197 case 0x09: util::stream_format(stream, "trunc.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
198 case 0x0a: util::stream_format(stream, "ceil.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
199 case 0x0b: util::stream_format(stream, "floor.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
200 case 0x0c: util::stream_format(stream, "round.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
201 case 0x0d: util::stream_format(stream, "trunc.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
202 case 0x0e: util::stream_format(stream, "ceil.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
203 case 0x0f: util::stream_format(stream, "floor.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
204 case 0x11: util::stream_format(stream, "mov%c.%s %s,%s,%d", ((op >> 16) & 1) ? 't' : 'f', fmt, cpreg[1][fd], cpreg[1][fs], (op >> 18) & 7); break;
205 case 0x12: util::stream_format(stream, "movz.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
206 case 0x13: util::stream_format(stream, "movn.%s %s,%s,%s", fmt, cpreg[1][fd], cpreg[1][fs], reg[rt]); break;
207 case 0x15: util::stream_format(stream, "recip.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
208 case 0x16: util::stream_format(stream, "rsqrt.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
209 case 0x20: util::stream_format(stream, "cvt.s.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
210 case 0x21: util::stream_format(stream, "cvt.d.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
211 case 0x24: util::stream_format(stream, "cvt.w.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
212 case 0x25: util::stream_format(stream, "cvt.l.%s %s,%s", fmt, cpreg[1][fd], cpreg[1][fs]); break;
213 case 0x30: util::stream_format(stream, "c.f.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
214 case 0x31: util::stream_format(stream, "c.un.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
215 case 0x32: util::stream_format(stream, "c.eq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
216 case 0x33: util::stream_format(stream, "c.ueq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
217 case 0x34: util::stream_format(stream, "c.olt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
218 case 0x35: util::stream_format(stream, "c.ult.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
219 case 0x36: util::stream_format(stream, "c.ole.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
220 case 0x37: util::stream_format(stream, "c.ule.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
221 case 0x38: util::stream_format(stream, "c.sf.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
222 case 0x39: util::stream_format(stream, "c.ngle.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7);break;
223 case 0x3a: util::stream_format(stream, "c.seq.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
224 case 0x3b: util::stream_format(stream, "c.ngl.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
225 case 0x3c: util::stream_format(stream, "c.lt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
226 case 0x3d: util::stream_format(stream, "c.nge.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
227 case 0x3e: util::stream_format(stream, "c.le.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
228 case 0x3f: util::stream_format(stream, "c.ngt.%s %s,%s,%d", fmt, cpreg[1][fs], cpreg[1][ft], (op >> 8) & 7); break;
229 default: util::stream_format(stream, "cop1 $%07x", op & 0x01ffffff); break;
230 }
231 break;
232 }
233 return flags;
234 }
235
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)236 offs_t mips1_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
237 {
238 uint32_t op = opcodes.r32(pc);
239 int rs = (op >> 21) & 31;
240 int rt = (op >> 16) & 31;
241 int rd = (op >> 11) & 31;
242 int shift = (op >> 6) & 31;
243 uint32_t flags = 0;
244
245 switch (op >> 26)
246 {
247 case 0x00: /* SPECIAL */
248 switch (op & 63)
249 {
250 case 0x00: if (op == 0)
251 util::stream_format(stream, "nop");
252 else
253 util::stream_format(stream, "sll %s,%s,%d", reg[rd], reg[rt], shift);
254 break;
255 case 0x02: util::stream_format(stream, "srl %s,%s,%d", reg[rd], reg[rt], shift); break;
256 case 0x03: util::stream_format(stream, "sra %s,%s,%d", reg[rd], reg[rt], shift); break;
257 case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
258 case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
259 case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break;
260 case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break;
261 case 0x09: if (rd == 31)
262 util::stream_format(stream, "jalr %s", reg[rs]);
263 else
264 util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]);
265 flags = STEP_OVER | step_over_extra(1);
266 break;
267 case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break;
268 case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break;
269 case 0x0f: util::stream_format(stream, "sync [invalid]"); break;
270 case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break;
271 case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break;
272 case 0x12: util::stream_format(stream, "mflo %s", reg[rd]); break;
273 case 0x13: util::stream_format(stream, "mtlo %s", reg[rs]); break;
274 case 0x18: util::stream_format(stream, "mult %s,%s", reg[rs], reg[rt]); break;
275 case 0x19: util::stream_format(stream, "multu %s,%s", reg[rs], reg[rt]); break;
276 case 0x1a: util::stream_format(stream, "div %s,%s", reg[rs], reg[rt]); break;
277 case 0x1b: util::stream_format(stream, "divu %s,%s", reg[rs], reg[rt]); break;
278 case 0x20: util::stream_format(stream, "add %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
279 case 0x21: util::stream_format(stream, "addu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
280 case 0x22: util::stream_format(stream, "sub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
281 case 0x23: util::stream_format(stream, "subu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
282 case 0x24: util::stream_format(stream, "and %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
283 case 0x25: util::stream_format(stream, "or %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
284 case 0x26: util::stream_format(stream, "xor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
285 case 0x27: util::stream_format(stream, "nor %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
286 case 0x2a: util::stream_format(stream, "slt %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
287 case 0x2b: util::stream_format(stream, "sltu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break;
288 case 0x30: util::stream_format(stream, "teq [invalid]"); break;
289 case 0x31: util::stream_format(stream, "tgeu [invalid]"); break;
290 case 0x32: util::stream_format(stream, "tlt [invalid]"); break;
291 case 0x33: util::stream_format(stream, "tltu [invalid]"); break;
292 case 0x34: util::stream_format(stream, "tge [invalid]"); break;
293 case 0x36: util::stream_format(stream, "tne [invalid]"); break;
294 default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
295 }
296 break;
297
298 case 0x01: /* REGIMM */
299 switch ((op >> 16) & 31)
300 {
301 case 0x00: util::stream_format(stream, "bltz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
302 case 0x01: util::stream_format(stream, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
303 case 0x02: util::stream_format(stream, "bltzl [invalid]"); break;
304 case 0x03: util::stream_format(stream, "bgezl [invalid]"); break;
305 case 0x08: util::stream_format(stream, "tgei [invalid]"); break;
306 case 0x09: util::stream_format(stream, "tgeiu [invalid]"); break;
307 case 0x0a: util::stream_format(stream, "tlti [invalid]"); break;
308 case 0x0b: util::stream_format(stream, "tltiu [invalid]"); break;
309 case 0x0c: util::stream_format(stream, "teqi [invalid]"); break;
310 case 0x0e: util::stream_format(stream, "tnei [invalid]"); break;
311 case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
312 case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break;
313 case 0x12: util::stream_format(stream, "bltzall [invalid]"); break;
314 case 0x13: util::stream_format(stream, "bgezall [invalid]"); break;
315 default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
316 }
317 break;
318
319 case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break;
320 case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break;
321 case 0x04: if (rs == 0 && rt == 0)
322 util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2));
323 else
324 util::stream_format(stream, "beq %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));
325 break;
326 case 0x05: util::stream_format(stream, "bne %s,%s,$%08x", reg[rs], reg[rt], pc + 4 + ((int16_t)op << 2));break;
327 case 0x06: util::stream_format(stream, "blez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
328 case 0x07: util::stream_format(stream, "bgtz %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break;
329 case 0x08: util::stream_format(stream, "addi %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
330 case 0x09: util::stream_format(stream, "addiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
331 case 0x0a: util::stream_format(stream, "slti %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
332 case 0x0b: util::stream_format(stream, "sltiu %s,%s,%s", reg[rt], reg[rs], signed_16bit(op)); break;
333 case 0x0c: util::stream_format(stream, "andi %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
334 case 0x0d: util::stream_format(stream, "ori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
335 case 0x0e: util::stream_format(stream, "xori %s,%s,$%04x", reg[rt], reg[rs], (uint16_t)op); break;
336 case 0x0f: util::stream_format(stream, "lui %s,$%04x", reg[rt], (uint16_t)op); break;
337 case 0x10: flags = dasm_cop(pc, 0, op, stream); break;
338 case 0x11: flags = dasm_cop1(pc, op, stream); break;
339 case 0x12: flags = dasm_cop(pc, 2, op, stream); break;
340 case 0x13: flags = dasm_cop(pc, 3, op, stream); break;
341 case 0x14: util::stream_format(stream, "beql [invalid]"); break;
342 case 0x15: util::stream_format(stream, "bnel [invalid]"); break;
343 case 0x16: util::stream_format(stream, "blezl [invalid]"); break;
344 case 0x17: util::stream_format(stream, "bgtzl [invalid]"); break;
345 case 0x20: util::stream_format(stream, "lb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
346 case 0x21: util::stream_format(stream, "lh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
347 case 0x22: util::stream_format(stream, "lwl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
348 case 0x23: util::stream_format(stream, "lw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
349 case 0x24: util::stream_format(stream, "lbu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
350 case 0x25: util::stream_format(stream, "lhu %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
351 case 0x26: util::stream_format(stream, "lwr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
352 case 0x28: util::stream_format(stream, "sb %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
353 case 0x29: util::stream_format(stream, "sh %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
354 case 0x2a: util::stream_format(stream, "swl %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
355 case 0x2b: util::stream_format(stream, "sw %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
356 case 0x2e: util::stream_format(stream, "swr %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break;
357 case 0x2f: util::stream_format(stream, "cache [invalid]"); break;
358 case 0x30: util::stream_format(stream, "ll [invalid]"); break;
359 case 0x31: util::stream_format(stream, "lwc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
360 case 0x32: util::stream_format(stream, "lwc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
361 case 0x33: util::stream_format(stream, "lwc3 %s,%s(%s)", cpreg[3][rt], signed_16bit(op), reg[rs]); break;
362 case 0x34: util::stream_format(stream, "ldc0 [invalid]"); break;
363 case 0x35: util::stream_format(stream, "ldc1 [invalid]"); break;
364 case 0x36: util::stream_format(stream, "ldc2 [invalid]"); break;
365 case 0x37: util::stream_format(stream, "ldc3 [invalid]"); break;
366 case 0x38: util::stream_format(stream, "sc [invalid]"); break;
367 case 0x39: util::stream_format(stream, "swc1 %s,%s(%s)", cpreg[1][rt], signed_16bit(op), reg[rs]); break;
368 case 0x3a: util::stream_format(stream, "swc2 %s,%s(%s)", cpreg[2][rt], signed_16bit(op), reg[rs]); break;
369 case 0x3b: util::stream_format(stream, "swc3 %s,%s(%s)", cpreg[3][rt], signed_16bit(op), reg[rs]); break;
370 case 0x3c: util::stream_format(stream, "sdc0 [invalid]"); break;
371 case 0x3d: util::stream_format(stream, "sdc1 [invalid]"); break;
372 case 0x3e: util::stream_format(stream, "sdc2 [invalid]"); break;
373 case 0x3f: util::stream_format(stream, "sdc3 [invalid]"); break;
374 default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break;
375 }
376 return 4 | flags | SUPPORTED;
377 }
378
opcode_alignment() const379 uint32_t mips1_disassembler::opcode_alignment() const
380 {
381 return 4;
382 }
383