libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
executor.h
1#pragma once
2
3#include "libmicroemu/internal/decoder/decoder.h"
4#include "libmicroemu/internal/executor/instr/binary64bit_instr.h"
5#include "libmicroemu/internal/executor/instr/binary_branch_instr.h"
6#include "libmicroemu/internal/executor/instr/binary_branch_instr_with_imm.h"
7#include "libmicroemu/internal/executor/instr/binary_instr.h"
8#include "libmicroemu/internal/executor/instr/binary_instr_with_imm.h"
9#include "libmicroemu/internal/executor/instr/binary_instr_with_imm_carry.h"
10#include "libmicroemu/internal/executor/instr/binary_instr_with_rotation.h"
11#include "libmicroemu/internal/executor/instr/binary_instr_with_shift.h"
12#include "libmicroemu/internal/executor/instr/binary_load_instr_with_imm.h"
13#include "libmicroemu/internal/executor/instr/binary_null_instr_with_imm.h"
14#include "libmicroemu/internal/executor/instr/binary_null_instr_with_imm_carry.h"
15#include "libmicroemu/internal/executor/instr/binary_store_instr_with_imm.h"
16#include "libmicroemu/internal/executor/instr/load_store/load_mem.h"
17#include "libmicroemu/internal/executor/instr/load_store/store_mem.h"
18#include "libmicroemu/internal/executor/instr/nullary_instr.h"
19#include "libmicroemu/internal/executor/instr/special_instr.h"
20#include "libmicroemu/internal/executor/instr/ternary_instr.h"
21#include "libmicroemu/internal/executor/instr/ternary_instr_with_shift.h"
22#include "libmicroemu/internal/executor/instr/ternary_load_instr_with_shift.h"
23#include "libmicroemu/internal/executor/instr/ternary_null_instr_with_shift.h"
24#include "libmicroemu/internal/executor/instr/ternary_store_instr_with_imm.h"
25#include "libmicroemu/internal/executor/instr/ternary_store_instr_with_shift.h"
26#include "libmicroemu/internal/executor/instr/unary_branch_instr.h"
27#include "libmicroemu/internal/executor/instr/unary_branch_instr_imm.h"
28#include "libmicroemu/internal/executor/instr/unary_instr.h"
29#include "libmicroemu/internal/executor/instr/unary_instr_imm.h"
30#include "libmicroemu/internal/executor/instr/unary_instr_imm_carry.h"
31#include "libmicroemu/internal/executor/instr/unary_load_instr_imm.h"
32#include "libmicroemu/internal/executor/instr/variadic_load_instr.h"
33#include "libmicroemu/internal/executor/instr/variadic_store_instr.h"
34#include "libmicroemu/internal/executor/instr/variadic_store_instr_db.h"
35#include "libmicroemu/internal/executor/instr_exec_results.h"
36#include "libmicroemu/internal/logic/alu.h"
37#include "libmicroemu/internal/logic/reg_ops.h"
39#include "libmicroemu/internal/semihosting/semihosting.h"
41#include "libmicroemu/internal/utils/bit_manip.h"
42#include "libmicroemu/internal/utils/rarg.h"
43#include "libmicroemu/logger.h"
44#include "libmicroemu/types.h"
45#include <cstddef>
46#include <cstdint>
47
48namespace libmicroemu::internal {
49
50template <typename TCpuAccessor, typename TBus, typename TCpuOps, typename TLogger = NullLogger>
51class Executor {
52public:
53 template <typename TDelegates>
54 static Result<InstrExecResult> Execute(TCpuAccessor &cpua, TBus &bus, const Instr &instr,
55 TDelegates &delegates) {
56 u8 flags = 0x0U;
58 auto ictx = TInstrCtx{cpua, bus};
59
60 switch (instr.id) {
61 case InstrId::kLdrLiteral: {
62 // see Armv7-M Architecture Reference Manual Issue E.e p.246
63 const auto &iargs = instr.ldr_immediate;
64 using TOp = LoadMemU32<TInstrCtx>;
66 TRY_ASSIGN(out_flags, InstrExecResult,
67 TInstr::Call(ictx, iargs.flags, iargs.imm32, RArg(iargs.t)));
68 flags |= out_flags.flags;
69 break;
70 }
71 case InstrId::kClz: {
72 // see Armv7-M Architecture Reference Manual Issue E.e p.220
73 const auto &iargs = instr.clz;
74 using TOp = Clz1Op<TInstrCtx>;
75 using TInstr = UnaryInstr<TOp, TInstrCtx>;
76 TRY_ASSIGN(out_flags, InstrExecResult,
77 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m)));
78 flags |= out_flags.flags;
79 break;
80 }
81 case InstrId::kLdrsbImmediate: {
82 const auto &iargs = instr.ldrsb_immediate;
83 using TOp = LoadMemI8<TInstrCtx>;
85 TRY_ASSIGN(out_flags, InstrExecResult,
86 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
87 flags |= out_flags.flags;
88 break;
89 }
90 case InstrId::kLdrbImmediate: {
91 const auto &iargs = instr.ldrb_immediate;
92 using TOp = LoadMemU8<TInstrCtx>;
94 TRY_ASSIGN(out_flags, InstrExecResult,
95 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
96 flags |= out_flags.flags;
97 break;
98 }
99 case InstrId::kLdrImmediate: {
100 const auto &iargs = instr.ldr_immediate;
101 using TOp = LoadMemU32<TInstrCtx>;
103 TRY_ASSIGN(out_flags, InstrExecResult,
104 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
105 flags |= out_flags.flags;
106 break;
107 }
108
109 case InstrId::kLdrex: {
110 const auto &iargs = instr.ldrex;
111 using TOp = LoadMemExU32<TInstrCtx>;
113 TRY_ASSIGN(out_flags, InstrExecResult,
114 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
115 flags |= out_flags.flags;
116 break;
117 }
118 case InstrId::kUmull: {
119 const auto &iargs = instr.umull;
120 using TOp = Umull2Op<TInstrCtx>;
122 TRY_ASSIGN(out_flags, InstrExecResult,
123 TInstr::Call(ictx, iargs.flags, RArg(iargs.dLo), RArg(iargs.dHi), RArg(iargs.n),
124 RArg(iargs.m)));
125 flags |= out_flags.flags;
126 break;
127 }
128 case InstrId::kMsr: {
129 const auto &iargs = instr.msr;
130 TRY_ASSIGN(out_flags, InstrExecResult,
131 (SpecialInstr<TInstrCtx, TLogger>::Msr(ictx, iargs.flags, RArg(iargs.n),
132 iargs.mask, iargs.SYSm)));
133 flags |= out_flags.flags;
134 break;
135 }
136
137 case InstrId::kMrs: {
138 const auto &iargs = instr.mrs;
139 TRY_ASSIGN(out_flags, InstrExecResult,
140 (SpecialInstr<TInstrCtx, TLogger>::Mrs(ictx, iargs.flags, RArg(iargs.d),
141 iargs.mask, iargs.SYSm)));
142 flags |= out_flags.flags;
143 break;
144 }
145 case InstrId::kUmlal: {
146 const auto &iargs = instr.umlal;
147 using TOp = Umlal2Op<TInstrCtx>;
149 TRY_ASSIGN(out_flags, InstrExecResult,
150 TInstr::Call(ictx, iargs.flags, RArg(iargs.dLo), RArg(iargs.dHi), RArg(iargs.n),
151 RArg(iargs.m)));
152 flags |= out_flags.flags;
153
154 break;
155 }
156 case InstrId::kSmull: {
157 const auto &iargs = instr.smull;
158 using TOp = Smull2Op<TInstrCtx>;
160 TRY_ASSIGN(out_flags, InstrExecResult,
161 TInstr::Call(ictx, iargs.flags, RArg(iargs.dLo), RArg(iargs.dHi), RArg(iargs.n),
162 RArg(iargs.m)));
163 flags |= out_flags.flags;
164 break;
165 }
166 case InstrId::kLdrdImmediate: {
167 // see Armv7-M Architecture Reference Manual Issue E.e p.257
168 const auto &iargs = instr.ldrd_immediate;
169 TRY_ASSIGN(out_flags, InstrExecResult,
170 SpecialInstr<TInstrCtx>::Ldrd(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.t2),
171 RArg(iargs.n), iargs.imm32));
172 flags |= out_flags.flags;
173 break;
174 }
175 case InstrId::kLdrhImmediate: {
176 // see Armv7-M Architecture Reference Manual Issue E.e p.264
177 const auto &iargs = instr.ldrh_immediate;
178 using TOp = LoadMemU16<TInstrCtx>;
180 TRY_ASSIGN(out_flags, InstrExecResult,
181 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
182 flags |= out_flags.flags;
183 break;
184 }
185 case InstrId::kLdrshImmediate: {
186 // see Armv7-M Architecture Reference Manual Issue E.e p.275
187 const auto &iargs = instr.ldrsh_immediate;
188 using TOp = LoadMemI16<TInstrCtx>;
190 TRY_ASSIGN(out_flags, InstrExecResult,
191 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
192 flags |= out_flags.flags;
193 break;
194 }
195 case InstrId::kAsrImmediate: {
196 // see Armv7-M Architecture Reference Manual Issue E.e p.203
197 const auto &iargs = instr.asr_immediate;
198 using TOp = Asr1ShiftOp<TInstrCtx>;
200 TRY_ASSIGN(out_flags, InstrExecResult,
201 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.shift_res));
202 flags |= out_flags.flags;
203 break;
204 }
205 case InstrId::kLslImmediate: {
206 // see Armv7-M Architecture Reference Manual Issue E.e p.282
207 const auto &iargs = instr.lsl_immediate;
208 using TOp = Lsl1ShiftOp<TInstrCtx>;
210 TRY_ASSIGN(out_flags, InstrExecResult,
211 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.shift_res));
212 flags |= out_flags.flags;
213 break;
214 }
215 case InstrId::kLsrRegister: {
216 const auto &iargs = instr.lsr_register;
217 using TOp = Lsr2Op<TInstrCtx>;
218 using TInstr = BinaryInstr<TOp, TInstrCtx>;
219 TRY_ASSIGN(out_flags, InstrExecResult,
220 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
221 flags |= out_flags.flags;
222 break;
223 }
224 case InstrId::kAsrRegister: {
225 const auto &iargs = instr.asr_register;
226 using TOp = Asr2Op<TInstrCtx>;
227 using TInstr = BinaryInstr<TOp, TInstrCtx>;
228 TRY_ASSIGN(out_flags, InstrExecResult,
229 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
230 flags |= out_flags.flags;
231 break;
232 }
233 case InstrId::kLslRegister: {
234 // see Armv7-M Architecture Reference Manual Issue E.e p.283
235 const auto &iargs = instr.lsr_register;
236 using TOp = Lsl2Op<TInstrCtx>;
237 using TInstr = BinaryInstr<TOp, TInstrCtx>;
238 TRY_ASSIGN(out_flags, InstrExecResult,
239 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
240 flags |= out_flags.flags;
241 break;
242 }
243 case InstrId::kCmpRegister: {
244 // see Armv7-M Architecture Reference Manual Issue E.e p.224
245 const auto &iargs = instr.cmp_register;
246 using TOp = Cmp2ShiftOp<TInstrCtx>;
248 TRY_ASSIGN(stm_flags, InstrExecResult,
249 TInstr::Call(ictx, iargs.flags, RArg(iargs.m), RArg(iargs.n), iargs.shift_res));
250 flags |= stm_flags.flags;
251 break;
252 }
253 case InstrId::kCmpImmediate: {
254 // see Armv7-M Architecture Reference Manual Issue E.e p.224
255 const auto &iargs = instr.cmp_immediate;
256 using TOp = Cmp1ImmOp<TInstrCtx>;
258 TRY_ASSIGN(stm_flags, InstrExecResult,
259 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.imm32));
260 flags |= stm_flags.flags;
261 break;
262 }
263 case InstrId::kCmnImmediate: {
264 // see Armv7-M Architecture Reference Manual Issue E.e p.221
265 const auto &iargs = instr.cmp_immediate;
266 using TOp = Cmn1ImmOp<TInstrCtx>;
268 TRY_ASSIGN(stm_flags, InstrExecResult,
269 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.imm32));
270 flags |= stm_flags.flags;
271 break;
272 }
273 case InstrId::kIt: {
274 // see Armv7-M Architecture Reference Manual Issue E.e p.236
275 const auto &iargs = instr.it;
276 TRY_ASSIGN(out_flags, InstrExecResult,
277 SpecialInstr<TInstrCtx>::ItInstr(ictx, iargs.flags, iargs.firstcond, iargs.mask));
278 flags |= out_flags.flags;
279 break;
280 }
281 case InstrId::kMovImmediate: {
282 // see Armv7-M Architecture Reference Manual Issue E.e p.291
283 const auto &iargs = instr.mov_immediate;
284 using TOp = MovImmCarryOp<TInstrCtx>;
286 TRY_ASSIGN(out_flags, InstrExecResult,
287 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), iargs.imm32_carry));
288 flags |= out_flags.flags;
289 break;
290 }
291 case InstrId::kMvnImmediate: {
292 // see Armv7-M Architecture Reference Manual Issue E.e p.291
293 const auto &iargs = instr.mvn_immediate;
294 using TOp = MvnImmCarryOp<TInstrCtx>;
296 TRY_ASSIGN(out_flags, InstrExecResult,
297 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), iargs.imm32_carry));
298 flags |= out_flags.flags;
299 break;
300 }
301 case InstrId::kMovRegister: {
302 // see Armv7-M Architecture Reference Manual Issue E.e p.293
303 const auto &iargs = instr.mov_register;
304 using TOp = Mov1Op<TInstrCtx>;
305 using TInstr = UnaryInstr<TOp, TInstrCtx>;
306 TRY_ASSIGN(out_flags, InstrExecResult,
307 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m)));
308 flags |= out_flags.flags;
309 break;
310 }
311
312 case InstrId::kRrx: {
313 const auto &iargs = instr.rrx;
314 using TOp = Rrx1Op<TInstrCtx>;
315 using TInstr = UnaryInstr<TOp, TInstrCtx>;
316 TRY_ASSIGN(out_flags, InstrExecResult,
317 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m)));
318 flags |= out_flags.flags;
319 break;
320 }
321 case InstrId::kUxtb: {
322 const auto &iargs = instr.uxtb;
323 using TOp = Uxtb1Rotation<TInstrCtx>;
325 TRY_ASSIGN(out_flags, InstrExecResult,
326 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.rotation));
327 flags |= out_flags.flags;
328 break;
329 }
330 case InstrId::kSxtb: {
331 const auto &iargs = instr.sxtb;
332 using TOp = Sxtb1Rotation<TInstrCtx>;
334 TRY_ASSIGN(out_flags, InstrExecResult,
335 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.rotation));
336 flags |= out_flags.flags;
337 break;
338 }
339 case InstrId::kSxth: {
340 // see Armv7-M Architecture Reference Manual Issue E.e p.414
341 const auto &iargs = instr.sxth;
342 using TOp = Sxth1Rotation<TInstrCtx>;
344 TRY_ASSIGN(out_flags, InstrExecResult,
345 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.rotation));
346 flags |= out_flags.flags;
347 break;
348 }
349 case InstrId::kUxth: {
350 // see Armv7-M Architecture Reference Manual Issue E.e p.454
351 const auto &iargs = instr.uxth;
352 using TOp = Uxth1Rotation<TInstrCtx>;
354 TRY_ASSIGN(out_flags, InstrExecResult,
355 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.rotation));
356 flags |= out_flags.flags;
357 break;
358 }
359 case InstrId::kBCond: {
360 // see Armv7-M Architecture Reference Manual Issue E.e p.205
361 const auto &iargs = instr.b_cond;
362 TRY_ASSIGN(out_flags, InstrExecResult,
363 SpecialInstr<TInstrCtx>::BCond(ictx, iargs.flags, iargs.imm32, iargs.cond));
364 flags |= out_flags.flags;
365
366 break;
367 }
368 case InstrId::kTbbH: {
369 // see Armv7-M Architecture Reference Manual Issue E.e p.416
370 const auto &iargs = instr.tbb_h;
371 using TOp = TbbH2Op<TInstrCtx>;
373 TRY_ASSIGN(out_flags, InstrExecResult,
374 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), RArg(iargs.m)));
375 flags |= out_flags.flags;
376
377 break;
378 }
379 case InstrId::kB: {
380 // see Armv7-M Architecture Reference Manual Issue E.e p.205
381 const auto &iargs = instr.b;
382 using TOp = B1ImmOp<TInstrCtx>;
383 using TInstr = UnaryBranchInstrImm<TOp, TInstrCtx>;
384 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags, iargs.imm32));
385 flags |= out_flags.flags;
386 break;
387 }
388 case InstrId::kBl: {
389 // see Armv7-M Architecture Reference Manual Issue E.e p.213
390 const auto &iargs = instr.b;
391 using TOp = Bl1ImmOp<TInstrCtx>;
392 using TInstr = UnaryBranchInstrImm<TOp, TInstrCtx>;
393 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags, iargs.imm32));
394 flags |= out_flags.flags;
395 break;
396 }
397 case InstrId::kCbNZ: {
398 // see Armv7-M Architecture Reference Manual Issue E.e p.216
399 const auto &iargs = instr.cb_n_z;
400 using TOp = CbNZ1ImmOp<TInstrCtx>;
402 TRY_ASSIGN(out_flags, InstrExecResult,
403 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.imm32));
404 flags |= out_flags.flags;
405 break;
406
407 break;
408 }
409 case InstrId::kBx: {
410 // see Armv7-M Architecture Reference Manual Issue E.e p.215
411 const auto &iargs = instr.bx;
412 using TOp = Bx1Op<TInstrCtx>;
414 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags, RArg(iargs.m)));
415 flags |= out_flags.flags;
416 break;
417 }
418 case InstrId::kBlx: {
419 // see Armv7-M Architecture Reference Manual Issue E.e p.214
420 const auto &iargs = instr.blx;
421 using TOp = Blx1Op<TInstrCtx>;
423 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags, RArg(iargs.m)));
424 flags |= out_flags.flags;
425 break;
426 }
427 case InstrId::kSubImmediate: {
428 // see Armv7-M Architecture Reference Manual Issue E.e p.402
429 const auto &iargs = instr.sub_immediate;
430 using TOp = Sub1ImmOp<TInstrCtx>;
432 TRY_ASSIGN(out_flags, InstrExecResult,
433 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32));
434 flags |= out_flags.flags;
435 break;
436 }
437 case InstrId::kSbcImmediate: {
438 // see Armv7-M Architecture Reference Manual Issue E.e p.346
439 const auto &iargs = instr.sbc_immediate;
440 using TOp = Sbc1ImmOp<TInstrCtx>;
442 TRY_ASSIGN(out_flags, InstrExecResult,
443 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32));
444 flags |= out_flags.flags;
445 break;
446 }
447 case InstrId::kRsbImmediate: {
448 // see Armv7-M Architecture Reference Manual Issue E.e p.341
449 const auto &iargs = instr.rsb_immediate;
450 using TOp = Rsb1ImmOp<TInstrCtx>;
452 TRY_ASSIGN(out_flags, InstrExecResult,
453 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32));
454 flags |= out_flags.flags;
455 break;
456 }
457 case InstrId::kSubSpMinusImmediate: {
458 // see Armv7-M Architecture Reference Manual Issue E.e p.406
459 const auto &iargs = instr.sub_sp_minus_immediate;
460 using TOp = Sub1ImmOp<TInstrCtx>;
462 TRY_ASSIGN(out_flags, InstrExecResult,
463 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArgConst<RegisterId::kSp>(),
464 iargs.imm32));
465 flags |= out_flags.flags;
466 break;
467 }
468 case InstrId::kAddImmediate: {
469 const auto &iargs = instr.add_immediate;
470 using TOp = Add1ImmOp<TInstrCtx>;
472 TRY_ASSIGN(out_flags, InstrExecResult,
473 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32));
474 flags |= out_flags.flags;
475 break;
476 }
477 case InstrId::kAdcImmediate: {
478 const auto &iargs = instr.adc_immediate;
479 using TOp = Adc1ImmOp<TInstrCtx>;
481 TRY_ASSIGN(out_flags, InstrExecResult,
482 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32));
483 flags |= out_flags.flags;
484 break;
485 }
486 case InstrId::kAddPcPlusImmediate: {
487 // see Armv7-M Architecture Reference Manual Issue E.e p.198
488 const auto &iargs = instr.add_pc_plus_immediate;
489 using TOp = AddToPcImmOp<TInstrCtx>;
490 using TInstr = UnaryInstrImm<TOp, TInstrCtx>;
491 TRY_ASSIGN(out_flags, InstrExecResult,
492 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), iargs.imm32));
493 flags |= out_flags.flags;
494 break;
495 }
496 case InstrId::kAddSpPlusImmediate: {
497 // see Armv7-M Architecture Reference Manual Issue E.e p.190
498 const auto &iargs = instr.add_sp_plus_immediate;
499 using TOp = Add1ImmOp<TInstrCtx>;
501 TRY_ASSIGN(out_flags, InstrExecResult,
502 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArgConst<RegisterId::kSp>(),
503 iargs.imm32));
504 flags |= out_flags.flags;
505 break;
506 }
507 case InstrId::kTeqImmediate: {
508 const auto &iargs = instr.teq_immediate;
509 using TOp = Teq1ImmCarryOp<TInstrCtx>;
511 TRY_ASSIGN(out_flags, InstrExecResult,
512 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.imm32_carry));
513 flags |= out_flags.flags;
514 break;
515 }
516 case InstrId::kTstImmediate: {
517 const auto &iargs = instr.tst_immediate;
518 using TOp = Tst1ImmCarryOp<TInstrCtx>;
520 TRY_ASSIGN(out_flags, InstrExecResult,
521 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.imm32_carry));
522 flags |= out_flags.flags;
523 break;
524 }
525 case InstrId::kTstRegister: {
526 const auto &iargs = instr.tst_register;
527 using TOp = Tst2ShiftOp<TInstrCtx>;
529 TRY_ASSIGN(out_flags, InstrExecResult,
530 TInstr::Call(ictx, iargs.flags, RArg(iargs.m), RArg(iargs.n), iargs.shift_res));
531 flags |= out_flags.flags;
532 break;
533 }
534 case InstrId::kTeqRegister: {
535 const auto &iargs = instr.teq_register;
536 using TOp = Teq2ShiftOp<TInstrCtx>;
538 TRY_ASSIGN(out_flags, InstrExecResult,
539 TInstr::Call(ictx, iargs.flags, RArg(iargs.m), RArg(iargs.n), iargs.shift_res));
540 flags |= out_flags.flags;
541 break;
542 }
543 case InstrId::kEorImmediate: {
544 const auto &iargs = instr.eor_immediate;
545 using TOp = Eor1ImmCarryOp<TInstrCtx>;
547 TRY_ASSIGN(out_flags, InstrExecResult,
548 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32_carry));
549 flags |= out_flags.flags;
550 break;
551 }
552 case InstrId::kOrrImmediate: {
553 const auto &iargs = instr.orr_immediate;
554 using TOp = Orr1ImmCarryOp<TInstrCtx>;
556 TRY_ASSIGN(out_flags, InstrExecResult,
557 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32_carry));
558 flags |= out_flags.flags;
559 break;
560 }
561 case InstrId::kAndImmediate: {
562 // see Armv7-M Architecture Reference Manual Issue E.e p.200
563 const auto &iargs = instr.and_immediate;
564 using TOp = And1ImmCarryOp<TInstrCtx>;
566 TRY_ASSIGN(out_flags, InstrExecResult,
567 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32_carry));
568 flags |= out_flags.flags;
569 break;
570 }
571 case InstrId::kUbfx: {
572 // see Armv7-M Architecture Reference Manual Issue E.e p.424
573 const auto &iargs = instr.ubfx;
574 TRY_ASSIGN(out_flags, InstrExecResult,
575 SpecialInstr<TInstrCtx>::Ubfx(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n),
576 iargs.lsbit, iargs.widthminus1));
577 flags |= out_flags.flags;
578 break;
579 }
580 case InstrId::kBfi: {
581 const auto &iargs = instr.bfi;
582 TRY_ASSIGN(out_flags, InstrExecResult,
583 SpecialInstr<TInstrCtx>::Bfi(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n),
584 iargs.lsbit, iargs.msbit));
585 flags |= out_flags.flags;
586 break;
587 }
588 case InstrId::kUdiv: {
589 const auto &iargs = instr.udiv;
590 using TOp = UDiv2Op<TInstrCtx>;
591 using TInstr = BinaryInstr<TOp, TInstrCtx>;
592 TRY_ASSIGN(out_flags, InstrExecResult,
593 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
594 flags |= out_flags.flags;
595 break;
596 }
597 case InstrId::kSdiv: {
598 const auto &iargs = instr.sdiv;
599 using TOp = SDiv2Op<TInstrCtx>;
600 using TInstr = BinaryInstr<TOp, TInstrCtx>;
601 TRY_ASSIGN(out_flags, InstrExecResult,
602 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
603 flags |= out_flags.flags;
604 break;
605 }
606 case InstrId::kMul: {
607 // see Armv7-M Architecture Reference Manual Issue E.e p.302
608 const auto &iargs = instr.mul;
609 using TOp = Mul2Op<TInstrCtx>;
610 using TInstr = BinaryInstr<TOp, TInstrCtx>;
611 TRY_ASSIGN(out_flags, InstrExecResult,
612 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m)));
613 flags |= out_flags.flags;
614 break;
615 }
616 case InstrId::kMls: {
617 const auto &iargs = instr.mls;
618 using TOp = Mls3Op<TInstrCtx>;
619 using TInstr = TernaryInstr<TOp, TInstrCtx>;
620 TRY_ASSIGN(out_flags, InstrExecResult,
621 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
622 RArg(iargs.a)));
623 flags |= out_flags.flags;
624 break;
625 }
626
627 case InstrId::kMla: {
628 const auto &iargs = instr.mla;
629 using TOp = Mla3Op<TInstrCtx>;
630 using TInstr = TernaryInstr<TOp, TInstrCtx>;
631 TRY_ASSIGN(out_flags, InstrExecResult,
632 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
633 RArg(iargs.a)));
634 flags |= out_flags.flags;
635 break;
636 }
637 case InstrId::kSubRegister: {
638 const auto &iargs = instr.sub_register;
639 using TOp = Sub2ShiftOp<TInstrCtx>;
641 TRY_ASSIGN(out_flags, InstrExecResult,
642 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
643 iargs.shift_res));
644 flags |= out_flags.flags;
645 break;
646 }
647 case InstrId::kRsbRegister: {
648 const auto &iargs = instr.rsb_register;
649 using TOp = Rsb2ShiftOp<TInstrCtx>;
651 TRY_ASSIGN(out_flags, InstrExecResult,
652 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
653 iargs.shift_res));
654 flags |= out_flags.flags;
655 break;
656 }
657 case InstrId::kAdcRegister: {
658 const auto &iargs = instr.adc_register;
659 using TOp = Adc2ShiftOp<TInstrCtx>;
661 TRY_ASSIGN(out_flags, InstrExecResult,
662 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
663 iargs.shift_res));
664 flags |= out_flags.flags;
665 break;
666 }
667 case InstrId::kAddRegister: {
668 const auto &iargs = instr.add_register;
669 using TOp = Add2ShiftOp<TInstrCtx>;
671 TRY_ASSIGN(out_flags, InstrExecResult,
672 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
673 iargs.shift_res));
674 flags |= out_flags.flags;
675 break;
676 }
677 case InstrId::kPush: {
678 // see Armv7-M Architecture Reference Manual Issue E.e p.322
679 const auto &iargs = instr.push;
680 using TInstr = VariadicStoreInstrDb<TInstrCtx>;
681 InstrFlagsSet iflags{0x0U};
682
683 // rewrite flags to ldm instruction
684 iflags |= static_cast<InstrFlagsSet>(InstrFlags::kWBack);
685 iflags |= iargs.flags & static_cast<InstrFlagsSet>(InstrFlags::k32Bit); // copy 32bit flag
686
687 TRY_ASSIGN(stm_flags, InstrExecResult,
688 TInstr::Call(ictx, iflags, RArgConst<RegisterId::kSp>(), iargs.registers));
689
690 flags |= stm_flags.flags;
691 break;
692 }
693 case InstrId::kStm: {
694 // see Armv7-M Architecture Reference Manual Issue E.e p.383
695 const auto &iargs = instr.ldm;
696 using TInstr = VariadicStoreInstr<TInstrCtx>;
697
698 TRY_ASSIGN(stm_flags, InstrExecResult,
699 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.registers));
700 flags |= stm_flags.flags;
701 break;
702 }
703 case InstrId::kLdm: {
704 // see Armv7-M Architecture Reference Manual Issue E.e p.242
705 const auto &iargs = instr.ldm;
706 using TInstr = VariadicLoadInstr<TInstrCtx>;
707 TRY_ASSIGN(ldm_flags, InstrExecResult,
708 TInstr::Call(ictx, iargs.flags, RArg(iargs.n), iargs.registers));
709 flags |= ldm_flags.flags;
710 break;
711 }
712 case InstrId::kPop: {
713 // see Armv7-M Architecture Reference Manual Issue E.e p.319
714 const auto &iargs = instr.pop;
715 using TInstr = VariadicLoadInstr<TInstrCtx>;
716 InstrFlagsSet iflags{0x0U};
717
718 // rewrite flags to ldm instruction
719 iflags |= static_cast<InstrFlagsSet>(InstrFlags::kWBack);
720 iflags |= iargs.flags & static_cast<InstrFlagsSet>(InstrFlags::k32Bit); // copy 32bit flag
721
722 TRY_ASSIGN(ldm_flags, InstrExecResult,
723 TInstr::Call(ictx, iflags, RArgConst<RegisterId::kSp>(), iargs.registers));
724
725 flags |= ldm_flags.flags;
726 break;
727 }
728 case InstrId::kOrrRegister: {
729 // see Armv7-M Architecture Reference Manual Issue E.e p.309
730 const auto &iargs = instr.orr_register;
731 using TOp = Orr2ShiftOp<TInstrCtx>;
733 TRY_ASSIGN(out_flags, InstrExecResult,
734 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
735 iargs.shift_res));
736 flags |= out_flags.flags;
737 break;
738 }
739 case InstrId::kSbcRegister: {
740 // see Armv7-M Architecture Reference Manual Issue E.e p.347
741 const auto &iargs = instr.sbc_register;
742 using TOp = Sbc2ShiftOp<TInstrCtx>;
744 TRY_ASSIGN(out_flags, InstrExecResult,
745 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
746 iargs.shift_res));
747 flags |= out_flags.flags;
748 break;
749 }
750 case InstrId::kEorRegister: {
751 // see Armv7-M Architecture Reference Manual Issue E.e p.233
752 const auto &iargs = instr.eor_register;
753 using TOp = Eor2ShiftOp<TInstrCtx>;
755 TRY_ASSIGN(out_flags, InstrExecResult,
756 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
757 iargs.shift_res));
758 flags |= out_flags.flags;
759 break;
760 }
761 case InstrId::kAndRegister: {
762 // see Armv7-M Architecture Reference Manual Issue E.e p.201
763 const auto &iargs = instr.and_register;
764 using TOp = And2ShiftOp<TInstrCtx>;
766 TRY_ASSIGN(out_flags, InstrExecResult,
767 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
768 iargs.shift_res));
769 flags |= out_flags.flags;
770 break;
771 }
772 case InstrId::kBicRegister: {
773 // see Armv7-M Architecture Reference Manual Issue E.e p.309
774 const auto &iargs = instr.bic_register;
775 using TOp = Bic2ShiftOp<TInstrCtx>;
777 TRY_ASSIGN(out_flags, InstrExecResult,
778 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), RArg(iargs.m),
779 iargs.shift_res));
780 flags |= out_flags.flags;
781 break;
782 }
783 case InstrId::kBicImmediate: {
784 const auto &iargs = instr.bic_immediate;
785 using TOp = Bic1ImmCarryOp<TInstrCtx>;
787 TRY_ASSIGN(out_flags, InstrExecResult,
788 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.n), iargs.imm32_carry));
789 flags |= out_flags.flags;
790 break;
791 }
792 case InstrId::kMvnRegister: {
793 const auto &iargs = instr.lsr_immediate;
794 using TOp = Mvn1ShiftOp<TInstrCtx>;
796 TRY_ASSIGN(out_flags, InstrExecResult,
797 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.shift_res));
798 flags |= out_flags.flags;
799 break;
800 }
801 case InstrId::kLsrImmediate: {
802 // see Armv7-M Architecture Reference Manual Issue E.e p.309
803 const auto &iargs = instr.lsr_immediate;
804 using TOp = Lsr1ShiftOp<TInstrCtx>;
806 TRY_ASSIGN(out_flags, InstrExecResult,
807 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.m), iargs.shift_res));
808 flags |= out_flags.flags;
809 break;
810 }
811 case InstrId::kStrdImmediate: {
812 // see Armv7-M Architecture Reference Manual Issue E.e p.393
813 const auto &iargs = instr.strd_immediate;
814 TRY_ASSIGN(out_flags, InstrExecResult,
815 SpecialInstr<TInstrCtx>::Strd(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.t2),
816 RArg(iargs.n), iargs.imm32));
817 flags |= out_flags.flags;
818 break;
819 }
820 case InstrId::kStrRegister: {
821 // see Armv7-M Architecture Reference Manual Issue E.e p.388
822 const auto &iargs = instr.str_register;
823 using TOp = StoreMemU32<TInstrCtx>;
825 TRY_ASSIGN(out_flags, InstrExecResult,
826 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
827 iargs.shift_res));
828 flags |= out_flags.flags;
829 break;
830 }
831 case InstrId::kStrbRegister: {
832 // see Armv7-M Architecture Reference Manual Issue E.e p.391
833 const auto &iargs = instr.strh_register;
834 using TOp = StoreMemU8<TInstrCtx>;
836 TRY_ASSIGN(out_flags, InstrExecResult,
837 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
838 iargs.shift_res));
839 flags |= out_flags.flags;
840 break;
841 }
842 case InstrId::kStrhRegister: {
843 // see Armv7-M Architecture Reference Manual Issue E.e p.399
844 const auto &iargs = instr.strh_register;
845 using TOp = StoreMemU16<TInstrCtx>;
847 TRY_ASSIGN(out_flags, InstrExecResult,
848 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
849 iargs.shift_res));
850 flags |= out_flags.flags;
851 break;
852 }
853 case InstrId::kLdrhRegister: {
854 const auto &iargs = instr.ldrh_register;
855 using TOp = LoadMemU16<TInstrCtx>;
857 TRY_ASSIGN(out_flags, InstrExecResult,
858 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
859 iargs.shift_res));
860 flags |= out_flags.flags;
861 break;
862 }
863 case InstrId::kLdrbRegister: {
864 const auto &iargs = instr.ldrb_register;
865 using TOp = LoadMemU8<TInstrCtx>;
867 TRY_ASSIGN(out_flags, InstrExecResult,
868 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
869 iargs.shift_res));
870 flags |= out_flags.flags;
871 break;
872 }
873 case InstrId::kLdrRegister: {
874 // see Armv7-M Architecture Reference Manual Issue E.e p.386
875 const auto &iargs = instr.ldr_register;
876 using TOp = LoadMemU32<TInstrCtx>;
878 TRY_ASSIGN(out_flags, InstrExecResult,
879 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), RArg(iargs.m),
880 iargs.shift_res));
881 flags |= out_flags.flags;
882 break;
883 }
884 case InstrId::kStrImmediate: {
885 // see Armv7-M Architecture Reference Manual Issue E.e p.386
886 const auto &iargs = instr.str_immediate;
887 using TOp = StoreMemU32<TInstrCtx>;
889 TRY_ASSIGN(out_flags, InstrExecResult,
890 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
891 flags |= out_flags.flags;
892 break;
893 }
894
895 case InstrId::kStrex: {
896 // see Armv7-M Architecture Reference Manual Issue E.e p.386
897 const auto &iargs = instr.strex;
898 using TOp = StoreMemExU32<TInstrCtx>;
900 TRY_ASSIGN(out_flags, InstrExecResult,
901 TInstr::Call(ictx, iargs.flags, RArg(iargs.d), RArg(iargs.t), RArg(iargs.n),
902 iargs.imm32));
903 flags |= out_flags.flags;
904 break;
905 }
906 case InstrId::kStrhImmediate: {
907 // see Armv7-M Architecture Reference Manual Issue E.e p.389
908 const auto &iargs = instr.strh_immediate;
909 using TOp = StoreMemU16<TInstrCtx>;
911 TRY_ASSIGN(out_flags, InstrExecResult,
912 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
913 flags |= out_flags.flags;
914 break;
915 }
916 case InstrId::kStrbImmediate: {
917 // see Armv7-M Architecture Reference Manual Issue E.e p.389
918 const auto &iargs = instr.strb_immediate;
919 using TOp = StoreMemU8<TInstrCtx>;
921 TRY_ASSIGN(out_flags, InstrExecResult,
922 TInstr::Call(ictx, iargs.flags, RArg(iargs.t), RArg(iargs.n), iargs.imm32));
923 flags |= out_flags.flags;
924 break;
925 }
926 case InstrId::kSvc: {
927 // see Armv7-M Architecture Reference Manual Issue E.e p.213
928 const auto &iargs = instr.svc;
929 TRY_ASSIGN(out_flags, InstrExecResult,
930 SpecialInstr<TInstrCtx>::Svc(ictx, iargs.flags, iargs.imm32, delegates));
931 flags |= out_flags.flags;
932 break;
933 }
934 case InstrId::kBkpt: {
935 // see Armv7-M Architecture Reference Manual Issue E.e p.212
936 const auto &iargs = instr.bkpt;
937 TRY_ASSIGN(out_flags, InstrExecResult,
938 SpecialInstr<TInstrCtx>::Bkpt(ictx, iargs.flags, iargs.imm32, delegates));
939 flags |= out_flags.flags;
940 break;
941 }
942 case InstrId::kNop: {
943 const auto &iargs = instr.nop;
944 using TOp = Nop0Op<TInstrCtx>;
945 using TInstr = NullaryInstr<TOp, TInstrCtx>;
946 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags));
947 flags |= out_flags.flags;
948 break;
949 }
950 case InstrId::kDmb: {
951 const auto &iargs = instr.dmb;
952 using TOp = Dmb0Op<TInstrCtx>;
953 using TInstr = NullaryInstr<TOp, TInstrCtx>;
954 TRY_ASSIGN(out_flags, InstrExecResult, TInstr::Call(ictx, iargs.flags));
955 flags |= out_flags.flags;
956 break;
957 }
958 default: {
959 break;
960 }
961 }
962
963 return Ok(InstrExecResult{flags});
964 };
965
966private:
970 Executor() = delete;
971
975 ~Executor() = delete;
976
981 Executor &operator=(const Executor &r_src) = delete;
982
987 Executor(Executor &&r_src) = delete;
988
993 Executor &operator=(Executor &&r_src) = delete;
994};
995
996} // namespace libmicroemu::internal
Register argument constant class.
Definition rarg.h:12
Register argument class.
Definition rarg.h:75
Adc.
Definition binary_instr_with_imm.h:37
Adc.
Definition ternary_instr_with_shift.h:231
Add.
Definition binary_instr_with_imm.h:17
Add.
Definition ternary_instr_with_shift.h:207
Add to pc.
Definition unary_instr_imm.h:18
And.
Definition binary_instr_with_imm_carry.h:66
And operation.
Definition ternary_instr_with_shift.h:75
Asr.
Definition binary_instr_with_shift.h:18
Asr.
Definition binary_instr.h:48
Bit clear.
Definition binary_instr_with_imm_carry.h:89
Bit clear operation.
Definition ternary_instr_with_shift.h:103
Definition binary64bit_instr.h:95
Definition binary_branch_instr.h:52
Definition binary_branch_instr_with_imm.h:43
Definition binary_instr.h:222
Definition binary_instr_with_imm_carry.h:107
Definition binary_instr_with_imm.h:120
Definition binary_instr_with_rotation.h:101
Definition binary_instr_with_shift.h:117
Load from immediate adr to register.
Definition binary_load_instr_with_imm.h:16
Definition binary_null_instr_with_imm_carry.h:59
Definition binary_null_instr_with_imm.h:55
Load from immediate adr to register.
Definition binary_store_instr_with_imm.h:15
Branch link X.
Definition unary_branch_instr.h:40
Branch X.
Definition unary_branch_instr.h:18
Compare branch.
Definition binary_branch_instr_with_imm.h:18
Clz.
Definition unary_instr.h:18
Cmn.
Definition binary_null_instr_with_imm.h:40
Cmp.
Definition binary_null_instr_with_imm.h:18
Compare two registers.
Definition ternary_null_instr_with_shift.h:18
Dmb instruction.
Definition nullary_instr.h:34
Eor.
Definition binary_instr_with_imm_carry.h:43
Exclusive Or operation.
Definition ternary_instr_with_shift.h:18
Loads u32 (exlusive) from memory.
Definition load_mem.h:94
Loads i16 from memory and extends the result to u32.
Definition load_mem.h:63
Loads i8 from memory and extends the result to i32.
Definition load_mem.h:30
Loads u16 from memory and extends the result to u32.
Definition load_mem.h:47
Loads u32 from memory.
Definition load_mem.h:79
Loads u8 from memory and extends the result to u32.
Definition load_mem.h:14
Lsl.
Definition binary_instr_with_shift.h:44
Lsl.
Definition binary_instr.h:77
Lsr.
Definition binary_instr_with_shift.h:70
Lsr.
Definition binary_instr.h:19
Mla.
Definition ternary_instr.h:44
Mls.
Definition ternary_instr.h:17
Mov.
Definition unary_instr.h:49
Mov.
Definition unary_instr_imm_carry.h:18
Mul.
Definition binary_instr.h:106
Mvn.
Definition binary_instr_with_shift.h:96
Mvn.
Definition unary_instr_imm_carry.h:40
Nop instruction.
Definition nullary_instr.h:18
Definition nullary_instr.h:42
Orr.
Definition binary_instr_with_imm_carry.h:18
Orr operation.
Definition ternary_instr_with_shift.h:47
Rrx.
Definition unary_instr.h:80
Reverse Subtract.
Definition binary_instr_with_imm.h:104
Reverse Subtract.
Definition ternary_instr_with_shift.h:183
Sdiv.
Definition binary_instr.h:179
Subtract with carry.
Definition binary_instr_with_imm.h:81
Subtract with carry.
Definition ternary_instr_with_shift.h:131
Smull.
Definition binary64bit_instr.h:44
static Result< InstrExecResult > Ubfx(TInstrContext &ictx, const InstrFlagsSet &iflags, const TDest &rd, const TArg0 &rn, const u8 &lsbit, const u8 &widthminus1)
Ubfx.
Definition special_instr.h:156
static Result< InstrExecResult > ItInstr(TInstrContext &ictx, const InstrFlagsSet &iflags, const u32 &firstcond, const u32 &mask)
It instruction.
Definition special_instr.h:28
static Result< InstrExecResult > Msr(TInstrContext &ictx, const InstrFlagsSet &iflags, const TArg0 &rn, const uint8_t mask, const uint8_t SYSm)
Msr.
Definition special_instr.h:225
static Result< InstrExecResult > Bkpt(TInstrContext &ictx, const InstrFlagsSet &iflags, const u32 &imm32, TDelegates &delegates)
Bkpt instruction.
Definition special_instr.h:78
static Result< InstrExecResult > Strd(TInstrContext &ictx, const InstrFlagsSet &iflags, const TTgt &rt, const TArg0 &rt2, const TArg1 &rn, const u32 &imm32)
Strd.
Definition special_instr.h:433
static Result< InstrExecResult > Bfi(TInstrContext &ictx, const InstrFlagsSet &iflags, const TDest &rd, const TArg0 &rn, const u8 &lsbit, const u8 &msbit)
Bfi.
Definition special_instr.h:122
static Result< InstrExecResult > BCond(TInstrContext &ictx, const InstrFlagsSet &iflags, const u32 &imm32, const u8 &cond)
Branch condition.
Definition special_instr.h:104
static Result< InstrExecResult > Svc(TInstrContext &ictx, const InstrFlagsSet &iflags, const u32 &imm32, TDelegates &delegates)
Svc instruction.
Definition special_instr.h:45
static Result< InstrExecResult > Mrs(TInstrContext &ictx, const InstrFlagsSet &iflags, const TDest &rd, const uint8_t mask, const uint8_t SYSm)
Mrs.
Definition special_instr.h:331
static Result< InstrExecResult > Ldrd(TInstrContext &ictx, const InstrFlagsSet &iflags, const TTgt0 &rt, const TTgt1 &rt2, const TArg0 &rn, const u32 &imm32)
Ldrd.
Definition special_instr.h:185
Store (exclusive) u32 to memory.
Definition store_mem.h:57
Store u16 to memory.
Definition store_mem.h:28
Store u32 to memory.
Definition store_mem.h:43
Store u8 to memory.
Definition store_mem.h:13
Subtract.
Definition binary_instr_with_imm.h:60
Subtract.
Definition ternary_instr_with_shift.h:158
Sxtb.
Definition binary_instr_with_rotation.h:40
Sxth.
Definition binary_instr_with_rotation.h:84
Table branch.
Definition binary_branch_instr.h:19
Teq.
Definition binary_null_instr_with_imm_carry.h:41
TEQ - Test two registers.
Definition ternary_null_instr_with_shift.h:72
Definition ternary_instr.h:69
Definition ternary_instr_with_shift.h:252
Load from register adress to register.
Definition ternary_load_instr_with_shift.h:15
Definition ternary_null_instr_with_shift.h:94
Definition ternary_store_instr_with_imm.h:12
Load from register adress to register.
Definition ternary_store_instr_with_shift.h:15
Tst.
Definition binary_null_instr_with_imm_carry.h:18
TST - Test two registers.
Definition ternary_null_instr_with_shift.h:44
Udiv.
Definition binary_instr.h:131
Umlal.
Definition binary64bit_instr.h:69
Umull.
Definition binary64bit_instr.h:18
Definition unary_branch_instr.h:62
Definition unary_instr.h:109
Definition unary_instr_imm_carry.h:56
Definition unary_instr_imm.h:35
Load from immediate adr to register.
Definition unary_load_instr_imm.h:16
Uxtb.
Definition binary_instr_with_rotation.h:18
Uxth.
Definition binary_instr_with_rotation.h:62
Load multiple.
Definition variadic_load_instr.h:18
Definition variadic_store_instr_db.h:16
Store Multiple.
Definition variadic_store_instr.h:17
In this file the MemoryViewer class is defined.
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6
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 instr_context.h:8
Definition instr_exec_results.h:23
Definition result.h:15
Definition instr.h:734