53 template <
typename TDelegates>
55 TDelegates &delegates) {
58 auto ictx = TInstrCtx{cpua, bus};
61 case InstrId::kLdrLiteral: {
63 const auto &iargs = instr.ldr_immediate;
67 TInstr::Call(ictx, iargs.flags, iargs.imm32,
RArg(iargs.t)));
68 flags |= out_flags.flags;
73 const auto &iargs = instr.clz;
77 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m)));
78 flags |= out_flags.flags;
81 case InstrId::kLdrsbImmediate: {
82 const auto &iargs = instr.ldrsb_immediate;
86 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
87 flags |= out_flags.flags;
90 case InstrId::kLdrbImmediate: {
91 const auto &iargs = instr.ldrb_immediate;
95 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
96 flags |= out_flags.flags;
99 case InstrId::kLdrImmediate: {
100 const auto &iargs = instr.ldr_immediate;
104 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
105 flags |= out_flags.flags;
109 case InstrId::kLdrex: {
110 const auto &iargs = instr.ldrex;
114 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
115 flags |= out_flags.flags;
118 case InstrId::kUmull: {
119 const auto &iargs = instr.umull;
123 TInstr::Call(ictx, iargs.flags,
RArg(iargs.dLo),
RArg(iargs.dHi),
RArg(iargs.n),
125 flags |= out_flags.flags;
128 case InstrId::kMsr: {
129 const auto &iargs = instr.msr;
132 iargs.mask, iargs.SYSm)));
133 flags |= out_flags.flags;
137 case InstrId::kMrs: {
138 const auto &iargs = instr.mrs;
141 iargs.mask, iargs.SYSm)));
142 flags |= out_flags.flags;
145 case InstrId::kUmlal: {
146 const auto &iargs = instr.umlal;
150 TInstr::Call(ictx, iargs.flags,
RArg(iargs.dLo),
RArg(iargs.dHi),
RArg(iargs.n),
152 flags |= out_flags.flags;
156 case InstrId::kSmull: {
157 const auto &iargs = instr.smull;
161 TInstr::Call(ictx, iargs.flags,
RArg(iargs.dLo),
RArg(iargs.dHi),
RArg(iargs.n),
163 flags |= out_flags.flags;
166 case InstrId::kLdrdImmediate: {
168 const auto &iargs = instr.ldrd_immediate;
171 RArg(iargs.n), iargs.imm32));
172 flags |= out_flags.flags;
175 case InstrId::kLdrhImmediate: {
177 const auto &iargs = instr.ldrh_immediate;
181 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
182 flags |= out_flags.flags;
185 case InstrId::kLdrshImmediate: {
187 const auto &iargs = instr.ldrsh_immediate;
191 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
192 flags |= out_flags.flags;
195 case InstrId::kAsrImmediate: {
197 const auto &iargs = instr.asr_immediate;
201 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.shift_res));
202 flags |= out_flags.flags;
205 case InstrId::kLslImmediate: {
207 const auto &iargs = instr.lsl_immediate;
211 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.shift_res));
212 flags |= out_flags.flags;
215 case InstrId::kLsrRegister: {
216 const auto &iargs = instr.lsr_register;
220 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
221 flags |= out_flags.flags;
224 case InstrId::kAsrRegister: {
225 const auto &iargs = instr.asr_register;
229 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
230 flags |= out_flags.flags;
233 case InstrId::kLslRegister: {
235 const auto &iargs = instr.lsr_register;
239 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
240 flags |= out_flags.flags;
243 case InstrId::kCmpRegister: {
245 const auto &iargs = instr.cmp_register;
249 TInstr::Call(ictx, iargs.flags,
RArg(iargs.m),
RArg(iargs.n), iargs.shift_res));
250 flags |= stm_flags.flags;
253 case InstrId::kCmpImmediate: {
255 const auto &iargs = instr.cmp_immediate;
259 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.imm32));
260 flags |= stm_flags.flags;
263 case InstrId::kCmnImmediate: {
265 const auto &iargs = instr.cmp_immediate;
269 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.imm32));
270 flags |= stm_flags.flags;
275 const auto &iargs = instr.it;
278 flags |= out_flags.flags;
281 case InstrId::kMovImmediate: {
283 const auto &iargs = instr.mov_immediate;
287 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d), iargs.imm32_carry));
288 flags |= out_flags.flags;
291 case InstrId::kMvnImmediate: {
293 const auto &iargs = instr.mvn_immediate;
297 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d), iargs.imm32_carry));
298 flags |= out_flags.flags;
301 case InstrId::kMovRegister: {
303 const auto &iargs = instr.mov_register;
307 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m)));
308 flags |= out_flags.flags;
312 case InstrId::kRrx: {
313 const auto &iargs = instr.rrx;
317 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m)));
318 flags |= out_flags.flags;
321 case InstrId::kUxtb: {
322 const auto &iargs = instr.uxtb;
326 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.rotation));
327 flags |= out_flags.flags;
330 case InstrId::kSxtb: {
331 const auto &iargs = instr.sxtb;
335 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.rotation));
336 flags |= out_flags.flags;
339 case InstrId::kSxth: {
341 const auto &iargs = instr.sxth;
345 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.rotation));
346 flags |= out_flags.flags;
349 case InstrId::kUxth: {
351 const auto &iargs = instr.uxth;
355 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.rotation));
356 flags |= out_flags.flags;
359 case InstrId::kBCond: {
361 const auto &iargs = instr.b_cond;
364 flags |= out_flags.flags;
368 case InstrId::kTbbH: {
370 const auto &iargs = instr.tbb_h;
374 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n),
RArg(iargs.m)));
375 flags |= out_flags.flags;
381 const auto &iargs = instr.b;
382 using TOp = B1ImmOp<TInstrCtx>;
383 using TInstr = UnaryBranchInstrImm<TOp, TInstrCtx>;
385 flags |= out_flags.flags;
390 const auto &iargs = instr.b;
391 using TOp = Bl1ImmOp<TInstrCtx>;
392 using TInstr = UnaryBranchInstrImm<TOp, TInstrCtx>;
394 flags |= out_flags.flags;
397 case InstrId::kCbNZ: {
399 const auto &iargs = instr.cb_n_z;
403 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.imm32));
404 flags |= out_flags.flags;
411 const auto &iargs = instr.bx;
415 flags |= out_flags.flags;
418 case InstrId::kBlx: {
420 const auto &iargs = instr.blx;
424 flags |= out_flags.flags;
427 case InstrId::kSubImmediate: {
429 const auto &iargs = instr.sub_immediate;
433 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32));
434 flags |= out_flags.flags;
437 case InstrId::kSbcImmediate: {
439 const auto &iargs = instr.sbc_immediate;
443 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32));
444 flags |= out_flags.flags;
447 case InstrId::kRsbImmediate: {
449 const auto &iargs = instr.rsb_immediate;
453 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32));
454 flags |= out_flags.flags;
457 case InstrId::kSubSpMinusImmediate: {
459 const auto &iargs = instr.sub_sp_minus_immediate;
465 flags |= out_flags.flags;
468 case InstrId::kAddImmediate: {
469 const auto &iargs = instr.add_immediate;
473 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32));
474 flags |= out_flags.flags;
477 case InstrId::kAdcImmediate: {
478 const auto &iargs = instr.adc_immediate;
482 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32));
483 flags |= out_flags.flags;
486 case InstrId::kAddPcPlusImmediate: {
488 const auto &iargs = instr.add_pc_plus_immediate;
492 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d), iargs.imm32));
493 flags |= out_flags.flags;
496 case InstrId::kAddSpPlusImmediate: {
498 const auto &iargs = instr.add_sp_plus_immediate;
504 flags |= out_flags.flags;
507 case InstrId::kTeqImmediate: {
508 const auto &iargs = instr.teq_immediate;
512 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.imm32_carry));
513 flags |= out_flags.flags;
516 case InstrId::kTstImmediate: {
517 const auto &iargs = instr.tst_immediate;
521 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.imm32_carry));
522 flags |= out_flags.flags;
525 case InstrId::kTstRegister: {
526 const auto &iargs = instr.tst_register;
530 TInstr::Call(ictx, iargs.flags,
RArg(iargs.m),
RArg(iargs.n), iargs.shift_res));
531 flags |= out_flags.flags;
534 case InstrId::kTeqRegister: {
535 const auto &iargs = instr.teq_register;
539 TInstr::Call(ictx, iargs.flags,
RArg(iargs.m),
RArg(iargs.n), iargs.shift_res));
540 flags |= out_flags.flags;
543 case InstrId::kEorImmediate: {
544 const auto &iargs = instr.eor_immediate;
548 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32_carry));
549 flags |= out_flags.flags;
552 case InstrId::kOrrImmediate: {
553 const auto &iargs = instr.orr_immediate;
557 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32_carry));
558 flags |= out_flags.flags;
561 case InstrId::kAndImmediate: {
563 const auto &iargs = instr.and_immediate;
567 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32_carry));
568 flags |= out_flags.flags;
571 case InstrId::kUbfx: {
573 const auto &iargs = instr.ubfx;
576 iargs.lsbit, iargs.widthminus1));
577 flags |= out_flags.flags;
580 case InstrId::kBfi: {
581 const auto &iargs = instr.bfi;
584 iargs.lsbit, iargs.msbit));
585 flags |= out_flags.flags;
588 case InstrId::kUdiv: {
589 const auto &iargs = instr.udiv;
593 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
594 flags |= out_flags.flags;
597 case InstrId::kSdiv: {
598 const auto &iargs = instr.sdiv;
602 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
603 flags |= out_flags.flags;
606 case InstrId::kMul: {
608 const auto &iargs = instr.mul;
612 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m)));
613 flags |= out_flags.flags;
616 case InstrId::kMls: {
617 const auto &iargs = instr.mls;
621 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
623 flags |= out_flags.flags;
627 case InstrId::kMla: {
628 const auto &iargs = instr.mla;
632 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
634 flags |= out_flags.flags;
637 case InstrId::kSubRegister: {
638 const auto &iargs = instr.sub_register;
642 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
644 flags |= out_flags.flags;
647 case InstrId::kRsbRegister: {
648 const auto &iargs = instr.rsb_register;
652 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
654 flags |= out_flags.flags;
657 case InstrId::kAdcRegister: {
658 const auto &iargs = instr.adc_register;
662 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
664 flags |= out_flags.flags;
667 case InstrId::kAddRegister: {
668 const auto &iargs = instr.add_register;
672 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
674 flags |= out_flags.flags;
677 case InstrId::kPush: {
679 const auto &iargs = instr.push;
681 InstrFlagsSet iflags{0x0U};
684 iflags |=
static_cast<InstrFlagsSet
>(InstrFlags::kWBack);
685 iflags |= iargs.flags &
static_cast<InstrFlagsSet
>(InstrFlags::k32Bit);
690 flags |= stm_flags.flags;
693 case InstrId::kStm: {
695 const auto &iargs = instr.ldm;
699 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.registers));
700 flags |= stm_flags.flags;
703 case InstrId::kLdm: {
705 const auto &iargs = instr.ldm;
708 TInstr::Call(ictx, iargs.flags,
RArg(iargs.n), iargs.registers));
709 flags |= ldm_flags.flags;
712 case InstrId::kPop: {
714 const auto &iargs = instr.pop;
716 InstrFlagsSet iflags{0x0U};
719 iflags |=
static_cast<InstrFlagsSet
>(InstrFlags::kWBack);
720 iflags |= iargs.flags &
static_cast<InstrFlagsSet
>(InstrFlags::k32Bit);
725 flags |= ldm_flags.flags;
728 case InstrId::kOrrRegister: {
730 const auto &iargs = instr.orr_register;
734 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
736 flags |= out_flags.flags;
739 case InstrId::kSbcRegister: {
741 const auto &iargs = instr.sbc_register;
745 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
747 flags |= out_flags.flags;
750 case InstrId::kEorRegister: {
752 const auto &iargs = instr.eor_register;
756 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
758 flags |= out_flags.flags;
761 case InstrId::kAndRegister: {
763 const auto &iargs = instr.and_register;
767 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
769 flags |= out_flags.flags;
772 case InstrId::kBicRegister: {
774 const auto &iargs = instr.bic_register;
778 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n),
RArg(iargs.m),
780 flags |= out_flags.flags;
783 case InstrId::kBicImmediate: {
784 const auto &iargs = instr.bic_immediate;
788 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.n), iargs.imm32_carry));
789 flags |= out_flags.flags;
792 case InstrId::kMvnRegister: {
793 const auto &iargs = instr.lsr_immediate;
797 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.shift_res));
798 flags |= out_flags.flags;
801 case InstrId::kLsrImmediate: {
803 const auto &iargs = instr.lsr_immediate;
807 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.m), iargs.shift_res));
808 flags |= out_flags.flags;
811 case InstrId::kStrdImmediate: {
813 const auto &iargs = instr.strd_immediate;
816 RArg(iargs.n), iargs.imm32));
817 flags |= out_flags.flags;
820 case InstrId::kStrRegister: {
822 const auto &iargs = instr.str_register;
826 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
828 flags |= out_flags.flags;
831 case InstrId::kStrbRegister: {
833 const auto &iargs = instr.strh_register;
837 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
839 flags |= out_flags.flags;
842 case InstrId::kStrhRegister: {
844 const auto &iargs = instr.strh_register;
848 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
850 flags |= out_flags.flags;
853 case InstrId::kLdrhRegister: {
854 const auto &iargs = instr.ldrh_register;
858 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
860 flags |= out_flags.flags;
863 case InstrId::kLdrbRegister: {
864 const auto &iargs = instr.ldrb_register;
868 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
870 flags |= out_flags.flags;
873 case InstrId::kLdrRegister: {
875 const auto &iargs = instr.ldr_register;
879 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n),
RArg(iargs.m),
881 flags |= out_flags.flags;
884 case InstrId::kStrImmediate: {
886 const auto &iargs = instr.str_immediate;
890 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
891 flags |= out_flags.flags;
895 case InstrId::kStrex: {
897 const auto &iargs = instr.strex;
901 TInstr::Call(ictx, iargs.flags,
RArg(iargs.d),
RArg(iargs.t),
RArg(iargs.n),
903 flags |= out_flags.flags;
906 case InstrId::kStrhImmediate: {
908 const auto &iargs = instr.strh_immediate;
912 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
913 flags |= out_flags.flags;
916 case InstrId::kStrbImmediate: {
918 const auto &iargs = instr.strb_immediate;
922 TInstr::Call(ictx, iargs.flags,
RArg(iargs.t),
RArg(iargs.n), iargs.imm32));
923 flags |= out_flags.flags;
926 case InstrId::kSvc: {
928 const auto &iargs = instr.svc;
931 flags |= out_flags.flags;
934 case InstrId::kBkpt: {
936 const auto &iargs = instr.bkpt;
939 flags |= out_flags.flags;
942 case InstrId::kNop: {
943 const auto &iargs = instr.nop;
947 flags |= out_flags.flags;
950 case InstrId::kDmb: {
951 const auto &iargs = instr.dmb;
955 flags |= out_flags.flags;
975 ~Executor() =
delete;
981 Executor &operator=(
const Executor &r_src) =
delete;
987 Executor(Executor &&r_src) =
delete;
993 Executor &operator=(Executor &&r_src) =
delete;