13template <
typename TContext>
class MnemonicBuilderSpecialInstr {
15 using It =
typename TContext::It;
16 using Reg =
typename TContext::Reg;
17 using SReg =
typename TContext::SReg;
19 template <
typename TDest,
typename TArg0>
20 static void BuildUbfx(
const char *instr_spec, TContext &mctx,
21 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
22 const TDest &rd,
const TArg0 &rn,
const u8 &lsbit,
const u8 &widthminus1) {
23 static_cast<void>(iflags);
24 static_cast<void>(bflags);
25 mctx.builder.AddString(instr_spec)
27 .AddString(Reg::GetRegisterName(rd.Get()))
29 .AddString(Reg::GetRegisterName(rn.Get()))
33 .AddUInt(widthminus1 + 1U);
35 mctx.builder.Terminate();
38 template <
typename TDest,
typename TArg0>
39 static void BuildBfi(
const char *instr_spec, TContext &mctx,
40 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
41 const TDest &rd,
const TArg0 &rn,
const u8 &lsbit,
const u8 &msbit) {
42 static_cast<void>(iflags);
43 static_cast<void>(bflags);
45 auto width = msbit - lsbit + 1;
46 mctx.builder.AddString(instr_spec)
48 .AddString(Reg::GetRegisterName(rd.Get()))
50 .AddString(Reg::GetRegisterName(rn.Get()))
56 mctx.builder.Terminate();
59 template <
typename TTgt>
60 static void BuildLdrLiteral(
const char *instr_spec, TContext &mctx,
61 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
62 const TTgt &rt,
const u32 imm32) {
63 static_cast<void>(iflags);
64 static_cast<void>(bflags);
65 mctx.builder.AddString(instr_spec)
66 .AddString(It::GetConditionAsStr(mctx.cpua))
68 .AddString(Reg::GetRegisterName(rt.Get()))
69 .AddString(
", [PC, #")
75 static void BuildMsrMrs(TContext &mctx,
const u8 &mask,
const u8 &SYSm) {
80 mctx.builder.AddString(
"APSR_g");
82 mctx.builder.AddString(
"APSR_nzcvq");
90 mctx.builder.AddString(
"MSP");
93 mctx.builder.AddString(
"PSP");
96 mctx.builder.AddString(
"undefined");
105 mctx.builder.AddString(
"PRIMASK");
108 mctx.builder.AddString(
"BASEPRI");
111 mctx.builder.AddString(
"BASEPRI_MAX");
114 mctx.builder.AddString(
"FAULTMASK");
117 mctx.builder.AddString(
"CONTROL");
120 mctx.builder.AddString(
"undefined");
125 mctx.builder.AddString(
"undefined");
130 template <
typename TDest>
131 static void BuildMrs(
const char *instr_spec, TContext &mctx,
132 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
133 const TDest &rd,
const u8 &mask,
const u8 &SYSm) {
134 static_cast<void>(iflags);
135 static_cast<void>(bflags);
136 mctx.builder.AddString(instr_spec).AddString(It::GetConditionAsStr(mctx.cpua)).AddChar(
' ');
137 mctx.builder.AddString(Reg::GetRegisterName(rd.Get())).AddString(
", ");
138 BuildMsrMrs(mctx, mask, SYSm);
139 mctx.builder.Terminate();
142 template <
typename TArg0>
143 static void BuildMsr(
const char *instr_spec, TContext &mctx,
144 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
145 const TArg0 &rn,
const u8 &mask,
const u8 &SYSm) {
146 static_cast<void>(iflags);
147 static_cast<void>(bflags);
148 mctx.builder.AddString(instr_spec).AddString(It::GetConditionAsStr(mctx.cpua)).AddChar(
' ');
149 BuildMsrMrs(mctx, mask, SYSm);
150 mctx.builder.AddString(
", ").AddString(Reg::GetRegisterName(rn.Get())).Terminate();
153 template <
typename TTgt,
typename TArg0,
typename TArg1>
154 static void BuildLdrdStrd(
const char *instr_spec, TContext &mctx,
155 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
156 const TTgt &rt,
const TArg0 &t2,
const TArg1 &rn,
const u32 imm32) {
157 static_cast<void>(bflags);
158 const bool is_wback = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kWBack)) != 0U;
159 const bool is_index = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kIndex)) != 0U;
160 const bool is_add = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kAdd)) != 0U;
161 mctx.builder.AddString(instr_spec)
162 .AddString(It::GetConditionAsStr(mctx.cpua))
164 .AddString(Reg::GetRegisterName(rt.Get()))
166 .AddString(Reg::GetRegisterName(t2.Get()))
171 mctx.builder.Terminate();
174 static void BuildBCond(
const char *instr_spec, TContext &mctx,
175 const MnemonicBuilderFlagsSet &bflags,
const InstrFlagsSet &iflags,
176 const u8 &cond,
const u32 &imm) {
177 static_cast<void>(iflags);
178 static_cast<void>(bflags);
179 mctx.builder.AddString(instr_spec)
180 .AddString(It::ConditionToString(cond))
182 .AddInt(
static_cast<i32
>(imm))
186 static void BuildIt(
const char *instr_spec, TContext &mctx,
const MnemonicBuilderFlagsSet &bflags,
187 const InstrFlagsSet &iflags,
const u8 &firstcond,
const u8 &mask) {
188 static_cast<void>(iflags);
189 static_cast<void>(bflags);
190 auto then_or_else = [](u8 cond) {
197 const char *x_spec =
"";
198 const char *y_spec =
"";
199 const char *z_spec =
"";
270 mctx.builder.AddString(instr_spec)
275 .AddString(It::ConditionToString(firstcond))
283 MnemonicBuilderSpecialInstr() =
delete;
288 ~MnemonicBuilderSpecialInstr() =
delete;
294 MnemonicBuilderSpecialInstr(
const MnemonicBuilderSpecialInstr &r_src) =
default;
300 MnemonicBuilderSpecialInstr &operator=(
const MnemonicBuilderSpecialInstr &r_src) =
delete;
306 MnemonicBuilderSpecialInstr(MnemonicBuilderSpecialInstr &&r_src) =
delete;
312 MnemonicBuilderSpecialInstr &operator=(MnemonicBuilderSpecialInstr &&r_src) =
delete;