libmicroemu 0.2.0
ARM Microcontroller Emulator Library
Loading...
Searching...
No Matches
thumb.h
1#pragma once
2#include "libmicroemu/internal/logic/alu.h"
3#include "libmicroemu/internal/logic/thumb_immediate_result.h"
5#include "libmicroemu/internal/utils/bit_manip.h"
6#include "libmicroemu/types.h"
7#include <assert.h>
8#include <cstddef>
9#include <cstdint>
10
11namespace libmicroemu::internal {
12
13class Thumb {
14public:
15 static Result<u32> ThumbExpandImm(u32 imm12) {
16 // APSR.C argument to following function call does not affect the imm32
17 // therefore fake it
18 const bool apsr_c_dummy = false;
19 const auto result = ThumbExpandImm_C(imm12, apsr_c_dummy);
20 return Result<u32>(result.status_code, result.content.out);
21 }
22
23 static Result<ThumbImmediateResult> ThumbExpandImm_C(const uint32_t &in, const bool carry_in) {
24 // see Armv7-M Architecture Reference Manual Issue E.e p.139 - 140
25 u32 imm32{0U};
26 bool carry_out{false};
27
28 if (Bm32::ExtractBits1R<11U, 10U>(in) == 0x0U) {
29 switch (Bm32::ExtractBits1R<9U, 8U>(in)) {
30
31 case 0x0U: {
32 imm32 = Bm32::ZeroExtend<u32>(in & 0xFFU);
33 break;
34 }
35 case 0x1U: {
36 if ((in & 0xFFU) == 0x0U) {
37 return Err<ThumbImmediateResult>(StatusCode::kExecutorUnpredictable);
38 }
39 imm32 = ((in & 0xFFU) << 16U) | (in & 0xFFU);
40 break;
41 }
42 case 0x2U: {
43 if ((in & 0xFFU) == 0x0U) {
44 return Err<ThumbImmediateResult>(StatusCode::kExecutorUnpredictable);
45 }
46 imm32 = ((in & 0xFFU) << 24U) | ((in & 0xFFU) << 8U);
47 break;
48 }
49 case 0x3U: {
50 if ((in & 0xFFU) == 0x0U) {
51 return Err<ThumbImmediateResult>(StatusCode::kExecutorUnpredictable);
52 }
53 imm32 = ((in & 0xFFU) << 24U) | ((in & 0xFFU) << 16U) | ((in & 0xFFU) << 8U) |
54 ((in & 0xFFU) << 0U);
55 break;
56 }
57 default:
58 // should not happen
59 assert(false);
60 break;
61 }
62 carry_out = carry_in;
63 } else {
64 const u32 unrotated_value = Bm32::ZeroExtend<u32>(0x80U | (in & 0x7FU));
65 const auto r_ror = Alu32::ROR_C(unrotated_value, Bm32::ExtractBits1R<11U, 7U>(in));
66
67 imm32 = r_ror.result;
68 carry_out = r_ror.carry_out;
69 }
70 return Ok(ThumbImmediateResult{imm32, carry_out});
71 }
72
73private:
77 Thumb() = delete;
78
82 ~Thumb() = delete;
83
88 Thumb(const Thumb &r_src) = delete;
89
94 Thumb &operator=(const Thumb &r_src) = delete;
95
100 Thumb(Thumb &&r_src) = delete;
101
106 Thumb &operator=(Thumb &&r_src) = delete;
107};
108
109} // namespace libmicroemu::internal
static U ZeroExtend(const u32 &value)
Definition bit_manip.h:200
static constexpr u32 ExtractBits1R(const u32 &value)
Definition bit_manip.h:136
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
Contains the Result class which is used to return the result of a function.
Definition thumb_immediate_result.h:6
Definition result.h:15