summaryrefslogtreecommitdiff
path: root/src/core/arm/nce/instructions.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/arm/nce/instructions.h')
-rw-r--r--src/core/arm/nce/instructions.h147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/core/arm/nce/instructions.h b/src/core/arm/nce/instructions.h
new file mode 100644
index 000000000..5b56ff857
--- /dev/null
+++ b/src/core/arm/nce/instructions.h
@@ -0,0 +1,147 @@
1// SPDX-FileCopyrightText: Copyright © 2020 Skyline Team and Contributors
2// SPDX-License-Identifier: MPL-2.0
3
4#include "common/bit_field.h"
5#include "common/common_types.h"
6
7namespace Core::NCE {
8
9enum SystemRegister : u32 {
10 TpidrEl0 = 0x5E82,
11 TpidrroEl0 = 0x5E83,
12 CntfrqEl0 = 0x5F00,
13 CntpctEl0 = 0x5F01,
14};
15
16// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/SVC--Supervisor-Call-
17union SVC {
18 constexpr explicit SVC(u32 raw_) : raw{raw_} {}
19
20 constexpr bool Verify() {
21 return (this->GetSig0() == 0x1 && this->GetSig1() == 0x6A0);
22 }
23
24 constexpr u32 GetSig0() {
25 return decltype(sig0)::ExtractValue(raw);
26 }
27
28 constexpr u32 GetValue() {
29 return decltype(value)::ExtractValue(raw);
30 }
31
32 constexpr u32 GetSig1() {
33 return decltype(sig1)::ExtractValue(raw);
34 }
35
36 u32 raw;
37
38private:
39 BitField<0, 5, u32> sig0; // 0x1
40 BitField<5, 16, u32> value; // 16-bit immediate
41 BitField<21, 11, u32> sig1; // 0x6A0
42};
43static_assert(sizeof(SVC) == sizeof(u32));
44static_assert(SVC(0xD40000C1).Verify());
45static_assert(SVC(0xD40000C1).GetValue() == 0x6);
46
47// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MRS--Move-System-Register-
48union MRS {
49 constexpr explicit MRS(u32 raw_) : raw{raw_} {}
50
51 constexpr bool Verify() {
52 return (this->GetSig() == 0xD53);
53 }
54
55 constexpr u32 GetRt() {
56 return decltype(rt)::ExtractValue(raw);
57 }
58
59 constexpr u32 GetSystemReg() {
60 return decltype(system_reg)::ExtractValue(raw);
61 }
62
63 constexpr u32 GetSig() {
64 return decltype(sig)::ExtractValue(raw);
65 }
66
67 u32 raw;
68
69private:
70 BitField<0, 5, u32> rt; // destination register
71 BitField<5, 15, u32> system_reg; // source system register
72 BitField<20, 12, u32> sig; // 0xD53
73};
74static_assert(sizeof(MRS) == sizeof(u32));
75static_assert(MRS(0xD53BE020).Verify());
76static_assert(MRS(0xD53BE020).GetSystemReg() == CntpctEl0);
77static_assert(MRS(0xD53BE020).GetRt() == 0x0);
78
79// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MSR--register---Move-general-purpose-register-to-System-Register-
80union MSR {
81 constexpr explicit MSR(u32 raw_) : raw{raw_} {}
82
83 constexpr bool Verify() {
84 return this->GetSig() == 0xD51;
85 }
86
87 constexpr u32 GetRt() {
88 return decltype(rt)::ExtractValue(raw);
89 }
90
91 constexpr u32 GetSystemReg() {
92 return decltype(system_reg)::ExtractValue(raw);
93 }
94
95 constexpr u32 GetSig() {
96 return decltype(sig)::ExtractValue(raw);
97 }
98
99 u32 raw;
100
101private:
102 BitField<0, 5, u32> rt; // source register
103 BitField<5, 15, u32> system_reg; // destination system register
104 BitField<20, 12, u32> sig; // 0xD51
105};
106static_assert(sizeof(MSR) == sizeof(u32));
107static_assert(MSR(0xD51BD040).Verify());
108static_assert(MSR(0xD51BD040).GetSystemReg() == TpidrEl0);
109static_assert(MSR(0xD51BD040).GetRt() == 0x0);
110
111// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/LDXR--Load-Exclusive-Register-
112// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/LDXP--Load-Exclusive-Pair-of-Registers-
113// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/STXR--Store-Exclusive-Register-
114// https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/STXP--Store-Exclusive-Pair-of-registers-
115union Exclusive {
116 constexpr explicit Exclusive(u32 raw_) : raw{raw_} {}
117
118 constexpr bool Verify() {
119 return this->GetSig() == 0x10;
120 }
121
122 constexpr u32 GetSig() {
123 return decltype(sig)::ExtractValue(raw);
124 }
125
126 constexpr u32 AsOrdered() {
127 return raw | decltype(o0)::FormatValue(1);
128 }
129
130 u32 raw;
131
132private:
133 BitField<0, 5, u32> rt; // memory operand
134 BitField<5, 5, u32> rn; // register operand 1
135 BitField<10, 5, u32> rt2; // register operand 2
136 BitField<15, 1, u32> o0; // ordered
137 BitField<16, 5, u32> rs; // status register
138 BitField<21, 2, u32> l; // operation type
139 BitField<23, 7, u32> sig; // 0x10
140 BitField<30, 2, u32> size; // size
141};
142static_assert(Exclusive(0xC85FFC00).Verify());
143static_assert(Exclusive(0xC85FFC00).AsOrdered() == 0xC85FFC00);
144static_assert(Exclusive(0xC85F7C00).AsOrdered() == 0xC85FFC00);
145static_assert(Exclusive(0xC8200440).AsOrdered() == 0xC8208440);
146
147} // namespace Core::NCE