1use alloc::{format, vec::Vec};
2
3use crate::{diff::display::InstructionPart, obj::ResolvedInstructionRef};
4
5static REG_NAMES: [&str; 16] = [
6 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14",
7 "r15",
8];
9
10enum Ops {
11 AddImmRn,
13 MovImmRn,
14 AndBImmAtR0Gbr,
16 OrBImmAtR0Gbr,
17 TstBImmAtR0Gbr,
18 XorBImmAtR0Gbr,
19 AndImmR0,
20 CmpEqImmR0,
21 OrImmR0,
22 TstImmR0,
23 XorImmR0,
24 Trapa,
25
26 MovWAtDispPcRn,
28 MovLAtDispPcRn,
29
30 Bra,
32 Bsr,
33
34 MovBR0AtDispGbr,
36 MovWR0AtDispGbr,
37 MovLR0AtDispGbr,
38 MovBAtDispGbrR0,
39 MovWAtDispGbrR0,
40 MovLAtDispGbrR0,
41 Bf,
42 Bfs,
43 Bt,
44 Bts,
45
46 MovLRmAtDispRn,
48 MovLRDispRmRn,
49
50 MovBAtDispRnR0,
52 MovWAtDispRnR0,
53 MovBR0AtDispRn,
54 MovWR0AtDispRn,
55
56 AddRmRn,
58 AddcRmRn,
59 AddvRmRn,
60 AndRmRn,
61 CmpEqRmRn,
62 CmpHsRmRn,
63 CmpGeRmRn,
64 CmpHiRmRn,
65 CmpGtRmRn,
66 CmpStrRmRn,
67 Div1RmRn,
68 Div0sRmRn,
69 DmulsLRmRn,
70 DmuluLRmRn,
71 ExtsBRmRn,
72 ExtsWRmRn,
73 ExtuBRmRn,
74 ExtuWRmRn,
75 MovRmRn,
76 MulLRmRn,
77 MulsRmRn,
78 MuluRmRn,
79 NegRmRn,
80 NegcRmRn,
81 NotRmRn,
82 OrRmRn,
83 SubRmRn,
84 SubcRmRn,
85 SubvRmRn,
86 SwapBRmRn,
87 SwapWRmRn,
88 TstRmRn,
89 XorRmRn,
90 XtrctRmRn,
91 MovBRmAtRn,
92 MovWRmAtRn,
93 MovLRmAtRn,
94 MovBAtRmRn,
95 MovWAtRmRn,
96 MovLAtRmRn,
97 MacLAtRmIncAtRnInc,
98 MacWAtRmIncAtRnInc,
99 MovBAtRmIncRn,
100 MovWAtRmIncRn,
101 MovLAtRmIncRn,
102 MovBRmAtDecRn,
103 MovWRmAtDecRn,
104 MovLRmAtDecRn,
105 MovBRmAtR0Rn,
106 MovWRmAtR0Rn,
107 MovLRmAtR0Rn,
108 MovBAtR0RmRn,
109 MovWAtR0RmRn,
110 MovLAtR0RmRn,
111
112 CmpPlRn,
114 CmpPzRn,
115 DtRn,
116 MovtRn,
117 RotlRn,
118 RotrRn,
119 RotclRn,
120 RotcrRn,
121 ShalRn,
122 SharRn,
123 ShllRn,
124 ShlrRn,
125 Shll2Rn,
126 Shlr2Rn,
127 Shll8Rn,
128 Shlr8Rn,
129 Shll16Rn,
130 Shlr16Rn,
131 StcSrRn,
132 StcGbrRn,
133 StcVbrRn,
134 StsMachRn,
135 StsMaclRn,
136 StsPrRn,
137 TasB,
138 StcLSrAtDecrementRn,
139 StcLGbrAtDecrementRn,
140 StcLVbrAtDecrementRn,
141 StsLMachAtDecrementRn,
142 StsLMaclAtDecrementRn,
143 StsLPrAtDecrementRn,
144 LdcRnSr,
145 LdcRnGbr,
146 LdcRnVbr,
147 LdsRnMach,
148 LdsRnMacl,
149 LdsRnPr,
150 JmpAtRn,
151 JsrAtRn,
152 LdcLAtRnIncSr,
153 LdcLAtRnIncGbr,
154 LdcLAtRnIncVbr,
155 LdsLAtRnIncMach,
156 LdsLAtRnIncMacl,
157 LdsLAtRnIncPr,
158 BrafRn,
159 BsrfRn,
160
161 Clrt,
163 Clrmac,
164 Div0u,
165 Nop,
166 Rte,
167 Rts,
168 Sett,
169 Sleep,
170}
171fn match_ni_f(
172 _v_addr: u32,
173 op: u16,
174 _mode: bool,
175 parts: &mut Vec<InstructionPart>,
176 _resolved: &ResolvedInstructionRef,
177 _branch_dest: &mut Option<u64>,
178) {
179 match op & 0xf000 {
180 0x7000 => {
181 let reg = REG_NAMES[((op >> 8) & 0xf) as usize];
183 parts.push(InstructionPart::opcode("add", Ops::AddImmRn as u16));
184 parts.push(InstructionPart::basic("#"));
185 parts.push(InstructionPart::unsigned(op & 0xff));
186 parts.push(InstructionPart::separator());
187 parts.push(InstructionPart::basic(reg));
188 }
189 0xe000 => {
190 let reg = REG_NAMES[((op >> 8) & 0xf) as usize];
192 parts.push(InstructionPart::opcode("mov", Ops::MovImmRn as u16));
193 parts.push(InstructionPart::basic("#"));
194 parts.push(InstructionPart::unsigned(op & 0xff));
195 parts.push(InstructionPart::separator());
196 parts.push(InstructionPart::opaque(reg));
197 }
198 _ => {
199 parts.push(InstructionPart::basic(".word 0x"));
200 parts.push(InstructionPart::basic(format!("{op:04X}")));
201 parts.push(InstructionPart::basic(" /* unknown instruction */"));
202 }
203 }
204}
205
206fn match_i_f(
207 v_addr: u32,
208 op: u16,
209 mode: bool,
210 parts: &mut Vec<InstructionPart>,
211 resolved: &ResolvedInstructionRef,
212 branch_dest: &mut Option<u64>,
213) {
214 match op & 0xff00 {
215 0xcd00 => {
216 parts.push(InstructionPart::opcode("and.b", Ops::AndBImmAtR0Gbr as u16));
218 parts.push(InstructionPart::basic("#"));
219 parts.push(InstructionPart::unsigned(op & 0xff));
220 parts.push(InstructionPart::separator());
221 parts.push(InstructionPart::basic("@("));
222 parts.push(InstructionPart::opaque("r0"));
223 parts.push(InstructionPart::separator());
224 parts.push(InstructionPart::opaque("gbr"));
225 parts.push(InstructionPart::basic(")"));
226 }
227 0xcf00 => {
228 parts.push(InstructionPart::opcode("or.b", Ops::OrBImmAtR0Gbr as u16));
230 parts.push(InstructionPart::basic("#"));
231 parts.push(InstructionPart::unsigned(op & 0xff));
232 parts.push(InstructionPart::separator());
233 parts.push(InstructionPart::basic("@("));
234 parts.push(InstructionPart::opaque("r0"));
235 parts.push(InstructionPart::separator());
236 parts.push(InstructionPart::opaque("gbr"));
237 parts.push(InstructionPart::basic(")"));
238 }
239 0xcc00 => {
240 parts.push(InstructionPart::opcode("tst.b", Ops::TstBImmAtR0Gbr as u16));
242 parts.push(InstructionPart::basic("#"));
243 parts.push(InstructionPart::unsigned(op & 0xff));
244 parts.push(InstructionPart::separator());
245 parts.push(InstructionPart::basic("@("));
246 parts.push(InstructionPart::opaque("r0"));
247 parts.push(InstructionPart::separator());
248 parts.push(InstructionPart::opaque("gbr"));
249 parts.push(InstructionPart::basic(")"));
250 }
251 0xce00 => {
252 parts.push(InstructionPart::opcode("xor.b", Ops::XorBImmAtR0Gbr as u16));
254 parts.push(InstructionPart::basic("#"));
255 parts.push(InstructionPart::unsigned(op & 0xff));
256 parts.push(InstructionPart::separator());
257 parts.push(InstructionPart::basic("@("));
258 parts.push(InstructionPart::opaque("r0"));
259 parts.push(InstructionPart::separator());
260 parts.push(InstructionPart::opaque("gbr"));
261 parts.push(InstructionPart::basic(")"));
262 }
263 0xc900 => {
264 parts.push(InstructionPart::opcode("and", Ops::AndImmR0 as u16));
266 parts.push(InstructionPart::basic("#"));
267 parts.push(InstructionPart::unsigned(op & 0xff));
268 parts.push(InstructionPart::separator());
269 parts.push(InstructionPart::opaque("r0"));
270 }
271 0x8800 => {
272 parts.push(InstructionPart::opcode("cmp/eq", Ops::CmpEqImmR0 as u16));
273 parts.push(InstructionPart::basic("#"));
274 parts.push(InstructionPart::unsigned(op & 0xff));
275 parts.push(InstructionPart::separator());
276 parts.push(InstructionPart::opaque("r0"));
277 }
278 0xcb00 => {
279 parts.push(InstructionPart::opcode("or", Ops::OrImmR0 as u16));
280 parts.push(InstructionPart::basic("#"));
281 parts.push(InstructionPart::unsigned(op & 0xff));
282 parts.push(InstructionPart::separator());
283 parts.push(InstructionPart::opaque("r0"));
284 }
285 0xc800 => {
286 parts.push(InstructionPart::opcode("tst", Ops::TstImmR0 as u16));
287 parts.push(InstructionPart::basic("#"));
288 parts.push(InstructionPart::unsigned(op & 0xff));
289 parts.push(InstructionPart::separator());
290 parts.push(InstructionPart::opaque("r0"));
291 }
292 0xca00 => {
293 parts.push(InstructionPart::opcode("xor", Ops::XorImmR0 as u16));
294 parts.push(InstructionPart::basic("#"));
295 parts.push(InstructionPart::unsigned(op & 0xff));
296 parts.push(InstructionPart::separator());
297 parts.push(InstructionPart::opaque("r0"));
298 }
299 0xc300 => {
300 parts.push(InstructionPart::opcode("trapa", Ops::Trapa as u16));
301 parts.push(InstructionPart::basic("#"));
302 parts.push(InstructionPart::unsigned(op & 0xff));
303 }
304 _ => match_ni_f(v_addr, op, mode, parts, resolved, branch_dest),
305 }
306}
307
308fn match_nd8_f(
309 v_addr: u32,
310 op: u16,
311 mode: bool,
312 parts: &mut Vec<InstructionPart>,
313 resolved: &ResolvedInstructionRef,
314 branch_dest: &mut Option<u64>,
315) {
316 match op & 0xf000 {
317 0x9000 => {
318 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtDispPcRn as u16));
319 parts.push(InstructionPart::basic("@("));
320 if resolved.relocation.is_some() {
321 parts.push(InstructionPart::reloc());
322 } else {
323 parts.push(InstructionPart::unsigned((op & 0xff) * 2 + 4));
324 }
325 parts.push(InstructionPart::separator());
326 parts.push(InstructionPart::opaque("pc"));
327 parts.push(InstructionPart::basic(")"));
328 parts.push(InstructionPart::separator());
329 parts.push(InstructionPart::opaque(format!("r{}", (op >> 8) & 0xf)));
330 }
331 0xd000 => {
332 let mut target_a = (op as u32 & 0xff) * 4 + 4;
333 let test = (op as u32 & 0xff) * 4 + 4 + v_addr;
334
335 if (test & 3) == 2 {
336 target_a -= 2;
337 }
338 parts.push(InstructionPart::opcode("mov.l", Ops::MovLAtDispPcRn as u16));
339 parts.push(InstructionPart::basic("@("));
340 if resolved.relocation.is_some() {
341 parts.push(InstructionPart::reloc());
342 } else {
343 parts.push(InstructionPart::unsigned(target_a));
344 }
345 parts.push(InstructionPart::separator());
346 parts.push(InstructionPart::opaque("pc"));
347 parts.push(InstructionPart::basic(")"));
348 parts.push(InstructionPart::separator());
349 parts.push(InstructionPart::opaque(format!("r{}", (op >> 8) & 0xf)));
350 }
351 _ => match_i_f(v_addr, op, mode, parts, resolved, branch_dest),
352 }
353}
354
355fn match_d12_f(
356 v_addr: u32,
357 op: u16,
358 mode: bool,
359 parts: &mut Vec<InstructionPart>,
360 resolved: &ResolvedInstructionRef,
361 branch_dest: &mut Option<u64>,
362) {
363 match op & 0xf000 {
364 0xa000 => {
365 if (op & 0x800) == 0x800 {
366 let addr = ((op as u32 & 0xfff) + 0xfffff000)
367 .wrapping_mul(2)
368 .wrapping_add(v_addr)
369 .wrapping_add(4);
370 *branch_dest = Some(addr as u64);
371 if resolved.relocation.is_some() {
372 parts.push(InstructionPart::opcode("bra", Ops::Bra as u16));
374 parts.push(InstructionPart::reloc());
375 } else {
376 parts.push(InstructionPart::opcode("bra", Ops::Bra as u16));
378 parts.push(InstructionPart::unsigned(addr));
379 }
380 } else {
381 let addr = (op as u32 & 0xfff) * 2 + v_addr + 4;
382 *branch_dest = Some(addr as u64);
383
384 if resolved.relocation.is_some() {
385 parts.push(InstructionPart::opcode("bra", Ops::Bra as u16));
387 parts.push(InstructionPart::reloc());
388 } else {
389 parts.push(InstructionPart::opcode("bra", Ops::Bra as u16));
391 parts.push(InstructionPart::unsigned(addr));
392 }
393 }
394 }
395 0xb000 => {
396 if (op & 0x800) == 0x800 {
397 let addr =
398 ((op as u32 & 0xfff) + 0xfffff000).wrapping_mul(2).wrapping_add(v_addr) + 4;
399 *branch_dest = Some(addr as u64);
400 if resolved.relocation.is_some() {
401 parts.push(InstructionPart::opcode("bsr", Ops::Bsr as u16));
403 parts.push(InstructionPart::reloc());
404 } else {
405 parts.push(InstructionPart::opcode("bsr", Ops::Bsr as u16));
407 parts.push(InstructionPart::unsigned(addr));
408 }
409 } else {
410 let addr = (op as u32 & 0xfff) * 2 + v_addr + 4;
411 *branch_dest = Some(addr as u64);
412 if resolved.relocation.is_some() {
413 parts.push(InstructionPart::opcode("bsr", Ops::Bsr as u16));
415 parts.push(InstructionPart::reloc());
416 } else {
417 parts.push(InstructionPart::opcode("bsr", Ops::Bsr as u16));
419 parts.push(InstructionPart::unsigned(addr));
420 }
421 }
422 }
423 _ => match_nd8_f(v_addr, op, mode, parts, resolved, branch_dest),
424 }
425}
426
427fn match_d_f(
428 v_addr: u32,
429 op: u16,
430 mode: bool,
431 parts: &mut Vec<InstructionPart>,
432 resolved: &ResolvedInstructionRef,
433 branch_dest: &mut Option<u64>,
434) {
435 match op & 0xff00 {
436 0xc000 => {
437 parts.push(InstructionPart::opcode("mov.b", Ops::MovBR0AtDispGbr as u16));
438 parts.push(InstructionPart::opaque("r0"));
439 parts.push(InstructionPart::separator());
440 parts.push(InstructionPart::basic("@("));
441 parts.push(InstructionPart::unsigned(op & 0xff));
442 parts.push(InstructionPart::separator());
443 parts.push(InstructionPart::opaque("gbr"));
444 parts.push(InstructionPart::basic(")"));
445 }
446 0xc100 => {
447 parts.push(InstructionPart::opcode("mov.w", Ops::MovWR0AtDispGbr as u16));
448 parts.push(InstructionPart::opaque("r0"));
449 parts.push(InstructionPart::separator());
450 parts.push(InstructionPart::basic("@("));
451 parts.push(InstructionPart::unsigned((op & 0xff) * 2));
452 parts.push(InstructionPart::separator());
453 parts.push(InstructionPart::opaque("gbr"));
454 parts.push(InstructionPart::basic(")"));
455 }
456 0xc200 => {
457 parts.push(InstructionPart::opcode("mov.l", Ops::MovLR0AtDispGbr as u16));
458 parts.push(InstructionPart::opaque("r0"));
459 parts.push(InstructionPart::separator());
460 parts.push(InstructionPart::basic("@("));
461 parts.push(InstructionPart::unsigned((op & 0xff) * 4));
462 parts.push(InstructionPart::separator());
463 parts.push(InstructionPart::opaque("gbr"));
464 parts.push(InstructionPart::basic(")"));
465 }
466 0xc400 => {
467 parts.push(InstructionPart::opcode("mov.b", Ops::MovBAtDispGbrR0 as u16));
468 parts.push(InstructionPart::basic("@("));
469 parts.push(InstructionPart::unsigned(op & 0xff));
470 parts.push(InstructionPart::separator());
471 parts.push(InstructionPart::opaque("gbr"));
472 parts.push(InstructionPart::basic(")"));
473 parts.push(InstructionPart::separator());
474 parts.push(InstructionPart::opaque("r0"));
475 }
476 0xc500 => {
477 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtDispGbrR0 as u16));
478 parts.push(InstructionPart::basic("@("));
479 parts.push(InstructionPart::unsigned((op & 0xff) * 2));
480 parts.push(InstructionPart::separator());
481 parts.push(InstructionPart::opaque("gbr"));
482 parts.push(InstructionPart::basic(")"));
483 parts.push(InstructionPart::separator());
484 parts.push(InstructionPart::opaque("r0"));
485 }
486 0xc600 => {
487 parts.push(InstructionPart::opcode("mov.l", Ops::MovLAtDispGbrR0 as u16));
488 parts.push(InstructionPart::basic("@("));
489 parts.push(InstructionPart::unsigned((op & 0xff) * 4));
490 parts.push(InstructionPart::separator());
491 parts.push(InstructionPart::opaque("gbr"));
492 parts.push(InstructionPart::basic(")"));
493 parts.push(InstructionPart::separator());
494 parts.push(InstructionPart::opaque("r0"));
495 }
496 0x8b00 => {
497 let addr: u32 = if (op & 0x80) == 0x80 {
498 (((op as u32 & 0xff).wrapping_add(0xffffff00)).wrapping_mul(2))
499 .wrapping_add(v_addr)
500 .wrapping_add(4)
501 } else {
502 ((op as u32 & 0xff) * 2).wrapping_add(v_addr).wrapping_add(4)
503 };
504 *branch_dest = Some(addr as u64);
505 parts.push(InstructionPart::opcode("bf", Ops::Bf as u16));
506 if resolved.relocation.is_some() {
507 parts.push(InstructionPart::reloc());
508 } else {
509 parts.push(InstructionPart::unsigned(addr));
510 }
511 }
512 0x8f00 => {
513 let addr = if (op & 0x80) == 0x80 {
514 (((op as u32 & 0xff).wrapping_add(0xffffff00)).wrapping_mul(2))
515 .wrapping_add(v_addr)
516 .wrapping_add(4)
517 } else {
518 ((op as u32 & 0xff) * 2).wrapping_add(v_addr).wrapping_add(4)
519 };
520 *branch_dest = Some(addr as u64);
521 parts.push(InstructionPart::opcode("bf.s", Ops::Bfs as u16));
522 if resolved.relocation.is_some() {
523 parts.push(InstructionPart::reloc());
524 } else {
525 parts.push(InstructionPart::unsigned(addr));
526 }
527 }
528 0x8900 => {
529 let addr = if (op & 0x80) == 0x80 {
530 (((op as u32 & 0xff).wrapping_add(0xffffff00)).wrapping_mul(2))
531 .wrapping_add(v_addr)
532 .wrapping_add(4)
533 } else {
534 ((op as u32 & 0xff) * 2).wrapping_add(v_addr).wrapping_add(4)
535 };
536 *branch_dest = Some(addr as u64);
537 parts.push(InstructionPart::opcode("bt", Ops::Bt as u16));
538 if resolved.relocation.is_some() {
539 parts.push(InstructionPart::reloc());
540 } else {
541 parts.push(InstructionPart::unsigned(addr));
542 }
543 }
544 0x8d00 => {
545 let addr = if (op & 0x80) == 0x80 {
546 (((op as u32 & 0xff).wrapping_add(0xffffff00)).wrapping_mul(2))
547 .wrapping_add(v_addr)
548 .wrapping_add(4)
549 } else {
550 ((op as u32 & 0xff) * 2).wrapping_add(v_addr).wrapping_add(4)
551 };
552 *branch_dest = Some(addr as u64);
553 parts.push(InstructionPart::opcode("bt.s", Ops::Bts as u16));
554 if resolved.relocation.is_some() {
555 parts.push(InstructionPart::reloc());
556 } else {
557 parts.push(InstructionPart::unsigned(addr));
558 }
559 }
560 _ => match_d12_f(v_addr, op, mode, parts, resolved, branch_dest),
561 }
562}
563
564fn match_nmd_f(
565 v_addr: u32,
566 op: u16,
567 mode: bool,
568 parts: &mut Vec<InstructionPart>,
569 resolved: &ResolvedInstructionRef,
570 branch_dest: &mut Option<u64>,
571) {
572 let reg_m = REG_NAMES[((op >> 4) & 0xf) as usize];
573 let reg_n = REG_NAMES[((op >> 8) & 0xf) as usize];
574 match op & 0xf000 {
575 0x1000 => {
576 parts.push(InstructionPart::opcode("mov.l", Ops::MovLRmAtDispRn as u16));
577 parts.push(InstructionPart::basic(reg_m));
578 parts.push(InstructionPart::separator());
579 parts.push(InstructionPart::basic("@("));
580 parts.push(InstructionPart::unsigned((op & 0xf) * 4));
581 parts.push(InstructionPart::separator());
582 parts.push(InstructionPart::basic(reg_n));
583 parts.push(InstructionPart::basic(")"));
584 }
585 0x5000 => {
586 parts.push(InstructionPart::opcode("mov.l", Ops::MovLRDispRmRn as u16));
587 parts.push(InstructionPart::basic("@("));
588 parts.push(InstructionPart::unsigned((op & 0xf) * 4));
589 parts.push(InstructionPart::separator());
590 parts.push(InstructionPart::basic(reg_m));
591 parts.push(InstructionPart::basic(")"));
592 parts.push(InstructionPart::separator());
593 parts.push(InstructionPart::basic(reg_n));
594 }
595 _ => match_d_f(v_addr, op, mode, parts, resolved, branch_dest),
596 }
597}
598fn match_ff00(
599 v_addr: u32,
600 op: u16,
601 mode: bool,
602 parts: &mut Vec<InstructionPart>,
603 resolved: &ResolvedInstructionRef,
604 branch_dest: &mut Option<u64>,
605) {
606 match op & 0xff00 {
607 0x8400 => {
608 parts.push(InstructionPart::opcode("mov.b", Ops::MovBAtDispRnR0 as u16));
609 parts.push(InstructionPart::basic("@("));
610 if (op & 0x100) == 0x100 {
611 parts.push(InstructionPart::unsigned((op & 0xf) * 2));
612 } else {
613 parts.push(InstructionPart::unsigned(op & 0xf));
614 }
615 parts.push(InstructionPart::separator());
616 parts.push(InstructionPart::opaque(REG_NAMES[((op >> 4) & 0xf) as usize]));
617 parts.push(InstructionPart::basic(")"));
618 parts.push(InstructionPart::separator());
619 parts.push(InstructionPart::opaque("r0"));
620 }
621 0x8500 => {
622 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtDispRnR0 as u16));
623 parts.push(InstructionPart::basic("@("));
624 if (op & 0x100) == 0x100 {
625 parts.push(InstructionPart::unsigned((op & 0xf) * 2));
626 } else {
627 parts.push(InstructionPart::unsigned(op & 0xf));
628 }
629 parts.push(InstructionPart::separator());
630 parts.push(InstructionPart::opaque(REG_NAMES[((op >> 4) & 0xf) as usize]));
631 parts.push(InstructionPart::basic(")"));
632 parts.push(InstructionPart::separator());
633 parts.push(InstructionPart::opaque("r0"));
634 }
635 0x8000 => {
636 parts.push(InstructionPart::opcode("mov.b", Ops::MovBR0AtDispRn as u16));
637 parts.push(InstructionPart::opaque("r0"));
638 parts.push(InstructionPart::separator());
639 parts.push(InstructionPart::basic("@("));
640 if (op & 0x100) == 0x100 {
641 parts.push(InstructionPart::unsigned((op & 0xf) * 2));
642 } else {
643 parts.push(InstructionPart::unsigned(op & 0xf));
644 }
645 parts.push(InstructionPart::separator());
646 parts.push(InstructionPart::opaque(REG_NAMES[((op >> 4) & 0xf) as usize]));
647 parts.push(InstructionPart::basic(")"));
648 }
649 0x8100 => {
650 parts.push(InstructionPart::opcode("mov.w", Ops::MovWR0AtDispRn as u16));
651 parts.push(InstructionPart::opaque("r0"));
652 parts.push(InstructionPart::separator());
653 parts.push(InstructionPart::basic("@("));
654 if (op & 0x100) == 0x100 {
655 parts.push(InstructionPart::unsigned((op & 0xf) * 2));
656 } else {
657 parts.push(InstructionPart::unsigned(op & 0xf));
658 }
659 parts.push(InstructionPart::separator());
660 parts.push(InstructionPart::opaque(REG_NAMES[((op >> 4) & 0xf) as usize]));
661 parts.push(InstructionPart::basic(")"));
662 }
663 _ => match_nmd_f(v_addr, op, mode, parts, resolved, branch_dest),
664 }
665}
666
667fn match_f00f(
668 v_addr: u32,
669 op: u16,
670 mode: bool,
671 parts: &mut Vec<InstructionPart>,
672 resolved: &ResolvedInstructionRef,
673 branch_dest: &mut Option<u64>,
674) {
675 let reg_m = REG_NAMES[((op >> 4) & 0xf) as usize];
676 let reg_n = REG_NAMES[((op >> 8) & 0xf) as usize];
677
678 match op & 0xf00f {
679 0x300c => {
680 parts.push(InstructionPart::opcode("add", Ops::AddRmRn as u16));
681 parts.push(InstructionPart::opaque(reg_m));
682 parts.push(InstructionPart::separator());
683 parts.push(InstructionPart::opaque(reg_n));
684 }
685 0x300e => {
686 parts.push(InstructionPart::opcode("addc", Ops::AddcRmRn as u16));
687 parts.push(InstructionPart::opaque(reg_m));
688 parts.push(InstructionPart::separator());
689 parts.push(InstructionPart::opaque(reg_n));
690 }
691 0x300f => {
692 parts.push(InstructionPart::opcode("addv", Ops::AddvRmRn as u16));
693 parts.push(InstructionPart::opaque(reg_m));
694 parts.push(InstructionPart::separator());
695 parts.push(InstructionPart::opaque(reg_n));
696 }
697 0x2009 => {
698 parts.push(InstructionPart::opcode("and", Ops::AndRmRn as u16));
699 parts.push(InstructionPart::opaque(reg_m));
700 parts.push(InstructionPart::separator());
701 parts.push(InstructionPart::opaque(reg_n));
702 }
703 0x3000 => {
704 parts.push(InstructionPart::opcode("cmp/eq", Ops::CmpEqRmRn as u16));
705 parts.push(InstructionPart::opaque(reg_m));
706 parts.push(InstructionPart::separator());
707 parts.push(InstructionPart::opaque(reg_n));
708 }
709 0x3002 => {
710 parts.push(InstructionPart::opcode("cmp/hs", Ops::CmpHsRmRn as u16));
711 parts.push(InstructionPart::opaque(reg_m));
712 parts.push(InstructionPart::separator());
713 parts.push(InstructionPart::opaque(reg_n));
714 }
715 0x3003 => {
716 parts.push(InstructionPart::opcode("cmp/ge", Ops::CmpGeRmRn as u16));
717 parts.push(InstructionPart::opaque(reg_m));
718 parts.push(InstructionPart::separator());
719 parts.push(InstructionPart::opaque(reg_n));
720 }
721 0x3006 => {
722 parts.push(InstructionPart::opcode("cmp/hi", Ops::CmpHiRmRn as u16));
723 parts.push(InstructionPart::opaque(reg_m));
724 parts.push(InstructionPart::separator());
725 parts.push(InstructionPart::opaque(reg_n));
726 }
727 0x3007 => {
728 parts.push(InstructionPart::opcode("cmp/gt", Ops::CmpGtRmRn as u16));
729 parts.push(InstructionPart::opaque(reg_m));
730 parts.push(InstructionPart::separator());
731 parts.push(InstructionPart::opaque(reg_n));
732 }
733 0x200c => {
734 parts.push(InstructionPart::opcode("cmp/str", Ops::CmpStrRmRn as u16));
735 parts.push(InstructionPart::opaque(reg_m));
736 parts.push(InstructionPart::separator());
737 parts.push(InstructionPart::opaque(reg_n));
738 }
739 0x3004 => {
740 parts.push(InstructionPart::opcode("div1", Ops::Div1RmRn as u16));
741 parts.push(InstructionPart::opaque(reg_m));
742 parts.push(InstructionPart::separator());
743 parts.push(InstructionPart::opaque(reg_n));
744 }
745 0x2007 => {
746 parts.push(InstructionPart::opcode("div0s", Ops::Div0sRmRn as u16));
747 parts.push(InstructionPart::opaque(reg_m));
748 parts.push(InstructionPart::separator());
749 parts.push(InstructionPart::opaque(reg_n));
750 }
751 0x300d => {
752 parts.push(InstructionPart::opcode("dmuls.l", Ops::DmulsLRmRn as u16));
753 parts.push(InstructionPart::opaque(reg_m));
754 parts.push(InstructionPart::separator());
755 parts.push(InstructionPart::opaque(reg_n));
756 }
757 0x3005 => {
758 parts.push(InstructionPart::opcode("dmulu.l", Ops::DmuluLRmRn as u16));
759 parts.push(InstructionPart::opaque(reg_m));
760 parts.push(InstructionPart::separator());
761 parts.push(InstructionPart::opaque(reg_n));
762 }
763 0x600e => {
764 parts.push(InstructionPart::opcode("exts.b", Ops::ExtsBRmRn as u16));
765 parts.push(InstructionPart::opaque(reg_m));
766 parts.push(InstructionPart::separator());
767 parts.push(InstructionPart::opaque(reg_n));
768 }
769 0x600f => {
770 parts.push(InstructionPart::opcode("exts.w", Ops::ExtsWRmRn as u16));
771 parts.push(InstructionPart::opaque(reg_m));
772 parts.push(InstructionPart::separator());
773 parts.push(InstructionPart::opaque(reg_n));
774 }
775 0x600c => {
776 parts.push(InstructionPart::opcode("extu.b", Ops::ExtuBRmRn as u16));
777 parts.push(InstructionPart::opaque(reg_m));
778 parts.push(InstructionPart::separator());
779 parts.push(InstructionPart::opaque(reg_n));
780 }
781 0x600d => {
782 parts.push(InstructionPart::opcode("extu.w", Ops::ExtuWRmRn as u16));
783 parts.push(InstructionPart::opaque(reg_m));
784 parts.push(InstructionPart::separator());
785 parts.push(InstructionPart::opaque(reg_n));
786 }
787 0x6003 => {
788 parts.push(InstructionPart::opcode("mov", Ops::MovRmRn as u16));
789 parts.push(InstructionPart::opaque(reg_m));
790 parts.push(InstructionPart::separator());
791 parts.push(InstructionPart::opaque(reg_n));
792 }
793 0x0007 => {
794 parts.push(InstructionPart::opcode("mul.l", Ops::MulLRmRn as u16));
795 parts.push(InstructionPart::opaque(reg_m));
796 parts.push(InstructionPart::separator());
797 parts.push(InstructionPart::opaque(reg_n));
798 }
799 0x200f => {
800 parts.push(InstructionPart::opcode("muls", Ops::MulsRmRn as u16));
801 parts.push(InstructionPart::opaque(reg_m));
802 parts.push(InstructionPart::separator());
803 parts.push(InstructionPart::opaque(reg_n));
804 }
805 0x200e => {
806 parts.push(InstructionPart::opcode("mulu", Ops::MuluRmRn as u16));
807 parts.push(InstructionPart::opaque(reg_m));
808 parts.push(InstructionPart::separator());
809 parts.push(InstructionPart::opaque(reg_n));
810 }
811 0x600b => {
812 parts.push(InstructionPart::opcode("neg", Ops::NegRmRn as u16));
813 parts.push(InstructionPart::opaque(reg_m));
814 parts.push(InstructionPart::separator());
815 parts.push(InstructionPart::opaque(reg_n));
816 }
817 0x600a => {
818 parts.push(InstructionPart::opcode("negc", Ops::NegcRmRn as u16));
819 parts.push(InstructionPart::opaque(reg_m));
820 parts.push(InstructionPart::separator());
821 parts.push(InstructionPart::opaque(reg_n));
822 }
823 0x6007 => {
824 parts.push(InstructionPart::opcode("not", Ops::NotRmRn as u16));
825 parts.push(InstructionPart::opaque(reg_m));
826 parts.push(InstructionPart::separator());
827 parts.push(InstructionPart::opaque(reg_n));
828 }
829 0x200b => {
830 parts.push(InstructionPart::opcode("or", Ops::OrRmRn as u16));
831 parts.push(InstructionPart::opaque(reg_m));
832 parts.push(InstructionPart::separator());
833 parts.push(InstructionPart::opaque(reg_n));
834 }
835 0x3008 => {
836 parts.push(InstructionPart::opcode("sub", Ops::SubRmRn as u16));
837 parts.push(InstructionPart::opaque(reg_m));
838 parts.push(InstructionPart::separator());
839 parts.push(InstructionPart::opaque(reg_n));
840 }
841 0x300a => {
842 parts.push(InstructionPart::opcode("subc", Ops::SubcRmRn as u16));
843 parts.push(InstructionPart::opaque(reg_m));
844 parts.push(InstructionPart::separator());
845 parts.push(InstructionPart::opaque(reg_n));
846 }
847 0x300b => {
848 parts.push(InstructionPart::opcode("subv", Ops::SubvRmRn as u16));
849 parts.push(InstructionPart::opaque(reg_m));
850 parts.push(InstructionPart::separator());
851 parts.push(InstructionPart::opaque(reg_n));
852 }
853 0x6008 => {
854 parts.push(InstructionPart::opcode("swap.b", Ops::SwapBRmRn as u16));
855 parts.push(InstructionPart::opaque(reg_m));
856 parts.push(InstructionPart::separator());
857 parts.push(InstructionPart::opaque(reg_n));
858 }
859 0x6009 => {
860 parts.push(InstructionPart::opcode("swap.w", Ops::SwapWRmRn as u16));
861 parts.push(InstructionPart::opaque(reg_m));
862 parts.push(InstructionPart::separator());
863 parts.push(InstructionPart::opaque(reg_n));
864 }
865 0x2008 => {
866 parts.push(InstructionPart::opcode("tst", Ops::TstRmRn as u16));
867 parts.push(InstructionPart::opaque(reg_m));
868 parts.push(InstructionPart::separator());
869 parts.push(InstructionPart::opaque(reg_n));
870 }
871 0x200a => {
872 parts.push(InstructionPart::opcode("xor", Ops::XorRmRn as u16));
873 parts.push(InstructionPart::opaque(reg_m));
874 parts.push(InstructionPart::separator());
875 parts.push(InstructionPart::opaque(reg_n));
876 }
877 0x200d => {
878 parts.push(InstructionPart::opcode("xtrct", Ops::XtrctRmRn as u16));
879 parts.push(InstructionPart::opaque(reg_m));
880 parts.push(InstructionPart::separator());
881 parts.push(InstructionPart::opaque(reg_n));
882 }
883 0x2000 => {
884 parts.push(InstructionPart::opcode("mov.b", Ops::MovBRmAtRn as u16));
885 parts.push(InstructionPart::opaque(reg_m));
886 parts.push(InstructionPart::separator());
887 parts.push(InstructionPart::basic("@"));
888 parts.push(InstructionPart::opaque(reg_n));
889 }
890 0x2001 => {
891 parts.push(InstructionPart::opcode("mov.w", Ops::MovWRmAtRn as u16));
892 parts.push(InstructionPart::opaque(reg_m));
893 parts.push(InstructionPart::separator());
894 parts.push(InstructionPart::basic("@"));
895 parts.push(InstructionPart::opaque(reg_n));
896 }
897 0x2002 => {
898 parts.push(InstructionPart::opcode("mov.l", Ops::MovLRmAtRn as u16));
899 parts.push(InstructionPart::opaque(reg_m));
900 parts.push(InstructionPart::separator());
901 parts.push(InstructionPart::basic("@"));
902 parts.push(InstructionPart::opaque(reg_n));
903 }
904 0x6000 => {
905 parts.push(InstructionPart::opcode("mov.b", Ops::MovBAtRmRn as u16));
906 parts.push(InstructionPart::basic("@"));
907 parts.push(InstructionPart::opaque(reg_m));
908 parts.push(InstructionPart::separator());
909 parts.push(InstructionPart::opaque(reg_n));
910 }
911 0x6001 => {
912 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtRmRn as u16));
913 parts.push(InstructionPart::basic("@"));
914 parts.push(InstructionPart::opaque(reg_m));
915 parts.push(InstructionPart::separator());
916 parts.push(InstructionPart::opaque(reg_n));
917 }
918 0x6002 => {
919 parts.push(InstructionPart::opcode("mov.l", Ops::MovLAtRmRn as u16));
920 parts.push(InstructionPart::basic("@"));
921 parts.push(InstructionPart::opaque(reg_m));
922 parts.push(InstructionPart::separator());
923 parts.push(InstructionPart::opaque(reg_n));
924 }
925 0x000f => {
926 parts.push(InstructionPart::opcode("mac.l", Ops::MacLAtRmIncAtRnInc as u16));
927 parts.push(InstructionPart::basic("@"));
928 parts.push(InstructionPart::opaque(reg_m));
929 parts.push(InstructionPart::basic("+"));
930 parts.push(InstructionPart::separator());
931 parts.push(InstructionPart::basic("@"));
932 parts.push(InstructionPart::opaque(reg_n));
933 parts.push(InstructionPart::basic("+"));
934 }
935 0x400f => {
936 parts.push(InstructionPart::opcode("mac.w", Ops::MacWAtRmIncAtRnInc as u16));
937 parts.push(InstructionPart::basic("@"));
938 parts.push(InstructionPart::opaque(reg_m));
939 parts.push(InstructionPart::basic("+"));
940 parts.push(InstructionPart::separator());
941 parts.push(InstructionPart::basic("@"));
942 parts.push(InstructionPart::opaque(reg_n));
943 parts.push(InstructionPart::basic("+"));
944 }
945 0x6004 => {
946 parts.push(InstructionPart::opcode("mov.b", Ops::MovBAtRmIncRn as u16));
947 parts.push(InstructionPart::basic("@"));
948 parts.push(InstructionPart::opaque(reg_m));
949 parts.push(InstructionPart::basic("+"));
950 parts.push(InstructionPart::separator());
951 parts.push(InstructionPart::opaque(reg_n));
952 }
953 0x6005 => {
954 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtRmIncRn as u16));
955 parts.push(InstructionPart::basic("@"));
956 parts.push(InstructionPart::opaque(reg_m));
957 parts.push(InstructionPart::basic("+"));
958 parts.push(InstructionPart::separator());
959 parts.push(InstructionPart::opaque(reg_n));
960 }
961 0x6006 => {
962 parts.push(InstructionPart::opcode("mov.l", Ops::MovLAtRmIncRn as u16));
963 parts.push(InstructionPart::basic("@"));
964 parts.push(InstructionPart::opaque(reg_m));
965 parts.push(InstructionPart::basic("+"));
966 parts.push(InstructionPart::separator());
967 parts.push(InstructionPart::opaque(reg_n));
968 }
969 0x2004 => {
970 parts.push(InstructionPart::opcode("mov.b", Ops::MovBRmAtDecRn as u16));
971 parts.push(InstructionPart::opaque(reg_m));
972 parts.push(InstructionPart::separator());
973 parts.push(InstructionPart::basic("@-"));
974 parts.push(InstructionPart::opaque(reg_n));
975 }
976 0x2005 => {
977 parts.push(InstructionPart::opcode("mov.w", Ops::MovWRmAtDecRn as u16));
978 parts.push(InstructionPart::opaque(reg_m));
979 parts.push(InstructionPart::separator());
980 parts.push(InstructionPart::basic("@-"));
981 parts.push(InstructionPart::opaque(reg_n));
982 }
983 0x2006 => {
984 parts.push(InstructionPart::opcode("mov.l", Ops::MovLRmAtDecRn as u16));
985 parts.push(InstructionPart::opaque(reg_m));
986 parts.push(InstructionPart::separator());
987 parts.push(InstructionPart::basic("@-"));
988 parts.push(InstructionPart::opaque(reg_n));
989 }
990 0x0004 => {
991 parts.push(InstructionPart::opcode("mov.b", Ops::MovBRmAtR0Rn as u16));
992 parts.push(InstructionPart::opaque(reg_m));
993 parts.push(InstructionPart::separator());
994 parts.push(InstructionPart::basic("@("));
995 parts.push(InstructionPart::opaque("r0"));
996 parts.push(InstructionPart::separator());
997 parts.push(InstructionPart::opaque(reg_n));
998 parts.push(InstructionPart::basic(")"));
999 }
1000 0x0005 => {
1001 parts.push(InstructionPart::opcode("mov.w", Ops::MovWRmAtR0Rn as u16));
1002 parts.push(InstructionPart::opaque(reg_m));
1003 parts.push(InstructionPart::separator());
1004 parts.push(InstructionPart::basic("@("));
1005 parts.push(InstructionPart::opaque("r0"));
1006 parts.push(InstructionPart::separator());
1007 parts.push(InstructionPart::opaque(reg_n));
1008 parts.push(InstructionPart::basic(")"));
1009 }
1010 0x0006 => {
1011 parts.push(InstructionPart::opcode("mov.l", Ops::MovLRmAtR0Rn as u16));
1012 parts.push(InstructionPart::opaque(reg_m));
1013 parts.push(InstructionPart::separator());
1014 parts.push(InstructionPart::basic("@("));
1015 parts.push(InstructionPart::opaque("r0"));
1016 parts.push(InstructionPart::separator());
1017 parts.push(InstructionPart::opaque(reg_n));
1018 parts.push(InstructionPart::basic(")"));
1019 }
1020 0x000c => {
1021 parts.push(InstructionPart::opcode("mov.b", Ops::MovBAtR0RmRn as u16));
1022 parts.push(InstructionPart::basic("@("));
1023 parts.push(InstructionPart::opaque("r0"));
1024 parts.push(InstructionPart::separator());
1025 parts.push(InstructionPart::opaque(reg_m));
1026 parts.push(InstructionPart::basic(")"));
1027 parts.push(InstructionPart::separator());
1028 parts.push(InstructionPart::opaque(reg_n));
1029 }
1030 0x000d => {
1031 parts.push(InstructionPart::opcode("mov.w", Ops::MovWAtR0RmRn as u16));
1032 parts.push(InstructionPart::basic("@("));
1033 parts.push(InstructionPart::opaque("r0"));
1034 parts.push(InstructionPart::separator());
1035 parts.push(InstructionPart::opaque(reg_m));
1036 parts.push(InstructionPart::basic(")"));
1037 parts.push(InstructionPart::separator());
1038 parts.push(InstructionPart::opaque(reg_n));
1039 }
1040 0x000e => {
1041 parts.push(InstructionPart::opcode("mov.l", Ops::MovLAtR0RmRn as u16));
1042 parts.push(InstructionPart::basic("@("));
1043 parts.push(InstructionPart::opaque("r0"));
1044 parts.push(InstructionPart::separator());
1045 parts.push(InstructionPart::opaque(reg_m));
1046 parts.push(InstructionPart::basic(")"));
1047 parts.push(InstructionPart::separator());
1048 parts.push(InstructionPart::opaque(reg_n));
1049 }
1050 _ => match_ff00(v_addr, op, mode, parts, resolved, branch_dest),
1051 }
1052}
1053
1054fn match_f0ff(
1055 v_addr: u32,
1056 op: u16,
1057 mode: bool,
1058 parts: &mut Vec<InstructionPart>,
1059 resolved: &ResolvedInstructionRef,
1060 branch_dest: &mut Option<u64>,
1061) {
1062 let reg = REG_NAMES[((op >> 8) & 0xf) as usize];
1063 match op & 0xf0ff {
1064 0x4015 => {
1065 parts.push(InstructionPart::opcode("cmp/pl", Ops::CmpPlRn as u16));
1067 parts.push(InstructionPart::opaque(reg));
1068 }
1069 0x4011 => {
1070 parts.push(InstructionPart::opcode("cmp/pz", Ops::CmpPzRn as u16));
1072 parts.push(InstructionPart::opaque(reg));
1073 }
1074 0x4010 => {
1075 parts.push(InstructionPart::opcode("dt", Ops::DtRn as u16));
1077 parts.push(InstructionPart::opaque(reg));
1078 }
1079 0x0029 => {
1080 parts.push(InstructionPart::opcode("movt", Ops::MovtRn as u16));
1082 parts.push(InstructionPart::opaque(reg));
1083 }
1084 0x4004 => {
1085 parts.push(InstructionPart::opcode("rotl", Ops::RotlRn as u16));
1087 parts.push(InstructionPart::opaque(reg));
1088 }
1089 0x4005 => {
1090 parts.push(InstructionPart::opcode("rotr", Ops::RotrRn as u16));
1092 parts.push(InstructionPart::opaque(reg));
1093 }
1094 0x4024 => {
1095 parts.push(InstructionPart::opcode("rotcl", Ops::RotclRn as u16));
1097 parts.push(InstructionPart::opaque(reg));
1098 }
1099 0x4025 => {
1100 parts.push(InstructionPart::opcode("rotcr", Ops::RotcrRn as u16));
1102 parts.push(InstructionPart::opaque(reg));
1103 }
1104 0x4020 => {
1105 parts.push(InstructionPart::opcode("shal", Ops::ShalRn as u16));
1107 parts.push(InstructionPart::opaque(reg));
1108 }
1109 0x4021 => {
1110 parts.push(InstructionPart::opcode("shar", Ops::SharRn as u16));
1112 parts.push(InstructionPart::opaque(reg));
1113 }
1114 0x4000 => {
1115 parts.push(InstructionPart::opcode("shll", Ops::ShllRn as u16));
1117 parts.push(InstructionPart::opaque(reg));
1118 }
1119 0x4001 => {
1120 parts.push(InstructionPart::opcode("shlr", Ops::ShlrRn as u16));
1122 parts.push(InstructionPart::opaque(reg));
1123 }
1124 0x4008 => {
1125 parts.push(InstructionPart::opcode("shll2", Ops::Shll2Rn as u16));
1127 parts.push(InstructionPart::opaque(reg));
1128 }
1129 0x4009 => {
1130 parts.push(InstructionPart::opcode("shlr2", Ops::Shlr2Rn as u16));
1132 parts.push(InstructionPart::opaque(reg));
1133 }
1134 0x4018 => {
1135 parts.push(InstructionPart::opcode("shll8", Ops::Shll8Rn as u16));
1137 parts.push(InstructionPart::opaque(reg));
1138 }
1139 0x4019 => {
1140 parts.push(InstructionPart::opcode("shlr8", Ops::Shlr8Rn as u16));
1142 parts.push(InstructionPart::opaque(reg));
1143 }
1144 0x4028 => {
1145 parts.push(InstructionPart::opcode("shll16", Ops::Shll16Rn as u16));
1147 parts.push(InstructionPart::opaque(reg));
1148 }
1149 0x4029 => {
1150 parts.push(InstructionPart::opcode("shlr16", Ops::Shlr16Rn as u16));
1152 parts.push(InstructionPart::opaque(reg));
1153 }
1154 0x0002 => {
1155 parts.push(InstructionPart::opcode("stc", Ops::StcSrRn as u16));
1157 parts.push(InstructionPart::opaque("sr"));
1158 parts.push(InstructionPart::separator());
1159 parts.push(InstructionPart::opaque(reg));
1160 }
1161 0x0012 => {
1162 parts.push(InstructionPart::opcode("stc", Ops::StcGbrRn as u16));
1164 parts.push(InstructionPart::opaque("gbr"));
1165 parts.push(InstructionPart::separator());
1166 parts.push(InstructionPart::opaque(reg));
1167 }
1168 0x0022 => {
1169 parts.push(InstructionPart::opcode("stc", Ops::StcVbrRn as u16));
1171 parts.push(InstructionPart::opaque("vbr"));
1172 parts.push(InstructionPart::separator());
1173 parts.push(InstructionPart::opaque(reg));
1174 }
1175 0x000a => {
1176 parts.push(InstructionPart::opcode("sts", Ops::StsMachRn as u16));
1178 parts.push(InstructionPart::opaque("mach"));
1179 parts.push(InstructionPart::separator());
1180 parts.push(InstructionPart::opaque(reg));
1181 }
1182 0x001a => {
1183 parts.push(InstructionPart::opcode("sts", Ops::StsMaclRn as u16));
1185 parts.push(InstructionPart::opaque("macl"));
1186 parts.push(InstructionPart::separator());
1187 parts.push(InstructionPart::opaque(reg));
1188 }
1189 0x002a => {
1190 parts.push(InstructionPart::opcode("sts", Ops::StsPrRn as u16));
1192 parts.push(InstructionPart::opaque("pr"));
1193 parts.push(InstructionPart::separator());
1194 parts.push(InstructionPart::opaque(reg));
1195 }
1196 0x401b => {
1197 parts.push(InstructionPart::opcode("tas.b", Ops::TasB as u16));
1199 parts.push(InstructionPart::opaque(reg));
1200 }
1201 0x4003 => {
1202 parts.push(InstructionPart::opcode("stc.l", Ops::StcLSrAtDecrementRn as u16));
1203 parts.push(InstructionPart::opaque("sr"));
1204 parts.push(InstructionPart::separator());
1205 parts.push(InstructionPart::basic("@-"));
1206 parts.push(InstructionPart::opaque(reg));
1207 }
1208 0x4013 => {
1209 parts.push(InstructionPart::opcode("stc.l", Ops::StcLGbrAtDecrementRn as u16));
1210 parts.push(InstructionPart::opaque("gbr"));
1211 parts.push(InstructionPart::separator());
1212 parts.push(InstructionPart::basic("@-"));
1213 parts.push(InstructionPart::opaque(reg));
1214 }
1215 0x4023 => {
1216 parts.push(InstructionPart::opcode("stc.l", Ops::StcLVbrAtDecrementRn as u16));
1217 parts.push(InstructionPart::opaque("vbr"));
1218 parts.push(InstructionPart::separator());
1219 parts.push(InstructionPart::basic("@-"));
1220 parts.push(InstructionPart::opaque(reg));
1221 }
1222 0x4002 => {
1223 parts.push(InstructionPart::opcode("sts.l", Ops::StsLMachAtDecrementRn as u16));
1224 parts.push(InstructionPart::opaque("mach"));
1225 parts.push(InstructionPart::separator());
1226 parts.push(InstructionPart::basic("@-"));
1227 parts.push(InstructionPart::opaque(reg));
1228 }
1229 0x4012 => {
1230 parts.push(InstructionPart::opcode("sts.l", Ops::StsLMaclAtDecrementRn as u16));
1231 parts.push(InstructionPart::opaque("macl"));
1232 parts.push(InstructionPart::separator());
1233 parts.push(InstructionPart::basic("@-"));
1234 parts.push(InstructionPart::opaque(reg));
1235 }
1236 0x4022 => {
1237 parts.push(InstructionPart::opcode("sts.l", Ops::StsLPrAtDecrementRn as u16));
1238 parts.push(InstructionPart::opaque("pr"));
1239 parts.push(InstructionPart::separator());
1240 parts.push(InstructionPart::basic("@-"));
1241 parts.push(InstructionPart::opaque(reg));
1242 }
1243 0x400e => {
1244 parts.push(InstructionPart::opcode("ldc", Ops::LdcRnSr as u16));
1245 parts.push(InstructionPart::opaque(reg));
1246 parts.push(InstructionPart::separator());
1247 parts.push(InstructionPart::opaque("sr"));
1248 }
1249 0x401e => {
1250 parts.push(InstructionPart::opcode("ldc", Ops::LdcRnGbr as u16));
1251 parts.push(InstructionPart::opaque(reg));
1252 parts.push(InstructionPart::separator());
1253 parts.push(InstructionPart::opaque("gbr"));
1254 }
1255 0x402e => {
1256 parts.push(InstructionPart::opcode("ldc", Ops::LdcRnVbr as u16));
1257 parts.push(InstructionPart::opaque(reg));
1258 parts.push(InstructionPart::separator());
1259 parts.push(InstructionPart::opaque("vbr"));
1260 }
1261 0x400a => {
1262 parts.push(InstructionPart::opcode("lds", Ops::LdsRnMach as u16));
1263 parts.push(InstructionPart::opaque(reg));
1264 parts.push(InstructionPart::separator());
1265 parts.push(InstructionPart::opaque("mach"));
1266 }
1267 0x401a => {
1268 parts.push(InstructionPart::opcode("lds", Ops::LdsRnMacl as u16));
1269 parts.push(InstructionPart::opaque(reg));
1270 parts.push(InstructionPart::separator());
1271 parts.push(InstructionPart::opaque("macl"));
1272 }
1273 0x402a => {
1274 parts.push(InstructionPart::opcode("lds", Ops::LdsRnPr as u16));
1275 parts.push(InstructionPart::opaque(reg));
1276 parts.push(InstructionPart::separator());
1277 parts.push(InstructionPart::opaque("pr"));
1278 }
1279 0x402b => {
1280 parts.push(InstructionPart::opcode("jmp", Ops::JmpAtRn as u16));
1281 parts.push(InstructionPart::basic("@"));
1282 parts.push(InstructionPart::opaque(reg));
1283 }
1284 0x400b => {
1285 parts.push(InstructionPart::opcode("jsr", Ops::JsrAtRn as u16));
1286 parts.push(InstructionPart::basic("@"));
1287 parts.push(InstructionPart::opaque(reg));
1288 }
1289 0x4007 => {
1290 parts.push(InstructionPart::opcode("ldc.l", Ops::LdcLAtRnIncSr as u16));
1291 parts.push(InstructionPart::basic("@"));
1292 parts.push(InstructionPart::opaque(reg));
1293 parts.push(InstructionPart::basic("+"));
1294 parts.push(InstructionPart::separator());
1295 parts.push(InstructionPart::opaque("sr"));
1296 }
1297 0x4017 => {
1298 parts.push(InstructionPart::opcode("ldc.l", Ops::LdcLAtRnIncGbr as u16));
1299 parts.push(InstructionPart::basic("@"));
1300 parts.push(InstructionPart::opaque(reg));
1301 parts.push(InstructionPart::basic("+"));
1302 parts.push(InstructionPart::separator());
1303 parts.push(InstructionPart::opaque("gbr"));
1304 }
1305 0x4027 => {
1306 parts.push(InstructionPart::opcode("ldc.l", Ops::LdcLAtRnIncVbr as u16));
1307 parts.push(InstructionPart::basic("@"));
1308 parts.push(InstructionPart::opaque(reg));
1309 parts.push(InstructionPart::basic("+"));
1310 parts.push(InstructionPart::separator());
1311 parts.push(InstructionPart::opaque("vbr"));
1312 }
1313 0x4006 => {
1314 parts.push(InstructionPart::opcode("lds.l", Ops::LdsLAtRnIncMach as u16));
1315 parts.push(InstructionPart::basic("@"));
1316 parts.push(InstructionPart::opaque(reg));
1317 parts.push(InstructionPart::basic("+"));
1318 parts.push(InstructionPart::separator());
1319 parts.push(InstructionPart::opaque("mach"));
1320 }
1321 0x4016 => {
1322 parts.push(InstructionPart::opcode("lds.l", Ops::LdsLAtRnIncMacl as u16));
1323 parts.push(InstructionPart::basic("@"));
1324 parts.push(InstructionPart::opaque(reg));
1325 parts.push(InstructionPart::basic("+"));
1326 parts.push(InstructionPart::separator());
1327 parts.push(InstructionPart::opaque("macl"));
1328 }
1329 0x4026 => {
1330 parts.push(InstructionPart::opcode("lds.l", Ops::LdsLAtRnIncPr as u16));
1331 parts.push(InstructionPart::basic("@"));
1332 parts.push(InstructionPart::opaque(reg));
1333 parts.push(InstructionPart::basic("+"));
1334 parts.push(InstructionPart::separator());
1335 parts.push(InstructionPart::opaque("pr"));
1336 }
1337 0x0023 => {
1338 parts.push(InstructionPart::opcode("braf", Ops::BrafRn as u16));
1339 parts.push(InstructionPart::opaque(reg));
1340 }
1341 0x0003 => {
1342 parts.push(InstructionPart::opcode("bsrf", Ops::BsrfRn as u16));
1343 parts.push(InstructionPart::opaque(reg));
1344 }
1345 _ => {
1346 match_f00f(v_addr, op, mode, parts, resolved, branch_dest);
1347 }
1348 }
1349}
1350
1351pub fn sh2_disasm(
1352 v_addr: u32,
1353 op: u16,
1354 mode: bool,
1355 parts: &mut Vec<InstructionPart>,
1356 resolved: &ResolvedInstructionRef,
1357 branch_dest: &mut Option<u64>,
1358) {
1359 match op {
1360 0x0008 => parts.push(InstructionPart::opcode("clrt", Ops::Clrt as u16)),
1361 0x0028 => parts.push(InstructionPart::opcode("clrmac", Ops::Clrmac as u16)),
1362 0x0019 => parts.push(InstructionPart::opcode("div0u", Ops::Div0u as u16)),
1363 0x0009 => parts.push(InstructionPart::opcode("nop", Ops::Nop as u16)),
1364 0x002b => parts.push(InstructionPart::opcode("rte", Ops::Rte as u16)),
1365 0x000b => parts.push(InstructionPart::opcode("rts", Ops::Rts as u16)),
1366 0x0018 => parts.push(InstructionPart::opcode("sett", Ops::Sett as u16)),
1367 0x001b => parts.push(InstructionPart::opcode("sleep", Ops::Sleep as u16)),
1368 _ => {
1369 match_f0ff(v_addr, op, mode, parts, resolved, branch_dest);
1370 }
1371 }
1372}