1use yaxpeax_arch::{AddressDiff, Arch, Decoder, LengthedInstruction, Reader};
9use yaxpeax_arch::StandardDecodeError as DecodeError;
10
11#[cfg(feature = "fmt")]
12mod display;
13
14#[derive(Debug)]
15pub struct Hexagon;
16
17impl Arch for Hexagon {
18 type Word = u8;
19 type Address = u32;
22 type Instruction = InstructionPacket;
23 type DecodeError = yaxpeax_arch::StandardDecodeError;
24 type Decoder = InstDecoder;
25 type Operand = Operand;
26}
27
28#[derive(Debug, Copy, Clone, Default, PartialEq)]
29struct Predicate {
30 state: u8,
31}
32
33#[derive(Debug, Copy, Clone, PartialEq)]
34enum BranchHint {
35 Taken,
36 NotTaken,
37}
38
39macro_rules! opcode_check {
40 ($e:expr) => {
41 if !$e {
42 return Err(DecodeError::InvalidOpcode);
43 }
44 }
45}
46
47macro_rules! operand_check {
48 ($e:expr) => {
49 if !$e {
50 return Err(DecodeError::InvalidOperand);
51 }
52 }
53}
54
55macro_rules! decode_opcode {
56 ($e:expr) => {
57 match $e {
58 Some(v) => v,
59 None => {
60 return Err(DecodeError::InvalidOpcode);
61 }
62 }
63 }
64}
65
66macro_rules! decode_operand {
67 ($e:expr) => {
68 match $e {
69 Some(v) => v,
70 None => {
71 return Err(DecodeError::InvalidOperand);
72 }
73 }
74 }
75}
76
77#[allow(dead_code)]
80impl Predicate {
81 fn reg(num: u8) -> Self {
82 assert!(num <= 0b11);
83 Self { state: num }
84 }
85
86 fn num(&self) -> u8 {
87 self.state & 0b11
88 }
89
90 fn set_negated(mut self, bit: bool) -> Self {
91 if bit {
92 assert!(self.state & 0b0100 == 0);
93 self.state |= 0b0100;
94 }
95 self
96 }
97
98 fn negated(&self) -> bool {
99 self.state & 0b0100 != 0
100 }
101
102 fn set_pred_new(mut self, bit: bool) -> Self {
103 if bit {
104 assert!(self.state & 0b1000 == 0);
105 self.state |= 0b1000;
106 }
107 self
108 }
109
110 fn pred_new(&self) -> bool {
111 self.state & 0b1000 != 0
112 }
113}
114
115#[derive(Debug, Copy, Clone, Default, PartialEq)]
116pub struct LoopEnd {
117 loops_ended: u8
118}
119
120impl LoopEnd {
121 pub fn end_0(&self) -> bool {
122 self.loops_ended & 0b01 != 0
123 }
124
125 pub fn end_1(&self) -> bool {
126 self.loops_ended & 0b10 != 0
127 }
128
129 pub fn end_any(&self) -> bool {
130 self.loops_ended != 0
131 }
132
133 fn mark_end(&mut self, lp: u8) {
135 self.loops_ended |= 1 << lp;
136 }
137}
138
139#[derive(Debug, Copy, Clone, Default)]
155pub struct InstructionPacket {
156 instructions: [Instruction; 4],
158 instruction_count: u8,
160 word_count: u8,
162 loop_effect: LoopEnd,
164}
165
166impl PartialEq for InstructionPacket {
167 fn eq(&self, other: &Self) -> bool {
168 let instructions = self.instruction_count as usize;
169 self.instruction_count == other.instruction_count &&
170 self.word_count == other.word_count &&
171 self.loop_effect == other.loop_effect &&
172 self.instructions[..instructions] == other.instructions[..instructions]
173 }
174}
175
176#[derive(Debug, Copy, Clone)]
273pub struct Instruction {
274 opcode: Opcode,
275 dest: Option<Operand>,
276 alt_dest: Option<Operand>,
286 flags: InstFlags,
287
288 sources: [Operand; 3],
289 sources_count: u8,
290}
291
292#[derive(Debug, Copy, Clone, PartialEq)]
293enum RoundingMode {
294 Round,
295 Cround,
296 Raw,
297 Pos,
298 Neg,
299}
300
301impl RoundingMode {
302 #[cfg(feature = "fmt")]
305 fn as_label(&self) -> &'static str {
306 match self {
307 RoundingMode::Round => ":rnd",
308 RoundingMode::Cround => ":crnd",
309 RoundingMode::Raw => ":raw",
310 RoundingMode::Pos => ":pos",
311 RoundingMode::Neg => ":neg",
312 }
313 }
314}
315
316#[derive(Debug, Copy, Clone, PartialEq)]
317enum AssignMode {
318 AddAssign,
319 SubAssign,
320 AndAssign,
321 OrAssign,
322 XorAssign,
323 ClrBit,
324 SetBit,
325}
326
327#[derive(Debug, Copy, Clone, PartialEq)]
328enum RawMode {
329 Lo,
330 Hi,
331}
332
333#[derive(Debug, Copy, Clone, PartialEq)]
334struct InstFlags {
335 predicate: Option<Predicate>,
336 branch_hint: Option<BranchHint>,
337 negated: bool,
338 saturate: bool,
339 scale: bool,
340 library: bool,
341 chop: bool,
342 rounded: Option<RoundingMode>,
343 threads: Option<DomainHint>,
344 assign_mode: Option<AssignMode>,
345 raw_mode: Option<RawMode>,
346 shift_left: Option<u8>,
347 shift_right: Option<u8>,
348 carry: bool,
349 deprecated: bool,
350}
351
352#[derive(Debug, Copy, Clone, PartialEq)]
353enum DomainHint {
354 Same,
355 All,
356}
357
358impl Default for InstFlags {
359 fn default() -> Self {
360 Self {
361 predicate: None,
362 branch_hint: None,
363 negated: false,
364 saturate: false,
365 scale: false,
366 library: false,
367 chop: false,
368 rounded: None,
369 threads: None,
370 assign_mode: None,
371 raw_mode: None,
372 shift_left: None,
373 shift_right: None,
374 carry: false,
375 deprecated: false,
376 }
377 }
378}
379
380#[allow(non_camel_case_types)]
413#[derive(Debug, Copy, Clone, PartialEq, Eq)]
414#[repr(u16)]
415pub enum Opcode {
416 #[doc(hidden)]
418 BUG,
419
420 Nop,
421
422 Jump,
424 Jumpr,
425 Jumprh,
426 Call,
427 Callr,
428 Callrh,
429 Hintjr,
430
431 LoadMemb,
432 LoadMemub,
433 LoadMemh,
434 LoadMemuh,
435 LoadMemw,
436 LoadMemd,
437
438 StoreMemb,
439 StoreMemh,
440 StoreMemw,
441 StoreMemd,
442
443 Memb, Memub, Memh, Memuh, Memw, Memd,
444
445 Membh,
446 MemhFifo,
447 Memubh,
448 MembFifo,
449
450 Aslh,
451 Asrh,
452 TransferRegister,
453 TransferRegisterJump,
455 Zxtb,
456 Sxtb,
457 Zxth,
458 Sxth,
459
460 TransferImmediate,
461 TransferImmediateJump,
463
464 Mux,
465
466 Combine,
467 CmpEq,
468 CmpGt,
469 CmpGtu,
470 CmpbEq,
471 CmphEq,
472 CmpbGtu,
473 CmphGtu,
474 CmpbGt,
475 CmphGt,
476
477 JumpEq,
478 JumpNeq,
479 JumpGt,
480 JumpLe,
481 JumpGtu,
482 JumpLeu,
483 JumpBitSet,
484 JumpBitClear,
485
486 TestClrJump,
488 CmpEqJump,
490 CmpGtJump,
492 CmpGtuJump,
494
495 JumpRegZ,
499 JumpRegNz,
503 JumpRegGez,
507 JumpRegLez,
511
512 Add,
513 And,
514 And_nRR,
515 And_RnR,
516 Sub,
517 Or,
518 Or_nRR,
519 Or_RnR,
520 Xor,
521 Contains,
522
523 Tlbw,
524 Tlbr,
525 Tlbp,
526 TlbInvAsid,
527 Ctlbw,
528 Tlboc,
529
530 Asr,
531 Lsr,
532 Asl,
533 Lsl,
535 Rol,
536 Vsathub,
537 Vsatwuh,
538 Vsatwh,
539 Vsathb,
540
541 Vabsh,
542 Vabsw,
543 Vasrw,
544 Vasrh,
545 Vlsrw,
546 Vlsrh,
547 Vaslw,
548 Vaslh,
549 Vlslw,
550 Vlslh,
551
552 Vabsdiffb,
553 Vabsdiffub,
554 Vabsdiffh,
555 Vabsdiffw,
556
557 Not,
558 Neg,
559 Abs,
560 Vconj,
561
562 Deinterleave,
563 Interleave,
564 Brev,
565
566 Extractu,
567 Extract,
568 Insert,
569
570 Trap0,
571 Trap1,
572 Pause,
573 Icinva,
574 Isync,
575 Unpause,
576
577 DfAdd,
578 DfSub,
579 DfMax,
580 DfMin,
581
582 SfSub,
583 SfAdd,
584 SfMpy,
585 SfMax,
586 SfMin,
587 SfCmpEq,
588 SfCmpGt,
589 SfCmpGe,
590 SfCmpUo,
591
592 DfCmpEq,
593 DfCmpGt,
594 DfCmpGe,
595 DfCmpUo,
596 DfMpyll,
597 DfMpylh,
598 DfMpyhh,
599 DfMpyfix,
600
601 Cmpy,
602 Cmpyiw,
603 Cmpyrw,
604 Cmpyiwh,
605 Cmpyrwh,
606 Cmpyi,
607 Cmpyr,
608 Vcmpyi,
609 Vcmpyr,
610 Vmpybu,
611 Vmpyh,
612 Vmpyhsu,
613 Vmpybsu,
614 Vrmpybsu,
615 Vdmpybsu,
616 Vrmpybu,
617 Vrmpyh,
618
619 Pmpyw,
620 Vpmpyh,
621 Lfs,
622
623 Vxaddsubh,
624 Vxaddsubw,
625 Vxsubaddh,
626 Vxsubaddw,
627
628 Vraddub,
629 Vraddh,
630 Vradduh,
631 Vrsadub,
632 Vaddub,
633 Vaddh,
634 Vaddhub,
635 Vadduh,
636 Vaddw,
637 Vsubub,
638 Vsubw,
639 Vsubh,
640 Vsubuh,
641 Vavgub,
642 Vavgw,
643 Vavguw,
644 Vavgh,
645 Vavguh,
646 Vnavgh,
647 Vnavgw,
648
649 Packhl,
650
651 DcCleanA,
652 DcInvA,
653 DcCleanInvA,
654 DcZeroA,
655 DcKill,
656 IcKill,
657 L2Fetch,
658 L2Kill,
659 L2Gunlock,
660 L2Gclean,
661 L2Gcleaninv,
662 DmSyncHt,
663 SyncHt,
664
665 Release,
666 Barrier,
667 AllocFrame,
668 MemwRl,
669 MemdRl,
670
671 DeallocFrame,
672 DeallocReturn,
673 Dcfetch,
674
675 MemwLockedLoad,
676 MemwStoreCond,
677 MemwAq,
678 MemdLockedLoad,
679 MemdStoreCond,
680 MemdAq,
681
682 Pmemcpy,
683 Linecpy,
684
685 Loop0,
686 Loop1,
687 Sp1Loop0,
688 Sp2Loop0,
689 Sp3Loop0,
690 Trace,
691 Diag,
692 Diag0,
693 Diag1,
694
695 Movlen,
696
697 Fastcorner9,
698 Any8,
699 All8,
700
701 Max,
702 Maxu,
703 Min,
704 Minu,
705
706 Valignb,
707 Vspliceb,
708 Vsxtbh,
709 Vzxtbh,
710 Vsxthw,
711 Vzxthw,
712 Vsplath,
713 Vsplatb,
714 Vcrotate,
715 Vrcrotate,
716 Vmaxb,
717 Vmaxub,
718 Vminb,
719 Vminuw,
720 Vminh,
721 Vminuh,
722 Vminw,
723 Vmaxw,
724 Vmaxuw,
725 Vmaxh,
726 Vmaxuh,
727 Vrmaxh,
728 Vrmaxw,
729 Vrminh,
730 Vrminw,
731 Vrmaxuh,
732 Vrmaxuw,
733 Vrminuh,
734 Vrminuw,
735 Vnegh,
736 Vcnegh,
737 Vrcnegh,
738
739 ConvertDf2D,
740 ConvertDf2Ud,
741 ConvertSf2W,
742 ConvertSf2D,
743 ConvertSf2Df,
744 ConvertDf2Sf,
745 ConvertSf2Uw,
746 ConvertSf2Ud,
747 ConvertUd2Df,
748 ConvertUd2Sf,
749 ConvertUw2Sf,
750 ConvertUw2Df,
751 ConvertW2Sf,
752 ConvertW2Df,
753 ConvertD2Df,
754 ConvertD2Sf,
755 Mask,
756 Setbit,
757 Clrbit,
758 Togglebit,
759 Tstbit,
760 Bitsclr,
761 Bitsset,
762 Modwrap,
763 SfClass,
764 DfClass,
765 SfMake,
766 DfMake,
767 Tableidxb,
768 Tableidxh,
769 Tableidxw,
770 Tableidxd,
771
772 Vasrhub,
773 Vrndwh,
774 Vtrunohb,
775 Vtrunowh,
776 Vtrunehb,
777 Vtrunewh,
778 Normamt,
779 Popcount,
780 Sat,
781 Sath,
782 Satb,
783 Satuh,
784 Satub,
785 Round,
786 Cround,
787 Bitsplit,
788 Clip,
789 Vclip,
790 Clb,
791 Cl0,
792 Cl1,
793 Ct0,
794 Ct1,
795 Vitpack,
796 SfFixupr,
797 SfFixupn,
798 SfFixupd,
799 Swiz,
800 Shuffeb,
801 Shuffob,
802 Shuffeh,
803 Shuffoh,
804 Decbin,
805
806 Parity,
807 Vmux,
808 VcmpwEq,
809 VcmpwGt,
810 VcmpwGtu,
811 VcmphEq,
812 VcmphGt,
813 VcmphGtu,
814 VcmpbEq,
815 VcmpbGt,
816 VcmpbGtu,
817 Tlbmatch,
818 Boundscheck,
819
820 Mpy,
821 Mpyu,
822 Mpyi,
823 Mpysu,
824 Vcmpyh,
825 Vrcmpys,
826 Vdmpy,
827 Vmpyeh,
828 Vmpyweh,
829 Vmpywoh,
830 Vmpyweuh,
831 Vmpywouh,
832 Vrmpyweh,
833 Vrmpywoh,
834 Vrmpyu,
835 Vrmpysu,
836
837 AddAslRegReg,
840
841 Swi,
842 Cswi,
843 Ciad,
844 Wait,
845 Resume,
846 Stop,
847 Start,
848 Nmi,
849 Setimask,
850 Siad,
851 Brkpt,
852 TlbLock,
853 K0Lock,
854 Crswap,
855 Getimask,
856 Iassignr,
857 Icdatar,
858 Ictagr,
859 Ictagw,
860 Icinvidx,
861
862 AndAnd = 0x8000,
863 AndOr,
864 OrAnd,
865 AndNot,
866 OrOr,
867 AndAndNot,
868 AndOrNot,
869 OrAndNot,
870 OrNot,
871 OrOrNot,
872 AndLsr,
873 OrLsr,
874 AddLsr,
875 SubLsr,
876 AddLsl,
877 AddAsl,
878 SubAsl,
879 AndAsl,
880 OrAsl,
881 AddClb,
882 AddAdd,
883 AddSub,
884 Vacsh,
885 Vminub,
886 SfRecipa,
887 SfInvsqrta,
888 Any8VcmpbEq,
889
890 AddMpyi,
891 MpyiNeg,
892 MpyiPos,
893}
894
895impl Opcode {
896 #[cfg(feature = "fmt")]
899 fn cmp_str(&self) -> Option<&'static str> {
900 match self {
901 Opcode::JumpEq => { Some("cmp.eq") },
902 Opcode::JumpNeq => { Some("!cmp.eq") },
903 Opcode::JumpGt => { Some("cmp.gt") },
904 Opcode::JumpLe => { Some("!cmp.gt") },
905 Opcode::JumpGtu => { Some("cmp.gtu") },
906 Opcode::JumpLeu => { Some("!cmp.gtu") },
907 Opcode::JumpBitSet => { Some("tstbit") },
908 Opcode::JumpBitClear => { Some("!tstbit") },
909 Opcode::CmpEqJump => { Some("cmp.eq") },
910 Opcode::CmpGtJump => { Some("cmp.gt") },
911 Opcode::CmpGtuJump => { Some("cmp.gtu") },
912 Opcode::TestClrJump => { Some("tstbit") },
913 _ => None
914 }
915 }
916}
917
918impl Instruction {
919 fn sources(&self) -> &[Operand] {
920 &self.sources[..self.sources_count as usize]
921 }
922}
923
924impl PartialEq for Instruction {
925 fn eq(&self, other: &Self) -> bool {
926 let Instruction {
927 opcode: leftop,
928 dest: leftdest,
929 alt_dest: leftaltdest,
930 flags: leftflags,
931 ..
932 } = self;
933 let Instruction {
934 opcode: rightop,
935 dest: rightdest,
936 alt_dest: rightaltdest,
937 flags: rightflags,
938 ..
939 } = other;
940
941 leftop == rightop &&
942 leftdest == rightdest &&
943 leftaltdest == rightaltdest &&
944 leftflags == rightflags &&
945 self.sources() == other.sources()
946 }
947}
948
949impl Default for Instruction {
950 fn default() -> Instruction {
951 Instruction {
952 opcode: Opcode::BUG,
953 dest: None,
954 alt_dest: None,
955 flags: InstFlags::default(),
956 sources: [Operand::Nothing, Operand::Nothing, Operand::Nothing],
957 sources_count: 0,
958 }
959 }
960}
961
962impl LengthedInstruction for InstructionPacket {
963 type Unit = AddressDiff<<Hexagon as Arch>::Address>;
964 fn min_size() -> Self::Unit {
965 AddressDiff::from_const(4)
966 }
967 fn len(&self) -> Self::Unit {
968 AddressDiff::from_const(self.word_count as u32 * 4)
969 }
970}
971
972impl yaxpeax_arch::Instruction for InstructionPacket {
973 fn well_defined(&self) -> bool { true }
975}
976
977#[derive(Debug, Copy, Clone, PartialEq, Eq)]
978pub enum Operand {
979 Nothing,
980
981 PCRel32 { rel: i32 },
982
983 Gpr { reg: u8 },
993 Cr { reg: u8 },
1010 Sr { reg: u8 },
1012 GprNew { reg: u8 },
1015 GprLow { reg: u8 },
1017 GprHigh { reg: u8 },
1019
1020 GprConjugate { reg: u8 },
1023 Gpr64b { reg_low: u8 },
1033 Gpr64bConjugate { reg_low: u8 },
1037 Cr64b { reg_low: u8 },
1039 Sr64b { reg_low: u8 },
1041
1042 PredicateReg { reg: u8 },
1044
1045 RegOffset { base: u8, offset: u32 },
1046
1047 RegOffsetInc { base: u8, offset: u32 },
1048
1049 RegShiftedReg { base: u8, index: u8, shift: u8 },
1050
1051 RegShiftOffset { base: u8, shift: u8, offset: u32 },
1052
1053 ImmU8 { imm: u8 },
1054
1055 ImmU16 { imm: u16 },
1056
1057 ImmI8 { imm: i8 },
1058
1059 ImmI16 { imm: i16 },
1060
1061 ImmI32 { imm: i32 },
1062
1063 ImmU32 { imm: u32 },
1064
1065 Immext { imm: u32 },
1066
1067 RegOffsetCirc { base: u8, offset: u32, mu: u8 },
1069
1070 RegCirc { base: u8, mu: u8 },
1071
1072 RegStoreAssign { base: u8, addr: u32 },
1073
1074 RegMemIndexed { base: u8, mu: u8 },
1075
1076 RegMemIndexedBrev { base: u8, mu: u8 },
1077
1078 Absolute { addr: u32 },
1079
1080 GpOffset { offset: u32 },
1081}
1082
1083impl Operand {
1084 fn gpr(num: u8) -> Self {
1085 Self::Gpr { reg: num }
1086 }
1087
1088 fn gpr_low(num: u8) -> Self {
1089 Self::GprLow { reg: num }
1090 }
1091
1092 fn gpr_high(num: u8) -> Self {
1093 Self::GprHigh { reg: num }
1094 }
1095
1096 fn gpr_conjugate(num: u8) -> Self {
1097 Self::GprConjugate { reg: num }
1098 }
1099
1100 fn gpr_4b(num: u8) -> Self {
1103 debug_assert!(num < 0b10000);
1104 let decoded = (num & 0b111) | ((num & 0b1000) << 1);
1106 Self::Gpr { reg: decoded }
1107 }
1108
1109 fn cr(num: u8) -> Self {
1110 Self::Cr { reg: num }
1111 }
1112
1113 fn sr(num: u8) -> Self {
1114 Self::Sr { reg: num }
1115 }
1116
1117 fn gpr_new(num: u8) -> Self {
1118 Self::GprNew { reg: num }
1119 }
1120
1121 fn gprpair(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1122 operand_check!(num & 1 == 0);
1123 Ok(Self::Gpr64b { reg_low: num })
1124 }
1125
1126 fn gprpair_conjugate(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1127 operand_check!(num & 1 == 0);
1128 Ok(Self::Gpr64bConjugate { reg_low: num })
1129 }
1130
1131 fn crpair(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1132 operand_check!(num & 1 == 0);
1133 Ok(Self::Cr64b { reg_low: num })
1134 }
1135
1136 fn srpair(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1137 operand_check!(num & 1 == 0);
1138 Ok(Self::Sr64b { reg_low: num })
1139 }
1140
1141 fn pred(num: u8) -> Self {
1142 Self::PredicateReg { reg: num }
1143 }
1144
1145 fn imm_i8(num: i8) -> Self {
1146 Self::ImmI8 { imm: num }
1147 }
1148
1149 fn imm_u8(num: u8) -> Self {
1150 Self::ImmU8 { imm: num }
1151 }
1152
1153 fn imm_i16(num: i16) -> Self {
1154 Self::ImmI16 { imm: num }
1155 }
1156
1157 fn imm_u16(num: u16) -> Self {
1158 Self::ImmU16 { imm: num }
1159 }
1160
1161 fn imm_i32(num: i32) -> Self {
1162 Self::ImmI32 { imm: num }
1163 }
1164
1165 fn imm_u32(num: u32) -> Self {
1166 Self::ImmU32 { imm: num }
1167 }
1168
1169 fn with_extension(
1170 i: u32, extender: &mut Option<u32>,
1171 extended: impl FnOnce(u32) -> Result<Self, yaxpeax_arch::StandardDecodeError>,
1172 no_extender: impl FnOnce(u32) -> Result<Self, yaxpeax_arch::StandardDecodeError>,
1173 ) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1174 if let Some(extender) = extender.take() {
1175 operand_check!(i & !0x3f == 0);
1176 extended(i | (extender << 6))
1177 } else {
1178 no_extender(i)
1179 }
1180 }
1181
1182 fn immext(
1183 i: u32, extender: &mut Option<u32>,
1184 unextended: impl FnOnce(u32) -> Result<Self, yaxpeax_arch::StandardDecodeError>,
1185 ) -> Result<Self, yaxpeax_arch::StandardDecodeError> {
1186 Self::with_extension(
1187 i, extender,
1188 |imm| Ok(Self::Immext { imm }),
1189 unextended
1190 )
1191 }
1192}
1193
1194#[derive(Debug)]
1195pub struct InstDecoder { }
1196
1197impl Default for InstDecoder {
1198 fn default() -> Self {
1199 InstDecoder {}
1200 }
1201}
1202
1203trait DecodeHandler<T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>> {
1204 #[inline(always)]
1205 fn read_u32(&mut self, words: &mut T) -> Result<u32, <Hexagon as Arch>::DecodeError> {
1206 let mut buf = [0u8; 4];
1207 words.next_n(&mut buf).ok().ok_or(DecodeError::ExhaustedInput)?;
1208 self.on_word_read(buf[0]);
1209 self.on_word_read(buf[1]);
1210 self.on_word_read(buf[2]);
1211 self.on_word_read(buf[3]);
1212 Ok(u32::from_le_bytes(buf))
1213 }
1214 fn read_inst_word(&mut self, words: &mut T) -> Result<u32, <Hexagon as Arch>::DecodeError>;
1215 fn on_decode_start(&mut self) {}
1216 fn on_decode_end(&mut self) {}
1217 fn start_instruction(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1218 fn end_instruction(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1219 fn on_nv_register(&mut self, _dist: u8) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1225 fn on_loop_end(&mut self, loop_num: u8);
1226 fn on_opcode_decoded(&mut self, _opcode: Opcode) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1227 fn on_source_decoded(&mut self, _operand: Operand) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1228 fn on_dest_decoded(&mut self, _operand: Operand) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1229 fn assign_mode(&mut self, _assign_mode: AssignMode) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1230 fn inst_predicated(&mut self, _num: u8, _negated: bool, _pred_new: bool) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1231 fn negate_result(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1232 fn saturate(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1233 fn scale(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1234 fn library(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1235 fn branch_hint(&mut self, _hint_taken: bool) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1236 fn domain_hint(&mut self, _domain: DomainHint) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1237 fn rounded(&mut self, _mode: RoundingMode) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1238 fn chop(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1239 fn raw_mode(&mut self, _mode: RawMode) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1240 fn shift_left(&mut self, _shiftamt: u8) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1241 fn shift_right(&mut self, _shiftamt: u8) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1242 fn carry(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1243 fn deprecated(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) }
1244 fn on_word_read(&mut self, _word: <Hexagon as Arch>::Word) {}
1245}
1246
1247impl<T: yaxpeax_arch::Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>> DecodeHandler<T> for InstructionPacket {
1248 fn on_decode_start(&mut self) {
1249 self.instructions = [Instruction::default(); 4];
1250 self.instruction_count = 0;
1251 self.word_count = 0;
1252 }
1253 fn on_loop_end(&mut self, loop_num: u8) {
1254 self.loop_effect.mark_end(loop_num);
1255 }
1256 fn on_opcode_decoded(&mut self, opcode: Opcode) -> Result<(), <Hexagon as Arch>::DecodeError> {
1257 self.instructions[self.instruction_count as usize].opcode = opcode;
1258 Ok(())
1259 }
1260 fn on_source_decoded(&mut self, operand: Operand) -> Result<(), <Hexagon as Arch>::DecodeError> {
1261 let inst = &mut self.instructions[self.instruction_count as usize];
1262 inst.sources[inst.sources_count as usize] = operand;
1263 inst.sources_count += 1;
1264 Ok(())
1265 }
1266 fn on_dest_decoded(&mut self, operand: Operand) -> Result<(), <Hexagon as Arch>::DecodeError> {
1267 let inst = &mut self.instructions[self.instruction_count as usize];
1268 if inst.dest.is_some() {
1269 assert!(inst.alt_dest.is_none());
1270 inst.alt_dest = Some(operand);
1271 } else {
1272 inst.dest = Some(operand);
1273 }
1274 Ok(())
1275 }
1276 fn on_nv_register(&mut self, dist: u8) -> Result<(), <Hexagon as Arch>::DecodeError> {
1277 operand_check!(dist & 1 == 0);
1281
1282 let dist = dist >> 1;
1283 operand_check!(dist != 0);
1285
1286 operand_check!(self.instruction_count >= dist);
1287 let producer_idx = self.instruction_count - dist;
1288
1289 let source = match self.instructions.get(producer_idx as usize) {
1290 Some(inst) => {
1291 match inst.dest {
1292 Some(Operand::Gpr { reg }) => {
1293 reg
1294 }
1295 _ => {
1300 return Err(DecodeError::InvalidOperand);
1303 }
1304 }
1305 }
1306 None => {
1307 return Err(DecodeError::InvalidOperand);
1308 }
1309 };
1310
1311 <Self as DecodeHandler<T>>::on_source_decoded(self, Operand::gpr_new(source))
1312 }
1313 fn assign_mode(&mut self, assign_mode: AssignMode) -> Result<(), <Hexagon as Arch>::DecodeError> {
1314 let inst = &mut self.instructions[self.instruction_count as usize];
1315 inst.flags.assign_mode = Some(assign_mode);
1316 Ok(())
1317 }
1318 fn inst_predicated(&mut self, num: u8, negated: bool, pred_new: bool) -> Result<(), <Hexagon as Arch>::DecodeError> {
1319 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1320 assert!(flags.predicate.is_none());
1321 flags.predicate = Some(Predicate::reg(num).set_negated(negated).set_pred_new(pred_new));
1322 Ok(())
1323 }
1324 fn negate_result(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1325 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1326 assert!(!flags.negated);
1327 flags.negated = true;
1328 Ok(())
1329 }
1330 fn saturate(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1331 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1332 assert!(!flags.saturate);
1333 flags.saturate = true;
1334 Ok(())
1335 }
1336 fn scale(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1337 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1338 assert!(!flags.scale);
1339 flags.scale = true;
1340 Ok(())
1341 }
1342 fn library(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1343 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1344 assert!(!flags.scale);
1345 flags.library = true;
1346 Ok(())
1347 }
1348 fn branch_hint(&mut self, hint_taken: bool) -> Result<(), <Hexagon as Arch>::DecodeError> {
1349 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1350 assert!(flags.branch_hint.is_none());
1351 if hint_taken {
1352 flags.branch_hint = Some(BranchHint::Taken);
1353 } else {
1354 flags.branch_hint = Some(BranchHint::NotTaken);
1355 }
1356 Ok(())
1357 }
1358 fn domain_hint(&mut self, domain: DomainHint) -> Result<(), <Hexagon as Arch>::DecodeError> {
1359 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1360 assert!(flags.threads.is_none());
1361 flags.threads = Some(domain);
1362 Ok(())
1363 }
1364 fn rounded(&mut self, mode: RoundingMode) -> Result<(), <Hexagon as Arch>::DecodeError> {
1365 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1366 assert!(flags.rounded.is_none());
1367 flags.rounded = Some(mode);
1368 Ok(())
1369 }
1370 fn chop(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1371 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1372 assert!(!flags.chop);
1373 flags.chop = true;
1374 Ok(())
1375 }
1376 fn raw_mode(&mut self, mode: RawMode) -> Result<(), <Hexagon as Arch>::DecodeError> {
1377 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1378 assert!(flags.raw_mode.is_none());
1379 flags.raw_mode = Some(mode);
1380 Ok(())
1381 }
1382 fn shift_left(&mut self, shiftamt: u8) -> Result<(), <Hexagon as Arch>::DecodeError> {
1383 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1384 assert!(flags.shift_left.is_none());
1385 assert!(flags.shift_right.is_none());
1386 if shiftamt == 0 {
1389 return Ok(());
1390 }
1391 flags.shift_left = Some(shiftamt);
1392 Ok(())
1393 }
1394 fn shift_right(&mut self, shiftamt: u8) -> Result<(), <Hexagon as Arch>::DecodeError> {
1395 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1396 assert!(flags.shift_left.is_none());
1397 assert!(flags.shift_right.is_none());
1398 if shiftamt == 0 {
1401 return Ok(());
1402 }
1403 flags.shift_right = Some(shiftamt);
1404 Ok(())
1405 }
1406 fn carry(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1407 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1408 assert!(!flags.carry);
1409 flags.carry = true;
1410 Ok(())
1411 }
1412 fn deprecated(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1413 let flags = &mut self.instructions[self.instruction_count as usize].flags;
1414 assert!(!flags.deprecated);
1415 flags.deprecated = true;
1416 Ok(())
1417 }
1418 #[inline(always)]
1419 fn read_inst_word(&mut self, words: &mut T) -> Result<u32, <Hexagon as Arch>::DecodeError> {
1420 self.word_count += 1;
1421 self.read_u32(words)
1422 }
1423 fn on_word_read(&mut self, _word: <Hexagon as Arch>::Word) { }
1424 fn start_instruction(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1425 opcode_check!(self.instruction_count < self.instructions.len() as u8);
1426 Ok(())
1427 }
1428 fn end_instruction(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> {
1429 self.instruction_count += 1;
1430 Ok(())
1431 }
1432}
1433
1434impl Decoder<Hexagon> for InstDecoder {
1435 fn decode_into<T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>>(&self, packet: &mut InstructionPacket, words: &mut T) -> Result<(), <Hexagon as Arch>::DecodeError> {
1436 decode_packet(self, packet, words)
1437 }
1438}
1439
1440fn reg_b0(inst: u32) -> u8 { (inst & 0b11111) as u8 }
1441fn reg_b8(inst: u32) -> u8 { ((inst >> 8) & 0b11111) as u8 }
1442fn reg_b16(inst: u32) -> u8 { ((inst >> 16) & 0b11111) as u8 }
1443
1444fn decode_store_ops<
1459 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1460 H: DecodeHandler<T>,
1461>(
1462 handler: &mut H, opbits: u8, srcreg: u8,
1463 dest_op: impl FnOnce(u8) -> Result<Operand, DecodeError>
1464) -> Result<(), DecodeError> {
1465 if opbits == 0b101 {
1466 handler.on_nv_register(srcreg & 0b111)?;
1467 let opbits = (srcreg >> 3) & 0b11;
1468 static OPS: [Option<Opcode>; 4] = [
1469 Some(Opcode::StoreMemb), Some(Opcode::StoreMemh),
1470 Some(Opcode::StoreMemw), None,
1471 ];
1472 handler.on_opcode_decoded(decode_opcode!(OPS[opbits as usize]))?;
1473 handler.on_dest_decoded(dest_op(opbits)?)?;
1474 } else {
1475 match opbits {
1476 0b000 => {
1477 handler.on_opcode_decoded(Opcode::StoreMemb)?;
1478 handler.on_source_decoded(Operand::gpr(srcreg))?;
1479 handler.on_dest_decoded(dest_op(0)?)?;
1480 }
1481 0b010 => {
1482 handler.on_opcode_decoded(Opcode::StoreMemh)?;
1483 handler.on_source_decoded(Operand::gpr(srcreg))?;
1484 handler.on_dest_decoded(dest_op(1)?)?;
1485 }
1486 0b011 => {
1487 handler.on_opcode_decoded(Opcode::StoreMemh)?;
1488 handler.on_source_decoded(Operand::gpr_high(srcreg))?;
1489 handler.on_dest_decoded(dest_op(1)?)?;
1490 }
1491 0b100 => {
1492 handler.on_opcode_decoded(Opcode::StoreMemw)?;
1493 handler.on_source_decoded(Operand::gpr(srcreg))?;
1494 handler.on_dest_decoded(dest_op(2)?)?;
1495 }
1496 0b110 => {
1497 handler.on_opcode_decoded(Opcode::StoreMemd)?;
1498 handler.on_source_decoded(Operand::gprpair(srcreg)?)?;
1499 handler.on_dest_decoded(dest_op(3)?)?;
1500 }
1501 _ => {
1502 return Err(DecodeError::InvalidOpcode);
1503 }
1504 }
1505 }
1506 Ok(())
1507}
1508
1509fn decode_load_ops<
1512 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1513 H: DecodeHandler<T>,
1514>(
1515 handler: &mut H, opbits: u8, dstreg: u8,
1516 src_op: impl FnOnce(u8) -> Result<Operand, DecodeError>
1517) -> Result<(), DecodeError> {
1518 match opbits {
1521 0b000 => {
1522 handler.on_opcode_decoded(Opcode::LoadMemb)?;
1523 handler.on_dest_decoded(Operand::gpr(dstreg))?;
1524 handler.on_source_decoded(src_op(0)?)?;
1525 }
1526 0b001 => {
1527 handler.on_opcode_decoded(Opcode::LoadMemub)?;
1528 handler.on_dest_decoded(Operand::gpr(dstreg))?;
1529 handler.on_source_decoded(src_op(0)?)?;
1530 }
1531 0b010 => {
1532 handler.on_opcode_decoded(Opcode::LoadMemh)?;
1533 handler.on_dest_decoded(Operand::gpr(dstreg))?;
1534 handler.on_source_decoded(src_op(1)?)?;
1535 }
1536 0b011 => {
1537 handler.on_opcode_decoded(Opcode::LoadMemuh)?;
1538 handler.on_dest_decoded(Operand::gpr(dstreg))?;
1539 handler.on_source_decoded(src_op(1)?)?;
1540 }
1541 0b100 => {
1542 handler.on_opcode_decoded(Opcode::LoadMemw)?;
1543 handler.on_dest_decoded(Operand::gpr(dstreg))?;
1544 handler.on_source_decoded(src_op(2)?)?;
1545 }
1546 0b110 => {
1547 handler.on_opcode_decoded(Opcode::LoadMemd)?;
1548 handler.on_dest_decoded(Operand::gprpair(dstreg)?)?;
1549 handler.on_source_decoded(src_op(3)?)?;
1550 }
1551 _ => {
1552 return Err(DecodeError::InvalidOpcode);
1553 }
1554 }
1555 Ok(())
1556}
1557
1558fn subinstr_gprpair_b0(word: u16) -> u8 {
1559 let word = word & 0b111;
1560 if word < 0b100 {
1561 word as u8
1562 } else {
1563 (word + 16) as u8
1564 }
1565}
1566
1567fn subinstr_gpr_b0(word: u16) -> u8 {
1568 let word = word & 0b1111;
1569 if word < 0b1000 {
1570 word as u8
1571 } else {
1572 (word + 8) as u8
1573 }
1574}
1575
1576fn subinstr_gpr_b4(word: u16) -> u8 {
1577 let word = (word >> 4) & 0b1111;
1578 if word < 0b1000 {
1579 word as u8
1580 } else {
1581 (word + 8) as u8
1582 }
1583}
1584
1585fn subinstr_l1<
1586 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1587 H: DecodeHandler<T>,
1588>(handler: &mut H, word: u16, _extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
1589 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1590
1591 let offset = ((word >> 8) & 0b1111) as i8;
1592 let offset = offset << 4 >> 4;
1593
1594 if word & 0b1_0000_0000_0000 == 0 {
1595 handler.on_opcode_decoded(Opcode::Memw)?;
1596 let source = Operand::RegOffset {
1597 base: subinstr_gpr_b4(word),
1598 offset: (offset << 2) as i32 as u32,
1599 };
1600 handler.on_source_decoded(source)?;
1601 } else {
1602 handler.on_opcode_decoded(Opcode::Memub)?;
1603 let source = Operand::RegOffset {
1604 base: subinstr_gpr_b4(word),
1605 offset: offset as i32 as u32,
1606 };
1607 handler.on_source_decoded(source)?;
1608 }
1609
1610 Ok(())
1611}
1612
1613fn subinstr_s1<
1614 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1615 H: DecodeHandler<T>,
1616>(handler: &mut H, word: u16, _extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
1617 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1618
1619 let offset = ((word >> 8) & 0b1111) as i8;
1620 let offset = offset >> 4 << 4;
1621
1622 if word & 0b1_0000_0000_0000 == 0 {
1623 handler.on_opcode_decoded(Opcode::StoreMemw)?;
1624 let dest = Operand::RegOffset {
1625 base: subinstr_gpr_b4(word),
1626 offset: (offset << 2) as i32 as u32,
1627 };
1628 handler.on_dest_decoded(dest)?;
1629 } else {
1630 handler.on_opcode_decoded(Opcode::StoreMemb)?;
1631 let dest = Operand::RegOffset {
1632 base: subinstr_gpr_b4(word),
1633 offset: offset as i32 as u32,
1634 };
1635 handler.on_dest_decoded(dest)?;
1636 }
1637
1638 Ok(())
1639}
1640
1641fn subinstr_l2<
1642 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1643 H: DecodeHandler<T>,
1644>(handler: &mut H, word: u16, _extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
1645 let upper = word >> 8;
1647
1648 if upper < 0b11000 {
1649 let (opc, shamt) = if upper < 0b01000 {
1650 (Opcode::Memb, 0)
1651 } else if upper < 0b10000 {
1652 (Opcode::Memh, 2)
1653 } else {
1654 (Opcode::Memuh, 2)
1655 };
1656 let offset = ((upper & 0b111) as i8) << 5 >> 5;
1657 let source = Operand::RegOffset {
1658 base: subinstr_gpr_b4(word),
1659 offset: (offset << shamt) as i32 as u32,
1660 };
1661 handler.on_opcode_decoded(opc)?;
1662 handler.on_source_decoded(source)?;
1663 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1664 return Ok(());
1665 }
1666
1667 let upper = upper & 0b111;
1668 if upper < 0b11100 {
1669 opcode_check!(false);
1670 } else if upper < 0b11110 {
1671 handler.on_opcode_decoded(Opcode::Memw)?;
1672 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1673 let offset = ((word >> 4) & 0b11111) as i8;
1674 let offset = offset << 3 >> 3;
1675 handler.on_source_decoded(Operand::RegOffset {
1676 base: 29,
1677 offset: (offset << 2) as i32 as u32,
1678 })?;
1679
1680 return Ok(());
1681 } else if upper < 0b11111 {
1682 handler.on_opcode_decoded(Opcode::Memd)?;
1683 handler.on_dest_decoded(Operand::gprpair(subinstr_gprpair_b0(word))?)?;
1684 let offset = ((word >> 3) & 0b11111) as i8;
1685 let offset = offset << 3 >> 3;
1686 handler.on_source_decoded(Operand::RegOffset {
1687 base: 29,
1688 offset: (offset << 3) as i32 as u32,
1689 })?;
1690
1691 return Ok(());
1692 }
1693
1694 if word & 0b0100 != 0 {
1695 opcode_check!(word & 0b01111100 == 0b01000100);
1697
1698 let negated = word & 0b01 != 0;
1699 let dotnew = word & 0b10 != 0;
1700 handler.inst_predicated(0 as u8, negated, dotnew)?;
1701
1702 let hint_taken = word & 0b10 == 0;
1704 handler.branch_hint(hint_taken)?;
1705
1706 if word & 0b10000000 == 0 {
1707 handler.on_opcode_decoded(Opcode::DeallocReturn)?;
1708 handler.on_dest_decoded(Operand::gprpair(30)?)?;
1709 handler.on_source_decoded(Operand::gpr(30))?;
1710 } else {
1711 handler.on_opcode_decoded(Opcode::Jumpr)?;
1712 handler.on_dest_decoded(Operand::gpr(31))?;
1713 }
1714 } else {
1715 opcode_check!(word & 0b00111111 == 0);
1716 let op = (word >> 6) & 0b11;
1717 match op {
1718 0b00 => {
1719 handler.on_opcode_decoded(Opcode::DeallocFrame)?;
1721 handler.on_dest_decoded(Operand::gprpair(30)?)?;
1722 handler.on_source_decoded(Operand::gpr(30))?;
1723 }
1724 0b01 => {
1725 handler.on_opcode_decoded(Opcode::DeallocReturn)?;
1727 handler.on_dest_decoded(Operand::gprpair(30)?)?;
1728 handler.on_source_decoded(Operand::gpr(30))?;
1729 }
1730 0b10 => {
1731 opcode_check!(false);
1733 }
1734 _ => {
1735 handler.on_opcode_decoded(Opcode::Jumpr)?;
1737 handler.on_dest_decoded(Operand::gpr(31))?;
1738 }
1739 }
1740 }
1741
1742 Ok(())
1743}
1744
1745fn subinstr_s2<
1746 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1747 H: DecodeHandler<T>,
1748>(handler: &mut H, word: u16, _extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
1749 let upper = word >> 8;
1751
1752 let top = upper >> 3;
1753
1754 if top < 0b01 {
1755 handler.on_opcode_decoded(Opcode::StoreMemh)?;
1756 let offset = (((word >> 8) & 0b111) as i8) << 5 >> 5;
1757 handler.on_dest_decoded(Operand::RegOffset {
1758 base: subinstr_gpr_b4(word),
1759 offset: (offset << 1) as i32 as u32,
1760 })?;
1761 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1762 } else if top < 0b10 {
1763 opcode_check!(word & 0b00100 == 0);
1764 if word & 0b0001 == 0 {
1765 handler.on_opcode_decoded(Opcode::StoreMemw)?;
1766 let offset = (((word >> 4) & 0b11111) as i8) << 3 >> 3;
1767 handler.on_dest_decoded(Operand::RegOffset {
1768 base: 29,
1769 offset: (offset << 2) as i32 as u32,
1770 })?;
1771 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1772 } else {
1773 handler.on_opcode_decoded(Opcode::StoreMemd)?;
1774 let offset = (((word >> 3) & 0b111111) as i8) << 2 >> 2;
1775 handler.on_dest_decoded(Operand::RegOffset {
1776 base: 29,
1777 offset: (offset as i32 as u32) << 3,
1778 })?;
1779 handler.on_source_decoded(Operand::gprpair(subinstr_gprpair_b0(word))?)?;
1780 }
1781 } else if top < 0b11 {
1782 opcode_check!(word & 0b00100 == 0);
1783 let offset = ((word & 0b1111) as i8) << 4 >> 4;
1784
1785 if word & 0b0001 == 0 {
1786 handler.on_opcode_decoded(Opcode::StoreMemw)?;
1787 handler.on_dest_decoded(Operand::RegOffset {
1788 base: subinstr_gpr_b4(word),
1789 offset: (offset as i32 as u32) << 2,
1790 })?;
1791 handler.on_source_decoded(Operand::imm_u32((word as u32 >> 8) & 1))?;
1792 } else {
1793 handler.on_opcode_decoded(Opcode::StoreMemb)?;
1794 handler.on_dest_decoded(Operand::RegOffset {
1795 base: subinstr_gpr_b4(word),
1796 offset: offset as i32 as u32,
1797 })?;
1798 handler.on_source_decoded(Operand::imm_u32((word as u32 >> 8) & 1))?;
1799 }
1800 } else {
1801 opcode_check!(word & 0b1111 == 0);
1802 handler.on_opcode_decoded(Opcode::AllocFrame)?;
1803 let imm = (word >> 4) & 0b11111;
1804 handler.on_source_decoded(Operand::imm_u16((imm as u16) << 3))?;
1805 }
1806
1807 Ok(())
1808}
1809
1810fn subinstr_a<
1811 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1812 H: DecodeHandler<T>,
1813>(handler: &mut H, word: u16, extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
1814 let upper = word >> 8;
1823
1824 let top = upper >> 3;
1825
1826 if top == 0b00 {
1827 handler.on_opcode_decoded(Opcode::Add)?;
1829 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1830 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1831 let imm = (word >> 4) & 0b1111111;
1832 handler.on_source_decoded(Operand::immext(imm as u32, extender, |imm| {
1833 Ok(Operand::imm_i8((imm as i8) << 1 >> 1))
1834 })?)?;
1835 } else if top == 0b01 {
1836 let imm = (word >> 4) & 0b111111;
1839 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1840
1841 if upper & 0b00100 == 0 {
1842 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
1844 handler.on_source_decoded(Operand::immext(imm as u32, extender, |imm| {
1845 Ok(Operand::imm_i8((imm as i8) << 2 >> 2))
1846 })?)?;
1847 } else {
1848 handler.on_opcode_decoded(Opcode::Add)?;
1850 handler.on_source_decoded(Operand::gpr(29))?;
1851 handler.on_source_decoded(Operand::imm_i8((imm as i8) << 2 >> 2))?;
1852 }
1853 } else if top == 0b10 {
1854 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1856 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b4(word)))?;
1857
1858 let op = (word >> 8) & 0b111;
1859 match op {
1860 0b000 => {
1861 handler.on_opcode_decoded(Opcode::TransferRegister)?;
1862 }
1863 0b001 => {
1864 handler.on_opcode_decoded(Opcode::Add)?;
1865 handler.on_source_decoded(Operand::imm_i8(1))?;
1866 }
1867 0b010 => {
1868 handler.on_opcode_decoded(Opcode::And)?;
1869 handler.on_source_decoded(Operand::imm_i8(1))?;
1870 }
1871 0b011 => {
1872 handler.on_opcode_decoded(Opcode::Add)?;
1873 handler.on_source_decoded(Operand::imm_i8(-1))?;
1874 }
1875 0b100 => {
1876 handler.on_opcode_decoded(Opcode::Sxth)?;
1877 }
1878 0b101 => {
1879 handler.on_opcode_decoded(Opcode::Sxtb)?;
1880 }
1881 0b110 => {
1882 handler.on_opcode_decoded(Opcode::Zxth)?;
1883 }
1884 _ => {
1885 handler.on_opcode_decoded(Opcode::Zxtb)?;
1886 }
1887 }
1888 } else {
1889 let rest = upper & 0b111;
1891 match rest {
1892 0b000 => {
1893 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1894 handler.on_opcode_decoded(Opcode::Add)?;
1895 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1896 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b4(word)))?;
1897 }
1898 0b001 => {
1899 handler.on_dest_decoded(Operand::pred(0))?;
1900 handler.on_opcode_decoded(Opcode::CmpEq)?;
1901 handler.on_source_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1902 let imm = ((word & 0b1111) as i8) << 4 >> 4;
1903 handler.on_source_decoded(Operand::imm_i8(imm))?;
1904 }
1905 0b010 => {
1906 handler.on_dest_decoded(Operand::gpr(subinstr_gpr_b0(word)))?;
1907 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
1908 if (word >> 6) & 1 == 0 {
1909 handler.on_source_decoded(Operand::imm_i8(-1))?;
1910 } else {
1911 let negated = word & 0b01 != 0;
1912 let dotnew = word & 0b10 == 0;
1915 handler.inst_predicated(0 as u8, negated, dotnew)?;
1916 handler.on_source_decoded(Operand::imm_i8(0))?;
1917 }
1918 }
1919 0b100 => {
1920 opcode_check!(word & 0b10000000 == 0);
1921 handler.on_dest_decoded(Operand::gprpair(subinstr_gprpair_b0(word))?)?;
1922 handler.on_opcode_decoded(Opcode::Combine)?;
1923 handler.on_source_decoded(Operand::imm_u8((word >> 3) as u8 & 0b11))?;
1924 handler.on_source_decoded(Operand::imm_u8((word >> 5) as u8 & 0b11))?;
1925 }
1926 0b101 => {
1927 handler.on_dest_decoded(Operand::gprpair(subinstr_gprpair_b0(word))?)?;
1928 handler.on_opcode_decoded(Opcode::Combine)?;
1929 let source_reg = Operand::gpr(subinstr_gpr_b4(word));
1930 if word & 0b1000 == 0 {
1931 handler.on_source_decoded(Operand::imm_u8(0))?;
1932 handler.on_source_decoded(source_reg)?;
1933 } else {
1934 handler.on_source_decoded(source_reg)?;
1935 handler.on_source_decoded(Operand::imm_u8(0))?;
1936 }
1937 }
1938 _ => {
1939 opcode_check!(false);
1940 }
1941 }
1942 }
1943
1944 Ok(())
1945}
1946
1947fn decode_packet<
1948 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
1949 H: DecodeHandler<T>,
1950>(decoder: &<Hexagon as Arch>::Decoder, handler: &mut H, words: &mut T) -> Result<(), <Hexagon as Arch>::DecodeError> {
1951 handler.on_decode_start();
1952
1953 let mut current_word = 0;
1954
1955 let mut loop_bits: u8 = 0b0000;
1965
1966 let mut extender: Option<u32> = None;
1976
1977 let mut end = false;
1979
1980 while !end {
1981 if current_word >= 4 {
1982 return Err(DecodeError::InvalidOpcode);
1983 }
1984
1985 let inst: u32 = handler.read_inst_word(words)?;
1986
1987 let parse = (inst >> 14) & 0b11;
1991
1992 if current_word == 0 {
1993 loop_bits |= parse as u8;
1994 } else if current_word == 1 {
1995 loop_bits |= (parse as u8) << 2;
1996 }
1997
1998 match parse {
2003 0b00 => {
2004 let iclass_lo = (inst >> 13) & 0b1;
2015 let iclass_hi = (inst >> 29) & 0b111;
2016 let iclass = iclass_lo | (iclass_hi << 1);
2017
2018 let subinstr_low = inst & 0x1fff;
2019 let subinstr_high = (inst >> 16) & 0x1fff;
2020
2021 struct DuplexParse<
2022 'a, T, H,
2023 > {
2024 handler: &'a mut H,
2025 _phantom: std::marker::PhantomData<T>,
2026 extender: &'a mut Option<u32>,
2027 subinstr_low: u16,
2028 subinstr_high: u16,
2029 }
2030
2031 impl<
2032 'a,
2033 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
2034 H: DecodeHandler<T>
2035 > DuplexParse<'a, T, H> {
2036 fn parse(
2037 self,
2038 parse_lo: fn(&mut H, u16, &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError>,
2039 parse_hi: fn(&mut H, u16, &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError>,
2040 ) -> Result<(), yaxpeax_arch::StandardDecodeError> {
2041 self.handler.start_instruction()?;
2042 parse_lo(self.handler, self.subinstr_low, self.extender)?;
2043 self.handler.end_instruction()?;
2044 self.handler.start_instruction()?;
2045 parse_hi(self.handler, self.subinstr_high, self.extender)?;
2046 self.handler.end_instruction()?;
2047 Ok(())
2048 }
2049 }
2050
2051 let ctx = DuplexParse {
2052 handler,
2053 _phantom: std::marker::PhantomData,
2054 extender: &mut extender,
2055 subinstr_low: subinstr_low as u16,
2056 subinstr_high: subinstr_high as u16,
2057 };
2058
2059 match iclass {
2060 0b0000 => {
2061 ctx.parse(subinstr_l1, subinstr_l1)?;
2062 },
2063 0b0001 => {
2064 ctx.parse(subinstr_l2, subinstr_l1)?;
2065 },
2066 0b0010 => {
2067 ctx.parse(subinstr_l2, subinstr_l2)?;
2068 },
2069 0b0011 => {
2070 ctx.parse(subinstr_a, subinstr_a)?;
2071 },
2072 0b0100 => {
2073 ctx.parse(subinstr_l1, subinstr_a)?;
2074 },
2075 0b0101 => {
2076 ctx.parse(subinstr_l2, subinstr_a)?;
2077 },
2078 0b0110 => {
2079 ctx.parse(subinstr_s1, subinstr_a)?;
2080 },
2081 0b0111 => {
2082 ctx.parse(subinstr_s2, subinstr_a)?;
2083 },
2084 0b1000 => {
2085 ctx.parse(subinstr_s1, subinstr_l1)?;
2086 },
2087 0b1001 => {
2088 ctx.parse(subinstr_s1, subinstr_l2)?;
2089 },
2090 0b1010 => {
2091 ctx.parse(subinstr_s1, subinstr_s1)?;
2092 },
2093 0b1011 => {
2094 ctx.parse(subinstr_s2, subinstr_s1)?;
2095 },
2096 0b1100 => {
2097 ctx.parse(subinstr_s2, subinstr_l1)?;
2098 },
2099 0b1101 => {
2100 ctx.parse(subinstr_s2, subinstr_l2)?;
2101 },
2102 0b1110 => {
2103 ctx.parse(subinstr_s2, subinstr_s2)?;
2104 },
2105 _ => {
2106 opcode_check!(false);
2108 }
2109 }
2110
2111 handler.on_decode_end();
2114
2115 return Ok(());
2116 }
2117 0b01 | 0b10 => { }
2118 0b11 => {
2119 end = true;
2120
2121 if loop_bits & 0b0111 == 0b0110 {
2122 handler.on_loop_end(0);
2123 } else if loop_bits == 0b1001 {
2124 handler.on_loop_end(1);
2125 } else if loop_bits == 0b1010 {
2126 handler.on_loop_end(0);
2127 handler.on_loop_end(1);
2128 }
2129 }
2130 _ => {
2131 unreachable!();
2132 }
2133 }
2134
2135 let iclass = (inst >> 28) & 0b1111;
2136
2137 if iclass == 0b0000 {
2138 extender = Some((inst & 0x3fff) | ((inst >> 2) & 0x3ffc000));
2139 } else {
2140 handler.start_instruction()?;
2141 decode_instruction(decoder, handler, inst, &mut extender)?;
2142 if extender.is_some() {
2152 return Err(DecodeError::InvalidOpcode);
2154 }
2155 handler.end_instruction()?;
2156 }
2157
2158 current_word += 1;
2159 }
2160
2161 opcode_check!(extender.is_none());
2162
2163 handler.on_decode_end();
2164
2165 Ok(())
2166}
2167
2168fn decode_instruction<
2169 T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word>,
2170 H: DecodeHandler<T>,
2171>(_decoder: &<Hexagon as Arch>::Decoder, handler: &mut H, inst: u32, extender: &mut Option<u32>) -> Result<(), <Hexagon as Arch>::DecodeError> {
2172 let iclass = (inst >> 28) & 0b1111;
2173
2174 use Opcode::*;
2175
2176 let reg_type = (inst >> 24) & 0b1111;
2179 let min_op = (inst >> 21) & 0b111;
2180
2181 match iclass {
2182 0b0001 => {
2183 opcode_check!((inst >> 27) & 1 == 0);
2186
2187 let opbits = (inst >> 22) & 0b11111;
2188 let ssss = (inst >> 16) & 0b1111;
2189 let dddd = (inst >> 8) & 0b1111;
2190 let i_hi = (inst >> 20) & 0b11;
2191 let i_lo = (inst >> 1) & 0b111_1111;
2192 let i9 = ((i_hi << 7) | i_lo) as i32;
2193 let i9 = i9 << 23 >> 23;
2194
2195 if opbits < 0b11000 {
2196 opcode_check!(opbits <= 0b10110);
2198
2199 handler.on_dest_decoded(Operand::PCRel32 { rel: i9 << 2 })?;
2200 handler.on_source_decoded(Operand::gpr_4b(ssss as u8))?;
2201
2202 let hint_taken = (inst >> 13) & 1 == 1;
2207 handler.branch_hint(hint_taken)?;
2208
2209 let negated = opbits & 1 == 1;
2210
2211 static HIGH_OPS: [Option<Opcode>; 4] = [
2212 Some(CmpEqJump), Some(CmpGtJump),
2213 Some(CmpGtuJump), None,
2214 ];
2215
2216 if opbits < 0b10000 {
2217 let p = (opbits >> 3) & 1;
2219 handler.inst_predicated(p as u8, negated, true)?;
2220
2221 if let Some(opc) = HIGH_OPS[((opbits as usize) >> 1) & 0b11] {
2222 handler.on_opcode_decoded(opc)?;
2223 let lllll = (inst >> 8) & 0b11111;
2224 handler.on_source_decoded(Operand::imm_u32(lllll))?;
2225 } else {
2226 const LOW_OPS: [Option<Opcode>; 4] = [
2227 Some(CmpEqJump), Some(CmpGtJump),
2228 None, Some(TestClrJump),
2229 ];
2230 let low_opbits = (inst as usize >> 8) & 0b11;
2231 handler.on_opcode_decoded(decode_opcode!(LOW_OPS[low_opbits]))?;
2232 if low_opbits == 0b11 {
2233 handler.on_source_decoded(Operand::imm_u8(0))?;
2234 } else {
2235 handler.on_source_decoded(Operand::imm_i32(-1))?;
2236 }
2237 }
2238 } else {
2239 let p = (inst >> 12) & 1;
2241 handler.inst_predicated(p as u8, negated, true)?;
2242 let tttt = inst >> 8 & 0b1111;
2243 handler.on_opcode_decoded(decode_opcode!(HIGH_OPS[((opbits as usize) >> 1) & 0b11]))?;
2244 handler.on_source_decoded(Operand::gpr_4b(tttt as u8))?;
2245 }
2246 } else {
2247 handler.on_dest_decoded(Operand::PCRel32 { rel: i9 << 2 })?;
2248 if opbits < 0b11100 {
2249 let llllll = (inst >> 8) & 0b11_1111;
2250 handler.on_opcode_decoded(Opcode::TransferImmediateJump)?;
2252 handler.on_source_decoded(Operand::imm_u32(llllll))?;
2253 handler.on_dest_decoded(Operand::gpr_4b(ssss as u8))?;
2254 } else {
2255 handler.on_opcode_decoded(Opcode::TransferRegisterJump)?;
2256 handler.on_source_decoded(Operand::gpr_4b(ssss as u8))?;
2257 handler.on_dest_decoded(Operand::gpr_4b(dddd as u8))?;
2258 }
2259 }
2260 }
2261 0b0010 => {
2262 opcode_check!((inst >> 27) & 1 == 0);
2265
2266 let hint_taken = (inst >> 13) & 1 == 1;
2267 let op = (inst >> 22) & 0b11111;
2268
2269 let r_lo = (inst >> 1) & 0b111_1111;
2270 let r_hi = (inst >> 20) & 0b11;
2271 let r = (((r_hi << 7) | r_lo) << 2) as i16;
2272 let r = r << 5 >> 5;
2273
2274 let sss = ((inst >> 16) & 0b111) as u8;
2275
2276 handler.on_dest_decoded(Operand::PCRel32 {
2277 rel: r as i32
2278 })?;
2279
2280 handler.branch_hint(hint_taken)?;
2281
2282 if op < 0b10000 {
2283 let ttttt = reg_b8(inst);
2285
2286 if op < 0b0110 {
2287 handler.on_nv_register(sss)?;
2288 handler.on_source_decoded(Operand::gpr(ttttt))?;
2289 } else {
2290 handler.on_source_decoded(Operand::gpr(ttttt))?;
2291 handler.on_nv_register(sss)?;
2292 }
2293
2294 static OPS: [Option<Opcode>; 16] = [
2295 Some(JumpEq), Some(JumpNeq), Some(JumpGt), Some(JumpLe),
2296 Some(JumpGtu), Some(JumpLeu), Some(JumpGt), Some(JumpLe),
2297 Some(JumpGtu), Some(JumpLeu), None, None,
2298 None, None, None, None,
2299 ];
2300
2301 handler.on_opcode_decoded(decode_opcode!(OPS[op as usize]))?;
2302 } else {
2303 handler.on_nv_register(sss)?;
2304
2305 if op < 0b10110 {
2306 let lllll = reg_b8(inst);
2307 static OPS: &[Opcode; 6] = &[
2308 JumpEq, JumpNeq, JumpGt, JumpLe,
2309 JumpGtu, JumpLeu
2310 ];
2311
2312 handler.on_source_decoded(Operand::immext(lllll as u32, extender, |i| Ok(Operand::imm_u32(i)))?)?;
2313 handler.on_opcode_decoded(OPS[op as usize - 0b10000])?;
2314 } else if op < 0b11000 {
2315 let opc = if op == 0b10110 {
2316 JumpBitSet
2317 } else {
2318 JumpBitClear
2319 };
2320 handler.on_source_decoded(Operand::imm_u32(0))?;
2321 handler.on_opcode_decoded(opc)?;
2322 } else if op < 0b11100 {
2323 static OPS: &[Opcode; 4] = &[
2324 JumpEq, JumpNeq, JumpGt, JumpLe,
2325 ];
2326 handler.on_source_decoded(Operand::imm_i32(-1))?;
2327 handler.on_opcode_decoded(OPS[op as usize - 0b11000])?;
2328 } else {
2329 return Err(DecodeError::InvalidOpcode);
2330 }
2331 }
2332 }
2333 0b0011 => {
2334 let upper = reg_type >> 2;
2335 match upper {
2336 0b00 => {
2337 let nn = (inst >> 24) & 0b11;
2340
2341 let negated = nn & 1 == 1;
2342 let pred_new = nn >> 1 == 1;
2343
2344 let ddddd = reg_b0(inst);
2345 let vv = ((inst >> 5) & 0b11) as u8;
2346 let i_lo = (inst >> 7) & 0b1;
2347 let ttttt = reg_b8(inst);
2348 let i_hi = ((inst >> 13) & 0b1) << 1;
2349 let ii = (i_lo | i_hi) as u8;
2350 let sssss = reg_b16(inst);
2351 let op = (inst >> 21) & 0b111;
2352
2353 handler.inst_predicated(vv, negated, pred_new)?;
2354
2355 handler.on_source_decoded(Operand::RegShiftedReg { base: sssss, index: ttttt, shift: ii })?;
2356 if op == 0b110 {
2357 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
2358 } else {
2359 handler.on_dest_decoded(Operand::gpr(ddddd))?;
2360 }
2361
2362 use Opcode::*;
2363 static OPCODES: [Option<Opcode>; 8] = [
2364 Some(LoadMemb), Some(LoadMemub), Some(LoadMemh), Some(LoadMemuh),
2365 Some(LoadMemw), None, Some(LoadMemd), None,
2366 ];
2367 handler.on_opcode_decoded(OPCODES[op as usize].ok_or(DecodeError::InvalidOpcode)?)?;
2368 }
2369 0b01 => {
2370 let nn = (inst >> 24) & 0b11;
2373
2374 let negated = nn & 1 == 1;
2375 let pred_new = nn >> 1 == 1;
2376
2377 let ttttt = reg_b0(inst);
2378 let vv = ((inst >> 5) & 0b11) as u8;
2379 let i_lo = (inst >> 7) & 0b1;
2380 let uuuuu = reg_b8(inst);
2381 let i_hi = ((inst >> 13) & 0b1) << 1;
2382 let ii = (i_lo | i_hi) as u8;
2383 let sssss = reg_b16(inst);
2384 let op = (inst >> 21) & 0b111;
2385
2386 handler.inst_predicated(vv, negated, pred_new)?;
2387 handler.on_dest_decoded(Operand::RegShiftedReg { base: sssss, index: uuuuu, shift: ii })?;
2388
2389 if op == 0b101 {
2390 let op = (inst >> 3) & 0b11;
2392 let ttt = inst & 0b111;
2393 static OPCODES: [Option<Opcode>; 4] = [
2394 Some(StoreMemb), Some(StoreMemh),
2395 Some(StoreMemw), None,
2396 ];
2397 handler.on_opcode_decoded(decode_opcode!(OPCODES[op as usize]))?;
2398 handler.on_nv_register(ttt as u8)?;
2399 } else {
2400 static OPCODES: [Option<Opcode>; 8] = [
2401 Some(StoreMemb), None, Some(StoreMemh), Some(StoreMemh),
2402 Some(StoreMemw), None, Some(StoreMemd), None,
2403 ];
2404 handler.on_opcode_decoded(decode_opcode!(OPCODES[op as usize]))?;
2405 if op == 0b011 {
2406 handler.on_source_decoded(Operand::GprHigh { reg: ttttt })?;
2407 } else if op == 0b110 {
2408 handler.on_source_decoded(Operand::gpr(ttttt))?;
2409 } else {
2410 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
2411 }
2412 }
2413 }
2414 0b10 => {
2415 let sssss = reg_b16(inst);
2418
2419 let predicate_store = (inst >> 25) & 0b1 == 0;
2420 if predicate_store {
2421 let nn = (inst >> 23) & 0b11;
2422
2423 let l_lo = reg_b0(inst);
2424 let vv = ((inst >> 5) & 0b11) as u8;
2425 let iiiiii = (inst >> 7) & 0b11_1111;
2426 let l_hi = (((inst >> 13) & 0b1) << 5) as u8;
2427 let llllll = (l_lo | l_hi) as u32;
2428 let op = (inst >> 21) & 0b11;
2429
2430 let negated = nn & 1 == 1;
2431 let pred_new = nn >> 1 == 1;
2432
2433 handler.inst_predicated(vv, negated, pred_new)?;
2434
2435 let offset = iiiiii;
2436 handler.on_dest_decoded(Operand::RegOffset { base: sssss, offset })?;
2437
2438 match op {
2439 0b00 => {
2440 handler.on_opcode_decoded(Opcode::StoreMemb)?;
2441
2442 let imm = Operand::with_extension(llllll, extender,
2443 |imm| Ok(Operand::imm_u32(imm)),
2444 |imm| Ok(Operand::imm_i8((imm as i8) << 2 >> 2)),
2445 )?;
2446 handler.on_source_decoded(imm)?;
2447 }
2448 0b01 => {
2449 handler.on_opcode_decoded(Opcode::StoreMemh)?;
2450
2451 let imm = Operand::with_extension(llllll, extender,
2452 |imm| Ok(Operand::imm_u32(imm)),
2453 |imm| Ok(Operand::imm_i16((imm as i16) << 10 >> 10)),
2454 )?;
2455 handler.on_source_decoded(imm)?;
2456 }
2457 0b10 => {
2458 handler.on_opcode_decoded(Opcode::StoreMemw)?;
2459 let imm = (llllll as i32) << 26 >> 26;
2460 handler.on_source_decoded(Operand::imm_i32(imm))?;
2461
2462 let imm = Operand::with_extension(llllll, extender,
2463 |imm| Ok(Operand::imm_u32(imm)),
2464 |imm| Ok(Operand::imm_i32((imm as i32) << 26 >> 26)),
2465 )?;
2466 handler.on_source_decoded(imm)?;
2467 }
2468 _ => {
2469 return Err(DecodeError::InvalidOpcode);
2470 }
2471 }
2472 } else {
2473 let store = (inst >> 24) & 1 == 1;
2475
2476 let reg_low = reg_b0(inst);
2477 let reg_mid = reg_b8(inst);
2478 let sssss = reg_b16(inst);
2479
2480 let i_lo = ((inst >> 7) & 1) as u8;
2481 let i_hi = (((inst >> 13) & 0b1) << 1) as u8;
2482 let ii = i_hi | i_lo;
2483
2484 if store {
2485 handler.on_dest_decoded(Operand::RegShiftedReg { base: sssss, index: reg_mid, shift: ii })?;
2487 match min_op {
2488 0b010 => {
2489 handler.on_opcode_decoded(Opcode::StoreMemh)?;
2490 handler.on_source_decoded(Operand::gpr(reg_low))?;
2491 },
2492 0b011 => {
2493 handler.on_opcode_decoded(Opcode::StoreMemh)?;
2494 handler.on_source_decoded(Operand::GprHigh { reg: reg_low})?;
2495 },
2496 0b100 => {
2497 handler.on_opcode_decoded(Opcode::StoreMemb)?;
2498 handler.on_source_decoded(Operand::gprpair(reg_low)?)?;
2499 }
2500 0b101 => {
2501 let op = (inst >> 3) & 0b11;
2503 let ttt = inst & 0b111;
2504 static OPCODES: [Option<Opcode>; 4] = [
2505 Some(StoreMemb), Some(StoreMemh),
2506 Some(StoreMemw), None,
2507 ];
2508 handler.on_opcode_decoded(decode_opcode!(OPCODES[op as usize]))?;
2509 handler.on_nv_register(ttt as u8)?;
2510 },
2511 0b0110 => {
2512 handler.on_opcode_decoded(Opcode::StoreMemd)?;
2513 handler.on_source_decoded(Operand::gprpair(reg_low)?)?;
2514 }
2515 _ => {
2516 return Err(DecodeError::InvalidOpcode);
2517 }
2518 }
2519 } else {
2520 static OPCODES: [Option<Opcode>; 8] = [
2522 Some(LoadMemb), Some(LoadMemub), Some(LoadMemh), Some(LoadMemh),
2523 Some(LoadMemw), None, Some(LoadMemd), None,
2524 ];
2525
2526 handler.on_opcode_decoded(decode_opcode!(OPCODES[min_op as usize]))?;
2527 handler.on_source_decoded(Operand::RegShiftedReg { base: sssss, index: reg_mid, shift: ii })?;
2528 if min_op == 0b110 {
2529 handler.on_dest_decoded(Operand::gprpair(reg_low)?)?;
2530 } else {
2531 handler.on_dest_decoded(Operand::gpr(reg_low))?;
2532 }
2533 }
2534 }
2535 }
2536 _other => {
2537 let opc_bits = (inst >> 21) & 0b11111;
2541 let opc_upper = opc_bits >> 3;
2542 let opc_lower = opc_bits & 0b11;
2543 let uuuuuu = (inst >> 7) & 0b111111;
2544 let sssss = (inst >> 16) & 0b11111;
2545
2546 match opc_upper {
2547 0b00 |
2548 0b01 => {
2549 let i7 = inst & 0b111_1111;
2550 let i_hi = ((inst >> 13) & 0b1) << 7;
2551 let i = i_hi | i7;
2552
2553 handler.on_opcode_decoded(match opc_lower {
2554 0b00 => {
2555 Opcode::StoreMemb
2556 }
2557 0b01 => {
2558 Opcode::StoreMemh
2559 }
2560 0b10 => {
2561 Opcode::StoreMemw
2562 }
2563 _ => { return Err(DecodeError::InvalidOpcode); }
2564 })?;
2565 handler.on_source_decoded(Operand::imm_i8(i as i8))?;
2566 handler.on_dest_decoded(Operand::RegOffset {
2567 base: sssss as u8,
2568 offset: (uuuuuu as u32) << opc_lower,
2569 })?;
2570 },
2571 0b10 => {
2572 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
2573 let ttttt = inst & 0b11111;
2574 let assign_mode = (inst >> 5) & 0b11;
2575
2576 handler.on_opcode_decoded(match opc_lower {
2577 0b00 => {
2578 Opcode::StoreMemb
2579 }
2580 0b01 => {
2581 Opcode::StoreMemh
2582 }
2583 0b10 => {
2584 Opcode::StoreMemw
2585 }
2586 _ => { return Err(DecodeError::InvalidOpcode); }
2587 })?;
2588 handler.assign_mode(match assign_mode {
2589 0b00 => AssignMode::AddAssign,
2590 0b01 => AssignMode::SubAssign,
2591 0b10 => AssignMode::AndAssign,
2592 _ => AssignMode::OrAssign,
2593 })?;
2594 handler.on_source_decoded(Operand::gpr(ttttt as u8))?;
2595 handler.on_dest_decoded(Operand::RegOffset {
2596 base: sssss as u8,
2597 offset: (uuuuuu as u32) << opc_lower,
2598 })?;
2599 },
2600 _ => {
2601 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
2602 let ttttt = inst & 0b11111;
2603 let assign_mode = (inst >> 5) & 0b11;
2604
2605 handler.on_opcode_decoded(match opc_lower {
2606 0b00 => {
2607 Opcode::StoreMemb
2608 }
2609 0b01 => {
2610 Opcode::StoreMemh
2611 }
2612 0b10 => {
2613 Opcode::StoreMemw
2614 }
2615 _ => { return Err(DecodeError::InvalidOpcode); }
2616 })?;
2617 handler.assign_mode(match assign_mode {
2618 0b00 => AssignMode::AddAssign,
2619 0b01 => AssignMode::SubAssign,
2620 0b10 => AssignMode::ClrBit,
2621 _ => AssignMode::SetBit,
2622 })?;
2623 handler.on_source_decoded(Operand::imm_u8(ttttt as u8))?;
2624 handler.on_dest_decoded(Operand::RegOffset {
2625 base: sssss as u8,
2626 offset: (uuuuuu as u32) << opc_lower,
2627 })?;
2628 }
2629 }
2630 }
2631 }
2632 }
2633 0b0100 => {
2634 let predicated = (inst >> 27) & 1 == 0;
2637 let store = (inst >> 24) & 1 == 0;
2638
2639 if predicated {
2640 let dotnew = (inst >> 26) & 0b1 == 1;
2641 let negated = (inst >> 25) & 0b1 == 1;
2642
2643 let opbits = (inst >> 21) & 0b111;
2644 let sssss = reg_b16(inst);
2645
2646 if store {
2647 let pred_reg = inst & 0b11;
2648 handler.inst_predicated(pred_reg as u8, negated, dotnew)?;
2649
2650 let srcreg = reg_b8(inst);
2651 let i5 = (inst >> 3) & 0b11111;
2652 let i = ((inst >> 13) & 1) << 5;
2653 let iiiiii = i | i5;
2654
2655 decode_store_ops(handler, opbits as u8, srcreg as u8, |shamt| {
2656 Operand::with_extension(
2657 iiiiii, extender,
2658 |offset| Ok(Operand::RegOffset {
2659 base: sssss as u8,
2660 offset,
2661 }),
2662 |offset| Ok(Operand::RegOffset {
2663 base: sssss as u8,
2664 offset: offset << shamt,
2665 }),
2666 )
2667 })?;
2668 } else {
2669 let pred_reg = (inst >> 11) & 0b11;
2670 handler.inst_predicated(pred_reg as u8, negated, dotnew)?;
2671
2672 let dstreg = reg_b0(inst);
2673 let iiiiii = (inst >> 5) & 0b111111;
2674
2675 decode_load_ops(handler, opbits as u8, dstreg as u8, |shamt| {
2676 Operand::with_extension(
2677 iiiiii, extender,
2678 |offset| Ok(Operand::RegOffset {
2679 base: sssss as u8,
2680 offset,
2681 }),
2682 |offset| Ok(Operand::RegOffset {
2683 base: sssss as u8,
2684 offset: offset << shamt,
2685 }),
2686 )
2687 })?;
2688 }
2689 } else {
2690 let i14 = (inst >> 25) & 0b11;
2691 let i9 = (inst >> 16) & 0b11111;
2692 let i_8 = (inst >> 13) & 0b1;
2693
2694 let opbits = ((inst >> 21) & 0b111) as u8;
2695
2696 if store {
2697 let i_lo = inst & 0b1111_1111;
2698 let i = (i14 << 14) | (i9 << 9) | (i_8 << 8) | i_lo;
2699 let ttttt = reg_b8(inst);
2700
2701 decode_store_ops(handler, opbits, ttttt, |shamt| {
2702 Operand::with_extension(
2703 i, extender,
2704 |imm| Ok(Operand::Immext { imm }),
2705 |offset| Ok(Operand::GpOffset {
2706 offset: offset << shamt,
2707 }),
2708 )
2709 })?;
2710 } else {
2711 let i_lo = (inst >> 5) & 0b1111_1111;
2712 let i = (i14 << 14) | (i9 << 9) | (i_8 << 8) | i_lo;
2713 let ddddd = reg_b0(inst);
2714
2715 decode_load_ops(handler, opbits, ddddd, |shamt| {
2716 Operand::with_extension(
2717 i, extender,
2718 |imm| Ok(Operand::Immext { imm }),
2719 |offset| Ok(Operand::GpOffset {
2720 offset: offset << shamt,
2721 }),
2722 )
2723 })?;
2724 }
2725 }
2726 },
2727 0b0101 => {
2728 let majop = (inst >> 25) & 0b111;
2729 match majop {
2730 0b000 => {
2731 let op = (inst >> 21) & 0b1111;
2734 let sssss = reg_b16(inst);
2735 handler.on_dest_decoded(Operand::gpr(sssss))?;
2736
2737 if op >= 0b1000 {
2738 opcode_check!(op < 0b1010);
2740 handler.on_opcode_decoded(Opcode::Callr)?;
2741 let negated = op & 1 == 1;
2742 let uu = (inst >> 8) & 0b11;
2743 handler.inst_predicated(uu as u8, negated, false)?;
2744 } else {
2745 opcode_check!(op == 0b101 || op == 0b110);
2747 if op == 0b101 {
2748 handler.on_opcode_decoded(Opcode::Callr)?;
2749 } else {
2750 handler.on_opcode_decoded(Opcode::Callrh)?;
2751 }
2752 }
2753 },
2754 0b001 => {
2755 let op = (inst >> 21) & 0b1111;
2758 let sssss = reg_b16(inst);
2759
2760 if op >= 0b1000 {
2761 opcode_check!(op == 0b0100 || op == 0b0101 || op == 0b0110 || op == 0b1010 || op == 0b1011);
2763 handler.on_opcode_decoded(Opcode::Jumpr)?;
2764 handler.on_dest_decoded(Operand::gpr(sssss))?;
2765 let negated = op & 1 == 1;
2766 let dotnew = (inst >> 11) & 1 == 1;
2767 let hint_taken = (inst >> 12) & 1 == 1;
2768 let uu = (inst >> 8) & 0b11;
2769 handler.inst_predicated(uu as u8, negated, dotnew)?;
2770 handler.branch_hint(hint_taken)?;
2771 } else {
2772 opcode_check!(op == 0b100 || op == 0b101 || op == 0b110);
2774 if op == 0b100 {
2775 handler.on_opcode_decoded(Opcode::Jumpr)?;
2776 handler.on_dest_decoded(Operand::gpr(sssss))?;
2777 } else if op == 0b101 {
2778 handler.on_opcode_decoded(Opcode::Hintjr)?;
2779 handler.on_source_decoded(Operand::gpr(sssss))?;
2780 } else {
2781 handler.on_opcode_decoded(Opcode::Jumprh)?;
2782 handler.on_dest_decoded(Operand::gpr(sssss))?;
2783 }
2784 }
2785 },
2786 0b010 => {
2787 let minbits = (inst >> 22) & 0b111;
2789 let u_low = (inst >> 2) & 0b111;
2790 let u_mid = (inst >> 8) & 0b11111;
2791 let u_8 = (u_mid << 3) | u_low;
2792
2793 if minbits == 0b000 {
2794 handler.on_opcode_decoded(Opcode::Trap0)?;
2795 handler.on_source_decoded(Operand::imm_u8(u_8 as u8))?;
2796 } else if minbits == 0b001 {
2797 handler.on_opcode_decoded(Opcode::Pause)?;
2798 let u_high = (inst >> 16) & 0b11;
2799 let u_10 = (u_high << 8) | u_8;
2800 handler.on_source_decoded(Operand::imm_u16(u_10 as u16))?;
2801 } else if minbits == 0b010 {
2802 handler.on_opcode_decoded(Opcode::Trap1)?;
2803 let xxxxx = reg_b16(inst);
2804 handler.on_source_decoded(Operand::gpr(xxxxx))?;
2805 handler.on_source_decoded(Operand::imm_u8(u_8 as u8))?;
2806 } else if minbits == 0b110 {
2807 opcode_check!(inst & (1 << 21) != 0);
2808 handler.on_opcode_decoded(Opcode::Icdatar)?;
2809 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
2810 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
2811 } else if minbits == 0b111 {
2812 if inst & (1 << 21) == 0 {
2813 handler.on_opcode_decoded(Opcode::Ictagw)?;
2814 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
2815 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
2816 } else {
2817 handler.on_opcode_decoded(Opcode::Ictagr)?;
2818 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
2819 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
2820 }
2821 } else {
2822 opcode_check!(false);
2823 }
2824 },
2825 0b011 => {
2826 let minbits = (inst >> 21) & 0b1111;
2828
2829 if minbits == 0b0110 {
2830 let op = (inst >> 11) & 0b111;
2831 if op == 0b000 {
2832 handler.on_opcode_decoded(Opcode::Icinva)?;
2833 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
2834 } else if op == 0b010 {
2835 handler.on_opcode_decoded(Opcode::IcKill)?;
2836 } else {
2837 opcode_check!(false);
2838 }
2839 } else if minbits == 0b0111 {
2840 handler.on_opcode_decoded(Opcode::Icinvidx)?;
2841 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
2842 } else if minbits == 0b1110 {
2843 handler.on_opcode_decoded(Opcode::Isync)?;
2844 opcode_check!(inst & 0x1f23ff == 0x000002);
2845 } else if minbits == 0b1111 {
2846 handler.on_opcode_decoded(Opcode::Unpause)?;
2847 opcode_check!(inst & 0x10e0 == 0x1000);
2848 } else {
2849 opcode_check!(false);
2850 }
2851 },
2852 0b100 => {
2853 handler.on_opcode_decoded(Opcode::Jump)?;
2856 let imm = ((inst >> 1) & 0x1fff) | ((inst >> 3) & 0xffe000);
2857 let imm = ((imm as i32) << 10) >> 10;
2858 handler.on_dest_decoded(
2859 Operand::with_extension(
2860 imm as u32, extender,
2861 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2862 |rel| Ok(Operand::PCRel32 { rel: (rel << 2) as i32 }),
2863 )?
2864 )?;
2865 },
2866 0b101 => {
2867 if inst & 0 != 0 {
2870 return Err(DecodeError::InvalidOpcode);
2872 }
2873 handler.on_opcode_decoded(Opcode::Call)?;
2874 let imm = ((inst >> 1) & 0x1fff) | ((inst >> 3) & 0xffe000);
2875 let imm = ((imm as i32) << 10) >> 10;
2876 handler.on_dest_decoded(
2877 Operand::with_extension(
2878 imm as u32, extender,
2879 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2880 |rel| Ok(Operand::PCRel32 { rel: (rel << 2) as i32 }),
2881 )?
2882 )?;
2883 },
2884 0b110 => {
2885 let negated = (inst >> 21) & 1 == 1;
2887 let dotnew = (inst >> 11) & 1 == 1;
2888 let uu = (inst >> 8) & 0b11;
2889 let hint_taken = (inst >> 11) == 1;
2890
2891 let i_lo = (inst >> 1) & 0x7f;
2892 let i_8 = (inst >> 13) & 1;
2893 let i_mid = (inst >> 16) & 0x1f;
2894 let i_hi = (inst >> 22) & 0b11;
2895 let i15 = i_lo | (i_8 << 7) | (i_mid << 8) | (i_hi << 13);
2896 let i15 = (i15 as i32) << 17 >> 17;
2897
2898 let is_call = (inst >> 24) & 1 == 1;
2899
2900 if is_call {
2901 handler.on_opcode_decoded(Opcode::Call)?;
2902 handler.inst_predicated(uu as u8, negated, false)?;
2903 opcode_check!(!dotnew);
2904 } else {
2905 handler.on_opcode_decoded(Opcode::Jump)?;
2908 handler.inst_predicated(uu as u8, negated, dotnew)?;
2909 handler.branch_hint(hint_taken)?;
2910 }
2911 handler.on_dest_decoded(
2912 Operand::with_extension(
2913 i15 as u32, extender,
2914 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2915 |rel| Ok(Operand::PCRel32 { rel: (rel << 2) as i32 }),
2916 )?
2917 )?;
2918 }
2919 0b111 => {
2920 return Err(DecodeError::InvalidOpcode);
2921 }
2922 _ => {
2923 opcode_check!(false);
2924 }
2925 }
2926 },
2927 0b0110 => {
2928 let opbits = (inst >> 21) & 0b1111111;
2929
2930 match opbits {
2931 0b0000000 => {
2932 let sssss = reg_b16(inst);
2933 let iiiii = reg_b8(inst);
2934 let ii = ((inst >> 3) & 0b11) as u8;
2935 let i7 = (iiiii << 2) | ii;
2936 let rel = ((i7 << 1) as i8 as i32) << 1;
2937
2938 handler.on_opcode_decoded(Opcode::Loop0)?;
2939 handler.on_source_decoded(
2940 Operand::with_extension(
2941 rel as u32, extender,
2942 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2943 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2944 )?
2945 )?;
2946 handler.on_source_decoded(Operand::gpr(sssss))?;
2947 }
2948 0b0000001 => {
2949 let sssss = reg_b16(inst);
2950 let iiiii = reg_b8(inst);
2951 let ii = ((inst >> 3) & 0b11) as u8;
2952 let i7 = (iiiii << 2) | ii;
2953 let rel = ((i7 << 1) as i8 as i32) << 1;
2954
2955 handler.on_opcode_decoded(Opcode::Loop1)?;
2956 handler.on_source_decoded(
2957 Operand::with_extension(
2958 rel as u32, extender,
2959 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2960 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2961 )?
2962 )?;
2963 handler.on_source_decoded(Operand::gpr(sssss))?;
2964 }
2965 0b0000010 | 0b0000011 => {
2966 return Err(DecodeError::InvalidOpcode);
2967 }
2968 0b0000101 => {
2969 let sssss = reg_b16(inst);
2970 let iiiii = reg_b8(inst);
2971 let ii = ((inst >> 3) & 0b11) as u8;
2972 let i7 = (iiiii << 2) | ii;
2973 let rel = ((i7 << 1) as i8 as i32) << 1;
2974
2975 handler.on_opcode_decoded(Opcode::Sp1Loop0)?;
2976 handler.on_source_decoded(
2977 Operand::with_extension(
2978 rel as u32, extender,
2979 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2980 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2981 )?
2982 )?;
2983 handler.on_source_decoded(Operand::gpr(sssss))?;
2984 handler.on_dest_decoded(Operand::pred(3))?;
2985 }
2986 0b0000110 => {
2987 let sssss = reg_b16(inst);
2988 let iiiii = reg_b8(inst);
2989 let ii = ((inst >> 3) & 0b11) as u8;
2990 let i7 = (iiiii << 2) | ii;
2991 let rel = ((i7 << 1) as i8 as i32) << 1;
2992
2993 handler.on_opcode_decoded(Opcode::Sp2Loop0)?;
2994 handler.on_source_decoded(
2995 Operand::with_extension(
2996 rel as u32, extender,
2997 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2998 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
2999 )?
3000 )?;
3001 handler.on_source_decoded(Operand::gpr(sssss))?;
3002 handler.on_dest_decoded(Operand::pred(3))?;
3003 }
3004 0b0000111 => {
3005 let sssss = reg_b16(inst);
3006 let iiiii = reg_b8(inst);
3007 let ii = ((inst >> 3) & 0b11) as u8;
3008 let i7 = (iiiii << 2) | ii;
3009 let rel = ((i7 << 1) as i8 as i32) << 1;
3010
3011 handler.on_opcode_decoded(Opcode::Sp3Loop0)?;
3012 handler.on_source_decoded(
3013 Operand::with_extension(
3014 rel as u32, extender,
3015 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
3016 |rel| Ok(Operand::PCRel32 { rel: rel as i32 }),
3017 )?
3018 )?;
3019 handler.on_source_decoded(Operand::gpr(sssss))?;
3020 handler.on_dest_decoded(Operand::pred(3))?;
3021 }
3022 0b0001000 | 0b0001001 => {
3023 let sssss = reg_b16(inst);
3024 let i11 = (inst >> 1) & 0b111_1111_1111;
3025 let i_mid = (inst >> 13) & 1;
3026 let i_hi = (inst >> 21) & 1;
3027 let i13 = i11 | (i_mid << 11) | (i_hi << 12);
3028 let rel = (i13 << 3) as i16 as i32 >> 1;
3029
3030 let taken = (inst >> 12) & 1 == 1;
3031 handler.branch_hint(taken)?;
3032 handler.on_opcode_decoded(Opcode::JumpRegNz)?;
3033 handler.on_source_decoded(Operand::gpr(sssss))?;
3034 handler.on_dest_decoded(Operand::PCRel32 { rel })?;
3035 }
3036 0b0001010 | 0b0001011 => {
3037 let sssss = reg_b16(inst);
3038 let i11 = (inst >> 1) & 0b111_1111_1111;
3039 let i_mid = (inst >> 13) & 1;
3040 let i_hi = (inst >> 21) & 1;
3041 let i13 = i11 | (i_mid << 11) | (i_hi << 12);
3042 let rel = (i13 << 3) as i16 as i32 >> 1;
3043
3044 let taken = (inst >> 12) & 1 == 1;
3045 handler.branch_hint(taken)?;
3046 handler.on_opcode_decoded(Opcode::JumpRegGez)?;
3047 handler.on_source_decoded(Operand::gpr(sssss))?;
3048 handler.on_dest_decoded(Operand::PCRel32 { rel })?;
3049 }
3050 0b0001100 | 0b0001101 => {
3051 let sssss = reg_b16(inst);
3052 let i11 = (inst >> 1) & 0b111_1111_1111;
3053 let i_mid = (inst >> 13) & 1;
3054 let i_hi = (inst >> 21) & 1;
3055 let i13 = i11 | (i_mid << 11) | (i_hi << 12);
3056 let rel = (i13 << 3) as i16 as i32 >> 1;
3057
3058 let taken = (inst >> 12) & 1 == 1;
3059 handler.branch_hint(taken)?;
3060 handler.on_opcode_decoded(Opcode::JumpRegZ)?;
3061 handler.on_source_decoded(Operand::gpr(sssss))?;
3062 handler.on_dest_decoded(Operand::PCRel32 { rel })?;
3063 }
3064 0b0001110 | 0b0001111 => {
3065 let sssss = reg_b16(inst);
3066 let i11 = (inst >> 1) & 0b111_1111_1111;
3067 let i_mid = (inst >> 13) & 1;
3068 let i_hi = (inst >> 21) & 1;
3069 let i13 = i11 | (i_mid << 11) | (i_hi << 12);
3070 let rel = (i13 << 3) as i16 as i32 >> 1;
3071
3072 let taken = (inst >> 12) & 1 == 1;
3073 handler.branch_hint(taken)?;
3074 handler.on_opcode_decoded(Opcode::JumpRegLez)?;
3075 handler.on_source_decoded(Operand::gpr(sssss))?;
3076 handler.on_dest_decoded(Operand::PCRel32 { rel })?;
3077 }
3078 0b0010001 => {
3079 let sssss = reg_b16(inst);
3080 let ddddd = reg_b0(inst);
3081 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3082 handler.on_source_decoded(Operand::gpr(sssss))?;
3083 handler.on_dest_decoded(Operand::cr(ddddd))?;
3084 }
3085 0b0010010 => {
3086 let opc = (inst >> 5) & 0b111;
3087 let sssss = reg_b16(inst);
3088 let ttttt = reg_b8(inst);
3089 match opc {
3090 0b000 => {
3091 handler.on_opcode_decoded(Opcode::Trace)?;
3092 handler.on_source_decoded(Operand::gpr(sssss))?;
3093 },
3094 0b001 => {
3095 handler.on_opcode_decoded(Opcode::Diag)?;
3096 handler.on_source_decoded(Operand::gpr(sssss))?;
3097 },
3098 0b010 => {
3099 handler.on_opcode_decoded(Opcode::Diag0)?;
3100 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3101 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
3102 },
3103 0b011 => {
3104 handler.on_opcode_decoded(Opcode::Diag1)?;
3105 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3106 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
3107 },
3108 _ => { return Err(DecodeError::InvalidOpcode); }
3109 };
3110 }
3111 0b0100000 => {
3112 static OPS: [Option<Opcode>; 8] = [
3116 Some(Opcode::Swi), Some(Opcode::Cswi), None, Some(Opcode::Ciad),
3117 None, None, None, None,
3118 ];
3119 handler.on_opcode_decoded(decode_opcode!(OPS[((inst >> 5) & 0b111) as usize]))?;
3120 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3121 }
3122 0b0100010 => {
3123 static OPS: [Option<Opcode>; 8] = [
3126 Some(Opcode::Wait), None, Some(Opcode::Resume), None,
3127 None, None, None, None,
3128 ];
3129 handler.on_opcode_decoded(decode_opcode!(OPS[((inst >> 5) & 0b111) as usize]))?;
3130 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3131 }
3132 0b0100011 => {
3133 static OPS: [Option<Opcode>; 8] = [
3137 Some(Opcode::Stop), Some(Opcode::Start), Some(Opcode::Nmi), None,
3138 None, None, None, None,
3139 ];
3140 handler.on_opcode_decoded(decode_opcode!(OPS[((inst >> 5) & 0b111) as usize]))?;
3141 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3142 }
3143 0b0100100 => {
3144 static OPS: [Option<Opcode>; 8] = [
3147 Some(Opcode::Setimask), None, None, Some(Opcode::Siad),
3148 None, None, None, None,
3149 ];
3150 let opc = (inst >> 5) & 0b111;
3151 handler.on_opcode_decoded(decode_opcode!(OPS[opc as usize]))?;
3152 if opc == 0b000 {
3153 handler.on_source_decoded(Operand::pred(reg_b0(inst) & 0b11))?;
3154 }
3155 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3156 }
3157 0b0101000 => {
3158 handler.on_opcode_decoded(Opcode::Crswap)?;
3159 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3160 handler.on_source_decoded(Operand::sr(0))?;
3161 }
3162 0b0101001 => {
3163 handler.on_opcode_decoded(Opcode::Crswap)?;
3164 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3165 handler.on_source_decoded(Operand::sr(1))?;
3166 }
3167 0b0110000 => {
3168 handler.on_opcode_decoded(Opcode::Getimask)?;
3169 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
3170 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3171 }
3172 0b0111000 => {
3173 let sssss = reg_b16(inst);
3175 let dddddd = inst & 0b11_1111;
3176 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3177 handler.on_dest_decoded(Operand::sr(dddddd as u8))?;
3178 handler.on_source_decoded(Operand::gpr(sssss))?;
3179 }
3180 0b1100001 => {
3182 static OPS: [Option<Opcode>; 8] = [
3186 Some(Opcode::Brkpt), Some(Opcode::TlbLock), None, Some(Opcode::K0Lock),
3187 None, None, None, None,
3188 ];
3189 handler.on_opcode_decoded(decode_opcode!(OPS[((inst >> 5) & 0b111) as usize]))?;
3190 }
3191 0b1101000 => {
3192 let sssss = reg_b16(inst);
3194 let ddddddd = inst & 0b111_1111;
3195 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3196 handler.on_dest_decoded(Operand::srpair(ddddddd as u8)?)?;
3197 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3198 }
3199 0b1101100 => {
3200 operand_check!(reg_b0(inst) == 0);
3201 handler.on_opcode_decoded(Opcode::Crswap)?;
3202 handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
3203 handler.on_source_decoded(Operand::srpair(0)?)?;
3204 }
3205 0b1110011 => {
3206 handler.on_opcode_decoded(Opcode::Iassignr)?;
3207 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
3208 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
3209 }
3210 0b1110100 | 0b1110101 |
3211 0b1110110 | 0b1110111 => {
3212 let sssss = reg_b0(inst);
3214 let dddddd = (inst >> 16) & 0b11_1111;
3215 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3216 handler.on_source_decoded(Operand::sr(dddddd as u8))?;
3217 handler.on_dest_decoded(Operand::gpr(sssss))?;
3218 }
3219 0b1111000 | 0b1111001 |
3220 0b1111010 | 0b1111011 => {
3221 let sssss = reg_b0(inst);
3223 let ddddddd = (inst >> 16) & 0b111_1111;
3224 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3225 handler.on_source_decoded(Operand::srpair(ddddddd as u8)?)?;
3226 handler.on_dest_decoded(Operand::gprpair(sssss)?)?;
3227 }
3228 0b0011001 => {
3229 let sssss = reg_b16(inst);
3230 let ddddd = reg_b0(inst);
3231 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3232 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3233 handler.on_dest_decoded(Operand::crpair(ddddd)?)?;
3234 }
3235 0b1000000 => {
3236 let sssss = reg_b16(inst);
3237 let ddddd = reg_b0(inst);
3238 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3239 handler.on_source_decoded(Operand::crpair(sssss)?)?;
3240 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3241 }
3242 0b1001000 => {
3243 let lllll = reg_b16(inst) as u32;
3244 let l_mid = (inst >> 5) & 0b111;
3245 let l_low = inst & 0b11;
3246 let l10 = l_low | (l_mid << 2) | (lllll << 5);
3247
3248 let iiiii = reg_b8(inst);
3249 let ii = ((inst >> 3) & 0b11) as u8;
3250 let i7 = (iiiii << 2) | ii;
3251 let rel = ((i7 << 1) as i8 as i32) << 1;
3252
3253 handler.on_opcode_decoded(Opcode::Loop0)?;
3254 handler.on_source_decoded(Operand::PCRel32 { rel })?;
3255 handler.on_source_decoded(Operand::ImmU16 { imm: l10 as u16 })?;
3256 }
3257 0b1001001 => {
3258 let lllll = reg_b16(inst) as u32;
3259 let l_mid = (inst >> 5) & 0b111;
3260 let l_low = inst & 0b11;
3261 let l10 = l_low | (l_mid << 2) | (lllll << 5);
3262
3263 let iiiii = reg_b8(inst);
3264 let ii = ((inst >> 3) & 0b11) as u8;
3265 let i7 = (iiiii << 2) | ii;
3266 let rel = ((i7 << 1) as i8 as i32) << 1;
3267
3268 handler.on_opcode_decoded(Opcode::Loop1)?;
3269 handler.on_source_decoded(Operand::PCRel32 { rel })?;
3270 handler.on_source_decoded(Operand::ImmU16 { imm: l10 as u16 })?;
3271 }
3272 0b1001101 => {
3273 let lllll = reg_b16(inst) as u32;
3274 let l_mid = (inst >> 5) & 0b111;
3275 let l_low = inst & 0b11;
3276 let l10 = l_low | (l_mid << 2) | (lllll << 5);
3277
3278 let iiiii = reg_b8(inst);
3279 let ii = ((inst >> 3) & 0b11) as u8;
3280 let i7 = (iiiii << 2) | ii;
3281 let rel = ((i7 << 1) as i8 as i32) << 1;
3282
3283 handler.on_opcode_decoded(Opcode::Sp1Loop0)?;
3284 handler.on_source_decoded(Operand::PCRel32 { rel })?;
3285 handler.on_source_decoded(Operand::ImmU16 { imm: l10 as u16 })?;
3286 handler.on_dest_decoded(Operand::pred(3))?;
3287 }
3288 0b1001110 => {
3289 let lllll = reg_b16(inst) as u32;
3290 let l_mid = (inst >> 5) & 0b111;
3291 let l_low = inst & 0b11;
3292 let l10 = l_low | (l_mid << 2) | (lllll << 5);
3293
3294 let iiiii = reg_b8(inst);
3295 let ii = ((inst >> 3) & 0b11) as u8;
3296 let i7 = (iiiii << 2) | ii;
3297 let rel = ((i7 << 1) as i8 as i32) << 1;
3298
3299 handler.on_opcode_decoded(Opcode::Sp2Loop0)?;
3300 handler.on_source_decoded(Operand::PCRel32 { rel })?;
3301 handler.on_source_decoded(Operand::ImmU16 { imm: l10 as u16 })?;
3302 handler.on_dest_decoded(Operand::pred(3))?;
3303 }
3304 0b1001111 => {
3305 let lllll = reg_b16(inst) as u32;
3306 let l_mid = (inst >> 5) & 0b111;
3307 let l_low = inst & 0b11;
3308 let l10 = l_low | (l_mid << 2) | (lllll << 5);
3309
3310 let iiiii = reg_b8(inst);
3311 let ii = ((inst >> 3) & 0b11) as u8;
3312 let i7 = (iiiii << 2) | ii;
3313 let rel = ((i7 << 1) as i8 as i32) << 1;
3314
3315 handler.on_opcode_decoded(Opcode::Sp3Loop0)?;
3316 handler.on_source_decoded(Operand::PCRel32 { rel })?;
3317 handler.on_source_decoded(Operand::ImmU16 { imm: l10 as u16 })?;
3318 handler.on_dest_decoded(Operand::pred(3))?;
3319 }
3320 0b1010000 => {
3321 let sssss = reg_b16(inst);
3322 let ddddd = reg_b0(inst);
3323 handler.on_opcode_decoded(Opcode::TransferRegister)?;
3324 handler.on_source_decoded(Operand::cr(sssss))?;
3325 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3326 }
3327 0b1010010 => {
3328 if (inst >> 16) & 0b11111 != 0b01001 {
3329 return Err(DecodeError::InvalidOperand);
3333 }
3334
3335 let iiiiii = (inst >> 7) & 0b111111;
3336 let ddddd = reg_b0(inst);
3337 handler.on_opcode_decoded(Opcode::Add)?;
3338 handler.on_source_decoded(Operand::cr(9))?;
3339 handler.on_source_decoded(
3340 Operand::immext(iiiiii, extender, |i| Ok(Operand::imm_u8(i as u8)) )?
3341 )?;
3342 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3343 }
3344 o if o & 0b1111000 == 0b1011000 => {
3345 let opc = (inst >> 20) & 0b1111;
3346 let dd = (inst & 0b11) as u8;
3347 let uu = ((inst >> 6) & 0b11) as u8;
3348 let tt = ((inst >> 8) & 0b11) as u8;
3349 let ss = ((inst >> 16) & 0b11) as u8;
3350 let b13 = (inst >> 13) & 0b1;
3351
3352 handler.on_dest_decoded(Operand::pred(dd))?;
3353
3354 match opc {
3355 0b0000 => {
3356 if b13 == 0 {
3357 handler.on_opcode_decoded(Opcode::And)?;
3358 handler.on_source_decoded(Operand::pred(tt))?;
3359 handler.on_source_decoded(Operand::pred(ss))?;
3360 } else {
3361 opcode_check!(inst & 0b10010000 == 0b10010000);
3362 handler.on_opcode_decoded(Opcode::Fastcorner9)?;
3363 handler.on_source_decoded(Operand::pred(ss))?;
3364 handler.on_source_decoded(Operand::pred(tt))?;
3365 }
3366 },
3367 0b0001 => {
3368 if b13 == 0 {
3369 handler.on_opcode_decoded(Opcode::AndAnd)?;
3370 handler.on_source_decoded(Operand::pred(tt))?;
3371 handler.on_source_decoded(Operand::pred(ss))?;
3372 handler.on_source_decoded(Operand::pred(uu))?;
3373 } else {
3374 opcode_check!(inst & 0b10010000 == 0b10010000);
3375 handler.on_opcode_decoded(Opcode::Fastcorner9)?;
3376 handler.negate_result()?;
3377 handler.on_source_decoded(Operand::pred(ss))?;
3378 handler.on_source_decoded(Operand::pred(tt))?;
3379 }
3380 },
3381 0b0010 => {
3382 opcode_check!(b13 == 0);
3383 handler.on_opcode_decoded(Opcode::Or)?;
3384 handler.on_source_decoded(Operand::pred(tt))?;
3385 handler.on_source_decoded(Operand::pred(ss))?;
3386 },
3387 0b0011 => {
3388 opcode_check!(b13 == 0);
3389 handler.on_opcode_decoded(Opcode::AndOr)?;
3390 handler.on_source_decoded(Operand::pred(ss))?;
3391 handler.on_source_decoded(Operand::pred(tt))?;
3392 handler.on_source_decoded(Operand::pred(uu))?;
3393 },
3394 0b0100 => {
3395 opcode_check!(b13 == 0);
3396 handler.on_opcode_decoded(Opcode::Xor)?;
3397 handler.on_source_decoded(Operand::pred(tt))?;
3398 handler.on_source_decoded(Operand::pred(ss))?;
3399 },
3400 0b0101 => {
3401 opcode_check!(b13 == 0);
3402 handler.on_opcode_decoded(Opcode::OrAnd)?;
3403 handler.on_source_decoded(Operand::pred(ss))?;
3404 handler.on_source_decoded(Operand::pred(tt))?;
3405 handler.on_source_decoded(Operand::pred(uu))?;
3406 },
3407 0b0110 => {
3408 opcode_check!(b13 == 0);
3409 handler.on_opcode_decoded(Opcode::AndNot)?;
3410 handler.on_source_decoded(Operand::pred(tt))?;
3411 handler.on_source_decoded(Operand::pred(ss))?;
3412 },
3413 0b0111 => {
3414 opcode_check!(b13 == 0);
3415 handler.on_opcode_decoded(Opcode::OrOr)?;
3416 handler.on_source_decoded(Operand::pred(ss))?;
3417 handler.on_source_decoded(Operand::pred(tt))?;
3418 handler.on_source_decoded(Operand::pred(uu))?;
3419 },
3420 0b1000 => {
3421 opcode_check!(b13 == 0);
3422 handler.on_opcode_decoded(Opcode::Any8)?;
3423 handler.on_source_decoded(Operand::pred(ss))?;
3424 },
3425 0b1001 => {
3426 opcode_check!(b13 == 0);
3427 handler.on_opcode_decoded(Opcode::AndAndNot)?;
3428 handler.on_source_decoded(Operand::pred(ss))?;
3429 handler.on_source_decoded(Operand::pred(tt))?;
3430 handler.on_source_decoded(Operand::pred(uu))?;
3431 },
3432 0b1010 => {
3433 opcode_check!(b13 == 0);
3434 handler.on_opcode_decoded(Opcode::All8)?;
3435 handler.on_source_decoded(Operand::pred(ss))?;
3436 },
3437 0b1011 => {
3438 opcode_check!(b13 == 0);
3439 handler.on_opcode_decoded(Opcode::AndOrNot)?;
3440 handler.on_source_decoded(Operand::pred(ss))?;
3441 handler.on_source_decoded(Operand::pred(tt))?;
3442 handler.on_source_decoded(Operand::pred(uu))?;
3443 },
3444 0b1100 => {
3445 opcode_check!(b13 == 0);
3446 handler.on_opcode_decoded(Opcode::Not)?;
3447 handler.on_source_decoded(Operand::pred(ss))?;
3448 },
3449 0b1101 => {
3450 opcode_check!(b13 == 0);
3451 handler.on_opcode_decoded(Opcode::OrAndNot)?;
3452 handler.on_source_decoded(Operand::pred(ss))?;
3453 handler.on_source_decoded(Operand::pred(tt))?;
3454 handler.on_source_decoded(Operand::pred(uu))?;
3455 },
3456 0b1110 => {
3457 opcode_check!(b13 == 0);
3458 handler.on_opcode_decoded(Opcode::OrNot)?;
3459 handler.on_source_decoded(Operand::pred(tt))?;
3460 handler.on_source_decoded(Operand::pred(ss))?;
3461 },
3462 _ => {
3464 opcode_check!(b13 == 0);
3465 handler.on_opcode_decoded(Opcode::OrOrNot)?;
3466 handler.on_source_decoded(Operand::pred(ss))?;
3467 handler.on_source_decoded(Operand::pred(tt))?;
3468 handler.on_source_decoded(Operand::pred(uu))?;
3469 },
3470 }
3471 }
3472 0b1100000 => {
3473 opcode_check!(inst & 0x2000 == 0);
3474 let sssss = reg_b16(inst);
3475 let ttttt = reg_b8(inst);
3476 handler.on_opcode_decoded(Opcode::Tlbw)?;
3477 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3478 handler.on_source_decoded(Operand::gpr(ttttt))?;
3479 }
3480 0b1100010 => {
3481 let sssss = reg_b16(inst);
3482 let ddddd = reg_b0(inst);
3483 handler.on_opcode_decoded(Opcode::Tlbr)?;
3484 handler.on_source_decoded(Operand::gpr(sssss))?;
3485 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3486 }
3487 0b1100100 => {
3488 let sssss = reg_b16(inst);
3489 let ddddd = reg_b0(inst);
3490 handler.on_opcode_decoded(Opcode::Tlbp)?;
3491 handler.on_source_decoded(Operand::gpr(sssss))?;
3492 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3493 }
3494 0b1100101 => {
3495 let sssss = reg_b16(inst);
3496 handler.on_opcode_decoded(Opcode::TlbInvAsid)?;
3497 handler.on_source_decoded(Operand::gpr(sssss))?;
3498 }
3499 0b1100110 => {
3500 opcode_check!(inst & 0x2000 == 0);
3501 let sssss = reg_b16(inst);
3502 let ttttt = reg_b8(inst);
3503 let ddddd = reg_b0(inst);
3504 handler.on_opcode_decoded(Opcode::Ctlbw)?;
3505 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3506 handler.on_source_decoded(Operand::gpr(ttttt))?;
3507 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3508 }
3509 0b1100111 => {
3510 let sssss = reg_b16(inst);
3511 let ddddd = reg_b0(inst);
3512 handler.on_opcode_decoded(Opcode::Tlboc)?;
3513 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3514 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3515 }
3516 0b1111111 => {
3517 opcode_check!((inst >> 5) & 0b100000111 == 0b010);
3518 let ddddd = reg_b0(inst);
3519 let sssss = reg_b8(inst);
3520 let ttttt = reg_b16(inst);
3521 handler.on_opcode_decoded(Opcode::Movlen)?;
3522 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3523 handler.on_source_decoded(Operand::gpr(sssss))?;
3524 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
3525 }
3526 _ => {
3527 opcode_check!(false);
3528 }
3529 }
3530 }
3531 0b0111 => {
3532 match reg_type {
3533 0b0000 => {
3534 static OPS: [Option<Opcode>; 8] = [
3535 Some(Opcode::Aslh), Some(Opcode::Asrh), None, Some(Opcode::TransferRegister),
3536 Some(Opcode::Zxtb), Some(Opcode::Sxtb), Some(Opcode::Zxth), Some(Opcode::Sxth),
3537 ];
3538
3539 let opcode = decode_opcode!(OPS[min_op as usize]);
3540
3541 let ddddd = reg_b0(inst);
3542 let sssss = reg_b16(inst);
3543 let predicated = (inst >> 13) & 1 != 0;
3544
3545 if opcode == Opcode::TransferRegister {
3546 opcode_check!(!predicated);
3548 } else if opcode == Opcode::Zxtb {
3549 opcode_check!(predicated);
3552 }
3553
3554 handler.on_opcode_decoded(opcode)?;
3555
3556 if predicated {
3557 let pred_bits = (inst >> 10) & 0b11;
3558 let negated = pred_bits >> 1 != 0;
3559 let dotnew = pred_bits & 1 != 0;
3560 let pred_number = (inst >> 8) & 0b11;
3561
3562 handler.inst_predicated(pred_number as u8, negated, dotnew)?;
3563 }
3564
3565 handler.on_dest_decoded(Operand::Gpr { reg: ddddd })?;
3566 handler.on_source_decoded(Operand::Gpr { reg: sssss })?;
3567 }
3568 0b0001 => {
3569 opcode_check!(min_op & 1 == 1);
3570
3571 let i_high = ((inst >> 8) & 0xc000) as u16;
3572 let i_low = (inst & 0x3fff) as u16;
3573 let i = i_high | i_low;
3574 let xxxxx = reg_b16(inst);
3575
3576 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
3577 handler.on_dest_decoded(Operand::GprLow { reg: xxxxx })?;
3578 handler.on_source_decoded(Operand::ImmU16 { imm: i })?;
3579 }
3580 0b0010 => {
3581 opcode_check!(min_op & 1 == 1);
3582
3583 let i_high = ((inst >> 8) & 0xc000) as u16;
3584 let i_low = (inst & 0x3fff) as u16;
3585 let i = i_high | i_low;
3586 let xxxxx = reg_b16(inst);
3587
3588 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
3589 handler.on_dest_decoded(Operand::GprHigh { reg: xxxxx })?;
3590 handler.on_source_decoded(Operand::ImmU16 { imm: i })?;
3591 }
3592 0b0011 => {
3593 let i = ((inst >> 5) & 0xff) as i8;
3595
3596 if inst & 0x2000 != 0 {
3597 let sssss = reg_b16(inst);
3598 let ddddd = reg_b0(inst);
3599
3600 let op = if min_op & 0b010 == 0 {
3601 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3602 Opcode::Combine
3603 } else {
3604 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3605 Opcode::CmpEq
3606 };
3607 handler.on_opcode_decoded(op)?;
3608
3609 let min_low = min_op & 0b11;
3610
3611 if min_low == 0b11 {
3612 handler.negate_result()?;
3613 }
3614
3615 if min_low == 0b01 {
3616 handler.on_source_decoded(
3617 Operand::immext(
3618 i as u32, extender,
3619 |i: u32| Ok(Operand::imm_i8(i as i8))
3620 )?
3621 )?;
3622 handler.on_source_decoded(Operand::gpr(sssss))?;
3623 } else {
3624 handler.on_source_decoded(Operand::gpr(sssss))?;
3625 handler.on_source_decoded(
3626 Operand::immext(
3627 i as u32, extender,
3628 |i: u32| Ok(Operand::imm_i8(i as i8))
3629 )?
3630 )?;
3631 }
3632 } else {
3633 let sssss = reg_b16(inst);
3634 let ddddd = reg_b0(inst);
3635 let uu = min_op as u8 & 0b11;
3636
3637 handler.on_opcode_decoded(Opcode::Mux)?;
3638 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3639 handler.on_source_decoded(Operand::pred(uu))?;
3640
3641 let reg_first = min_op & 0b100 == 0;
3642
3643 if reg_first {
3644 handler.on_source_decoded(Operand::gpr(sssss))?;
3645 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
3646 } else {
3647 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
3648 handler.on_source_decoded(Operand::gpr(sssss))?;
3649 }
3650 }
3651 }
3652 0b0100 => {
3653 let sssss = reg_b16(inst);
3654 let ddddd = reg_b0(inst);
3655
3656 handler.on_opcode_decoded(Opcode::Add)?;
3657
3658 let negated = (min_op >> 2) & 1 == 1;
3659 let pred_number = min_op & 0b11;
3660 let dotnew = inst >> 13 & 1 == 1;
3661 let i = ((inst >> 5) & 0xff) as i8;
3662
3663 handler.inst_predicated(pred_number as u8, negated, dotnew)?;
3664 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3665 handler.on_source_decoded(Operand::gpr(sssss))?;
3666 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
3667 }
3668 0b0101 => {
3669 let sssss = reg_b16(inst);
3670 let ddddd = reg_b0(inst);
3671 let dd = ddddd & 0b11;
3672 operand_check!(ddddd & 0b01100 == 0);
3673
3674 let i_hi = ((min_op & 0b1) as i16) << 15 >> 6;
3675 let i_lo = ((inst >> 5) as i16) & 0b1_1111_1111;
3676 let i = i_lo | i_hi;
3677
3678 let op_bits = min_op >> 1;
3679
3680 static OPS: [Option<Opcode>; 4] = [
3681 Some(Opcode::CmpEq), Some(Opcode::CmpGt),
3682 Some(Opcode::CmpGtu), None,
3683 ];
3684
3685 let opcode = decode_opcode!(OPS[op_bits as usize]);
3686
3687 let negated = ddddd & 0b10000 != 0;
3688 if negated {
3689 handler.negate_result()?;
3690 }
3691
3692 handler.on_opcode_decoded(opcode)?;
3693 handler.on_dest_decoded(Operand::pred(dd))?;
3694 handler.on_source_decoded(Operand::gpr(sssss))?;
3695 if opcode == Opcode::CmpGtu {
3696 operand_check!(i >= 0);
3697 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_u16(i as u16)))?)?;
3698 } else {
3699 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?;
3700 }
3701 }
3702 0b0110 => {
3703 let sssss = reg_b16(inst);
3704 let ddddd = reg_b0(inst);
3705
3706 let i_hi = ((min_op & 0b1) as i16) << 15 >> 6;
3707 let i_lo = ((inst >> 5) as i16) & 0b1_1111_1111;
3708 let i = i_lo | i_hi;
3709
3710 let op_bits = min_op >> 1;
3711
3712 static OPS: [Option<Opcode>; 4] = [
3713 Some(Opcode::And), Some(Opcode::Sub),
3714 Some(Opcode::Or), None,
3715 ];
3716
3717 let opcode = decode_opcode!(OPS[op_bits as usize]);
3718
3719 handler.on_opcode_decoded(opcode)?;
3720 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3721 if opcode == Opcode::Sub {
3722 handler.on_source_decoded(
3723 Operand::immext(
3724 i as u32, extender,
3725 |i: u32| Ok(Operand::imm_i16(i as i16))
3726 )?
3727 )?;
3728 handler.on_source_decoded(Operand::gpr(sssss))?;
3729 } else {
3730 handler.on_source_decoded(Operand::gpr(sssss))?;
3731 handler.on_source_decoded(
3732 Operand::immext(
3733 i as u32, extender,
3734 |i: u32| Ok(Operand::imm_i16(i as i16))
3735 )?
3736 )?;
3737 }
3738 }
3739 0b0111 => {
3740 return Err(DecodeError::InvalidOpcode);
3741 }
3742 0b1000 => {
3743 let ddddd = reg_b0(inst);
3744
3745 let i_hi = (min_op >> 1) as i16;
3746 let i_mid = reg_b16(inst) as i16;
3747 let i_lo = ((inst >> 5) as i16) & 0b1_1111_1111;
3748 let i = i_lo | (i_mid << 5) | (i_hi << 14);
3749
3750 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
3751 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3752 handler.on_source_decoded(
3753 Operand::immext(
3754 i as u32, extender,
3755 |i: u32| Ok(Operand::imm_i16(i as i16))
3756 )?
3757 )?;
3758 }
3759 0b1010 |
3760 0b1011 => {
3761 let ddddd = reg_b0(inst);
3762
3763 let i = (inst >> 5) as i8;
3764 let uu = (inst >> 23) & 0b11;
3765 let l_lo = ((inst >> 13) & 0b01) as i8;
3766 let l_hi = ((inst >> 16) & 0x7f) as i8;
3767 let l = l_lo | (l_hi << 1);
3768
3769 handler.on_opcode_decoded(Opcode::Mux)?;
3770 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3771 handler.on_source_decoded(Operand::pred(uu as u8))?;
3772 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
3773 handler.on_source_decoded(Operand::imm_i8(l))?;
3774 }
3775 0b1100 => {
3776 let ddddd = reg_b0(inst);
3777
3778 let i = (inst >> 5) as i8;
3779 let l_lo = ((inst >> 13) & 0b01) as i8;
3780 let l_hi = ((inst >> 16) & 0x7f) as i8;
3781 let l = l_lo | (l_hi << 1);
3782
3783 handler.on_opcode_decoded(Opcode::Combine)?;
3784 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3785 if min_op & 0b100 == 0 {
3786 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
3787 handler.on_source_decoded(Operand::imm_i8(l))?;
3788 } else {
3789 handler.on_source_decoded(Operand::imm_i8(i))?;
3790 let l = l as u8;
3793 operand_check!(l & 0xc0 == 0);
3794 handler.on_source_decoded(Operand::immext(l as u32, extender, |l| Ok(Operand::imm_u8(l as u8)))?)?;
3795 }
3796 }
3797 0b1101 => {
3798 return Err(DecodeError::InvalidOpcode);
3799 }
3800 0b1110 => {
3801 let iiii = reg_b16(inst) as i16;
3802 operand_check!(iiii & 0b1_0000 == 0);
3803
3804 let ddddd = reg_b0(inst);
3805
3806 handler.on_opcode_decoded(Opcode::TransferImmediate)?;
3807
3808 let negated = (min_op >> 2) & 1 == 1;
3809 let pred_number = min_op & 0b11;
3810 let dotnew = inst >> 13 & 1 == 1;
3811
3812 let i_lo = ((inst >> 5) & 0xff) as i16;
3813 let i_hi = iiii << 12 >> 4 as i16;
3814 let i = i_lo | i_hi;
3815
3816 handler.inst_predicated(pred_number as u8, negated, dotnew)?;
3817 handler.on_dest_decoded(Operand::gpr(ddddd))?;
3818 handler.on_source_decoded(Operand::immext(i as u32, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?;
3819 }
3820 0b1111 => {
3821 handler.on_opcode_decoded(Opcode::Nop)?;
3823 }
3824 _ => {
3825 opcode_check!(false);
3827 }
3828 }
3829 }
3830 0b1000 => {
3831 let ddddd = reg_b0(inst);
3832 let iiiiii = ((inst >> 8) & 0b111111) as u8;
3833 let sssss = reg_b16(inst);
3834
3835 let majbits = (inst >> 24) & 0b1111;
3836 let minbits = (inst >> 21) & 0b111;
3837 let op_low = (inst >> 5) & 0b111;
3838
3839 match majbits {
3840 0b0000 => {
3841 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3842 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3843 match minbits {
3844 0b000 => {
3845 static OPS: [Opcode; 8] = [
3846 Asr, Lsr, Asl, Rol,
3847 Vsathub, Vsatwuh, Vsatwh, Vsathb,
3848 ];
3849 handler.on_opcode_decoded(OPS[op_low as usize])?;
3850 if op_low < 0b100 {
3851 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3852 }
3853 }
3854 0b001 => {
3855 opcode_check!(inst & 0x00e0 == 0);
3856 operand_check!(inst & 0x3000 == 0);
3857 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3858 handler.on_opcode_decoded(Opcode::Vasrh)?;
3859 handler.rounded(RoundingMode::Raw)?;
3860 }
3861 0b010 => {
3862 static OPS: [Option<Opcode>; 8] = [
3863 Some(Vasrw), Some(Vlsrw), Some(Vaslw), None,
3864 Some(Vabsh), Some(Vabsh), Some(Vabsw), Some(Vabsw),
3865 ];
3866 handler.on_opcode_decoded(decode_opcode!(OPS[op_low as usize]))?;
3867 if op_low < 0b100 {
3868 operand_check!(inst & 0x2000 == 0);
3869 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3870 } else {
3871 if op_low & 1 == 1 {
3872 handler.saturate()?;
3873 }
3874 }
3875 }
3876 0b011 |
3877 0b101 => {
3878 return Err(DecodeError::InvalidOpcode);
3879 }
3880 0b100 => {
3881 static OPS: [Option<Opcode>; 8] = [
3882 Some(Vasrh), Some(Vlsrh), Some(Vaslh), None,
3883 Some(Not), Some(Neg), Some(Abs), Some(Vconj),
3884 ];
3885 handler.on_opcode_decoded(decode_opcode!(OPS[op_low as usize]))?;
3886 if op_low < 0b100 {
3887 operand_check!(inst & 0x3000 == 0);
3888 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3889 } else {
3890 if op_low == 0b111 {
3891 handler.saturate()?;
3892 }
3893 }
3894 },
3895 0b110 => {
3896 static OPS: [Option<Opcode>; 8] = [
3897 None, None, None, None,
3898 Some(Deinterleave), Some(Interleave), Some(Brev), Some(Asr),
3899 ];
3900 handler.on_opcode_decoded(decode_opcode!(OPS[op_low as usize]))?;
3901 if op_low == 0b111 {
3902 handler.rounded(RoundingMode::Round)?;
3903 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3904 }
3905 }
3906 other => {
3907 debug_assert!(other == 0b111);
3908
3909 static OPS: [Option<Opcode>; 8] = [
3910 Some(ConvertDf2D), Some(ConvertDf2Ud), Some(ConvertUd2Df), Some(ConvertD2Df),
3911 None, None, Some(ConvertDf2D), Some(ConvertDf2Ud),
3912 ];
3913 handler.on_opcode_decoded(decode_opcode!(OPS[op_low as usize]))?;
3914 opcode_check!(inst & 0x2000 == 0);
3915 if op_low >= 0b100 {
3916 handler.chop()?;
3917 }
3918 }
3919 }
3920 },
3921 0b0001 => {
3922 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3923 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3924 handler.on_opcode_decoded(Opcode::Extractu)?;
3925 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
3926
3927 let l_low = ((inst >> 5) & 0b111) as u8;
3928 let l_high = ((inst >> 21) & 0b111) as u8;
3929 let llllll = (l_high << 3) | l_low;
3930 handler.on_source_decoded(Operand::imm_u8(llllll))?;
3931 }
3932 0b0010 => {
3933 let opc_hi = (inst >> 22) & 0b11;
3934 let opc_lo = (inst >> 5) & 0b111;
3935 let opc = (opc_hi << 3) | opc_lo;
3936
3937 let assign_mode_bits = opc >> 2;
3938 let shift_op_bits = opc & 0b11;
3939
3940 let assign_mode = match assign_mode_bits {
3941 0b000 => AssignMode::SubAssign,
3942 0b001 => AssignMode::AddAssign,
3943 0b010 => AssignMode::AndAssign,
3944 0b011 => AssignMode::OrAssign,
3945 0b100 => AssignMode::XorAssign,
3946 _ => {
3947 return Err(DecodeError::InvalidOpcode);
3948 }
3949 };
3950 let opc = match shift_op_bits {
3951 0b00 => Opcode::Asr,
3952 0b01 => Opcode::Lsr,
3953 0b10 => Opcode::Asl,
3954 _ => Opcode::Rol,
3955 };
3956 let sssss = reg_b16(inst);
3957 let xxxxx = reg_b0(inst);
3958 let u6 = ((inst >> 8) & 0b11_1111) as u8;
3959 handler.assign_mode(assign_mode)?;
3960 handler.on_opcode_decoded(opc)?;
3961 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
3962 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3963 handler.on_source_decoded(Operand::imm_u8(u6))?;
3964 }
3965 0b0011 => {
3966 let xxxxx = reg_b0(inst);
3967 let sssss = reg_b16(inst);
3968
3969 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
3972 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
3973 handler.on_opcode_decoded(Opcode::Insert)?;
3974
3975 let iiiiii = (inst >> 8) & 0b111111;
3976 let l_lo = (inst >> 5) & 0b111;
3977 let l_hi = (inst >> 21) & 0b111;
3978 let llllll = l_lo | (l_hi << 3);
3979
3980 handler.on_source_decoded(Operand::imm_u8(iiiiii as u8))?;
3981 handler.on_source_decoded(Operand::imm_u8(llllll as u8))?;
3982 }
3983 0b0100 => {
3984 let ddddd = reg_b0(inst);
3985 let sssss = reg_b16(inst);
3986
3987 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
3988 handler.on_source_decoded(Operand::gpr(sssss))?;
3989
3990 let opc_lo = (inst >> 5) & 0b111;
3991 let opc_hi = (inst >> 21) & 0b111;
3992
3993 if opc_hi >= 0b100 {
3994 static CONVERT_OPS: [Option<(Opcode, bool)>; 8] = [
3996 Some((ConvertSf2Df, false)), Some((ConvertUw2Df, false)),
3997 Some((ConvertW2Df, false)), Some((ConvertSf2Ud, true)),
3998 Some((ConvertSf2D, true)), Some((ConvertSf2Ud, true)),
3999 Some((ConvertSf2D, true)), None,
4000 ];
4001 let (opc, check_b13_zero) = decode_opcode!(CONVERT_OPS[opc_lo as usize]);
4002 opcode_check!(!check_b13_zero || (inst & 0b0010_0000_0000_0000) == 0);
4003 handler.on_opcode_decoded(opc)?;
4004
4005 if opc_lo > 0b100 {
4006 handler.chop()?;
4007 }
4008 } else if opc_hi >= 0b010 {
4009 if opc_lo == 0b010 || opc_lo == 0b011 {
4011 handler.on_opcode_decoded(Opcode::Vsplath)?;
4012 } else if opc_lo == 0b100 || opc_lo == 0b101 {
4013 handler.on_opcode_decoded(Opcode::Vsplatb)?;
4014 } else {
4015 return Err(DecodeError::InvalidOpcode);
4016 }
4017 } else {
4018 static EXT_OPS: [Opcode; 4] = [
4019 Vsxtbh, Vzxtbh, Vsxthw, Vzxthw
4020 ];
4021 handler.on_opcode_decoded(EXT_OPS[(opc_lo >> 1) as usize])?;
4022 }
4023 }
4024 0b0101 => {
4025 let opc_hi = (inst >> 21) & 0b111;
4026 let i6 = (inst >> 8) & 0b111111;
4027 let dd = (inst & 0b11) as u8;
4028 let sssss = reg_b16(inst);
4029
4030 handler.on_dest_decoded(Operand::pred(dd as u8))?;
4031 handler.on_source_decoded(Operand::gpr(sssss))?;
4032
4033 match opc_hi {
4034 0b000 => {
4035 handler.on_opcode_decoded(Opcode::Tstbit)?;
4036 operand_check!(i6 & 0b10_0000 == 0);
4037 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4038 }
4039 0b001 => {
4040 handler.on_opcode_decoded(Opcode::Tstbit)?;
4041 operand_check!(i6 & 0b10_0000 == 0);
4042 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4043 handler.negate_result()?;
4044 }
4045 0b010 => {
4046 handler.on_opcode_decoded(Opcode::TransferRegister)?;
4047 }
4048 0b100 => {
4049 handler.on_opcode_decoded(Opcode::Bitsclr)?;
4050 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4051 }
4052 0b101 => {
4053 handler.on_opcode_decoded(Opcode::Bitsclr)?;
4054 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4055 handler.negate_result()?;
4056 }
4057 0b111 => {
4058 handler.on_opcode_decoded(Opcode::SfClass)?;
4059 operand_check!(i6 & 0b10_0000 == 0);
4060 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4061 }
4062 _ => {
4063 return Err(DecodeError::InvalidOpcode);
4064 }
4065 }
4066 }
4067 0b0110 => {
4068 handler.on_opcode_decoded(Opcode::Mask)?;
4069 handler.on_dest_decoded(Operand::gprpair(reg_b0(inst))?)?;
4070 handler.on_source_decoded(Operand::pred(reg_b8(inst) & 0b11))?;
4071 }
4072 0b0111 => {
4073 let l6 = (inst >> 8) & 0b111111;
4074 let l6 = ((l6 as i8) << 2) >> 2;
4075 let i3 = (inst >> 5) & 0b111;
4076 let i_hi = (inst >> 21) & 0b1;
4077 let i4 = (i_hi << 3) | i3;
4078 let opc = (inst >> 22) & 0b11;
4079 static TABLEIDX_OPS: [Opcode; 4] = [
4080 Opcode::Tableidxb, Opcode::Tableidxh,
4081 Opcode::Tableidxw, Opcode::Tableidxd
4082 ];
4083
4084 handler.on_opcode_decoded(TABLEIDX_OPS[opc as usize])?;
4085 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
4086 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
4087 handler.on_source_decoded(Operand::imm_u8(i4 as u8))?;
4088 handler.on_source_decoded(Operand::imm_i8(l6))?;
4089 handler.rounded(RoundingMode::Raw)?;
4090 }
4091 0b1000 => {
4092 let ddddd = reg_b0(inst);
4094 let sssss = reg_b16(inst);
4095 let opc_lo = (inst >> 5) & 0b111;
4096 let opc_hi = (inst >> 21) & 0b111;
4097 let opc = opc_lo | (opc_hi << 3);
4098
4099 static OPCODES: [Option<Opcode>; 64] = [
4100 Some(Vsathub), Some(ConvertDf2Sf), Some(Vsatwh), None, Some(Vsatwuh), None, Some(Vsathb), None,
4102 None, Some(ConvertUd2Sf), None, None, None, None, None, None,
4104 Some(Clb), Some(ConvertD2Sf), Some(Cl0), None, Some(Cl1), None, None, None,
4106 Some(Normamt), Some(ConvertSf2Ud), Some(AddClb), Some(Popcount), Some(Vasrhub), Some(Vasrhub), None, None,
4108 Some(Vtrunohb), Some(ConvertSf2D), Some(Vtrunehb), None, Some(Vrndwh), None, Some(Vrndwh), None,
4110 None, Some(ConvertSf2Ud), None, None, None, None, None, None,
4112 Some(Sat), Some(Round), Some(Vasrw), None, Some(Bitsplit), Some(Clip), Some(Vclip), None,
4114 None, Some(ConvertSf2D), Some(Ct0), None, Some(Ct1), None, None, None,
4116 ];
4117
4118 let op = decode_opcode!(OPCODES[opc as usize]);
4119 handler.on_opcode_decoded(op)?;
4120
4121 let i6 = (inst >> 8) & 0b111111;
4122
4123 match opc {
4124 0b100110 |
4125 0b110001 => {
4126 operand_check!(i6 < 0b100000);
4127 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4128 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4129 handler.saturate()?;
4130 }
4131 0b110101 => {
4132 operand_check!(i6 < 0b100000);
4133 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4134 handler.on_source_decoded(Operand::gpr(sssss))?;
4135 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4136 }
4137 0b110110 => {
4138 operand_check!(i6 < 0b100000);
4139 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4140 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4141 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4142 }
4143 0b110010 => {
4144 operand_check!(i6 < 0b100000);
4145 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4146 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4147 let i6 = (i6 as i8) << 3 >> 3;
4148 handler.on_source_decoded(Operand::imm_i8(i6))?;
4149 }
4150 0b011001 => {
4151 operand_check!(i6 < 0b100000);
4152 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4153 handler.on_source_decoded(Operand::gpr(sssss))?;
4154 }
4155 0b011010 => {
4156 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4157 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4158 handler.on_source_decoded(Operand::imm_i8((i6 as i8) << 2 >> 2))?;
4159 }
4160 0b011100 => {
4161 operand_check!(i6 < 0b10000);
4162 handler.rounded(RoundingMode::Raw)?;
4163 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4164 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4165 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4166 }
4167 0b011101 => {
4168 operand_check!(i6 < 0b10000);
4169 handler.saturate()?;
4170 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4171 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4172 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4173 }
4174 0b110100 => {
4175 operand_check!(i6 < 0b10000);
4176 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4177 handler.on_source_decoded(Operand::gpr(sssss))?;
4178 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4179 }
4180 0b100001 => {
4181 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4182 handler.on_source_decoded(Operand::gpr(sssss))?;
4183 }
4184 0b101001 |
4185 0b111001 => {
4186 operand_check!(i6 & 0b10_0000 == 0);
4187 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4188 handler.on_source_decoded(Operand::gpr(sssss))?;
4189 handler.chop()?;
4190 }
4191 _ => {
4192 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4193 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4194 }
4195 }
4196 }
4197 0b1001 => {
4198 let opc_hi = (inst >> 21) & 0b111;
4200
4201 let ddddd = reg_b0(inst);
4202 let tt = reg_b8(inst) & 0b11;
4203 let ss = reg_b16(inst) & 0b11;
4204
4205 if opc_hi & 0b011 == 0b000 {
4206 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4208 handler.on_source_decoded(Operand::pred(ss))?;
4209 handler.on_source_decoded(Operand::pred(tt))?;
4210 handler.on_opcode_decoded(Opcode::Vitpack)?;
4211 } else if opc_hi & 0b010 == 0b010 {
4212 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4214 handler.on_source_decoded(Operand::pred(ss))?;
4215 handler.on_opcode_decoded(Opcode::TransferRegister)?;
4216 } else {
4217 return Err(DecodeError::InvalidOpcode);
4218 }
4219 }
4220 0b1010 => {
4221 let ddddd = reg_b0(inst);
4223 let sssss = reg_b16(inst);
4224 let l_lo = (inst >> 5) & 0b111;
4225 let l_hi = (inst >> 21) & 0b111;
4226 let l6 = l_lo | (l_hi << 3);
4227 let i6 = (inst >> 8) & 0b111111;
4228
4229 handler.on_opcode_decoded(Extract)?;
4230 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4231 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4232 handler.on_source_decoded(Operand::imm_u8(i6 as u8))?;
4233 handler.on_source_decoded(Operand::imm_u8(l6 as u8))?;
4234 }
4235 0b1011 => {
4236 let ddddd = reg_b0(inst);
4238 let sssss = reg_b16(inst);
4239 let op_lo = ((inst >> 5) & 0b111) as u8;
4240 let op_hi = ((inst >> 21) & 0b111) as u8;
4241 let i6 = (inst >> 8) & 0b111111;
4242
4243 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4244 handler.on_source_decoded(Operand::gpr(sssss))?;
4245
4246 match (op_hi, op_lo) {
4247 (0b001, 0b000) => {
4248 handler.on_opcode_decoded(Opcode::ConvertUw2Sf)?;
4249 }
4250 (0b010, 0b000) => {
4251 handler.on_opcode_decoded(Opcode::ConvertW2Sf)?;
4252 }
4253 (0b011, 0b000) => {
4254 operand_check!(i6 & 0b10_0000 == 0);
4255 handler.on_opcode_decoded(Opcode::ConvertSf2Uw)?;
4256 }
4257 (0b011, 0b001) => {
4258 operand_check!(i6 & 0b10_0000 == 0);
4259 handler.on_opcode_decoded(Opcode::ConvertSf2Uw)?;
4260 handler.chop()?;
4261 }
4262 (0b100, 0b010) => {
4263 operand_check!(i6 & 0b10_0000 == 0);
4264 handler.on_opcode_decoded(Opcode::ConvertSf2W)?;
4265 }
4266 (0b100, 0b011) => {
4267 operand_check!(i6 & 0b10_0000 == 0);
4268 handler.on_opcode_decoded(Opcode::ConvertSf2W)?;
4269 handler.chop()?;
4270 }
4271 (0b101, 0b000) => {
4272 handler.on_opcode_decoded(Opcode::SfFixupr)?;
4273 }
4274 (0b111, low) => {
4275 operand_check!(low & 0b100 == 0);
4276 let ee = (low & 0b11) as u8;
4277 handler.on_opcode_decoded(Opcode::SfInvsqrta)?;
4278 handler.on_dest_decoded(Operand::pred(ee))?;
4279 }
4280 _ => {
4281 return Err(DecodeError::InvalidOpcode);
4282 }
4283 }
4284 }
4285 0b1100 => {
4286 let opc_lo = (inst >> 5) & 0b111;
4287 let opc_hi = (inst >> 21) & 0b111;
4288 let opc = opc_lo | (opc_hi << 3);
4289 let ddddd = reg_b0(inst);
4290 let sssss = reg_b16(inst);
4291 let i6 = ((inst >> 8) & 0b11_1111) as u8;
4292
4293 if opc & 0b111110 == 0b111010 {
4294 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4295 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4296 } else {
4297 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4298 handler.on_source_decoded(Operand::gpr(sssss))?;
4299 }
4300
4301 match opc {
4302 0b000_000 => {
4303 operand_check!(i6 & 0b10_0000 == 0);
4304 handler.on_opcode_decoded(Opcode::Asr)?;
4305 handler.on_source_decoded(Operand::imm_u8(i6))?;
4306 }
4307 0b000_001 => {
4308 operand_check!(i6 & 0b10_0000 == 0);
4309 handler.on_opcode_decoded(Opcode::Lsr)?;
4310 handler.on_source_decoded(Operand::imm_u8(i6))?;
4311 }
4312 0b000_010 => {
4313 operand_check!(i6 & 0b10_0000 == 0);
4314 handler.on_opcode_decoded(Opcode::Asl)?;
4315 handler.on_source_decoded(Operand::imm_u8(i6))?;
4316 }
4317 0b000_011 => {
4318 operand_check!(i6 & 0b10_0000 == 0);
4319 handler.on_opcode_decoded(Opcode::Rol)?;
4320 handler.on_source_decoded(Operand::imm_u8(i6))?;
4321 }
4322 0b000_100 => {
4323 handler.on_opcode_decoded(Opcode::Clb)?;
4324 }
4325 0b000_101 => {
4326 handler.on_opcode_decoded(Opcode::Cl0)?;
4327 }
4328 0b000_110 => {
4329 handler.on_opcode_decoded(Opcode::Cl1)?;
4330 }
4331 0b000_111 => {
4332 handler.on_opcode_decoded(Opcode::Normamt)?;
4333 }
4334 0b001_000 => {
4335 handler.on_opcode_decoded(Opcode::AddClb)?;
4336 handler.on_source_decoded(Operand::imm_i8((i6 as i8) << 2 >> 2))?;
4337 }
4338 0b010_000 => {
4339 operand_check!(i6 & 0b10_0000 == 0);
4340 handler.on_opcode_decoded(Opcode::Asr)?;
4341 handler.on_source_decoded(Operand::imm_u8(i6))?;
4342 handler.rounded(RoundingMode::Round)?;
4343 }
4344 0b010_010 => {
4345 operand_check!(i6 & 0b10_0000 == 0);
4346 handler.on_opcode_decoded(Opcode::Asl)?;
4347 handler.on_source_decoded(Operand::imm_u8(i6))?;
4348 handler.saturate()?;
4349 }
4350 0b010_100 => {
4351 handler.on_opcode_decoded(Opcode::Ct0)?;
4352 }
4353 0b010_101 => {
4354 handler.on_opcode_decoded(Opcode::Ct1)?;
4355 }
4356 0b010_110 => {
4357 handler.on_opcode_decoded(Opcode::Brev)?;
4358 }
4359 0b010_111 => {
4360 handler.on_opcode_decoded(Opcode::Vsplatb)?;
4361 }
4362 _ if opc & 0b110_110 == 0b100_000 => {
4363 handler.on_opcode_decoded(Opcode::Vsathb)?;
4364 }
4365 _ if opc & 0b110_110 == 0b100_010 => {
4366 handler.on_opcode_decoded(Opcode::Vsathub)?;
4367 }
4368 0b100_100 => {
4369 handler.on_opcode_decoded(Opcode::Abs)?;
4370 }
4371 0b100_101 => {
4372 handler.on_opcode_decoded(Opcode::Abs)?;
4373 handler.saturate()?;
4374 }
4375 0b100_110 => {
4376 handler.on_opcode_decoded(Opcode::Neg)?;
4377 handler.saturate()?;
4378 }
4379 0b100_111 => {
4380 handler.on_opcode_decoded(Opcode::Swiz)?;
4381 }
4382 0b110_000 => {
4383 operand_check!(i6 & 0b10_0000 == 0);
4384 handler.on_opcode_decoded(Opcode::Setbit)?;
4385 handler.on_source_decoded(Operand::imm_u8(i6))?;
4386 }
4387 0b110_001 => {
4388 operand_check!(i6 & 0b10_0000 == 0);
4389 handler.on_opcode_decoded(Opcode::Clrbit)?;
4390 handler.on_source_decoded(Operand::imm_u8(i6))?;
4391 }
4392 0b110_010 => {
4393 operand_check!(i6 & 0b10_0000 == 0);
4394 handler.on_opcode_decoded(Opcode::Togglebit)?;
4395 handler.on_source_decoded(Operand::imm_u8(i6))?;
4396 }
4397 0b110_100 => {
4398 handler.on_opcode_decoded(Opcode::Sath)?;
4399 }
4400 0b110_101 => {
4401 handler.on_opcode_decoded(Opcode::Satuh)?;
4402 }
4403 0b110_110 => {
4404 handler.on_opcode_decoded(Opcode::Satub)?;
4405 }
4406 0b110_111 => {
4407 handler.on_opcode_decoded(Opcode::Satb)?;
4408 }
4409 0b111_000 | 0b111_001 => {
4410 operand_check!(i6 & 0b10_0000 == 0);
4411 handler.on_opcode_decoded(Opcode::Cround)?;
4412 handler.on_source_decoded(Operand::imm_u8(i6))?;
4413 }
4414 0b111_010 | 0b111_011 => {
4415 operand_check!(i6 & 0b10_0000 == 0);
4416 handler.on_opcode_decoded(Opcode::Cround)?;
4417 handler.on_source_decoded(Operand::imm_u8(i6))?;
4418 }
4419 0b111_100 | 0b111_101 => {
4420 operand_check!(i6 & 0b10_0000 == 0);
4421 handler.on_opcode_decoded(Opcode::Round)?;
4422 handler.on_source_decoded(Operand::imm_u8(i6))?;
4423 }
4424 0b111_110 | 0b111_111 => {
4425 operand_check!(i6 & 0b10_0000 == 0);
4426 handler.on_opcode_decoded(Opcode::Round)?;
4427 handler.saturate()?;
4428 handler.on_source_decoded(Operand::imm_u8(i6))?;
4429 }
4430 _ => {
4431 return Err(DecodeError::InvalidOpcode);
4432 }
4433 }
4434 }
4435 0b1101 => {
4436 let ddddd = reg_b0(inst);
4437 let sssss = reg_b16(inst);
4438 let iiiii = reg_b8(inst);
4439 let lll = (inst >> 5) & 0b111;
4440 let ll = (inst >> 21) & 0b11;
4441 let lllll = (lll | (ll << 3)) as u8;
4442 let opc_lo = (inst >> 13) & 1;
4443 let opc_hi = (inst >> 23) & 1;
4444 let opc = opc_lo | (opc_hi << 1);
4445
4446 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4447
4448 match opc {
4449 0b00 => {
4450 handler.on_opcode_decoded(Opcode::Extractu)?;
4451 handler.on_source_decoded(Operand::gpr(sssss))?;
4452 }
4453 0b01 => {
4454 handler.on_opcode_decoded(Opcode::Mask)?;
4455 }
4456 0b10 => {
4457 handler.on_opcode_decoded(Opcode::Extract)?;
4458 handler.on_source_decoded(Operand::gpr(sssss))?;
4459 }
4460 _ => {
4461 return Err(DecodeError::InvalidOpcode);
4462 }
4463 }
4464
4465 handler.on_source_decoded(Operand::imm_u8(iiiii))?;
4466 handler.on_source_decoded(Operand::imm_u8(lllll))?;
4467 }
4468 0b1110 => {
4469 let opc_hi = (inst >> 22) & 0b11;
4470 let opc_lo = (inst >> 5) & 0b111;
4471 let opc = (opc_hi << 3) | opc_lo;
4472 let sssss = reg_b16(inst);
4473 let xxxxx = reg_b0(inst);
4474 let iiiiii = ((inst >> 8) & 0b111111) as u8;
4475
4476 let assign_mode_bits = (opc >> 2) & 0b111;
4477 let shift_op_bits = opc & 0b11;
4478
4479 let assign_mode = match assign_mode_bits {
4480 0b000 => AssignMode::SubAssign,
4481 0b001 => AssignMode::AddAssign,
4482 0b010 => AssignMode::AndAssign,
4483 0b011 => AssignMode::OrAssign,
4484 0b100 => AssignMode::XorAssign,
4485 _ => {
4486 return Err(DecodeError::InvalidOpcode);
4487 }
4488 };
4489 let opc = match shift_op_bits {
4490 0b00 => Opcode::Asr,
4491 0b01 => Opcode::Lsr,
4492 0b10 => Opcode::Asl,
4493 _ => Opcode::Rol,
4494 };
4495 handler.on_opcode_decoded(opc)?;
4496 handler.assign_mode(assign_mode)?;
4497
4498 if assign_mode_bits < 0b010 {
4499 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
4500 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
4501 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
4502 } else {
4503 operand_check!(iiiiii & 0b10_0000 == 0);
4504 handler.on_dest_decoded(Operand::gpr(xxxxx))?;
4505 handler.on_source_decoded(Operand::gpr(sssss))?;
4506 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
4507 }
4508 }
4509 0b1111 => {
4510 opcode_check!(inst & 0x00102000 == 0);
4511 handler.on_source_decoded(Operand::gpr(sssss))?;
4512 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4513 handler.on_opcode_decoded(Opcode::Insert)?;
4514 handler.on_source_decoded(Operand::imm_u8(iiiiii))?;
4515
4516 let l_low = ((inst >> 5) & 0b111) as u8;
4517 let l_high = ((inst >> 21) & 0b111) as u8;
4518 let llllll = (l_high << 3) | l_low;
4519 handler.on_source_decoded(Operand::imm_u8(llllll))?;
4520 }
4521 _ => {
4522 unreachable!("impossible bit pattern");
4523 }
4524 }
4525 }
4526 0b1001 => {
4527 if (inst >> 27) & 1 != 0 {
4528 let opc_high = (inst >> 24) & 0b111;
4529
4530 let op = (inst >> 21) & 0b111;
4531
4532 let ddddd = reg_b0(inst);
4533 let xxxxx = reg_b16(inst);
4534
4535 use Opcode::*;
4536 static MEM_FIFO_OPS: [Option<(Opcode, bool, u8)>; 8] = [
4537 None, Some((Membh, false, 0x01)), Some((MemhFifo, true, 0x01)), Some((Memubh, false, 0x01)),
4538 Some((MembFifo, true, 0x00)), Some((Memubh, true, 0x02)), None, Some((Membh, true, 0x02)),
4539 ];
4540 static MEM_OPCODES: [Option<(Opcode, bool, u8)>; 8] = [
4541 Some((Memb, false, 0x00)), Some((Memub, false, 0x00)), Some((Memh, false, 0x01)), Some((Memuh, false, 0x01)),
4542 Some((Memw, false, 0x02)), None, Some((Memd, true, 0x03)), None,
4543 ];
4544
4545 match opc_high {
4546 0b000 => {
4547 let (op, wide, samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]);
4548 let src_offset = (inst >> 9) & 1 == 0;
4549 let iiii = (inst >> 5) & 0b1111;
4550 let mu = ((inst >> 13) & 1) as u8;
4551
4552
4553 if src_offset {
4554 let s4 = (iiii << 4) as i8 >> 4;
4555 handler.on_source_decoded(Operand::RegOffsetCirc { base: xxxxx, offset: (s4 << samt) as u32, mu })?;
4556 } else {
4557 operand_check!(iiii & 0b0100 == 0);
4558 handler.on_source_decoded(Operand::RegCirc { base: xxxxx, mu })?;
4559 }
4560 if !wide {
4561 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4562 } else {
4563 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4564 }
4565 handler.on_opcode_decoded(op)?;
4566 }
4567 0b001 => {
4568 if op == 0b111 {
4569 let sssss = reg_b8(inst);
4570 let ttttt = reg_b16(inst);
4571 handler.on_source_decoded(Operand::gpr(sssss))?;
4574 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
4575 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4576
4577 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
4578 let opc = (inst >> 5) & 0b111;
4579 let op = match opc {
4580 0b000 => Opcode::Pmemcpy,
4581 0b001 => Opcode::Linecpy,
4582 _ => {
4583 return Err(DecodeError::InvalidOpcode);
4584 }
4585 };
4586 handler.on_opcode_decoded(op)?;
4587 return Ok(());
4588 }
4589
4590 let (op, wide, samt) = decode_opcode!(MEM_OPCODES[op as usize]);
4591 let src_offset = (inst >> 9) & 1 == 0;
4592 let iiii = (inst >> 5) & 0b1111;
4593 let mu = ((inst >> 13) & 1) as u8;
4594
4595
4596 if src_offset {
4597 let s4 = (iiii << 4) as i8 >> 4;
4598 handler.on_source_decoded(Operand::RegOffsetCirc { base: xxxxx, offset: (s4 << samt) as u32, mu })?;
4599 } else {
4600 operand_check!(iiii & 0b0100 == 0);
4601 handler.on_source_decoded(Operand::RegCirc { base: xxxxx, mu })?;
4602 }
4603 if !wide {
4604 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4605 } else {
4606 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4607 }
4608 handler.on_opcode_decoded(op)?;
4609 }
4610 0b010 => {
4611 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
4612
4613 let (op, wide, samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]);
4614
4615 if inst & 0b0001_0000_0000_0000 == 0 {
4616 let iiii = (inst >> 5) & 0b1111;
4617 handler.on_source_decoded(Operand::RegOffsetInc { base: xxxxx, offset: (iiii << samt) })?;
4618 } else {
4619 let u2 = (inst >> 5) & 0b11;
4620 let u4 = (inst >> 8) & 0b1111;
4621 let uuuuuu = u2 | (u4 << 2);
4622 handler.on_source_decoded(
4623 Operand::with_extension(uuuuuu, extender,
4624 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
4625 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
4626 )?
4627 )?;
4628 }
4629 if !wide {
4630 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4631 } else {
4632 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4633 }
4634 handler.on_opcode_decoded(op)?;
4635 }
4636 0b011 => {
4637 let predicated = inst & 0b0010_0000_0000_0000 != 0;
4638
4639 let (op, wide, samt) = decode_opcode!(MEM_OPCODES[op as usize]);
4640
4641 if !predicated {
4642 if inst & 0b0001_0000_0000_0000 == 0 {
4643 let iiii = (inst >> 5) & 0b1111;
4644 handler.on_source_decoded(Operand::RegOffsetInc { base: xxxxx, offset: (iiii << samt) })?;
4645 } else {
4646 let u2 = (inst >> 5) & 0b11;
4647 let u4 = (inst >> 8) & 0b1111;
4648 let uuuuuu = (u2 | (u4 << 2)) as u32;
4649 handler.on_source_decoded(
4650 Operand::with_extension(uuuuuu, extender,
4651 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
4652 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
4653 )?
4654 )?;
4655 }
4656 if !wide {
4657 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4658 } else {
4659 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4660 }
4661 handler.on_opcode_decoded(op)?;
4662 } else {
4663 let iiii = (inst >> 5) & 0b1111;
4664 let tt = (inst >> 9) & 0b11;
4665 let negated = (inst >> 11) & 0b1 != 0;
4666 let dotnew = (inst >> 12) & 0b1 != 0;
4667
4668 handler.inst_predicated(tt as u8, negated, dotnew)?;
4669 handler.on_source_decoded(Operand::RegOffsetInc { base: xxxxx, offset: (iiii << samt) })?;
4670 if !wide {
4671 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4672 } else {
4673 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4674 }
4675 handler.on_opcode_decoded(op)?;
4676 }
4677 }
4678 0b100 => {
4679 let shifted_reg = inst & 0b0001_0000_0000_0000 != 0;
4680
4681 let (op, wide, _samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]);
4682
4683 if !wide {
4684 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4685 } else {
4686 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4687 }
4688 handler.on_opcode_decoded(op)?;
4689
4690 if !shifted_reg {
4691 operand_check!(inst & 0b0000_0000_1000_0000 == 0);
4692
4693 let mu = ((inst >> 13) & 1) as u8;
4694
4695 handler.on_source_decoded(Operand::RegMemIndexed { base: xxxxx, mu })?;
4696 } else {
4697 let i_hi = (inst >> 13) & 1;
4698 let i_lo = (inst >> 7) & 1;
4699 let ii = ((i_hi << 1) | i_lo) as u8;
4700
4701 let u2 = (inst >> 5) & 0b11;
4702 let u4 = (inst >> 8) & 0b1111;
4703 let uuuuuu = u2 | (u4 << 2);
4704
4705 handler.on_source_decoded(
4706 Operand::with_extension(uuuuuu, extender,
4707 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset }),
4708 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset }),
4709 )?
4710 )?;
4711 }
4712 }
4713 0b101 => {
4714 let shifted_reg = inst & 0b0001_0000_0000_0000 != 0;
4715
4716 let (op, wide, _samt) = decode_opcode!(MEM_OPCODES[op as usize]);
4717
4718 if !wide {
4719 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4720 } else {
4721 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4722 }
4723 handler.on_opcode_decoded(op)?;
4724
4725 if !shifted_reg {
4726 operand_check!(inst & 0b0000_0000_1000_0000 == 0);
4727
4728 let mu = ((inst >> 13) & 1) as u8;
4729
4730 handler.on_source_decoded(Operand::RegMemIndexed { base: xxxxx, mu })?;
4731 } else {
4732 let i_hi = (inst >> 13) & 1;
4733 let i_lo = (inst >> 7) & 1;
4734 let ii = ((i_hi << 1) | i_lo) as u8;
4735
4736 let u2 = (inst >> 5) & 0b11;
4737 let u4 = (inst >> 8) & 0b1111;
4738 let uuuuuu = u2 | (u4 << 2);
4739
4740 handler.on_source_decoded(
4741 Operand::with_extension(uuuuuu, extender,
4742 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset }),
4743 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: ii, offset }),
4744 )?
4745 )?;
4746 }
4747 }
4748 0b110 => {
4749 operand_check!(inst & 0b0001_0000_1000_0000 == 0);
4750
4751 let (op, wide, _samt) = decode_opcode!(MEM_FIFO_OPS[op as usize]);
4752
4753 let mu = ((inst >> 13) & 1) as u8;
4754 handler.on_source_decoded(Operand::RegMemIndexedBrev { base: xxxxx, mu })?;
4755 if !wide {
4756 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4757 } else {
4758 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4759 }
4760 handler.on_opcode_decoded(op)?;
4761 }
4762 _ => {
4763 let predicated = inst & 0b0000_0000_1000_0000 != 0;
4765
4766 let (op, wide, _samt) = decode_opcode!(MEM_OPCODES[op as usize]);
4767
4768 if !predicated {
4769 operand_check!(inst & 0b0001_0000_0000_0000 == 0);
4770 let mu = ((inst >> 13) & 1) as u8;
4771 handler.on_source_decoded(Operand::RegMemIndexedBrev { base: xxxxx, mu })?;
4772 if !wide {
4773 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4774 } else {
4775 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4776 }
4777 handler.on_opcode_decoded(op)?;
4778 } else {
4779 let i5 = reg_b16(inst);
4780 let i = ((inst >> 8) & 1) as u8;
4781 let iiiiii = (i5 << 1) | i;
4782 let ddddd = reg_b0(inst);
4783
4784 let tt = (inst >> 9) & 0b11;
4785 let negated = (inst >> 11) & 0b1 != 0;
4786 let dotnew = (inst >> 12) & 0b1 != 0;
4787
4788 handler.inst_predicated(tt as u8, negated, dotnew)?;
4789 handler.on_source_decoded(
4790 Operand::immext(iiiiii as u32, extender, |i6| {
4791 Ok(Operand::imm_u32(i6))
4792 })?
4793 )?;
4794 if !wide {
4795 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4796 } else {
4797 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4798 }
4799 handler.on_opcode_decoded(op)?;
4800 }
4801 }
4802 }
4803 } else {
4804 let ddddd = reg_b0(inst);
4805 let sssss = reg_b16(inst);
4806 let op = (inst >> 21) & 0b1111;
4807
4808 if op == 0b0000 {
4809 let op_high = (inst >> 25) & 0b11;
4811 match op_high {
4812 0b00 => {
4813 opcode_check!(inst & 0b10000_00000000 == 0);
4814
4815 handler.on_source_decoded(Operand::gpr(sssss))?;
4816 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4817 handler.on_opcode_decoded(Opcode::DeallocFrame)?;
4818 }
4819 0b01 => {
4820 opcode_check!(inst & 0b100000_111_00000 == 0);
4821 let op_low = (inst >> 11) & 0b11;
4822 static OP: [Opcode; 4] = [
4823 Opcode::MemwLockedLoad, Opcode::MemwAq,
4824 Opcode::MemdLockedLoad, Opcode::MemdAq,
4825 ];
4826 handler.on_source_decoded(Operand::gpr(sssss))?;
4827 if op_low > 0b01 {
4828 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4829 } else {
4830 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4831 }
4832 handler.on_opcode_decoded(OP[op_low as usize])?;
4833 }
4834 0b10 => {
4835 let i11 = inst & 0b111111_11111;
4836 handler.on_source_decoded(Operand::RegOffset { base: sssss, offset: i11 << 3 })?;
4837 handler.on_opcode_decoded(Opcode::Dcfetch)?;
4838 }
4839 _ => { opcode_check!(inst & 0b1_00000_00000 == 0);
4841
4842 handler.on_source_decoded(Operand::gpr(sssss))?;
4843 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4844 handler.on_opcode_decoded(Opcode::DeallocReturn)?;
4845
4846 let hints = (inst >> 11) & 0b111;
4847 if hints == 0 {
4848 } else if hints == 0b100 {
4850 return Err(DecodeError::InvalidOpcode);
4853 } else {
4854 let dotnew = (hints & 0b001) != 0;
4855 let negated = (hints & 0b100) != 0;
4856 let pred = (inst >> 8) & 0b11;
4857
4858 handler.inst_predicated(pred as u8, negated, dotnew)?;
4859 if dotnew {
4860 let taken = hints & 0b010 != 0;
4861 handler.branch_hint(taken)?;
4862 }
4863 }
4864 }
4865 }
4866 } else {
4867 let i_lo = (inst >> 5) & 0b1_1111_1111;
4868 let i_hi = (inst >> 25) & 0b11;
4869 let i = i_lo | (i_hi << 9);
4870
4871 use Opcode::*;
4872 static OPCODES: [Option<(Opcode, bool, u8)>; 16] = [
4873 None, Some((Membh, false, 0x01)), Some((MemhFifo, true, 0x01)), Some((Memubh, false, 0x01)),
4874 Some((MembFifo, true, 0x00)), Some((Memubh, true, 0x02)), None, Some((Membh, true, 0x02)),
4875 Some((Memb, false, 0x00)), Some((Memub, false, 0x00)), Some((Memh, false, 0x01)), Some((Memuh, false, 0x01)),
4876 Some((Memw, false, 0x02)), None, Some((Memd, true, 0x03)), None,
4877 ];
4878 let (op, wide, shamt) = decode_opcode!(OPCODES[op as usize]);
4879 handler.on_source_decoded(
4885 Operand::with_extension(
4886 i as u32, extender,
4887 |offset| Ok(Operand::RegOffset { base: sssss, offset }),
4888 |offset| Ok(Operand::RegOffset {
4889 base: sssss, offset: offset << shamt
4890 }),
4891 )?
4892 )?;
4893 if !wide {
4894 handler.on_dest_decoded(Operand::gpr(ddddd))?;
4895 } else {
4896 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
4897 }
4898 handler.on_opcode_decoded(op)?;
4899 }
4900 }
4901 }
4902 0b1010 => {
4903 if inst >> 27 & 1 == 0 {
4904 let sssss = reg_b16(inst);
4908 #[allow(non_snake_case)]
4909 let Rs = Operand::gpr(sssss);
4910
4911 if inst >> 24 & 1 == 0 {
4912 let opc_upper = inst >> 25 & 0b11;
4914 if opc_upper == 0b00 {
4915 let opc_lower = (inst >> 21) & 0b111;
4916 match opc_lower {
4917 0b000 => {
4918 handler.on_opcode_decoded(Opcode::DcCleanA)?;
4919 handler.on_source_decoded(Rs)?;
4920 },
4921 0b001 => {
4922 handler.on_opcode_decoded(Opcode::DcInvA)?;
4923 handler.on_source_decoded(Rs)?;
4924 },
4925 0b010 => {
4926 handler.on_opcode_decoded(Opcode::DcCleanInvA)?;
4927 handler.on_source_decoded(Rs)?;
4928 },
4929 0b011 => {
4930 opcode_check!(inst & 0b11100 == 0b01100);
4931 handler.on_opcode_decoded(Opcode::Release)?;
4932 handler.on_source_decoded(Rs)?;
4933 if (inst >> 5) & 1 == 0 {
4934 handler.domain_hint(DomainHint::All)?;
4935 } else {
4936 handler.domain_hint(DomainHint::Same)?;
4937 }
4938 },
4939 0b100 => {
4940 handler.on_opcode_decoded(Opcode::AllocFrame)?;
4941 let i11 = inst & 0b111_11111111;
4942 operand_check!(inst & 0b111000_00000000 == 0);
4943 handler.on_source_decoded(Rs)?;
4944 handler.on_source_decoded(Operand::imm_u16((i11 as u16) << 3))?;
4945 }
4946 0b101 => {
4947 handler.on_dest_decoded(Rs)?;
4948 handler.on_source_decoded(Operand::gpr((inst >> 8) as u8 & 0b11111))?;
4949 if inst & 0b1100 == 0b0000 {
4950 handler.on_opcode_decoded(Opcode::MemwStoreCond)?;
4951 handler.on_dest_decoded(Operand::pred(inst as u8 & 0b11))?;
4952 } else if inst & 0b11100 == 0b01000 {
4953 handler.on_opcode_decoded(Opcode::MemwRl)?;
4954 if (inst >> 5) & 1 == 0 {
4955 handler.domain_hint(DomainHint::All)?;
4956 } else {
4957 handler.domain_hint(DomainHint::Same)?;
4958 }
4959 } else {
4960 return Err(DecodeError::InvalidOpcode);
4961 }
4962 },
4963 0b110 => {
4964 opcode_check!((inst >> 13) & 1 == 0);
4965 handler.on_opcode_decoded(Opcode::DcZeroA)?;
4966 handler.on_source_decoded(Rs)?;
4967 }
4968 _ => {
4969 handler.on_dest_decoded(Rs)?;
4971 handler.on_source_decoded(Operand::gprpair((inst >> 8) as u8 & 0b11111)?)?;
4972 if inst & 0b1100 == 0b0000 {
4973 handler.on_opcode_decoded(Opcode::MemdStoreCond)?;
4974 handler.on_dest_decoded(Operand::pred(inst as u8 & 0b11))?;
4975 } else if inst & 0b11100 == 0b01000 {
4976 handler.on_opcode_decoded(Opcode::MemdRl)?;
4977 if (inst >> 5) & 1 == 0 {
4978 handler.domain_hint(DomainHint::All)?;
4979 } else {
4980 handler.domain_hint(DomainHint::Same)?;
4981 }
4982 } else {
4983 return Err(DecodeError::InvalidOpcode);
4984 }
4985 },
4986 }
4987 } else if opc_upper == 0b01 {
4988 handler.on_opcode_decoded(Opcode::DcKill)?;
4991 } else {
4992 opcode_check!(opc_upper == 0b11);
4998 let opc_lower = (inst >> 21) & 0b111;
4999
5000 let ttttt = reg_b8(inst);
5001 match opc_lower {
5002 0b000 => {
5003 handler.on_opcode_decoded(Opcode::L2Fetch)?;
5004 handler.on_source_decoded(Rs)?;
5005 opcode_check!((inst >> 5) & 0b111 == 0b000);
5006 handler.on_source_decoded(Operand::gpr(ttttt))?;
5007 }
5008 0b100 => {
5009 handler.on_opcode_decoded(Opcode::L2Fetch)?;
5010 handler.on_source_decoded(Rs)?;
5011 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5012 }
5013 0b101 => {
5014 handler.on_opcode_decoded(Opcode::L2Gclean)?;
5015 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5016 }
5017 0b110 => {
5018 handler.on_opcode_decoded(Opcode::L2Gcleaninv)?;
5019 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5020 }
5021 _ => {
5022 opcode_check!(false);
5023 }
5024 }
5025 }
5026 } else {
5027 let opc = ((inst >> 21) & 0b111) as u8;
5029 let i_high = (inst >> 25) & 0b11;
5030 let i_mid = (inst >> 13) & 1;
5031 let i_low = inst & 0b11111111;
5032 let ttttt = reg_b8(inst);
5033
5034 let i11 = i_low | (i_mid << 8) | (i_high << 9);
5035
5036 decode_store_ops(handler, opc, ttttt, |shamt| {
5037 Operand::with_extension(
5038 i11, extender,
5039 |offset| Ok(Operand::RegOffset { base: sssss, offset }),
5040 |offset| Ok(Operand::RegOffset {
5041 base: sssss, offset: offset << shamt
5042 }),
5043 )
5044 })?;
5045
5046 }
5047 } else {
5048 let majbits = (inst >> 24) & 0b111;
5050
5051 let minbits = ((inst >> 21) & 0b111) as u8;
5052 match majbits {
5053 0b000 => {
5054 if inst & 0x00_e0_00_e0 == 0 {
5059 handler.on_opcode_decoded(Opcode::Barrier)?;
5060 } else if inst & 0x00_e0_00_00 == 0x00_20_00_00 {
5061 let op = (inst >> 10) & 0b111;
5062 static OPCODES: [Option<Opcode>; 8] = [
5063 Some(L2Kill), None, Some(L2Gunlock), None,
5064 Some(L2Gclean), None, Some(L2Gcleaninv), None,
5065 ];
5066 handler.on_opcode_decoded(decode_opcode!(OPCODES[op as usize]))?;
5067 } else if inst & 0x00_e0_01_e0 == 0x00_00_00_e0 {
5068 handler.on_opcode_decoded(Opcode::DmSyncHt)?;
5069 handler.on_dest_decoded(Operand::gpr(inst as u8 & 0b11111))?;
5070 } else if inst & 0x00_e0_00_00 == 0x00_40_00_00 {
5071 handler.on_opcode_decoded(Opcode::SyncHt)?;
5072 } else {
5073 return Err(DecodeError::InvalidOpcode);
5074 }
5075 }
5076 0b001 => {
5077 let xxxxx = reg_b16(inst);
5078 let ttttt = reg_b8(inst);
5079 let u = ((inst >> 13) & 1) as u8;
5080 opcode_check!((inst >> 7) & 1 == 0);
5082 if (inst >> 1) & 1 == 0 {
5083 let iiii = (inst >> 3) & 0b1111;
5084 decode_store_ops(handler, minbits, ttttt, |shamt| {
5085 Ok(Operand::RegOffsetCirc { base: xxxxx, offset: iiii << shamt, mu: u })
5086 })?;
5087 } else {
5088 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5089 Ok(Operand::RegCirc { base: xxxxx, mu: u })
5090 })?;
5091 }
5092 }
5093 0b010 => {
5094 return Err(DecodeError::InvalidOpcode);
5095 }
5096 0b011 => {
5097 let xxxxx = reg_b16(inst);
5098 let ttttt = reg_b8(inst);
5099 if (inst >> 13) & 1 == 0 {
5100 if (inst >> 7) & 1 == 0 {
5102 opcode_check!(inst & 2 == 0);
5103 let iiii = ((inst >> 3) & 0b1111) as u32;
5104 decode_store_ops(handler, minbits, ttttt, |shamt| {
5105 Ok(Operand::RegOffset { base: xxxxx, offset: iiii << shamt })
5106 })?;
5107 } else {
5108 let uuuuuu = inst & 0b111111;
5109 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5110 Operand::with_extension(uuuuuu, extender,
5111 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
5112 |addr| Ok(Operand::RegStoreAssign { base: xxxxx, addr }),
5113 )
5114 })?;
5115 }
5116 } else {
5117 let vv = inst & 0b11;
5120 let negated = (inst >> 2) & 1 == 1;
5121 let iiii = (inst >> 3) & 0b1111;
5122 let dotnew = (inst >> 7) & 1 == 1;
5123 decode_store_ops(handler, minbits, ttttt, |shamt| {
5124 Ok(Operand::RegOffsetInc { base: xxxxx, offset: iiii << shamt })
5125 })?;
5126 handler.inst_predicated(vv as u8, negated, dotnew)?;
5127 }
5128 }
5129 0b100 => {
5130 return Err(DecodeError::InvalidOpcode);
5131 }
5132 0b101 => {
5133 let xxxxx = reg_b16(inst);
5134 let ttttt = reg_b8(inst);
5135 if (inst >> 7) & 1 == 0 {
5136 let u = (inst >> 13) & 1;
5137 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5138 Ok(Operand::RegMemIndexed { base: xxxxx, mu: u as u8 })
5139 })?;
5140 } else {
5141 let i_hi = (inst >> 13) & 1;
5142 let i_lo = (inst >> 6) & 1;
5143 let i = ((i_hi << 1) | i_lo) as u8;
5144 let uuuuuu = inst & 0b111111;
5145 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5146 Operand::with_extension(uuuuuu, extender,
5147 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: i, offset }),
5148 |offset| Ok(Operand::RegShiftOffset { base: xxxxx, shift: i, offset }),
5149 )
5150 })?;
5151 }
5152 },
5153 0b110 => {
5154 return Err(DecodeError::InvalidOpcode);
5155 }
5156 _ => { let xxxxx = reg_b16(inst);
5158 let ttttt = reg_b8(inst);
5159 if (inst >> 7) & 1 == 0 {
5160 let u = (inst >> 13) & 1;
5161 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5162 Ok(Operand::RegMemIndexedBrev { base: xxxxx, mu: u as u8 })
5163 })?;
5164 } else {
5165 let vv = inst & 0b11;
5168 let negated = (inst >> 2) & 1 == 1;
5169 let iiii = ((inst >> 3) & 0b1111) as u8;
5170 let ii_high = xxxxx & 0b11;
5171 let i6 = ((ii_high << 4) | iiii) as i8;
5172 let dotnew = (inst >> 13) & 1 == 1;
5173 decode_store_ops(handler, minbits, ttttt, |_shamt| {
5174 Operand::with_extension(i6 as u32, extender,
5175 |addr| Ok(Operand::Absolute { addr }),
5176 |addr| Ok(Operand::Absolute { addr }),
5177 )
5178 })?;
5179 handler.inst_predicated(vv as u8, negated, dotnew)?;
5180 }
5181 }
5182 }
5183 }
5184 }
5185 0b1011 => {
5186 handler.on_opcode_decoded(Opcode::Add)?;
5187
5188 let ddddd = reg_b0(inst);
5189 let sssss = reg_b16(inst);
5190
5191 let i_hi = (inst >> 21) & 0b111_1111;
5192 let i_lo = (inst >> 5) & 0b1_1111_1111;
5193 let i = (i_hi << 9) | i_lo;
5194
5195 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5196 handler.on_source_decoded(Operand::gpr(sssss))?;
5197 handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_i16(i as i16)))?)?;
5198 }
5199 0b1100 => {
5200 let ddddd = reg_b0(inst);
5201 let ttttt = reg_b8(inst);
5202 let sssss = reg_b16(inst);
5203
5204 let majbits = (inst >> 24) & 0b1111;
5205 match majbits {
5206 0b0000 => {
5207 let op = (inst >> 23) & 1;
5209
5210 let iii = (inst >> 5) & 0b111;
5211
5212 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5213
5214 if op == 0 {
5215 handler.on_opcode_decoded(Opcode::Valignb)?;
5216 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5217 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5218 } else {
5219 handler.on_opcode_decoded(Opcode::Vspliceb)?;
5220 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5221 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5222 }
5223 handler.on_source_decoded(Operand::imm_u8(iii as u8))?;
5224 }
5225 0b0001 => {
5226 let op_lo = (inst >> 5) & 0b111;
5227 let op_hi = (inst >> 22) & 011;
5228
5229 match op_hi {
5230 0b00 => {
5231 static OPCODES: [Opcode; 8] = [
5232 Opcode::Extractu, Opcode::Extractu, Opcode::Shuffeb, Opcode::Shuffeb,
5233 Opcode::Shuffob, Opcode::Shuffob, Opcode::Shuffeh, Opcode::Shuffeh,
5234 ];
5235
5236 handler.on_opcode_decoded(OPCODES[op_lo as usize])?;
5237 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5238 if op_lo < 0b100 {
5239 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5240 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5241 } else {
5242 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5243 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5244 }
5245 },
5246 0b01 => {
5247 static OPCODES: [Option<Opcode>; 8] = [
5248 Some(Vxaddsubw), Some(Vaddhub), Some(Vxsubaddw), None,
5249 Some(Vxaddsubh), None , Some(Vxsubaddh), None,
5250 ];
5251
5252 let op_lo = (inst >> 5) as usize & 0b111;
5253
5254 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo]))?;
5255 handler.saturate()?;
5256 if op_lo == 0b001 {
5257 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5258 } else {
5259 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5260 }
5261 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5262 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5263 }
5264 0b10 => {
5265 static OPCODES: [Option<Opcode>; 8] = [
5266 Some(Shuffoh), None, Some(Vtrunewh), Some(Vtrunehb),
5267 Some(Vtrunowh), Some(Vtrunohb), Some(Lfs), None,
5268 ];
5269
5270 let op_lo = (inst >> 5) as usize & 0b111;
5271
5272 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo]))?;
5273 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5274
5275 if op_lo == 0b000 {
5276 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5277 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5278 } else {
5279 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5280 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5281 }
5282 }
5283 _ => {
5284 static OPCODES: [Opcode; 8] = [
5285 Opcode::Vxaddsubh, Opcode::Vxaddsubh, Opcode::Vxsubaddh, Opcode::Vxsubaddh,
5286 Opcode::Extractu, Opcode::Extractu, Opcode::Decbin, Opcode::Decbin,
5287 ];
5288
5289 handler.on_opcode_decoded(OPCODES[op_lo as usize])?;
5290 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5291 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5292 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5293
5294 if op_lo < 0b100 {
5295 handler.rounded(RoundingMode::Round)?;
5296 handler.shift_right(1)?;
5297 handler.saturate()?;
5298 }
5299 }
5300 }
5301 }
5302 0b0010 => {
5303 let minbits = (inst >> 21) & 0b111;
5304
5305 let uu = ((inst >> 5) & 0b11) as u8;
5306
5307 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5308 if minbits & 0b100 == 0 {
5309 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5310 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5311 } else {
5312 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5313 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5314 }
5315 handler.on_source_decoded(Operand::pred(uu))?;
5316
5317 if minbits & 0b100 == 0 {
5318 handler.on_opcode_decoded(Opcode::Valignb)?;
5319 } else if minbits == 0b100 {
5320 handler.on_opcode_decoded(Opcode::Vspliceb)?;
5321 } else if minbits == 0b110 {
5322 handler.on_opcode_decoded(Opcode::Add)?;
5323 handler.carry()?;
5324 } else if minbits == 0b111 {
5325 handler.on_opcode_decoded(Opcode::Sub)?;
5326 handler.carry()?;
5327 } else {
5328 return Err(DecodeError::InvalidOpcode);
5329 }
5330 }
5331 0b0011 => {
5332 let minbits = (inst >> 22) & 0b11;
5333 let op_lo = (inst >> 6) & 0b11;
5334
5335 let opc = op_lo | (minbits << 2);
5336
5337 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5338 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5339 handler.on_source_decoded(Operand::gpr(ttttt))?;
5340
5341 if minbits == 0b11 {
5342 if op_lo == 0b00 {
5343 handler.on_opcode_decoded(Opcode::Vcrotate)?;
5344 } else if op_lo == 0b01 {
5345 handler.on_opcode_decoded(Opcode::Vcnegh)?;
5346 } else if op_lo == 0b11 {
5347 handler.on_opcode_decoded(Opcode::Vrcrotate)?;
5348 let u_lo = (inst >> 5) & 1;
5349 let u_hi = (inst >> 13) & 1;
5350 let u = u_lo | (u_hi << 1);
5351 handler.on_source_decoded(Operand::imm_u8(u as u8))?;
5352 } else {
5353 return Err(DecodeError::InvalidOpcode);
5354 }
5355 } else {
5356 static OPCODES: [Option<Opcode>; 16] = [
5357 Some(Vasrw), Some(Vlsrw), Some(Vaslw), Some(Vlslw),
5358 Some(Vasrh), Some(Vlsrh), Some(Vaslh), Some(Vlslh),
5359 Some(Asr), Some(Lsr), Some(Asl), Some(Lsl),
5360 None, None, None, None,
5361 ];
5362
5363 handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?;
5364 }
5365
5366 }
5367 0b0100 => {
5368 let minbits = (inst >> 21) & 0b111;
5369 opcode_check!(minbits == 0b000);
5370 operand_check!(inst & 0b0010_0000_0000_0000 == 0);
5371
5372 handler.on_opcode_decoded(Opcode::AddAslRegReg)?;
5373 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5374 handler.on_source_decoded(Operand::gpr(ttttt))?;
5375 handler.on_source_decoded(Operand::gpr(sssss))?;
5376 handler.on_source_decoded(Operand::imm_u8(((inst >> 5) & 0b111) as u8))?;
5377 }
5378 0b0101 => {
5379 let minbits = (inst >> 5) & 0b111;
5380
5381 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5382
5383 if minbits < 0b100 {
5384 opcode_check!(minbits == 0b010);
5385 handler.on_opcode_decoded(Opcode::Vasrw)?;
5386 handler.on_source_decoded(Operand::gpr(sssss))?;
5387 handler.on_source_decoded(Operand::gpr(ttttt))?;
5388 } else {
5389 handler.shift_left(1)?;
5390 handler.rounded(RoundingMode::Round)?;
5391 handler.saturate()?;
5392 if minbits & 0b010 == 0 {
5393 handler.on_opcode_decoded(Opcode::Cmpyiwh)?;
5394 } else {
5395 handler.on_opcode_decoded(Opcode::Cmpyrwh)?;
5396 }
5397 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5398 if minbits & 0b001 == 0 {
5399 handler.on_source_decoded(Operand::gpr(ttttt))?;
5400 } else {
5401 handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?;
5402 }
5403 }
5404 }
5405 0b0110 => {
5406 let op_lo = (inst >> 6) & 0b11;
5408 let op_hi = (inst >> 22) & 0b11;
5409 let opc = op_lo | (op_hi << 2);
5410
5411 match opc {
5412 0b0000 => {
5413 handler.on_opcode_decoded(Opcode::Asr)?;
5414 handler.saturate()?;
5415 },
5416 0b0010 => {
5417 handler.on_opcode_decoded(Opcode::Asl)?;
5418 handler.saturate()?;
5419 },
5420 0b0100 => {
5421 handler.on_opcode_decoded(Opcode::Asr)?;
5422 },
5423 0b0101 => {
5424 handler.on_opcode_decoded(Opcode::Lsr)?;
5425 },
5426 0b0110 => {
5427 handler.on_opcode_decoded(Opcode::Asl)?;
5428 },
5429 0b0111 => {
5430 handler.on_opcode_decoded(Opcode::Lsl)?;
5431 },
5432 0b1011 => {
5433 let i_hi = reg_b16(inst);
5434 let i_lo = ((inst >> 5) & 1) as u8;
5435 let i6 = i_lo | (i_hi << 1);
5436 let i6 = i6 as i8;
5437
5438 handler.on_opcode_decoded(Opcode::Lsl)?;
5439 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
5440 handler.on_source_decoded(Operand::imm_i8(i6 << 2 >> 2))?;
5441 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
5442 return Ok(());
5443 },
5444 0b1100 => {
5445 handler.on_opcode_decoded(Opcode::Cround)?;
5446 },
5447 0b1101 => {
5448 handler.on_opcode_decoded(Opcode::Cround)?;
5449 handler.on_dest_decoded(Operand::gprpair(reg_b0(inst))?)?;
5450 handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
5451 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
5452 return Ok(());
5453 },
5454 0b1110 => {
5455 handler.on_opcode_decoded(Opcode::Round)?;
5456 },
5457 0b1111 => {
5458 handler.on_opcode_decoded(Opcode::Round)?;
5459 handler.saturate()?;
5460 },
5461 _ => {
5462 opcode_check!(false);
5463 }
5464 }
5465
5466 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
5467 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
5468 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
5469 }
5470 0b0111 => {
5471 let op_hi = (inst >> 21) & 0b111;
5472 let op_lo = (inst >> 5) & 0b111;
5473
5474 handler.on_dest_decoded(Operand::pred(reg_b0(inst) & 0b11))?;
5475 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
5476 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
5477
5478 if op_hi < 0b110 {
5479 if op_hi & 0b001 == 1 {
5480 handler.negate_result()?;
5481 }
5482 match op_hi >> 1 {
5483 0b00 => {
5484 handler.on_opcode_decoded(Opcode::Tstbit)?;
5485 }
5486 0b01 => {
5487 handler.on_opcode_decoded(Opcode::Bitsset)?;
5488 }
5489 _ => {
5490 handler.on_opcode_decoded(Opcode::Bitsclr)?;
5491 }
5492 }
5493 } else if op_hi == 0b110 {
5494 static OPCODES: [Option<Opcode>; 8] = [
5495 None, None,
5496 Some(Opcode::CmpbGt), Some(Opcode::CmphGt),
5497 Some(Opcode::CmphEq), Some(Opcode::CmphGtu),
5498 Some(Opcode::CmpbEq), Some(Opcode::CmpbGtu),
5499 ];
5500 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo as usize]))?;
5501 } else {
5502 static OPCODES: [Option<Opcode>; 8] = [
5504 Some(Opcode::SfCmpGe), Some(Opcode::SfCmpUo),
5505 None, Some(Opcode::SfCmpEq),
5506 Some(Opcode::SfCmpGt), None,
5507 None, None,
5508 ];
5509 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo as usize]))?;
5510 }
5511 }
5512 0b1000 => {
5513 handler.on_opcode_decoded(Opcode::Insert)?;
5514 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
5515 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
5516 handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
5517 }
5518 0b1001 => {
5519 opcode_check!((inst >> 22) & 0b11 == 0b11);
5520 let minbits = (inst >> 6) & 0b11;
5521
5522 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
5523 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
5524 handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
5525
5526 if minbits == 0b00 {
5527 handler.on_opcode_decoded(Opcode::Extractu)?;
5528 } else if minbits == 0b01 {
5529 handler.on_opcode_decoded(Opcode::Extract)?;
5530 } else {
5531 opcode_check!(false);
5532 }
5533 }
5534 0b1010 => {
5535 let minbits = (inst >> 21) & 0b111;
5536 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
5537 if minbits & 0b100 == 0 {
5538 handler.on_opcode_decoded(Opcode::Insert)?;
5539 handler.on_dest_decoded(Operand::gprpair(reg_b0(inst))?)?;
5540 handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
5541 handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
5542 } else if minbits & 0b110 == 0b100 {
5543 opcode_check!((inst >> 5) & 0b111 == 0);
5544 handler.on_opcode_decoded(Opcode::Xor)?;
5545 handler.assign_mode(AssignMode::XorAssign)?;
5546 handler.on_dest_decoded(Operand::gprpair(reg_b0(inst))?)?;
5547 handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
5548 handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
5549 } else {
5550 opcode_check!(false);
5551 }
5552 }
5553 0b1011 => {
5554 let minbits = (inst >> 21) & 0b111;
5555 let op_bits = (inst >> 5) & 0b111;
5556 let xxxxx = reg_b0(inst);
5557 let ttttt = reg_b8(inst);
5558 let sssss = reg_b16(inst);
5559
5560 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
5561 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5562 handler.on_source_decoded(Operand::gpr(ttttt))?;
5563
5564 if minbits == 0b001 {
5565 static OPS: [Option<Opcode>; 16] = [
5566 None, Some(Opcode::Vrmaxh), Some(Opcode::Vrmaxw), None,
5567 None, Some(Opcode::Vrminh), Some(Opcode::Vrminw), None,
5568 None, Some(Opcode::Vrmaxuh), Some(Opcode::Vrmaxuw), None,
5569 None, Some(Opcode::Vrminuh), Some(Opcode::Vrminuw), Some(Opcode::Vrcnegh),
5570 ];
5571 let op_hi = (inst >> 13) & 1;
5572 let op = op_bits | (op_hi << 3);
5573 let op = decode_opcode!(OPS[op as usize]);
5574 handler.on_opcode_decoded(op)?;
5575 if op == Opcode::Vrcnegh {
5576 handler.assign_mode(AssignMode::AddAssign)?;
5577 }
5578 return Ok(());
5579 } else if minbits == 0b101 {
5580 handler.on_opcode_decoded(Opcode::Vrcrotate)?;
5581 handler.assign_mode(AssignMode::AddAssign)?;
5582 let i_lo = (inst >> 5) & 1;
5583 let i_hi = (inst >> 13) & 1;
5584 let ii = i_lo | (i_hi << 1);
5585 handler.on_source_decoded(Operand::imm_u8(ii as u8))?;
5586 return Ok(());
5587 }
5588
5589 let assign_mode = match minbits {
5590 0b000 => AssignMode::OrAssign,
5591 0b010 => AssignMode::AndAssign,
5592 0b011 => AssignMode::XorAssign,
5593 0b100 => AssignMode::SubAssign,
5594 0b110 => AssignMode::AddAssign,
5595 _ => {
5596 return Err(DecodeError::InvalidOpcode);
5597 }
5598 };
5599 let opc = match op_bits >> 1 {
5600 0b00 => Opcode::Asr,
5601 0b01 => Opcode::Lsr,
5602 0b10 => Opcode::Asl,
5603 _ => Opcode::Lsl,
5604 };
5605 handler.on_opcode_decoded(opc)?;
5606 handler.assign_mode(assign_mode)?;
5607 }
5608 0b1100 => {
5609 let minbits = (inst >> 22) & 0b11;
5610 let op_bits = (inst >> 6) & 0b11;
5611 let xxxxx = reg_b0(inst);
5612 let ttttt = reg_b8(inst);
5613 let sssss = reg_b16(inst);
5614
5615 let assign_mode = match minbits {
5616 0b00 => AssignMode::OrAssign,
5617 0b01 => AssignMode::AndAssign,
5618 0b10 => AssignMode::SubAssign,
5619 0b11 => AssignMode::AddAssign,
5620 _ => {
5621 return Err(DecodeError::InvalidOpcode);
5622 }
5623 };
5624 let opc = match op_bits {
5625 0b00 => Opcode::Asr,
5626 0b01 => Opcode::Lsr,
5627 0b10 => Opcode::Asl,
5628 _ => Opcode::Lsl,
5629 };
5630 handler.on_opcode_decoded(opc)?;
5631 handler.assign_mode(assign_mode)?;
5632 handler.on_dest_decoded(Operand::gpr(xxxxx))?;
5633 handler.on_source_decoded(Operand::gpr(sssss))?;
5634 handler.on_source_decoded(Operand::gpr(ttttt))?;
5635 }
5636 0b1101 |
5637 0b1110 |
5638 _ => { opcode_check!(false);
5640 }
5641 }
5642 }
5643 0b1101 => {
5644 let opc_hi = (inst >> 24) & 0b1111;
5645 let ddddd = reg_b0(inst);
5646 let ttttt = reg_b8(inst);
5647 let sssss = reg_b16(inst);
5648
5649 match opc_hi {
5650 0b0000 => {
5651 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5652 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5653 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5654 handler.on_opcode_decoded(Opcode::Parity)?;
5655 }
5656 0b0001 => {
5657 let uu = ((inst >> 5) & 0b11) as u8;
5658 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
5659 handler.on_source_decoded(Operand::pred(uu))?;
5660 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5661 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5662 handler.on_opcode_decoded(Opcode::Vmux)?;
5663 }
5664 0b0010 => {
5665 let vector = inst & 0x80_00_00 == 0;
5666
5667 let ophi = (inst >> 13) & 1;
5668 let oplo = (inst >> 5) & 0b111;
5669 let opc = oplo | (ophi << 3);
5670 let dd = (ddddd & 0b11) as u8;
5671
5672 if vector {
5673 handler.on_dest_decoded(Operand::pred(dd))?;
5674 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5675 if opc != 0b1011 {
5676 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5677 } else {
5678 handler.on_source_decoded(Operand::gpr(ttttt))?;
5679 }
5680
5681 match opc {
5682 0b0000 => {
5683 handler.on_opcode_decoded(Opcode::VcmpwEq)?;
5684 }
5685 0b0001 => {
5686 handler.on_opcode_decoded(Opcode::VcmpwGt)?;
5687 }
5688 0b0010 => {
5689 handler.on_opcode_decoded(Opcode::VcmpwGtu)?;
5690 }
5691 0b0011 => {
5692 handler.on_opcode_decoded(Opcode::VcmphEq)?;
5693 }
5694 0b0100 => {
5695 handler.on_opcode_decoded(Opcode::VcmphGt)?;
5696 }
5697 0b0101 => {
5698 handler.on_opcode_decoded(Opcode::VcmphGtu)?;
5699 }
5700 0b0110 => {
5701 handler.on_opcode_decoded(Opcode::VcmpbEq)?;
5702 }
5703 0b0111 => {
5704 handler.on_opcode_decoded(Opcode::VcmpbGtu)?;
5705 }
5706 0b1000 => {
5707 handler.on_opcode_decoded(Opcode::Any8VcmpbEq)?;
5708 }
5709 0b1001 => {
5710 handler.on_opcode_decoded(Opcode::Any8VcmpbEq)?;
5711 handler.negate_result()?;
5712 }
5713 0b1010 => {
5714 handler.on_opcode_decoded(Opcode::VcmpbGt)?;
5715 }
5716 0b1011 => {
5717 handler.on_opcode_decoded(Opcode::Tlbmatch)?;
5718 }
5719 0b1100 => {
5720 handler.on_opcode_decoded(Opcode::Boundscheck)?;
5721 handler.raw_mode(RawMode::Lo)?;
5722 }
5723 0b1101 => {
5724 handler.on_opcode_decoded(Opcode::Boundscheck)?;
5725 handler.raw_mode(RawMode::Hi)?;
5726 }
5727 _ => {
5728 return Err(DecodeError::InvalidOpcode);
5729 }
5730 }
5731 } else {
5732 opcode_check!(inst & 0x00_60_00_00 == 0);
5733 handler.on_dest_decoded(Operand::pred(dd))?;
5734 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
5735 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
5736
5737 match oplo {
5738 0b000 => {
5739 handler.on_opcode_decoded(Opcode::CmpGt)?;
5740 }
5741 0b010 => {
5742 handler.on_opcode_decoded(Opcode::CmpEq)?;
5743 }
5744 0b0100 => {
5745 handler.on_opcode_decoded(Opcode::CmpGtu)?;
5746 }
5747 _ => {
5748 opcode_check!(false);
5749 }
5750 }
5751 }
5752 }
5753
5754 0b0011 => {
5755 let ddddd = reg_b0(inst);
5757 let ttttt = reg_b8(inst);
5758 let sssss = reg_b16(inst);
5759
5760 let op_lo = ((inst >> 5) & 0b111) as u8;
5761 let op_hi = ((inst >> 21) & 0b111) as u8;
5762
5763 type OpRes = Result<Operand, DecodeError>;
5764
5765 let do_decode_dst = |handler: &mut H, op: Opcode, dest: fn(u8) -> OpRes, op1: fn(u8) -> OpRes, op2: fn(u8) -> OpRes| {
5766 handler.on_opcode_decoded(op)?;
5767 handler.on_dest_decoded(dest(ddddd)?)?;
5768 handler.on_source_decoded(op1(sssss)?)?;
5769 handler.on_source_decoded(op2(ttttt)?)?;
5770 Ok::<(), DecodeError>(())
5771 };
5772
5773 let do_decode_dts = |handler: &mut H, op: Opcode, dest: fn(u8) -> OpRes, op1: fn(u8) -> OpRes, op2: fn(u8) -> OpRes| {
5774 handler.on_opcode_decoded(op)?;
5775 handler.on_dest_decoded(dest(ddddd)?)?;
5776 handler.on_source_decoded(op1(ttttt)?)?;
5777 handler.on_source_decoded(op2(sssss)?)?;
5778 Ok::<(), DecodeError>(())
5779 };
5780
5781 let opc = op_lo | (op_hi << 3);
5782 match opc {
5783 0b000000 => {
5784 do_decode_dst(handler, Opcode::Vaddub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5785 }
5786 0b000001 => {
5787 do_decode_dst(handler, Opcode::Vaddub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5788 handler.saturate()?;
5789 }
5790 0b000010 => {
5791 do_decode_dst(handler, Opcode::Vaddh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5792 }
5793 0b000011 => {
5794 do_decode_dst(handler, Opcode::Vaddh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5795 handler.saturate()?;
5796 }
5797 0b000100 => {
5798 do_decode_dst(handler, Opcode::Vadduh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5799 handler.saturate()?;
5800 }
5801 0b000101 => {
5802 do_decode_dst(handler, Opcode::Vaddw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5803 }
5804 0b000110 => {
5805 do_decode_dst(handler, Opcode::Vaddw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5806 handler.saturate()?;
5807 }
5808 0b000111 => {
5809 do_decode_dst(handler, Opcode::Add, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5810 }
5811 0b001000 => {
5812 do_decode_dts(handler, Opcode::Vsubub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5813 }
5814 0b001001 => {
5815 do_decode_dts(handler, Opcode::Vsubub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5816 handler.saturate()?;
5817 }
5818 0b001010 => {
5819 do_decode_dts(handler, Opcode::Vsubh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5820 }
5821 0b001011 => {
5822 do_decode_dts(handler, Opcode::Vsubh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5823 handler.saturate()?;
5824 }
5825 0b001100 => {
5826 do_decode_dts(handler, Opcode::Vsubuh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5827 handler.saturate()?;
5828 }
5829 0b001101 => {
5830 do_decode_dts(handler, Opcode::Vsubw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5831 }
5832 0b001110 => {
5833 do_decode_dts(handler, Opcode::Vsubw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5834 handler.saturate()?;
5835 }
5836 0b001111 => {
5837 do_decode_dts(handler, Opcode::Sub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5838 }
5839 0b010000 => {
5840 do_decode_dst(handler, Opcode::Vavgub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5841 }
5842 0b010001 => {
5843 do_decode_dst(handler, Opcode::Vavgub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5844 handler.rounded(RoundingMode::Round)?;
5845 }
5846 0b010010 => {
5847 do_decode_dst(handler, Opcode::Vavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5848 }
5849 0b010011 => {
5850 do_decode_dst(handler, Opcode::Vavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5851 handler.rounded(RoundingMode::Round)?;
5852 }
5853 0b010100 => {
5854 do_decode_dst(handler, Opcode::Vavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5855 handler.rounded(RoundingMode::Cround)?;
5856 }
5857 0b010101 => {
5858 do_decode_dst(handler, Opcode::Vavguh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5859 }
5860 0b010110 | 0b010111 => {
5861 do_decode_dst(handler, Opcode::Vavguh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5862 handler.rounded(RoundingMode::Round)?;
5863 }
5864 0b011000 => {
5865 do_decode_dst(handler, Opcode::Vavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5866 }
5867 0b011001 => {
5868 do_decode_dst(handler, Opcode::Vavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5869 handler.rounded(RoundingMode::Round)?;
5870 }
5871 0b011010 => {
5872 do_decode_dst(handler, Opcode::Vavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5873 handler.rounded(RoundingMode::Cround)?;
5874 }
5875 0b011011 => {
5876 do_decode_dst(handler, Opcode::Vavguw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5877 }
5878 0b011100 => {
5879 do_decode_dst(handler, Opcode::Vavguw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5880 handler.rounded(RoundingMode::Round)?;
5881 }
5882 0b011101 => {
5883 do_decode_dst(handler, Opcode::Add, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5884 handler.saturate()?;
5885 }
5886 0b011110 => {
5887 do_decode_dst(handler, Opcode::Add, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5888 handler.raw_mode(RawMode::Lo)?;
5889 }
5890 0b011111 => {
5891 do_decode_dst(handler, Opcode::Add, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5892 handler.raw_mode(RawMode::Hi)?;
5893 }
5894 0b100000 => {
5895 do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5896 }
5897 0b100001 => {
5898 do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5899 handler.rounded(RoundingMode::Round)?;
5900 handler.saturate()?;
5901 }
5902 0b100010 => {
5903 do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5904 handler.rounded(RoundingMode::Cround)?;
5905 handler.saturate()?;
5906 }
5907 0b100011 => {
5908 do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5909 }
5910 0b100100 | 0b100101 => {
5912 do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5913 handler.rounded(RoundingMode::Round)?;
5914 handler.saturate()?;
5915 }
5916 0b100110 | 0b100111 => {
5918 do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5919 handler.rounded(RoundingMode::Cround)?;
5920 handler.saturate()?;
5921 }
5922 0b101000 => {
5923 do_decode_dts(handler, Opcode::Vminub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5924 }
5925 0b101001 => {
5926 do_decode_dts(handler, Opcode::Vminh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5927 }
5928 0b101010 => {
5929 do_decode_dts(handler, Opcode::Vminuh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5930 }
5931 0b101011 => {
5932 do_decode_dts(handler, Opcode::Vminw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5933 }
5934 0b101100 => {
5935 do_decode_dts(handler, Opcode::Vminuw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5936 }
5937 0b101101 => {
5938 do_decode_dts(handler, Opcode::Vmaxuw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5939 }
5940 0b101110 => {
5941 do_decode_dts(handler, Opcode::Min, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5942 }
5943 0b101111 => {
5944 do_decode_dts(handler, Opcode::Minu, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5945 }
5946 0b110000 => {
5947 do_decode_dts(handler, Opcode::Vmaxub, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5948 }
5949 0b110001 => {
5950 do_decode_dts(handler, Opcode::Vmaxh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5951 }
5952 0b110010 => {
5953 do_decode_dts(handler, Opcode::Vmaxuh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5954 }
5955 0b110011 => {
5956 do_decode_dts(handler, Opcode::Vmaxw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5957 }
5958 0b110100 => {
5959 do_decode_dst(handler, Opcode::Max, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5960 }
5961 0b110101 => {
5962 do_decode_dst(handler, Opcode::Maxu, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5963 }
5964 0b110110 => {
5965 do_decode_dts(handler, Opcode::Vmaxb, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5966 }
5967 0b110111 => {
5968 do_decode_dts(handler, Opcode::Vminb, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5969 }
5970 0b111000 => {
5971 do_decode_dst(handler, Opcode::And, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5972 }
5973 0b111001 => {
5974 do_decode_dst(handler, Opcode::And_RnR, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5975 }
5976 0b111010 => {
5977 do_decode_dst(handler, Opcode::Or, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5978 }
5979 0b111011 => {
5980 do_decode_dst(handler, Opcode::Or_RnR, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5981 }
5982 0b111100 => {
5983 do_decode_dst(handler, Opcode::Xor, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
5984 }
5985 0b111111 => {
5986 handler.on_opcode_decoded(Opcode::Modwrap)?;
5987 handler.on_dest_decoded(Operand::gpr(ddddd))?;
5988 handler.on_source_decoded(Operand::gpr(sssss))?;
5989 handler.on_source_decoded(Operand::gpr(ttttt))?;
5990 }
5991 _ => {
5992 return Err(DecodeError::InvalidOpcode);
5993 }
5994 }
5995 }
5996 0b0100 => {
5997 let ddddd = reg_b0(inst);
5999 let ttttt = reg_b8(inst);
6000 let sssss = reg_b16(inst);
6001
6002 opcode_check!((inst >> 21) & 1 == 1);
6003
6004 handler.on_opcode_decoded(Opcode::Bitsplit)?;
6005 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6006 handler.on_source_decoded(Operand::gpr(sssss))?;
6007 handler.on_source_decoded(Operand::gpr(ttttt))?;
6008 }
6009 0b0101 => {
6010 let ddddd = reg_b0(inst);
6012 let ttttt = reg_b8(inst);
6013 let sssss = reg_b16(inst);
6014
6015 let op_hi = (inst >> 21) & 0b111;
6016 let op_lo = (inst >> 5) & 0b111;
6017
6018 if op_hi < 0b100 {
6019 let addsub = op_hi & 0b001;
6020 let shl = op_hi & 0b010 != 0;
6021 let sat = op_lo & 0b100 != 0;
6022
6023 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6024
6025 if addsub == 0 {
6026 handler.on_opcode_decoded(Opcode::Add)?;
6027 } else {
6028 handler.on_opcode_decoded(Opcode::Sub)?;
6029 }
6030
6031 if sat {
6032 handler.saturate()?;
6033 }
6034
6035 if shl {
6036 handler.shift_left(16)?;
6038 if op_lo & 0b010 == 0 {
6039 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
6040 } else {
6041 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
6042 }
6043 if op_lo & 0b001 == 0 {
6044 handler.on_source_decoded(Operand::gpr_low(sssss))?;
6045 } else {
6046 handler.on_source_decoded(Operand::gpr_high(sssss))?;
6047 }
6048 } else {
6049 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
6051 if op_lo & 0b010 == 0 {
6052 handler.on_source_decoded(Operand::gpr_low(sssss))?;
6053 } else {
6054 handler.on_source_decoded(Operand::gpr_high(sssss))?;
6055 }
6056 }
6057 } else {
6058 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6059 let op = ((inst >> 7) & 1) | (op_hi & 0b11) << 1;
6060 if op == 0b001 {
6061 handler.on_source_decoded(Operand::gpr(ttttt))?;
6062 handler.on_source_decoded(Operand::gpr(sssss))?;
6063 } else {
6064 handler.on_source_decoded(Operand::gpr(sssss))?;
6065 handler.on_source_decoded(Operand::gpr(ttttt))?;
6066 }
6067 match op {
6068 0b000 => {
6069 handler.on_opcode_decoded(Opcode::Add)?;
6070 handler.saturate()?;
6071 handler.deprecated()?;
6072 }
6073 0b001 => {
6074 handler.on_opcode_decoded(Opcode::Sub)?;
6075 handler.saturate()?;
6076 handler.deprecated()?;
6077 }
6078 0b010 => {
6079 handler.on_opcode_decoded(Opcode::Min)?;
6080 }
6081 0b011 => {
6082 handler.on_opcode_decoded(Opcode::Minu)?;
6083 }
6084 0b100 => {
6085 handler.on_opcode_decoded(Opcode::Max)?;
6086 }
6087 0b101 => {
6088 handler.on_opcode_decoded(Opcode::Maxu)?;
6089 }
6090 _o => {
6091 handler.on_opcode_decoded(Opcode::Parity)?;
6092 }
6093 }
6094 }
6095 }
6096 0b0110 => {
6097 let op_hi = (inst >> 21) & 0b111;
6099 let op_lo = (inst >> 5) & 0b111;
6100
6101 if op_hi & 0b100 == 0 {
6102 let i9 = (inst >> 5) & 0b1_1111_1111;
6103 let i_hi = (inst >> 21) & 1;
6104 let i = i9 | (i_hi << 9);
6105
6106 handler.on_opcode_decoded(Opcode::SfMake)?;
6107 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
6108 handler.on_source_decoded(Operand::imm_u16(i as u16))?;
6109 if op_hi & 0b010 == 0 {
6110 handler.rounded(RoundingMode::Pos)?;
6111 } else {
6112 handler.rounded(RoundingMode::Neg)?;
6113 }
6114 } else {
6115 opcode_check!(op_hi == 0b111);
6116 static OPCODES: [Option<Opcode>; 8] = [
6117 Some(Opcode::DfCmpEq), Some(Opcode::DfCmpGt), None, Some(Opcode::DfCmpGe),
6118 Some(Opcode::DfCmpUo), None, None, None,
6119 ];
6120
6121 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo as usize]))?;
6122 handler.on_dest_decoded(Operand::pred(reg_b0(inst) & 0b11))?;
6123 handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
6124 handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
6125 }
6126 }
6127 0b0111 => {
6128 let ddddd = reg_b0(inst);
6130 let ttttt = reg_b8(inst);
6131 let sssss = reg_b16(inst);
6132
6133 opcode_check!(inst & 0x80_00_00 == 0);
6134
6135 let i_lo = (inst >> 5) & 0b111;
6136 let i_mid = (inst >> 13) & 0b1;
6137 let i_hi = (inst >> 21) & 0b11;
6138 let i = i_lo | (i_mid << 3) | (i_hi << 4);
6139
6140 handler.on_opcode_decoded(Opcode::AddMpyi)?;
6141 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6142 handler.on_source_decoded(
6143 Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))?
6144 )?;
6145 handler.on_source_decoded(Operand::gpr(sssss))?;
6146 handler.on_source_decoded(Operand::gpr(ttttt))?;
6147 }
6148 0b1000 => {
6149 let lllll = reg_b0(inst);
6151 let ddddd = reg_b8(inst);
6152 let sssss = reg_b16(inst);
6153
6154 let l_hi = ((inst >> 23) & 0b1) as u8;
6155 let l = lllll | (l_hi << 5);
6156
6157 let i_lo = (inst >> 5) & 0b111;
6158 let i_mid = (inst >> 13) & 0b1;
6159 let i_hi = (inst >> 21) & 0b11;
6160 let i = i_lo | (i_mid << 3) | (i_hi << 4);
6161
6162 handler.on_opcode_decoded(Opcode::AddMpyi)?;
6163 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6164 handler.on_source_decoded(
6165 Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))?
6166 )?;
6167 handler.on_source_decoded(Operand::gpr(sssss))?;
6168 handler.on_source_decoded(Operand::imm_u8(l as u8))?;
6169 }
6170 0b1001 => {
6171 let ddddd = reg_b0(inst);
6173
6174 let i9 = (inst >> 5) & 0b1_1111_1111;
6175 let i_hi = (inst >> 21) & 1;
6176 let i10 = i9 | (i_hi << 9);
6177 let i = (i10 as u16) << 6 >> 6;
6178
6179 let op = (inst >> 22) & 0b11;
6180
6181 opcode_check!(op & 0b10 == 0);
6182
6183 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6184 handler.on_opcode_decoded(Opcode::DfMake)?;
6185 handler.on_source_decoded(Operand::imm_u16(i))?;
6186 if op == 0 {
6187 handler.rounded(RoundingMode::Pos)?;
6188 } else {
6189 handler.rounded(RoundingMode::Neg)?;
6190 }
6191 }
6192 0b1010 => {
6193 let uuuuu = reg_b0(inst);
6195 let sssss = reg_b16(inst);
6196
6197 let op = (inst >> 22) & 0b11;
6198
6199 match op {
6200 0b00 => {
6201 let i9 = (inst >> 5) & 0b1_1111_1111;
6202 let i_hi = (inst >> 21) & 1;
6203 let i10 = i9 | (i_hi << 9);
6204 let i = (i10 as i16) << 6 >> 6;
6205 handler.on_opcode_decoded(Opcode::And)?;
6206 handler.assign_mode(AssignMode::OrAssign)?;
6207 handler.on_dest_decoded(Operand::gpr(uuuuu))?;
6208 handler.on_source_decoded(Operand::gpr(sssss))?;
6209 handler.on_source_decoded(Operand::imm_i16(i))?;
6210 }
6211 0b01 => {
6212 let i9 = (inst >> 5) & 0b1_1111_1111;
6213 let i_hi = (inst >> 21) & 1;
6214 let i10 = i9 | (i_hi << 9);
6215 handler.on_opcode_decoded(Opcode::OrAnd)?;
6216 handler.on_dest_decoded(Operand::gpr(reg_b16(inst)))?;
6217 handler.on_source_decoded(Operand::gpr(reg_b0(inst)))?;
6218 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
6219 handler.on_source_decoded(
6220 Operand::immext(i10, extender, |i| Ok(Operand::imm_i16((i as i16) << 6 >> 6)))?
6221 )?;
6222 }
6223 0b10 => {
6224 let i9 = (inst >> 5) & 0b1_1111_1111;
6225 let i_hi = (inst >> 21) & 1;
6226 let i10 = i9 | (i_hi << 9);
6227 let i = (i10 as i16) << 6 >> 6;
6228 handler.on_opcode_decoded(Opcode::Or)?;
6229 handler.assign_mode(AssignMode::OrAssign)?;
6230 handler.on_dest_decoded(Operand::gpr(uuuuu))?;
6231 handler.on_source_decoded(Operand::gpr(sssss))?;
6232 handler.on_source_decoded(Operand::imm_i16(i))?;
6233 }
6234 _ => {
6235 return Err(DecodeError::InvalidOpcode);
6236 }
6237 }
6238 }
6239 0b1011 => {
6240 let uuuuu = reg_b0(inst);
6242 let ddddd = reg_b8(inst);
6243 let sssss = reg_b16(inst);
6244
6245 let i_lo = (inst >> 5) & 0b111;
6246 let i_mid = (inst >> 13) & 0b1;
6247 let i_hi = (inst >> 21) & 0b11;
6248 let i = i_lo | (i_mid << 3) | (i_hi << 4);
6249
6250 let op = (inst >> 23) & 1;
6251
6252 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6253 handler.on_source_decoded(Operand::gpr(sssss))?;
6254 if op == 0 {
6255 handler.on_opcode_decoded(Opcode::AddAdd)?;
6256 handler.on_source_decoded(Operand::gpr(uuuuu))?;
6257 handler.on_source_decoded(
6258 Operand::immext(i, extender, |i| Ok(Operand::imm_i8((i as i8) << 2 >> 2)))?
6259 )?;
6260 } else {
6261 handler.on_opcode_decoded(Opcode::AddSub)?;
6262 handler.on_source_decoded(
6263 Operand::immext(i, extender, |i| Ok(Operand::imm_i8((i as i8) << 2 >> 2)))?
6264 )?;
6265 handler.on_source_decoded(Operand::gpr(uuuuu))?;
6266 }
6267 }
6268 0b1100 => {
6269 let dd = (inst & 0b11) as u8;
6271 let imm = (inst >> 5) & 0b1111_1111;
6272 let sssss = reg_b16(inst);
6273 let op_lo = (inst >> 3) & 0b11;
6274 let op_hi = (inst >> 21) & 0b111;
6275 let opc = op_lo | (op_hi << 2);
6276
6277 handler.on_dest_decoded(Operand::pred(dd))?;
6278 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6279 if opc >= 0b10000 {
6280 operand_check!(imm < 0b100000);
6281 } else if opc >= 0b1000 {
6282 operand_check!(imm < 0b10000000);
6283 }
6284 handler.on_source_decoded(Operand::imm_u8(imm as u8))?;
6285
6286 const OPCODES: [Option<Opcode>; 32] = [
6287 Some(Opcode::VcmpbEq), Some(Opcode::VcmphEq), Some(Opcode::VcmpwEq), None,
6288 Some(Opcode::VcmpbGt), Some(Opcode::VcmphGt), Some(Opcode::VcmpwGt), None,
6289 Some(Opcode::VcmpbGtu), Some(Opcode::VcmphGtu), Some(Opcode::VcmpwGtu), None,
6291 None, None, None, None,
6292 None, None, Some(DfClass), None,
6294 None, None, None, None,
6295 None, None, None, None,
6296 None, None, None, None,
6297 ];
6298
6299 handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?;
6300 }
6301 0b1101 => {
6302 let dd = (inst & 0b11) as u8;
6303 let imm = (inst >> 5) & 0b1111_1111;
6304 let sssss = reg_b16(inst);
6305 let op_lo = ((inst >> 3) & 0b11) as u8;
6306 let op_hi = ((inst >> 21) & 0b11) as u8;
6307
6308 const OPCODES: [Option<Opcode>; 16] = [
6309 Some(Opcode::CmpbGt), Some(Opcode::CmphGt), None, None,
6310 Some(Opcode::CmpbEq), Some(Opcode::CmphEq), None, None,
6311 Some(Opcode::CmpbGtu), Some(Opcode::CmphGtu), None, None,
6312 None, None, None, None,
6313 ];
6314
6315 let opc = op_lo | (op_hi << 2);
6316
6317 handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?;
6318 handler.on_dest_decoded(Operand::pred(dd))?;
6319 handler.on_source_decoded(Operand::gpr(sssss))?;
6320 if opc & 0b10_00 != 0 {
6321 operand_check!(imm < 0b1000_0000);
6322 }
6323 handler.on_source_decoded(
6324 Operand::immext(imm, extender, |imm| Ok(Operand::imm_u8(imm as u8)))?
6325 )?;
6326 }
6327 0b1110 => {
6328 let xxxxx = reg_b16(inst);
6329 let op_lo = (inst >> 1) & 0b11;
6330 let op_hi = (inst >> 4) & 0b1;
6331 let opc = op_lo | (op_hi << 2);
6332 let i_lo = (inst >> 3) & 0b1;
6333 let i_lo3 = (inst >> 5) & 0b111;
6334 let i_mid = (inst >> 13) & 0b1;
6335 let i_hi = (inst >> 21) & 0b11;
6336 let i = i_lo | (i_lo3 << 1) | (i_mid << 4) | (i_hi << 6);
6337 let u5 = reg_b8(inst);
6338
6339 handler.on_dest_decoded(Operand::gpr(xxxxx))?;
6340 handler.on_source_decoded(
6341 Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))?
6342 )?;
6343 handler.on_source_decoded(Operand::gpr(xxxxx))?;
6344 handler.on_source_decoded(Operand::imm_u8(u5))?;
6345
6346 const OPCODES: [Opcode; 8] = [
6347 AndAsl, OrAsl,
6348 AddAsl, SubAsl,
6349 AndLsr, OrLsr,
6350 AddLsr, SubLsr,
6351 ];
6352
6353 handler.on_opcode_decoded(OPCODES[opc as usize])?;
6354 }
6355 0b1111 => {
6356 let order = (inst >> 23) & 1;
6357 let uuuuu = reg_b0(inst);
6358 let ddddd = reg_b8(inst);
6359 let sssss = reg_b16(inst);
6360 let i_lo = (inst >> 5) & 0b111;
6361 let i_mid = (inst >> 13) & 0b1;
6362 let i_hi = (inst >> 21) & 0b11;
6363 let i6 = (i_lo | (i_mid << 3) | (i_hi << 4)) as u8;
6364
6365 handler.on_opcode_decoded(Opcode::AddMpyi)?;
6366 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6367 handler.on_source_decoded(Operand::gpr(uuuuu))?;
6368
6369 if order == 0 {
6370 handler.on_source_decoded(Operand::imm_u8(i6 << 2))?;
6371 handler.on_source_decoded(Operand::gpr(sssss))?;
6372 } else {
6373 handler.on_source_decoded(Operand::gpr(sssss))?;
6374 handler.on_source_decoded(Operand::imm_u8(i6 << 2))?;
6375 }
6376 }
6377 _ => {
6378 todo!("other");
6379 },
6380 }
6381 }
6382 0b1110 => {
6383 let ddddd = reg_b0(inst);
6384 let ttttt = reg_b8(inst);
6385 let sssss = reg_b16(inst);
6386
6387 let opc = (inst >> 24) & 0b1111;
6388
6389 let op_hi = ((inst >> 21) & 0b111) as u8;
6390 let op_lo = ((inst >> 5) & 0b111) as u8;
6391
6392 match opc {
6393 0b0000 => {
6394 operand_check!(inst & 0b10_0000 == 0);
6396 let i = (inst >> 5) & 0b1111_1111;
6397 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6398 handler.on_source_decoded(Operand::gpr(sssss))?;
6399 handler.on_source_decoded(Operand::imm_u8(i as u8))?;
6400 if op_hi < 0b100 {
6401 handler.on_opcode_decoded(Opcode::MpyiPos)?;
6402 } else {
6403 handler.on_opcode_decoded(Opcode::MpyiNeg)?;
6404 }
6405 }
6406 0b0001 => {
6407 operand_check!(inst & 0b10_0000 == 0);
6409 let i = (inst >> 5) & 0b1111_1111;
6410 handler.on_opcode_decoded(Opcode::Mpyi)?;
6411 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
6412 handler.on_source_decoded(Operand::gpr(sssss))?;
6413 handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_u8(i as u8)))?)?;
6414 if op_hi < 0b100 {
6415 handler.assign_mode(AssignMode::AddAssign)?;
6416 } else {
6417 handler.assign_mode(AssignMode::SubAssign)?;
6418 }
6419 }
6420 0b0010 => {
6421 operand_check!(inst & 0b10_0000 == 0);
6422 let i = (inst >> 5) & 0b1111_1111;
6423 handler.on_opcode_decoded(Opcode::Add)?;
6424 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
6425 handler.on_source_decoded(Operand::gpr(sssss))?;
6426 handler.on_source_decoded(Operand::immext(i, extender, |i| Ok(Operand::imm_i8(i as i8)))?)?;
6427 if op_hi < 0b100 {
6428 handler.assign_mode(AssignMode::AddAssign)?;
6429 } else {
6430 handler.assign_mode(AssignMode::SubAssign)?;
6431 }
6432 }
6433 0b0011 => {
6434 let uuuuu = reg_b0(inst);
6435 let yyyyy = reg_b8(inst);
6436 handler.on_opcode_decoded(Opcode::AddMpyi)?;
6437 handler.on_dest_decoded(Operand::gpr(yyyyy))?;
6438 handler.on_source_decoded(Operand::gpr(uuuuu))?;
6439 handler.on_source_decoded(Operand::gpr(yyyyy))?;
6440 handler.on_source_decoded(Operand::gpr(sssss))?;
6441 }
6442 0b0100 => {
6443 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6444 let opbits = op_hi & 0b11;
6445 match opbits {
6446 0b00 => {
6447 handler.on_opcode_decoded(Opcode::Mpy)?;
6448 }
6449 0b01 => {
6450 handler.on_opcode_decoded(Opcode::Mpy)?;
6451 handler.rounded(RoundingMode::Round)?;
6452 }
6453 0b10 => {
6454 handler.on_opcode_decoded(Opcode::Mpyu)?;
6455 }
6456 _ => {
6457 return Err(DecodeError::InvalidOpcode);
6458 }
6459 };
6460
6461 if op_lo & 0b10 == 0 {
6462 handler.on_source_decoded(Operand::gpr_low(sssss))?;
6463 } else {
6464 handler.on_source_decoded(Operand::gpr_high(sssss))?;
6465 }
6466 if op_lo & 0b01 == 0 {
6467 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
6468 } else {
6469 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
6470 }
6471
6472 let shift = (op_hi >> 2) & 1;
6473 if shift != 0 {
6474 handler.shift_left(shift)?;
6475 }
6476 }
6477 0b0101 => {
6478 let opc = op_lo | (op_hi << 3);
6481
6482 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6483
6484 let masked = opc & 0b011_111;
6485 if masked == 0b00101 {
6486 handler.on_opcode_decoded(Opcode::Vmpyh)?;
6487 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6488 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6489 let shift = opc >> 5;
6490 if shift != 0 {
6491 handler.shift_left((opc >> 5) as u8)?;
6492 }
6493 handler.saturate()?;
6494 return Ok(());
6495 }
6496
6497 handler.on_source_decoded(Operand::gpr(sssss))?;
6498
6499 if masked == 0b00110 {
6500 handler.on_opcode_decoded(Opcode::Cmpy)?;
6501 handler.on_source_decoded(Operand::gpr(ttttt))?;
6502 handler.shift_left((opc >> 5) as u8)?;
6503 handler.saturate()?;
6504 return Ok(());
6505 } else if masked == 0b00111 {
6506 handler.on_opcode_decoded(Opcode::Vmpyhsu)?;
6507 handler.on_source_decoded(Operand::gpr(ttttt))?;
6508 handler.shift_left((opc >> 5) as u8)?;
6509 handler.saturate()?;
6510 return Ok(());
6511 } else if masked == 0b10110 {
6512 handler.on_opcode_decoded(Opcode::Cmpy)?;
6513 handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?;
6514 handler.shift_left((opc >> 5) as u8)?;
6515 handler.saturate()?;
6516 return Ok(());
6517 }
6518
6519 handler.on_source_decoded(Operand::gpr(ttttt))?;
6520
6521 static OPCODES: [Option<Opcode>; 64] = [
6522 Some(Mpy), Some(Cmpyi), Some(Cmpyr), None, None, None, None, None,
6523 None, None, None, None, None, None, None, None,
6524 Some(Mpyu), Some(Vmpybsu), None, None, None, None, None, Some(Pmpyw),
6525 None, None, None, None, None, None, None, None,
6526 None, Some(Vmpybu), None, None, None, None, None, None,
6527 None, None, None, None, None, None, None, None,
6528 None, None, None, None, None, None, None, Some(Vpmpyh),
6529 None, None, None, None, None, None, None, None,
6530 ];
6531
6532 handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?;
6533 }
6534 0b0110 => {
6535 if op_hi & 0b010 == 0 {
6538 handler.on_opcode_decoded(Opcode::Mpy)?;
6539 } else {
6540 handler.on_opcode_decoded(Opcode::Mpyu)?;
6541 }
6542 if op_hi & 0b001 == 0 {
6543 handler.assign_mode(AssignMode::AddAssign)?;
6544 } else {
6545 handler.assign_mode(AssignMode::SubAssign)?;
6546 }
6547
6548 operand_check!(op_lo & 0b100 == 0);
6549 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6550 if op_lo & 0b10 == 0 {
6551 handler.on_source_decoded(Operand::gpr_low(sssss))?;
6552 } else {
6553 handler.on_source_decoded(Operand::gpr_high(sssss))?;
6554 }
6555 if op_lo & 0b01 == 0 {
6556 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
6557 } else {
6558 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
6559 }
6560
6561 handler.shift_left((op_hi >> 2) & 1)?;
6562 }
6563 0b0111 => {
6564 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
6565 let xxxxx = reg_b0(inst);
6566 let ttttt = reg_b8(inst);
6567 let sssss = reg_b16(inst);
6568
6569 match op_lo {
6570 0b000 => {
6571 opcode_check!(op_hi & 0b100 == 0);
6572 if op_hi & 0b010 == 0 {
6573 handler.on_opcode_decoded(Opcode::Mpy)?;
6574 } else {
6575 handler.on_opcode_decoded(Opcode::Mpyu)?;
6576 }
6577 if op_hi & 0b001 == 0 {
6578 handler.assign_mode(AssignMode::AddAssign)?;
6579 } else {
6580 handler.assign_mode(AssignMode::SubAssign)?;
6581 }
6582 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6583 handler.on_source_decoded(Operand::gpr(sssss))?;
6584 handler.on_source_decoded(Operand::gpr(ttttt))?;
6585 }
6586 0b001 => {
6587 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6588 if op_hi == 0b000 {
6589 handler.on_source_decoded(Operand::gpr(sssss))?;
6590 handler.on_source_decoded(Operand::gpr(ttttt))?;
6591 } else {
6592 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6593 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6594 }
6595 static OPCODES: [Option<Opcode>; 8] = [
6596 Some(Cmpyi), Some(Vmpyh), None, None,
6597 Some(Vmpybu), None, Some(Vmpybsu), None,
6598 ];
6599 handler.assign_mode(AssignMode::AddAssign)?;
6600 handler.on_opcode_decoded(decode_opcode!(OPCODES[op_hi as usize]))?;
6601 }
6602 0b010 => {
6603 opcode_check!(op_hi == 0);
6604 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6605 handler.on_source_decoded(Operand::gpr(sssss))?;
6606 handler.on_source_decoded(Operand::gpr(ttttt))?;
6607 handler.assign_mode(AssignMode::AddAssign)?;
6608 handler.on_opcode_decoded(Opcode::Cmpyr)?;
6609 }
6610 0b101 => {
6611 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6612 handler.shift_left(op_hi >> 2)?;
6613 handler.saturate()?;
6614 handler.assign_mode(AssignMode::AddAssign)?;
6615
6616 match op_hi & 0b11 {
6617 0b00 => {
6618 handler.on_opcode_decoded(Opcode::Vmpyh)?;
6619 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6620 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6621 }
6622 0b11 => {
6623 handler.on_opcode_decoded(Opcode::Vmpyhsu)?;
6624 handler.on_source_decoded(Operand::gpr(sssss))?;
6625 handler.on_source_decoded(Operand::gpr(ttttt))?;
6626 }
6627 _ => { return Err(DecodeError::InvalidOpcode); }
6628 }
6629 }
6630 0b110 => {
6631 handler.on_opcode_decoded(Opcode::Cmpy)?;
6632 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6633 handler.on_source_decoded(Operand::gpr(sssss))?;
6634 if op_hi & 0b010 == 0 {
6635 handler.on_source_decoded(Operand::gpr(ttttt))?;
6636 } else {
6637 handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?;
6638 }
6639 handler.assign_mode(AssignMode::AddAssign)?;
6640 handler.shift_left(op_hi >> 2)?;
6641 handler.saturate()?;
6642 }
6643 0b111 => {
6644 handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?;
6645 handler.on_source_decoded(Operand::gpr(sssss))?;
6646 if op_hi & 0b011 == 0b010 {
6647 handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?;
6648 } else {
6649 handler.on_source_decoded(Operand::gpr(ttttt))?;
6650 }
6651 match op_hi {
6652 0b000 | 0b100 |
6653 0b010 | 0b110 => {
6654 handler.assign_mode(AssignMode::SubAssign)?;
6655 handler.saturate()?;
6656 handler.on_opcode_decoded(Opcode::Cmpy)?;
6657 handler.shift_left(op_hi >> 2)?;
6658 }
6659 0b001 => {
6660 handler.assign_mode(AssignMode::XorAssign)?;
6661 handler.on_opcode_decoded(Opcode::Pmpyw)?;
6662 }
6663 0b101 => {
6664 handler.assign_mode(AssignMode::XorAssign)?;
6665 handler.on_opcode_decoded(Opcode::Vpmpyh)?;
6666 }
6667 _ => {
6668 return Err(DecodeError::InvalidOpcode);
6669 }
6670 }
6671 }
6672 _ => {
6673 return Err(DecodeError::InvalidOpcode);
6674 }
6675 }
6676 }
6677 0b1000 => {
6678 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
6680 let ddddd = reg_b0(inst);
6681 let ttttt = reg_b8(inst);
6682 let sssss = reg_b16(inst);
6683
6684 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6685
6686 if op_lo & 0b100 == 0b100 || (op_lo == 0b010 && op_hi & 0b011 == 0b001) {
6687 let n = (op_hi >> 2) & 1;
6689 handler.shift_left(n)?;
6690 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6691 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6692
6693 if op_lo == 0b010 && op_hi & 0b011 == 0b001 {
6694 handler.on_opcode_decoded(Vrmpywoh)?;
6695 } else {
6696 let opc = (op_lo & 0b11) | ((op_hi & 0b11) << 2);
6697 match opc {
6698 0b0000 => {
6699 handler.on_opcode_decoded(Vdmpy)?;
6700 handler.saturate()?;
6701 }
6702 0b0001 => {
6703 handler.on_opcode_decoded(Vmpyweh)?;
6704 handler.saturate()?;
6705 }
6706 0b0010 => {
6707 handler.on_opcode_decoded(Vmpyeh)?;
6708 handler.saturate()?;
6709 }
6710 0b0011 => {
6711 handler.on_opcode_decoded(Vmpywoh)?;
6712 handler.saturate()?;
6713 }
6714 0b0100 => {
6715 opcode_check!(op_hi & 0b100 != 0);
6716 handler.on_opcode_decoded(Vrcmpys)?;
6717 handler.saturate()?;
6718 handler.raw_mode(RawMode::Hi)?;
6719 }
6720 0b0101 => {
6721 handler.on_opcode_decoded(Vmpyweh)?;
6722 handler.saturate()?;
6723 handler.rounded(RoundingMode::Round)?;
6724 }
6725 0b0110 => {
6726 handler.on_opcode_decoded(Vcmpyr)?;
6727 handler.saturate()?;
6728 }
6729 0b0111 => {
6730 handler.on_opcode_decoded(Vmpywoh)?;
6731 handler.saturate()?;
6732 handler.rounded(RoundingMode::Round)?;
6733 }
6734 0b1000 => {
6735 handler.on_opcode_decoded(Vrmpywoh)?;
6736 }
6737 0b1001 => {
6738 handler.on_opcode_decoded(Vmpyweuh)?;
6739 handler.saturate()?;
6740 }
6741 0b1010 => {
6742 handler.on_opcode_decoded(Vcmpyi)?;
6743 handler.saturate()?;
6744 }
6745 0b1011 => {
6746 handler.on_opcode_decoded(Vmpywouh)?;
6747 handler.saturate()?;
6748 }
6749 0b1100 => {
6750 opcode_check!(inst & 0b100 != 0);
6751 handler.on_opcode_decoded(Vrcmpys)?;
6752 handler.saturate()?;
6753 handler.raw_mode(RawMode::Lo)?;
6754 }
6755 0b1101 => {
6756 handler.on_opcode_decoded(Vmpyweuh)?;
6757 handler.rounded(RoundingMode::Round)?;
6758 handler.saturate()?;
6759 }
6760 0b1111 => {
6761 handler.on_opcode_decoded(Vmpywouh)?;
6762 handler.rounded(RoundingMode::Round)?;
6763 handler.saturate()?;
6764 }
6765 _ => {
6766 return Err(DecodeError::InvalidOpcode);
6767 }
6768 }
6769 }
6770 } else {
6771 static OPCODES: [Option<Opcode>; 32] = [
6772 None, None, Some(Vrmpyh), Some(DfAdd),
6773 Some(Vabsdiffw), None, None, Some(DfMax),
6774 None, Some(Vraddub), Some(Vrsadub), Some(DfMpyfix),
6775 Some(Vabsdiffh), None, Some(Cmpyiw), None,
6776 None, Some(Vrmpyu), Some(Cmpyrw), Some(DfSub),
6777 Some(Vabsdiffub), Some(Vdmpybsu), None, Some(DfMpyll),
6778 None, Some(Vrmpysu), Some(Cmpyrw), Some(DfMin),
6779 Some(Vabsdiffb), None, Some(Cmpyiw), None,
6780 ];
6781 let opc = (op_lo & 0b11) | (op_hi << 2);
6782 handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?;
6783
6784 if opc == 0b0101 || opc == 0b10101 {
6785 handler.saturate()?;
6786 }
6787
6788 if (op_lo & 0b11) == 0b00 {
6789 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6790 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6791 } else if opc == 0b11010 || opc == 0b11110 {
6792 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6793 handler.on_source_decoded(Operand::gprpair_conjugate(ttttt)?)?;
6794 } else {
6795 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6796 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6797 }
6798 }
6799 }
6800 0b1001 => {
6801 let opc = op_lo | (op_hi << 3);
6803
6804 let mut rtt_star = false;
6805 let mut saturate = true;
6806 let mut shift_amt = 1;
6807
6808 handler.on_dest_decoded(Operand::gpr(ddddd))?;
6809 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6810
6811 match opc {
6812 o if o & 0b100011 == 0b000001 => {
6813 handler.on_opcode_decoded(Opcode::Vradduh)?;
6814 saturate = false;
6815 shift_amt = 0;
6816 }
6817 o if o & 0b101111 == 0b001111 => {
6818 handler.on_opcode_decoded(Opcode::Vraddh)?;
6819 saturate = false;
6820 shift_amt = 0;
6821 }
6822 0b000100 => {
6823 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6824 rtt_star = true;
6825 }
6826 0b001000 => {
6827 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6828 }
6829 0b010000 => {
6830 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6831 }
6832 0b011000 => {
6833 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6834 rtt_star = true;
6835 }
6836 o if o & 0b101111 == 0b101110 => {
6837 handler.on_opcode_decoded(Opcode::Vrcmpys)?;
6838 handler.rounded(RoundingMode::Round)?;
6839 handler.raw_mode(RawMode::Hi)?;
6840 }
6841 o if o & 0b101111 == 0b101111 => {
6842 handler.on_opcode_decoded(Opcode::Vrcmpys)?;
6843 handler.rounded(RoundingMode::Round)?;
6844 handler.raw_mode(RawMode::Lo)?;
6845 }
6846 0b100100 => {
6847 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6848 handler.rounded(RoundingMode::Round)?;
6849 rtt_star = true;
6850 }
6851 0b101000 => {
6852 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6853 handler.rounded(RoundingMode::Round)?;
6854 }
6855 0b110000 => {
6856 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6857 handler.rounded(RoundingMode::Round)?;
6858 }
6859 0b111000 => {
6860 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6861 handler.rounded(RoundingMode::Round)?;
6862 rtt_star = true;
6863 }
6864 o if o & 0b011111 == 0b000000 => {
6865 handler.on_opcode_decoded(Opcode::Vdmpy)?;
6866 handler.rounded(RoundingMode::Round)?;
6867 if o & 0b100000 == 0 {
6868 shift_amt = 0;
6869 }
6870 }
6871 _other => {
6872 return Err(DecodeError::InvalidOpcode);
6873 }
6874 }
6875
6876 if saturate {
6877 handler.saturate()?;
6878 }
6879 if shift_amt == 1 {
6880 handler.shift_left(shift_amt)?;
6881 }
6882 if rtt_star {
6883 handler.on_source_decoded(Operand::gprpair_conjugate(ttttt)?)?;
6884 } else {
6885 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
6886 }
6887 }
6888 0b1010 => {
6889 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
6891
6892 let opc = op_lo | (op_hi << 3);
6893
6894 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
6895 handler.on_source_decoded(Operand::gprpair(sssss)?)?;
6896 let mut rtt_star = false;
6897 let mut add_assign = true;
6898
6899 match opc {
6900 0b000010 => {
6901 handler.on_opcode_decoded(Opcode::Vrmpyh)?;
6902 }
6903 0b000011 => {
6904 handler.on_opcode_decoded(Opcode::DfMpylh)?;
6905 }
6906 0b001001 => {
6907 handler.on_opcode_decoded(Opcode::Vdmpybsu)?;
6908 handler.saturate()?;
6909 }
6910 0b001010 => {
6911 handler.on_opcode_decoded(Opcode::Vmpyeh)?;
6912 }
6913 0b001100 => {
6914 handler.on_opcode_decoded(Opcode::Vcmpyr)?;
6915 handler.saturate()?;
6916 }
6917 0b010001 => {
6918 handler.on_opcode_decoded(Opcode::Vraddub)?;
6919 }
6920 0b010010 => {
6921 handler.on_opcode_decoded(Opcode::Vrsadub)?;
6922 }
6923 0b010100 => {
6924 handler.on_opcode_decoded(Opcode::Vcmpyi)?;
6925 handler.saturate()?;
6926 }
6927 0b010110 => {
6928 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6929 rtt_star = true;
6930 }
6931 0b011010 => {
6932 handler.on_opcode_decoded(Opcode::Cmpyiw)?;
6933 }
6934 0b100001 => {
6935 handler.on_opcode_decoded(Opcode::Vrmpybu)?;
6936 }
6937 0b100010 => {
6938 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6939 }
6940 0b100011 => {
6941 handler.on_opcode_decoded(Opcode::DfMpyhh)?;
6942 }
6943 o if o & 0b111100 == 0b101000 => {
6944 handler.on_opcode_decoded(Opcode::Vacsh)?;
6945 handler.on_dest_decoded(Operand::pred(o as u8 & 0b11))?;
6946 }
6947 0b101100 => {
6948 handler.on_opcode_decoded(Opcode::Vrcmpys)?;
6949 handler.shift_left(1)?;
6950 handler.saturate()?;
6951 handler.raw_mode(RawMode::Hi)?;
6952 }
6953 0b110001 => {
6954 handler.on_opcode_decoded(Opcode::Vrmpybsu)?;
6955 }
6956 0b110010 => {
6957 handler.on_opcode_decoded(Opcode::Cmpyrw)?;
6958 rtt_star = true;
6959 }
6960 o if o & 0b111100 == 0b111000 => {
6961 handler.on_opcode_decoded(Opcode::Vminub)?;
6962 handler.on_dest_decoded(Operand::pred(o & 0b11))?;
6963 add_assign = false;
6964 }
6965 0b111100 => {
6966 handler.on_opcode_decoded(Opcode::Vrcmpys)?;
6967 handler.shift_left(1)?;
6968 handler.saturate()?;
6969 handler.raw_mode(RawMode::Lo)?;
6970 }
6971 0b000_100 | 0b100_100 => {
6972 handler.on_opcode_decoded(Opcode::Vdmpy)?;
6973 handler.saturate()?;
6974 handler.shift_left((opc >> 5) as u8)?;
6975 }
6976 0b000_101 | 0b100_101 => {
6977 handler.on_opcode_decoded(Opcode::Vmpyweh)?;
6978 handler.saturate()?;
6979 handler.shift_left((opc >> 5) as u8)?;
6980 }
6981 0b000_110 | 0b100_110 => {
6982 handler.on_opcode_decoded(Opcode::Vmpyeh)?;
6983 handler.saturate()?;
6984 handler.shift_left((opc >> 5) as u8)?;
6985 }
6986 0b000_111 | 0b100_111 => {
6987 handler.on_opcode_decoded(Opcode::Vmpywoh)?;
6988 handler.saturate()?;
6989 handler.shift_left((opc >> 5) as u8)?;
6990 }
6991 0b001_101 | 0b101_101 => {
6992 handler.on_opcode_decoded(Opcode::Vmpyweh)?;
6993 handler.saturate()?;
6994 handler.rounded(RoundingMode::Round)?;
6995 handler.shift_left((opc >> 5) as u8)?;
6996 }
6997 0b001_110 | 0b101_110 => {
6998 handler.on_opcode_decoded(Opcode::Vrmpyweh)?;
6999 handler.shift_left((opc >> 5) as u8)?;
7000 }
7001 0b001_111 | 0b101_111 => {
7002 handler.on_opcode_decoded(Opcode::Vmpywoh)?;
7003 handler.saturate()?;
7004 handler.rounded(RoundingMode::Round)?;
7005 handler.shift_left((opc >> 5) as u8)?;
7006 }
7007 0b010_101 | 0b110_101 => {
7008 handler.on_opcode_decoded(Opcode::Vmpyweuh)?;
7009 handler.saturate()?;
7010 handler.shift_left((opc >> 5) as u8)?;
7011 }
7012 0b010_111 | 0b110_111 => {
7013 handler.on_opcode_decoded(Opcode::Vmpywouh)?;
7014 handler.saturate()?;
7015 handler.shift_left((opc >> 5) as u8)?;
7016 }
7017 0b011_101 | 0b111_101 => {
7018 handler.on_opcode_decoded(Opcode::Vmpyweuh)?;
7019 handler.saturate()?;
7020 handler.rounded(RoundingMode::Round)?;
7021 handler.shift_left((opc >> 5) as u8)?;
7022 }
7023 0b011_110 | 0b111_110 => {
7024 handler.on_opcode_decoded(Opcode::Vrmpywoh)?;
7025 handler.shift_left((opc >> 5) as u8)?;
7026 }
7027 0b011_111 | 0b111_111 => {
7028 handler.on_opcode_decoded(Opcode::Vmpywouh)?;
7029 handler.saturate()?;
7030 handler.rounded(RoundingMode::Round)?;
7031 handler.shift_left((opc >> 5) as u8)?;
7032 }
7033 _ => {
7034 return Err(DecodeError::InvalidOpcode);
7035 }
7036 }
7037
7038 if rtt_star {
7039 handler.on_source_decoded(Operand::gprpair_conjugate(ttttt)?)?;
7040 } else {
7041 handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
7042 }
7043 if add_assign {
7044 handler.assign_mode(AssignMode::AddAssign)?;
7045 }
7046 }
7047 0b1011 => {
7048 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
7050 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7051 handler.on_source_decoded(Operand::gpr(sssss))?;
7052 handler.on_source_decoded(Operand::gpr(ttttt))?;
7053
7054 let opc = op_lo | (op_hi << 3);
7055
7056 match opc {
7057 0b000_001 => {
7058 handler.on_opcode_decoded(SfSub)?;
7059 }
7060 0b000_011 => {
7061 handler.on_opcode_decoded(SfAdd)?;
7062 }
7063 0b010_000 => {
7064 handler.on_opcode_decoded(SfMpy)?;
7065 }
7066 0b100_000 => {
7067 handler.on_opcode_decoded(SfMax)?;
7068 }
7069 0b100_001 => {
7070 handler.on_opcode_decoded(SfMin)?;
7071 }
7072 0b110_000 => {
7073 handler.on_opcode_decoded(SfFixupn)?;
7074 }
7075 0b110_001 => {
7076 handler.on_opcode_decoded(SfFixupd)?;
7077 }
7078 o if o >= 0b111100 => {
7079 let ee = o & 0b11;
7080 handler.on_opcode_decoded(SfRecipa)?;
7081 handler.on_dest_decoded(Operand::pred(ee))?;
7082 }
7083 _ => {
7084 opcode_check!(false);
7085 }
7086 }
7087 }
7088 0b1100 => {
7089 handler.on_opcode_decoded(Opcode::Mpy)?;
7090 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7091 if op_hi & 0b100 != 0 {
7092 handler.shift_left(1)?;
7093 }
7094 opcode_check!(op_hi & 0b010 == 0);
7095 if op_hi & 0b001 != 0 {
7096 handler.rounded(RoundingMode::Round)?;
7097 }
7098 if op_lo & 0b100 != 0 {
7099 handler.saturate()?;
7100 }
7101 if op_lo & 0b010 != 0 {
7102 handler.on_source_decoded(Operand::gpr_high(sssss))?;
7103 } else {
7104 handler.on_source_decoded(Operand::gpr_low(sssss))?;
7105 }
7106 if op_lo & 0b001 != 0 {
7107 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
7108 } else {
7109 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
7110 }
7111 }
7112 0b1101 => {
7113 opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
7115
7116 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
7117 handler.on_source_decoded(Operand::gpr(reg_b16(inst)))?;
7118
7119 match op_lo {
7120 0b000 => {
7121 if op_hi == 0b000 {
7122 handler.on_opcode_decoded(Opcode::Mpyi)?;
7123 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7124 } else if op_hi == 0b101 {
7125 handler.on_opcode_decoded(Opcode::Mpy)?;
7126 handler.on_source_decoded(Operand::gpr_high(reg_b8(inst)))?;
7127 handler.shift_left(1)?;
7128 handler.saturate()?;
7129 } else if op_hi == 0b111 {
7130 handler.on_opcode_decoded(Opcode::Mpy)?;
7131 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7132 handler.shift_left(1)?;
7133 handler.saturate()?;
7134 } else {
7135 opcode_check!(false);
7136 }
7137 }
7138 0b001 => {
7139 match op_hi {
7140 0b000 => {
7141 handler.on_opcode_decoded(Opcode::Mpy)?;
7142 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7143 }
7144 0b001 => {
7145 handler.on_opcode_decoded(Opcode::Mpy)?;
7146 handler.rounded(RoundingMode::Round)?;
7147 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7148 }
7149 0b010 => {
7150 handler.on_opcode_decoded(Opcode::Mpyu)?;
7151 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7152 }
7153 0b011 => {
7154 handler.on_opcode_decoded(Opcode::Mpysu)?;
7155 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7156 }
7157 0b101 => {
7158 handler.on_opcode_decoded(Opcode::Mpy)?;
7159 handler.on_source_decoded(Operand::gpr_low(reg_b8(inst)))?;
7160 handler.shift_left(1)?;
7161 handler.saturate()?;
7162 }
7163 _ => {
7164 opcode_check!(false);
7165 }
7166 }
7167 }
7168 0b010 => {
7169 opcode_check!(op_hi == 0b101);
7170 handler.on_opcode_decoded(Opcode::Mpy)?;
7171 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7172 handler.shift_left(1)?;
7173 }
7174 0b100 => {
7175 handler.on_opcode_decoded(Opcode::Mpy)?;
7176 handler.shift_left(1)?;
7177 handler.rounded(RoundingMode::Round)?;
7178 handler.saturate()?;
7179 if op_hi == 0b101 {
7180 handler.on_source_decoded(Operand::gpr_high(reg_b8(inst)))?;
7181 } else if op_hi == 0b111 {
7182 handler.on_source_decoded(Operand::gpr_low(reg_b8(inst)))?;
7183 } else {
7184 opcode_check!(false);
7185 }
7186 }
7187 0b110 => {
7188 opcode_check!(op_hi & 0b001 == 0b001);
7189 handler.on_opcode_decoded(Opcode::Cmpy)?;
7190 handler.shift_left(op_hi >> 2)?;
7191 if op_hi & 0b010 == 0 {
7192 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7193 } else {
7194 handler.on_source_decoded(Operand::gpr_conjugate(reg_b8(inst)))?;
7195 }
7196 handler.rounded(RoundingMode::Round)?;
7197 handler.saturate()?;
7198 }
7199 0b111 => {
7200 opcode_check!(op_hi & 0b011 == 0b001);
7201 handler.on_opcode_decoded(Opcode::Vmpyh)?;
7202 handler.shift_left(op_hi >> 2)?;
7203 handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
7204 handler.on_source_decoded(Operand::gpr(reg_b8(inst)))?;
7205 handler.rounded(RoundingMode::Round)?;
7206 handler.saturate()?;
7207 }
7208 _ => {
7209 opcode_check!(false);
7210 }
7211 }
7212 }
7213 0b1110 => {
7214 handler.on_opcode_decoded(Opcode::Mpy)?;
7215 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7216 if op_hi & 0b100 != 0 {
7217 handler.shift_left(1)?;
7218 }
7219 opcode_check!(op_hi & 0b010 == 0);
7220 if op_hi & 0b001 == 0 {
7221 handler.assign_mode(AssignMode::AddAssign)?;
7222 } else {
7223 handler.assign_mode(AssignMode::SubAssign)?;
7224 }
7225 if op_lo & 0b100 != 0 {
7226 handler.saturate()?;
7227 }
7228 if op_lo & 0b010 != 0 {
7229 handler.on_source_decoded(Operand::gpr_high(sssss))?;
7230 } else {
7231 handler.on_source_decoded(Operand::gpr_low(sssss))?;
7232 }
7233 if op_lo & 0b001 != 0 {
7234 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
7235 } else {
7236 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
7237 }
7238 }
7239 _ => { opcode_check!(inst & 0b0010_0000_0000_0000 == 0);
7241
7242 let opc = op_lo | (op_hi << 3);
7243
7244 use AssignMode::*;
7245
7246 static OPCODES: [Option<(AssignMode, Opcode)>; 64] = [
7247 Some((AddAssign, Mpyi)), Some((AddAssign, Add)), None, Some((AddAssign, Sub)),
7249 Some((AddAssign, SfMpy)), Some((SubAssign, SfMpy)), Some((AddAssign, SfMpy)), Some((SubAssign, SfMpy)),
7250 Some((OrAssign, AndNot)), Some((AndAssign, AndNot)), Some((XorAssign, AndNot)), None,
7252 None, None, None, None,
7253 Some((AndAssign, And)), Some((AndAssign, Or)), Some((AndAssign, Xor)), Some((OrAssign, And)),
7255 None, None, None, None,
7256 Some((AddAssign, Mpy)), Some((SubAssign, Mpy)), None, None,
7258 Some((AddAssign, SfMpy)), Some((AddAssign, SfMpy)), Some((AddAssign, SfMpy)), Some((AddAssign, SfMpy)),
7259 Some((SubAssign, Mpyi)), Some((SubAssign, Add)), None, Some((XorAssign, Xor)),
7261 None, None, None, None,
7262 None, None, None, None,
7264 None, None, None, None,
7265 Some((OrAssign, Or)), Some((OrAssign, Xor)), Some((XorAssign, And)), Some((XorAssign, Or)),
7267 None, None, None, None,
7268 None, None, None, None,
7270 None, None, None, None,
7271 ];
7272
7273 let (assign_mode, opcode) = decode_operand!(OPCODES[opc as usize]);
7274 handler.on_opcode_decoded(opcode)?;
7275 handler.assign_mode(assign_mode)?;
7276 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7277
7278 if opcode == Opcode::Sub {
7279 handler.on_source_decoded(Operand::gpr(ttttt))?;
7280 handler.on_source_decoded(Operand::gpr(sssss))?;
7281 } else {
7282 handler.on_source_decoded(Operand::gpr(sssss))?;
7283 handler.on_source_decoded(Operand::gpr(ttttt))?;
7284 }
7285
7286 if opc == 0b000110 || opc == 0b000111 {
7287 handler.library()?;
7288 }
7289
7290 if opc == 0b011000 || opc == 0b011001 {
7291 handler.shift_left(1)?;
7292 handler.saturate()?;
7293 } else if opc >= 0b011100 && opc < 0b100000 {
7294 handler.on_source_decoded(Operand::pred(op_lo & 0b11))?;
7295 handler.scale()?;
7296 }
7297 }
7298 }
7299 }
7300 0b1111 => {
7301 let ddddd = reg_b0(inst);
7302 let ttttt = reg_b8(inst);
7303 let sssss = reg_b16(inst);
7304 let uu = (inst >> 5) & 0b11;
7305
7306 let majbits = (inst >> 24) & 0b111;
7307 let predicated = (inst >> 27) & 1 == 1;
7308 if !predicated {
7309 let minbits = (inst >> 21) & 0b111;
7313 match majbits {
7314 0b001 => {
7315 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7316 handler.on_source_decoded(Operand::gpr(sssss))?;
7317 handler.on_source_decoded(Operand::gpr(ttttt))?;
7318 static OPC: [Option<Opcode>; 8] = [
7319 Some(Opcode::And), Some(Opcode::Or), None, Some(Opcode::Xor),
7320 Some(Opcode::And_nRR), Some(Opcode::Or_nRR), None, None,
7321 ];
7322 handler.on_opcode_decoded(decode_opcode!(OPC[minbits as usize]))?;
7323 },
7324 0b010 => {
7325 operand_check!(ddddd & 0b1100 == 0b0000);
7326 handler.on_dest_decoded(Operand::pred(ddddd & 0b11))?;
7327 handler.on_source_decoded(Operand::gpr(sssss))?;
7328 handler.on_source_decoded(Operand::gpr(ttttt))?;
7329 let op_low = (inst >> 4) & 1;
7330 static OPC: [Option<Opcode>; 8] = [
7331 Some(Opcode::CmpEq), None, Some(Opcode::CmpGt), Some(Opcode::CmpGtu),
7332 Some(Opcode::CmpEq), None, Some(Opcode::CmpGt), Some(Opcode::CmpGtu),
7333 ];
7334 if op_low == 1 {
7335 handler.negate_result()?;
7336 }
7337 handler.on_opcode_decoded(decode_opcode!(OPC[minbits as usize]))?;
7338 }
7339 0b011 => {
7340 if minbits >= 0b100 {
7341 handler.on_opcode_decoded(Opcode::Combine)?;
7342 }
7343 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7344 match minbits {
7345 0b000 => {
7346 handler.on_source_decoded(Operand::gpr(sssss))?;
7347 handler.on_source_decoded(Operand::gpr(ttttt))?;
7348 handler.on_opcode_decoded(Opcode::Add)?;
7349 },
7350 0b001 => {
7351 handler.on_source_decoded(Operand::gpr(ttttt))?;
7352 handler.on_source_decoded(Operand::gpr(sssss))?;
7353 handler.on_opcode_decoded(Opcode::Sub)?;
7354 }
7355 0b010 => {
7356 handler.on_source_decoded(Operand::gpr(sssss))?;
7357 handler.on_source_decoded(Operand::gpr(ttttt))?;
7358 handler.on_opcode_decoded(Opcode::CmpEq)?;
7359 }
7360 0b011 => {
7361 handler.on_source_decoded(Operand::gpr(sssss))?;
7362 handler.on_source_decoded(Operand::gpr(ttttt))?;
7363 handler.on_opcode_decoded(Opcode::CmpEq)?;
7364 handler.negate_result()?;
7365 }
7366 0b100 => {
7367 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
7368 handler.on_source_decoded(Operand::gpr_high(sssss))?;
7369 }
7370 0b101 => {
7371 handler.on_source_decoded(Operand::gpr_high(ttttt))?;
7372 handler.on_source_decoded(Operand::gpr_low(sssss))?;
7373 }
7374 0b110 => {
7375 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
7376 handler.on_source_decoded(Operand::gpr_high(sssss))?;
7377 }
7378 _ => {
7379 handler.on_source_decoded(Operand::gpr_low(ttttt))?;
7380 handler.on_source_decoded(Operand::gpr_low(sssss))?;
7381 }
7382 }
7383 }
7384 0b100 => {
7385 handler.on_opcode_decoded(Opcode::Mux)?;
7386 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7387 let uu = (inst >> 5) & 0b11;
7388 handler.on_source_decoded(Operand::pred(uu as u8))?;
7389 handler.on_source_decoded(Operand::gpr(sssss))?;
7390 handler.on_source_decoded(Operand::gpr(ttttt))?;
7391 }
7392 0b101 => {
7393 let op = (inst >> 23) & 1 == 1;
7394
7395 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
7396 handler.on_source_decoded(Operand::gpr(sssss))?;
7397 handler.on_source_decoded(Operand::gpr(ttttt))?;
7398
7399 if !op {
7400 opcode_check!((inst >> 13) & 1 == 0);
7401 handler.on_opcode_decoded(Opcode::Combine)?;
7402 } else {
7403 handler.on_opcode_decoded(Opcode::Packhl)?;
7404 }
7405 }
7406 0b110 => {
7407 let opc = (inst >> 21) & 0b111;
7408 static OPCODES: [Opcode; 8] = [
7409 Vaddh, Vaddh, Add, Vadduh,
7410 Vsubh, Vsubh, Sub, Vsubuh,
7411 ];
7412 handler.on_opcode_decoded(OPCODES[opc as usize])?;
7413
7414 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7415 if opc < 0b100 {
7416 handler.on_source_decoded(Operand::gpr(sssss))?;
7417 handler.on_source_decoded(Operand::gpr(ttttt))?;
7418 } else {
7419 handler.on_source_decoded(Operand::gpr(ttttt))?;
7420 handler.on_source_decoded(Operand::gpr(sssss))?;
7421 }
7422 if opc & 0b11 != 0 {
7423 handler.saturate()?;
7424 }
7425 }
7426 0b111 => {
7427 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7428
7429 if (inst >> 22) & 1 == 0 {
7430 handler.on_opcode_decoded(Vavgh)?;
7431 if (inst >> 21) & 1 == 1 {
7432 handler.saturate()?;
7433 }
7434 handler.on_source_decoded(Operand::gpr(sssss))?;
7435 handler.on_source_decoded(Operand::gpr(ttttt))?;
7436 } else {
7437 handler.on_opcode_decoded(Vnavgh)?;
7438 opcode_check!((inst >> 21) & 1 == 1);
7439 handler.on_source_decoded(Operand::gpr(sssss))?;
7440 handler.on_source_decoded(Operand::gpr(ttttt))?;
7441 }
7442 }
7443 _ => {
7444 opcode_check!(false);
7445 }
7446 }
7447 } else {
7448 handler.on_source_decoded(Operand::gpr(sssss))?;
7449 handler.on_source_decoded(Operand::gpr(ttttt))?;
7450
7451 let negated = (inst >> 7) & 1 == 1;
7452 let dotnew = (inst >> 13) & 1 == 1;
7453 handler.inst_predicated(uu as u8, negated, dotnew)?;
7454 if majbits == 0b001 {
7455 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7456 static OPS: [Option<Opcode>; 4] = [
7457 Some(Opcode::And), Some(Opcode::Or), None, Some(Opcode::Xor)
7458 ];
7459 let opbits = (inst >> 21) & 0b11;
7460 handler.on_opcode_decoded(decode_opcode!(OPS[opbits as usize]))?;
7461 } else if majbits == 0b011 {
7462 handler.on_dest_decoded(Operand::gpr(ddddd))?;
7463 opcode_check!((inst >> 23) & 1 == 0);
7464 if (inst >> 21) & 1 == 0 {
7465 handler.on_opcode_decoded(Opcode::Add)?;
7466 } else {
7467 handler.on_opcode_decoded(Opcode::Sub)?;
7468 }
7469 } else if majbits == 0b101 {
7470 handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
7471 handler.on_opcode_decoded(Opcode::Contains)?;
7472 opcode_check!((inst >> 21) & 0b111 == 0b000);
7473 } else {
7474 opcode_check!(false);
7475 }
7476 }
7477 }
7478 _ => {
7479 opcode_check!(false);
7480 }
7481 }
7482
7483 Ok(())
7484}