libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
binary64bit_instr.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 Umull2Op {
19public:
20 template <typename TDestLo, typename TDestHi, typename TArg0, typename TArg1>
21 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
22 const TDestLo &rd_lo, const TDestHi &rd_hi, const TArg0 &rn,
23 const TArg1 &rm) {
24 const auto n = ictx.cpua.ReadRegister(rn.Get());
25 const auto m = ictx.cpua.ReadRegister(rm.Get());
26
27 const u64 result = (static_cast<u64>(n) * static_cast<u64>(m));
28 const u32 result_lo = static_cast<u32>(result & 0xFFFFFFFFU);
29 const u32 result_hi = static_cast<u32>((result >> 32U) & 0xFFFFFFFFU);
30
31 PostExecWriteRegPcExcluded::Call(ictx, rd_lo, result_lo);
32 PostExecWriteRegPcExcluded::Call(ictx, rd_hi, result_hi);
33 PostExecAdvancePcAndIt::Call(ictx, iflags);
34
35 return Ok(kNoInstrExecFlags);
36 }
37};
38
44template <typename TInstrContext> class Smull2Op {
45public:
46 template <typename TDestLo, typename TDestHi, typename TArg0, typename TArg1>
47 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
48 const TDestLo &rd_lo, const TDestHi &rd_hi, const TArg0 &rn,
49 const TArg1 &rm) {
50 const auto n = static_cast<i32>(ictx.cpua.ReadRegister(rn.Get()));
51 const auto m = static_cast<i32>(ictx.cpua.ReadRegister(rm.Get()));
52 const u64 result = static_cast<u64>(static_cast<i64>(n) * static_cast<i64>(m));
53 const u32 result_lo = static_cast<u32>(result & 0xFFFFFFFFU);
54 const u32 result_hi = static_cast<u32>((result >> 32U) & 0xFFFFFFFFU);
55
56 PostExecWriteRegPcExcluded::Call(ictx, rd_lo, result_lo);
57 PostExecWriteRegPcExcluded::Call(ictx, rd_hi, result_hi);
58 PostExecAdvancePcAndIt::Call(ictx, iflags);
59
60 return Ok(kNoInstrExecFlags);
61 }
62};
63
69template <typename TInstrContext> class Umlal2Op {
70public:
71 template <typename TDestLo, typename TDestHi, typename TArg0, typename TArg1>
72 static Result<InstrExecFlagsSet> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
73 const TDestLo &rd_lo, const TDestHi &rd_hi, const TArg0 &rn,
74 const TArg1 &rm) {
75
76 const u32 rdhi = ictx.cpua.ReadRegister(rd_hi.Get());
77 const u32 rdlo = ictx.cpua.ReadRegister(rd_lo.Get());
78 const u32 rd = static_cast<u64>(rdhi) << 32U | static_cast<u64>(rdlo);
79
80 const auto n = ictx.cpua.ReadRegister(rn.Get());
81 const auto m = ictx.cpua.ReadRegister(rm.Get());
82
83 const u64 result = (static_cast<u64>(n) * static_cast<u64>(m)) + rd;
84 const u32 result_lo = static_cast<u32>(result & 0xFFFFFFFFU);
85 const u32 result_hi = static_cast<u32>((result >> 32U) & 0xFFFFFFFFU);
86
87 PostExecWriteRegPcExcluded::Call(ictx, rd_lo, result_lo);
88 PostExecWriteRegPcExcluded::Call(ictx, rd_hi, result_hi);
89 PostExecAdvancePcAndIt::Call(ictx, iflags);
90
91 return Ok(kNoInstrExecFlags);
92 }
93};
94
95template <typename TOp, typename TInstrContext> class Binary64bitInstr {
96public:
97 using It = typename TInstrContext::It;
98 using Pc = typename TInstrContext::Pc;
99
100 template <typename TDestLo, typename TDestHi, typename TArg0, typename TArg1>
101 static Result<InstrExecResult> Call(TInstrContext &ictx, const InstrFlagsSet &iflags,
102 const TDestLo &rd_lo, const TDestHi &rd_hi, const TArg0 &rn,
103 const TArg1 &rm) {
104 TRY_ASSIGN(condition_passed, InstrExecResult, It::ConditionPassed(ictx.cpua));
105 if (!condition_passed) {
106 PostExecAdvancePcAndIt::Call(ictx, iflags);
107 return Ok(InstrExecResult{kNoInstrExecFlags});
108 }
109
110 TRY_ASSIGN(eflags, InstrExecResult, TOp::Call(ictx, iflags, rd_lo, rd_hi, rn, rm));
111 return Ok(InstrExecResult{eflags});
112 }
113
114private:
118 Binary64bitInstr() = delete;
119
123 ~Binary64bitInstr() = delete;
124
129 Binary64bitInstr(const Binary64bitInstr &r_src) = delete;
130
135 Binary64bitInstr &operator=(const Binary64bitInstr &r_src) = delete;
136
141 Binary64bitInstr(Binary64bitInstr &&r_src) = delete;
142
147 Binary64bitInstr &operator=(Binary64bitInstr &&r_src) = delete;
148};
149
150} // namespace libmicroemu::internal
Smull.
Definition binary64bit_instr.h:44
Umlal.
Definition binary64bit_instr.h:69
Umull.
Definition binary64bit_instr.h:18
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