/src/capstonev5/arch/AArch64/AArch64BaseInfo.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- AArch64BaseInfo.h - Top level definitions for AArch64- --*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains small standalone helper functions and enum definitions for |
11 | | // the AArch64 target useful for the compiler back-end and the MC libraries. |
12 | | // As such, it deliberately does not include references to LLVM core |
13 | | // code gen types, passes, etc.. |
14 | | // |
15 | | //===----------------------------------------------------------------------===// |
16 | | |
17 | | /* Capstone Disassembly Engine */ |
18 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ |
19 | | |
20 | | #ifndef CS_LLVM_AARCH64_BASEINFO_H |
21 | | #define CS_LLVM_AARCH64_BASEINFO_H |
22 | | |
23 | | #include <ctype.h> |
24 | | #include <string.h> |
25 | | #include "AArch64Mapping.h" |
26 | | |
27 | | #ifndef __cplusplus |
28 | | #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64) |
29 | | #define inline /* inline */ |
30 | | #endif |
31 | | #endif |
32 | | |
33 | | inline static unsigned getWRegFromXReg(unsigned Reg) |
34 | 4.75k | { |
35 | 4.75k | switch (Reg) { |
36 | 140 | default: break; |
37 | 383 | case ARM64_REG_X0: return ARM64_REG_W0; |
38 | 330 | case ARM64_REG_X1: return ARM64_REG_W1; |
39 | 306 | case ARM64_REG_X2: return ARM64_REG_W2; |
40 | 467 | case ARM64_REG_X3: return ARM64_REG_W3; |
41 | 34 | case ARM64_REG_X4: return ARM64_REG_W4; |
42 | 233 | case ARM64_REG_X5: return ARM64_REG_W5; |
43 | 268 | case ARM64_REG_X6: return ARM64_REG_W6; |
44 | 340 | case ARM64_REG_X7: return ARM64_REG_W7; |
45 | 59 | case ARM64_REG_X8: return ARM64_REG_W8; |
46 | 89 | case ARM64_REG_X9: return ARM64_REG_W9; |
47 | 117 | case ARM64_REG_X10: return ARM64_REG_W10; |
48 | 139 | case ARM64_REG_X11: return ARM64_REG_W11; |
49 | 90 | case ARM64_REG_X12: return ARM64_REG_W12; |
50 | 188 | case ARM64_REG_X13: return ARM64_REG_W13; |
51 | 92 | case ARM64_REG_X14: return ARM64_REG_W14; |
52 | 107 | case ARM64_REG_X15: return ARM64_REG_W15; |
53 | 39 | case ARM64_REG_X16: return ARM64_REG_W16; |
54 | 56 | case ARM64_REG_X17: return ARM64_REG_W17; |
55 | 41 | case ARM64_REG_X18: return ARM64_REG_W18; |
56 | 93 | case ARM64_REG_X19: return ARM64_REG_W19; |
57 | 19 | case ARM64_REG_X20: return ARM64_REG_W20; |
58 | 159 | case ARM64_REG_X21: return ARM64_REG_W21; |
59 | 45 | case ARM64_REG_X22: return ARM64_REG_W22; |
60 | 55 | case ARM64_REG_X23: return ARM64_REG_W23; |
61 | 74 | case ARM64_REG_X24: return ARM64_REG_W24; |
62 | 131 | case ARM64_REG_X25: return ARM64_REG_W25; |
63 | 55 | case ARM64_REG_X26: return ARM64_REG_W26; |
64 | 93 | case ARM64_REG_X27: return ARM64_REG_W27; |
65 | 258 | case ARM64_REG_X28: return ARM64_REG_W28; |
66 | 47 | case ARM64_REG_FP: return ARM64_REG_W29; |
67 | 138 | case ARM64_REG_LR: return ARM64_REG_W30; |
68 | 0 | case ARM64_REG_SP: return ARM64_REG_WSP; |
69 | 70 | case ARM64_REG_XZR: return ARM64_REG_WZR; |
70 | 4.75k | } |
71 | | |
72 | | // For anything else, return it unchanged. |
73 | 140 | return Reg; |
74 | 4.75k | } Unexecuted instantiation: AArch64Disassembler.c:getWRegFromXReg AArch64InstPrinter.c:getWRegFromXReg Line | Count | Source | 34 | 4.75k | { | 35 | 4.75k | switch (Reg) { | 36 | 140 | default: break; | 37 | 383 | case ARM64_REG_X0: return ARM64_REG_W0; | 38 | 330 | case ARM64_REG_X1: return ARM64_REG_W1; | 39 | 306 | case ARM64_REG_X2: return ARM64_REG_W2; | 40 | 467 | case ARM64_REG_X3: return ARM64_REG_W3; | 41 | 34 | case ARM64_REG_X4: return ARM64_REG_W4; | 42 | 233 | case ARM64_REG_X5: return ARM64_REG_W5; | 43 | 268 | case ARM64_REG_X6: return ARM64_REG_W6; | 44 | 340 | case ARM64_REG_X7: return ARM64_REG_W7; | 45 | 59 | case ARM64_REG_X8: return ARM64_REG_W8; | 46 | 89 | case ARM64_REG_X9: return ARM64_REG_W9; | 47 | 117 | case ARM64_REG_X10: return ARM64_REG_W10; | 48 | 139 | case ARM64_REG_X11: return ARM64_REG_W11; | 49 | 90 | case ARM64_REG_X12: return ARM64_REG_W12; | 50 | 188 | case ARM64_REG_X13: return ARM64_REG_W13; | 51 | 92 | case ARM64_REG_X14: return ARM64_REG_W14; | 52 | 107 | case ARM64_REG_X15: return ARM64_REG_W15; | 53 | 39 | case ARM64_REG_X16: return ARM64_REG_W16; | 54 | 56 | case ARM64_REG_X17: return ARM64_REG_W17; | 55 | 41 | case ARM64_REG_X18: return ARM64_REG_W18; | 56 | 93 | case ARM64_REG_X19: return ARM64_REG_W19; | 57 | 19 | case ARM64_REG_X20: return ARM64_REG_W20; | 58 | 159 | case ARM64_REG_X21: return ARM64_REG_W21; | 59 | 45 | case ARM64_REG_X22: return ARM64_REG_W22; | 60 | 55 | case ARM64_REG_X23: return ARM64_REG_W23; | 61 | 74 | case ARM64_REG_X24: return ARM64_REG_W24; | 62 | 131 | case ARM64_REG_X25: return ARM64_REG_W25; | 63 | 55 | case ARM64_REG_X26: return ARM64_REG_W26; | 64 | 93 | case ARM64_REG_X27: return ARM64_REG_W27; | 65 | 258 | case ARM64_REG_X28: return ARM64_REG_W28; | 66 | 47 | case ARM64_REG_FP: return ARM64_REG_W29; | 67 | 138 | case ARM64_REG_LR: return ARM64_REG_W30; | 68 | 0 | case ARM64_REG_SP: return ARM64_REG_WSP; | 69 | 70 | case ARM64_REG_XZR: return ARM64_REG_WZR; | 70 | 4.75k | } | 71 | | | 72 | | // For anything else, return it unchanged. | 73 | 140 | return Reg; | 74 | 4.75k | } |
Unexecuted instantiation: AArch64BaseInfo.c:getWRegFromXReg |
75 | | |
76 | | inline static unsigned getXRegFromWReg(unsigned Reg) |
77 | 0 | { |
78 | 0 | switch (Reg) { |
79 | 0 | case ARM64_REG_W0: return ARM64_REG_X0; |
80 | 0 | case ARM64_REG_W1: return ARM64_REG_X1; |
81 | 0 | case ARM64_REG_W2: return ARM64_REG_X2; |
82 | 0 | case ARM64_REG_W3: return ARM64_REG_X3; |
83 | 0 | case ARM64_REG_W4: return ARM64_REG_X4; |
84 | 0 | case ARM64_REG_W5: return ARM64_REG_X5; |
85 | 0 | case ARM64_REG_W6: return ARM64_REG_X6; |
86 | 0 | case ARM64_REG_W7: return ARM64_REG_X7; |
87 | 0 | case ARM64_REG_W8: return ARM64_REG_X8; |
88 | 0 | case ARM64_REG_W9: return ARM64_REG_X9; |
89 | 0 | case ARM64_REG_W10: return ARM64_REG_X10; |
90 | 0 | case ARM64_REG_W11: return ARM64_REG_X11; |
91 | 0 | case ARM64_REG_W12: return ARM64_REG_X12; |
92 | 0 | case ARM64_REG_W13: return ARM64_REG_X13; |
93 | 0 | case ARM64_REG_W14: return ARM64_REG_X14; |
94 | 0 | case ARM64_REG_W15: return ARM64_REG_X15; |
95 | 0 | case ARM64_REG_W16: return ARM64_REG_X16; |
96 | 0 | case ARM64_REG_W17: return ARM64_REG_X17; |
97 | 0 | case ARM64_REG_W18: return ARM64_REG_X18; |
98 | 0 | case ARM64_REG_W19: return ARM64_REG_X19; |
99 | 0 | case ARM64_REG_W20: return ARM64_REG_X20; |
100 | 0 | case ARM64_REG_W21: return ARM64_REG_X21; |
101 | 0 | case ARM64_REG_W22: return ARM64_REG_X22; |
102 | 0 | case ARM64_REG_W23: return ARM64_REG_X23; |
103 | 0 | case ARM64_REG_W24: return ARM64_REG_X24; |
104 | 0 | case ARM64_REG_W25: return ARM64_REG_X25; |
105 | 0 | case ARM64_REG_W26: return ARM64_REG_X26; |
106 | 0 | case ARM64_REG_W27: return ARM64_REG_X27; |
107 | 0 | case ARM64_REG_W28: return ARM64_REG_X28; |
108 | 0 | case ARM64_REG_W29: return ARM64_REG_FP; |
109 | 0 | case ARM64_REG_W30: return ARM64_REG_LR; |
110 | 0 | case ARM64_REG_WSP: return ARM64_REG_SP; |
111 | 0 | case ARM64_REG_WZR: return ARM64_REG_XZR; |
112 | 0 | } |
113 | 0 |
|
114 | 0 | // For anything else, return it unchanged. |
115 | 0 | return Reg; |
116 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:getXRegFromWReg Unexecuted instantiation: AArch64InstPrinter.c:getXRegFromWReg Unexecuted instantiation: AArch64BaseInfo.c:getXRegFromWReg |
117 | | |
118 | | inline static unsigned getBRegFromDReg(unsigned Reg) |
119 | 0 | { |
120 | 0 | switch (Reg) { |
121 | 0 | case ARM64_REG_D0: return ARM64_REG_B0; |
122 | 0 | case ARM64_REG_D1: return ARM64_REG_B1; |
123 | 0 | case ARM64_REG_D2: return ARM64_REG_B2; |
124 | 0 | case ARM64_REG_D3: return ARM64_REG_B3; |
125 | 0 | case ARM64_REG_D4: return ARM64_REG_B4; |
126 | 0 | case ARM64_REG_D5: return ARM64_REG_B5; |
127 | 0 | case ARM64_REG_D6: return ARM64_REG_B6; |
128 | 0 | case ARM64_REG_D7: return ARM64_REG_B7; |
129 | 0 | case ARM64_REG_D8: return ARM64_REG_B8; |
130 | 0 | case ARM64_REG_D9: return ARM64_REG_B9; |
131 | 0 | case ARM64_REG_D10: return ARM64_REG_B10; |
132 | 0 | case ARM64_REG_D11: return ARM64_REG_B11; |
133 | 0 | case ARM64_REG_D12: return ARM64_REG_B12; |
134 | 0 | case ARM64_REG_D13: return ARM64_REG_B13; |
135 | 0 | case ARM64_REG_D14: return ARM64_REG_B14; |
136 | 0 | case ARM64_REG_D15: return ARM64_REG_B15; |
137 | 0 | case ARM64_REG_D16: return ARM64_REG_B16; |
138 | 0 | case ARM64_REG_D17: return ARM64_REG_B17; |
139 | 0 | case ARM64_REG_D18: return ARM64_REG_B18; |
140 | 0 | case ARM64_REG_D19: return ARM64_REG_B19; |
141 | 0 | case ARM64_REG_D20: return ARM64_REG_B20; |
142 | 0 | case ARM64_REG_D21: return ARM64_REG_B21; |
143 | 0 | case ARM64_REG_D22: return ARM64_REG_B22; |
144 | 0 | case ARM64_REG_D23: return ARM64_REG_B23; |
145 | 0 | case ARM64_REG_D24: return ARM64_REG_B24; |
146 | 0 | case ARM64_REG_D25: return ARM64_REG_B25; |
147 | 0 | case ARM64_REG_D26: return ARM64_REG_B26; |
148 | 0 | case ARM64_REG_D27: return ARM64_REG_B27; |
149 | 0 | case ARM64_REG_D28: return ARM64_REG_B28; |
150 | 0 | case ARM64_REG_D29: return ARM64_REG_B29; |
151 | 0 | case ARM64_REG_D30: return ARM64_REG_B30; |
152 | 0 | case ARM64_REG_D31: return ARM64_REG_B31; |
153 | 0 | } |
154 | 0 |
|
155 | 0 | // For anything else, return it unchanged. |
156 | 0 | return Reg; |
157 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:getBRegFromDReg Unexecuted instantiation: AArch64InstPrinter.c:getBRegFromDReg Unexecuted instantiation: AArch64BaseInfo.c:getBRegFromDReg |
158 | | |
159 | | inline static unsigned getDRegFromBReg(unsigned Reg) |
160 | 0 | { |
161 | 0 | switch (Reg) { |
162 | 0 | case ARM64_REG_B0: return ARM64_REG_D0; |
163 | 0 | case ARM64_REG_B1: return ARM64_REG_D1; |
164 | 0 | case ARM64_REG_B2: return ARM64_REG_D2; |
165 | 0 | case ARM64_REG_B3: return ARM64_REG_D3; |
166 | 0 | case ARM64_REG_B4: return ARM64_REG_D4; |
167 | 0 | case ARM64_REG_B5: return ARM64_REG_D5; |
168 | 0 | case ARM64_REG_B6: return ARM64_REG_D6; |
169 | 0 | case ARM64_REG_B7: return ARM64_REG_D7; |
170 | 0 | case ARM64_REG_B8: return ARM64_REG_D8; |
171 | 0 | case ARM64_REG_B9: return ARM64_REG_D9; |
172 | 0 | case ARM64_REG_B10: return ARM64_REG_D10; |
173 | 0 | case ARM64_REG_B11: return ARM64_REG_D11; |
174 | 0 | case ARM64_REG_B12: return ARM64_REG_D12; |
175 | 0 | case ARM64_REG_B13: return ARM64_REG_D13; |
176 | 0 | case ARM64_REG_B14: return ARM64_REG_D14; |
177 | 0 | case ARM64_REG_B15: return ARM64_REG_D15; |
178 | 0 | case ARM64_REG_B16: return ARM64_REG_D16; |
179 | 0 | case ARM64_REG_B17: return ARM64_REG_D17; |
180 | 0 | case ARM64_REG_B18: return ARM64_REG_D18; |
181 | 0 | case ARM64_REG_B19: return ARM64_REG_D19; |
182 | 0 | case ARM64_REG_B20: return ARM64_REG_D20; |
183 | 0 | case ARM64_REG_B21: return ARM64_REG_D21; |
184 | 0 | case ARM64_REG_B22: return ARM64_REG_D22; |
185 | 0 | case ARM64_REG_B23: return ARM64_REG_D23; |
186 | 0 | case ARM64_REG_B24: return ARM64_REG_D24; |
187 | 0 | case ARM64_REG_B25: return ARM64_REG_D25; |
188 | 0 | case ARM64_REG_B26: return ARM64_REG_D26; |
189 | 0 | case ARM64_REG_B27: return ARM64_REG_D27; |
190 | 0 | case ARM64_REG_B28: return ARM64_REG_D28; |
191 | 0 | case ARM64_REG_B29: return ARM64_REG_D29; |
192 | 0 | case ARM64_REG_B30: return ARM64_REG_D30; |
193 | 0 | case ARM64_REG_B31: return ARM64_REG_D31; |
194 | 0 | } |
195 | 0 |
|
196 | 0 | // For anything else, return it unchanged. |
197 | 0 | return Reg; |
198 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:getDRegFromBReg Unexecuted instantiation: AArch64InstPrinter.c:getDRegFromBReg Unexecuted instantiation: AArch64BaseInfo.c:getDRegFromBReg |
199 | | |
200 | | // // Enums corresponding to AArch64 condition codes |
201 | | // The CondCodes constants map directly to the 4-bit encoding of the |
202 | | // condition field for predicated instructions. |
203 | | typedef enum AArch64CC_CondCode { // Meaning (integer) Meaning (floating-point) |
204 | | AArch64CC_EQ = 0x0, // Equal Equal |
205 | | AArch64CC_NE = 0x1, // Not equal Not equal, or unordered |
206 | | AArch64CC_HS = 0x2, // Unsigned higher or same >, ==, or unordered |
207 | | AArch64CC_LO = 0x3, // Unsigned lower Less than |
208 | | AArch64CC_MI = 0x4, // Minus, negative Less than |
209 | | AArch64CC_PL = 0x5, // Plus, positive or zero >, ==, or unordered |
210 | | AArch64CC_VS = 0x6, // Overflow Unordered |
211 | | AArch64CC_VC = 0x7, // No overflow Not unordered |
212 | | AArch64CC_HI = 0x8, // Unsigned higher Greater than, or unordered |
213 | | AArch64CC_LS = 0x9, // Unsigned lower or same Less than or equal |
214 | | AArch64CC_GE = 0xa, // Greater than or equal Greater than or equal |
215 | | AArch64CC_LT = 0xb, // Less than Less than, or unordered |
216 | | AArch64CC_GT = 0xc, // Greater than Greater than |
217 | | AArch64CC_LE = 0xd, // Less than or equal <, ==, or unordered |
218 | | AArch64CC_AL = 0xe, // Always (unconditional) Always (unconditional) |
219 | | AArch64CC_NV = 0xf, // Always (unconditional) Always (unconditional) |
220 | | // Note the NV exists purely to disassemble 0b1111. Execution is "always". |
221 | | AArch64CC_Invalid |
222 | | } AArch64CC_CondCode; |
223 | | |
224 | | inline static AArch64CC_CondCode getInvertedCondCode(AArch64CC_CondCode Code) |
225 | 632 | { |
226 | | // To reverse a condition it's necessary to only invert the low bit: |
227 | 632 | return (AArch64CC_CondCode)((unsigned)Code ^ 0x1); |
228 | 632 | } Unexecuted instantiation: AArch64Disassembler.c:getInvertedCondCode AArch64InstPrinter.c:getInvertedCondCode Line | Count | Source | 225 | 632 | { | 226 | | // To reverse a condition it's necessary to only invert the low bit: | 227 | 632 | return (AArch64CC_CondCode)((unsigned)Code ^ 0x1); | 228 | 632 | } |
Unexecuted instantiation: AArch64BaseInfo.c:getInvertedCondCode |
229 | | |
230 | | inline static const char *getCondCodeName(AArch64CC_CondCode CC) |
231 | 2.48k | { |
232 | 2.48k | switch (CC) { |
233 | 0 | default: return NULL; // never reach |
234 | 441 | case AArch64CC_EQ: return "eq"; |
235 | 160 | case AArch64CC_NE: return "ne"; |
236 | 392 | case AArch64CC_HS: return "hs"; |
237 | 77 | case AArch64CC_LO: return "lo"; |
238 | 281 | case AArch64CC_MI: return "mi"; |
239 | 218 | case AArch64CC_PL: return "pl"; |
240 | 105 | case AArch64CC_VS: return "vs"; |
241 | 66 | case AArch64CC_VC: return "vc"; |
242 | 94 | case AArch64CC_HI: return "hi"; |
243 | 23 | case AArch64CC_LS: return "ls"; |
244 | 79 | case AArch64CC_GE: return "ge"; |
245 | 30 | case AArch64CC_LT: return "lt"; |
246 | 220 | case AArch64CC_GT: return "gt"; |
247 | 173 | case AArch64CC_LE: return "le"; |
248 | 37 | case AArch64CC_AL: return "al"; |
249 | 92 | case AArch64CC_NV: return "nv"; |
250 | 2.48k | } |
251 | 2.48k | } Unexecuted instantiation: AArch64Disassembler.c:getCondCodeName AArch64InstPrinter.c:getCondCodeName Line | Count | Source | 231 | 2.48k | { | 232 | 2.48k | switch (CC) { | 233 | 0 | default: return NULL; // never reach | 234 | 441 | case AArch64CC_EQ: return "eq"; | 235 | 160 | case AArch64CC_NE: return "ne"; | 236 | 392 | case AArch64CC_HS: return "hs"; | 237 | 77 | case AArch64CC_LO: return "lo"; | 238 | 281 | case AArch64CC_MI: return "mi"; | 239 | 218 | case AArch64CC_PL: return "pl"; | 240 | 105 | case AArch64CC_VS: return "vs"; | 241 | 66 | case AArch64CC_VC: return "vc"; | 242 | 94 | case AArch64CC_HI: return "hi"; | 243 | 23 | case AArch64CC_LS: return "ls"; | 244 | 79 | case AArch64CC_GE: return "ge"; | 245 | 30 | case AArch64CC_LT: return "lt"; | 246 | 220 | case AArch64CC_GT: return "gt"; | 247 | 173 | case AArch64CC_LE: return "le"; | 248 | 37 | case AArch64CC_AL: return "al"; | 249 | 92 | case AArch64CC_NV: return "nv"; | 250 | 2.48k | } | 251 | 2.48k | } |
Unexecuted instantiation: AArch64BaseInfo.c:getCondCodeName |
252 | | |
253 | | /// Given a condition code, return NZCV flags that would satisfy that condition. |
254 | | /// The flag bits are in the format expected by the ccmp instructions. |
255 | | /// Note that many different flag settings can satisfy a given condition code, |
256 | | /// this function just returns one of them. |
257 | | inline static unsigned getNZCVToSatisfyCondCode(AArch64CC_CondCode Code) |
258 | 0 | { |
259 | 0 | // NZCV flags encoded as expected by ccmp instructions, ARMv8 ISA 5.5.7. |
260 | 0 | enum { N = 8, Z = 4, C = 2, V = 1 }; |
261 | 0 | switch (Code) { |
262 | 0 | default: // llvm_unreachable("Unknown condition code"); |
263 | 0 | case AArch64CC_EQ: return Z; // Z == 1 |
264 | 0 | case AArch64CC_NE: return 0; // Z == 0 |
265 | 0 | case AArch64CC_HS: return C; // C == 1 |
266 | 0 | case AArch64CC_LO: return 0; // C == 0 |
267 | 0 | case AArch64CC_MI: return N; // N == 1 |
268 | 0 | case AArch64CC_PL: return 0; // N == 0 |
269 | 0 | case AArch64CC_VS: return V; // V == 1 |
270 | 0 | case AArch64CC_VC: return 0; // V == 0 |
271 | 0 | case AArch64CC_HI: return C; // C == 1 && Z == 0 |
272 | 0 | case AArch64CC_LS: return 0; // C == 0 || Z == 1 |
273 | 0 | case AArch64CC_GE: return 0; // N == V |
274 | 0 | case AArch64CC_LT: return N; // N != V |
275 | 0 | case AArch64CC_GT: return 0; // Z == 0 && N == V |
276 | 0 | case AArch64CC_LE: return Z; // Z == 1 || N != V |
277 | 0 | } |
278 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:getNZCVToSatisfyCondCode Unexecuted instantiation: AArch64InstPrinter.c:getNZCVToSatisfyCondCode Unexecuted instantiation: AArch64BaseInfo.c:getNZCVToSatisfyCondCode |
279 | | |
280 | | /// Instances of this class can perform bidirectional mapping from random |
281 | | /// identifier strings to operand encodings. For example "MSR" takes a named |
282 | | /// system-register which must be encoded somehow and decoded for printing. This |
283 | | /// central location means that the information for those transformations is not |
284 | | /// duplicated and remains in sync. |
285 | | /// |
286 | | /// FIXME: currently the algorithm is a completely unoptimised linear |
287 | | /// search. Obviously this could be improved, but we would probably want to work |
288 | | /// out just how often these instructions are emitted before working on it. It |
289 | | /// might even be optimal to just reorder the tables for the common instructions |
290 | | /// rather than changing the algorithm. |
291 | | typedef struct A64NamedImmMapper_Mapping { |
292 | | const char *Name; |
293 | | uint32_t Value; |
294 | | } A64NamedImmMapper_Mapping; |
295 | | |
296 | | typedef struct A64NamedImmMapper { |
297 | | const A64NamedImmMapper_Mapping *Pairs; |
298 | | size_t NumPairs; |
299 | | uint32_t TooBigImm; |
300 | | } A64NamedImmMapper; |
301 | | |
302 | | typedef struct A64SysRegMapper { |
303 | | const A64NamedImmMapper_Mapping *SysRegPairs; |
304 | | const A64NamedImmMapper_Mapping *InstPairs; |
305 | | size_t NumInstPairs; |
306 | | } A64SysRegMapper; |
307 | | |
308 | | typedef enum A64SE_ShiftExtSpecifiers { |
309 | | A64SE_Invalid = -1, |
310 | | A64SE_LSL, |
311 | | A64SE_MSL, |
312 | | A64SE_LSR, |
313 | | A64SE_ASR, |
314 | | A64SE_ROR, |
315 | | |
316 | | A64SE_UXTB, |
317 | | A64SE_UXTH, |
318 | | A64SE_UXTW, |
319 | | A64SE_UXTX, |
320 | | |
321 | | A64SE_SXTB, |
322 | | A64SE_SXTH, |
323 | | A64SE_SXTW, |
324 | | A64SE_SXTX |
325 | | } A64SE_ShiftExtSpecifiers; |
326 | | |
327 | | typedef enum A64Layout_VectorLayout { |
328 | | A64Layout_Invalid = -1, |
329 | | A64Layout_VL_8B, |
330 | | A64Layout_VL_4H, |
331 | | A64Layout_VL_2S, |
332 | | A64Layout_VL_1D, |
333 | | |
334 | | A64Layout_VL_16B, |
335 | | A64Layout_VL_8H, |
336 | | A64Layout_VL_4S, |
337 | | A64Layout_VL_2D, |
338 | | |
339 | | // Bare layout for the 128-bit vector |
340 | | // (only show ".b", ".h", ".s", ".d" without vector number) |
341 | | A64Layout_VL_B, |
342 | | A64Layout_VL_H, |
343 | | A64Layout_VL_S, |
344 | | A64Layout_VL_D |
345 | | } A64Layout_VectorLayout; |
346 | | |
347 | | inline static const char * |
348 | | AArch64VectorLayoutToString(A64Layout_VectorLayout Layout) |
349 | 0 | { |
350 | 0 | switch (Layout) { |
351 | 0 | default: return NULL; // never reach |
352 | 0 | case A64Layout_VL_8B: return ".8b"; |
353 | 0 | case A64Layout_VL_4H: return ".4h"; |
354 | 0 | case A64Layout_VL_2S: return ".2s"; |
355 | 0 | case A64Layout_VL_1D: return ".1d"; |
356 | 0 | case A64Layout_VL_16B: return ".16b"; |
357 | 0 | case A64Layout_VL_8H: return ".8h"; |
358 | 0 | case A64Layout_VL_4S: return ".4s"; |
359 | 0 | case A64Layout_VL_2D: return ".2d"; |
360 | 0 | case A64Layout_VL_B: return ".b"; |
361 | 0 | case A64Layout_VL_H: return ".h"; |
362 | 0 | case A64Layout_VL_S: return ".s"; |
363 | 0 | case A64Layout_VL_D: return ".d"; |
364 | 0 | } |
365 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64VectorLayoutToString Unexecuted instantiation: AArch64InstPrinter.c:AArch64VectorLayoutToString Unexecuted instantiation: AArch64BaseInfo.c:AArch64VectorLayoutToString |
366 | | |
367 | | inline static A64Layout_VectorLayout |
368 | | AArch64StringToVectorLayout(char *LayoutStr) |
369 | 0 | { |
370 | 0 | if (!strcmp(LayoutStr, ".8b")) |
371 | 0 | return A64Layout_VL_8B; |
372 | 0 |
|
373 | 0 | if (!strcmp(LayoutStr, ".4h")) |
374 | 0 | return A64Layout_VL_4H; |
375 | 0 |
|
376 | 0 | if (!strcmp(LayoutStr, ".2s")) |
377 | 0 | return A64Layout_VL_2S; |
378 | 0 |
|
379 | 0 | if (!strcmp(LayoutStr, ".1d")) |
380 | 0 | return A64Layout_VL_1D; |
381 | 0 |
|
382 | 0 | if (!strcmp(LayoutStr, ".16b")) |
383 | 0 | return A64Layout_VL_16B; |
384 | 0 |
|
385 | 0 | if (!strcmp(LayoutStr, ".8h")) |
386 | 0 | return A64Layout_VL_8H; |
387 | 0 |
|
388 | 0 | if (!strcmp(LayoutStr, ".4s")) |
389 | 0 | return A64Layout_VL_4S; |
390 | 0 |
|
391 | 0 | if (!strcmp(LayoutStr, ".2d")) |
392 | 0 | return A64Layout_VL_2D; |
393 | 0 |
|
394 | 0 | if (!strcmp(LayoutStr, ".b")) |
395 | 0 | return A64Layout_VL_B; |
396 | 0 |
|
397 | 0 | if (!strcmp(LayoutStr, ".s")) |
398 | 0 | return A64Layout_VL_S; |
399 | 0 |
|
400 | 0 | if (!strcmp(LayoutStr, ".d")) |
401 | 0 | return A64Layout_VL_D; |
402 | 0 |
|
403 | 0 | return A64Layout_Invalid; |
404 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64StringToVectorLayout Unexecuted instantiation: AArch64InstPrinter.c:AArch64StringToVectorLayout Unexecuted instantiation: AArch64BaseInfo.c:AArch64StringToVectorLayout |
405 | | |
406 | | /// Target Operand Flag enum. |
407 | | enum TOF { |
408 | | //===------------------------------------------------------------------===// |
409 | | // AArch64 Specific MachineOperand flags. |
410 | | |
411 | | MO_NO_FLAG, |
412 | | |
413 | | MO_FRAGMENT = 0xf, |
414 | | |
415 | | /// MO_PAGE - A symbol operand with this flag represents the pc-relative |
416 | | /// offset of the 4K page containing the symbol. This is used with the |
417 | | /// ADRP instruction. |
418 | | MO_PAGE = 1, |
419 | | |
420 | | /// MO_PAGEOFF - A symbol operand with this flag represents the offset of |
421 | | /// that symbol within a 4K page. This offset is added to the page address |
422 | | /// to produce the complete address. |
423 | | MO_PAGEOFF = 2, |
424 | | |
425 | | /// MO_G3 - A symbol operand with this flag (granule 3) represents the high |
426 | | /// 16-bits of a 64-bit address, used in a MOVZ or MOVK instruction |
427 | | MO_G3 = 3, |
428 | | |
429 | | /// MO_G2 - A symbol operand with this flag (granule 2) represents the bits |
430 | | /// 32-47 of a 64-bit address, used in a MOVZ or MOVK instruction |
431 | | MO_G2 = 4, |
432 | | |
433 | | /// MO_G1 - A symbol operand with this flag (granule 1) represents the bits |
434 | | /// 16-31 of a 64-bit address, used in a MOVZ or MOVK instruction |
435 | | MO_G1 = 5, |
436 | | |
437 | | /// MO_G0 - A symbol operand with this flag (granule 0) represents the bits |
438 | | /// 0-15 of a 64-bit address, used in a MOVZ or MOVK instruction |
439 | | MO_G0 = 6, |
440 | | |
441 | | /// MO_HI12 - This flag indicates that a symbol operand represents the bits |
442 | | /// 13-24 of a 64-bit address, used in a arithmetic immediate-shifted-left- |
443 | | /// by-12-bits instruction. |
444 | | MO_HI12 = 7, |
445 | | |
446 | | /// MO_GOT - This flag indicates that a symbol operand represents the |
447 | | /// address of the GOT entry for the symbol, rather than the address of |
448 | | /// the symbol itself. |
449 | | MO_GOT = 0x10, |
450 | | |
451 | | /// MO_NC - Indicates whether the linker is expected to check the symbol |
452 | | /// reference for overflow. For example in an ADRP/ADD pair of relocations |
453 | | /// the ADRP usually does check, but not the ADD. |
454 | | MO_NC = 0x20, |
455 | | |
456 | | /// MO_TLS - Indicates that the operand being accessed is some kind of |
457 | | /// thread-local symbol. On Darwin, only one type of thread-local access |
458 | | /// exists (pre linker-relaxation), but on ELF the TLSModel used for the |
459 | | /// referee will affect interpretation. |
460 | | MO_TLS = 0x40, |
461 | | |
462 | | /// MO_DLLIMPORT - On a symbol operand, this represents that the reference |
463 | | /// to the symbol is for an import stub. This is used for DLL import |
464 | | /// storage class indication on Windows. |
465 | | MO_DLLIMPORT = 0x80, |
466 | | }; |
467 | | |
468 | | typedef struct SysAlias { |
469 | | const char *Name; |
470 | | uint16_t Encoding; |
471 | | } SysAlias; |
472 | | |
473 | 1.42k | #define AT SysAlias |
474 | 621 | #define DB SysAlias |
475 | 1.80k | #define DC SysAlias |
476 | | #define SVEPRFM SysAlias |
477 | 7.46k | #define PRFM SysAlias |
478 | 964 | #define PSB SysAlias |
479 | 7 | #define ISB SysAlias |
480 | 0 | #define TSB SysAlias |
481 | 692 | #define PState SysAlias |
482 | | #define SVEPREDPAT SysAlias |
483 | | #define SVCR SysAlias |
484 | 280 | #define BTI SysAlias |
485 | | |
486 | | typedef struct SysAliasReg { |
487 | | const char *Name; |
488 | | uint16_t Encoding; |
489 | | bool NeedsReg; |
490 | | } SysAliasReg; |
491 | | |
492 | 721 | #define IC SysAliasReg |
493 | 372 | #define TLBI SysAliasReg |
494 | | |
495 | | typedef struct SysAliasSysReg { |
496 | | const char *Name; |
497 | | uint16_t Encoding; |
498 | | bool Readable; |
499 | | bool Writeable; |
500 | | } SysAliasSysReg; |
501 | | |
502 | | #define SysReg SysAliasSysReg |
503 | | |
504 | | typedef struct SysAliasImm { |
505 | | const char *Name; |
506 | | uint16_t Encoding; |
507 | | uint16_t ImmValue; |
508 | | } SysAliasImm; |
509 | | |
510 | | #define DBnXS SysAliasImm |
511 | | |
512 | | typedef struct ExactFPImm { |
513 | | const char *Name; |
514 | | int Enum; |
515 | | const char *Repr; |
516 | | } ExactFPImm; |
517 | | |
518 | | const AT *lookupATByEncoding(uint16_t Encoding); |
519 | | const DB *lookupDBByEncoding(uint16_t Encoding); |
520 | | const DC *lookupDCByEncoding(uint16_t Encoding); |
521 | | const IC *lookupICByEncoding(uint16_t Encoding); |
522 | | const TLBI *lookupTLBIByEncoding(uint16_t Encoding); |
523 | | const SVEPRFM *lookupSVEPRFMByEncoding(uint16_t Encoding); |
524 | | const PRFM *lookupPRFMByEncoding(uint16_t Encoding); |
525 | | const PSB *lookupPSBByEncoding(uint16_t Encoding); |
526 | | const ISB *lookupISBByEncoding(uint16_t Encoding); |
527 | | const TSB *lookupTSBByEncoding(uint16_t Encoding); |
528 | | const SysReg *lookupSysRegByEncoding(uint16_t Encoding); |
529 | | const PState *lookupPStateByEncoding(uint16_t Encoding); |
530 | | const SVEPREDPAT *lookupSVEPREDPATByEncoding(uint16_t Encoding); |
531 | | const ExactFPImm *lookupExactFPImmByEnum(uint16_t Encoding); |
532 | | const SVCR *lookupSVCRByEncoding(uint8_t Encoding); |
533 | | const BTI *lookupBTIByEncoding(uint8_t Encoding); |
534 | | const DBnXS *lookupDBnXSByEncoding(uint8_t Encoding); |
535 | | |
536 | | // NOTE: result must be 128 bytes to contain the result |
537 | | void AArch64SysReg_genericRegisterString(uint32_t Bits, char *result); |
538 | | |
539 | | // --------------------------------------------------------------------------- |
540 | | // The following Structs and Enum are taken from MCInstPrinter.h in llvm. |
541 | | // These are required for the updated printAliasInstr() function in |
542 | | // $ARCHGenAsmWriter.inc |
543 | | |
544 | | /// Map from opcode to pattern list by binary search. |
545 | | typedef struct PatternsForOpcode { |
546 | | uint32_t Opcode; |
547 | | uint16_t PatternStart; |
548 | | uint16_t NumPatterns; |
549 | | } PatternsForOpcode; |
550 | | |
551 | | /// Data for each alias pattern. Includes feature bits, string, number of |
552 | | /// operands, and a variadic list of conditions to check. |
553 | | typedef struct AliasPattern { |
554 | | uint32_t AsmStrOffset; |
555 | | uint32_t AliasCondStart; |
556 | | uint8_t NumOperands; |
557 | | uint8_t NumConds; |
558 | | } AliasPattern; |
559 | | |
560 | | enum CondKind { |
561 | | AliasPatternCond_K_Feature, // Match only if a feature is enabled. |
562 | | AliasPatternCond_K_NegFeature, // Match only if a feature is disabled. |
563 | | AliasPatternCond_K_OrFeature, // Match only if one of a set of features is |
564 | | // enabled. |
565 | | AliasPatternCond_K_OrNegFeature, // Match only if one of a set of features is |
566 | | // disabled. |
567 | | AliasPatternCond_K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features. |
568 | | AliasPatternCond_K_Ignore, // Match any operand. |
569 | | AliasPatternCond_K_Reg, // Match a specific register. |
570 | | AliasPatternCond_K_TiedReg, // Match another already matched register. |
571 | | AliasPatternCond_K_Imm, // Match a specific immediate. |
572 | | AliasPatternCond_K_RegClass, // Match registers in a class. |
573 | | AliasPatternCond_K_Custom, // Call custom matcher by index. |
574 | | }; |
575 | | |
576 | | typedef struct AliasPatternCond { |
577 | | int Kind; |
578 | | uint32_t Value; |
579 | | } AliasPatternCond; |
580 | | |
581 | | // --------------------------------------------------------------------------- |
582 | | |
583 | | #include "AArch64GenSystemOperands_enum.inc" |
584 | | |
585 | | #endif |