libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
binary_branch_instr.h
1#pragma once
2#include "libmicroemu/internal/cpu_accessor.h"
3#include "libmicroemu/internal/decoder/decoder.h"
4#include "libmicroemu/internal/executor/instr/post_exec.h"
5#include "libmicroemu/internal/executor/instr_context.h"
6#include "libmicroemu/internal/executor/instr_exec_results.h"
8#include "libmicroemu/internal/utils/rarg.h"
9#include "libmicroemu/register_details.h"
10#include "libmicroemu/types.h"
11
12namespace libmicroemu::internal {
13
19template <typename TInstrContext> class TbbH2Op {
20public:
21 using It = typename TInstrContext::It;
22 using Pc = typename TInstrContext::Pc;
23
24 template <typename TArg0, typename TArg1>
25 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
26 const TArg0 &rn, const TArg1 &rm) {
27
28 const bool is_tbh = (iflags & static_cast<InstrFlagsSet>(InstrFlags::kTbh)) != 0U;
29 const auto m = ictx.cpua.ReadRegister(rm.Get());
30 const auto n = ictx.cpua.ReadRegister(rn.Get());
31 me_adr_t halfwords{0U};
32 if (is_tbh) {
33 me_adr_t adr = (n + Alu32::LSL(m, 1U));
34 TRY_ASSIGN(out, InstrExecFlagsSet,
35 ictx.bus.template ReadOrRaise<u16>(ictx.cpua, adr,
36 BusExceptionType::kRaisePreciseDataBusError));
37 halfwords = out;
38 } else {
39 me_adr_t adr = n + m;
40 TRY_ASSIGN(out, InstrExecFlagsSet,
41 ictx.bus.template ReadOrRaise<u8>(ictx.cpua, adr,
42 BusExceptionType::kRaisePreciseDataBusError));
43 halfwords = out;
44 }
45
46 const me_adr_t pc = static_cast<me_adr_t>(ictx.cpua.template ReadRegister<RegisterId::kPc>());
47 Pc::BranchWritePC(ictx.cpua, pc + (halfwords << 1U));
48 return Ok(kNoInstrExecFlags);
49 }
50};
51
52template <typename TOp, typename TInstrContext> class BinaryBranchInstr {
53public:
54 using It = typename TInstrContext::It;
55 using Pc = typename TInstrContext::Pc;
56
57 template <typename TArg0, typename TArg1>
58 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
59 const TArg0 &rn, const TArg1 &rm) {
60
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, rn, rm));
68 return Ok(InstrExecResult{eflags});
69 }
70
71private:
75 BinaryBranchInstr() = delete;
76
80 ~BinaryBranchInstr() = delete;
81
86 BinaryBranchInstr(const BinaryBranchInstr &r_src) = delete;
87
92 BinaryBranchInstr &operator=(const BinaryBranchInstr &r_src) = delete;
93
98 BinaryBranchInstr(BinaryBranchInstr &&r_src) = delete;
99
104 BinaryBranchInstr &operator=(BinaryBranchInstr &&r_src) = delete;
105};
106
107} // namespace libmicroemu::internal
Table branch.
Definition binary_branch_instr.h:19
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_exec_results.h:23
Definition result.h:15