libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
ternary_store_instr_with_imm.h
1#pragma once
2#include "libmicroemu/internal/decoder/decoder.h"
3#include "libmicroemu/internal/executor/instr_context.h"
4#include "libmicroemu/internal/executor/instr_exec_results.h"
6#include "libmicroemu/internal/utils/rarg.h"
7#include "libmicroemu/register_details.h"
8#include "libmicroemu/types.h"
9
10namespace libmicroemu::internal {
11
12template <typename TStoreOp, typename TInstrContext> class TernaryStoreInstrWithImm {
13public:
14 using It = typename TInstrContext::It;
15 using Pc = typename TInstrContext::Pc;
16
17 template <typename TDest, typename TTgt, typename TArg0>
18 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
19 const TDest &rd, const TTgt &rt, const TArg0 &rn,
20 const u32 &imm32) {
21 const bool is_index = (iflags & static_cast<InstrFlagsSet>(InstrFlags::kIndex)) != 0U;
22 const bool is_add = (iflags & static_cast<InstrFlagsSet>(InstrFlags::kAdd)) != 0U;
23
24 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
25 if (!condition_passed) {
26 PostExecAdvancePcAndIt::Call(ictx, iflags);
27 return Ok(InstrExecResult{kNoInstrExecFlags});
28 }
29
30 InstrExecFlagsSet eflags{kNoInstrExecFlags};
31 const auto n = ictx.cpua.ReadRegister(rn.Get());
32
33 const me_adr_t offset_addr = is_add == true ? n + imm32 : n - imm32;
34 const me_adr_t address = is_index == true ? offset_addr : n;
35
36 const auto t = ictx.cpua.ReadRegister(rt.Get());
37 u32 d{0U};
38
39 TRY(InstrExecResult, TStoreOp::Write(ictx, address, t, d));
40
41 // write back if write succeeded
42 ictx.cpua.WriteRegister(rd.Get(), d);
43
44 const bool is_wback = (iflags & static_cast<InstrFlagsSet>(InstrFlags::kWBack)) != 0U;
45 if (is_wback) {
46 PostExecWriteRegPcExcluded::Call(ictx, rn, offset_addr);
47 }
48 PostExecAdvancePcAndIt::Call(ictx, iflags);
49 return Ok(InstrExecResult{eflags});
50 }
51
52private:
56 TernaryStoreInstrWithImm() = delete;
57
61 ~TernaryStoreInstrWithImm() = delete;
62
67 TernaryStoreInstrWithImm(const TernaryStoreInstrWithImm &r_src) = delete;
68
73 TernaryStoreInstrWithImm &operator=(const TernaryStoreInstrWithImm &r_src) = delete;
74
79 TernaryStoreInstrWithImm(TernaryStoreInstrWithImm &&r_src) = delete;
80
85 TernaryStoreInstrWithImm &operator=(TernaryStoreInstrWithImm &&r_src) = delete;
86};
87
88} // namespace libmicroemu::internal
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