libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
variadic_store_instr_db.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
12/*
13 * @brief Store Multiple Decrement Before
14 * PUSH - see Armv7-M Architecture Reference Manual Issue E.e p.322
15 */
16template <typename TInstrContext> class VariadicStoreInstrDb {
17public:
18 using It = typename TInstrContext::It;
19 using Pc = typename TInstrContext::Pc;
20
21 template <typename TArg0>
22 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
23 const TArg0 &rn, const u32 &registers) {
24 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
25
26 if (!condition_passed) {
27 PostExecAdvancePcAndIt::Call(ictx, iflags);
28 return Ok(InstrExecResult{kNoInstrExecFlags});
29 }
30 const auto n = ictx.cpua.ReadRegister(rn.Get());
31 auto reg_count = Bm32::BitCount(registers);
32 u32 address = n - 4U * reg_count;
33
34 for (u32 reg = 0U; reg <= 14U; ++reg) {
35 u32 bm = 0x1U << reg;
36 if ((registers & bm) != 0U) {
37 const auto r = ictx.cpua.ReadRegister(static_cast<RegisterId>(reg));
39 ictx.bus.template WriteOrRaise<u32>(ictx.cpua, address, r,
40 BusExceptionType::kRaisePreciseDataBusError));
41 address += 4U;
42 }
43 }
44
45 // For debugging purposes
46 // MemoryViewer<TMemAccess> mem_view(bus_);
47 // mem_view.Print(0x80000 - 0x32, 0x64);
48
49 const bool is_wback = (iflags & static_cast<InstrFlagsSet>(InstrFlags::kWBack)) != 0U;
50
51 if (is_wback) {
52 const auto wback_val = n - 4U * reg_count;
53
54 // Update n register
55 PostExecWriteRegPcExcluded::Call(ictx, rn, wback_val);
56 }
57 PostExecAdvancePcAndIt::Call(ictx, iflags);
58
59 return Ok(InstrExecResult{kNoInstrExecFlags});
60 }
61
62private:
66 VariadicStoreInstrDb() = delete;
67
71 ~VariadicStoreInstrDb() = delete;
72
77 VariadicStoreInstrDb(const VariadicStoreInstrDb &r_src) = delete;
78
83 VariadicStoreInstrDb &operator=(const VariadicStoreInstrDb &r_src) = delete;
84
89 VariadicStoreInstrDb(VariadicStoreInstrDb &&r_src) = delete;
90
95 VariadicStoreInstrDb &operator=(VariadicStoreInstrDb &&r_src) = delete;
96};
97
98} // namespace libmicroemu::internal
static u32 BitCount(const u32 &value)
Definition bit_manip.h:243
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6
RegisterId
Enumeration of register IDs.
Definition register_id.h:13
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