libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
unary_branch_instr_imm.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 B1ImmOp {
19public:
20 using It = typename TInstrContext::It;
21 using Pc = typename TInstrContext::Pc;
22
23 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
24 const u32 &imm32) {
25 static_cast<void>(iflags);
26 const me_adr_t pc = static_cast<me_adr_t>(ictx.cpua.template ReadRegister<RegisterId::kPc>());
27 auto branch_res = pc + imm32;
28 PostExecBranch::Call(ictx, branch_res);
29 return Ok(kNoInstrExecFlags);
30 }
31};
32
38template <typename TInstrContext> class Bl1ImmOp {
39public:
40 using It = typename TInstrContext::It;
41 using Pc = typename TInstrContext::Pc;
42
43 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
44 const u32 &imm32) {
45 static_cast<void>(iflags);
46 const me_adr_t pc = static_cast<me_adr_t>(ictx.cpua.template ReadRegister<RegisterId::kPc>());
47 ictx.cpua.template WriteRegister<RegisterId::kLr>(static_cast<uint32_t>((pc & ~0x1U) | 0x1U));
48 auto branch_res = pc + imm32;
49 PostExecBranch::Call(ictx, branch_res);
50 return Ok(kNoInstrExecFlags);
51 }
52};
53
54template <typename TOp, typename TInstrContext> class UnaryBranchInstrImm {
55public:
56 using It = typename TInstrContext::It;
57 using Pc = typename TInstrContext::Pc;
58
59 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
60 const u32 &imm32) {
61 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
62 if (!condition_passed) {
63 PostExecAdvancePcAndIt::Call(ictx, iflags);
64 return Ok(InstrExecResult{kNoInstrExecFlags});
65 }
66
67 TRY_ASSIGN(eflags, InstrExecResult, TOp::Call(ictx, iflags, imm32));
68 return Ok(InstrExecResult{eflags});
69 }
70
71private:
75 UnaryBranchInstrImm() = delete;
76
80 ~UnaryBranchInstrImm() = delete;
81
86 UnaryBranchInstrImm(const UnaryBranchInstrImm &r_src) = delete;
87
92 UnaryBranchInstrImm &operator=(const UnaryBranchInstrImm &r_src) = delete;
93
98 UnaryBranchInstrImm(UnaryBranchInstrImm &&r_src) = delete;
99
104 UnaryBranchInstrImm &operator=(UnaryBranchInstrImm &&r_src) = delete;
105};
106
107} // namespace libmicroemu::internal
Branch.
Definition unary_branch_instr_imm.h:18
Branch Link.
Definition unary_branch_instr_imm.h:38
The libmicroemu namespace contains all classes and functions of the libmicroemu which are public.
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 result.h:15