1use core::fmt;
16use core::cmp;
17
18use yaxpeax_arch::{AddressDiff, Arch, Decoder, LengthedInstruction, Reader, StandardDecodeError};
19
20#[derive(Debug)]
21pub struct RX;
22
23impl Arch for RX {
24 type Address = u32;
25 type Word = u8;
26 type Instruction = Instruction;
27 type DecodeError = StandardDecodeError;
28 type Decoder = InstDecoder;
29 type Operand = Operand;
30}
31
32#[derive(Debug)]
33pub struct Instruction {
34 opcode: Opcode,
35 operands: [Operand; 3],
36 length: u8,
37}
38
39impl PartialEq for Instruction {
40 fn eq(&self, other: &Self) -> bool {
41 let Instruction {
42 opcode: left_opcode,
43 operands: _, length: left_length,
45 } = self;
46 let Instruction {
47 opcode: right_opcode,
48 operands: _, length: right_length,
50 } = other;
51
52 left_opcode == right_opcode &&
53 left_length == right_length &&
54 self.operands() == other.operands()
55 }
56}
57
58impl Instruction {
59 pub fn opcode(&self) -> Opcode {
60 self.opcode
61 }
62
63 pub fn operands(&self) -> &[Operand] {
64 &self.operands[..self.operand_count() as usize]
65 }
66
67 pub fn length(&self) -> u8 {
68 self.length
69 }
70
71 fn operand_count(&self) -> u8 {
72 let mut operands = 0;
73 for op in self.operands.iter() {
74 if op == &Operand::Nothing {
75 return operands;
76 }
77 operands += 1;
78 }
79
80 operands
81 }
82}
83
84impl Default for Instruction {
85 fn default() -> Instruction {
86 Instruction {
87 opcode: Opcode::NOP,
88 operands: [Operand::Nothing, Operand::Nothing, Operand::Nothing],
89 length: 1,
90 }
91 }
92}
93
94impl fmt::Display for Instruction {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 let ops = self.operands();
97 let mut size = None;
98 for op in ops {
99 match op {
100 Operand::Nothing => {},
101 Operand::Register { num: _ } => {},
102 Operand::RegisterRange { start_gpr: _, end_gpr: _ } => {},
103 Operand::Subreg { num: _, width } => {
104 size = Some(*width);
105 break;
106 },
107 Operand::Accumulator { num: _ } => {},
108 Operand::BitfieldSpec { bf_spec: _ } => {},
109 Operand::DoubleReg { num: _ } => {},
110 Operand::DoubleRegLow { num: _ } => {},
111 Operand::DoubleRegHigh { num: _ } => {},
112 Operand::ControlReg { reg: _ } => {},
113 Operand::PSWBit { bit: _ } => {},
114 Operand::Deref { gpr: _, disp: _, width } => {
115 size = Some(*width);
116 break;
117 },
118 Operand::DerefIndexed { base: _, index: _, width } => {
119 size = Some(*width);
120 break;
121 },
122 Operand::DoubleRegisterRange { start_reg: _, end_reg: _ } => {},
123 Operand::DoubleControlRegisterRange { start_reg: _, end_reg: _ } => {},
124 Operand::ImmB { imm: _ } => {},
125 Operand::ImmW { imm: _ } => {},
126 Operand::ImmL { imm: _ } => {},
127 Operand::BrS { offset: _ } => {
128 size = Some(SizeCode::S);
129 break;
130 },
131 Operand::BrB { offset: _ } => {
132 size = Some(SizeCode::B);
133 break;
134 },
135 Operand::BrW { offset: _ } => {
136 size = Some(SizeCode::W);
137 break;
138 },
139 Operand::BrA { offset: _ } => {
140 size = Some(SizeCode::A);
141 break;
142 },
143 }
144 }
145 write!(f, "{}", self.opcode())?;
146
147 if let Some(size) = size {
148 write!(f, ".{}", size)?;
149 }
150 if let Some(op) = ops.get(0) {
151 write!(f, " {}", op)?;
152 }
153 if let Some(op) = ops.get(1) {
154 write!(f, ", {}", op)?;
155 }
156 if let Some(op) = ops.get(2) {
157 write!(f, ", {}", op)?;
158 }
159 Ok(())
160 }
161}
162
163impl LengthedInstruction for Instruction {
164 type Unit = AddressDiff<<RX as Arch>::Address>;
165 fn min_size() -> Self::Unit {
166 AddressDiff::from_const(1)
167 }
168 fn len(&self) -> Self::Unit {
169 AddressDiff::from_const(self.length as u32)
170 }
171}
172
173impl yaxpeax_arch::Instruction for Instruction {
174 fn well_defined(&self) -> bool { true }
176}
177
178#[derive(Debug, Copy, Clone, PartialEq, Eq)]
179pub enum PSWBit {
180 C,
181 Z,
182 S,
183 O,
184 I,
185 U,
186}
187
188impl fmt::Display for PSWBit {
189 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190 match self {
191 PSWBit::C => f.write_str("c"),
192 PSWBit::Z => f.write_str("z"),
193 PSWBit::S => f.write_str("s"),
194 PSWBit::O => f.write_str("o"),
195 PSWBit::I => f.write_str("i"),
196 PSWBit::U => f.write_str("u"),
197 }
198 }
199}
200
201#[derive(Debug, Copy, Clone, PartialEq, Eq)]
202pub enum ControlReg {
203 PSW,
204 PC,
205 USP,
206 FPSW,
207 BPSW,
208 BPC,
209 ISP,
210 FINTV,
211 INTB,
212 EXTB,
213 DPSW,
217 DCMR,
218 DECNT,
219 DEPC,
220}
221
222impl fmt::Display for ControlReg {
223 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
224 match self {
225 ControlReg::PSW => f.write_str("psw"),
226 ControlReg::PC => f.write_str("pc"),
227 ControlReg::USP => f.write_str("usp"),
228 ControlReg::FPSW => f.write_str("fpsw"),
229 ControlReg::BPSW => f.write_str("bpsw"),
230 ControlReg::BPC => f.write_str("bpc"),
231 ControlReg::ISP => f.write_str("isp"),
232 ControlReg::FINTV => f.write_str("fintv"),
233 ControlReg::INTB => f.write_str("intb"),
234 ControlReg::EXTB => f.write_str("extb"),
235 ControlReg::DPSW => f.write_str("dpsw"),
236 ControlReg::DCMR => f.write_str("dcmr"),
237 ControlReg::DECNT => f.write_str("decnt"),
238 ControlReg::DEPC => f.write_str("DEPC")
239 }
240 }
241}
242
243#[derive(Debug, Copy, Clone, PartialEq, Eq)]
244pub struct BitfieldSpec {
245 bits: u16,
246}
247
248impl fmt::Display for BitfieldSpec {
249 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
250 write!(f, "#{}, #{}, #{}", self.source_start_bit(), self.destination_start_bit(), self.width())
251 }
252}
253
254impl BitfieldSpec {
255 fn source_start_bit(&self) -> u8 {
258 let dslb_and_slsb = ((self.bits >> 10) & 0b11111) as u8;
259 self.destination_start_bit().wrapping_sub(dslb_and_slsb) & 0x1f
260 }
261
262 fn destination_start_bit(&self) -> u8 {
265 ((self.bits >> 5) & 0b11111) as u8
266 }
267
268 fn width(&self) -> u8 {
270 let dslb_and_width = ((self.bits >> 10) & 0b11111) as u8;
271 dslb_and_width.wrapping_sub(self.destination_start_bit()) & 0x1f
272 }
273}
274
275#[derive(Debug, Copy, Clone, PartialEq, Eq)]
276pub enum Operand {
277 Nothing,
278 Register { num: u8 },
280 RegisterRange { start_gpr: u8, end_gpr: u8 },
282 Subreg { num: u8, width: SizeCode },
285 Accumulator { num: u8 },
286 BitfieldSpec { bf_spec: BitfieldSpec },
289 DoubleReg { num: u8 },
291 DoubleRegLow { num: u8 },
293 DoubleRegHigh { num: u8 },
295 ControlReg { reg: ControlReg },
296 PSWBit { bit: PSWBit },
297 Deref { gpr: u8, disp: u32, width: SizeCode },
301 DerefIndexed { base: u8, index: u8, width: SizeCode },
303 DoubleRegisterRange { start_reg: u8, end_reg: u8 },
305 DoubleControlRegisterRange { start_reg: ControlReg, end_reg: ControlReg },
306 ImmB { imm: u8 },
308 ImmW { imm: u16 },
310 ImmL { imm: u32 },
312 BrS { offset: u8 },
315 BrB { offset: i8 },
317 BrW { offset: i16 },
319 BrA { offset: i32 },
323}
324
325#[derive(Debug, Copy, Clone, PartialEq, Eq)]
326pub enum SizeCode {
327 S,
328 B,
329 W,
330 A,
331 L,
332 D,
333 UW,
334}
335
336impl fmt::Display for SizeCode {
337 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338 let text = match self {
339 SizeCode::S => "s",
340 SizeCode::B => "b",
341 SizeCode::W => "w",
342 SizeCode::A => "a",
343 SizeCode::L => "l",
344 SizeCode::D => "d",
345 SizeCode::UW => "uw",
346 };
347
348 f.write_str(text)
349 }
350}
351
352impl SizeCode {
353 fn bytes(&self) -> u8 {
354 match self {
355 SizeCode::S => 1,
356 SizeCode::B => 1,
357 SizeCode::W => 2,
358 SizeCode::UW => 2,
359 SizeCode::A => 3,
360 SizeCode::L => 4,
361 SizeCode::D => 8,
362 }
363 }
364}
365
366impl fmt::Display for Operand {
367 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
368 match self {
369 Operand::Nothing => {
370 f.write_str("")
371 },
372 Operand::Register { num } => {
373 write!(f, "r{}", num)
374 },
375 Operand::RegisterRange { start_gpr, end_gpr } => {
376 write!(f, "r{}-r{}", start_gpr, end_gpr)
377 }
378 Operand::Subreg { num, width: _unused } => {
379 write!(f, "r{}", num)
382 }
383 Operand::Accumulator { num } => {
384 write!(f, "a{}", num)
385 },
386 Operand::BitfieldSpec { bf_spec } => {
387 fmt::Display::fmt(bf_spec, f)
388 }
389 Operand::DoubleReg { num } => {
390 write!(f, "dr{}", num)
391 },
392 Operand::DoubleRegLow { num } => {
393 write!(f, "drl{}", num)
394 },
395 Operand::DoubleRegHigh { num } => {
396 write!(f, "drh{}", num)
397 },
398 Operand::ControlReg { reg } => {
399 fmt::Display::fmt(reg, f)
400 },
401 Operand::PSWBit { bit } => {
402 fmt::Display::fmt(bit, f)
403 }
404 Operand::Deref { gpr, disp, .. } => {
405 if *disp == 0 {
406 write!(f, "[r{}]", gpr)
407 } else {
408 write!(f, "{:x}h[r{}]", disp, gpr)
409 }
410 },
411 Operand::DerefIndexed { base, index, .. } => {
412 write!(f, "[r{}, r{}]", base, index)
415 }
416 Operand::DoubleRegisterRange { start_reg, end_reg } => {
417 write!(f, "dr{}-dr{}", start_reg, end_reg)
418 }
419 Operand::DoubleControlRegisterRange { start_reg, end_reg } => {
420 write!(f, "{}-{}", start_reg, end_reg)
421 }
422 Operand::BrS { offset } => {
423 write!(f, "$+{:#x}", offset)
425 }
426 Operand::BrB { offset } => {
427 if *offset < 0 {
429 write!(f, "$-{:#x}", -offset)
430 } else {
431 write!(f, "$+{:#x}", offset)
432 }
433 }
434 Operand::BrW { offset } => {
435 if *offset < 0 {
437 write!(f, "$-{:#x}", -offset)
438 } else {
439 write!(f, "$+{:#x}", offset)
440 }
441 }
442 Operand::BrA { offset } => {
443 if *offset < 0 {
445 write!(f, "$-{:#x}", -offset)
446 } else {
447 write!(f, "$+{:#x}", offset)
448 }
449 }
450 Operand::ImmB { imm } => {
451 write!(f, "#{:x}h", imm)
452 }
453 Operand::ImmW { imm } => {
454 write!(f, "#{:x}h", imm)
455 }
456 Operand::ImmL { imm } => {
457 write!(f, "#{:x}h", imm)
458 }
459 }
460 }
461}
462
463#[allow(non_camel_case_types)]
464#[derive(Debug, Copy, Clone, PartialEq, Eq)]
465pub enum Opcode {
466 REVW,
467 REVL,
468 MSBHI,
469 MSBLH,
470 MSBLO,
471 EMSBA,
472 MVFACHI,
473 MVFACLO,
474 MVFACMI,
475 MVFACGU,
476 RACW,
477 RACL,
478 RDACW,
479 RDACL,
480 MVTACHI,
481 MVTACLO,
482 MVTACGU,
483 XOR,
484 OR,
485 AND,
486 MUL,
487 ADD,
488 SUB,
489 MOVU,
490 SHLL,
491 SHAR,
492 SHLR,
493 BRA,
494 NOP,
495 MOV,
496 DMOV,
497 ROTR,
498 ROTL,
499 SCEQ,
500 SCNE,
501 SCGEU,
502 SCLTU,
503 SCGTU,
504 SCLEU,
505 SCPZ,
506 SCN,
507 SCGE,
508 SCLT,
509 SCGT,
510 SCLE,
511 SCO,
512 SCNO,
513 BMEQ,
514 BMNE,
515 BMGEU,
516 BMLTU,
517 BMGTU,
518 BMLEU,
519 BMPZ,
520 BMN,
521 BMGE,
522 BMLT,
523 BMGT,
524 BMLE,
525 BMO,
526 BMNO,
527 BNOT,
528 FSUB,
529 FCMP,
530 FADD,
531 FMUL,
532 FDIV,
533 MVFC,
534 MVFDC,
535 MVTC,
536 MVTDC,
537 STNZ,
538 STZ,
539 TST,
540 DIVU,
541 DIV,
542 EMULU,
543 EMUL,
544 MIN,
545 MAX,
546 ITOD,
547 FTOD,
548 UTOD,
549 ADC,
550 RSTR,
551 SAVE,
552 MULHI,
553 MULLO,
554 MULLH,
555 EMULA,
556 MACHI,
557 MACLO,
558 MACLH,
559 EMACA,
560 FTOI,
561 ITOF,
562 FTOU,
563 UTOF,
564 FSQRT,
565 ROUND,
566 BSET,
567 BCLR,
568 BTST,
569 BFMOV,
570 BFMOVZ,
571 ABS,
572 NOT,
573 XCHG,
574 SBB,
575 RTFI,
576 RTE,
577 WAIT,
578 SETPSW,
579 CLRPSW,
580 RMPA_B,
581 RMPA_W,
582 RMPA_L,
583 SMOVF,
584 SATR,
585 SSTR_B,
586 SSTR_W,
587 SSTR_L,
588 SMOVB,
589 SWHILE_B,
590 SWHILE_W,
591 SWHILE_L,
592 SMOVU,
593 SUNTIL_B,
594 SUNTIL_W,
595 SUNTIL_L,
596 SCMPU,
597 JMP,
598 JSR,
599 POP,
600 POPC,
601 POPM,
602 PUSH,
603 PUSHC,
604 PUSHM,
605 RORC,
606 ROLC,
607 NEG,
608 DPUSHM,
609 DPOP,
610 DTOF,
611 DROUND,
612 DSQRT,
613 DTOI,
614 DTOU,
615 DABS,
616 DNEG,
617 DADD,
618 DSUB,
619 DMUL,
620 DDIV,
621 DCMPUN,
622 DCMPEQ,
623 DCMPLT,
624 DCMPLE,
625 INT,
626 MVTIPL,
627 MVFDR,
628 CMP,
629 SAT,
630 RTSD,
631 BSR,
632 BRK,
633 BEQ,
634 BNE,
635 BGEU,
636 BLTU,
637 BGTU,
638 BLEU,
639 BPZ,
640 BN,
641 BGE,
642 BLT,
643 BGT,
644 BLE,
645 BO,
646 BNO,
647 RTS,
648}
649
650impl fmt::Display for Opcode {
651 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
652 match self {
653 Opcode::REVW => f.write_str("revw"),
654 Opcode::REVL => f.write_str("revl"),
655 Opcode::MSBHI => f.write_str("msbhi"),
656 Opcode::MSBLH => f.write_str("msblh"),
657 Opcode::MSBLO => f.write_str("msblo"),
658 Opcode::EMSBA => f.write_str("emsba"),
659 Opcode::MVFACHI => f.write_str("mvfachi"),
660 Opcode::MVFACLO => f.write_str("mvfaclo"),
661 Opcode::MVFACMI => f.write_str("mvfacmi"),
662 Opcode::MVFACGU => f.write_str("mvfacgu"),
663 Opcode::RACW => f.write_str("racw"),
664 Opcode::RACL => f.write_str("racl"),
665 Opcode::RDACW => f.write_str("rdacw"),
666 Opcode::RDACL => f.write_str("rdacl"),
667 Opcode::MVTACHI => f.write_str("mvtachi"),
668 Opcode::MVTACLO => f.write_str("mvtaclo"),
669 Opcode::MVTACGU => f.write_str("mvtacgu"),
670 Opcode::XOR => f.write_str("xor"),
671 Opcode::OR => f.write_str("or"),
672 Opcode::AND => f.write_str("and"),
673 Opcode::MUL => f.write_str("mul"),
674 Opcode::ADD => f.write_str("add"),
675 Opcode::SUB => f.write_str("sub"),
676 Opcode::MOVU => f.write_str("movu"),
677 Opcode::SHLL => f.write_str("shll"),
678 Opcode::SHAR => f.write_str("shar"),
679 Opcode::SHLR => f.write_str("shlr"),
680 Opcode::BRA => f.write_str("bra"),
681 Opcode::NOP => f.write_str("nop"),
682 Opcode::MOV => f.write_str("mov"),
683 Opcode::DMOV => f.write_str("dmov"),
684 Opcode::ROTR => f.write_str("rotr"),
685 Opcode::ROTL => f.write_str("rotl"),
686 Opcode::SCEQ => f.write_str("sceq"),
687 Opcode::SCNE => f.write_str("scne"),
688 Opcode::SCGEU => f.write_str("scgeu"),
689 Opcode::SCLTU => f.write_str("scltu"),
690 Opcode::SCGTU => f.write_str("scgtu"),
691 Opcode::SCLEU => f.write_str("scleu"),
692 Opcode::SCPZ => f.write_str("scpz"),
693 Opcode::SCN => f.write_str("scn"),
694 Opcode::SCGE => f.write_str("scge"),
695 Opcode::SCLT => f.write_str("sclt"),
696 Opcode::SCGT => f.write_str("scgt"),
697 Opcode::SCLE => f.write_str("scle"),
698 Opcode::SCO => f.write_str("sco"),
699 Opcode::SCNO => f.write_str("scno"),
700 Opcode::BMEQ => f.write_str("bmeq"),
701 Opcode::BMNE => f.write_str("bmne"),
702 Opcode::BMGEU => f.write_str("bmgeu"),
703 Opcode::BMLTU => f.write_str("bmltu"),
704 Opcode::BMGTU => f.write_str("bmgtu"),
705 Opcode::BMLEU => f.write_str("bmleu"),
706 Opcode::BMPZ => f.write_str("bmpz"),
707 Opcode::BMN => f.write_str("bmn"),
708 Opcode::BMGE => f.write_str("bmge"),
709 Opcode::BMLT => f.write_str("bmlt"),
710 Opcode::BMGT => f.write_str("bmgt"),
711 Opcode::BMLE => f.write_str("bmle"),
712 Opcode::BMO => f.write_str("bmo"),
713 Opcode::BMNO => f.write_str("bmno"),
714 Opcode::BNOT => f.write_str("bnot"),
715 Opcode::FSUB => f.write_str("fsub"),
716 Opcode::FCMP => f.write_str("fcmp"),
717 Opcode::FADD => f.write_str("fadd"),
718 Opcode::FMUL => f.write_str("fmul"),
719 Opcode::FDIV => f.write_str("fdiv"),
720 Opcode::MVFC => f.write_str("mvfc"),
721 Opcode::MVFDC => f.write_str("mvfdc"),
722 Opcode::MVTC => f.write_str("mvtc"),
723 Opcode::MVTDC => f.write_str("mvtdc"),
724 Opcode::STNZ => f.write_str("stnz"),
725 Opcode::STZ => f.write_str("stz"),
726 Opcode::TST => f.write_str("tst"),
727 Opcode::DIVU => f.write_str("divu"),
728 Opcode::DIV => f.write_str("div"),
729 Opcode::EMULU => f.write_str("emulu"),
730 Opcode::EMUL => f.write_str("emul"),
731 Opcode::MIN => f.write_str("min"),
732 Opcode::MAX => f.write_str("max"),
733 Opcode::ITOD => f.write_str("itod"),
734 Opcode::FTOD => f.write_str("ftod"),
735 Opcode::UTOD => f.write_str("utod"),
736 Opcode::ADC => f.write_str("adc"),
737 Opcode::RSTR => f.write_str("rstr"),
738 Opcode::SAVE => f.write_str("save"),
739 Opcode::MULHI => f.write_str("mulhi"),
740 Opcode::MULLO => f.write_str("mullo"),
741 Opcode::MULLH => f.write_str("mullh"),
742 Opcode::EMULA => f.write_str("emula"),
743 Opcode::MACHI => f.write_str("machi"),
744 Opcode::MACLO => f.write_str("maclo"),
745 Opcode::MACLH => f.write_str("maclh"),
746 Opcode::EMACA => f.write_str("emaca"),
747 Opcode::FTOI => f.write_str("ftoi"),
748 Opcode::ITOF => f.write_str("itof"),
749 Opcode::FTOU => f.write_str("ftou"),
750 Opcode::UTOF => f.write_str("utof"),
751 Opcode::FSQRT => f.write_str("fsqrt"),
752 Opcode::ROUND => f.write_str("round"),
753 Opcode::BSET => f.write_str("bset"),
754 Opcode::BCLR => f.write_str("bclr"),
755 Opcode::BTST => f.write_str("btst"),
756 Opcode::BFMOV => f.write_str("bfmov"),
757 Opcode::BFMOVZ => f.write_str("bfmovz"),
758 Opcode::ABS => f.write_str("abs"),
759 Opcode::NOT => f.write_str("not"),
760 Opcode::XCHG => f.write_str("xchg"),
761 Opcode::SBB => f.write_str("sbb"),
762 Opcode::RTFI => f.write_str("rtfi"),
763 Opcode::RTE => f.write_str("rte"),
764 Opcode::WAIT => f.write_str("wait"),
765 Opcode::SETPSW => f.write_str("setpsw"),
766 Opcode::CLRPSW => f.write_str("clrpsw"),
767 Opcode::RMPA_B => f.write_str("rmpa_b"),
768 Opcode::RMPA_W => f.write_str("rmpa_w"),
769 Opcode::RMPA_L => f.write_str("rmpa_l"),
770 Opcode::SMOVF => f.write_str("smovf"),
771 Opcode::SATR => f.write_str("satr"),
772 Opcode::SSTR_B => f.write_str("sstr_b"),
773 Opcode::SSTR_W => f.write_str("sstr_w"),
774 Opcode::SSTR_L => f.write_str("sstr_l"),
775 Opcode::SMOVB => f.write_str("smovb"),
776 Opcode::SWHILE_B => f.write_str("swhile_b"),
777 Opcode::SWHILE_W => f.write_str("swhile_w"),
778 Opcode::SWHILE_L => f.write_str("swhile_l"),
779 Opcode::SMOVU => f.write_str("smovu"),
780 Opcode::SUNTIL_B => f.write_str("suntil_b"),
781 Opcode::SUNTIL_W => f.write_str("suntil_w"),
782 Opcode::SUNTIL_L => f.write_str("suntil_l"),
783 Opcode::SCMPU => f.write_str("scmpu"),
784 Opcode::JMP => f.write_str("jmp"),
785 Opcode::JSR => f.write_str("jsr"),
786 Opcode::POP => f.write_str("pop"),
787 Opcode::POPC => f.write_str("popc"),
788 Opcode::POPM => f.write_str("popm"),
789 Opcode::PUSH => f.write_str("push"),
790 Opcode::PUSHC => f.write_str("pushc"),
791 Opcode::PUSHM => f.write_str("pushm"),
792 Opcode::RORC => f.write_str("rorc"),
793 Opcode::ROLC => f.write_str("rolc"),
794 Opcode::NEG => f.write_str("neg"),
795 Opcode::DPUSHM => f.write_str("dpushm"),
796 Opcode::DPOP => f.write_str("dpop"),
797 Opcode::DTOF => f.write_str("dtof"),
798 Opcode::DROUND => f.write_str("dround"),
799 Opcode::DSQRT => f.write_str("dsqrt"),
800 Opcode::DTOI => f.write_str("dtoi"),
801 Opcode::DTOU => f.write_str("dtou"),
802 Opcode::DABS => f.write_str("dabs"),
803 Opcode::DNEG => f.write_str("dneg"),
804 Opcode::DADD => f.write_str("dadd"),
805 Opcode::DSUB => f.write_str("dsub"),
806 Opcode::DMUL => f.write_str("dmul"),
807 Opcode::DDIV => f.write_str("ddiv"),
808 Opcode::DCMPUN => f.write_str("dcmpun"),
809 Opcode::DCMPEQ => f.write_str("dcmpeq"),
810 Opcode::DCMPLT => f.write_str("dcmplt"),
811 Opcode::DCMPLE => f.write_str("dcmple"),
812 Opcode::INT => f.write_str("int"),
813 Opcode::MVTIPL => f.write_str("mvtipl"),
814 Opcode::MVFDR => f.write_str("mvfdr"),
815 Opcode::CMP => f.write_str("cmp"),
816 Opcode::SAT => f.write_str("sat"),
817 Opcode::RTSD => f.write_str("rtsd"),
818 Opcode::BSR => f.write_str("bsr"),
819 Opcode::BRK => f.write_str("brk"),
820 Opcode::BEQ => f.write_str("beq"),
821 Opcode::BNE => f.write_str("bne"),
822 Opcode::BGEU => f.write_str("bgeu"),
823 Opcode::BLTU => f.write_str("bltu"),
824 Opcode::BGTU => f.write_str("bgtu"),
825 Opcode::BLEU => f.write_str("bleu"),
826 Opcode::BPZ => f.write_str("bpz"),
827 Opcode::BN => f.write_str("bn"),
828 Opcode::BGE => f.write_str("bge"),
829 Opcode::BLT => f.write_str("blt"),
830 Opcode::BGT => f.write_str("bgt"),
831 Opcode::BLE => f.write_str("ble"),
832 Opcode::BO => f.write_str("bo"),
833 Opcode::BNO => f.write_str("bno"),
834 Opcode::RTS => f.write_str("rts"),
835 }
836 }
837}
838
839#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord)]
840#[repr(u8)]
841pub enum RxVersion {
842 V1,
843 V2,
844 V3,
845}
846
847impl PartialOrd for RxVersion {
848 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
849 (*self as u8).partial_cmp(&(*other as u8))
850 }
851}
852
853#[test]
854fn versions_compare_right() {
855 assert!(RxVersion::V1 < RxVersion::V2);
856 assert!(RxVersion::V2 < RxVersion::V3);
857 assert!(RxVersion::V1 < RxVersion::V3);
858}
859
860#[derive(Debug)]
861pub struct InstDecoder {
862 version: RxVersion,
863}
864
865impl Default for InstDecoder {
866 fn default() -> Self {
870 Self::v3()
871 }
872}
873
874impl InstDecoder {
875 pub fn v1() -> Self {
876 Self { version: RxVersion::V1 }
877 }
878
879 pub fn v2() -> Self {
880 Self { version: RxVersion::V2 }
881 }
882
883 pub fn v3() -> Self {
884 Self { version: RxVersion::V3 }
885 }
886
887 fn num_to_psw_bit(&self, reg: u8) -> Result<Operand, <RX as Arch>::DecodeError> {
888 match reg {
889 0b0000 => Ok(Operand::PSWBit { bit: PSWBit::C }),
890 0b0001 => Ok(Operand::PSWBit { bit: PSWBit::Z }),
891 0b0010 => Ok(Operand::PSWBit { bit: PSWBit::S }),
892 0b0011 => Ok(Operand::PSWBit { bit: PSWBit::O }),
893 0b1000 => Ok(Operand::PSWBit { bit: PSWBit::I }),
894 0b1001 => Ok(Operand::PSWBit { bit: PSWBit::U }),
895 _ => Err(StandardDecodeError::InvalidOperand),
896 }
897 }
898
899 fn reg_to_control_reg(&self, reg: u8) -> Result<Operand, <RX as Arch>::DecodeError> {
900 match reg {
901 0b0000 => { Ok(Operand::ControlReg { reg: ControlReg::PSW }) },
902 0b0001 => { Ok(Operand::ControlReg { reg: ControlReg::PC }) },
903 0b0010 => { Ok(Operand::ControlReg { reg: ControlReg::USP }) },
904 0b0011 => { Ok(Operand::ControlReg { reg: ControlReg::FPSW}) },
905 0b1000 => { Ok(Operand::ControlReg { reg: ControlReg::BPSW }) },
906 0b1001 => { Ok(Operand::ControlReg { reg: ControlReg::BPC }) },
907 0b1010 => { Ok(Operand::ControlReg { reg: ControlReg::ISP }) },
908 0b1011 => { Ok(Operand::ControlReg { reg: ControlReg::FINTV }) },
909 0b1100 => { Ok(Operand::ControlReg { reg: ControlReg::INTB }) },
910 0b1101 => {
911 if self.version >= RxVersion::V3 {
912 Ok(Operand::ControlReg { reg: ControlReg::EXTB })
913 } else {
914 Err(StandardDecodeError::InvalidOperand)
915 }
916 },
917 _ => {
918 Err(StandardDecodeError::InvalidOperand)
919 }
920 }
921 }
922
923 fn reg_to_double_control_reg(&self, reg: u8) -> Result<Operand, <RX as Arch>::DecodeError> {
924 match reg {
925 0b0000 => { Ok(Operand::ControlReg { reg: ControlReg::DPSW }) },
926 0b0001 => { Ok(Operand::ControlReg { reg: ControlReg::DCMR }) },
927 0b0010 => { Ok(Operand::ControlReg { reg: ControlReg::DECNT }) },
928 0b0011 => { Ok(Operand::ControlReg { reg: ControlReg::DEPC }) },
929 _ => {
930 Err(StandardDecodeError::InvalidOperand)
931 }
932 }
933 }
934}
935
936trait DecodeHandler<T: Reader<<RX as Arch>::Address, <RX as Arch>::Word>> {
937 #[inline(always)]
938 fn read_u8(&mut self, words: &mut T) -> Result<u8, <RX as Arch>::DecodeError> {
939 let b = words.next()?;
940 self.on_word_read(b);
941 Ok(b)
942 }
943 #[inline(always)]
944 fn read_u16(&mut self, words: &mut T) -> Result<u16, <RX as Arch>::DecodeError> {
945 let mut buf = [0u8; 2];
946 words.next_n(&mut buf).ok().ok_or(StandardDecodeError::ExhaustedInput)?;
947 self.on_word_read(buf[0]);
948 self.on_word_read(buf[1]);
949 Ok(u16::from_le_bytes(buf))
950 }
951 #[inline(always)]
952 fn read_u24(&mut self, words: &mut T) -> Result<u32, <RX as Arch>::DecodeError> {
953 let mut buf = [0u8; 4];
954 words.next_n(&mut buf[1..4]).ok().ok_or(StandardDecodeError::ExhaustedInput)?;
957 self.on_word_read(buf[0]);
958 self.on_word_read(buf[1]);
959 self.on_word_read(buf[2]);
960 Ok(u32::from_le_bytes(buf))
961 }
962 #[inline(always)]
963 fn read_i24(&mut self, words: &mut T) -> Result<i32, <RX as Arch>::DecodeError> {
964 let v = self.read_u24(words)?;
965 Ok(((v as i32) << 8) >> 8)
966 }
967 #[inline(always)]
968 fn read_u32(&mut self, words: &mut T) -> Result<u32, <RX as Arch>::DecodeError> {
969 let mut buf = [0u8; 4];
970 words.next_n(&mut buf).ok().ok_or(StandardDecodeError::ExhaustedInput)?;
971 self.on_word_read(buf[0]);
972 self.on_word_read(buf[1]);
973 self.on_word_read(buf[2]);
974 self.on_word_read(buf[3]);
975 Ok(u32::from_le_bytes(buf))
976 }
977 fn decode_mem_op(&mut self, rs: u8, ld: u8, size: SizeCode, words: &mut T) -> Result<Operand, <RX as Arch>::DecodeError> {
986 Ok(match ld {
987 0b00 => {
988 Operand::Deref { gpr: rs, disp: 0, width: size }
989 },
990 0b01 => {
991 let disp = self.read_u8(words)? as u32 * size.bytes() as u32;
992 Operand::Deref { gpr: rs, disp, width: size }
993 }
994 0b10 => {
995 let disp = self.read_u16(words)? as u32 * size.bytes() as u32;
996 Operand::Deref { gpr: rs, disp, width: size }
997 }
998 _ => {
999 debug_assert_eq!(ld, 0b11);
1002 Operand::Register { num: rs }
1003 }
1004 })
1005 }
1006 fn on_decode_start(&mut self) {}
1007 fn on_decode_end(&mut self) {}
1008 fn on_opcode_decoded(&mut self, _opcode: Opcode) -> Result<(), <RX as Arch>::DecodeError> { Ok(()) }
1009 fn on_operand_decoded(&mut self, _number: u8, _operand: Operand) -> Result<(), <RX as Arch>::DecodeError> { Ok(()) }
1010 fn on_word_read(&mut self, _word: <RX as Arch>::Word) {}
1011}
1012
1013impl<T: yaxpeax_arch::Reader<<RX as Arch>::Address, <RX as Arch>::Word>> DecodeHandler<T> for Instruction {
1014 fn on_decode_start(&mut self) {
1015 self.length = 0;
1016 self.opcode = Opcode::NOP;
1017 self.operands = [Operand::Nothing, Operand::Nothing, Operand::Nothing];
1018 }
1019 fn on_opcode_decoded(&mut self, opcode: Opcode) -> Result<(), <RX as Arch>::DecodeError> {
1020 self.opcode = opcode;
1021 Ok(())
1022 }
1023 fn on_operand_decoded(&mut self, number: u8, operand: Operand) -> Result<(), <RX as Arch>::DecodeError> {
1024 self.operands[number as usize] = operand;
1025 Ok(())
1026 }
1027 fn on_word_read(&mut self, _word: <RX as Arch>::Word) {
1028 self.length += 1;
1029 }
1030}
1031
1032impl Decoder<RX> for InstDecoder {
1033 fn decode_into<T: Reader<<RX as Arch>::Address, <RX as Arch>::Word>>(&self, inst: &mut Instruction, words: &mut T) -> Result<(), <RX as Arch>::DecodeError> {
1034 decode_inst(self, inst, words)
1035 }
1036}
1037
1038fn decode_inst<
1039 T: Reader<<RX as Arch>::Address, <RX as Arch>::Word>,
1040 H: DecodeHandler<T>,
1041>(decoder: &<RX as Arch>::Decoder, handler: &mut H, words: &mut T) -> Result<(), <RX as Arch>::DecodeError> {
1042 handler.on_decode_start();
1043
1044 let opc: u8 = handler.read_u8(words)?;
1045
1046 if opc == 0b0000_0000 {
1047 handler.on_opcode_decoded(Opcode::BRK)?;
1048 } else if opc == 0b0000_0001 {
1049 return Err(StandardDecodeError::InvalidOpcode);
1050 } else if opc == 0b0000_0010 {
1051 handler.on_opcode_decoded(Opcode::RTS)?;
1052 } else if opc == 0b0000_0011 {
1053 handler.on_opcode_decoded(Opcode::NOP)?;
1054 } else if opc == 0b0000_0100 {
1055 handler.on_opcode_decoded(Opcode::BRA)?;
1056 let offset = handler.read_i24(words)?;
1057 handler.on_operand_decoded(0, Operand::BrA { offset })?;
1058 } else if opc == 0b0000_0101 {
1059 handler.on_opcode_decoded(Opcode::BSR)?;
1060 let offset = handler.read_i24(words)?;
1061 handler.on_operand_decoded(0, Operand::BrA { offset })?;
1062 } else if opc == 0b0000_0110 {
1063 let next: u8 = handler.read_u8(words)?;
1064 let mi = (next >> 6) & 0b11;
1065 let ld = next & 0b11;
1066 let opc = (next >> 2) & 0b1111;
1067
1068 if opc < 0b0110 {
1069 const OPC_TABLE: [Opcode; 6] = [Opcode::SUB, Opcode::CMP, Opcode::ADD, Opcode::MUL, Opcode::AND, Opcode::OR];
1070
1071 handler.on_opcode_decoded(OPC_TABLE[opc as usize])?;
1072 } else if opc == 0b1000 {
1073 handler.on_opcode_decoded(match next {
1074 0b0_0000 => {
1075 if mi == 0b10 && ld != 0b11 {
1076 Opcode::SBB
1077 } else {
1078 return Err(StandardDecodeError::InvalidOperand);
1079 }
1080 }
1081 0b0_0001 => {
1082 return Err(StandardDecodeError::InvalidOpcode);
1083 }
1084 0b0_0010 => {
1085 if mi == 0b10 && ld != 0b11 {
1086 Opcode::ADC
1087 } else {
1088 return Err(StandardDecodeError::InvalidOperand);
1089 }
1090 }
1091 0b0_0011 => {
1092 return Err(StandardDecodeError::InvalidOpcode);
1093 }
1094 0b0_0100 => { Opcode::MAX },
1095 0b0_0101 => { Opcode::MIN },
1096 0b0_0110 => { Opcode::EMUL },
1097 0b0_0111 => { Opcode::EMULU },
1098 0b0_1000 => { Opcode::DIV },
1099 0b0_1001 => { Opcode::DIVU },
1100 0b0_1010 => { return Err(StandardDecodeError::InvalidOpcode); },
1101 0b0_1011 => { return Err(StandardDecodeError::InvalidOpcode); },
1102 0b0_1100 => { Opcode::TST },
1103 0b0_1101 => { Opcode::XOR },
1104 0b0_1110 => { return Err(StandardDecodeError::InvalidOpcode); },
1105 0b0_1111 => { return Err(StandardDecodeError::InvalidOpcode); },
1106 0b1_0000 => { Opcode::XCHG },
1107 0b1_0001 => { Opcode::ITOF },
1108 0b1_0010 => { return Err(StandardDecodeError::InvalidOpcode); },
1109 0b1_0011 => { return Err(StandardDecodeError::InvalidOpcode); },
1110 0b1_0100 => { return Err(StandardDecodeError::InvalidOpcode); },
1111 0b1_0101 => if decoder.version >= RxVersion::V2 {
1112 Opcode::UTOF
1113 } else {
1114 return Err(StandardDecodeError::InvalidOpcode);
1115 },
1116 0b1_0110 => { return Err(StandardDecodeError::InvalidOpcode); },
1117 0b1_0111 => { return Err(StandardDecodeError::InvalidOpcode); },
1118 0b1_1000 => { return Err(StandardDecodeError::InvalidOpcode); },
1119 0b1_1001 => { return Err(StandardDecodeError::InvalidOpcode); },
1120 0b1_1010 => { return Err(StandardDecodeError::InvalidOpcode); },
1121 0b1_1011 => { return Err(StandardDecodeError::InvalidOpcode); },
1122 0b1_1100 => { return Err(StandardDecodeError::InvalidOpcode); },
1123 0b1_1101 => { return Err(StandardDecodeError::InvalidOpcode); },
1124 0b1_1110 => { return Err(StandardDecodeError::InvalidOpcode); },
1125 0b1_1111 => { return Err(StandardDecodeError::InvalidOpcode); },
1126 _ => { return Err(StandardDecodeError::InvalidOpcode); },
1128 })?;
1129 } else {
1130 return Err(StandardDecodeError::InvalidOpcode);
1131 }
1132
1133 let next: u8 = handler.read_u8(words)?;
1135
1136 let rs = (next >> 4) & 0b1111;
1137 let rd = next & 0b1111;
1138
1139 let size = [SizeCode::B, SizeCode::W, SizeCode::L, SizeCode::UW][mi as usize];
1140 let src = handler.decode_mem_op(rs, ld, size, words)?;
1141
1142 handler.on_operand_decoded(0, src)?;
1143 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1144 } else if opc == 0b0000_0111 {
1145 return Err(StandardDecodeError::InvalidOpcode);
1146 } else if opc < 0b0001_0000 {
1147 handler.on_opcode_decoded(Opcode::BRA)?;
1148 let disp = opc & 0b111;
1149 let offset = if disp < 0b11 { disp + 8 } else { disp };
1150 handler.on_operand_decoded(0, Operand::BrS { offset })?;
1151 } else if opc < 0b0010_0000 {
1152 handler.on_opcode_decoded(if opc & 0b0000_1000 == 0 {
1153 Opcode::BEQ
1154 } else {
1155 Opcode::BNE
1156 })?;
1157 let disp = opc & 0b111;
1158 let offset = if disp < 0b11 { disp + 8 } else { disp };
1159 handler.on_operand_decoded(0, Operand::BrS { offset })?;
1160 } else if opc < 0b0011_0000 {
1161 let cond = opc & 0b1111;
1163 const OPC_TABLE: &'static [Opcode] = &[
1164 Opcode::BEQ, Opcode::BNE, Opcode::BGEU, Opcode::BLTU,
1165 Opcode::BGTU, Opcode::BLEU, Opcode::BPZ, Opcode::BN,
1166 Opcode::BGE, Opcode::BLT, Opcode::BGT, Opcode::BLE,
1167 Opcode::BO, Opcode::BNO, Opcode::BRA, ];
1169
1170 if cond == 0b1110 {
1171 handler.on_opcode_decoded(Opcode::BRA)?;
1172 let imm = handler.read_u8(words)?;
1173 handler.on_operand_decoded(0, Operand::BrB { offset: imm as i8 })?;
1174 } else if let Some(op) = OPC_TABLE.get(cond as usize) {
1175 handler.on_opcode_decoded(*op)?;
1176 let imm = handler.read_u8(words)?;
1177 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1178 } else {
1179 return Err(StandardDecodeError::InvalidOpcode);
1180 }
1181 } else if opc < 0b0011_1000 {
1182 return Err(StandardDecodeError::InvalidOpcode);
1183 } else if opc == 0b0011_1000 {
1184 handler.on_opcode_decoded(Opcode::BRA)?;
1185 let imm = handler.read_u16(words)?;
1186 handler.on_operand_decoded(0, Operand::BrW { offset: imm as i16 })?;
1187 } else if opc == 0b0011_1001 {
1188 handler.on_opcode_decoded(Opcode::BSR)?;
1189 let imm = handler.read_u16(words)?;
1190 handler.on_operand_decoded(0, Operand::ImmW { imm })?;
1191 } else if opc == 0b0011_1010 {
1192 handler.on_opcode_decoded(Opcode::BEQ)?;
1193 let imm = handler.read_u16(words)?;
1194 handler.on_operand_decoded(0, Operand::ImmW { imm })?;
1195 } else if opc == 0b0011_1011 {
1196 handler.on_opcode_decoded(Opcode::BNE)?;
1197 let imm = handler.read_u16(words)?;
1198 handler.on_operand_decoded(0, Operand::ImmW { imm })?;
1199 } else if opc < 0b0011_1111 {
1200 handler.on_opcode_decoded(Opcode::MOV)?;
1202 let operands = handler.read_u8(words)?;
1203 let rd = (operands >> 4) & 0b111;
1204 let disp = (((operands >> 3) & 0b10000) | (operands & 0b1111)) as u8 as u32;
1205 let imm = handler.read_u8(words)?;
1206 match opc & 0b11 {
1207 0b00 => {
1208 handler.on_operand_decoded(0, Operand::ImmB { imm: imm as u8 })?;
1209 handler.on_operand_decoded(1, Operand::Deref { gpr: rd, disp: disp * 1, width: SizeCode::B })?;
1210 }
1211 0b01 => {
1212 handler.on_operand_decoded(0, Operand::ImmW { imm: imm as u8 as u16 })?;
1213 handler.on_operand_decoded(1, Operand::Deref { gpr: rd, disp: disp * 2, width: SizeCode::W })?;
1214 }
1215 0b10 => {
1216 handler.on_operand_decoded(0, Operand::ImmL { imm: imm as u8 as u32 })?;
1217 handler.on_operand_decoded(1, Operand::Deref { gpr: rd, disp: disp * 4, width: SizeCode::L })?;
1218 }
1219 _ => { unreachable!("sz=11 is rtsd") }
1220 };
1221 } else if opc == 0b0011_1111 {
1222 handler.on_opcode_decoded(Opcode::RTSD)?;
1223
1224 let operands = handler.read_u8(words)?;
1225 let imm = handler.read_u8(words)?;
1226 let rd = operands >> 4;
1227 let rd2 = operands & 0b1111;
1228 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1229 handler.on_operand_decoded(1, Operand::RegisterRange { start_gpr: rd, end_gpr: rd2 })?;
1230 } else if opc < 0b0110_0000 {
1231 let code = (opc >> 2) & 0b111;
1232 let opcode = [
1233 Opcode::SUB, Opcode::CMP, Opcode::ADD, Opcode::MUL,
1234 Opcode::AND, Opcode::OR, Opcode::MOVU, Opcode::MOVU,
1235 ][code as usize];
1236 handler.on_opcode_decoded(opcode)?;
1237
1238 let ld = opc & 0b11;
1239 let operands = handler.read_u8(words)?;
1240 let rs = operands >> 4;
1241 let rd = operands & 0b1111;
1242
1243 let size = [
1244 SizeCode::L, SizeCode::L, SizeCode::L, SizeCode::L,
1245 SizeCode::L, SizeCode::L, SizeCode::B, SizeCode::W,
1246 ][code as usize];
1247 let src = handler.decode_mem_op(rs, ld, size, words)?;
1248 handler.on_operand_decoded(0, src)?;
1249 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1250 } else if opc < 0b0111_0000 {
1251 let opc = opc & 0b1111;
1253 if opc < 0b1000 {
1254 let operands = handler.read_u8(words)?;
1257 if opc == 0b0111 {
1258 handler.on_opcode_decoded(Opcode::RTSD)?;
1259 handler.on_operand_decoded(0, Operand::ImmB { imm: operands })?;
1260 } else {
1261 let opcode = [
1262 Opcode::SUB, Opcode::CMP, Opcode::ADD, Opcode::MUL,
1263 Opcode::AND, Opcode::OR, Opcode::MOV
1264 ][opc as usize];
1265 handler.on_opcode_decoded(opcode)?;
1266 let imm = operands >> 4;
1267 let rd = operands & 0b1111;
1268 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1269 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1270 }
1271 } else if opc < 0b1110 {
1272 handler.on_opcode_decoded(match opc >> 1 {
1274 0b100 => Opcode::SHLR,
1275 0b101 => Opcode::SHAR,
1276 0b110 => Opcode::SHLL,
1277 _ => { unreachable!("implies opc=0b1111") }
1278 })?;
1279 let operands = handler.read_u8(words)?;
1280 let imm = operands >> 3;
1281 let rd = operands & 0b111;
1282 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1283 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1284 } else {
1285 handler.on_opcode_decoded(if opc == 0b1110 {
1287 Opcode::PUSHM
1288 } else {
1289 Opcode::POPM
1290 })?;
1291 let operands = handler.read_u8(words)?;
1292 let reg_lo = operands >> 4;
1293 let reg_hi = operands & 0b1111;
1294 handler.on_operand_decoded(0, Operand::RegisterRange { start_gpr: reg_lo, end_gpr: reg_hi })?;
1295 }
1296 } else if opc < 0b0111_0100 {
1297 handler.on_opcode_decoded(Opcode::ADD)?;
1299 let operands = handler.read_u8(words)?;
1300 let rs2 = operands >> 4;
1301 let rd = operands & 0b1111;
1302 let li = opc & 0b11;
1303 let imm = match li {
1304 0b00 => {
1305 handler.read_u32(words)?
1306 }
1307 0b01 => {
1308 handler.read_u8(words)? as i8 as i32 as u32
1309 }
1310 0b10 => {
1311 handler.read_u16(words)? as i16 as i32 as u32
1312 }
1313 _ => {
1314 debug_assert!(li == 0b11, "li is at most the low two bits set");
1315 handler.read_i24(words)? as u32
1316 }
1317 };
1318 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
1319 handler.on_operand_decoded(1, Operand::Register { num: rs2 })?;
1320 handler.on_operand_decoded(2, Operand::Register { num: rd })?;
1321 } else if opc < 0b0111_1000 {
1322 let li = opc & 0b11;
1324 let operands = handler.read_u8(words)?;
1325 let opc = operands >> 4;
1326 let opcode = match opc {
1327 0b0000 => Some(Opcode::CMP),
1328 0b0001 => Some(Opcode::MUL),
1329 0b0010 => Some(Opcode::AND),
1330 0b0011 => Some(Opcode::OR),
1331 0b0100 => {
1332 if li != 0b01 {
1333 return Err(StandardDecodeError::InvalidOperand);
1334 }
1335 Some(Opcode::MOV)
1336 }
1337 0b0101 => {
1338 if li != 0b01 {
1339 return Err(StandardDecodeError::InvalidOperand);
1340 }
1341 Some(Opcode::CMP)
1342 }
1343 _ => {
1344 None
1348 }
1349 };
1350 let rd = operands & 0b1111;
1351 let imm = match li {
1352 0b00 => {
1353 handler.read_u32(words)?
1354 }
1355 0b01 => {
1356 handler.read_u8(words)? as i8 as i32 as u32
1357 }
1358 0b10 => {
1359 handler.read_u16(words)? as i16 as i32 as u32
1360 }
1361 _ => {
1362 debug_assert!(li == 0b11, "li is at most the low two bits set");
1363 handler.read_i24(words)? as u32
1364 }
1365 };
1366 if let Some(op) = opcode {
1367 handler.on_opcode_decoded(op)?;
1368 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
1369 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1370 } else {
1371 if opc == 0b0110 {
1372 if rd == 0 {
1374 handler.on_opcode_decoded(Opcode::INT)?;
1375 handler.on_operand_decoded(0, Operand::ImmB { imm: imm as u8 })?;
1376 } else {
1377 return Err(StandardDecodeError::InvalidOperand);
1378 }
1379 } else if opc == 0b0111 {
1380 if rd == 0 && (imm & 0b1111_0000 == 0) {
1382 handler.on_opcode_decoded(Opcode::MVTIPL)?;
1383 handler.on_operand_decoded(0, Operand::ImmB { imm: imm as u8 & 0b1111 })?;
1384 } else {
1385 return Err(StandardDecodeError::InvalidOperand);
1386 }
1387 } else if opc == 0b1001 {
1388 if decoder.version < RxVersion::V3 {
1390 return Err(StandardDecodeError::InvalidOpcode);
1391 }
1392 if rd != 0 {
1393 return Err(StandardDecodeError::InvalidOpcode);
1394 }
1395 if li == 0b01 {
1396 if imm != 0b0001_1011 {
1397 handler.on_opcode_decoded(Opcode::MVFDR)?;
1398 } else {
1399 return Err(StandardDecodeError::InvalidOperand);
1400 }
1401 } else if li == 0b10 {
1402 let rs = imm as u8;
1403 let rd = (imm >> 4) as u8;
1404 let opc = (imm >> 8) as u8;
1405 let rs2 = (imm >> 12) as u8;
1406
1407 let opcode = match opc {
1408 0b0000 => Opcode::DADD,
1409 0b0001 => Opcode::DSUB,
1410 0b0010 => Opcode::DMUL,
1411 0b0100 => Opcode::DDIV,
1413 0b0111 => {
1415 let opc = match rd {
1417 0b0001 => Opcode::DCMPUN,
1418 0b0010 => Opcode::DCMPEQ,
1419 0b0100 => Opcode::DCMPLT,
1420 0b0110 => Opcode::DCMPLE,
1421 _ => {
1422 return Err(StandardDecodeError::InvalidOpcode);
1423 }
1424 };
1425 handler.on_opcode_decoded(opc)?;
1426 handler.on_operand_decoded(0, Operand::DoubleReg { num: rs })?;
1427 handler.on_operand_decoded(1, Operand::DoubleReg { num: rs2 })?;
1428 return Ok(());
1429 }
1430 0b1100 => {
1431 let opc = match rs {
1433 0b0000 => Opcode::DMOV,
1434 0b0001 => Opcode::DABS,
1435 0b0010 => Opcode::DNEG,
1436 _ => {
1437 return Err(StandardDecodeError::InvalidOpcode);
1438 }
1439 };
1440 handler.on_opcode_decoded(opc)?;
1441 handler.on_operand_decoded(0, Operand::DoubleReg { num: rs })?;
1442 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
1443 return Ok(());
1444 }
1445 0b1101 => {
1446 let opc = match rs {
1448 0b0000 => Opcode::DSQRT,
1449 0b1000 => Opcode::DTOI,
1450 0b1001 => Opcode::DTOU,
1451 0b1100 => Opcode::DTOF,
1452 0b1101 => Opcode::DROUND,
1453 _ => {
1454 return Err(StandardDecodeError::InvalidOpcode);
1455 }
1456 };
1457 handler.on_opcode_decoded(opc)?;
1458 handler.on_operand_decoded(0, Operand::DoubleReg { num: rs })?;
1459 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
1460 return Ok(());
1461 }
1462 _ => {
1463 return Err(StandardDecodeError::InvalidOperand);
1464 }
1465 };
1466 handler.on_opcode_decoded(opcode)?;
1467 handler.on_operand_decoded(0, Operand::DoubleReg { num: rs })?;
1468 handler.on_operand_decoded(1, Operand::DoubleReg { num: rs2 })?;
1469 handler.on_operand_decoded(2, Operand::DoubleReg { num: rd })?;
1470 } else {
1471 return Err(StandardDecodeError::InvalidOperand);
1472 }
1473 } else if opc == 0b1010 {
1474 let opc = if rd == 0b000 {
1476 Opcode::DPUSHM
1477 } else if rd == 0b1000 {
1478 Opcode::DPOP
1479 } else {
1480 return Err(StandardDecodeError::InvalidOperand);
1481 };
1482 handler.on_opcode_decoded(opc)?;
1483 let rs = (imm as u8 >> 4) & 0b1111;
1484 let nm = imm as u8 & 0b1111;
1485 let end_reg = rs + nm + 1;
1486 if end_reg > 15 {
1487 return Err(StandardDecodeError::InvalidOperand);
1488 }
1489 let start_reg = if let Operand::ControlReg { reg } = decoder.reg_to_double_control_reg(rs)? {
1490 reg
1491 } else {
1492 panic!("impossible operand for double-precision control reg?");
1493 };
1494 let end_reg = if let Operand::ControlReg { reg } = decoder.reg_to_double_control_reg(end_reg)? {
1495 reg
1496 } else {
1497 panic!("impossible operand for double-precision control reg?");
1498 };
1499 handler.on_operand_decoded(0, Operand::DoubleControlRegisterRange { start_reg, end_reg })?;
1500 } else if opc == 0b1011 {
1501 let opc = if rd == 0b000 {
1503 Opcode::DPUSHM
1504 } else if rd == 0b1000 {
1505 Opcode::DPOP
1506 } else {
1507 return Err(StandardDecodeError::InvalidOperand);
1508 };
1509 handler.on_opcode_decoded(opc)?;
1510 let rs = (imm as u8 >> 4) & 0b1111;
1511 let nm = imm as u8 & 0b1111;
1512 let end_reg = rs + nm + 1;
1513 if end_reg > 15 {
1514 return Err(StandardDecodeError::InvalidOperand);
1515 }
1516 handler.on_operand_decoded(0, Operand::DoubleRegisterRange { start_reg: rs, end_reg })?;
1517 } else {
1518 return Err(StandardDecodeError::InvalidOperand);
1519 }
1520 }
1521 } else if opc < 0b0111_1110 {
1522 let operands = handler.read_u8(words)?;
1525 let imm = ((opc & 1) << 4) | (operands >> 4);
1526 let rd = operands & 0b1111;
1527 let opc = match (operands >> 1) & 0b11 {
1528 0b00 => Opcode::BSET,
1529 0b01 => Opcode::BCLR,
1530 _ => Opcode::BTST,
1532 };
1533 handler.on_opcode_decoded(opc)?;
1534 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1535 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1536 } else if opc < 0b0111_1111 {
1537 let operands = handler.read_u8(words)?;
1539 let opc = operands >> 4;
1540 let rd = operands & 0b1111;
1541 match opc {
1542 0b0000 => {
1543 handler.on_opcode_decoded(Opcode::NOT)?;
1544 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1545 }
1546 0b0001 => {
1547 handler.on_opcode_decoded(Opcode::NEG)?;
1548 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1549 }
1550 0b0010 => {
1551 handler.on_opcode_decoded(Opcode::ABS)?;
1552 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1553 }
1554 0b0011 => {
1555 handler.on_opcode_decoded(Opcode::SAT)?;
1556 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1557 }
1558 0b0100 => {
1559 handler.on_opcode_decoded(Opcode::RORC)?;
1560 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1561 }
1562 0b0101 => {
1563 handler.on_opcode_decoded(Opcode::ROLC)?;
1564 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1565 }
1566 0b1000 => {
1567 handler.on_opcode_decoded(Opcode::PUSH)?;
1568 handler.on_operand_decoded(0, Operand::Subreg { num: rd, width: SizeCode::B })?;
1569 }
1570 0b1001 => {
1571 handler.on_opcode_decoded(Opcode::PUSH)?;
1572 handler.on_operand_decoded(0, Operand::Subreg { num: rd, width: SizeCode::W })?;
1573 }
1574 0b1010 => {
1575 handler.on_opcode_decoded(Opcode::PUSH)?;
1576 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1577 }
1578 0b1011 => {
1579 handler.on_opcode_decoded(Opcode::POP)?;
1580 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
1581 }
1582 0b1100 => {
1583 handler.on_opcode_decoded(Opcode::PUSHC)?;
1584 handler.on_operand_decoded(0, decoder.reg_to_control_reg(rd)?)?;
1585 }
1586 0b1110 => {
1587 handler.on_opcode_decoded(Opcode::POPC)?;
1588 if rd == 0b0001 {
1590 return Err(StandardDecodeError::InvalidOperand);
1591 }
1592 handler.on_operand_decoded(0, decoder.reg_to_control_reg(rd)?)?;
1593 }
1594 _ => {
1595 return Err(StandardDecodeError::InvalidOpcode);
1596 }
1597 }
1598 } else if opc < 0b1000_0000 {
1599 let operands = handler.read_u8(words)?;
1601 let opc = operands >> 4;
1602 if opc < 0b1000 {
1603 handler.on_operand_decoded(0, Operand::Register { num: operands & 0b1111 })?;
1604 let opcode = match opc {
1605 0b0000 => Opcode::JMP,
1606 0b0001 => Opcode::JSR,
1607 0b0100 => Opcode::BRA,
1608 0b0101 => Opcode::BRA,
1609 _ => {
1610 return Err(StandardDecodeError::InvalidOpcode);
1611 }
1612 };
1613 handler.on_opcode_decoded(opcode)?;
1614 } else if opc == 0b1000 {
1615 let opcode = [
1617 Opcode::SUNTIL_B, Opcode::SUNTIL_W, Opcode::SUNTIL_L, Opcode::SCMPU,
1618 Opcode::SWHILE_B, Opcode::SWHILE_W, Opcode::SWHILE_L, Opcode::SMOVU,
1619 Opcode::SSTR_B, Opcode::SSTR_W, Opcode::SSTR_L, Opcode::SMOVB,
1620 Opcode::RMPA_B, Opcode::RMPA_W, Opcode::RMPA_L, Opcode::SMOVF,
1621 ][operands as usize & 0b1111];
1622 handler.on_opcode_decoded(opcode)?;
1623 } else if opc == 0b1001 {
1624 let opcode = match operands & 0b1111 {
1626 0b0011 => Opcode::SATR,
1627 0b0100 => Opcode::RTFI,
1628 0b0101 => Opcode::RTE,
1629 0b0110 => Opcode::WAIT,
1630 _ => {
1631 return Err(StandardDecodeError::InvalidOpcode);
1632 }
1633 };
1634 handler.on_opcode_decoded(opcode)?;
1635 } else if opc == 0b1010 {
1636 handler.on_operand_decoded(0, decoder.num_to_psw_bit(operands & 0b1111)?)?;
1638 handler.on_opcode_decoded(Opcode::SETPSW)?;
1639 } else if opc == 0b1011 {
1640 handler.on_operand_decoded(0, decoder.num_to_psw_bit(operands & 0b1111)?)?;
1642 handler.on_opcode_decoded(Opcode::CLRPSW)?;
1643 } else {
1644 return Err(StandardDecodeError::InvalidOpcode);
1645 }
1646 } else if opc < 0b1111_0000 {
1647 let sz = (opc >> 4) & 0b11;
1650 if sz == 0b11 {
1651 handler.on_opcode_decoded(Opcode::MOVU)?;
1654 let sz = if (opc >> 3) & 0b1 != 0 {
1655 SizeCode::B
1656 } else {
1657 SizeCode::W
1658 };
1659 let operands = handler.read_u8(words)?;
1660 let rs = operands & 0b111;
1661 let rd = (operands >> 4) & 0b111;
1662 let displo = (operands >> 3) & 1;
1663 let dispmid = (operands >> 6) & 2;
1664 let disphi = (opc & 0b111) << 2;
1665 let disp = displo | dispmid | disphi;
1666 handler.on_operand_decoded(0, Operand::Deref { gpr: rs, disp: disp as u32 * sz.bytes() as u32, width: sz })?;
1667 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1668 } else {
1669 handler.on_opcode_decoded(Opcode::MOV)?;
1670 let sz = [SizeCode::B, SizeCode::W, SizeCode::L][sz as usize];
1671 if opc & 0b0100_0000 == 0 {
1673 let operands = handler.read_u8(words)?;
1675 let rs = operands & 0b111;
1676 let rd = (operands >> 4) & 0b111;
1677 let displo = (operands >> 3) & 1;
1678 let dispmid = (operands >> 6) & 2;
1679 let disphi = (opc & 0b111) << 2;
1680 let disp = displo | dispmid | disphi;
1681 if opc & 0b0000_1000 == 0 {
1682 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
1683 handler.on_operand_decoded(1, Operand::Deref { gpr: rd, disp: disp as u32 * sz.bytes() as u32, width: sz })?;
1684 } else {
1685 let rs = (operands >> 4) & 0b111;
1687 let rd = operands & 0b111;
1688 handler.on_operand_decoded(0, Operand::Deref { gpr: rs, disp: disp as u32 * sz.bytes() as u32, width: sz })?;
1689 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1690 }
1691 } else {
1692 let ldd = (opc >> 2) & 0b11;
1694 let lds = opc & 0b11;
1695 let operands = handler.read_u8(words)?;
1696 let rs = operands & 0b1111;
1697 let rd = operands >> 4;
1698
1699 match (ldd, lds) {
1700 (0b11, 0b11) => {
1701 let source_op = if sz == SizeCode::L {
1703 Operand::Register { num: rs }
1704 } else {
1705 Operand::Subreg { num: rs, width: sz }
1706 };
1707 handler.on_operand_decoded(0, source_op)?;
1708 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1709 }
1710 (ld, 0b11) => {
1711 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
1712 let op = handler.decode_mem_op(rd, ld, sz, words)?;
1713 handler.on_operand_decoded(1, op)?;
1714 },
1715 (0b11, ld) => {
1716 let rs = operands >> 4;
1718 let rd = operands & 0b1111;
1719 let op = handler.decode_mem_op(rs, ld, sz, words)?;
1720 handler.on_operand_decoded(0, op)?;
1721 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1722 },
1723 (ldd, lds) => {
1724 let op = handler.decode_mem_op(rs, lds, sz, words)?;
1725 handler.on_operand_decoded(0, op)?;
1726 let op = handler.decode_mem_op(rd, ldd, sz, words)?;
1727 handler.on_operand_decoded(1, op)?;
1728 }
1729 }
1730 }
1731 }
1732 } else if opc < 0b1111_0100 {
1733 let ld = opc & 0b11;
1735 if ld == 0b11 {
1736 return Err(StandardDecodeError::InvalidOperand);
1737 }
1738
1739 let operands = handler.read_u8(words)?;
1740 let imm = operands & 0b111;
1741 let rd = operands >> 4;
1742
1743 let operand = handler.decode_mem_op(rd, ld, SizeCode::B, words)?;
1744
1745 let opcode = if operands & 0b0000_1000 == 0 {
1746 Opcode::BSET
1747 } else {
1748 Opcode::BCLR
1749 };
1750 handler.on_opcode_decoded(opcode)?;
1751 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1752 handler.on_operand_decoded(1, operand)?;
1753 } else if opc < 0b1111_1000 {
1754 let ld = opc & 0b11;
1756 if ld == 0b11 {
1757 return Err(StandardDecodeError::InvalidOperand);
1758 }
1759
1760 let operands = handler.read_u8(words)?;
1761 let rs = operands >> 4;
1762 if operands & 0b0000_1000 == 0 {
1763 let imm = operands & 0b111;
1764 let op = handler.decode_mem_op(rs, ld, SizeCode::B, words)?;
1765 handler.on_operand_decoded(1, op)?;
1766 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
1767 handler.on_opcode_decoded(Opcode::BTST)?;
1768 } else if operands & 0b0000_1100 == 0b0000_1000 {
1769 let sz = match operands & 0b11 {
1770 0b00 => SizeCode::B,
1771 0b01 => SizeCode::W,
1772 0b10 => SizeCode::L,
1773 0b11 => { return Err(StandardDecodeError::InvalidOperand) },
1774 _ => { unreachable!("sz is only two bits"); }
1775 };
1776
1777 let op = handler.decode_mem_op(rs, ld, sz, words)?;
1778 handler.on_operand_decoded(0, op)?;
1779 handler.on_opcode_decoded(Opcode::PUSH)?;
1780 } else {
1781 return Err(StandardDecodeError::InvalidOperand);
1782 }
1783 } else if opc < 0b1111_1100 {
1784 let ld = opc & 0b11;
1786 let operands = handler.read_u8(words)?;
1787 let sz = operands & 0b11;
1788 if sz == 0b11 {
1789 if decoder.version < RxVersion::V3 {
1790 return Err(StandardDecodeError::InvalidOperand);
1792 } else {
1793 if operands != 0b0000_0011 {
1795 return Err(StandardDecodeError::InvalidOpcode);
1796 }
1797 let operands = handler.read_u8(words)?;
1798 let rd = operands >> 4;
1799 match operands & 0b1111 {
1800 0b0000 => {
1801 handler.on_opcode_decoded(Opcode::DMOV)?;
1802 handler.on_operand_decoded(1, Operand::DoubleRegLow { num: rd })?;
1803 },
1804 0b0010 => {
1805 handler.on_opcode_decoded(Opcode::DMOV)?;
1806 handler.on_operand_decoded(1, Operand::DoubleRegHigh { num: rd })?;
1807 },
1808 0b0011 => {
1809 handler.on_opcode_decoded(Opcode::DMOV)?;
1812 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
1813 },
1814 _ => {
1815 return Err(StandardDecodeError::InvalidOpcode);
1816 }
1817 }
1818 let imm = handler.read_u32(words)?;
1819 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
1820 }
1821 } else {
1822 let rd = operands >> 4;
1823 let li = (operands >> 2) & 0b11;
1824 let sz = [SizeCode::B, SizeCode::W, SizeCode::L][sz as usize];
1825 let li_code = [SizeCode::B, SizeCode::W, SizeCode::L, SizeCode::L][li as usize];
1828 if li_code.bytes() > sz.bytes() {
1830 return Err(StandardDecodeError::InvalidOperand);
1831 }
1832
1833 let operand = handler.decode_mem_op(rd, ld, sz, words)?;
1834 let imm = match li {
1835 0b00 => {
1836 handler.read_u32(words)?
1837 }
1838 0b01 => {
1839 handler.read_u8(words)? as i8 as i32 as u32
1840 }
1841 0b10 => {
1842 handler.read_u16(words)? as i16 as i32 as u32
1843 }
1844 _ => {
1845 debug_assert!(li == 0b11, "li is at most the low two bits set");
1846 handler.read_i24(words)? as u32
1847 }
1848 };
1849 handler.on_opcode_decoded(Opcode::MOV)?;
1850 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
1851 handler.on_operand_decoded(1, operand)?;
1852 }
1853 } else if opc == 0b1111_1100 {
1854 let operands = handler.read_u8(words)?;
1856 let opc5 = (operands >> 2) & 0b11111;
1857 let ld = operands & 0b11;
1858
1859 let registers = handler.read_u8(words)?;
1860 let rd = registers & 0b1111;
1861 let rs = registers >> 4;
1862
1863 if operands & 0b1000_0000 == 0 {
1864 if opc5 < 0b10010 {
1866 let opcode = match opc5 {
1868 0b00000 => {
1869 if ld != 0b11 {
1870 return Err(StandardDecodeError::InvalidOperand);
1871 }
1872 Opcode::SBB
1873 }
1874 0b00001 => {
1875 if ld != 0b11 {
1876 return Err(StandardDecodeError::InvalidOperand);
1877 }
1878 Opcode::NEG
1879 }
1880 0b00010 => {
1881 if ld != 0b11 {
1882 return Err(StandardDecodeError::InvalidOperand);
1883 }
1884 Opcode::ADC
1885 }
1886 0b00011 => {
1887 if ld != 0b11 {
1888 return Err(StandardDecodeError::InvalidOperand);
1889 }
1890 Opcode::ABS
1891 }
1892 0b00100 => Opcode::MAX,
1893 0b00101 => Opcode::MIN,
1894 0b00110 => Opcode::EMUL,
1895 0b00111 => Opcode::EMULU,
1896 0b01000 => Opcode::DIV,
1897 0b01001 => Opcode::DIVU,
1898 0b01010 => { return Err(StandardDecodeError::InvalidOperand); },
1899 0b01011 => { return Err(StandardDecodeError::InvalidOperand); },
1900 0b01100 => Opcode::TST,
1901 0b01101 => Opcode::XOR,
1902 0b01110 => {
1903 if ld != 0b11 {
1904 return Err(StandardDecodeError::InvalidOperand);
1905 }
1906 Opcode::NOT
1907 }
1908 0b01111 => { return Err(StandardDecodeError::InvalidOperand); },
1909 0b10000 => Opcode::XCHG,
1910 _ => {
1911 debug_assert!(opc5 == 0b10001, "checked opc is below 0b10010");
1912 Opcode::ITOF
1913 }
1914 };
1915 handler.on_opcode_decoded(opcode)?;
1916 let source = handler.decode_mem_op(rs, ld, SizeCode::L, words)?;
1917 handler.on_operand_decoded(0, source)?;
1918 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1919 } else if opc5 < 0b10100 {
1920 if decoder.version < RxVersion::V2 {
1922 return Err(StandardDecodeError::InvalidOpcode);
1923 }
1924
1925 handler.on_opcode_decoded(if opc5 & 1 == 0 {
1926 Opcode::STZ
1927 } else {
1928 Opcode::STNZ
1929 })?;
1930 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
1931 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1932 } else if opc5 < 0b10101 {
1933 return Err(StandardDecodeError::InvalidOpcode);
1936 } else if opc5 < 0b10110 {
1937 if decoder.version < RxVersion::V2 {
1940 return Err(StandardDecodeError::InvalidOpcode);
1941 }
1942 handler.on_opcode_decoded(Opcode::UTOF)?;
1943 let op = handler.decode_mem_op(rs, ld, SizeCode::L, words)?;
1944 handler.on_operand_decoded(0, op)?;
1945 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
1946 } else if opc5 < 0b11000 {
1947 if decoder.version < RxVersion::V3 {
1950 return Err(StandardDecodeError::InvalidOpcode);
1951 }
1952 let regs = handler.read_u8(words)?;
1953 handler.on_opcode_decoded(if opc5 & 1 == 0 {
1954 Opcode::BFMOVZ
1955 } else {
1956 Opcode::BFMOV
1957 })?;
1958 let rs = regs >> 4;
1959 let rd = regs & 0b1111;
1960
1961 let bits = handler.read_u16(words)?;
1962 handler.on_operand_decoded(0, Operand::BitfieldSpec { bf_spec: BitfieldSpec { bits } })?;
1963 handler.on_operand_decoded(1, Operand::Register { num: rs })?;
1964 handler.on_operand_decoded(2, Operand::Register { num: rd })?;
1965 } else if opc5 < 0b11100 {
1966 let opcode = [Opcode::BSET, Opcode::BCLR, Opcode::BTST, Opcode::BNOT][opc5 as usize & 0b11];
1967 handler.on_opcode_decoded(opcode)?;
1968 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
1969 let op = handler.decode_mem_op(rd, ld, SizeCode::B, words)?;
1970 handler.on_operand_decoded(1, op)?;
1971 } else if opc5 == 0b11110 {
1972 if decoder.version < RxVersion::V3 {
1973 return Err(StandardDecodeError::InvalidOpcode);
1974 }
1975
1976 let regs = handler.read_u8(words)?;
1977 let regs_lo = regs & 0b1111;
1978 if regs_lo != 0b1000 {
1981 return Err(StandardDecodeError::InvalidOpcode);
1982 }
1983 let rd = regs >> 4;
1984 let dest_op = handler.decode_mem_op(rd, ld, SizeCode::D, words)?;
1985 let regs = handler.read_u8(words)?;
1986 let rs = regs >> 4;
1987 let regs_lo = regs & 0b1111;
1988 if regs_lo != 0b0000 {
1990 return Err(StandardDecodeError::InvalidOpcode);
1991 }
1992
1993 handler.on_opcode_decoded(Opcode::DMOV)?;
1994 handler.on_operand_decoded(0, Operand::DoubleReg { num: rs })?;
1995 handler.on_operand_decoded(1, dest_op)?;
1996 } else {
1997 return Err(StandardDecodeError::InvalidOpcode);
1999 }
2000 } else {
2001 if opc5 < 0b10000 {
2003 let opcode = match opc5 & 0b1111 {
2004 0b0000 => Opcode::FSUB,
2005 0b0001 => Opcode::FCMP,
2006 0b0010 => Opcode::FADD,
2007 0b0011 => Opcode::FMUL,
2008 0b0100 => Opcode::FDIV,
2009 0b0101 => Opcode::FTOI,
2010 0b0110 => Opcode::ROUND,
2011 0b1000 => {
2012 if decoder.version < RxVersion::V2 {
2013 return Err(StandardDecodeError::InvalidOpcode);
2014 }
2015 Opcode::FSQRT
2016 },
2017 0b1001 => {
2018 if decoder.version < RxVersion::V2 {
2019 return Err(StandardDecodeError::InvalidOpcode);
2020 }
2021 Opcode::FTOU
2022 },
2023 _ => {
2024 return Err(StandardDecodeError::InvalidOpcode);
2025 }
2026 };
2027 let regs = handler.read_u8(words)?;
2028 let rs = regs >> 4;
2029 let rd = regs & 0b1111;
2030 let source = handler.decode_mem_op(rs, ld, SizeCode::D, words)?;
2031 handler.on_opcode_decoded(opcode)?;
2032 handler.on_operand_decoded(0, source)?;
2033 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2034 } else if opc5 == 0b10010 {
2035 if decoder.version < RxVersion::V3 {
2038 return Err(StandardDecodeError::InvalidOpcode);
2039 }
2040
2041 let operands = handler.read_u8(words)?;
2042 let rs = operands >> 4;
2043 if operands & 0b1111 != 0b1000 {
2044 return Err(StandardDecodeError::InvalidOpcode);
2045 }
2046 let source = handler.decode_mem_op(rs, ld, SizeCode::D, words)?;
2047 let operands = handler.read_u8(words)?;
2048 let rd = operands >> 4;
2049 if operands & 0b1111 != 0b0000 {
2050 return Err(StandardDecodeError::InvalidOpcode);
2051 }
2052
2053 handler.on_opcode_decoded(Opcode::DMOV)?;
2054 handler.on_operand_decoded(0, source)?;
2055 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2056 } else if opc5 < 0b11000 {
2057 let operands = handler.read_u8(words)?;
2060 let rd = operands >> 4;
2061 let cnd = operands & 0b1111;
2062 let sz = match opc5 & 0b11 {
2063 0b00 => SizeCode::B,
2064 0b01 => SizeCode::W,
2065 0b10 => SizeCode::L,
2066 _ => {
2067 return Err(StandardDecodeError::InvalidOperand);
2068 }
2069 };
2070 if cnd >= 0b1110 {
2071 return Err(StandardDecodeError::InvalidOpcode);
2072 }
2073 let opcode = [
2074 Opcode::SCEQ, Opcode::SCNE, Opcode::SCGEU, Opcode::SCLTU,
2075 Opcode::SCGTU, Opcode::SCLEU, Opcode::SCPZ, Opcode::SCN,
2076 Opcode::SCGE, Opcode::SCLT, Opcode::SCGT, Opcode::SCLE,
2077 Opcode::SCO, Opcode::SCNO, Opcode::NOP, Opcode::NOP ][cnd as usize];
2079 handler.on_opcode_decoded(opcode)?;
2080 let op = handler.decode_mem_op(rd, ld, sz, words)?;
2081 handler.on_operand_decoded(0, op)?;
2082 } else if opc5 >= 0b11000 {
2083 let operands = handler.read_u8(words)?;
2085 let rd = operands >> 4;
2086 let cnd = operands & 0b1111;
2087 let imm = opc5 & 0b111;
2088
2089 if ld == 0b11 {
2090 return Err(StandardDecodeError::InvalidOperand);
2091 }
2092
2093 let opcode = if cnd == 0b1111 {
2094 Opcode::BNOT
2095 } else if cnd == 0b1110 {
2096 return Err(StandardDecodeError::InvalidOpcode);
2097 } else {
2098 [
2099 Opcode::BMEQ, Opcode::BMNE, Opcode::BMGEU, Opcode::BMLTU,
2100 Opcode::BMGTU, Opcode::BMLEU, Opcode::BMPZ, Opcode::BMN,
2101 Opcode::BMGE, Opcode::BMLT, Opcode::BMGT, Opcode::BMLE,
2102 Opcode::BMO, Opcode::BMNO, Opcode::NOP, Opcode::NOP ][cnd as usize]
2104 };
2105 handler.on_opcode_decoded(opcode)?;
2106 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
2107 let op = handler.decode_mem_op(rd, ld, SizeCode::B, words)?;
2108 handler.on_operand_decoded(1, op)?;
2109 } else {
2110 unreachable!("should be unreachable, fuzzing will tell..");
2111 }
2112 }
2113 } else if opc == 0b1111_1101 {
2114 let opcode = handler.read_u8(words)?;
2118
2119 if opcode < 0b1000_0000 {
2120 if opcode < 0b0001_0000 {
2122 let a = (opcode >> 3) & 1;
2123 if a != 0 && decoder.version < RxVersion::V2 {
2124 return Err(StandardDecodeError::InvalidOperand);
2125 }
2126
2127 let regs = handler.read_u8(words)?;
2128 let rs = regs >> 4;
2129 let rs2 = regs & 0b1111;
2130
2131 if opcode & 0b010 != 0b000 && decoder.version < RxVersion::V2 {
2133 return Err(StandardDecodeError::InvalidOpcode);
2134 }
2135
2136 let opcode = match opcode & 0b111 {
2137 0b000 => Opcode::MULHI,
2138 0b001 => Opcode::MULLO,
2139 0b010 => Opcode::MULLH,
2140 0b011 => Opcode::EMULA,
2141 0b100 => Opcode::MACHI,
2142 0b101 => Opcode::MACLO,
2143 0b110 => Opcode::MACLH,
2144 _ => Opcode::EMACA,
2145 };
2146 handler.on_opcode_decoded(opcode)?;
2147 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2148 handler.on_operand_decoded(1, Operand::Register { num: rs2 })?;
2149 handler.on_operand_decoded(2, Operand::Accumulator { num: a })?;
2150 } else if opcode == 0b0001_0111 {
2151 let operands = handler.read_u8(words)?;
2152 let rs = operands & 0b1111;
2153 let opc = (operands >> 4) & 0b111;
2154 let a = operands >> 7;
2155
2156 if a != 0 && decoder.version < RxVersion::V2 {
2157 return Err(StandardDecodeError::InvalidOperand);
2158 }
2159
2160 let opcode = match opc {
2161 0b000 => Opcode::MVTACHI,
2162 0b001 => Opcode::MVTACLO,
2163 0b011 => {
2164 if decoder.version < RxVersion::V2 {
2165 return Err(StandardDecodeError::InvalidOpcode);
2166 }
2167 Opcode::MVTACGU
2168 }
2169 _ => {
2170 return Err(StandardDecodeError::InvalidOpcode);
2171 }
2172 };
2173 handler.on_opcode_decoded(opcode)?;
2174 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2175 handler.on_operand_decoded(1, Operand::Accumulator { num: a })?;
2176 } else if opcode & 0b1111_1110 == 0b0001_1000 {
2177 let wide = opcode & 1;
2179
2180 let operands = handler.read_u8(words)?;
2181 if operands & 0b1111 != 0 {
2182 return Err(StandardDecodeError::InvalidOperand);
2183 }
2184 let imm = (operands >> 4) & 0b11;
2185 let opc = (operands >> 6) & 1;
2186 let a = operands >> 7;
2187
2188 if imm > 0b01 {
2189 return Err(StandardDecodeError::InvalidOperand);
2190 }
2191
2192 if a != 0 && decoder.version < RxVersion::V2 {
2193 return Err(StandardDecodeError::InvalidOperand);
2194 }
2195
2196 let opcode = if opc == 0 {
2197 if wide == 0 { Opcode::RACW } else { Opcode::RACL }
2198 } else if decoder.version >= RxVersion::V2 {
2199 if wide == 0 { Opcode::RDACW } else { Opcode::RDACL }
2200 } else {
2201 return Err(StandardDecodeError::InvalidOpcode);
2202 };
2203 handler.on_opcode_decoded(opcode)?;
2204 handler.on_operand_decoded(0, Operand::ImmB { imm: imm + 1 })?;
2205 handler.on_operand_decoded(1, Operand::Accumulator { num: a })?;
2206 } else if opcode & 0b1111_1110 == 0b0001_1110 {
2207 let operands = handler.read_u8(words)?;
2208 let rd = operands & 0b1111;
2209 let immlo = (operands >> 6) & 1;
2210 let immhi = opcode & 1;
2211 let imm = (immhi << 1) | immlo;
2212 let opc = (operands >> 4) & 0b11;
2213 let a = operands >> 7;
2214
2215 let opcode = match opc {
2216 0b00 => Opcode::MVFACHI,
2217 0b01 => {
2218 if decoder.version < RxVersion::V2 {
2219 return Err(StandardDecodeError::InvalidOpcode);
2220 }
2221 Opcode::MVFACLO
2222 }
2223 0b10 => Opcode::MVFACMI,
2224 _ => {
2225 if decoder.version < RxVersion::V2 {
2226 return Err(StandardDecodeError::InvalidOpcode);
2227 }
2228 Opcode::MVFACGU
2229 }
2230 };
2231
2232 if imm != 0 && decoder.version < RxVersion::V2 {
2233 return Err(StandardDecodeError::InvalidOperand);
2234 }
2235
2236 handler.on_opcode_decoded(opcode)?;
2237 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
2238 handler.on_operand_decoded(1, Operand::Accumulator { num: a })?;
2239 handler.on_operand_decoded(2, Operand::Register { num: rd })?;
2240 } else if opcode < 0b0100_0000 {
2241 return Err(StandardDecodeError::InvalidOpcode);
2244 } else if opcode < 0b0101_0000 {
2245 if opcode & 0b0000_0100 != 0 {
2247 return Err(StandardDecodeError::InvalidOpcode);
2249 }
2250
2251 if decoder.version < RxVersion::V2 {
2252 return Err(StandardDecodeError::InvalidOpcode);
2253 }
2254
2255 let a = (opcode >> 3) & 1;
2256 let opc = opcode & 0b11;
2257 let operands = handler.read_u8(words)?;
2258 let rs = operands >> 4;
2259 let rs2 = operands & 0b1111;
2260
2261 let opcode = [Opcode::MSBHI, Opcode::MSBLH, Opcode::MSBLO, Opcode::EMSBA][opc as usize];
2262 handler.on_opcode_decoded(opcode)?;
2263 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2264 handler.on_operand_decoded(1, Operand::Register { num: rs2 })?;
2265 handler.on_operand_decoded(2, Operand::Accumulator { num: a })?;
2266 } else if opcode < 0b0110_0000 {
2267 return Err(StandardDecodeError::InvalidOpcode);
2270 } else if opcode < 0b0110_1000 {
2271 let operands = handler.read_u8(words)?;
2273 let rd = operands & 0b1111;
2274 let rs = operands >> 4;
2275
2276 let opcode = match opcode & 0b111 {
2277 0b000 => Opcode::SHLR,
2278 0b001 => Opcode::SHAR,
2279 0b010 => Opcode::SHLL,
2280 0b011 => { return Err(StandardDecodeError::InvalidOpcode); },
2281 0b100 => Opcode::ROTR,
2282 0b101 => Opcode::REVW,
2283 0b110 => Opcode::ROTL,
2284 _ => Opcode::REVL,
2285 };
2286
2287 handler.on_opcode_decoded(opcode)?;
2288 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2289 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2290 } else if opcode == 0b0110_1000 {
2291 let operands = handler.read_u8(words)?;
2292 let cr = operands & 0b1111;
2293 let rs = operands >> 4;
2294
2295 if cr == 0b0010 {
2296 return Err(StandardDecodeError::InvalidOperand);
2298 }
2299 handler.on_opcode_decoded(Opcode::MVTC)?;
2300 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2301 handler.on_operand_decoded(1, decoder.reg_to_control_reg(cr)?)?;
2302 } else if opcode == 0b0110_1010 {
2303 let operands = handler.read_u8(words)?;
2304 let rd = operands & 0b1111;
2305 let cr = operands >> 4;
2306
2307 handler.on_opcode_decoded(Opcode::MVFC)?;
2308 handler.on_operand_decoded(0, decoder.reg_to_control_reg(cr)?)?;
2309 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2310 } else if opcode < 0b0110_1100 {
2311 return Err(StandardDecodeError::InvalidOpcode);
2312 } else if opcode < 0b0111_0000 {
2313 let operands = handler.read_u8(words)?;
2316 let rd = operands & 0b1111;
2317 let immlo = operands >> 4;
2318 let immhi = opcode & 1;
2319 let imm = (immhi << 4) | immlo;
2320 handler.on_opcode_decoded(if opcode & 0b10 == 0 {
2321 Opcode::ROTR
2322 } else {
2323 Opcode::ROTL
2324 })?;
2325 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
2326 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2327 } else if opcode == 0b0111_0101 {
2328 if decoder.version < RxVersion::V3 {
2329 return Err(StandardDecodeError::InvalidOpcode);
2330 }
2331
2332 let operands = handler.read_u8(words)?;
2333 if operands & 0b1111_0000 != 0b1000_0000 {
2334 return Err(StandardDecodeError::InvalidOpcode);
2335 }
2336 let rd = operands & 0b1111;
2337 let operands = handler.read_u8(words)?;
2338 let opc = operands & 0b1111;
2339 let rs = operands >> 4;
2340
2341 match opc {
2342 0b0000 => {
2343 handler.on_opcode_decoded(Opcode::DMOV)?;
2344 handler.on_operand_decoded(0, Operand::DoubleRegLow { num: rs })?;
2345 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2346 }
2347 0b0010 => {
2348 handler.on_opcode_decoded(Opcode::DMOV)?;
2349 handler.on_operand_decoded(0, Operand::DoubleRegHigh { num: rs })?;
2350 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2351 }
2352 0b0100 => {
2353 handler.on_opcode_decoded(Opcode::MVFDC)?;
2354 handler.on_operand_decoded(0, Operand::DoubleRegHigh { num: rs })?;
2355 handler.on_operand_decoded(1, decoder.reg_to_double_control_reg(rd)?)?;
2356 }
2357 _ => { return Err(StandardDecodeError::InvalidOpcode) }
2358 }
2359 } else if opcode == 0b0111_0110 {
2360 if decoder.version < RxVersion::V3 {
2361 return Err(StandardDecodeError::InvalidOpcode);
2362 }
2363
2364 let operands = handler.read_u8(words)?;
2365 let opc = operands >> 4;
2366 let rs = operands & 0b1111;
2367 let imm = handler.read_u8(words)?;
2368
2369 match opc {
2370 0b1100 => {
2371 if imm != 0b0000_0000 {
2372 return Err(StandardDecodeError::InvalidOperand);
2373 }
2374 handler.on_opcode_decoded(Opcode::SAVE)?;
2375 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2376 }
2377 0b1101 => {
2378 if imm != 0b0000_0000 {
2379 return Err(StandardDecodeError::InvalidOperand);
2380 }
2381 handler.on_opcode_decoded(Opcode::RSTR)?;
2382 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2383 }
2384 0b1110 => {
2385 if rs != 0b0000_0000 {
2386 return Err(StandardDecodeError::InvalidOperand);
2387 }
2388 handler.on_opcode_decoded(Opcode::SAVE)?;
2389 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
2390 }
2391 0b1111 => {
2392 if rs != 0b0000_0000 {
2393 return Err(StandardDecodeError::InvalidOperand);
2394 }
2395 handler.on_opcode_decoded(Opcode::RSTR)?;
2396 handler.on_operand_decoded(0, Operand::ImmB { imm })?;
2397 }
2398 _ => { return Err(StandardDecodeError::InvalidOpcode) }
2399 };
2400 } else if opcode == 0b0111_0111 {
2401 if decoder.version < RxVersion::V3 {
2402 return Err(StandardDecodeError::InvalidOpcode);
2403 }
2404
2405 let operands = handler.read_u8(words)?;
2406 if operands & 0b1111_0000 != 0b1000_0000 {
2407 return Err(StandardDecodeError::InvalidOpcode);
2408 }
2409 let rs = operands & 0b1111;
2410 let operands = handler.read_u8(words)?;
2411 let rd = operands >> 4;
2412 let opc = operands & 0b1111;
2413 match opc {
2414 0b0000 => {
2415 handler.on_opcode_decoded(Opcode::DMOV)?;
2417 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2418 handler.on_operand_decoded(1, Operand::DoubleRegLow { num: rd })?;
2419 }
2420 0b0010 => {
2421 handler.on_opcode_decoded(Opcode::DMOV)?;
2423 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2424 handler.on_operand_decoded(1, Operand::DoubleRegHigh { num: rd })?;
2425 }
2426 0b0011 => {
2427 handler.on_opcode_decoded(Opcode::DMOV)?;
2429 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2430 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2431 }
2432 0b0100 => {
2433 let cr = decoder.reg_to_double_control_reg(rd)?;
2435 handler.on_opcode_decoded(Opcode::MVTDC)?;
2436 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2437 handler.on_operand_decoded(1, cr)?;
2438 }
2439 0b1001 => {
2440 handler.on_opcode_decoded(Opcode::ITOD)?;
2442 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2443 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2444 }
2445 0b1010 => {
2446 handler.on_opcode_decoded(Opcode::FTOD)?;
2448 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2449 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2450 }
2451 0b1101 => {
2452 handler.on_opcode_decoded(Opcode::UTOD)?;
2454 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2455 handler.on_operand_decoded(1, Operand::DoubleReg { num: rd })?;
2456 }
2457 _ => {
2458 return Err(StandardDecodeError::InvalidOpcode);
2459 }
2460 }
2461 } else if opcode < 0b0111_0000 {
2462 return Err(StandardDecodeError::InvalidOpcode);
2464 } else {
2465 let li = (opcode >> 2) & 0b11;
2466 let opc_lo = opcode & 0b11;
2467 if opc_lo == 0b00 {
2468 let opcode = handler.read_u8(words)?;
2471 let rd = opcode & 0b1111;
2472 let opcode = opcode >> 4;
2473 let opcode = match opcode {
2474 0b0010 => Opcode::ADC,
2475 0b0100 => Opcode::MAX,
2476 0b0101 => Opcode::MIN,
2477 0b0110 => Opcode::EMUL,
2478 0b0111 => Opcode::EMULU,
2479 0b1000 => Opcode::DIV,
2480 0b1001 => Opcode::DIVU,
2481 0b1100 => Opcode::TST,
2482 0b1101 => Opcode::XOR,
2483 0b1110 => Opcode::STZ,
2484 0b1111 => Opcode::STNZ,
2485 _ => { return Err(StandardDecodeError::InvalidOpcode) }
2486 };
2487 handler.on_opcode_decoded(opcode)?;
2488 let imm = match li {
2489 0b00 => {
2490 handler.read_u32(words)?
2491 }
2492 0b01 => {
2493 handler.read_u8(words)? as i8 as i32 as u32
2494 }
2495 0b10 => {
2496 handler.read_u16(words)? as i16 as i32 as u32
2497 }
2498 _ => {
2499 debug_assert!(li == 0b11, "li is at most the low two bits set");
2500 handler.read_i24(words)? as u32
2501 }
2502 };
2503 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
2504 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2505 } else if opc_lo == 0b11 {
2506 let opcode = handler.read_u8(words)?;
2509 let rd = opcode & 0b1111;
2510 let opcode = opcode >> 4;
2511 if opcode != 0b0000 {
2512 return Err(StandardDecodeError::InvalidOpcode);
2513 }
2514 if rd == 0b0001 {
2515 return Err(StandardDecodeError::InvalidOperand);
2517 }
2518 let cr = decoder.reg_to_control_reg(rd)?;
2519 handler.on_opcode_decoded(Opcode::MVTC)?;
2520 let imm = match li {
2521 0b00 => {
2522 handler.read_u32(words)?
2523 }
2524 0b01 => {
2525 handler.read_u8(words)? as i8 as i32 as u32
2526 }
2527 0b10 => {
2528 handler.read_u16(words)? as i16 as i32 as u32
2529 }
2530 _ => {
2531 debug_assert!(li == 0b11, "li is at most the low two bits set");
2532 handler.read_i24(words)? as u32
2533 }
2534 };
2535 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
2536 handler.on_operand_decoded(1, cr)?;
2537 } else if opc_lo == 0b10 {
2538 if li != 0b00 {
2541 return Err(StandardDecodeError::InvalidOperand);
2542 }
2543
2544 let opcode = handler.read_u8(words)?;
2545 let rd = opcode & 0b1111;
2546 let opcode = opcode >> 4;
2547 if opcode > 0b100 {
2548 return Err(StandardDecodeError::InvalidOpcode);
2549 }
2550 handler.on_opcode_decoded(
2551 [Opcode::FSUB, Opcode::FCMP, Opcode::FADD, Opcode::FMUL, Opcode::FDIV][opcode as usize]
2552 )?;
2553 let imm = handler.read_u32(words)?;
2554 handler.on_operand_decoded(0, Operand::ImmL { imm })?;
2555 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2556 } else {
2557 return Err(StandardDecodeError::InvalidOpcode);
2558 }
2559 }
2560 } else {
2561 let opc = (opcode >> 5) & 0b11;
2563 let imm5 = opcode & 0b1_1111;
2564
2565 let operands = handler.read_u8(words)?;
2566 let rd = operands & 0b1111;
2567 let rs2 = operands >> 4;
2568
2569 if opc == 0b11 {
2570 let cnd = rs2;
2572 let opcode = [
2573 Opcode::BMEQ, Opcode::BMNE, Opcode::BMGEU, Opcode::BMLTU,
2574 Opcode::BMGTU, Opcode::BMLEU, Opcode::BMPZ, Opcode::BMN,
2575 Opcode::BMGE, Opcode::BMLT, Opcode::BMGT, Opcode::BMLE,
2576 Opcode::BMO, Opcode::BMNO, Opcode::NOP, Opcode::BNOT ][cnd as usize];
2578 handler.on_opcode_decoded(opcode)?;
2579 handler.on_operand_decoded(0, Operand::ImmB { imm: imm5 })?;
2580 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2581 } else {
2582 let opcode = [Opcode::SHLR, Opcode::SHAR, Opcode::SHLL][opc as usize];
2583 handler.on_opcode_decoded(opcode)?;
2584 handler.on_operand_decoded(0, Operand::ImmB { imm: imm5 })?;
2585 handler.on_operand_decoded(1, Operand::Register { num: rs2 })?;
2586 handler.on_operand_decoded(2, Operand::Register { num: rd })?;
2587 }
2588 }
2589 } else if opc == 0b1111_1110 {
2590 let operands = handler.read_u8(words)?;
2592 let next_regs = handler.read_u8(words)?;
2593 let ri = operands & 0b1111;
2594 let rb = next_regs >> 4;
2595 let rd = next_regs & 0b1111;
2596 let sz = (operands >> 4) & 0b11;
2597
2598 if sz == 0b11 {
2599 return Err(StandardDecodeError::InvalidOperand);
2600 }
2601
2602 let sz = [SizeCode::B, SizeCode::W, SizeCode::L][sz as usize];
2603
2604 if operands < 0b0100_0000 {
2605 handler.on_opcode_decoded(Opcode::MOV)?;
2606 handler.on_operand_decoded(0, Operand::Register { num: rd })?;
2607 handler.on_operand_decoded(1, Operand::DerefIndexed { base: rb, index: ri, width: sz })?;
2608 } else if operands < 0b1000_0000 {
2609 handler.on_opcode_decoded(Opcode::MOV)?;
2610 handler.on_operand_decoded(0, Operand::DerefIndexed { base: rb, index: ri, width: sz })?;
2611 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2612 } else if operands < 0b1100_0000 {
2613 return Err(StandardDecodeError::InvalidOpcode);
2616 } else if operands < 0b1110_0000 {
2617 if sz == SizeCode::L {
2618 return Err(StandardDecodeError::InvalidOperand);
2619 }
2620
2621 handler.on_opcode_decoded(Opcode::MOVU)?;
2622 handler.on_operand_decoded(0, Operand::DerefIndexed { base: rb, index: ri, width: sz })?;
2623 handler.on_operand_decoded(1, Operand::Register { num: rd })?;
2624 } else {
2625 return Err(StandardDecodeError::InvalidOpcode);
2626 }
2627 } else if opc == 0b1111_1111 {
2628 let operands = handler.read_u8(words)?;
2630 let rd = operands & 0b1111;
2631 let opc = operands >> 4;
2632 let extra_regs = handler.read_u8(words)?;
2633 let rs2 = extra_regs & 0b1111;
2634 let rs = extra_regs >> 4;
2635
2636 let opc = match opc {
2637 0b0000 => Opcode::SUB,
2638 0b0010 => Opcode::ADD,
2639 0b0011 => Opcode::MUL,
2640 0b0100 => Opcode::AND,
2641 0b0101 => Opcode::OR,
2642 0b0110 => {
2643 if decoder.version >= RxVersion::V3 {
2644 Opcode::XOR
2645 } else {
2646 return Err(StandardDecodeError::InvalidOpcode);
2647 }
2648 },
2649 0b1000 => {
2650 if decoder.version >= RxVersion::V2 {
2651 Opcode::FSUB
2652 } else {
2653 return Err(StandardDecodeError::InvalidOpcode);
2654 }
2655 },
2656 0b1010 => {
2657 if decoder.version >= RxVersion::V2 {
2658 Opcode::FADD
2659 } else {
2660 return Err(StandardDecodeError::InvalidOpcode);
2661 }
2662 },
2663 0b1011 => {
2664 if decoder.version >= RxVersion::V2 {
2665 Opcode::FMUL
2666 } else {
2667 return Err(StandardDecodeError::InvalidOpcode);
2668 }
2669 },
2670 _ => {
2671 return Err(StandardDecodeError::InvalidOpcode);
2672 }
2673 };
2674
2675 handler.on_opcode_decoded(opc)?;
2676 handler.on_operand_decoded(0, Operand::Register { num: rs })?;
2677 handler.on_operand_decoded(1, Operand::Register { num: rs2 })?;
2678 handler.on_operand_decoded(2, Operand::Register { num: rd })?;
2679 } else {
2680 unreachable!("fuzzing should show this to be unreachable");
2681 }
2682
2683 Ok(())
2684}