diff options
Diffstat (limited to 'src/core/arm/nce/instructions.h')
| -rw-r--r-- | src/core/arm/nce/instructions.h | 147 |
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 | |||
| 7 | namespace Core::NCE { | ||
| 8 | |||
| 9 | enum 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- | ||
| 17 | union 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 | |||
| 38 | private: | ||
| 39 | BitField<0, 5, u32> sig0; // 0x1 | ||
| 40 | BitField<5, 16, u32> value; // 16-bit immediate | ||
| 41 | BitField<21, 11, u32> sig1; // 0x6A0 | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(SVC) == sizeof(u32)); | ||
| 44 | static_assert(SVC(0xD40000C1).Verify()); | ||
| 45 | static_assert(SVC(0xD40000C1).GetValue() == 0x6); | ||
| 46 | |||
| 47 | // https://developer.arm.com/documentation/ddi0596/2021-12/Base-Instructions/MRS--Move-System-Register- | ||
| 48 | union 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 | |||
| 69 | private: | ||
| 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 | }; | ||
| 74 | static_assert(sizeof(MRS) == sizeof(u32)); | ||
| 75 | static_assert(MRS(0xD53BE020).Verify()); | ||
| 76 | static_assert(MRS(0xD53BE020).GetSystemReg() == CntpctEl0); | ||
| 77 | static_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- | ||
| 80 | union 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 | |||
| 101 | private: | ||
| 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 | }; | ||
| 106 | static_assert(sizeof(MSR) == sizeof(u32)); | ||
| 107 | static_assert(MSR(0xD51BD040).Verify()); | ||
| 108 | static_assert(MSR(0xD51BD040).GetSystemReg() == TpidrEl0); | ||
| 109 | static_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- | ||
| 115 | union 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 | |||
| 132 | private: | ||
| 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 | }; | ||
| 142 | static_assert(Exclusive(0xC85FFC00).Verify()); | ||
| 143 | static_assert(Exclusive(0xC85FFC00).AsOrdered() == 0xC85FFC00); | ||
| 144 | static_assert(Exclusive(0xC85F7C00).AsOrdered() == 0xC85FFC00); | ||
| 145 | static_assert(Exclusive(0xC8200440).AsOrdered() == 0xC8208440); | ||
| 146 | |||
| 147 | } // namespace Core::NCE | ||