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"
20 template <
typename TInstrContext,
typename OpResult>
21 static inline void Call(
const TInstrContext &ictx,
const OpResult &result) {
22 auto apsr = ictx.cpua.template ReadSpecialRegister<SpecialRegisterId::kApsr>();
26 ~(ApsrRegister::kNMsk | ApsrRegister::kZMsk | ApsrRegister::kCMsk | ApsrRegister::kVMsk);
28 apsr |= ((result.value >> 31U) & 0x1U) << ApsrRegister::kNPos;
30 apsr |= (result.carry_out ==
true ? 0x1U : 0x0U) << ApsrRegister::kCPos;
31 apsr |= (result.overflow ==
true ? 0x1U : 0x0U) << ApsrRegister::kVPos;
32 ictx.cpua.template WriteSpecialRegister<SpecialRegisterId::kApsr>(apsr);
38 template <
typename TInstrContext,
typename OpResult>
39 static inline void Call(
const TInstrContext &ictx,
const InstrFlagsSet &iflags,
41 if ((iflags &
static_cast<InstrFlagsSet
>(InstrFlags::kSetFlags)) != 0U) {
42 PostExecSetFlags::Call(ictx, result);
49 template <
typename TInstrContext>
50 static inline void Call(
const TInstrContext &ictx,
const InstrFlagsSet &iflags) {
51 using It =
typename TInstrContext::It;
52 using Pc =
typename TInstrContext::Pc;
54 const auto is_32bit = (iflags &
static_cast<InstrFlagsSet
>(InstrFlags::k32Bit)) != 0U;
55 It::ITAdvance(ictx.cpua);
56 Pc::AdvanceInstr(ictx.cpua, is_32bit);
62 template <
typename TInstrContext>
63 static inline void Call(
const TInstrContext &ictx,
const me_adr_t &new_pc) {
64 using It =
typename TInstrContext::It;
65 using Pc =
typename TInstrContext::Pc;
67 Pc::BranchWritePC(ictx.cpua, new_pc);
68 It::ITAdvance(ictx.cpua);
74 template <
typename TInstrContext>
75 static inline Result<void> Call(
const TInstrContext &ictx,
const me_adr_t &new_pc) {
76 using It =
typename TInstrContext::It;
77 using Pc =
typename TInstrContext::Pc;
79 TRY(
void, Pc::LoadWritePC(ictx.cpua, ictx.bus, new_pc));
80 It::ITAdvance(ictx.cpua);
87 template <
typename TInstrContext>
88 static inline Result<void> Call(
const TInstrContext &ictx,
const me_adr_t &new_pc) {
89 using It =
typename TInstrContext::It;
90 using Pc =
typename TInstrContext::Pc;
92 TRY(
void, Pc::BXWritePC(ictx.cpua, ictx.bus, new_pc));
93 It::ITAdvance(ictx.cpua);
100 template <
typename TInstrContext>
101 static inline void Call(
const TInstrContext &ictx,
const me_adr_t &new_pc) {
102 using It =
typename TInstrContext::It;
103 using Pc =
typename TInstrContext::Pc;
105 Pc::BLXWritePC(ictx.cpua, new_pc);
106 It::ITAdvance(ictx.cpua);
112 template <
typename TInstrContext,
typename TArg>
113 static void Call(
const TInstrContext &ictx,
const TArg &arg,
const u32 &value) {
115 ictx.cpua.WriteRegister(arg.Get(), value);
121 template <
typename TInstrContext,
typename TArg>
122 static Result<void> Call(
const TInstrContext &ictx,
const InstrFlagsSet &iflags,
const TArg &arg,
123 const u32 &value,
const bool is_aligned) {
128 TRY(
void, PostExecLoadWritePc::Call(ictx, value));
133 ictx.cpua.WriteRegister(arg.Get(), value);
134 PostExecAdvancePcAndIt::Call(ictx, iflags);
static u32 IsZeroBit(const u32 &value)
Definition bit_manip.h:234
Definition post_exec.h:47
Definition post_exec.h:98
Definition post_exec.h:60
Definition post_exec.h:85
Definition post_exec.h:72
Definition post_exec.h:36
Definition post_exec.h:18
Definition post_exec.h:110
Definition post_exec.h:119
The libmicroemu::internal namespace contains all classes and functions of libmicroemu which are priva...
Definition bkpt_flags.h:6
@ kExecutorUnpredictable
Executor encountered an unpredictable operation.
Definition status_code.h:76
@ kPc
Program-counter register.
Definition register_id.h:34
Contains the Result class which is used to return the result of a function.
#define TRY(OUT_TYPE, CALL)
Try to call a function and return an error if the call fails.
Definition result.h:138
Definition post_exec.h:12