3#include "libmicroemu/internal/decoder/instr.h"
4#include "libmicroemu/internal/fetcher/raw_instr.h"
5#include "libmicroemu/internal/logic/thumb.h"
7#include "libmicroemu/internal/utils/bit_manip.h"
8#include "libmicroemu/register_details.h"
9#include "libmicroemu/types.h"
19static constexpr u32 kDecodersOpCodeLast = 15U;
20static constexpr u32 kDecodersOpCodeFirst = 11U;
22template <
typename TCpuAccessor,
typename TItOps>
23static Result<Instr> InvalidInstrDecoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
24 static_cast<void>(rinstr);
25 static_cast<void>(cpua);
29template <
typename TCpuAccessor,
typename TItOps>
30static Result<Instr> NopT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
31 static_cast<void>(cpua);
32 const InstrId iid{InstrId::kNop};
35 static_cast<void>(rinstr);
37 assert(rinstr.low == 0b1011111100000000U);
45template <
typename TCpuAccessor,
typename TItOps>
46static Result<Instr> DmbT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
47 static_cast<void>(cpua);
48 const InstrId iid{InstrId::kDmb};
51 assert(rinstr.low == 0b1111001110111111U);
53 static_cast<void>(rinstr);
55 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
63template <
typename TCpuAccessor,
typename TItOps>
64static Result<Instr> AddPcPlusImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
65 static_cast<void>(cpua);
66 const InstrId iid{InstrId::kAddPcPlusImmediate};
71 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
73 const u8 d =
static_cast<u8
>(Rd);
80template <
typename TCpuAccessor,
typename TItOps>
81static Result<Instr> LslImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
82 static_cast<void>(cpua);
83 const InstrId iid{InstrId::kLslImmediate};
90 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
92 const u8 d =
static_cast<u8
>(Rd);
94 const u8 m =
static_cast<u8
>(Rm);
96 const auto shift_res = Alu32::DecodeImmShift(0b00, imm5);
98 assert(shift_res.type == SRType::SRType_LSL);
103template <
typename TCpuAccessor,
typename TItOps>
104static Result<Instr> LslImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
105 static_cast<void>(cpua);
106 const InstrId iid{InstrId::kLslImmediate};
115 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
117 const u8 d =
static_cast<u8
>(Rd);
119 const u8 m =
static_cast<u8
>(Rm);
122 const auto shift_res = Alu32::DecodeImmShift(0b00U, (imm3 << 2U) | imm2);
124 assert(shift_res.type == SRType::SRType_LSL);
125 assert(((imm3 << 2U) | imm2) != 0b0U);
126 if (d == 13U || d == 15U || m == 13U || m == 15U) {
129 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
134template <
typename TCpuAccessor,
typename TItOps>
135static Result<Instr> LslRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
136 static_cast<void>(cpua);
137 const InstrId iid{InstrId::kLslRegister};
143 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
145 const u8 n =
static_cast<u8
>(Rn);
147 const u8 d =
static_cast<u8
>(Rd);
149 const u8 m =
static_cast<u8
>(Rm);
154template <
typename TCpuAccessor,
typename TItOps>
155static Result<Instr> LslRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
156 static_cast<void>(cpua);
157 const InstrId iid{InstrId::kLslRegister};
165 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
167 const u8 n =
static_cast<u8
>(Rn);
169 const u8 d =
static_cast<u8
>(Rd);
171 const u8 m =
static_cast<u8
>(Rm);
173 if (d == 13U || d == 15 || n == 13U || n == 15 || m == 13U || m == 15) {
176 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
181template <
typename TCpuAccessor,
typename TItOps>
182static Result<Instr> ClzT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
183 static_cast<void>(cpua);
184 const InstrId iid{InstrId::kClz};
192 const u8 d =
static_cast<u8
>(Rd);
198 const u8 m =
static_cast<u8
>(Rm_1);
200 if (d == 13U || d == 15 || m == 13U || m == 15) {
203 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
208template <
typename TCpuAccessor,
typename TItOps>
209static Result<Instr> AsrImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
210 static_cast<void>(cpua);
211 const InstrId iid{InstrId::kAsrImmediate};
217 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
219 const u8 m =
static_cast<u8
>(Rm);
221 const u8 d =
static_cast<u8
>(Rd);
223 const auto shift_res = Alu32::DecodeImmShift(0b10U, imm5);
228template <
typename TCpuAccessor,
typename TItOps>
229static Result<Instr> CmpRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
230 static_cast<void>(cpua);
231 const InstrId iid{InstrId::kCmpRegister};
237 const u8 n =
static_cast<u8
>(Rn);
239 const u8 m =
static_cast<u8
>(Rm);
245template <
typename TCpuAccessor,
typename TItOps>
246static Result<Instr> CmpRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
247 static_cast<void>(cpua);
248 const InstrId iid{InstrId::kCmpRegister};
255 const u8 n =
static_cast<u8
>(N << 3U | Rn);
257 const u8 m =
static_cast<u8
>(Rm);
260 if (n < 8U && m < 8U) {
263 if (n == 15U || m == 15U) {
270template <
typename TCpuAccessor,
typename TItOps>
271static Result<Instr> CmpRegisterT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
272 static_cast<void>(cpua);
273 const InstrId iid{InstrId::kCmpRegister};
281 const u8 n =
static_cast<u8
>(Rn);
283 const u8 m =
static_cast<u8
>(Rm);
287 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
289 if (n == 15U || m == 13U || m == 15U) {
292 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
297template <
typename TCpuAccessor,
typename TItOps>
298static Result<Instr> CmpImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
299 static_cast<void>(cpua);
300 const InstrId iid{InstrId::kCmpImmediate};
306 const u8 n =
static_cast<u8
>(Rn);
313template <
typename TCpuAccessor,
typename TItOps>
314static Result<Instr> CmpImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
315 static_cast<void>(cpua);
316 const InstrId iid{InstrId::kCmpImmediate};
325 const u8 n =
static_cast<u8
>(Rn);
329 TRY_ASSIGN(imm32,
Instr, Thumb::ThumbExpandImm((i << 11U) | (imm3 << 8U) | imm8));
334 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
339template <
typename TCpuAccessor,
typename TItOps>
340static Result<Instr> CmnImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
341 static_cast<void>(cpua);
342 const InstrId iid{InstrId::kCmnImmediate};
351 const u8 n =
static_cast<u8
>(Rn);
355 TRY_ASSIGN(imm32,
Instr, Thumb::ThumbExpandImm((i << 11U) | (imm3 << 8U) | imm8));
360 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
365template <
typename TCpuAccessor,
typename TItOps>
366static Result<Instr> MovImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
367 static_cast<void>(cpua);
368 const InstrId iid{InstrId::kMovImmediate};
374 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
376 const u8 d =
static_cast<u8
>(Rd);
377 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
379 const auto imm32_carry =
380 ThumbImmediateResult{imm8, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk};
385template <
typename TCpuAccessor,
typename TItOps>
386static Result<Instr> MovImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
387 static_cast<void>(cpua);
388 const InstrId iid{InstrId::kMovImmediate};
397 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
399 const u8 d =
static_cast<u8
>(Rd);
403 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
404 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
406 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
408 if (d == 13U || d == 15) {
411 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
416template <
typename TCpuAccessor,
typename TItOps>
417static Result<Instr> MovImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
418 static_cast<void>(cpua);
419 const InstrId iid{InstrId::kMovImmediate};
426 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
428 const u8 d =
static_cast<u8
>(Rd);
433 const auto imm32_carry =
434 ThumbImmediateResult{(imm4 << 12U) | (i << 11U) | (imm3 << 8U) | imm8,
false};
436 if (d == 13U || d == 15) {
439 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
444template <
typename TCpuAccessor,
typename TItOps>
445static Result<Instr> MvnImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
446 static_cast<void>(cpua);
447 const InstrId iid{InstrId::kMvnImmediate};
456 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
458 const u8 d =
static_cast<u8
>(Rd);
462 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
463 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
465 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
467 if (d == 13U || d == 15) {
470 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
475template <
typename TCpuAccessor,
typename TItOps>
476static Result<Instr> TbbHT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
477 static_cast<void>(cpua);
478 const InstrId iid{InstrId::kTbbH};
485 flags |= H << static_cast<InstrFlagsSet>(InstrFlagsShift::kTbhShift);
487 const u8 m =
static_cast<u8
>(Rm);
489 const u8 n =
static_cast<u8
>(Rn);
491 if (n == 13U || m == 13U || m == 15U) {
494 if (TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
497 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
502template <
typename TCpuAccessor,
typename TItOps>
503static Result<Instr> RsbImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
504 static_cast<void>(cpua);
505 const InstrId iid{InstrId::kRsbImmediate};
511 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
513 const u8 n =
static_cast<u8
>(Rn);
515 const u8 d =
static_cast<u8
>(Rd);
516 const u32 imm32 = 0x0U;
521template <
typename TCpuAccessor,
typename TItOps>
522static Result<Instr> RsbImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
523 static_cast<void>(cpua);
524 const InstrId iid{InstrId::kRsbImmediate};
532 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
534 const u8 n =
static_cast<u8
>(Rn);
536 const u8 d =
static_cast<u8
>(Rd);
541 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
544 if (d == 13U || d == 15U || n == 13U || n == 15U) {
547 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
552template <
typename TCpuAccessor,
typename TItOps>
553static Result<Instr> MovRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
554 static_cast<void>(cpua);
555 const InstrId iid{InstrId::kMovRegister};
560 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
562 const u8 d =
static_cast<u8
>(Rd);
564 const u8 m =
static_cast<u8
>(Rm);
566 if (d == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
573template <
typename TCpuAccessor,
typename TItOps>
574static Result<Instr> MovRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
575 static_cast<void>(cpua);
576 const InstrId iid{InstrId::kMovRegister};
581 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags);
583 const u8 d =
static_cast<u8
>(Rd);
585 const u8 m =
static_cast<u8
>(Rm);
587 if (TItOps::InITBlock(cpua)) {
594template <
typename TCpuAccessor,
typename TItOps>
595static Result<Instr> MovRegisterT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
596 static_cast<void>(cpua);
597 const InstrId iid{InstrId::kMovRegister};
606 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
608 const u8 d =
static_cast<u8
>(Rd);
610 const u8 m =
static_cast<u8
>(Rm);
612 if ((flags &
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) != 0U) &&
613 (d == 13U || d == 15U || m == 13U || m == 15U)) {
616 if ((flags &
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) == 0U) &&
617 (d == 15U || m == 15U || (d == 13U && m == 13U))) {
620 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
625template <
typename TCpuAccessor,
typename TItOps>
626static Result<Instr> RrxT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
627 static_cast<void>(cpua);
628 const InstrId iid{InstrId::kRrx};
637 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
639 const u8 d =
static_cast<u8
>(Rd);
641 const u8 m =
static_cast<u8
>(Rm);
643 if ((d == 13U) || (d == 15U) || (m == 13U) || (m == 15U)) {
646 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
651template <
typename TCpuAccessor,
typename TItOps>
652static Result<Instr> LdrLiteralT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
653 static_cast<void>(cpua);
654 const InstrId iid{InstrId::kLdrLiteral};
657 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
659 const u8 t =
static_cast<u8
>(Rt);
666template <
typename TCpuAccessor,
typename TItOps>
667static Result<Instr> LdrLiteralT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
668 static_cast<void>(cpua);
669 const InstrId iid{InstrId::kLdrLiteral};
676 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
678 const u8 t =
static_cast<u8
>(Rt);
682 if (t == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
685 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
690template <
typename TCpuAccessor,
typename TItOps>
691static Result<Instr> LdrbImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
692 static_cast<void>(cpua);
693 const InstrId iid{InstrId::kLdrbImmediate};
698 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
699 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
700 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
702 const u8 t =
static_cast<u8
>(Rt);
704 const u8 n =
static_cast<u8
>(Rn);
711template <
typename TCpuAccessor,
typename TItOps>
712static Result<Instr> LdrbImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
713 static_cast<void>(cpua);
714 const InstrId iid{InstrId::kLdrbImmediate};
719 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
720 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
721 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
723 const u8 t =
static_cast<u8
>(Rt);
725 const u8 n =
static_cast<u8
>(Rn);
729 assert(Rt != 0b1111U);
730 assert(Rn != 0b1111U);
734 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
739template <
typename TCpuAccessor,
typename TItOps>
740static Result<Instr> LdrbImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
741 static_cast<void>(cpua);
742 const InstrId iid{InstrId::kLdrbImmediate};
749 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
751 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
753 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
755 const u8 t =
static_cast<u8
>(Rt);
757 const u8 n =
static_cast<u8
>(Rn);
761 assert((Rt != 0b1111U) || (P != 1U) || (U != 0U) || (W != 0U));
762 assert(Rn != 0b1111U);
763 assert((P != 0b1U) || (U != 0b1U) || (W != 0b0U));
764 assert((Rn != 0b1101U) || (P != 0x0U) || (U != 0x1U) || (W != 0x1U) || (imm8 != 0b00000100U));
765 if ((P == 0x0U) && (W == 0x0U)) {
768 if (t == 13U || (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
771 if (t == 15U && ((P == 0U) || (U == 1U) || (W == 1U))) {
774 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
779template <
typename TCpuAccessor,
typename TItOps>
780static Result<Instr> LdrsbImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
781 static_cast<void>(cpua);
782 const InstrId iid{InstrId::kLdrsbImmediate};
787 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
788 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
789 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
791 const u8 t =
static_cast<u8
>(Rt);
793 const u8 n =
static_cast<u8
>(Rn);
797 assert(Rt != 0b1111U);
798 assert(Rn != 0b1111U);
802 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
807template <
typename TCpuAccessor,
typename TItOps>
808static Result<Instr> LdrsbImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
809 static_cast<void>(cpua);
810 const InstrId iid{InstrId::kLdrsbImmediate};
818 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
820 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
822 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
824 const u8 t =
static_cast<u8
>(Rt);
826 const u8 n =
static_cast<u8
>(Rn);
830 assert((Rt != 0b1111U) || (P != 1U) || (U != 0U) || (W != 0U));
831 assert(Rn != 0b1111U);
832 assert((P != 0b1U) || (U != 0b1U) || (W != 0b0U));
833 assert((Rn != 0b1101U) || (P != 0x0U) || (U != 0x1U) || (W != 0x1U) || (imm8 != 0b00000100U));
834 if ((P == 0x0U) && (W == 0x0U)) {
837 if (t == 13U || (t == 15U && (W == 1U)) ||
838 (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
841 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
846template <
typename TCpuAccessor,
typename TItOps>
847static Result<Instr> LdrshImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
848 static_cast<void>(cpua);
849 const InstrId iid{InstrId::kLdrshImmediate};
854 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
855 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
856 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
858 const u8 t =
static_cast<u8
>(Rt);
860 const u8 n =
static_cast<u8
>(Rn);
864 assert(Rn != 0b1111U);
865 assert(Rt != 0b1111U);
869 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
874template <
typename TCpuAccessor,
typename TItOps>
875static Result<Instr> LdrshImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
876 static_cast<void>(cpua);
877 const InstrId iid{InstrId::kLdrshImmediate};
884 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
886 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
888 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
890 const u8 t =
static_cast<u8
>(Rt);
892 const u8 n =
static_cast<u8
>(Rn);
896 assert(Rn != 0b1111U);
897 assert(Rt != 0b1111U || P != 1U || U != 0U || W != 0U);
898 assert(P != 0b1U || U != 0b1U || W != 0b0U);
899 if (P == 0b0U && W == 0b0U) {
902 if (t == 13U || (t == 15U && W == 1U) ||
903 (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
906 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
911template <
typename TCpuAccessor,
typename TItOps>
912static Result<Instr> LdrhImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
913 static_cast<void>(cpua);
914 const InstrId iid{InstrId::kLdrhImmediate};
919 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
920 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
921 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
923 const u8 t =
static_cast<u8
>(Rt);
925 const u8 n =
static_cast<u8
>(Rn);
932template <
typename TCpuAccessor,
typename TItOps>
933static Result<Instr> LdrhImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
934 static_cast<void>(cpua);
935 const InstrId iid{InstrId::kLdrhImmediate};
940 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
941 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
942 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
944 const u8 t =
static_cast<u8
>(Rt);
946 const u8 n =
static_cast<u8
>(Rn);
950 assert(Rt != 0b1111U);
951 assert(Rn != 0b1111U);
955 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
960template <
typename TCpuAccessor,
typename TItOps>
961static Result<Instr> LdrhImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
962 static_cast<void>(cpua);
963 const InstrId iid{InstrId::kLdrhImmediate};
970 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
972 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
974 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
976 const u8 t =
static_cast<u8
>(Rt);
978 const u8 n =
static_cast<u8
>(Rn);
982 assert(Rn != 0b1111U);
983 assert(Rt != 0b1111U || P != 1U || U != 0U || W != 0U);
984 assert(P != 0b1U || U != 0b1U || W != 0b0U);
985 if (P == 0b0U && W == 0b0U) {
988 if (t == 13U || (t == 15U && W == 1U) ||
989 (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
992 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
997template <
typename TCpuAccessor,
typename TItOps>
998static Result<Instr> PopT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
999 static_cast<void>(cpua);
1000 const InstrId iid{InstrId::kPop};
1005 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kUnalignedAllow);
1008 const u32 registers = (P << 15U) | register_list;
1014 (!TItOps::LastInITBlock(cpua))) {
1021template <
typename TCpuAccessor,
typename TItOps>
1022static Result<Instr> PopT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1023 static_cast<void>(cpua);
1024 const InstrId iid{InstrId::kPop};
1030 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kUnalignedAllow);
1034 const u32 registers = (P << 15U) | (M << 14U) | register_list;
1036 if ((
Bm32::BitCount(registers) < 2U) || ((P == 1U) && M == 1U)) {
1040 (!TItOps::LastInITBlock(cpua))) {
1043 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1048template <
typename TCpuAccessor,
typename TItOps>
1049static Result<Instr> PopT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1050 static_cast<void>(cpua);
1051 const InstrId iid{InstrId::kPop};
1057 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kUnalignedAllow);
1059 const u8 t =
static_cast<u8
>(Rt);
1060 const u32 registers = 1U << Rt;
1062 if (t == 13U || (t == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua))) {
1065 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1070template <
typename TCpuAccessor,
typename TItOps>
1071static Result<Instr> LdrImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1072 static_cast<void>(cpua);
1073 const InstrId iid{InstrId::kLdrImmediate};
1078 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
1079 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
1080 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
1082 const u8 t =
static_cast<u8
>(Rt);
1084 const u8 n =
static_cast<u8
>(Rn);
1091template <
typename TCpuAccessor,
typename TItOps>
1092static Result<Instr> LdrImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1093 static_cast<void>(cpua);
1094 const InstrId iid{InstrId::kLdrImmediate};
1099 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
1100 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
1101 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
1103 const u8 t =
static_cast<u8
>(Rt);
1111template <
typename TCpuAccessor,
typename TItOps>
1112static Result<Instr> LdrImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1113 static_cast<void>(cpua);
1114 const InstrId iid{InstrId::kLdrImmediate};
1119 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
1120 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
1121 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
1123 const u8 t =
static_cast<u8
>(Rt);
1125 const u8 n =
static_cast<u8
>(Rn);
1129 if (t == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1132 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1137template <
typename TCpuAccessor,
typename TItOps>
1138static Result<Instr> LdrImmediateT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1139 static_cast<void>(cpua);
1140 const InstrId iid{InstrId::kLdrImmediate};
1147 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
1149 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
1151 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
1153 const u8 t =
static_cast<u8
>(Rt);
1155 const u8 n =
static_cast<u8
>(Rn);
1159 assert(Rn != 0b1111U);
1160 assert((P != 0b1U) || (U != 0b1U) || (W != 0b0U));
1161 if ((Rn == 0b1101U) && (P == 0x0U) && (U == 0x1U) && (W == 0x1U) && (imm8 == 0b00000100U)) {
1163 return PopT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
1165 if ((P == 0x0U) && (W == 0x0U)) {
1168 if ((flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t) ||
1169 t == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1172 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1177template <
typename TCpuAccessor,
typename TItOps>
1178static Result<Instr> LdrexT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1179 static_cast<void>(cpua);
1180 const InstrId iid{InstrId::kLdrex};
1186 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
1187 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
1188 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
1190 const u8 t =
static_cast<u8
>(Rt);
1192 const u8 n =
static_cast<u8
>(Rn);
1196 if (t == 13U || t == 15U || n == 15U) {
1199 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1204template <
typename TCpuAccessor,
typename TItOps>
1205static Result<Instr> LdrdImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1206 static_cast<void>(cpua);
1207 const InstrId iid{InstrId::kLdrdImmediate};
1215 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
1217 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
1219 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
1221 const u8 t =
static_cast<u8
>(Rt);
1223 const u8 t2 =
static_cast<u8
>(Rt2);
1225 const u8 n =
static_cast<u8
>(Rn);
1229 assert((P != 0U) || (W != 0));
1230 assert(Rn != 0b1111U);
1231 if (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && ((n == t) || (n == t2))) {
1234 if (t == 13U || t == 15 || (t2 == 13U) || (t2 == 15) || (t == t2)) {
1237 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1242template <
typename TCpuAccessor,
typename TItOps>
1243static Result<Instr> ItT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1244 static_cast<void>(cpua);
1245 const InstrId iid{InstrId::kIt};
1251 const u8 firstcond =
static_cast<u8
>(firstcond_32);
1253 const u8 mask =
static_cast<u8
>(mask_32);
1255 assert(mask != 0x0U);
1256 if (firstcond == 0xFU || (firstcond == 0b1110U &&
Bm8::BitCount(mask) != 1U)) {
1260 if (TItOps::InITBlock(cpua)) {
1264 return Ok(
Instr{
InstrIt{iid, flags, firstcond, mask}});
1267template <
typename TCpuAccessor,
typename TItOps>
1268static Result<Instr> BlT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1269 static_cast<void>(cpua);
1270 const InstrId iid{InstrId::kBl};
1282 const u32 i1 = (~(j1 ^ s)) & 0x1U;
1283 const u32 i2 = (~(j2 ^ s)) & 0x1U;
1284 const u32 imm32_us = (s << 24U) | (i1 << 23U) | (i2 << 22U) | (imm10 << 12U) | imm11 << 1U;
1287 if (TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1290 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1295template <
typename TCpuAccessor,
typename TItOps>
1296static Result<Instr> BxT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1297 static_cast<void>(cpua);
1298 const InstrId iid{InstrId::kBx};
1304 const u8 m =
static_cast<u8
>(Rm);
1306 if (TItOps::InITBlock(cpua) && (!TItOps::LastInITBlock(cpua))) {
1313template <
typename TCpuAccessor,
typename TItOps>
1314static Result<Instr> BlxT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1315 static_cast<void>(cpua);
1316 const InstrId iid{InstrId::kBlx};
1322 const u8 m =
static_cast<u8
>(Rm);
1327 if (TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1334template <
typename TCpuAccessor,
typename TItOps>
1335static Result<Instr> BT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1336 static_cast<void>(cpua);
1337 const InstrId iid{InstrId::kBCond};
1340 if (TItOps::InITBlock(cpua)) {
1345 const u8 cond =
static_cast<u8
>(cond_32);
1349 assert(cond != 0b1110U);
1350 assert(cond != 0b1111U);
1355template <
typename TCpuAccessor,
typename TItOps>
1356static Result<Instr> BT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1357 static_cast<void>(cpua);
1358 const InstrId iid{InstrId::kB};
1364 if (TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1371template <
typename TCpuAccessor,
typename TItOps>
1372static Result<Instr> BT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1373 static_cast<void>(cpua);
1374 const InstrId iid{InstrId::kBCond};
1382 const u8 cond =
static_cast<u8
>(cond_32);
1388 const u32 imm32_us = (S << 20U) | (J2 << 19U) | (J1 << 18U) | (imm6 << 12U) | (imm11 << 1U);
1391 if (TItOps::InITBlock(cpua)) {
1394 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1399template <
typename TCpuAccessor,
typename TItOps>
1400static Result<Instr> BT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1401 static_cast<void>(cpua);
1402 const InstrId iid{InstrId::kB};
1414 const u32 I1 = (~(J1 ^ S)) & 0x1U;
1415 const u32 I2 = (~(J2 ^ S)) & 0x1U;
1416 const u32 imm32_us = (S << 24U) | (I1 << 23U) | (I2 << 22U) | (imm10 << 12U) | imm11 << 1U;
1419 if (TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
1422 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1427template <
typename TCpuAccessor,
typename TItOps>
1428static Result<Instr> SubSpMinusImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1429 static_cast<void>(cpua);
1430 const InstrId iid{InstrId::kSubSpMinusImmediate};
1435 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1443template <
typename TCpuAccessor,
typename TItOps>
1444static Result<Instr> SubSpMinusImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1445 static_cast<void>(cpua);
1446 const InstrId iid{InstrId::kSubSpMinusImmediate};
1455 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1457 const u8 d =
static_cast<u8
>(Rd);
1462 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1465 assert((d != 0b1111U) || (S != 1U));
1466 if (d == 15U && (S == 0x0U)) {
1469 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1474template <
typename TCpuAccessor,
typename TItOps>
1475static Result<Instr> SubSpMinusImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1476 static_cast<void>(cpua);
1477 const InstrId iid{InstrId::kSubSpMinusImmediate};
1484 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1486 const u8 d =
static_cast<u8
>(Rd);
1491 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1497 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1502template <
typename TCpuAccessor,
typename TItOps>
1503static Result<Instr> SubImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1504 static_cast<void>(cpua);
1505 const InstrId iid{InstrId::kSubImmediate};
1511 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
1520template <
typename TCpuAccessor,
typename TItOps>
1521static Result<Instr> SubImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1522 static_cast<void>(cpua);
1523 const InstrId iid{InstrId::kSubImmediate};
1529 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
1538template <
typename TCpuAccessor,
typename TItOps>
1539static Result<Instr> SubImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1540 static_cast<void>(cpua);
1541 const InstrId iid{InstrId::kSubImmediate};
1549 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1551 const u8 n =
static_cast<u8
>(Rn);
1553 const u8 d =
static_cast<u8
>(Rd);
1558 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1561 assert(!((d == 0xFU) && (S == 1U)));
1563 return SubSpMinusImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
1565 if (d == 13U || (d == 15U && S == 0x0U) || n == 15U) {
1568 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1573template <
typename TCpuAccessor,
typename TItOps>
1574static Result<Instr> SubImmediateT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1575 static_cast<void>(cpua);
1576 const InstrId iid{InstrId::kSubImmediate};
1583 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1585 const u8 n =
static_cast<u8
>(Rn);
1587 const u8 d =
static_cast<u8
>(Rd);
1592 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1595 assert(Rn != 0b1111U);
1596 if (Rn == 0b1101U) {
1597 return SubSpMinusImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
1599 if (d == 13U || d == 15U) {
1602 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1607template <
typename TCpuAccessor,
typename TItOps>
1608static Result<Instr> SbcImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1609 static_cast<void>(cpua);
1610 const InstrId iid{InstrId::kSbcImmediate};
1618 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1620 const u8 n =
static_cast<u8
>(Rn);
1622 const u8 d =
static_cast<u8
>(Rd);
1627 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1630 assert(!((d == 0xFU) && (S == 1U)));
1632 if (d == 13U || (d == 15U && S == 0x0U) || n == 15U) {
1635 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1640template <
typename TCpuAccessor,
typename TItOps>
1641static Result<Instr> AddSpPlusImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1642 static_cast<void>(cpua);
1643 const InstrId iid{InstrId::kAddSpPlusImmediate};
1648 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1656template <
typename TCpuAccessor,
typename TItOps>
1657static Result<Instr> AddSpPlusImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1658 static_cast<void>(cpua);
1659 const InstrId iid{InstrId::kAddSpPlusImmediate};
1664 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1672template <
typename TCpuAccessor,
typename TItOps>
1673static Result<Instr> AddSpPlusImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1674 static_cast<void>(cpua);
1675 const InstrId iid{InstrId::kAddSpPlusImmediate};
1684 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1686 const u8 d =
static_cast<u8
>(Rd);
1691 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1694 assert((Rd != 0b1111U) || (S != 1));
1695 if (d == 15U && S == 0x0U) {
1698 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1703template <
typename TCpuAccessor,
typename TItOps>
1704static Result<Instr> AddSpPlusImmediateT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1705 static_cast<void>(cpua);
1706 const InstrId iid{InstrId::kAddSpPlusImmediate};
1713 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1715 const u8 d =
static_cast<u8
>(Rd);
1720 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1726 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1731template <
typename TCpuAccessor,
typename TItOps>
1732static Result<Instr> AddImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1733 static_cast<void>(cpua);
1734 const InstrId iid{InstrId::kAddImmediate};
1740 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
1749template <
typename TCpuAccessor,
typename TItOps>
1750static Result<Instr> AddImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1751 static_cast<void>(cpua);
1752 const InstrId iid{InstrId::kAddImmediate};
1756 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
1765template <
typename TCpuAccessor,
typename TItOps>
1766static Result<Instr> AddImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1767 static_cast<void>(cpua);
1768 const InstrId iid{InstrId::kAddImmediate};
1776 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1778 const u8 n =
static_cast<u8
>(Rn);
1780 const u8 d =
static_cast<u8
>(Rd);
1785 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1788 assert(!((d == 0xFU) && (S == 1U)));
1789 if (Rn == 0b1101U) {
1790 return AddSpPlusImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
1792 if (d == 13U || (d == 15U && S == 0x0U) || n == 15U) {
1795 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1800template <
typename TCpuAccessor,
typename TItOps>
1801static Result<Instr> AddImmediateT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1802 static_cast<void>(cpua);
1803 const InstrId iid{InstrId::kAddImmediate};
1810 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
1812 const u8 n =
static_cast<u8
>(Rn);
1814 const u8 d =
static_cast<u8
>(Rd);
1819 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1822 assert(Rn != 0b1111U);
1823 if (Rn == 0b1101U) {
1824 return AddSpPlusImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
1826 if (d == 13U || d == 15U) {
1829 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1834template <
typename TCpuAccessor,
typename TItOps>
1835static Result<Instr> AdcImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1836 static_cast<void>(cpua);
1837 const InstrId iid{InstrId::kAdcImmediate};
1845 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1847 const u8 n =
static_cast<u8
>(Rn);
1849 const u8 d =
static_cast<u8
>(Rd);
1854 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1857 if (d == 13U || d == 15U || n == 13U || n == 15U) {
1860 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1865template <
typename TCpuAccessor,
typename TItOps>
1866static Result<Instr> TstImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1867 static_cast<void>(cpua);
1868 const InstrId iid{InstrId::kTstImmediate};
1877 const u8 n =
static_cast<u8
>(Rn);
1881 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1882 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
1884 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
1886 if (n == 13U || n == 15U) {
1889 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1894template <
typename TCpuAccessor,
typename TItOps>
1895static Result<Instr> TeqImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1896 static_cast<void>(cpua);
1897 const InstrId iid{InstrId::kTeqImmediate};
1906 const u8 n =
static_cast<u8
>(Rn);
1910 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1911 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
1913 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
1915 if (n == 13U || n == 15U) {
1918 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1923template <
typename TCpuAccessor,
typename TItOps>
1924static Result<Instr> TstRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1925 static_cast<void>(cpua);
1926 const InstrId iid{InstrId::kTstRegister};
1932 const u8 n =
static_cast<u8
>(Rn);
1934 const u8 m =
static_cast<u8
>(Rm);
1940template <
typename TCpuAccessor,
typename TItOps>
1941static Result<Instr> TeqRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1942 static_cast<void>(cpua);
1943 const InstrId iid{InstrId::kTeqRegister};
1951 const u8 n =
static_cast<u8
>(Rn);
1953 const u8 m =
static_cast<u8
>(Rm);
1957 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
1959 if (n == 13U || n == 15U || m == 13U || m == 15U) {
1962 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
1967template <
typename TCpuAccessor,
typename TItOps>
1968static Result<Instr> AndImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
1969 static_cast<void>(cpua);
1970 const InstrId iid{InstrId::kAndImmediate};
1979 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
1981 const u8 n =
static_cast<u8
>(Rn);
1983 const u8 d =
static_cast<u8
>(Rd);
1987 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
1988 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
1990 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
1992 if (d == 13U || (d == 15U && S == 0U) || n == 13U || n == 15U) {
1995 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2000template <
typename TCpuAccessor,
typename TItOps>
2001static Result<Instr> OrrImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2002 static_cast<void>(cpua);
2003 const InstrId iid{InstrId::kOrrImmediate};
2011 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2013 const u8 n =
static_cast<u8
>(Rn);
2015 const u8 d =
static_cast<u8
>(Rd);
2019 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
2020 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
2022 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
2024 assert(Rn != 0b1111U);
2025 if (d == 13U || d == 15U || n == 13U) {
2028 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2033template <
typename TCpuAccessor,
typename TItOps>
2034static Result<Instr> EorImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2035 static_cast<void>(cpua);
2036 const InstrId iid{InstrId::kEorImmediate};
2044 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2046 const u8 n =
static_cast<u8
>(Rn);
2048 const u8 d =
static_cast<u8
>(Rd);
2052 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
2053 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
2055 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
2057 if (d == 13U || (d == 15U && (S == 0U)) || n == 13U || n == 15U) {
2060 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2065template <
typename TCpuAccessor,
typename TItOps>
2066static Result<Instr> SubRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2067 static_cast<void>(cpua);
2068 const InstrId iid{InstrId::kSubRegister};
2074 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
2083template <
typename TCpuAccessor,
typename TItOps>
2084static Result<Instr> SubRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2085 static_cast<void>(cpua);
2086 const InstrId iid{InstrId::kSubRegister};
2093 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2097 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
2099 const u8 m =
static_cast<u8
>(Rm);
2101 const u8 n =
static_cast<u8
>(Rn);
2103 const u8 d =
static_cast<u8
>(Rd);
2105 assert((Rd != 0b1111U) || (S != 1U));
2106 assert(Rn != 0b1101U);
2107 if (d == 13U || (d == 15U && S == 0U) || n == 15U || m == 13U || m == 15U) {
2110 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2115template <
typename TCpuAccessor,
typename TItOps>
2116static Result<Instr> RsbRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2117 static_cast<void>(cpua);
2118 const InstrId iid{InstrId::kRsbRegister};
2125 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2129 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
2131 const u8 m =
static_cast<u8
>(Rm);
2133 const u8 n =
static_cast<u8
>(Rn);
2135 const u8 d =
static_cast<u8
>(Rd);
2137 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2140 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2145template <
typename TCpuAccessor,
typename TItOps>
2146static Result<Instr> UmlalT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2147 static_cast<void>(cpua);
2148 const InstrId iid{InstrId::kUmlal};
2154 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2156 const u8 dHi =
static_cast<u8
>(RdHi);
2158 const u8 dLo =
static_cast<u8
>(RdLo);
2160 const u8 m =
static_cast<u8
>(Rm);
2162 const u8 n =
static_cast<u8
>(Rn);
2164 if (dLo == 13U || dLo == 15U || dHi == 13U || dHi == 15U || n == 13U || n == 15U || m == 13U ||
2171 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2176template <
typename TCpuAccessor,
typename TItOps>
2177static Result<Instr> UmullT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2178 static_cast<void>(cpua);
2179 const InstrId iid{InstrId::kUmull};
2185 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2187 const u8 dHi =
static_cast<u8
>(RdHi);
2189 const u8 dLo =
static_cast<u8
>(RdLo);
2191 const u8 m =
static_cast<u8
>(Rm);
2193 const u8 n =
static_cast<u8
>(Rn);
2195 if (dLo == 13U || dLo == 15U || dHi == 13U || dHi == 15U || n == 13U || n == 15U || m == 13U ||
2202 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2207template <
typename TCpuAccessor,
typename TItOps>
2208static Result<Instr> SmullT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2209 static_cast<void>(cpua);
2210 const InstrId iid{InstrId::kSmull};
2216 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2218 const u8 dHi =
static_cast<u8
>(RdHi);
2220 const u8 dLo =
static_cast<u8
>(RdLo);
2222 const u8 m =
static_cast<u8
>(Rm);
2224 const u8 n =
static_cast<u8
>(Rn);
2229 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2234template <
typename TCpuAccessor,
typename TItOps>
2235static Result<Instr> MulT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2236 static_cast<void>(cpua);
2237 const InstrId iid{InstrId::kMul};
2244 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2246 const u8 d =
static_cast<u8
>(Rd);
2248 const u8 m =
static_cast<u8
>(Rm);
2250 const u8 n =
static_cast<u8
>(Rn);
2252 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2255 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2260template <
typename TCpuAccessor,
typename TItOps>
2261static Result<Instr> UdivT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2262 static_cast<void>(cpua);
2263 const InstrId iid{InstrId::kUdiv};
2271 const u8 d =
static_cast<u8
>(Rd);
2273 const u8 m =
static_cast<u8
>(Rm);
2275 const u8 n =
static_cast<u8
>(Rn);
2277 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2280 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2285template <
typename TCpuAccessor,
typename TItOps>
2286static Result<Instr> SdivT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2287 static_cast<void>(cpua);
2288 const InstrId iid{InstrId::kSdiv};
2296 const u8 d =
static_cast<u8
>(Rd);
2298 const u8 m =
static_cast<u8
>(Rm);
2300 const u8 n =
static_cast<u8
>(Rn);
2302 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2305 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2310template <
typename TCpuAccessor,
typename TItOps>
2311static Result<Instr> MlsT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2312 static_cast<void>(cpua);
2313 const InstrId iid{InstrId::kMls};
2320 const u8 a =
static_cast<u8
>(Ra);
2322 const u8 d =
static_cast<u8
>(Rd);
2324 const u8 m =
static_cast<u8
>(Rm);
2326 const u8 n =
static_cast<u8
>(Rn);
2328 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U || (a == 13U) ||
2332 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2337template <
typename TCpuAccessor,
typename TItOps>
2338static Result<Instr> MlaT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2339 static_cast<void>(cpua);
2340 const InstrId iid{InstrId::kMla};
2346 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2348 const u8 a =
static_cast<u8
>(Ra);
2350 const u8 d =
static_cast<u8
>(Rd);
2352 const u8 m =
static_cast<u8
>(Rm);
2354 const u8 n =
static_cast<u8
>(Rn);
2356 assert(Ra != 0b1111U);
2357 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U || (a == 13U) ||
2361 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2366template <
typename TCpuAccessor,
typename TItOps>
2367static Result<Instr> AddRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2368 static_cast<void>(cpua);
2369 const InstrId iid{InstrId::kAddRegister};
2375 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
2384template <
typename TCpuAccessor,
typename TItOps>
2385static Result<Instr> AddRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2386 static_cast<void>(cpua);
2387 const InstrId iid{InstrId::kAddRegister};
2392 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kSetFlags);
2396 const u8 n =
static_cast<u8
>(dn_1 << 3U | Bm16::ExtractBits1R<2U, 0U>(rinstr.low));
2398 const u8 d =
static_cast<u8
>(dn_2 << 3U | Bm16::ExtractBits1R<2U, 0U>(rinstr.low));
2400 assert(d != 0b1101U);
2401 assert(n != 0b1101U);
2402 if (d == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
2405 if (d == 15U && m == 15U) {
2412template <
typename TCpuAccessor,
typename TItOps>
2413static Result<Instr> AddRegisterT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2414 static_cast<void>(cpua);
2415 const InstrId iid{InstrId::kAddRegister};
2422 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2426 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
2428 const u8 m =
static_cast<u8
>(Rm);
2430 const u8 n =
static_cast<u8
>(Rn);
2432 const u8 d =
static_cast<u8
>(Rd);
2434 assert((d != 0b1111U) || (S != 1U));
2435 assert(m != 0b1101U);
2436 if (d == 13U || (d == 15U && S == 0U) || n == 15U || m == 13U || m == 15U) {
2439 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2444template <
typename TCpuAccessor,
typename TItOps>
2445static Result<Instr> AdcRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2446 static_cast<void>(cpua);
2447 const InstrId iid{InstrId::kAdcRegister};
2453 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
2454 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(0U)};
2456 const u8 m =
static_cast<u8
>(Rm);
2458 const u8 n =
static_cast<u8
>(Rn);
2460 const u8 d =
static_cast<u8
>(Rd);
2465template <
typename TCpuAccessor,
typename TItOps>
2466static Result<Instr> AdcRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2467 static_cast<void>(cpua);
2468 const InstrId iid{InstrId::kAdcRegister};
2475 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2479 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2) | imm2);
2481 const u8 m =
static_cast<u8
>(Rm);
2483 const u8 n =
static_cast<u8
>(Rn);
2485 const u8 d =
static_cast<u8
>(Rd);
2487 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2490 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2495template <
typename TCpuAccessor,
typename TItOps>
2496static Result<Instr> StmdbT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2497 static_cast<void>(cpua);
2498 const InstrId iid{InstrId::kStmdb};
2508 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
2510 const u8 n =
static_cast<u8
>(Rn);
2513 const u32 registers = (M << 14U) | register_list;
2515 assert((W != 0x1U) || (Rn != 0b1101U));
2520 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2525template <
typename TCpuAccessor,
typename TItOps>
2526static Result<Instr> PushT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2527 static_cast<void>(cpua);
2528 const InstrId iid{InstrId::kPush};
2533 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kUnalignedAllow);
2536 const u32 registers = (M << 14U) | register_list;
2545template <
typename TCpuAccessor,
typename TItOps>
2546static Result<Instr> PushT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2547 static_cast<void>(cpua);
2548 const InstrId iid{InstrId::kPush};
2555 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kUnalignedAllow);
2558 const u32 registers = (M << 14U) | register_list;
2563 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2568template <
typename TCpuAccessor,
typename TItOps>
2569static Result<Instr> PushT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2570 static_cast<void>(cpua);
2571 const InstrId iid{InstrId::kPush};
2574 assert(rinstr.low == 0b1111100001001101U);
2577 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kUnalignedAllow);
2579 const u8 t =
static_cast<u8
>(Rt);
2580 const u32 registers = 1U << Rt;
2582 if (t == 13U || t == 15U) {
2585 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2590template <
typename TCpuAccessor,
typename TItOps>
2591static Result<Instr> LdmT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2592 static_cast<void>(cpua);
2593 const InstrId iid{InstrId::kLdm};
2600 const u16 n_mask = 1U << Rn_flag;
2601 flags |= (register_list_flag & n_mask) == 0 ?
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) : 0U;
2603 const u32 registers =
static_cast<u32
>(register_list);
2605 const u8 n =
static_cast<u8
>(Rn);
2614template <
typename TCpuAccessor,
typename TItOps>
2615static Result<Instr> LdmT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2616 static_cast<void>(cpua);
2617 const InstrId iid{InstrId::kLdm};
2625 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
2629 const u32 registers = (P << 15U) | (M << 14U) | register_list;
2631 const u8 n =
static_cast<u8
>(Rn);
2633 assert((W != 1) || (Rn != 0b1101U));
2634 if (n == 15 || (
Bm32::BitCount(registers) < 2U) || ((P == 1U) && M == 1U)) {
2638 (!TItOps::LastInITBlock(cpua))) {
2641 if (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && ((registers & (1 << n)) != 0U)) {
2644 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2649template <
typename TCpuAccessor,
typename TItOps>
2650static Result<Instr> StmT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2651 static_cast<void>(cpua);
2652 const InstrId iid{InstrId::kStm};
2657 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kWBack);
2659 const u32 registers =
static_cast<u32
>(register_list);
2661 const u8 n =
static_cast<u8
>(Rn);
2666template <
typename TCpuAccessor,
typename TItOps>
2667static Result<Instr> StmT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2668 static_cast<void>(cpua);
2669 const InstrId iid{InstrId::kStm};
2677 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kUnalignedAllow);
2679 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
2682 const u32 registers = (M << 14U) | register_list;
2684 const u8 n =
static_cast<u8
>(Rn);
2689 if (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && ((registers & (1 << n)) != 0U)) {
2692 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2697template <
typename TCpuAccessor,
typename TItOps>
2698static Result<Instr> SxthT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2699 static_cast<void>(cpua);
2700 const InstrId iid{InstrId::kSxth};
2706 const u8 m =
static_cast<u8
>(Rm);
2708 const u8 d =
static_cast<u8
>(Rd);
2709 const u8 rotation = 0U;
2714template <
typename TCpuAccessor,
typename TItOps>
2715static Result<Instr> SxthT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2716 static_cast<void>(cpua);
2717 const InstrId iid{InstrId::kSxth};
2725 const u8 m =
static_cast<u8
>(Rm);
2727 const u8 d =
static_cast<u8
>(Rd);
2729 const u8 rotation =
static_cast<u8
>(rotate << 3U);
2731 if (d == 13U || d == 15U || m == 13U || m == 15U) {
2734 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2739template <
typename TCpuAccessor,
typename TItOps>
2740static Result<Instr> UxtbT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2741 static_cast<void>(cpua);
2742 const InstrId iid{InstrId::kUxtb};
2748 const u8 m =
static_cast<u8
>(Rm);
2750 const u8 d =
static_cast<u8
>(Rd);
2751 const u8 rotation = 0U;
2756template <
typename TCpuAccessor,
typename TItOps>
2757static Result<Instr> UxtbT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2758 static_cast<void>(cpua);
2759 const InstrId iid{InstrId::kUxtb};
2767 const u8 m =
static_cast<u8
>(Rm);
2769 const u8 d =
static_cast<u8
>(Rd);
2771 const u8 rotation =
static_cast<u8
>(rotate << 3U);
2773 if (d == 13U || d == 15U || m == 13U || m == 15U) {
2776 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2781template <
typename TCpuAccessor,
typename TItOps>
2782static Result<Instr> SxtbT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2783 static_cast<void>(cpua);
2784 const InstrId iid{InstrId::kSxtb};
2790 const u8 m =
static_cast<u8
>(Rm);
2792 const u8 d =
static_cast<u8
>(Rd);
2793 const u8 rotation = 0U;
2798template <
typename TCpuAccessor,
typename TItOps>
2799static Result<Instr> SxtbT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2800 static_cast<void>(cpua);
2801 const InstrId iid{InstrId::kSxtb};
2809 const u8 m =
static_cast<u8
>(Rm);
2811 const u8 d =
static_cast<u8
>(Rd);
2813 const u8 rotation =
static_cast<u8
>(rotate << 3U);
2815 if (d == 13U || d == 15U || m == 13U || m == 15U) {
2818 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2823template <
typename TCpuAccessor,
typename TItOps>
2824static Result<Instr> UxthT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2825 static_cast<void>(cpua);
2826 const InstrId iid{InstrId::kUxth};
2832 const u8 m =
static_cast<u8
>(Rm);
2834 const u8 d =
static_cast<u8
>(Rd);
2835 const u8 rotation = 0U;
2840template <
typename TCpuAccessor,
typename TItOps>
2841static Result<Instr> UxthT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2842 static_cast<void>(cpua);
2843 const InstrId iid{InstrId::kUxth};
2851 const u8 m =
static_cast<u8
>(Rm);
2853 const u8 d =
static_cast<u8
>(Rd);
2855 const u8 rotation = rotate << 3U;
2857 if (d == 13U || d == 15U || m == 13U || m == 15U) {
2860 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2865template <
typename TCpuAccessor,
typename TItOps>
2866static Result<Instr> BfiT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2867 static_cast<void>(cpua);
2868 const InstrId iid{InstrId::kBfi};
2876 const u8 d =
static_cast<u8
>(Rd);
2878 const u8 n =
static_cast<u8
>(Rn);
2881 const u8 lsbit =
static_cast<u8
>((imm3 << 2U) | imm2);
2883 const u8 msbit =
static_cast<u8
>(msb);
2885 if (d == 13U || d == 15U || n == 13U) {
2888 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2893template <
typename TCpuAccessor,
typename TItOps>
2894static Result<Instr> UbfxT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2895 static_cast<void>(cpua);
2896 const InstrId iid{InstrId::kUbfx};
2904 const u8 d =
static_cast<u8
>(Rd);
2906 const u8 n =
static_cast<u8
>(Rn);
2909 const u8 lsbit =
static_cast<u8
>((imm3 << 2U) | imm2);
2911 const u8 widthminus1 =
static_cast<u8
>(widthm1);
2913 if (d == 13U || d == 15U || n == 13U || n == 15U) {
2916 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2918 return Ok(
Instr{
InstrUbfx{iid, flags, d, n, lsbit, widthminus1}});
2921template <
typename TCpuAccessor,
typename TItOps>
2922static Result<Instr> EorRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2923 static_cast<void>(cpua);
2924 const InstrId iid{InstrId::kEorRegister};
2930 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
2932 const u8 n =
static_cast<u8
>(Rn);
2934 const u8 d =
static_cast<u8
>(Rd);
2936 const u8 m =
static_cast<u8
>(Rm);
2942template <
typename TCpuAccessor,
typename TItOps>
2943static Result<Instr> EorRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2944 static_cast<void>(cpua);
2945 const InstrId iid{InstrId::kEorRegister};
2952 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2954 const u8 n =
static_cast<u8
>(Rn);
2956 const u8 d =
static_cast<u8
>(Rd);
2958 const u8 m =
static_cast<u8
>(Rm);
2962 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
2964 assert((Rd != 0b1111U) || (S != 1));
2965 if (d == 13U || (d == 15U && (S == 0)) || n == 15U || m == 13U || m == 15U) {
2968 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
2973template <
typename TCpuAccessor,
typename TItOps>
2974static Result<Instr> SbcRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
2975 static_cast<void>(cpua);
2976 const InstrId iid{InstrId::kSbcRegister};
2983 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
2985 const u8 n =
static_cast<u8
>(Rn);
2987 const u8 d =
static_cast<u8
>(Rd);
2989 const u8 m =
static_cast<u8
>(Rm);
2993 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
2995 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
2998 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3003template <
typename TCpuAccessor,
typename TItOps>
3004static Result<Instr> OrrRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3005 static_cast<void>(cpua);
3006 const InstrId iid{InstrId::kOrrRegister};
3012 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3014 const u8 n =
static_cast<u8
>(Rn);
3016 const u8 d =
static_cast<u8
>(Rd);
3018 const u8 m =
static_cast<u8
>(Rm);
3024template <
typename TCpuAccessor,
typename TItOps>
3025static Result<Instr> OrrRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3026 static_cast<void>(cpua);
3027 const InstrId iid{InstrId::kOrrRegister};
3034 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3036 const u8 n =
static_cast<u8
>(Rn);
3038 const u8 d =
static_cast<u8
>(Rd);
3040 const u8 m =
static_cast<u8
>(Rm);
3044 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
3046 assert(Rn != 0b1111U);
3047 if (d == 13U || d == 15U || n == 15U || m == 13U || m == 15U) {
3050 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3055template <
typename TCpuAccessor,
typename TItOps>
3056static Result<Instr> AndRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3057 static_cast<void>(cpua);
3058 const InstrId iid{InstrId::kAndRegister};
3064 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3066 const u8 n =
static_cast<u8
>(Rn);
3068 const u8 d =
static_cast<u8
>(Rd);
3070 const u8 m =
static_cast<u8
>(Rm);
3076template <
typename TCpuAccessor,
typename TItOps>
3077static Result<Instr> AndRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3078 static_cast<void>(cpua);
3079 const InstrId iid{InstrId::kAndRegister};
3086 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3088 const u8 n =
static_cast<u8
>(Rn);
3090 const u8 d =
static_cast<u8
>(Rd);
3092 const u8 m =
static_cast<u8
>(Rm);
3096 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
3098 assert((Rd != 0b1111U) || (S != 0b1U));
3099 if (d == 13U || (d == 15U && (S == 0U)) || n == 13U || n == 15U || m == 13U || m == 15U) {
3102 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3107template <
typename TCpuAccessor,
typename TItOps>
3108static Result<Instr> BicImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3109 static_cast<void>(cpua);
3110 const InstrId iid{InstrId::kBicImmediate};
3117 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3119 const u8 n =
static_cast<u8
>(Rn);
3121 const u8 d =
static_cast<u8
>(Rd);
3125 const u32 imm12 = (i << 11U) | (imm3 << 8U) | imm8;
3126 auto apsr = cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
3128 Thumb::ThumbExpandImm_C(imm12, (apsr & ApsrRegister::kCMsk) == ApsrRegister::kCMsk));
3130 if (d == 13U || d == 15U || n == 13U || n == 15U) {
3133 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3138template <
typename TCpuAccessor,
typename TItOps>
3139static Result<Instr> BicRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3140 static_cast<void>(cpua);
3141 const InstrId iid{InstrId::kBicRegister};
3147 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3149 const u8 n =
static_cast<u8
>(Rn);
3151 const u8 d =
static_cast<u8
>(Rd);
3153 const u8 m =
static_cast<u8
>(Rm);
3159template <
typename TCpuAccessor,
typename TItOps>
3160static Result<Instr> BicRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3161 static_cast<void>(cpua);
3162 const InstrId iid{InstrId::kBicRegister};
3169 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3171 const u8 n =
static_cast<u8
>(Rn);
3173 const u8 d =
static_cast<u8
>(Rd);
3175 const u8 m =
static_cast<u8
>(Rm);
3179 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
3181 if (d == 13U || d == 15U || n == 13U || n == 15U || m == 13U || m == 15U) {
3184 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3189template <
typename TCpuAccessor,
typename TItOps>
3190static Result<Instr> LsrRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3191 static_cast<void>(cpua);
3192 const InstrId iid{InstrId::kLsrRegister};
3198 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3200 const u8 n =
static_cast<u8
>(Rn);
3202 const u8 d =
static_cast<u8
>(Rd);
3204 const u8 m =
static_cast<u8
>(Rm);
3209template <
typename TCpuAccessor,
typename TItOps>
3210static Result<Instr> LsrRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3211 static_cast<void>(cpua);
3212 const InstrId iid{InstrId::kLsrRegister};
3220 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3222 const u8 n =
static_cast<u8
>(Rn);
3224 const u8 d =
static_cast<u8
>(Rd);
3226 const u8 m =
static_cast<u8
>(Rm);
3228 if (d == 13U || d == 15 || n == 13U || n == 15 || m == 13U || m == 15) {
3231 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3236template <
typename TCpuAccessor,
typename TItOps>
3237static Result<Instr> AsrRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3238 static_cast<void>(cpua);
3239 const InstrId iid{InstrId::kAsrRegister};
3245 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3247 const u8 n =
static_cast<u8
>(Rn);
3249 const u8 d =
static_cast<u8
>(Rd);
3251 const u8 m =
static_cast<u8
>(Rm);
3256template <
typename TCpuAccessor,
typename TItOps>
3257static Result<Instr> AsrRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3258 static_cast<void>(cpua);
3259 const InstrId iid{InstrId::kAsrRegister};
3267 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3269 const u8 n =
static_cast<u8
>(Rn);
3271 const u8 d =
static_cast<u8
>(Rd);
3273 const u8 m =
static_cast<u8
>(Rm);
3275 if (d == 13U || d == 15 || n == 13U || n == 15 || m == 13U || m == 15) {
3278 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3283template <
typename TCpuAccessor,
typename TItOps>
3284static Result<Instr> LsrImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3285 static_cast<void>(cpua);
3286 const InstrId iid{InstrId::kLsrImmediate};
3292 TItOps::InITBlock(cpua) ==
false ?
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags) : 0U;
3294 const u8 m =
static_cast<u8
>(Rm);
3296 const u8 d =
static_cast<u8
>(Rd);
3298 const auto shift_res = Alu32::DecodeImmShift(0b01U, imm5);
3303template <
typename TCpuAccessor,
typename TItOps>
3304static Result<Instr> LsrImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3305 static_cast<void>(cpua);
3306 const InstrId iid{InstrId::kLsrImmediate};
3315 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3317 const u8 m =
static_cast<u8
>(Rm);
3319 const u8 d =
static_cast<u8
>(Rd);
3322 const auto shift_res = Alu32::DecodeImmShift(0b01U, (imm3_32 << 2U) | imm2_32);
3324 assert(shift_res.type == SRType::SRType_LSR);
3325 if (d == 13U || d == 15U || m == 13U || m == 15U) {
3328 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3333template <
typename TCpuAccessor,
typename TItOps>
3334static Result<Instr> MvnRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3335 static_cast<void>(cpua);
3336 const InstrId iid{InstrId::kMvnRegister};
3344 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3346 const u8 m =
static_cast<u8
>(Rm);
3348 const u8 d =
static_cast<u8
>(Rd);
3352 const auto shift_res = Alu32::DecodeImmShift(type, (imm3 << 2U) | imm2);
3354 if (d == 13U || d == 15U || m == 13U || m == 15U) {
3357 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3362template <
typename TCpuAccessor,
typename TItOps>
3363static Result<Instr> AsrImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3364 static_cast<void>(cpua);
3365 const InstrId iid{InstrId::kAsrImmediate};
3374 flags |= S << static_cast<InstrFlagsSet>(InstrFlagsShift::kSetFlagsShift);
3376 const u8 m =
static_cast<u8
>(Rm);
3378 const u8 d =
static_cast<u8
>(Rd);
3381 const auto shift_res = Alu32::DecodeImmShift(0b10U, (imm3_32 << 2U) | imm2_32);
3383 assert(shift_res.type == SRType::SRType_ASR);
3384 if (d == 13U || d == 15U || m == 13U || m == 15U) {
3387 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3392template <
typename TCpuAccessor,
typename TItOps>
3393static Result<Instr> StrRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3394 static_cast<void>(cpua);
3395 const InstrId iid{InstrId::kStrRegister};
3400 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3401 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3402 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3404 const u8 n =
static_cast<u8
>(Rn);
3406 const u8 m =
static_cast<u8
>(Rm);
3408 const u8 t =
static_cast<u8
>(Rt);
3414template <
typename TCpuAccessor,
typename TItOps>
3415static Result<Instr> StrRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3416 static_cast<void>(cpua);
3417 const InstrId iid{InstrId::kStrRegister};
3423 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3424 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3425 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3427 const u8 n =
static_cast<u8
>(Rn);
3429 const u8 m =
static_cast<u8
>(Rm);
3431 const u8 t =
static_cast<u8
>(Rt);
3433 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(imm2)};
3435 if (t == 15U || m == 13U || m == 15) {
3438 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3443template <
typename TCpuAccessor,
typename TItOps>
3444static Result<Instr> StrbRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3445 static_cast<void>(cpua);
3446 const InstrId iid{InstrId::kStrbRegister};
3451 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3452 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3453 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3455 const u8 n =
static_cast<u8
>(Rn);
3457 const u8 m =
static_cast<u8
>(Rm);
3459 const u8 t =
static_cast<u8
>(Rt);
3465template <
typename TCpuAccessor,
typename TItOps>
3466static Result<Instr> StrbRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3467 static_cast<void>(cpua);
3468 const InstrId iid{InstrId::kStrbRegister};
3474 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3475 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3476 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3478 const u8 n =
static_cast<u8
>(Rn);
3480 const u8 m =
static_cast<u8
>(Rm);
3482 const u8 t =
static_cast<u8
>(Rt);
3484 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(imm2)};
3486 if (Rn == 0b1111U) {
3489 if (t == 13U || t == 15U || m == 13U || m == 15) {
3492 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3497template <
typename TCpuAccessor,
typename TItOps>
3498static Result<Instr> StrhRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3499 static_cast<void>(cpua);
3500 const InstrId iid{InstrId::kStrhRegister};
3506 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3507 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3508 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3510 const u8 n =
static_cast<u8
>(Rn);
3512 const u8 m =
static_cast<u8
>(Rm);
3514 const u8 t =
static_cast<u8
>(Rt);
3516 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(imm2)};
3518 if (Rn == 0b1111U) {
3521 if (t == 13U || t == 15U || m == 13U || m == 15) {
3524 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3529template <
typename TCpuAccessor,
typename TItOps>
3530static Result<Instr> LdrbRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3531 static_cast<void>(cpua);
3532 const InstrId iid{InstrId::kLdrbRegister};
3537 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3538 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3539 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3541 const u8 m =
static_cast<u8
>(Rm);
3543 const u8 n =
static_cast<u8
>(Rn);
3545 const u8 t =
static_cast<u8
>(Rt);
3551template <
typename TCpuAccessor,
typename TItOps>
3552static Result<Instr> LdrRegisterT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3553 static_cast<void>(cpua);
3554 const InstrId iid{InstrId::kLdrRegister};
3559 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3560 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3561 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3563 const u8 m =
static_cast<u8
>(Rm);
3565 const u8 n =
static_cast<u8
>(Rn);
3567 const u8 t =
static_cast<u8
>(Rt);
3573template <
typename TCpuAccessor,
typename TItOps>
3574static Result<Instr> LdrRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3575 static_cast<void>(cpua);
3576 const InstrId iid{InstrId::kLdrRegister};
3583 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3584 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3585 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3587 const u8 m =
static_cast<u8
>(Rm);
3589 const u8 n =
static_cast<u8
>(Rn);
3591 const u8 t =
static_cast<u8
>(Rt);
3593 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(imm2)};
3595 if (m == 13U || m == 15) {
3598 if (t == 15U && TItOps::InITBlock(cpua) && !TItOps::LastInITBlock(cpua)) {
3601 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3606template <
typename TCpuAccessor,
typename TItOps>
3607static Result<Instr> LdrhRegisterT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3608 static_cast<void>(cpua);
3609 const InstrId iid{InstrId::kLdrhRegister};
3615 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3616 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3617 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3619 const u8 m =
static_cast<u8
>(Rm);
3621 const u8 n =
static_cast<u8
>(Rn);
3623 const u8 t =
static_cast<u8
>(Rt);
3625 const auto shift_res =
ImmShiftResults{SRType::SRType_LSL,
static_cast<u8
>(imm2)};
3627 assert(Rn != 0b1111U);
3628 assert(Rt != 0b1111U);
3629 if (t == 13U || m == 13U || m == 15) {
3632 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3637template <
typename TCpuAccessor,
typename TItOps>
3638static Result<Instr> StrdImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3639 static_cast<void>(cpua);
3640 const InstrId iid{InstrId::kStrdImmediate};
3648 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
3650 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
3652 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
3654 const u8 n =
static_cast<u8
>(Rn);
3656 const u8 t =
static_cast<u8
>(Rt);
3658 const u8 t2 =
static_cast<u8
>(Rt2);
3662 assert((P != 0U) || (W != 0U));
3663 if (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && (n == t || n == t2)) {
3666 if (n == 15U || t == 13U || t == 15U || t2 == 13U || t2 == 15U) {
3669 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3674template <
typename TCpuAccessor,
typename TItOps>
3675static Result<Instr> StrhImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3676 static_cast<void>(cpua);
3677 const InstrId iid{InstrId::kStrhImmediate};
3682 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3683 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3684 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3686 const u8 n =
static_cast<u8
>(Rn);
3688 const u8 t =
static_cast<u8
>(Rt);
3695template <
typename TCpuAccessor,
typename TItOps>
3696static Result<Instr> StrhImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3697 static_cast<void>(cpua);
3698 const InstrId iid{InstrId::kStrhImmediate};
3703 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3704 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3705 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3707 const u8 n =
static_cast<u8
>(Rn);
3709 const u8 t =
static_cast<u8
>(Rt);
3713 if (t == 13U || t == 15U) {
3716 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3721template <
typename TCpuAccessor,
typename TItOps>
3722static Result<Instr> StrhImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3723 static_cast<void>(cpua);
3724 const InstrId iid{InstrId::kStrhImmediate};
3731 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
3733 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
3735 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
3737 const u8 n =
static_cast<u8
>(Rn);
3739 const u8 t =
static_cast<u8
>(Rt);
3743 assert(P != 0b1U || U != 0b1U || W != 0b0U);
3744 if ((Rn == 0b1111U) || (P == 0b0 && W == 0b0U)) {
3747 if ((t == 13U || t == 15U) &&
3748 (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
3751 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3756template <
typename TCpuAccessor,
typename TItOps>
3757static Result<Instr> StrbImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3758 static_cast<void>(cpua);
3759 const InstrId iid{InstrId::kStrbImmediate};
3764 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3765 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3766 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3768 const u8 n =
static_cast<u8
>(Rn);
3770 const u8 t =
static_cast<u8
>(Rt);
3777template <
typename TCpuAccessor,
typename TItOps>
3778static Result<Instr> StrbImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3779 static_cast<void>(cpua);
3780 const InstrId iid{InstrId::kStrbImmediate};
3785 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3786 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3787 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3789 const u8 n =
static_cast<u8
>(Rn);
3791 const u8 t =
static_cast<u8
>(Rt);
3795 if (Rn == 0b1111U) {
3798 if (t == 13U || t == 15U) {
3801 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3806template <
typename TCpuAccessor,
typename TItOps>
3807static Result<Instr> StrbImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3808 static_cast<void>(cpua);
3809 const InstrId iid{InstrId::kStrbImmediate};
3816 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
3818 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
3820 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
3822 const u8 n =
static_cast<u8
>(Rn);
3824 const u8 t =
static_cast<u8
>(Rt);
3828 assert((P != 1U) || (U != 1) || (W != 0U));
3829 if (n == 15U || ((P == 0U) && (W == 0U))) {
3832 if (t == 13U || t == 15U || (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
3835 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3840template <
typename TCpuAccessor,
typename TItOps>
3841static Result<Instr> StrImmediateT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3842 static_cast<void>(cpua);
3843 const InstrId iid{InstrId::kStrImmediate};
3848 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3849 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3850 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3852 const u8 n =
static_cast<u8
>(Rn);
3854 const u8 t =
static_cast<u8
>(Rt);
3861template <
typename TCpuAccessor,
typename TItOps>
3862static Result<Instr> StrImmediateT2Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3863 static_cast<void>(cpua);
3864 const InstrId iid{InstrId::kStrImmediate};
3869 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3870 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3871 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3874 const u8 t =
static_cast<u8
>(Rt);
3881template <
typename TCpuAccessor,
typename TItOps>
3882static Result<Instr> StrImmediateT3Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3883 static_cast<void>(cpua);
3884 const InstrId iid{InstrId::kStrImmediate};
3889 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3890 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3891 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3893 const u8 n =
static_cast<u8
>(Rn);
3895 const u8 t =
static_cast<u8
>(Rt);
3905 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3910template <
typename TCpuAccessor,
typename TItOps>
3911static Result<Instr> StrImmediateT4Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3912 static_cast<void>(cpua);
3913 const InstrId iid{InstrId::kStrImmediate};
3920 flags |= U << static_cast<InstrFlagsSet>(InstrFlagsShift::kAddShift);
3922 flags |= P << static_cast<InstrFlagsSet>(InstrFlagsShift::kIndexShift);
3924 flags |= W << static_cast<InstrFlagsSet>(InstrFlagsShift::kWBackShift);
3926 const u8 n =
static_cast<u8
>(Rn);
3928 const u8 t =
static_cast<u8
>(Rt);
3932 assert((P != 1U) || (U != 1) || (W != 0U));
3933 if ((n == 13U) && (P == 1) && (U == 0U) && (W == 1U) && (imm8_32 == 0b00000100U)) {
3934 return PushT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
3936 if (n == 15U || ((P == 0U) && (W == 0U))) {
3939 if (t == 15U || (flags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack) && n == t)) {
3942 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3947template <
typename TCpuAccessor,
typename TItOps>
3948static Result<Instr> StrexT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3949 static_cast<void>(cpua);
3950 const InstrId iid{InstrId::kStrex};
3955 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kAdd);
3956 flags |=
static_cast<InstrFlagsSet
>(InstrFlags::kIndex);
3957 flags &= ~static_cast<InstrFlagsSet>(InstrFlags::kWBack);
3959 const u8 n =
static_cast<u8
>(Rn);
3961 const u8 t =
static_cast<u8
>(Rt);
3963 const u8 d =
static_cast<u8
>(Rd);
3967 if (d == n || d == t) {
3970 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
3975template <
typename TCpuAccessor,
typename TItOps>
3976static Result<Instr> CbNZT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
3977 static_cast<void>(cpua);
3978 const InstrId iid{InstrId::kCbNZ};
3986 flags |= op << static_cast<InstrFlagsSet>(InstrFlagsShift::kNonZeroShift);
3988 const u8 n =
static_cast<u8
>(Rn);
3993 if (TItOps::InITBlock(cpua)) {
4000template <
typename TCpuAccessor,
typename TItOps>
4001static Result<Instr> SvcT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4002 static_cast<void>(cpua);
4003 const InstrId iid{InstrId::kSvc};
4014template <
typename TCpuAccessor,
typename TItOps>
4015static Result<Instr> BkptT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4016 static_cast<void>(cpua);
4017 const InstrId iid{InstrId::kBkpt};
4028template <
typename TCpuAccessor,
typename TItOps>
4029static Result<Instr> MsrT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4030 static_cast<void>(cpua);
4031 const InstrId iid{InstrId::kMsr};
4042 if (mask == 0b00U || (mask != 0b10U && !(SYSm == 0U || SYSm == 1U || SYSm == 2U || SYSm == 3U))) {
4045 if ((n == 13U) || (n == 15U) ||
4046 !(SYSm == 0U || SYSm == 1U || SYSm == 2U || SYSm == 3U || SYSm == 5U || SYSm == 6U ||
4047 SYSm == 7U || SYSm == 8U || SYSm == 9U || SYSm == 16U || SYSm == 17U || SYSm == 18U ||
4048 SYSm == 19U || SYSm == 20U)) {
4051 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
4056template <
typename TCpuAccessor,
typename TItOps>
4057static Result<Instr> MrsT1Decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4058 static_cast<void>(cpua);
4059 const InstrId iid{InstrId::kMrs};
4062 assert(rinstr.low == 0b1111001111101111U);
4069 if ((d == 13U) || (d == 15U) ||
4070 !(SYSm == 0U || SYSm == 1U || SYSm == 2U || SYSm == 3U || SYSm == 5U || SYSm == 6U ||
4071 SYSm == 7U || SYSm == 8U || SYSm == 9U || SYSm == 16U || SYSm == 17U || SYSm == 18U ||
4072 SYSm == 19U || SYSm == 20U)) {
4075 flags |=
static_cast<u8
>(InstrFlags::k32Bit);
4080template <
typename TCpuAccessor,
typename TItOps>
4081static Result<Instr> Splitter16bit_op00000(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4089 return MovRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4091 return LslImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4096template <
typename TCpuAccessor,
typename TItOps>
4097static Result<Instr> Splitter16bit_op00011(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4104 if (opcode == 0b01100U) {
4105 return AddRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4106 }
else if (opcode == 0b01110U) {
4107 return AddImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4108 }
else if (opcode == 0b01101U) {
4109 return SubRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4110 }
else if (opcode == 0b01111U) {
4111 return SubImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4115template <
typename TCpuAccessor,
typename TItOps>
4116static Result<Instr> Splitter16bit_op01010(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4122 if (op_a == 0b0101U && op_b == 0b000U) {
4123 return StrRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4124 }
else if (op_a == 0b0101U && op_b == 0b010U) {
4125 return StrbRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4129template <
typename TCpuAccessor,
typename TItOps>
4130static Result<Instr> Splitter16bit_op10111(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4136 return CbNZT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4138 return CbNZT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4140 return PopT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4142 return BkptT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4147 return ItT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4151 return NopT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4156template <
typename TCpuAccessor,
typename TItOps>
4157static Result<Instr> Splitter16bit_op10110(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4165 return AddSpPlusImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4167 return CbNZT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4169 return SubSpMinusImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4171 return CbNZT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4173 return SxtbT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4175 return UxtbT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4177 return UxthT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4179 return SxthT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4181 return PushT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4185template <
typename TCpuAccessor,
typename TItOps>
4186static Result<Instr> Splitter16bit_op01000(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4191 return AddRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4193 return MovRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4195 return CmpRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4197 return BxT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4199 return BlxT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4205 if (_opcode == 0b0000U) {
4206 return AndRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4207 }
else if (_opcode == 0b0010U) {
4208 return LslRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4209 }
else if (_opcode == 0b0011U) {
4210 return LsrRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4211 }
else if (_opcode == 0b0100U) {
4212 return AsrRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4213 }
else if (_opcode == 0b0101U) {
4214 return AdcRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4215 }
else if (_opcode == 0b0001U) {
4216 return EorRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4217 }
else if (_opcode == 0b1000U) {
4218 return TstRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4219 }
else if (_opcode == 0b1001U) {
4220 return RsbImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4221 }
else if (_opcode == 0b1010U) {
4222 return CmpRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4223 }
else if (_opcode == 0b1100U) {
4224 return OrrRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4225 }
else if (_opcode == 0b1110U) {
4226 return BicRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4231template <
typename TCpuAccessor,
typename TItOps>
4232static Result<Instr> Splitter16bit_op01011(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4239 if (opB == 0b100U) {
4240 return LdrRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4241 }
else if (opB == 0b110U) {
4242 return LdrbRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4246template <
typename TCpuAccessor,
typename TItOps>
4247static Result<Instr> Splitter16bit_op01101(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4255 return LdrImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4259template <
typename TCpuAccessor,
typename TItOps>
4260static Result<Instr> Splitter16bit_op11011(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4268 return BT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4269 }
else if (opcode == 0b1111U) {
4270 return SvcT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4274template <
typename TCpuAccessor,
typename TItOps>
4275static Result<Instr> Splitter32bit_op11101(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4285 if ((op == 0b0000U) && (Rd != 0b1111U)) {
4286 return AndRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4287 }
else if (op == 0b0001U) {
4288 return BicRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4289 }
else if (op == 0b0011U && Rn == 0b1111U) {
4290 return MvnRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4291 }
else if (op == 0b1000U && Rd != 0b1111U) {
4292 return AddRegisterT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4293 }
else if (op == 0b1110U) {
4294 return RsbRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4295 }
else if (op == 0b0010U && Rn == 0b1111U) {
4301 const u32 imm3_2 = imm3 << 2U | imm2;
4302 if (type == 0b00U && imm3_2 == 0b00000U) {
4303 return MovRegisterT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4304 }
else if (type == 0b01U) {
4305 return LsrImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4306 }
else if (type == 0b10U) {
4307 return AsrImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4308 }
else if (type == 0b00U && imm3_2 != 0b00000U) {
4309 return LslImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4310 }
else if (type == 0b11U && imm3_2 == 0b00000U) {
4311 return RrxT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4313 }
else if (op == 0b0010U && Rn != 0b1111U) {
4314 return OrrRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4315 }
else if (op == 0b0100U && Rd != 0b1111U) {
4316 return EorRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4317 }
else if (op == 0b0100U && Rd == 0b1111U && S == 1) {
4318 return TeqRegisterT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4319 }
else if (op == 0b0100U && Rd == 0b1111U && S == 0) {
4321 }
else if (op == 0b1101U && Rd != 0b1111U) {
4322 return SubRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4323 }
else if (op == 0b1010U) {
4324 return AdcRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4325 }
else if (op == 0b1011U) {
4326 return SbcRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4327 }
else if (op == 0b1101U && Rd == 0b1111U) {
4328 return CmpRegisterT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4338 const u16 W_Rn = (W << 4U) | Rn;
4339 if ((op == 0b10U) && (L == 0U) && (W_Rn == 0b11101U)) {
4340 return PushT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4341 }
else if ((op == 0b01U) && (L == 0U)) {
4342 return StmT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4343 }
else if ((op == 0b10U) && (L == 0U) && (W_Rn != 0b11101U)) {
4344 return StmdbT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4345 }
else if ((op == 0b01U) && (L == 1U) && (W_Rn != 0b11101U)) {
4346 return LdmT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4347 }
else if ((op == 0b01U) && (L == 1U) && (W_Rn == 0b11101U)) {
4348 return PopT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4357 if (op1 == 0b00U && op2 == 0b00U) {
4358 return StrexT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4359 }
else if (op1 == 0b00U && op2 == 0b01U) {
4360 return LdrexT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4362 return StrdImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4365 return StrdImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4367 return LdrdImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4370 return LdrdImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4371 }
else if ((op1 == 0b01U) && (op2 == 0b01U) && (op3 == 0b0000U)) {
4372 return TbbHT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4373 }
else if ((op1 == 0b01U) && (op2 == 0b01U) && (op3 == 0b0001U)) {
4374 return TbbHT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4379template <
typename TCpuAccessor,
typename TItOps>
4380static Result<Instr> Splitter32bit_op11110(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4386 if ((op1 == 0b10U) && (op == 0b1U)) {
4392 return BT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4393 }
else if ((_op1 == 0b000U || _op1 == 0b010U) &&
4395 return MsrT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4396 }
else if ((_op1 == 0b000U || _op1 == 0b010U) &&
4398 return MrsT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4399 }
else if (_op1 == 0b001U || _op1 == 0b011U) {
4400 return BT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4401 }
else if (_op1 == 0b101U || _op1 == 0b111U) {
4402 return BlT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4403 }
else if ((_op1 == 0b000U || _op1 == 0b010U) && (_op == 0b0111011U)) {
4408 if (_opc == 0b0101U) {
4409 return DmbT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4419 return TstImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4421 return AndImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4423 return OrrImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4425 return MovImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4427 return MvnImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4429 return EorImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4431 return TeqImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4433 return BicImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4435 return AddImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4437 return CmnImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4439 return AdcImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4441 return SubImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4443 return CmpImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4445 return SbcImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4447 return RsbImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4454 if (_op == 0b00100U) {
4455 return MovImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4456 }
else if (_op == 0b00000U && _Rn != 0b1111U) {
4457 return AddImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4458 }
else if (_op == 0b01010U && _Rn != 0b1111U) {
4459 return SubImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4460 }
else if (_op == 0b10110U && _Rn != 0b1111U) {
4461 return BfiT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4462 }
else if (_op == 0b11100U) {
4463 return UbfxT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4468template <
typename TCpuAccessor,
typename TItOps>
4469static Result<Instr> Splitter32bit_op11111(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4479 if (_op1 == 0b100U) {
4480 return StrbImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4481 }
else if (_op1 == 0b101U) {
4482 return StrhImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4484 return StrhImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4486 return StrbImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4488 return StrImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4490 return StrRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4492 return StrhRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4494 return StrbRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4495 }
else if (_op1 == 0b110U) {
4496 return StrImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4506 if (_op1 == 0b01U && _Rn != 0b1111 && _Rt != 0b1111U) {
4507 return LdrbImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4510 return LdrbImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4513 return LdrbImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4514 }
else if (_op1 == 0b11U && _Rn != 0b1111 && _Rt != 0b1111U) {
4515 return LdrsbImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4525 if (_op1 == 0b01U && _Rn != 0b1111U && _Rt != 0b1111U) {
4526 return LdrhImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4527 }
else if (_op1 == 0b00U && (_op2 == 0b000000U) && _Rn != 0b1111U && _Rt != 0b1111U) {
4528 return LdrhRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4529 }
else if (_op1 == 0b11U && _Rn != 0b1111U && _Rt != 0b1111U) {
4530 return LdrshImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4533 return LdrhImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4536 return LdrhImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4539 return LdrshImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4542 return LdrshImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4552 return LdrLiteralT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4553 }
else if (_op1 == 0b01U && _Rn != 0b1111U) {
4554 return LdrImmediateT3Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4557 return LdrImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4559 return LdrImmediateT4Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4560 }
else if (_op1 == 0b00U && _op2 == 0b000000U && _Rn != 0b1111U) {
4561 return LdrRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4570 return LslRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4572 return LsrRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4574 return AsrRegisterT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4576 return UxthT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4578 return SxtbT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4580 return SxthT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4582 return UxtbT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4589 if ((__op1 == 0b11U) && (__op2 == 0b00U)) {
4590 return ClzT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4599 if (_op1 == 0b000U && _op2 == 0b00U && _Ra == 0b1111U) {
4600 return MulT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4601 }
else if (_op1 == 0b000U && _op2 == 0b00U && _Ra != 0b1111U) {
4602 return MlaT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4603 }
else if (_op1 == 0b000U && _op2 == 0b01U) {
4604 return MlsT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4611 if (_op1 == 0b010U && _op2 == 0b0000U) {
4612 return UmullT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4613 }
else if (_op1 == 0b000U && _op2 == 0b0000U) {
4614 return SmullT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4615 }
else if (_op1 == 0b011U && _op2 == 0b1111U) {
4616 return UdivT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4617 }
else if (_op1 == 0b001U && _op2 == 0b1111U) {
4618 return SdivT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4619 }
else if (_op1 == 0b110U && _op2 == 0b0000U) {
4620 return UmlalT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4626template <
typename TCpuAccessor,
typename TItOps>
4627static Result<Instr> call_decoder(
const RawInstr &rinstr, TCpuAccessor &cpua) {
4631 return Splitter16bit_op00000<TCpuAccessor, TItOps>(rinstr, cpua);
4634 return LsrImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4637 return AsrImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4640 return Splitter16bit_op00011<TCpuAccessor, TItOps>(rinstr, cpua);
4643 return MovImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4646 return CmpImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4649 return AddImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4652 return SubImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4655 return Splitter16bit_op01000<TCpuAccessor, TItOps>(rinstr, cpua);
4658 return LdrLiteralT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4661 return Splitter16bit_op01010<TCpuAccessor, TItOps>(rinstr, cpua);
4664 return Splitter16bit_op01011<TCpuAccessor, TItOps>(rinstr, cpua);
4667 return StrImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4670 return Splitter16bit_op01101<TCpuAccessor, TItOps>(rinstr, cpua);
4673 return StrbImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4676 return LdrbImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4679 return StrhImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4682 return LdrhImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4685 return StrImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4688 return LdrImmediateT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4691 return AddPcPlusImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4694 return AddSpPlusImmediateT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4697 return Splitter16bit_op10110<TCpuAccessor, TItOps>(rinstr, cpua);
4700 return Splitter16bit_op10111<TCpuAccessor, TItOps>(rinstr, cpua);
4703 return StmT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4706 return LdmT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4709 return BT1Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4712 return Splitter16bit_op11011<TCpuAccessor, TItOps>(rinstr, cpua);
4715 return BT2Decoder<TCpuAccessor, TItOps>(rinstr, cpua);
4718 return Splitter32bit_op11101<TCpuAccessor, TItOps>(rinstr, cpua);
4721 return Splitter32bit_op11110<TCpuAccessor, TItOps>(rinstr, cpua);
4724 return Splitter32bit_op11111<TCpuAccessor, TItOps>(rinstr, cpua);
4732 return InvalidInstrDecoder<TCpuAccessor, TItOps>(rinstr, cpua);
Definition bit_manip.h:11
static U ZeroExtend(const u32 &value)
Definition bit_manip.h:200
static constexpr u32 ExtractBits2R(const u32 &value)
Definition bit_manip.h:188
static U SignExtend(const u32 &value)
Definition bit_manip.h:214
static constexpr u16 ExtractBits1R(const u16 &value)
Definition bit_manip.h:136
static u32 BitCount(const u32 &value)
Definition bit_manip.h:243
static constexpr u16 IsolateBit(const u16 &value)
Definition bit_manip.h:114
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6
@ kDecoderUndefined
Decoder encountered an undefined operation.
Definition status_code.h:69
@ kDecoderUnknownOpCode
Decoder encountered an unknown opcode.
Definition status_code.h:61
@ kDecoderUnpredictable
Decoder encountered an unpredictable operation.
Definition status_code.h:66
Contains the Result class which is used to return the result of a function.
#define TRY_ASSIGN(NAME, OUT_TYPE, CALL)
Try to assign a value to a variable and return an error if the assignment fails.
Definition result.h:123
Definition imm_shift_results.h:15