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