libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
unary_branch_instr.h
1#pragma once
2#include "libmicroemu/internal/decoder/decoder.h"
3
4#include "libmicroemu/internal/executor/instr_context.h"
5#include "libmicroemu/internal/executor/instr_exec_results.h"
7#include "libmicroemu/internal/utils/rarg.h"
8#include "libmicroemu/register_details.h"
9#include "libmicroemu/types.h"
10
11namespace libmicroemu::internal {
12
18template <typename TInstrContext> class Bx1Op {
19public:
20 using It = typename TInstrContext::It;
21 using Pc = typename TInstrContext::Pc;
22
23 template <typename TArg0>
24 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
25 const TArg0 &rm) {
26 static_cast<void>(iflags);
27 const auto m = ictx.cpua.ReadRegister(rm.Get());
28 const auto bres = static_cast<me_adr_t>(m);
29
30 TRY(InstrExecFlagsSet, PostExecBxWritePc::Call(ictx, bres));
31 return Ok(kNoInstrExecFlags);
32 }
33};
34
40template <typename TInstrContext> class Blx1Op {
41public:
42 using It = typename TInstrContext::It;
43 using Pc = typename TInstrContext::Pc;
44
45 template <typename TArg0>
46 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
47 const TArg0 &rm) {
48 static_cast<void>(iflags);
49 const me_adr_t pc = static_cast<me_adr_t>(ictx.cpua.template ReadRegister<RegisterId::kPc>());
50 const auto m = ictx.cpua.ReadRegister(rm.Get());
51 const me_adr_t next_instr_address = static_cast<me_adr_t>(pc - 2U);
52
53 const auto lr_val = static_cast<uint32_t>((next_instr_address & ~0x1) | 0x1U);
54 ictx.cpua.template WriteRegister<RegisterId::kLr>(lr_val);
55
56 const auto bres = static_cast<me_adr_t>(m);
57 PostExecBlxWritePc::Call(ictx, bres);
58 return Ok(kNoInstrExecFlags);
59 }
60};
61
62template <typename TOp, typename TInstrContext> class UnaryBranchInstr {
63public:
64 using It = typename TInstrContext::It;
65 using Pc = typename TInstrContext::Pc;
66
67 using ExcTrig = typename TInstrContext::ExcTrig;
68
69 template <typename TArg0>
70 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
71 const TArg0 &rm) {
72 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
73 if (!condition_passed) {
74 PostExecAdvancePcAndIt::Call(ictx, iflags);
75 return Ok(InstrExecResult{kNoInstrExecFlags});
76 }
77
78 TRY_ASSIGN(eflags, InstrExecResult, TOp::Call(ictx, iflags, rm));
79 return Ok(InstrExecResult{eflags});
80 }
81
82private:
86 UnaryBranchInstr() = delete;
87
91 ~UnaryBranchInstr() = delete;
92
97 UnaryBranchInstr(const UnaryBranchInstr &r_src) = delete;
98
103 UnaryBranchInstr &operator=(const UnaryBranchInstr &r_src) = delete;
104
109 UnaryBranchInstr(UnaryBranchInstr &&r_src) = delete;
110
115 UnaryBranchInstr &operator=(UnaryBranchInstr &&r_src) = delete;
116};
117
118} // namespace libmicroemu::internal
Branch link X.
Definition unary_branch_instr.h:40
Branch X.
Definition unary_branch_instr.h:18
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
#define TRY(OUT_TYPE, CALL)
Try to call a function and return an error if the call fails.
Definition result.h:138
Definition instr_exec_results.h:23
Definition result.h:15