libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
binary_instr_with_rotation.h
1#pragma once
2#include "libmicroemu/internal/decoder/decoder.h"
3#include "libmicroemu/internal/executor/instr/post_exec.h"
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 Uxtb1Rotation {
19public:
20 template <typename TDest, typename TArg0>
21 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
22 const TDest &rd, const TArg0 &rm, const u8 &rotation) {
23 const auto m = ictx.cpua.ReadRegister(rm.Get());
24 const u32 rotated = Alu32::ROR(m, rotation);
25 const u32 data = Bm8::ZeroExtend<u32>(static_cast<uint8_t>(rotated & 0xFFU));
26 const auto op_res = OpResult{data, false, false};
27
28 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
29 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
30 PostExecAdvancePcAndIt::Call(ictx, iflags);
31 return Ok(kNoInstrExecFlags);
32 }
33};
34
40template <typename TInstrContext> class Sxtb1Rotation {
41public:
42 template <typename TDest, typename TArg0>
43 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
44 const TDest &rd, const TArg0 &rm, const u8 &rotation) {
45 const auto m = ictx.cpua.ReadRegister(rm.Get());
46 const u32 rotated = Alu32::ROR(m, rotation);
47 const u32 data = Bm8::SignExtend<u32, 7U>(static_cast<uint8_t>(rotated & 0xFFU));
48 const auto op_res = OpResult{data, false, false};
49
50 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
51 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
52 PostExecAdvancePcAndIt::Call(ictx, iflags);
53 return Ok(kNoInstrExecFlags);
54 }
55};
56
62template <typename TInstrContext> class Uxth1Rotation {
63public:
64 template <typename TDest, typename TArg0>
65 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
66 const TDest &rd, const TArg0 &rm, const u8 &rotation) {
67 const auto m = ictx.cpua.ReadRegister(rm.Get());
68 const u32 rotated = Alu32::ROR(m, rotation);
69 const u32 data = Bm16::ZeroExtend<u32>(static_cast<uint16_t>(rotated & 0xFFFFU));
70 const auto op_res = OpResult{data, false, false};
71
72 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
73 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
74 PostExecAdvancePcAndIt::Call(ictx, iflags);
75 return Ok(kNoInstrExecFlags);
76 }
77};
78
84template <typename TInstrContext> class Sxth1Rotation {
85public:
86 template <typename TDest, typename TArg0>
87 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
88 const TDest &rd, const TArg0 &rm, const u8 &rotation) {
89 const auto m = ictx.cpua.ReadRegister(rm.Get());
90 const u32 rotated = Alu32::ROR(m, rotation);
91 const u32 val = Bm16::SignExtend<u32, 15>(static_cast<uint16_t>(rotated & 0xFFFFU));
92 const auto op_res = OpResult{val, false, false};
93
94 PostExecWriteRegPcExcluded::Call(ictx, rd, op_res.value);
95 PostExecOptionalSetFlags::Call(ictx, iflags, op_res);
96 PostExecAdvancePcAndIt::Call(ictx, iflags);
97 return Ok(kNoInstrExecFlags);
98 }
99};
100
101template <typename TOp, typename TInstrContext> class BinaryInstrWithRotation {
102public:
103 using It = typename TInstrContext::It;
104 using Pc = typename TInstrContext::Pc;
105
106 template <typename TDest, typename TArg0>
107 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
108 const TDest &rd, const TArg0 &rm, const u8 &rotation) {
109 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
110 if (!condition_passed) {
111 PostExecAdvancePcAndIt::Call(ictx, iflags);
112 return Ok(InstrExecResult{kNoInstrExecFlags});
113 }
114
115 TRY_ASSIGN(eflags, InstrExecResult, TOp::Call(ictx, iflags, rd, rm, rotation));
116 return Ok(InstrExecResult{eflags});
117 }
118
119private:
123 BinaryInstrWithRotation() = delete;
124
128 ~BinaryInstrWithRotation() = delete;
129
134 BinaryInstrWithRotation(const BinaryInstrWithRotation &r_src) = delete;
135
140 BinaryInstrWithRotation &operator=(const BinaryInstrWithRotation &r_src) = delete;
141
146 BinaryInstrWithRotation(BinaryInstrWithRotation &&r_src) = delete;
147
152 BinaryInstrWithRotation &operator=(BinaryInstrWithRotation &&r_src) = delete;
153};
154
155} // namespace libmicroemu::internal
static U ZeroExtend(const u8 &value)
Definition bit_manip.h:200
static U SignExtend(const u8 &value)
Definition bit_manip.h:214
Sxtb.
Definition binary_instr_with_rotation.h:40
Sxth.
Definition binary_instr_with_rotation.h:84
Uxtb.
Definition binary_instr_with_rotation.h:18
Uxth.
Definition binary_instr_with_rotation.h:62
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 post_exec.h:12
Definition result.h:15