/src/capstonev5/arch/AArch64/AArch64AddressingModes.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- AArch64AddressingModes.h - AArch64 Addressing Modes ------*- 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 the AArch64 addressing mode implementation stuff. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef CS_AARCH64_ADDRESSINGMODES_H |
15 | | #define CS_AARCH64_ADDRESSINGMODES_H |
16 | | |
17 | | /* Capstone Disassembly Engine */ |
18 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ |
19 | | |
20 | | #include "../../MathExtras.h" |
21 | | |
22 | | /// AArch64_AM - AArch64 Addressing Mode Stuff |
23 | | |
24 | | //===----------------------------------------------------------------------===// |
25 | | // Shifts |
26 | | // |
27 | | typedef enum AArch64_AM_ShiftExtendType { |
28 | | AArch64_AM_InvalidShiftExtend = -1, |
29 | | AArch64_AM_LSL = 0, |
30 | | AArch64_AM_LSR, |
31 | | AArch64_AM_ASR, |
32 | | AArch64_AM_ROR, |
33 | | AArch64_AM_MSL, |
34 | | |
35 | | AArch64_AM_UXTB, |
36 | | AArch64_AM_UXTH, |
37 | | AArch64_AM_UXTW, |
38 | | AArch64_AM_UXTX, |
39 | | |
40 | | AArch64_AM_SXTB, |
41 | | AArch64_AM_SXTH, |
42 | | AArch64_AM_SXTW, |
43 | | AArch64_AM_SXTX, |
44 | | } AArch64_AM_ShiftExtendType; |
45 | | |
46 | | /// getShiftName - Get the string encoding for the shift type. |
47 | | static inline const char *AArch64_AM_getShiftExtendName(AArch64_AM_ShiftExtendType ST) |
48 | 11.4k | { |
49 | 11.4k | switch (ST) { |
50 | 0 | default: return NULL; // never reach |
51 | 4.38k | case AArch64_AM_LSL: return "lsl"; |
52 | 1.68k | case AArch64_AM_LSR: return "lsr"; |
53 | 1.66k | case AArch64_AM_ASR: return "asr"; |
54 | 1.49k | case AArch64_AM_ROR: return "ror"; |
55 | 331 | case AArch64_AM_MSL: return "msl"; |
56 | 200 | case AArch64_AM_UXTB: return "uxtb"; |
57 | 620 | case AArch64_AM_UXTH: return "uxth"; |
58 | 72 | case AArch64_AM_UXTW: return "uxtw"; |
59 | 377 | case AArch64_AM_UXTX: return "uxtx"; |
60 | 112 | case AArch64_AM_SXTB: return "sxtb"; |
61 | 202 | case AArch64_AM_SXTH: return "sxth"; |
62 | 185 | case AArch64_AM_SXTW: return "sxtw"; |
63 | 116 | case AArch64_AM_SXTX: return "sxtx"; |
64 | 11.4k | } |
65 | 11.4k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getShiftExtendName AArch64InstPrinter.c:AArch64_AM_getShiftExtendName Line | Count | Source | 48 | 11.4k | { | 49 | 11.4k | switch (ST) { | 50 | 0 | default: return NULL; // never reach | 51 | 4.38k | case AArch64_AM_LSL: return "lsl"; | 52 | 1.68k | case AArch64_AM_LSR: return "lsr"; | 53 | 1.66k | case AArch64_AM_ASR: return "asr"; | 54 | 1.49k | case AArch64_AM_ROR: return "ror"; | 55 | 331 | case AArch64_AM_MSL: return "msl"; | 56 | 200 | case AArch64_AM_UXTB: return "uxtb"; | 57 | 620 | case AArch64_AM_UXTH: return "uxth"; | 58 | 72 | case AArch64_AM_UXTW: return "uxtw"; | 59 | 377 | case AArch64_AM_UXTX: return "uxtx"; | 60 | 112 | case AArch64_AM_SXTB: return "sxtb"; | 61 | 202 | case AArch64_AM_SXTH: return "sxth"; | 62 | 185 | case AArch64_AM_SXTW: return "sxtw"; | 63 | 116 | case AArch64_AM_SXTX: return "sxtx"; | 64 | 11.4k | } | 65 | 11.4k | } |
|
66 | | |
67 | | /// getShiftType - Extract the shift type. |
68 | | static inline AArch64_AM_ShiftExtendType AArch64_AM_getShiftType(unsigned Imm) |
69 | 29.5k | { |
70 | 29.5k | switch ((Imm >> 6) & 0x7) { |
71 | 0 | default: return AArch64_AM_InvalidShiftExtend; |
72 | 14.0k | case 0: return AArch64_AM_LSL; |
73 | 5.04k | case 1: return AArch64_AM_LSR; |
74 | 5.00k | case 2: return AArch64_AM_ASR; |
75 | 4.49k | case 3: return AArch64_AM_ROR; |
76 | 993 | case 4: return AArch64_AM_MSL; |
77 | 29.5k | } |
78 | 29.5k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getShiftType AArch64InstPrinter.c:AArch64_AM_getShiftType Line | Count | Source | 69 | 29.5k | { | 70 | 29.5k | switch ((Imm >> 6) & 0x7) { | 71 | 0 | default: return AArch64_AM_InvalidShiftExtend; | 72 | 14.0k | case 0: return AArch64_AM_LSL; | 73 | 5.04k | case 1: return AArch64_AM_LSR; | 74 | 5.00k | case 2: return AArch64_AM_ASR; | 75 | 4.49k | case 3: return AArch64_AM_ROR; | 76 | 993 | case 4: return AArch64_AM_MSL; | 77 | 29.5k | } | 78 | 29.5k | } |
|
79 | | |
80 | | /// getShiftValue - Extract the shift value. |
81 | | static inline unsigned AArch64_AM_getShiftValue(unsigned Imm) |
82 | 30.0k | { |
83 | 30.0k | return Imm & 0x3f; |
84 | 30.0k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getShiftValue AArch64InstPrinter.c:AArch64_AM_getShiftValue Line | Count | Source | 82 | 30.0k | { | 83 | 30.0k | return Imm & 0x3f; | 84 | 30.0k | } |
|
85 | | |
86 | | static inline unsigned AArch64_AM_getShifterImm(AArch64_AM_ShiftExtendType ST, unsigned Imm) |
87 | 0 | { |
88 | 0 | // assert((Imm & 0x3f) == Imm && "Illegal shifted immedate value!"); |
89 | 0 | unsigned STEnc = 0; |
90 | 0 |
|
91 | 0 | switch (ST) { |
92 | 0 | default: // llvm_unreachable("Invalid shift requested"); |
93 | 0 | case AArch64_AM_LSL: STEnc = 0; break; |
94 | 0 | case AArch64_AM_LSR: STEnc = 1; break; |
95 | 0 | case AArch64_AM_ASR: STEnc = 2; break; |
96 | 0 | case AArch64_AM_ROR: STEnc = 3; break; |
97 | 0 | case AArch64_AM_MSL: STEnc = 4; break; |
98 | 0 | } |
99 | 0 |
|
100 | 0 | return (STEnc << 6) | (Imm & 0x3f); |
101 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getShifterImm Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_getShifterImm |
102 | | |
103 | | //===----------------------------------------------------------------------===// |
104 | | // Extends |
105 | | // |
106 | | |
107 | | /// getArithShiftValue - get the arithmetic shift value. |
108 | | static inline unsigned AArch64_AM_getArithShiftValue(unsigned Imm) |
109 | 2.14k | { |
110 | 2.14k | return Imm & 0x7; |
111 | 2.14k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getArithShiftValue AArch64InstPrinter.c:AArch64_AM_getArithShiftValue Line | Count | Source | 109 | 2.14k | { | 110 | 2.14k | return Imm & 0x7; | 111 | 2.14k | } |
|
112 | | |
113 | | /// getExtendType - Extract the extend type for operands of arithmetic ops. |
114 | | static inline AArch64_AM_ShiftExtendType AArch64_AM_getExtendType(unsigned Imm) |
115 | 2.14k | { |
116 | | // assert((Imm & 0x7) == Imm && "invalid immediate!"); |
117 | 2.14k | switch (Imm) { |
118 | 0 | default: // llvm_unreachable("Compiler bug!"); |
119 | 200 | case 0: return AArch64_AM_UXTB; |
120 | 620 | case 1: return AArch64_AM_UXTH; |
121 | 98 | case 2: return AArch64_AM_UXTW; |
122 | 613 | case 3: return AArch64_AM_UXTX; |
123 | 112 | case 4: return AArch64_AM_SXTB; |
124 | 202 | case 5: return AArch64_AM_SXTH; |
125 | 185 | case 6: return AArch64_AM_SXTW; |
126 | 116 | case 7: return AArch64_AM_SXTX; |
127 | 2.14k | } |
128 | 2.14k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getExtendType AArch64InstPrinter.c:AArch64_AM_getExtendType Line | Count | Source | 115 | 2.14k | { | 116 | | // assert((Imm & 0x7) == Imm && "invalid immediate!"); | 117 | 2.14k | switch (Imm) { | 118 | 0 | default: // llvm_unreachable("Compiler bug!"); | 119 | 200 | case 0: return AArch64_AM_UXTB; | 120 | 620 | case 1: return AArch64_AM_UXTH; | 121 | 98 | case 2: return AArch64_AM_UXTW; | 122 | 613 | case 3: return AArch64_AM_UXTX; | 123 | 112 | case 4: return AArch64_AM_SXTB; | 124 | 202 | case 5: return AArch64_AM_SXTH; | 125 | 185 | case 6: return AArch64_AM_SXTW; | 126 | 116 | case 7: return AArch64_AM_SXTX; | 127 | 2.14k | } | 128 | 2.14k | } |
|
129 | | |
130 | | static inline AArch64_AM_ShiftExtendType AArch64_AM_getArithExtendType(unsigned Imm) |
131 | 2.14k | { |
132 | 2.14k | return AArch64_AM_getExtendType((Imm >> 3) & 0x7); |
133 | 2.14k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getArithExtendType AArch64InstPrinter.c:AArch64_AM_getArithExtendType Line | Count | Source | 131 | 2.14k | { | 132 | 2.14k | return AArch64_AM_getExtendType((Imm >> 3) & 0x7); | 133 | 2.14k | } |
|
134 | | |
135 | | /// Mapping from extend bits to required operation: |
136 | | /// shifter: 000 ==> uxtb |
137 | | /// 001 ==> uxth |
138 | | /// 010 ==> uxtw |
139 | | /// 011 ==> uxtx |
140 | | /// 100 ==> sxtb |
141 | | /// 101 ==> sxth |
142 | | /// 110 ==> sxtw |
143 | | /// 111 ==> sxtx |
144 | | static inline unsigned AArch64_AM_getExtendEncoding(AArch64_AM_ShiftExtendType ET) |
145 | 0 | { |
146 | 0 | switch (ET) { |
147 | 0 | default: // llvm_unreachable("Invalid extend type requested"); |
148 | 0 | case AArch64_AM_UXTB: return 0; break; |
149 | 0 | case AArch64_AM_UXTH: return 1; break; |
150 | 0 | case AArch64_AM_UXTW: return 2; break; |
151 | 0 | case AArch64_AM_UXTX: return 3; break; |
152 | 0 | case AArch64_AM_SXTB: return 4; break; |
153 | 0 | case AArch64_AM_SXTH: return 5; break; |
154 | 0 | case AArch64_AM_SXTW: return 6; break; |
155 | 0 | case AArch64_AM_SXTX: return 7; break; |
156 | 0 | } |
157 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getExtendEncoding Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_getExtendEncoding |
158 | | |
159 | | /// getArithExtendImm - Encode the extend type and shift amount for an |
160 | | /// arithmetic instruction: |
161 | | /// imm: 3-bit extend amount |
162 | | /// {5-3} = shifter |
163 | | /// {2-0} = imm3 |
164 | | static inline unsigned AArch64_AM_getArithExtendImm(AArch64_AM_ShiftExtendType ET, unsigned Imm) |
165 | 0 | { |
166 | 0 | // assert((Imm & 0x7) == Imm && "Illegal shifted immedate value!"); |
167 | 0 | return (AArch64_AM_getExtendEncoding(ET) << 3) | (Imm & 0x7); |
168 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getArithExtendImm Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_getArithExtendImm |
169 | | |
170 | | /// getMemDoShift - Extract the "do shift" flag value for load/store |
171 | | /// instructions. |
172 | | static inline bool AArch64_AM_getMemDoShift(unsigned Imm) |
173 | 0 | { |
174 | 0 | return (Imm & 0x1) != 0; |
175 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getMemDoShift Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_getMemDoShift |
176 | | |
177 | | /// getExtendType - Extract the extend type for the offset operand of |
178 | | /// loads/stores. |
179 | | static inline AArch64_AM_ShiftExtendType AArch64_AM_getMemExtendType(unsigned Imm) |
180 | 0 | { |
181 | 0 | return AArch64_AM_getExtendType((Imm >> 1) & 0x7); |
182 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getMemExtendType Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_getMemExtendType |
183 | | |
184 | | static inline uint64_t ror(uint64_t elt, unsigned size) |
185 | 143k | { |
186 | 143k | return ((elt & 1) << (size-1)) | (elt >> 1); |
187 | 143k | } Unexecuted instantiation: AArch64Disassembler.c:ror Line | Count | Source | 185 | 143k | { | 186 | 143k | return ((elt & 1) << (size-1)) | (elt >> 1); | 187 | 143k | } |
|
188 | | |
189 | | /// processLogicalImmediate - Determine if an immediate value can be encoded |
190 | | /// as the immediate operand of a logical instruction for the given register |
191 | | /// size. If so, return true with "encoding" set to the encoded value in |
192 | | /// the form N:immr:imms. |
193 | | static inline bool AArch64_AM_processLogicalImmediate(uint64_t Imm, unsigned RegSize, uint64_t *Encoding) |
194 | 1.93k | { |
195 | 1.93k | unsigned Size, Immr, N; |
196 | 1.93k | uint32_t CTO, I; |
197 | 1.93k | uint64_t Mask, NImms; |
198 | | |
199 | 1.93k | if (Imm == 0ULL || Imm == ~0ULL || |
200 | 1.93k | (RegSize != 64 && (Imm >> RegSize != 0 || Imm == (~0ULL >> (64 - RegSize))))) { |
201 | 0 | return false; |
202 | 0 | } |
203 | | |
204 | | // First, determine the element size. |
205 | 1.93k | Size = RegSize; |
206 | 3.59k | do { |
207 | 3.59k | uint64_t Mask; |
208 | | |
209 | 3.59k | Size /= 2; |
210 | 3.59k | Mask = (1ULL << Size) - 1; |
211 | 3.59k | if ((Imm & Mask) != ((Imm >> Size) & Mask)) { |
212 | 1.93k | Size *= 2; |
213 | 1.93k | break; |
214 | 1.93k | } |
215 | 3.59k | } while (Size > 2); |
216 | | |
217 | | // Second, determine the rotation to make the element be: 0^m 1^n. |
218 | 0 | Mask = ((uint64_t)-1LL) >> (64 - Size); |
219 | 1.93k | Imm &= Mask; |
220 | | |
221 | 1.93k | if (isShiftedMask_64(Imm)) { |
222 | 1.19k | I = CountTrailingZeros_32(Imm); |
223 | | // assert(I < 64 && "undefined behavior"); |
224 | 1.19k | CTO = CountTrailingOnes_32(Imm >> I); |
225 | 1.19k | } else { |
226 | 742 | unsigned CLO; |
227 | | |
228 | 742 | Imm |= ~Mask; |
229 | 742 | if (!isShiftedMask_64(~Imm)) |
230 | 0 | return false; |
231 | | |
232 | 742 | CLO = CountLeadingOnes_32(Imm); |
233 | 742 | I = 64 - CLO; |
234 | 742 | CTO = CLO + CountTrailingOnes_32(Imm) - (64 - Size); |
235 | 742 | } |
236 | | |
237 | | // Encode in Immr the number of RORs it would take to get *from* 0^m 1^n |
238 | | // to our target value, where I is the number of RORs to go the opposite |
239 | | // direction. |
240 | | // assert(Size > I && "I should be smaller than element size"); |
241 | 1.93k | Immr = (Size - I) & (Size - 1); |
242 | | |
243 | | // If size has a 1 in the n'th bit, create a value that has zeroes in |
244 | | // bits [0, n] and ones above that. |
245 | 1.93k | NImms = ~(Size-1) << 1; |
246 | | |
247 | | // Or the CTO value into the low bits, which must be below the Nth bit |
248 | | // bit mentioned above. |
249 | 1.93k | NImms |= (CTO-1); |
250 | | |
251 | | // Extract the seventh bit and toggle it to create the N field. |
252 | 1.93k | N = ((NImms >> 6) & 1) ^ 1; |
253 | | |
254 | 1.93k | *Encoding = (N << 12) | (Immr << 6) | (NImms & 0x3f); |
255 | | |
256 | 1.93k | return true; |
257 | 1.93k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_processLogicalImmediate AArch64InstPrinter.c:AArch64_AM_processLogicalImmediate Line | Count | Source | 194 | 1.93k | { | 195 | 1.93k | unsigned Size, Immr, N; | 196 | 1.93k | uint32_t CTO, I; | 197 | 1.93k | uint64_t Mask, NImms; | 198 | | | 199 | 1.93k | if (Imm == 0ULL || Imm == ~0ULL || | 200 | 1.93k | (RegSize != 64 && (Imm >> RegSize != 0 || Imm == (~0ULL >> (64 - RegSize))))) { | 201 | 0 | return false; | 202 | 0 | } | 203 | | | 204 | | // First, determine the element size. | 205 | 1.93k | Size = RegSize; | 206 | 3.59k | do { | 207 | 3.59k | uint64_t Mask; | 208 | | | 209 | 3.59k | Size /= 2; | 210 | 3.59k | Mask = (1ULL << Size) - 1; | 211 | 3.59k | if ((Imm & Mask) != ((Imm >> Size) & Mask)) { | 212 | 1.93k | Size *= 2; | 213 | 1.93k | break; | 214 | 1.93k | } | 215 | 3.59k | } while (Size > 2); | 216 | | | 217 | | // Second, determine the rotation to make the element be: 0^m 1^n. | 218 | 0 | Mask = ((uint64_t)-1LL) >> (64 - Size); | 219 | 1.93k | Imm &= Mask; | 220 | | | 221 | 1.93k | if (isShiftedMask_64(Imm)) { | 222 | 1.19k | I = CountTrailingZeros_32(Imm); | 223 | | // assert(I < 64 && "undefined behavior"); | 224 | 1.19k | CTO = CountTrailingOnes_32(Imm >> I); | 225 | 1.19k | } else { | 226 | 742 | unsigned CLO; | 227 | | | 228 | 742 | Imm |= ~Mask; | 229 | 742 | if (!isShiftedMask_64(~Imm)) | 230 | 0 | return false; | 231 | | | 232 | 742 | CLO = CountLeadingOnes_32(Imm); | 233 | 742 | I = 64 - CLO; | 234 | 742 | CTO = CLO + CountTrailingOnes_32(Imm) - (64 - Size); | 235 | 742 | } | 236 | | | 237 | | // Encode in Immr the number of RORs it would take to get *from* 0^m 1^n | 238 | | // to our target value, where I is the number of RORs to go the opposite | 239 | | // direction. | 240 | | // assert(Size > I && "I should be smaller than element size"); | 241 | 1.93k | Immr = (Size - I) & (Size - 1); | 242 | | | 243 | | // If size has a 1 in the n'th bit, create a value that has zeroes in | 244 | | // bits [0, n] and ones above that. | 245 | 1.93k | NImms = ~(Size-1) << 1; | 246 | | | 247 | | // Or the CTO value into the low bits, which must be below the Nth bit | 248 | | // bit mentioned above. | 249 | 1.93k | NImms |= (CTO-1); | 250 | | | 251 | | // Extract the seventh bit and toggle it to create the N field. | 252 | 1.93k | N = ((NImms >> 6) & 1) ^ 1; | 253 | | | 254 | 1.93k | *Encoding = (N << 12) | (Immr << 6) | (NImms & 0x3f); | 255 | | | 256 | 1.93k | return true; | 257 | 1.93k | } |
|
258 | | |
259 | | /// isLogicalImmediate - Return true if the immediate is valid for a logical |
260 | | /// immediate instruction of the given register size. Return false otherwise. |
261 | | static inline bool isLogicalImmediate(uint64_t imm, unsigned regSize) |
262 | 1.93k | { |
263 | 1.93k | uint64_t encoding; |
264 | 1.93k | return AArch64_AM_processLogicalImmediate(imm, regSize, &encoding); |
265 | 1.93k | } Unexecuted instantiation: AArch64Disassembler.c:isLogicalImmediate AArch64InstPrinter.c:isLogicalImmediate Line | Count | Source | 262 | 1.93k | { | 263 | 1.93k | uint64_t encoding; | 264 | 1.93k | return AArch64_AM_processLogicalImmediate(imm, regSize, &encoding); | 265 | 1.93k | } |
|
266 | | |
267 | | /// encodeLogicalImmediate - Return the encoded immediate value for a logical |
268 | | /// immediate instruction of the given register size. |
269 | | static inline uint64_t AArch64_AM_encodeLogicalImmediate(uint64_t imm, unsigned regSize) |
270 | 0 | { |
271 | 0 | uint64_t encoding = 0; |
272 | 0 |
|
273 | 0 | bool res = AArch64_AM_processLogicalImmediate(imm, regSize, &encoding); |
274 | 0 | // assert(res && "invalid logical immediate"); |
275 | 0 | (void)res; |
276 | 0 |
|
277 | 0 | return encoding; |
278 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeLogicalImmediate Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeLogicalImmediate |
279 | | |
280 | | /// decodeLogicalImmediate - Decode a logical immediate value in the form |
281 | | /// "N:immr:imms" (where the immr and imms fields are each 6 bits) into the |
282 | | /// integer value it represents with regSize bits. |
283 | | static inline uint64_t AArch64_AM_decodeLogicalImmediate(uint64_t val, unsigned regSize) |
284 | 20.9k | { |
285 | | // Extract the N, imms, and immr fields. |
286 | 20.9k | unsigned N = (val >> 12) & 1; |
287 | 20.9k | unsigned immr = (val >> 6) & 0x3f; |
288 | 20.9k | unsigned imms = val & 0x3f; |
289 | 20.9k | unsigned i, size, R, S; |
290 | 20.9k | uint64_t pattern; |
291 | | |
292 | | // assert((regSize == 64 || N == 0) && "undefined logical immediate encoding"); |
293 | 20.9k | int len = 31 - CountLeadingZeros_32((N << 6) | (~imms & 0x3f)); |
294 | | |
295 | | // assert(len >= 0 && "undefined logical immediate encoding"); |
296 | 20.9k | size = (1 << len); |
297 | 20.9k | R = immr & (size - 1); |
298 | 20.9k | S = imms & (size - 1); |
299 | | |
300 | | // assert(S != size - 1 && "undefined logical immediate encoding"); |
301 | 20.9k | pattern = (1ULL << (S + 1)) - 1; |
302 | | |
303 | 164k | for (i = 0; i < R; ++i) |
304 | 143k | pattern = ror(pattern, size); |
305 | | |
306 | | // Replicate the pattern to fill the regSize. |
307 | 39.4k | while (size != regSize) { |
308 | 18.4k | pattern |= (pattern << size); |
309 | 18.4k | size *= 2; |
310 | 18.4k | } |
311 | | |
312 | 20.9k | return pattern; |
313 | 20.9k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeLogicalImmediate AArch64InstPrinter.c:AArch64_AM_decodeLogicalImmediate Line | Count | Source | 284 | 20.9k | { | 285 | | // Extract the N, imms, and immr fields. | 286 | 20.9k | unsigned N = (val >> 12) & 1; | 287 | 20.9k | unsigned immr = (val >> 6) & 0x3f; | 288 | 20.9k | unsigned imms = val & 0x3f; | 289 | 20.9k | unsigned i, size, R, S; | 290 | 20.9k | uint64_t pattern; | 291 | | | 292 | | // assert((regSize == 64 || N == 0) && "undefined logical immediate encoding"); | 293 | 20.9k | int len = 31 - CountLeadingZeros_32((N << 6) | (~imms & 0x3f)); | 294 | | | 295 | | // assert(len >= 0 && "undefined logical immediate encoding"); | 296 | 20.9k | size = (1 << len); | 297 | 20.9k | R = immr & (size - 1); | 298 | 20.9k | S = imms & (size - 1); | 299 | | | 300 | | // assert(S != size - 1 && "undefined logical immediate encoding"); | 301 | 20.9k | pattern = (1ULL << (S + 1)) - 1; | 302 | | | 303 | 164k | for (i = 0; i < R; ++i) | 304 | 143k | pattern = ror(pattern, size); | 305 | | | 306 | | // Replicate the pattern to fill the regSize. | 307 | 39.4k | while (size != regSize) { | 308 | 18.4k | pattern |= (pattern << size); | 309 | 18.4k | size *= 2; | 310 | 18.4k | } | 311 | | | 312 | 20.9k | return pattern; | 313 | 20.9k | } |
|
314 | | |
315 | | /// isValidDecodeLogicalImmediate - Check to see if the logical immediate value |
316 | | /// in the form "N:immr:imms" (where the immr and imms fields are each 6 bits) |
317 | | /// is a valid encoding for an integer value with regSize bits. |
318 | | static inline bool AArch64_AM_isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize) |
319 | 6.70k | { |
320 | 6.70k | unsigned size, S; |
321 | 6.70k | int len; |
322 | | // Extract the N and imms fields needed for checking. |
323 | 6.70k | unsigned N = (val >> 12) & 1; |
324 | 6.70k | unsigned imms = val & 0x3f; |
325 | | |
326 | 6.70k | if (regSize == 32 && N != 0) // undefined logical immediate encoding |
327 | 0 | return false; |
328 | 6.70k | len = 31 - CountLeadingZeros_32((N << 6) | (~imms & 0x3f)); |
329 | 6.70k | if (len < 0) // undefined logical immediate encoding |
330 | 4 | return false; |
331 | 6.69k | size = (1 << len); |
332 | 6.69k | S = imms & (size - 1); |
333 | 6.69k | if (S == size - 1) // undefined logical immediate encoding |
334 | 5 | return false; |
335 | | |
336 | 6.69k | return true; |
337 | 6.69k | } AArch64Disassembler.c:AArch64_AM_isValidDecodeLogicalImmediate Line | Count | Source | 319 | 6.70k | { | 320 | 6.70k | unsigned size, S; | 321 | 6.70k | int len; | 322 | | // Extract the N and imms fields needed for checking. | 323 | 6.70k | unsigned N = (val >> 12) & 1; | 324 | 6.70k | unsigned imms = val & 0x3f; | 325 | | | 326 | 6.70k | if (regSize == 32 && N != 0) // undefined logical immediate encoding | 327 | 0 | return false; | 328 | 6.70k | len = 31 - CountLeadingZeros_32((N << 6) | (~imms & 0x3f)); | 329 | 6.70k | if (len < 0) // undefined logical immediate encoding | 330 | 4 | return false; | 331 | 6.69k | size = (1 << len); | 332 | 6.69k | S = imms & (size - 1); | 333 | 6.69k | if (S == size - 1) // undefined logical immediate encoding | 334 | 5 | return false; | 335 | | | 336 | 6.69k | return true; | 337 | 6.69k | } |
Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isValidDecodeLogicalImmediate |
338 | | |
339 | | //===----------------------------------------------------------------------===// |
340 | | // Floating-point Immediates |
341 | | // |
342 | | static inline float AArch64_AM_getFPImmFloat(unsigned Imm) |
343 | 1.05k | { |
344 | | // We expect an 8-bit binary encoding of a floating-point number here. |
345 | 1.05k | union { |
346 | 1.05k | uint32_t I; |
347 | 1.05k | float F; |
348 | 1.05k | } FPUnion; |
349 | | |
350 | 1.05k | uint8_t Sign = (Imm >> 7) & 0x1; |
351 | 1.05k | uint8_t Exp = (Imm >> 4) & 0x7; |
352 | 1.05k | uint8_t Mantissa = Imm & 0xf; |
353 | | |
354 | | // 8-bit FP iEEEE Float Encoding |
355 | | // abcd efgh aBbbbbbc defgh000 00000000 00000000 |
356 | | // |
357 | | // where B = NOT(b); |
358 | | |
359 | 1.05k | FPUnion.I = 0; |
360 | 1.05k | FPUnion.I |= ((uint32_t)Sign) << 31; |
361 | 1.05k | FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; |
362 | 1.05k | FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; |
363 | 1.05k | FPUnion.I |= (Exp & 0x3) << 23; |
364 | 1.05k | FPUnion.I |= Mantissa << 19; |
365 | | |
366 | 1.05k | return FPUnion.F; |
367 | 1.05k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_getFPImmFloat AArch64InstPrinter.c:AArch64_AM_getFPImmFloat Line | Count | Source | 343 | 1.05k | { | 344 | | // We expect an 8-bit binary encoding of a floating-point number here. | 345 | 1.05k | union { | 346 | 1.05k | uint32_t I; | 347 | 1.05k | float F; | 348 | 1.05k | } FPUnion; | 349 | | | 350 | 1.05k | uint8_t Sign = (Imm >> 7) & 0x1; | 351 | 1.05k | uint8_t Exp = (Imm >> 4) & 0x7; | 352 | 1.05k | uint8_t Mantissa = Imm & 0xf; | 353 | | | 354 | | // 8-bit FP iEEEE Float Encoding | 355 | | // abcd efgh aBbbbbbc defgh000 00000000 00000000 | 356 | | // | 357 | | // where B = NOT(b); | 358 | | | 359 | 1.05k | FPUnion.I = 0; | 360 | 1.05k | FPUnion.I |= ((uint32_t)Sign) << 31; | 361 | 1.05k | FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; | 362 | 1.05k | FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; | 363 | 1.05k | FPUnion.I |= (Exp & 0x3) << 23; | 364 | 1.05k | FPUnion.I |= Mantissa << 19; | 365 | | | 366 | 1.05k | return FPUnion.F; | 367 | 1.05k | } |
|
368 | | |
369 | | //===--------------------------------------------------------------------===// |
370 | | // AdvSIMD Modified Immediates |
371 | | //===--------------------------------------------------------------------===// |
372 | | |
373 | | // 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh |
374 | | static inline bool AArch64_AM_isAdvSIMDModImmType1(uint64_t Imm) |
375 | 0 | { |
376 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
377 | 0 | ((Imm & 0xffffff00ffffff00ULL) == 0); |
378 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType1 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType1 |
379 | | |
380 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType1(uint64_t Imm) |
381 | 0 | { |
382 | 0 | return (Imm & 0xffULL); |
383 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType1 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType1 |
384 | | |
385 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType1(uint8_t Imm) |
386 | 0 | { |
387 | 0 | uint64_t EncVal = Imm; |
388 | 0 |
|
389 | 0 | return (EncVal << 32) | EncVal; |
390 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType1 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType1 |
391 | | |
392 | | // 0x00 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 |
393 | | static inline bool AArch64_AM_isAdvSIMDModImmType2(uint64_t Imm) |
394 | 0 | { |
395 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
396 | 0 | ((Imm & 0xffff00ffffff00ffULL) == 0); |
397 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType2 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType2 |
398 | | |
399 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType2(uint64_t Imm) |
400 | 0 | { |
401 | 0 | return (Imm & 0xff00ULL) >> 8; |
402 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType2 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType2 |
403 | | |
404 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType2(uint8_t Imm) |
405 | 0 | { |
406 | 0 | uint64_t EncVal = Imm; |
407 | 0 | return (EncVal << 40) | (EncVal << 8); |
408 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType2 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType2 |
409 | | |
410 | | // 0x00 abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 |
411 | | static inline bool AArch64_AM_isAdvSIMDModImmType3(uint64_t Imm) |
412 | 0 | { |
413 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
414 | 0 | ((Imm & 0xff00ffffff00ffffULL) == 0); |
415 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType3 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType3 |
416 | | |
417 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType3(uint64_t Imm) |
418 | 0 | { |
419 | 0 | return (Imm & 0xff0000ULL) >> 16; |
420 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType3 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType3 |
421 | | |
422 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType3(uint8_t Imm) |
423 | 0 | { |
424 | 0 | uint64_t EncVal = Imm; |
425 | 0 | return (EncVal << 48) | (EncVal << 16); |
426 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType3 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType3 |
427 | | |
428 | | // abcdefgh 0x00 0x00 0x00 abcdefgh 0x00 0x00 0x00 |
429 | | static inline bool AArch64_AM_isAdvSIMDModImmType4(uint64_t Imm) |
430 | 0 | { |
431 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
432 | 0 | ((Imm & 0x00ffffff00ffffffULL) == 0); |
433 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType4 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType4 |
434 | | |
435 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType4(uint64_t Imm) |
436 | 0 | { |
437 | 0 | return (Imm & 0xff000000ULL) >> 24; |
438 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType4 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType4 |
439 | | |
440 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType4(uint8_t Imm) |
441 | 0 | { |
442 | 0 | uint64_t EncVal = Imm; |
443 | 0 | return (EncVal << 56) | (EncVal << 24); |
444 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType4 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType4 |
445 | | |
446 | | // 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh |
447 | | static inline bool AArch64_AM_isAdvSIMDModImmType5(uint64_t Imm) |
448 | 0 | { |
449 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
450 | 0 | (((Imm & 0x00ff0000ULL) >> 16) == (Imm & 0x000000ffULL)) && |
451 | 0 | ((Imm & 0xff00ff00ff00ff00ULL) == 0); |
452 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType5 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType5 |
453 | | |
454 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType5(uint64_t Imm) |
455 | 0 | { |
456 | 0 | return (Imm & 0xffULL); |
457 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType5 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType5 |
458 | | |
459 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType5(uint8_t Imm) |
460 | 0 | { |
461 | 0 | uint64_t EncVal = Imm; |
462 | 0 | return (EncVal << 48) | (EncVal << 32) | (EncVal << 16) | EncVal; |
463 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType5 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType5 |
464 | | |
465 | | // abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 abcdefgh 0x00 |
466 | | static inline bool AArch64_AM_isAdvSIMDModImmType6(uint64_t Imm) |
467 | 0 | { |
468 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
469 | 0 | (((Imm & 0xff000000ULL) >> 16) == (Imm & 0x0000ff00ULL)) && |
470 | 0 | ((Imm & 0x00ff00ff00ff00ffULL) == 0); |
471 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType6 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType6 |
472 | | |
473 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType6(uint64_t Imm) |
474 | 0 | { |
475 | 0 | return (Imm & 0xff00ULL) >> 8; |
476 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType6 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType6 |
477 | | |
478 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType6(uint8_t Imm) |
479 | 0 | { |
480 | 0 | uint64_t EncVal = Imm; |
481 | 0 | return (EncVal << 56) | (EncVal << 40) | (EncVal << 24) | (EncVal << 8); |
482 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType6 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType6 |
483 | | |
484 | | // 0x00 0x00 abcdefgh 0xFF 0x00 0x00 abcdefgh 0xFF |
485 | | static inline bool AArch64_AM_isAdvSIMDModImmType7(uint64_t Imm) |
486 | 0 | { |
487 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
488 | 0 | ((Imm & 0xffff00ffffff00ffULL) == 0x000000ff000000ffULL); |
489 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType7 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType7 |
490 | | |
491 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType7(uint64_t Imm) |
492 | 0 | { |
493 | 0 | return (Imm & 0xff00ULL) >> 8; |
494 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType7 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType7 |
495 | | |
496 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType7(uint8_t Imm) |
497 | 0 | { |
498 | 0 | uint64_t EncVal = Imm; |
499 | 0 | return (EncVal << 40) | (EncVal << 8) | 0x000000ff000000ffULL; |
500 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType7 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType7 |
501 | | |
502 | | // 0x00 abcdefgh 0xFF 0xFF 0x00 abcdefgh 0xFF 0xFF |
503 | | static inline bool AArch64_AM_isAdvSIMDModImmType8(uint64_t Imm) |
504 | 0 | { |
505 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
506 | 0 | ((Imm & 0xff00ffffff00ffffULL) == 0x0000ffff0000ffffULL); |
507 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType8 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType8 |
508 | | |
509 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType8(uint8_t Imm) |
510 | 0 | { |
511 | 0 | uint64_t EncVal = Imm; |
512 | 0 | return (EncVal << 48) | (EncVal << 16) | 0x0000ffff0000ffffULL; |
513 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType8 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType8 |
514 | | |
515 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType8(uint64_t Imm) |
516 | 0 | { |
517 | 0 | return (Imm & 0x00ff0000ULL) >> 16; |
518 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType8 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType8 |
519 | | |
520 | | // abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh abcdefgh |
521 | | static inline bool AArch64_AM_isAdvSIMDModImmType9(uint64_t Imm) |
522 | 0 | { |
523 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
524 | 0 | ((Imm >> 48) == (Imm & 0x0000ffffULL)) && |
525 | 0 | ((Imm >> 56) == (Imm & 0x000000ffULL)); |
526 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType9 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType9 |
527 | | |
528 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType9(uint64_t Imm) |
529 | 0 | { |
530 | 0 | return (Imm & 0xffULL); |
531 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType9 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType9 |
532 | | |
533 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType9(uint8_t Imm) |
534 | 0 | { |
535 | 0 | uint64_t EncVal = Imm; |
536 | 0 | EncVal |= (EncVal << 8); |
537 | 0 | EncVal |= (EncVal << 16); |
538 | 0 | EncVal |= (EncVal << 32); |
539 | 0 |
|
540 | 0 | return EncVal; |
541 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType9 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType9 |
542 | | |
543 | | // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh |
544 | | // cmode: 1110, op: 1 |
545 | | static inline bool AArch64_AM_isAdvSIMDModImmType10(uint64_t Imm) |
546 | 0 | { |
547 | 0 | uint64_t ByteA = Imm & 0xff00000000000000ULL; |
548 | 0 | uint64_t ByteB = Imm & 0x00ff000000000000ULL; |
549 | 0 | uint64_t ByteC = Imm & 0x0000ff0000000000ULL; |
550 | 0 | uint64_t ByteD = Imm & 0x000000ff00000000ULL; |
551 | 0 | uint64_t ByteE = Imm & 0x00000000ff000000ULL; |
552 | 0 | uint64_t ByteF = Imm & 0x0000000000ff0000ULL; |
553 | 0 | uint64_t ByteG = Imm & 0x000000000000ff00ULL; |
554 | 0 | uint64_t ByteH = Imm & 0x00000000000000ffULL; |
555 | 0 |
|
556 | 0 | return (ByteA == 0ULL || ByteA == 0xff00000000000000ULL) && |
557 | 0 | (ByteB == 0ULL || ByteB == 0x00ff000000000000ULL) && |
558 | 0 | (ByteC == 0ULL || ByteC == 0x0000ff0000000000ULL) && |
559 | 0 | (ByteD == 0ULL || ByteD == 0x000000ff00000000ULL) && |
560 | 0 | (ByteE == 0ULL || ByteE == 0x00000000ff000000ULL) && |
561 | 0 | (ByteF == 0ULL || ByteF == 0x0000000000ff0000ULL) && |
562 | 0 | (ByteG == 0ULL || ByteG == 0x000000000000ff00ULL) && |
563 | 0 | (ByteH == 0ULL || ByteH == 0x00000000000000ffULL); |
564 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType10 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType10 |
565 | | |
566 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType10(uint64_t Imm) |
567 | 0 | { |
568 | 0 | uint8_t BitA = (Imm & 0xff00000000000000ULL) != 0; |
569 | 0 | uint8_t BitB = (Imm & 0x00ff000000000000ULL) != 0; |
570 | 0 | uint8_t BitC = (Imm & 0x0000ff0000000000ULL) != 0; |
571 | 0 | uint8_t BitD = (Imm & 0x000000ff00000000ULL) != 0; |
572 | 0 | uint8_t BitE = (Imm & 0x00000000ff000000ULL) != 0; |
573 | 0 | uint8_t BitF = (Imm & 0x0000000000ff0000ULL) != 0; |
574 | 0 | uint8_t BitG = (Imm & 0x000000000000ff00ULL) != 0; |
575 | 0 | uint8_t BitH = (Imm & 0x00000000000000ffULL) != 0; |
576 | 0 |
|
577 | 0 | uint8_t EncVal = BitA; |
578 | 0 |
|
579 | 0 | EncVal <<= 1; |
580 | 0 | EncVal |= BitB; |
581 | 0 | EncVal <<= 1; |
582 | 0 | EncVal |= BitC; |
583 | 0 | EncVal <<= 1; |
584 | 0 | EncVal |= BitD; |
585 | 0 | EncVal <<= 1; |
586 | 0 | EncVal |= BitE; |
587 | 0 | EncVal <<= 1; |
588 | 0 | EncVal |= BitF; |
589 | 0 | EncVal <<= 1; |
590 | 0 | EncVal |= BitG; |
591 | 0 | EncVal <<= 1; |
592 | 0 | EncVal |= BitH; |
593 | 0 |
|
594 | 0 | return EncVal; |
595 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType10 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType10 |
596 | | |
597 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType10(uint8_t Imm) |
598 | 796 | { |
599 | 796 | uint64_t EncVal = 0; |
600 | | |
601 | 796 | if (Imm & 0x80) |
602 | 335 | EncVal |= 0xff00000000000000ULL; |
603 | | |
604 | 796 | if (Imm & 0x40) |
605 | 452 | EncVal |= 0x00ff000000000000ULL; |
606 | | |
607 | 796 | if (Imm & 0x20) |
608 | 453 | EncVal |= 0x0000ff0000000000ULL; |
609 | | |
610 | 796 | if (Imm & 0x10) |
611 | 350 | EncVal |= 0x000000ff00000000ULL; |
612 | | |
613 | 796 | if (Imm & 0x08) |
614 | 240 | EncVal |= 0x00000000ff000000ULL; |
615 | | |
616 | 796 | if (Imm & 0x04) |
617 | 194 | EncVal |= 0x0000000000ff0000ULL; |
618 | | |
619 | 796 | if (Imm & 0x02) |
620 | 199 | EncVal |= 0x000000000000ff00ULL; |
621 | | |
622 | 796 | if (Imm & 0x01) |
623 | 706 | EncVal |= 0x00000000000000ffULL; |
624 | | |
625 | 796 | return EncVal; |
626 | 796 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType10 AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType10 Line | Count | Source | 598 | 796 | { | 599 | 796 | uint64_t EncVal = 0; | 600 | | | 601 | 796 | if (Imm & 0x80) | 602 | 335 | EncVal |= 0xff00000000000000ULL; | 603 | | | 604 | 796 | if (Imm & 0x40) | 605 | 452 | EncVal |= 0x00ff000000000000ULL; | 606 | | | 607 | 796 | if (Imm & 0x20) | 608 | 453 | EncVal |= 0x0000ff0000000000ULL; | 609 | | | 610 | 796 | if (Imm & 0x10) | 611 | 350 | EncVal |= 0x000000ff00000000ULL; | 612 | | | 613 | 796 | if (Imm & 0x08) | 614 | 240 | EncVal |= 0x00000000ff000000ULL; | 615 | | | 616 | 796 | if (Imm & 0x04) | 617 | 194 | EncVal |= 0x0000000000ff0000ULL; | 618 | | | 619 | 796 | if (Imm & 0x02) | 620 | 199 | EncVal |= 0x000000000000ff00ULL; | 621 | | | 622 | 796 | if (Imm & 0x01) | 623 | 706 | EncVal |= 0x00000000000000ffULL; | 624 | | | 625 | 796 | return EncVal; | 626 | 796 | } |
|
627 | | |
628 | | // aBbbbbbc defgh000 0x00 0x00 aBbbbbbc defgh000 0x00 0x00 |
629 | | static inline bool AArch64_AM_isAdvSIMDModImmType11(uint64_t Imm) |
630 | 0 | { |
631 | 0 | uint64_t BString = (Imm & 0x7E000000ULL) >> 25; |
632 | 0 |
|
633 | 0 | return ((Imm >> 32) == (Imm & 0xffffffffULL)) && |
634 | 0 | (BString == 0x1f || BString == 0x20) && |
635 | 0 | ((Imm & 0x0007ffff0007ffffULL) == 0); |
636 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType11 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType11 |
637 | | |
638 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType11(uint64_t Imm) |
639 | 0 | { |
640 | 0 | uint8_t BitA = (Imm & 0x80000000ULL) != 0; |
641 | 0 | uint8_t BitB = (Imm & 0x20000000ULL) != 0; |
642 | 0 | uint8_t BitC = (Imm & 0x01000000ULL) != 0; |
643 | 0 | uint8_t BitD = (Imm & 0x00800000ULL) != 0; |
644 | 0 | uint8_t BitE = (Imm & 0x00400000ULL) != 0; |
645 | 0 | uint8_t BitF = (Imm & 0x00200000ULL) != 0; |
646 | 0 | uint8_t BitG = (Imm & 0x00100000ULL) != 0; |
647 | 0 | uint8_t BitH = (Imm & 0x00080000ULL) != 0; |
648 | 0 |
|
649 | 0 | uint8_t EncVal = BitA; |
650 | 0 | EncVal <<= 1; |
651 | 0 | EncVal |= BitB; |
652 | 0 | EncVal <<= 1; |
653 | 0 | EncVal |= BitC; |
654 | 0 | EncVal <<= 1; |
655 | 0 | EncVal |= BitD; |
656 | 0 | EncVal <<= 1; |
657 | 0 | EncVal |= BitE; |
658 | 0 | EncVal <<= 1; |
659 | 0 | EncVal |= BitF; |
660 | 0 | EncVal <<= 1; |
661 | 0 | EncVal |= BitG; |
662 | 0 | EncVal <<= 1; |
663 | 0 | EncVal |= BitH; |
664 | 0 |
|
665 | 0 | return EncVal; |
666 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType11 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType11 |
667 | | |
668 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType11(uint8_t Imm) |
669 | 0 | { |
670 | 0 | uint64_t EncVal = 0; |
671 | 0 |
|
672 | 0 | if (Imm & 0x80) |
673 | 0 | EncVal |= 0x80000000ULL; |
674 | 0 |
|
675 | 0 | if (Imm & 0x40) |
676 | 0 | EncVal |= 0x3e000000ULL; |
677 | 0 | else |
678 | 0 | EncVal |= 0x40000000ULL; |
679 | 0 |
|
680 | 0 | if (Imm & 0x20) |
681 | 0 | EncVal |= 0x01000000ULL; |
682 | 0 |
|
683 | 0 | if (Imm & 0x10) |
684 | 0 | EncVal |= 0x00800000ULL; |
685 | 0 |
|
686 | 0 | if (Imm & 0x08) |
687 | 0 | EncVal |= 0x00400000ULL; |
688 | 0 |
|
689 | 0 | if (Imm & 0x04) |
690 | 0 | EncVal |= 0x00200000ULL; |
691 | 0 |
|
692 | 0 | if (Imm & 0x02) |
693 | 0 | EncVal |= 0x00100000ULL; |
694 | 0 |
|
695 | 0 | if (Imm & 0x01) |
696 | 0 | EncVal |= 0x00080000ULL; |
697 | 0 |
|
698 | 0 | return (EncVal << 32) | EncVal; |
699 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType11 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType11 |
700 | | |
701 | | // aBbbbbbb bbcdefgh 0x00 0x00 0x00 0x00 0x00 0x00 |
702 | | static inline bool AArch64_AM_isAdvSIMDModImmType12(uint64_t Imm) |
703 | 0 | { |
704 | 0 | uint64_t BString = (Imm & 0x7fc0000000000000ULL) >> 54; |
705 | 0 | return ((BString == 0xff || BString == 0x100) && |
706 | 0 | ((Imm & 0x0000ffffffffffffULL) == 0)); |
707 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAdvSIMDModImmType12 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAdvSIMDModImmType12 |
708 | | |
709 | | static inline uint8_t AArch64_AM_encodeAdvSIMDModImmType12(uint64_t Imm) |
710 | 0 | { |
711 | 0 | uint8_t BitA = (Imm & 0x8000000000000000ULL) != 0; |
712 | 0 | uint8_t BitB = (Imm & 0x0040000000000000ULL) != 0; |
713 | 0 | uint8_t BitC = (Imm & 0x0020000000000000ULL) != 0; |
714 | 0 | uint8_t BitD = (Imm & 0x0010000000000000ULL) != 0; |
715 | 0 | uint8_t BitE = (Imm & 0x0008000000000000ULL) != 0; |
716 | 0 | uint8_t BitF = (Imm & 0x0004000000000000ULL) != 0; |
717 | 0 | uint8_t BitG = (Imm & 0x0002000000000000ULL) != 0; |
718 | 0 | uint8_t BitH = (Imm & 0x0001000000000000ULL) != 0; |
719 | 0 |
|
720 | 0 | uint8_t EncVal = BitA; |
721 | 0 | EncVal <<= 1; |
722 | 0 | EncVal |= BitB; |
723 | 0 | EncVal <<= 1; |
724 | 0 | EncVal |= BitC; |
725 | 0 | EncVal <<= 1; |
726 | 0 | EncVal |= BitD; |
727 | 0 | EncVal <<= 1; |
728 | 0 | EncVal |= BitE; |
729 | 0 | EncVal <<= 1; |
730 | 0 | EncVal |= BitF; |
731 | 0 | EncVal <<= 1; |
732 | 0 | EncVal |= BitG; |
733 | 0 | EncVal <<= 1; |
734 | 0 | EncVal |= BitH; |
735 | 0 |
|
736 | 0 | return EncVal; |
737 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_encodeAdvSIMDModImmType12 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_encodeAdvSIMDModImmType12 |
738 | | |
739 | | static inline uint64_t AArch64_AM_decodeAdvSIMDModImmType12(uint8_t Imm) |
740 | 0 | { |
741 | 0 | uint64_t EncVal = 0; |
742 | 0 | if (Imm & 0x80) |
743 | 0 | EncVal |= 0x8000000000000000ULL; |
744 | 0 |
|
745 | 0 | if (Imm & 0x40) |
746 | 0 | EncVal |= 0x3fc0000000000000ULL; |
747 | 0 | else |
748 | 0 | EncVal |= 0x4000000000000000ULL; |
749 | 0 |
|
750 | 0 | if (Imm & 0x20) |
751 | 0 | EncVal |= 0x0020000000000000ULL; |
752 | 0 |
|
753 | 0 | if (Imm & 0x10) |
754 | 0 | EncVal |= 0x0010000000000000ULL; |
755 | 0 |
|
756 | 0 | if (Imm & 0x08) |
757 | 0 | EncVal |= 0x0008000000000000ULL; |
758 | 0 |
|
759 | 0 | if (Imm & 0x04) |
760 | 0 | EncVal |= 0x0004000000000000ULL; |
761 | 0 |
|
762 | 0 | if (Imm & 0x02) |
763 | 0 | EncVal |= 0x0002000000000000ULL; |
764 | 0 |
|
765 | 0 | if (Imm & 0x01) |
766 | 0 | EncVal |= 0x0001000000000000ULL; |
767 | 0 |
|
768 | 0 | return (EncVal << 32) | EncVal; |
769 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_decodeAdvSIMDModImmType12 Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_decodeAdvSIMDModImmType12 |
770 | | |
771 | | /// Returns true if Imm is the concatenation of a repeating pattern of type T. |
772 | | static inline bool AArch64_AM_isSVEMaskOfIdenticalElements8(int64_t Imm) |
773 | 4.55k | { |
774 | 12.6k | #define _VECSIZE (sizeof(int64_t)/sizeof(int8_t)) |
775 | 4.55k | unsigned int i; |
776 | 4.55k | union { |
777 | 4.55k | int64_t Whole; |
778 | 4.55k | int8_t Parts[_VECSIZE]; |
779 | 4.55k | } Vec; |
780 | | |
781 | 4.55k | Vec.Whole = Imm; |
782 | | |
783 | 12.6k | for(i = 1; i < _VECSIZE; i++) { |
784 | 11.8k | if (Vec.Parts[i] != Vec.Parts[0]) |
785 | 3.81k | return false; |
786 | 11.8k | } |
787 | 741 | #undef _VECSIZE |
788 | | |
789 | 741 | return true; |
790 | 4.55k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isSVEMaskOfIdenticalElements8 AArch64InstPrinter.c:AArch64_AM_isSVEMaskOfIdenticalElements8 Line | Count | Source | 773 | 4.55k | { | 774 | 4.55k | #define _VECSIZE (sizeof(int64_t)/sizeof(int8_t)) | 775 | 4.55k | unsigned int i; | 776 | 4.55k | union { | 777 | 4.55k | int64_t Whole; | 778 | 4.55k | int8_t Parts[_VECSIZE]; | 779 | 4.55k | } Vec; | 780 | | | 781 | 4.55k | Vec.Whole = Imm; | 782 | | | 783 | 12.6k | for(i = 1; i < _VECSIZE; i++) { | 784 | 11.8k | if (Vec.Parts[i] != Vec.Parts[0]) | 785 | 3.81k | return false; | 786 | 11.8k | } | 787 | 741 | #undef _VECSIZE | 788 | | | 789 | 741 | return true; | 790 | 4.55k | } |
|
791 | | |
792 | | static inline bool AArch64_AM_isSVEMaskOfIdenticalElements16(int64_t Imm) |
793 | 8.76k | { |
794 | 19.2k | #define _VECSIZE (sizeof(int64_t)/sizeof(int16_t)) |
795 | 8.76k | unsigned int i; |
796 | 8.76k | union { |
797 | 8.76k | int64_t Whole; |
798 | 8.76k | int16_t Parts[_VECSIZE]; |
799 | 8.76k | } Vec; |
800 | | |
801 | 8.76k | Vec.Whole = Imm; |
802 | | |
803 | 19.2k | for(i = 1; i < _VECSIZE; i++) { |
804 | 16.1k | if (Vec.Parts[i] != Vec.Parts[0]) |
805 | 5.66k | return false; |
806 | 16.1k | } |
807 | 3.10k | #undef _VECSIZE |
808 | | |
809 | 3.10k | return true; |
810 | 8.76k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isSVEMaskOfIdenticalElements16 AArch64InstPrinter.c:AArch64_AM_isSVEMaskOfIdenticalElements16 Line | Count | Source | 793 | 8.76k | { | 794 | 8.76k | #define _VECSIZE (sizeof(int64_t)/sizeof(int16_t)) | 795 | 8.76k | unsigned int i; | 796 | 8.76k | union { | 797 | 8.76k | int64_t Whole; | 798 | 8.76k | int16_t Parts[_VECSIZE]; | 799 | 8.76k | } Vec; | 800 | | | 801 | 8.76k | Vec.Whole = Imm; | 802 | | | 803 | 19.2k | for(i = 1; i < _VECSIZE; i++) { | 804 | 16.1k | if (Vec.Parts[i] != Vec.Parts[0]) | 805 | 5.66k | return false; | 806 | 16.1k | } | 807 | 3.10k | #undef _VECSIZE | 808 | | | 809 | 3.10k | return true; | 810 | 8.76k | } |
|
811 | | |
812 | | static inline bool AArch64_AM_isSVEMaskOfIdenticalElements32(int64_t Imm) |
813 | 9.53k | { |
814 | 17.0k | #define _VECSIZE (sizeof(int64_t)/sizeof(int32_t)) |
815 | 9.53k | unsigned int i; |
816 | 9.53k | union { |
817 | 9.53k | int64_t Whole; |
818 | 9.53k | int32_t Parts[_VECSIZE]; |
819 | 9.53k | } Vec; |
820 | | |
821 | 9.53k | Vec.Whole = Imm; |
822 | | |
823 | 17.0k | for(i = 1; i < _VECSIZE; i++) { |
824 | 9.53k | if (Vec.Parts[i] != Vec.Parts[0]) |
825 | 2.01k | return false; |
826 | 9.53k | } |
827 | 7.52k | #undef _VECSIZE |
828 | | |
829 | 7.52k | return true; |
830 | 9.53k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isSVEMaskOfIdenticalElements32 AArch64InstPrinter.c:AArch64_AM_isSVEMaskOfIdenticalElements32 Line | Count | Source | 813 | 9.53k | { | 814 | 9.53k | #define _VECSIZE (sizeof(int64_t)/sizeof(int32_t)) | 815 | 9.53k | unsigned int i; | 816 | 9.53k | union { | 817 | 9.53k | int64_t Whole; | 818 | 9.53k | int32_t Parts[_VECSIZE]; | 819 | 9.53k | } Vec; | 820 | | | 821 | 9.53k | Vec.Whole = Imm; | 822 | | | 823 | 17.0k | for(i = 1; i < _VECSIZE; i++) { | 824 | 9.53k | if (Vec.Parts[i] != Vec.Parts[0]) | 825 | 2.01k | return false; | 826 | 9.53k | } | 827 | 7.52k | #undef _VECSIZE | 828 | | | 829 | 7.52k | return true; | 830 | 9.53k | } |
|
831 | | |
832 | | static inline bool AArch64_AM_isSVEMaskOfIdenticalElements64(int64_t Imm) |
833 | 2.19k | { |
834 | 2.19k | return true; |
835 | 2.19k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isSVEMaskOfIdenticalElements64 AArch64InstPrinter.c:AArch64_AM_isSVEMaskOfIdenticalElements64 Line | Count | Source | 833 | 2.19k | { | 834 | 2.19k | return true; | 835 | 2.19k | } |
|
836 | | |
837 | | static inline bool isSVECpyImm8(int64_t Imm) |
838 | 483 | { |
839 | 483 | bool IsImm8 = (int8_t)Imm == Imm; |
840 | | |
841 | 483 | return IsImm8 || (uint8_t)Imm == Imm; |
842 | 483 | } Unexecuted instantiation: AArch64Disassembler.c:isSVECpyImm8 AArch64InstPrinter.c:isSVECpyImm8 Line | Count | Source | 838 | 483 | { | 839 | 483 | bool IsImm8 = (int8_t)Imm == Imm; | 840 | | | 841 | 483 | return IsImm8 || (uint8_t)Imm == Imm; | 842 | 483 | } |
|
843 | | |
844 | | static inline bool isSVECpyImm16(int64_t Imm) |
845 | 1.86k | { |
846 | 1.86k | bool IsImm8 = (int8_t)Imm == Imm; |
847 | 1.86k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; |
848 | | |
849 | 1.86k | return IsImm8 || IsImm16 || (uint16_t)(Imm & ~0xff) == Imm; |
850 | 1.86k | } Unexecuted instantiation: AArch64Disassembler.c:isSVECpyImm16 AArch64InstPrinter.c:isSVECpyImm16 Line | Count | Source | 845 | 1.86k | { | 846 | 1.86k | bool IsImm8 = (int8_t)Imm == Imm; | 847 | 1.86k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; | 848 | | | 849 | 1.86k | return IsImm8 || IsImm16 || (uint16_t)(Imm & ~0xff) == Imm; | 850 | 1.86k | } |
|
851 | | |
852 | | static inline bool isSVECpyImm32(int64_t Imm) |
853 | 4.27k | { |
854 | 4.27k | bool IsImm8 = (int8_t)Imm == Imm; |
855 | 4.27k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; |
856 | | |
857 | 4.27k | return IsImm8 || IsImm16; |
858 | 4.27k | } Unexecuted instantiation: AArch64Disassembler.c:isSVECpyImm32 AArch64InstPrinter.c:isSVECpyImm32 Line | Count | Source | 853 | 4.27k | { | 854 | 4.27k | bool IsImm8 = (int8_t)Imm == Imm; | 855 | 4.27k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; | 856 | | | 857 | 4.27k | return IsImm8 || IsImm16; | 858 | 4.27k | } |
|
859 | | |
860 | | static inline bool isSVECpyImm64(int64_t Imm) |
861 | 5.21k | { |
862 | 5.21k | bool IsImm8 = (int8_t)Imm == Imm; |
863 | 5.21k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; |
864 | | |
865 | 5.21k | return IsImm8 || IsImm16; |
866 | 5.21k | } Unexecuted instantiation: AArch64Disassembler.c:isSVECpyImm64 AArch64InstPrinter.c:isSVECpyImm64 Line | Count | Source | 861 | 5.21k | { | 862 | 5.21k | bool IsImm8 = (int8_t)Imm == Imm; | 863 | 5.21k | bool IsImm16 = (int16_t)(Imm & ~0xff) == Imm; | 864 | | | 865 | 5.21k | return IsImm8 || IsImm16; | 866 | 5.21k | } |
|
867 | | |
868 | | /// Return true if Imm is valid for DUPM and has no single CPY/DUP equivalent. |
869 | | static inline bool AArch64_AM_isSVEMoveMaskPreferredLogicalImmediate(int64_t Imm) |
870 | 5.21k | { |
871 | 5.21k | union { |
872 | 5.21k | int64_t D; |
873 | 5.21k | int32_t S[2]; |
874 | 5.21k | int16_t H[4]; |
875 | 5.21k | int8_t B[8]; |
876 | 5.21k | } Vec = {Imm}; |
877 | | |
878 | 5.21k | if (isSVECpyImm64(Vec.D)) |
879 | 288 | return false; |
880 | | |
881 | 4.92k | if (AArch64_AM_isSVEMaskOfIdenticalElements32(Imm) && |
882 | 4.92k | isSVECpyImm32(Vec.S[0])) |
883 | 1.51k | return false; |
884 | | |
885 | 3.41k | if (AArch64_AM_isSVEMaskOfIdenticalElements16(Imm) && |
886 | 3.41k | isSVECpyImm16(Vec.H[0])) |
887 | 996 | return false; |
888 | | |
889 | 2.41k | if (AArch64_AM_isSVEMaskOfIdenticalElements8(Imm) && |
890 | 2.41k | isSVECpyImm8(Vec.B[0])) |
891 | 483 | return false; |
892 | | |
893 | 1.93k | return isLogicalImmediate(Vec.D, 64); |
894 | 2.41k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isSVEMoveMaskPreferredLogicalImmediate AArch64InstPrinter.c:AArch64_AM_isSVEMoveMaskPreferredLogicalImmediate Line | Count | Source | 870 | 5.21k | { | 871 | 5.21k | union { | 872 | 5.21k | int64_t D; | 873 | 5.21k | int32_t S[2]; | 874 | 5.21k | int16_t H[4]; | 875 | 5.21k | int8_t B[8]; | 876 | 5.21k | } Vec = {Imm}; | 877 | | | 878 | 5.21k | if (isSVECpyImm64(Vec.D)) | 879 | 288 | return false; | 880 | | | 881 | 4.92k | if (AArch64_AM_isSVEMaskOfIdenticalElements32(Imm) && | 882 | 4.92k | isSVECpyImm32(Vec.S[0])) | 883 | 1.51k | return false; | 884 | | | 885 | 3.41k | if (AArch64_AM_isSVEMaskOfIdenticalElements16(Imm) && | 886 | 3.41k | isSVECpyImm16(Vec.H[0])) | 887 | 996 | return false; | 888 | | | 889 | 2.41k | if (AArch64_AM_isSVEMaskOfIdenticalElements8(Imm) && | 890 | 2.41k | isSVECpyImm8(Vec.B[0])) | 891 | 483 | return false; | 892 | | | 893 | 1.93k | return isLogicalImmediate(Vec.D, 64); | 894 | 2.41k | } |
|
895 | | |
896 | | inline static bool isAnyMOVZMovAlias(uint64_t Value, int RegWidth) |
897 | 1.33k | { |
898 | 1.33k | int Shift; |
899 | | |
900 | 5.81k | for (Shift = 0; Shift <= RegWidth - 16; Shift += 16) |
901 | 4.58k | if ((Value & ~(0xffffULL << Shift)) == 0) |
902 | 104 | return true; |
903 | | |
904 | 1.22k | return false; |
905 | 1.33k | } Unexecuted instantiation: AArch64Disassembler.c:isAnyMOVZMovAlias AArch64InstPrinter.c:isAnyMOVZMovAlias Line | Count | Source | 897 | 1.33k | { | 898 | 1.33k | int Shift; | 899 | | | 900 | 5.81k | for (Shift = 0; Shift <= RegWidth - 16; Shift += 16) | 901 | 4.58k | if ((Value & ~(0xffffULL << Shift)) == 0) | 902 | 104 | return true; | 903 | | | 904 | 1.22k | return false; | 905 | 1.33k | } |
|
906 | | |
907 | | inline static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth) |
908 | 1.63k | { |
909 | 1.63k | if (RegWidth == 32) |
910 | 327 | Value &= 0xffffffffULL; |
911 | | |
912 | | // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0". |
913 | 1.63k | if (Value == 0 && Shift != 0) |
914 | 68 | return false; |
915 | | |
916 | 1.56k | return (Value & ~(0xffffULL << Shift)) == 0; |
917 | 1.63k | } Unexecuted instantiation: AArch64Disassembler.c:isMOVZMovAlias AArch64InstPrinter.c:isMOVZMovAlias Line | Count | Source | 908 | 1.63k | { | 909 | 1.63k | if (RegWidth == 32) | 910 | 327 | Value &= 0xffffffffULL; | 911 | | | 912 | | // "lsl #0" takes precedence: in practice this only affects "#0, lsl #0". | 913 | 1.63k | if (Value == 0 && Shift != 0) | 914 | 68 | return false; | 915 | | | 916 | 1.56k | return (Value & ~(0xffffULL << Shift)) == 0; | 917 | 1.63k | } |
|
918 | | |
919 | | inline static bool AArch64_AM_isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth) |
920 | 1.33k | { |
921 | | // MOVZ takes precedence over MOVN. |
922 | 1.33k | if (isAnyMOVZMovAlias(Value, RegWidth)) |
923 | 104 | return false; |
924 | | |
925 | 1.22k | Value = ~Value; |
926 | 1.22k | if (RegWidth == 32) |
927 | 240 | Value &= 0xffffffffULL; |
928 | | |
929 | 1.22k | return isMOVZMovAlias(Value, Shift, RegWidth); |
930 | 1.33k | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isMOVNMovAlias AArch64InstPrinter.c:AArch64_AM_isMOVNMovAlias Line | Count | Source | 920 | 1.33k | { | 921 | | // MOVZ takes precedence over MOVN. | 922 | 1.33k | if (isAnyMOVZMovAlias(Value, RegWidth)) | 923 | 104 | return false; | 924 | | | 925 | 1.22k | Value = ~Value; | 926 | 1.22k | if (RegWidth == 32) | 927 | 240 | Value &= 0xffffffffULL; | 928 | | | 929 | 1.22k | return isMOVZMovAlias(Value, Shift, RegWidth); | 930 | 1.33k | } |
|
931 | | |
932 | | inline static bool AArch64_AM_isAnyMOVWMovAlias(uint64_t Value, int RegWidth) |
933 | 0 | { |
934 | 0 | if (isAnyMOVZMovAlias(Value, RegWidth)) |
935 | 0 | return true; |
936 | 0 |
|
937 | 0 | // It's not a MOVZ, but it might be a MOVN. |
938 | 0 | Value = ~Value; |
939 | 0 | if (RegWidth == 32) |
940 | 0 | Value &= 0xffffffffULL; |
941 | 0 |
|
942 | 0 | return isAnyMOVZMovAlias(Value, RegWidth); |
943 | 0 | } Unexecuted instantiation: AArch64Disassembler.c:AArch64_AM_isAnyMOVWMovAlias Unexecuted instantiation: AArch64InstPrinter.c:AArch64_AM_isAnyMOVWMovAlias |
944 | | |
945 | | #endif |