aarch64-opc.c revision 1.9 1 1.1 christos /* aarch64-opc.c -- AArch64 opcode support.
2 1.9 christos Copyright (C) 2009-2020 Free Software Foundation, Inc.
3 1.1 christos Contributed by ARM Ltd.
4 1.1 christos
5 1.1 christos This file is part of the GNU opcodes library.
6 1.1 christos
7 1.1 christos This library is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3, or (at your option)
10 1.1 christos any later version.
11 1.1 christos
12 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
13 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 1.1 christos License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; see the file COPYING3. If not,
19 1.1 christos see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include <assert.h>
23 1.1 christos #include <stdlib.h>
24 1.1 christos #include <stdio.h>
25 1.8 christos #include "bfd_stdint.h"
26 1.1 christos #include <stdarg.h>
27 1.1 christos #include <inttypes.h>
28 1.1 christos
29 1.1 christos #include "opintl.h"
30 1.7 christos #include "libiberty.h"
31 1.1 christos
32 1.1 christos #include "aarch64-opc.h"
33 1.1 christos
34 1.1 christos #ifdef DEBUG_AARCH64
35 1.1 christos int debug_dump = FALSE;
36 1.1 christos #endif /* DEBUG_AARCH64 */
37 1.1 christos
38 1.7 christos /* The enumeration strings associated with each value of a 5-bit SVE
39 1.7 christos pattern operand. A null entry indicates a reserved meaning. */
40 1.7 christos const char *const aarch64_sve_pattern_array[32] = {
41 1.7 christos /* 0-7. */
42 1.7 christos "pow2",
43 1.7 christos "vl1",
44 1.7 christos "vl2",
45 1.7 christos "vl3",
46 1.7 christos "vl4",
47 1.7 christos "vl5",
48 1.7 christos "vl6",
49 1.7 christos "vl7",
50 1.7 christos /* 8-15. */
51 1.7 christos "vl8",
52 1.7 christos "vl16",
53 1.7 christos "vl32",
54 1.7 christos "vl64",
55 1.7 christos "vl128",
56 1.7 christos "vl256",
57 1.7 christos 0,
58 1.7 christos 0,
59 1.7 christos /* 16-23. */
60 1.7 christos 0,
61 1.7 christos 0,
62 1.7 christos 0,
63 1.7 christos 0,
64 1.7 christos 0,
65 1.7 christos 0,
66 1.7 christos 0,
67 1.7 christos 0,
68 1.7 christos /* 24-31. */
69 1.7 christos 0,
70 1.7 christos 0,
71 1.7 christos 0,
72 1.7 christos 0,
73 1.7 christos 0,
74 1.7 christos "mul4",
75 1.7 christos "mul3",
76 1.7 christos "all"
77 1.7 christos };
78 1.7 christos
79 1.7 christos /* The enumeration strings associated with each value of a 4-bit SVE
80 1.7 christos prefetch operand. A null entry indicates a reserved meaning. */
81 1.7 christos const char *const aarch64_sve_prfop_array[16] = {
82 1.7 christos /* 0-7. */
83 1.7 christos "pldl1keep",
84 1.7 christos "pldl1strm",
85 1.7 christos "pldl2keep",
86 1.7 christos "pldl2strm",
87 1.7 christos "pldl3keep",
88 1.7 christos "pldl3strm",
89 1.7 christos 0,
90 1.7 christos 0,
91 1.7 christos /* 8-15. */
92 1.7 christos "pstl1keep",
93 1.7 christos "pstl1strm",
94 1.7 christos "pstl2keep",
95 1.7 christos "pstl2strm",
96 1.7 christos "pstl3keep",
97 1.7 christos "pstl3strm",
98 1.7 christos 0,
99 1.7 christos 0
100 1.7 christos };
101 1.7 christos
102 1.1 christos /* Helper functions to determine which operand to be used to encode/decode
103 1.1 christos the size:Q fields for AdvSIMD instructions. */
104 1.1 christos
105 1.1 christos static inline bfd_boolean
106 1.1 christos vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
107 1.1 christos {
108 1.1 christos return ((qualifier >= AARCH64_OPND_QLF_V_8B
109 1.1 christos && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
110 1.1 christos : FALSE);
111 1.1 christos }
112 1.1 christos
113 1.1 christos static inline bfd_boolean
114 1.1 christos fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
115 1.1 christos {
116 1.1 christos return ((qualifier >= AARCH64_OPND_QLF_S_B
117 1.1 christos && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
118 1.1 christos : FALSE);
119 1.1 christos }
120 1.1 christos
121 1.1 christos enum data_pattern
122 1.1 christos {
123 1.1 christos DP_UNKNOWN,
124 1.1 christos DP_VECTOR_3SAME,
125 1.1 christos DP_VECTOR_LONG,
126 1.1 christos DP_VECTOR_WIDE,
127 1.1 christos DP_VECTOR_ACROSS_LANES,
128 1.1 christos };
129 1.1 christos
130 1.1 christos static const char significant_operand_index [] =
131 1.1 christos {
132 1.1 christos 0, /* DP_UNKNOWN, by default using operand 0. */
133 1.1 christos 0, /* DP_VECTOR_3SAME */
134 1.1 christos 1, /* DP_VECTOR_LONG */
135 1.1 christos 2, /* DP_VECTOR_WIDE */
136 1.1 christos 1, /* DP_VECTOR_ACROSS_LANES */
137 1.1 christos };
138 1.1 christos
139 1.1 christos /* Given a sequence of qualifiers in QUALIFIERS, determine and return
140 1.1 christos the data pattern.
141 1.1 christos N.B. QUALIFIERS is a possible sequence of qualifiers each of which
142 1.1 christos corresponds to one of a sequence of operands. */
143 1.1 christos
144 1.1 christos static enum data_pattern
145 1.1 christos get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
146 1.1 christos {
147 1.1 christos if (vector_qualifier_p (qualifiers[0]) == TRUE)
148 1.1 christos {
149 1.1 christos /* e.g. v.4s, v.4s, v.4s
150 1.1 christos or v.4h, v.4h, v.h[3]. */
151 1.1 christos if (qualifiers[0] == qualifiers[1]
152 1.1 christos && vector_qualifier_p (qualifiers[2]) == TRUE
153 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
154 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1]))
155 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
156 1.1 christos == aarch64_get_qualifier_esize (qualifiers[2])))
157 1.1 christos return DP_VECTOR_3SAME;
158 1.1 christos /* e.g. v.8h, v.8b, v.8b.
159 1.1 christos or v.4s, v.4h, v.h[2].
160 1.1 christos or v.8h, v.16b. */
161 1.1 christos if (vector_qualifier_p (qualifiers[1]) == TRUE
162 1.1 christos && aarch64_get_qualifier_esize (qualifiers[0]) != 0
163 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
164 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
165 1.1 christos return DP_VECTOR_LONG;
166 1.1 christos /* e.g. v.8h, v.8h, v.8b. */
167 1.1 christos if (qualifiers[0] == qualifiers[1]
168 1.1 christos && vector_qualifier_p (qualifiers[2]) == TRUE
169 1.1 christos && aarch64_get_qualifier_esize (qualifiers[0]) != 0
170 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
171 1.1 christos == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
172 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
173 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1])))
174 1.1 christos return DP_VECTOR_WIDE;
175 1.1 christos }
176 1.1 christos else if (fp_qualifier_p (qualifiers[0]) == TRUE)
177 1.1 christos {
178 1.1 christos /* e.g. SADDLV <V><d>, <Vn>.<T>. */
179 1.1 christos if (vector_qualifier_p (qualifiers[1]) == TRUE
180 1.1 christos && qualifiers[2] == AARCH64_OPND_QLF_NIL)
181 1.1 christos return DP_VECTOR_ACROSS_LANES;
182 1.1 christos }
183 1.1 christos
184 1.1 christos return DP_UNKNOWN;
185 1.1 christos }
186 1.1 christos
187 1.1 christos /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
188 1.1 christos the AdvSIMD instructions. */
189 1.1 christos /* N.B. it is possible to do some optimization that doesn't call
190 1.1 christos get_data_pattern each time when we need to select an operand. We can
191 1.1 christos either buffer the caculated the result or statically generate the data,
192 1.1 christos however, it is not obvious that the optimization will bring significant
193 1.1 christos benefit. */
194 1.1 christos
195 1.1 christos int
196 1.1 christos aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
197 1.1 christos {
198 1.1 christos return
199 1.1 christos significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
200 1.1 christos }
201 1.1 christos
202 1.1 christos const aarch64_field fields[] =
204 1.1 christos {
205 1.1 christos { 0, 0 }, /* NIL. */
206 1.1 christos { 0, 4 }, /* cond2: condition in truly conditional-executed inst. */
207 1.1 christos { 0, 4 }, /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
208 1.1 christos { 5, 5 }, /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
209 1.1 christos { 16, 3 }, /* abc: a:b:c bits in AdvSIMD modified immediate. */
210 1.1 christos { 5, 19 }, /* imm19: e.g. in CBZ. */
211 1.1 christos { 5, 19 }, /* immhi: e.g. in ADRP. */
212 1.1 christos { 29, 2 }, /* immlo: e.g. in ADRP. */
213 1.1 christos { 22, 2 }, /* size: in most AdvSIMD and floating-point instructions. */
214 1.1 christos { 10, 2 }, /* vldst_size: size field in the AdvSIMD load/store inst. */
215 1.1 christos { 29, 1 }, /* op: in AdvSIMD modified immediate instructions. */
216 1.1 christos { 30, 1 }, /* Q: in most AdvSIMD instructions. */
217 1.1 christos { 0, 5 }, /* Rt: in load/store instructions. */
218 1.1 christos { 0, 5 }, /* Rd: in many integer instructions. */
219 1.1 christos { 5, 5 }, /* Rn: in many integer instructions. */
220 1.1 christos { 10, 5 }, /* Rt2: in load/store pair instructions. */
221 1.1 christos { 10, 5 }, /* Ra: in fp instructions. */
222 1.1 christos { 5, 3 }, /* op2: in the system instructions. */
223 1.1 christos { 8, 4 }, /* CRm: in the system instructions. */
224 1.1 christos { 12, 4 }, /* CRn: in the system instructions. */
225 1.1 christos { 16, 3 }, /* op1: in the system instructions. */
226 1.1 christos { 19, 2 }, /* op0: in the system instructions. */
227 1.1 christos { 10, 3 }, /* imm3: in add/sub extended reg instructions. */
228 1.1 christos { 12, 4 }, /* cond: condition flags as a source operand. */
229 1.1 christos { 12, 4 }, /* opcode: in advsimd load/store instructions. */
230 1.1 christos { 12, 4 }, /* cmode: in advsimd modified immediate instructions. */
231 1.1 christos { 13, 3 }, /* asisdlso_opcode: opcode in advsimd ld/st single element. */
232 1.1 christos { 13, 2 }, /* len: in advsimd tbl/tbx instructions. */
233 1.1 christos { 16, 5 }, /* Rm: in ld/st reg offset and some integer inst. */
234 1.1 christos { 16, 5 }, /* Rs: in load/store exclusive instructions. */
235 1.1 christos { 13, 3 }, /* option: in ld/st reg offset + add/sub extended reg inst. */
236 1.1 christos { 12, 1 }, /* S: in load/store reg offset instructions. */
237 1.1 christos { 21, 2 }, /* hw: in move wide constant instructions. */
238 1.1 christos { 22, 2 }, /* opc: in load/store reg offset instructions. */
239 1.1 christos { 23, 1 }, /* opc1: in load/store reg offset instructions. */
240 1.1 christos { 22, 2 }, /* shift: in add/sub reg/imm shifted instructions. */
241 1.1 christos { 22, 2 }, /* type: floating point type field in fp data inst. */
242 1.1 christos { 30, 2 }, /* ldst_size: size field in ld/st reg offset inst. */
243 1.8 christos { 10, 6 }, /* imm6: in add/sub reg shifted instructions. */
244 1.1 christos { 15, 6 }, /* imm6_2: in rmif instructions. */
245 1.8 christos { 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
246 1.8 christos { 0, 4 }, /* imm4_2: in rmif instructions. */
247 1.1 christos { 10, 4 }, /* imm4_3: in adddg/subg instructions. */
248 1.1 christos { 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
249 1.1 christos { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
250 1.1 christos { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
251 1.1 christos { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
252 1.1 christos { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
253 1.1 christos { 5, 14 }, /* imm14: in test bit and branch instructions. */
254 1.9 christos { 5, 16 }, /* imm16: in exception instructions. */
255 1.1 christos { 0, 16 }, /* imm16_2: in udf instruction. */
256 1.1 christos { 0, 26 }, /* imm26: in unconditional branch instructions. */
257 1.1 christos { 10, 6 }, /* imms: in bitfield and logical immediate instructions. */
258 1.1 christos { 16, 6 }, /* immr: in bitfield and logical immediate instructions. */
259 1.1 christos { 16, 3 }, /* immb: in advsimd shift by immediate instructions. */
260 1.7 christos { 19, 4 }, /* immh: in advsimd shift by immediate instructions. */
261 1.1 christos { 22, 1 }, /* S: in LDRAA and LDRAB instructions. */
262 1.1 christos { 22, 1 }, /* N: in logical (immediate) instructions. */
263 1.1 christos { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
264 1.1 christos { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
265 1.3 christos { 31, 1 }, /* sf: in integer data processing instructions. */
266 1.1 christos { 30, 1 }, /* lse_size: in LSE extension atomic instructions. */
267 1.1 christos { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
268 1.1 christos { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
269 1.1 christos { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
270 1.1 christos { 31, 1 }, /* b5: in the test bit and branch instructions. */
271 1.1 christos { 19, 5 }, /* b40: in the test bit and branch instructions. */
272 1.7 christos { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
273 1.7 christos { 4, 1 }, /* SVE_M_4: Merge/zero select, bit 4. */
274 1.7 christos { 14, 1 }, /* SVE_M_14: Merge/zero select, bit 14. */
275 1.7 christos { 16, 1 }, /* SVE_M_16: Merge/zero select, bit 16. */
276 1.7 christos { 17, 1 }, /* SVE_N: SVE equivalent of N. */
277 1.7 christos { 0, 4 }, /* SVE_Pd: p0-p15, bits [3,0]. */
278 1.7 christos { 10, 3 }, /* SVE_Pg3: p0-p7, bits [12,10]. */
279 1.7 christos { 5, 4 }, /* SVE_Pg4_5: p0-p15, bits [8,5]. */
280 1.7 christos { 10, 4 }, /* SVE_Pg4_10: p0-p15, bits [13,10]. */
281 1.7 christos { 16, 4 }, /* SVE_Pg4_16: p0-p15, bits [19,16]. */
282 1.7 christos { 16, 4 }, /* SVE_Pm: p0-p15, bits [19,16]. */
283 1.7 christos { 5, 4 }, /* SVE_Pn: p0-p15, bits [8,5]. */
284 1.7 christos { 0, 4 }, /* SVE_Pt: p0-p15, bits [3,0]. */
285 1.7 christos { 5, 5 }, /* SVE_Rm: SVE alternative position for Rm. */
286 1.7 christos { 16, 5 }, /* SVE_Rn: SVE alternative position for Rn. */
287 1.7 christos { 0, 5 }, /* SVE_Vd: Scalar SIMD&FP register, bits [4,0]. */
288 1.7 christos { 5, 5 }, /* SVE_Vm: Scalar SIMD&FP register, bits [9,5]. */
289 1.7 christos { 5, 5 }, /* SVE_Vn: Scalar SIMD&FP register, bits [9,5]. */
290 1.7 christos { 5, 5 }, /* SVE_Za_5: SVE vector register, bits [9,5]. */
291 1.7 christos { 16, 5 }, /* SVE_Za_16: SVE vector register, bits [20,16]. */
292 1.7 christos { 0, 5 }, /* SVE_Zd: SVE vector register. bits [4,0]. */
293 1.7 christos { 5, 5 }, /* SVE_Zm_5: SVE vector register, bits [9,5]. */
294 1.7 christos { 16, 5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
295 1.7 christos { 5, 5 }, /* SVE_Zn: SVE vector register, bits [9,5]. */
296 1.7 christos { 0, 5 }, /* SVE_Zt: SVE vector register, bits [4,0]. */
297 1.7 christos { 5, 1 }, /* SVE_i1: single-bit immediate. */
298 1.9 christos { 22, 1 }, /* SVE_i3h: high bit of 3-bit immediate. */
299 1.9 christos { 11, 1 }, /* SVE_i3l: low bit of 3-bit immediate. */
300 1.9 christos { 19, 2 }, /* SVE_i3h2: two high bits of 3bit immediate, bits [20,19]. */
301 1.7 christos { 20, 1 }, /* SVE_i2h: high bit of 2bit immediate, bits. */
302 1.7 christos { 16, 3 }, /* SVE_imm3: 3-bit immediate field. */
303 1.7 christos { 16, 4 }, /* SVE_imm4: 4-bit immediate field. */
304 1.7 christos { 5, 5 }, /* SVE_imm5: 5-bit immediate field. */
305 1.7 christos { 16, 5 }, /* SVE_imm5b: secondary 5-bit immediate field. */
306 1.7 christos { 16, 6 }, /* SVE_imm6: 6-bit immediate field. */
307 1.7 christos { 14, 7 }, /* SVE_imm7: 7-bit immediate field. */
308 1.7 christos { 5, 8 }, /* SVE_imm8: 8-bit immediate field. */
309 1.7 christos { 5, 9 }, /* SVE_imm9: 9-bit immediate field. */
310 1.7 christos { 11, 6 }, /* SVE_immr: SVE equivalent of immr. */
311 1.7 christos { 5, 6 }, /* SVE_imms: SVE equivalent of imms. */
312 1.7 christos { 10, 2 }, /* SVE_msz: 2-bit shift amount for ADR. */
313 1.7 christos { 5, 5 }, /* SVE_pattern: vector pattern enumeration. */
314 1.7 christos { 0, 4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD]. */
315 1.7 christos { 16, 1 }, /* SVE_rot1: 1-bit rotation amount. */
316 1.9 christos { 10, 2 }, /* SVE_rot2: 2-bit rotation amount. */
317 1.7 christos { 10, 1 }, /* SVE_rot3: 1-bit rotation amount at bit 10. */
318 1.9 christos { 22, 1 }, /* SVE_sz: 1-bit element size select. */
319 1.9 christos { 17, 2 }, /* SVE_size: 2-bit element size, bits [18,17]. */
320 1.7 christos { 30, 1 }, /* SVE_sz2: 1-bit element size select. */
321 1.7 christos { 16, 4 }, /* SVE_tsz: triangular size select. */
322 1.7 christos { 22, 2 }, /* SVE_tszh: triangular size select high, bits [23,22]. */
323 1.7 christos { 8, 2 }, /* SVE_tszl_8: triangular size select low, bits [9,8]. */
324 1.7 christos { 19, 2 }, /* SVE_tszl_19: triangular size select low, bits [20,19]. */
325 1.7 christos { 14, 1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14). */
326 1.7 christos { 22, 1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22). */
327 1.7 christos { 11, 2 }, /* rotate1: FCMLA immediate rotate. */
328 1.7 christos { 13, 2 }, /* rotate2: Indexed element FCMLA immediate rotate. */
329 1.8 christos { 12, 1 }, /* rotate3: FCADD immediate rotate. */
330 1.8 christos { 12, 2 }, /* SM3: Indexed element SM3 2 bits index immediate. */
331 1.1 christos { 22, 1 }, /* sz: 1-bit element size select. */
332 1.1 christos };
333 1.1 christos
334 1.1 christos enum aarch64_operand_class
335 1.1 christos aarch64_get_operand_class (enum aarch64_opnd type)
336 1.1 christos {
337 1.1 christos return aarch64_operands[type].op_class;
338 1.1 christos }
339 1.1 christos
340 1.1 christos const char *
341 1.1 christos aarch64_get_operand_name (enum aarch64_opnd type)
342 1.1 christos {
343 1.1 christos return aarch64_operands[type].name;
344 1.1 christos }
345 1.1 christos
346 1.1 christos /* Get operand description string.
347 1.1 christos This is usually for the diagnosis purpose. */
348 1.1 christos const char *
349 1.1 christos aarch64_get_operand_desc (enum aarch64_opnd type)
350 1.1 christos {
351 1.1 christos return aarch64_operands[type].desc;
352 1.1 christos }
353 1.1 christos
354 1.1 christos /* Table of all conditional affixes. */
355 1.1 christos const aarch64_cond aarch64_conds[16] =
356 1.7 christos {
357 1.7 christos {{"eq", "none"}, 0x0},
358 1.7 christos {{"ne", "any"}, 0x1},
359 1.7 christos {{"cs", "hs", "nlast"}, 0x2},
360 1.7 christos {{"cc", "lo", "ul", "last"}, 0x3},
361 1.7 christos {{"mi", "first"}, 0x4},
362 1.1 christos {{"pl", "nfrst"}, 0x5},
363 1.1 christos {{"vs"}, 0x6},
364 1.7 christos {{"vc"}, 0x7},
365 1.7 christos {{"hi", "pmore"}, 0x8},
366 1.7 christos {{"ls", "plast"}, 0x9},
367 1.7 christos {{"ge", "tcont"}, 0xa},
368 1.1 christos {{"lt", "tstop"}, 0xb},
369 1.1 christos {{"gt"}, 0xc},
370 1.1 christos {{"le"}, 0xd},
371 1.1 christos {{"al"}, 0xe},
372 1.1 christos {{"nv"}, 0xf},
373 1.1 christos };
374 1.1 christos
375 1.1 christos const aarch64_cond *
376 1.1 christos get_cond_from_value (aarch64_insn value)
377 1.1 christos {
378 1.1 christos assert (value < 16);
379 1.1 christos return &aarch64_conds[(unsigned int) value];
380 1.1 christos }
381 1.1 christos
382 1.1 christos const aarch64_cond *
383 1.1 christos get_inverted_cond (const aarch64_cond *cond)
384 1.1 christos {
385 1.1 christos return &aarch64_conds[cond->value ^ 0x1];
386 1.1 christos }
387 1.1 christos
388 1.1 christos /* Table describing the operand extension/shifting operators; indexed by
389 1.1 christos enum aarch64_modifier_kind.
390 1.1 christos
391 1.1 christos The value column provides the most common values for encoding modifiers,
392 1.1 christos which enables table-driven encoding/decoding for the modifiers. */
393 1.1 christos const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
394 1.1 christos {
395 1.1 christos {"none", 0x0},
396 1.1 christos {"msl", 0x0},
397 1.1 christos {"ror", 0x3},
398 1.1 christos {"asr", 0x2},
399 1.1 christos {"lsr", 0x1},
400 1.1 christos {"lsl", 0x0},
401 1.1 christos {"uxtb", 0x0},
402 1.1 christos {"uxth", 0x1},
403 1.1 christos {"uxtw", 0x2},
404 1.1 christos {"uxtx", 0x3},
405 1.1 christos {"sxtb", 0x4},
406 1.1 christos {"sxth", 0x5},
407 1.1 christos {"sxtw", 0x6},
408 1.7 christos {"sxtx", 0x7},
409 1.7 christos {"mul", 0x0},
410 1.1 christos {"mul vl", 0x0},
411 1.1 christos {NULL, 0},
412 1.1 christos };
413 1.1 christos
414 1.1 christos enum aarch64_modifier_kind
415 1.1 christos aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
416 1.1 christos {
417 1.1 christos return desc - aarch64_operand_modifiers;
418 1.1 christos }
419 1.1 christos
420 1.1 christos aarch64_insn
421 1.1 christos aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
422 1.1 christos {
423 1.1 christos return aarch64_operand_modifiers[kind].value;
424 1.1 christos }
425 1.1 christos
426 1.1 christos enum aarch64_modifier_kind
427 1.1 christos aarch64_get_operand_modifier_from_value (aarch64_insn value,
428 1.1 christos bfd_boolean extend_p)
429 1.1 christos {
430 1.1 christos if (extend_p == TRUE)
431 1.1 christos return AARCH64_MOD_UXTB + value;
432 1.1 christos else
433 1.1 christos return AARCH64_MOD_LSL - value;
434 1.1 christos }
435 1.1 christos
436 1.1 christos bfd_boolean
437 1.1 christos aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
438 1.1 christos {
439 1.1 christos return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
440 1.1 christos ? TRUE : FALSE;
441 1.1 christos }
442 1.1 christos
443 1.1 christos static inline bfd_boolean
444 1.1 christos aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
445 1.1 christos {
446 1.1 christos return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
447 1.1 christos ? TRUE : FALSE;
448 1.1 christos }
449 1.1 christos
450 1.1 christos const struct aarch64_name_value_pair aarch64_barrier_options[16] =
451 1.1 christos {
452 1.1 christos { "#0x00", 0x0 },
453 1.1 christos { "oshld", 0x1 },
454 1.1 christos { "oshst", 0x2 },
455 1.1 christos { "osh", 0x3 },
456 1.1 christos { "#0x04", 0x4 },
457 1.1 christos { "nshld", 0x5 },
458 1.1 christos { "nshst", 0x6 },
459 1.1 christos { "nsh", 0x7 },
460 1.1 christos { "#0x08", 0x8 },
461 1.1 christos { "ishld", 0x9 },
462 1.1 christos { "ishst", 0xa },
463 1.1 christos { "ish", 0xb },
464 1.1 christos { "#0x0c", 0xc },
465 1.1 christos { "ld", 0xd },
466 1.1 christos { "st", 0xe },
467 1.1 christos { "sy", 0xf },
468 1.1 christos };
469 1.6 christos
470 1.6 christos /* Table describing the operands supported by the aliases of the HINT
471 1.6 christos instruction.
472 1.6 christos
473 1.6 christos The name column is the operand that is accepted for the alias. The value
474 1.6 christos column is the hint number of the alias. The list of operands is terminated
475 1.6 christos by NULL in the name column. */
476 1.6 christos
477 1.6 christos const struct aarch64_name_value_pair aarch64_hint_options[] =
478 1.8 christos {
479 1.8 christos /* BTI. This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET. */
480 1.8 christos { " ", HINT_ENCODE (HINT_OPD_F_NOPRINT, 0x20) },
481 1.8 christos { "csync", HINT_OPD_CSYNC }, /* PSB CSYNC. */
482 1.8 christos { "c", HINT_OPD_C }, /* BTI C. */
483 1.8 christos { "j", HINT_OPD_J }, /* BTI J. */
484 1.8 christos { "jc", HINT_OPD_JC }, /* BTI JC. */
485 1.6 christos { NULL, HINT_OPD_NULL },
486 1.6 christos };
487 1.1 christos
488 1.1 christos /* op -> op: load = 0 instruction = 1 store = 2
489 1.1 christos l -> level: 1-3
490 1.1 christos t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
491 1.1 christos #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
492 1.1 christos const struct aarch64_name_value_pair aarch64_prfops[32] =
493 1.1 christos {
494 1.1 christos { "pldl1keep", B(0, 1, 0) },
495 1.1 christos { "pldl1strm", B(0, 1, 1) },
496 1.1 christos { "pldl2keep", B(0, 2, 0) },
497 1.1 christos { "pldl2strm", B(0, 2, 1) },
498 1.1 christos { "pldl3keep", B(0, 3, 0) },
499 1.1 christos { "pldl3strm", B(0, 3, 1) },
500 1.1 christos { NULL, 0x06 },
501 1.1 christos { NULL, 0x07 },
502 1.1 christos { "plil1keep", B(1, 1, 0) },
503 1.1 christos { "plil1strm", B(1, 1, 1) },
504 1.1 christos { "plil2keep", B(1, 2, 0) },
505 1.1 christos { "plil2strm", B(1, 2, 1) },
506 1.1 christos { "plil3keep", B(1, 3, 0) },
507 1.1 christos { "plil3strm", B(1, 3, 1) },
508 1.1 christos { NULL, 0x0e },
509 1.1 christos { NULL, 0x0f },
510 1.1 christos { "pstl1keep", B(2, 1, 0) },
511 1.1 christos { "pstl1strm", B(2, 1, 1) },
512 1.1 christos { "pstl2keep", B(2, 2, 0) },
513 1.1 christos { "pstl2strm", B(2, 2, 1) },
514 1.1 christos { "pstl3keep", B(2, 3, 0) },
515 1.1 christos { "pstl3strm", B(2, 3, 1) },
516 1.1 christos { NULL, 0x16 },
517 1.1 christos { NULL, 0x17 },
518 1.1 christos { NULL, 0x18 },
519 1.1 christos { NULL, 0x19 },
520 1.1 christos { NULL, 0x1a },
521 1.1 christos { NULL, 0x1b },
522 1.1 christos { NULL, 0x1c },
523 1.1 christos { NULL, 0x1d },
524 1.1 christos { NULL, 0x1e },
525 1.1 christos { NULL, 0x1f },
526 1.1 christos };
527 1.1 christos #undef B
528 1.1 christos
529 1.1 christos /* Utilities on value constraint. */
531 1.1 christos
532 1.1 christos static inline int
533 1.1 christos value_in_range_p (int64_t value, int low, int high)
534 1.1 christos {
535 1.1 christos return (value >= low && value <= high) ? 1 : 0;
536 1.7 christos }
537 1.1 christos
538 1.1 christos /* Return true if VALUE is a multiple of ALIGN. */
539 1.1 christos static inline int
540 1.7 christos value_aligned_p (int64_t value, int align)
541 1.1 christos {
542 1.1 christos return (value % align) == 0;
543 1.1 christos }
544 1.1 christos
545 1.1 christos /* A signed value fits in a field. */
546 1.1 christos static inline int
547 1.1 christos value_fit_signed_field_p (int64_t value, unsigned width)
548 1.1 christos {
549 1.1 christos assert (width < 32);
550 1.9 christos if (width < sizeof (value) * 8)
551 1.1 christos {
552 1.1 christos int64_t lim = (uint64_t) 1 << (width - 1);
553 1.1 christos if (value >= -lim && value < lim)
554 1.1 christos return 1;
555 1.1 christos }
556 1.1 christos return 0;
557 1.1 christos }
558 1.1 christos
559 1.1 christos /* An unsigned value fits in a field. */
560 1.1 christos static inline int
561 1.1 christos value_fit_unsigned_field_p (int64_t value, unsigned width)
562 1.1 christos {
563 1.1 christos assert (width < 32);
564 1.9 christos if (width < sizeof (value) * 8)
565 1.1 christos {
566 1.1 christos int64_t lim = (uint64_t) 1 << width;
567 1.1 christos if (value >= 0 && value < lim)
568 1.1 christos return 1;
569 1.1 christos }
570 1.1 christos return 0;
571 1.1 christos }
572 1.1 christos
573 1.1 christos /* Return 1 if OPERAND is SP or WSP. */
574 1.1 christos int
575 1.1 christos aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
576 1.1 christos {
577 1.1 christos return ((aarch64_get_operand_class (operand->type)
578 1.1 christos == AARCH64_OPND_CLASS_INT_REG)
579 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type)
580 1.1 christos && operand->reg.regno == 31);
581 1.1 christos }
582 1.1 christos
583 1.1 christos /* Return 1 if OPERAND is XZR or WZP. */
584 1.1 christos int
585 1.1 christos aarch64_zero_register_p (const aarch64_opnd_info *operand)
586 1.1 christos {
587 1.1 christos return ((aarch64_get_operand_class (operand->type)
588 1.1 christos == AARCH64_OPND_CLASS_INT_REG)
589 1.1 christos && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
590 1.1 christos && operand->reg.regno == 31);
591 1.1 christos }
592 1.1 christos
593 1.1 christos /* Return true if the operand *OPERAND that has the operand code
594 1.1 christos OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
595 1.1 christos qualified by the qualifier TARGET. */
596 1.1 christos
597 1.1 christos static inline int
598 1.1 christos operand_also_qualified_p (const struct aarch64_opnd_info *operand,
599 1.1 christos aarch64_opnd_qualifier_t target)
600 1.1 christos {
601 1.1 christos switch (operand->qualifier)
602 1.1 christos {
603 1.1 christos case AARCH64_OPND_QLF_W:
604 1.1 christos if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
605 1.1 christos return 1;
606 1.1 christos break;
607 1.1 christos case AARCH64_OPND_QLF_X:
608 1.1 christos if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
609 1.1 christos return 1;
610 1.1 christos break;
611 1.1 christos case AARCH64_OPND_QLF_WSP:
612 1.1 christos if (target == AARCH64_OPND_QLF_W
613 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type))
614 1.1 christos return 1;
615 1.1 christos break;
616 1.1 christos case AARCH64_OPND_QLF_SP:
617 1.1 christos if (target == AARCH64_OPND_QLF_X
618 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type))
619 1.1 christos return 1;
620 1.1 christos break;
621 1.1 christos default:
622 1.1 christos break;
623 1.1 christos }
624 1.1 christos
625 1.1 christos return 0;
626 1.1 christos }
627 1.1 christos
628 1.1 christos /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
629 1.1 christos for operand KNOWN_IDX, return the expected qualifier for operand IDX.
630 1.1 christos
631 1.1 christos Return NIL if more than one expected qualifiers are found. */
632 1.1 christos
633 1.1 christos aarch64_opnd_qualifier_t
634 1.1 christos aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
635 1.1 christos int idx,
636 1.1 christos const aarch64_opnd_qualifier_t known_qlf,
637 1.1 christos int known_idx)
638 1.1 christos {
639 1.1 christos int i, saved_i;
640 1.1 christos
641 1.1 christos /* Special case.
642 1.1 christos
643 1.1 christos When the known qualifier is NIL, we have to assume that there is only
644 1.1 christos one qualifier sequence in the *QSEQ_LIST and return the corresponding
645 1.1 christos qualifier directly. One scenario is that for instruction
646 1.1 christos PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
647 1.1 christos which has only one possible valid qualifier sequence
648 1.1 christos NIL, S_D
649 1.1 christos the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
650 1.1 christos determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
651 1.1 christos
652 1.1 christos Because the qualifier NIL has dual roles in the qualifier sequence:
653 1.1 christos it can mean no qualifier for the operand, or the qualifer sequence is
654 1.1 christos not in use (when all qualifiers in the sequence are NILs), we have to
655 1.1 christos handle this special case here. */
656 1.1 christos if (known_qlf == AARCH64_OPND_NIL)
657 1.1 christos {
658 1.1 christos assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
659 1.1 christos return qseq_list[0][idx];
660 1.1 christos }
661 1.1 christos
662 1.1 christos for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
663 1.1 christos {
664 1.1 christos if (qseq_list[i][known_idx] == known_qlf)
665 1.1 christos {
666 1.1 christos if (saved_i != -1)
667 1.1 christos /* More than one sequences are found to have KNOWN_QLF at
668 1.1 christos KNOWN_IDX. */
669 1.1 christos return AARCH64_OPND_NIL;
670 1.1 christos saved_i = i;
671 1.1 christos }
672 1.1 christos }
673 1.1 christos
674 1.1 christos return qseq_list[saved_i][idx];
675 1.1 christos }
676 1.1 christos
677 1.1 christos enum operand_qualifier_kind
678 1.1 christos {
679 1.1 christos OQK_NIL,
680 1.1 christos OQK_OPD_VARIANT,
681 1.1 christos OQK_VALUE_IN_RANGE,
682 1.1 christos OQK_MISC,
683 1.1 christos };
684 1.1 christos
685 1.1 christos /* Operand qualifier description. */
686 1.1 christos struct operand_qualifier_data
687 1.1 christos {
688 1.1 christos /* The usage of the three data fields depends on the qualifier kind. */
689 1.1 christos int data0;
690 1.1 christos int data1;
691 1.1 christos int data2;
692 1.1 christos /* Description. */
693 1.1 christos const char *desc;
694 1.1 christos /* Kind. */
695 1.1 christos enum operand_qualifier_kind kind;
696 1.1 christos };
697 1.1 christos
698 1.1 christos /* Indexed by the operand qualifier enumerators. */
699 1.1 christos struct operand_qualifier_data aarch64_opnd_qualifiers[] =
700 1.1 christos {
701 1.1 christos {0, 0, 0, "NIL", OQK_NIL},
702 1.1 christos
703 1.1 christos /* Operand variant qualifiers.
704 1.1 christos First 3 fields:
705 1.1 christos element size, number of elements and common value for encoding. */
706 1.1 christos
707 1.1 christos {4, 1, 0x0, "w", OQK_OPD_VARIANT},
708 1.1 christos {8, 1, 0x1, "x", OQK_OPD_VARIANT},
709 1.1 christos {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
710 1.1 christos {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
711 1.1 christos
712 1.1 christos {1, 1, 0x0, "b", OQK_OPD_VARIANT},
713 1.1 christos {2, 1, 0x1, "h", OQK_OPD_VARIANT},
714 1.1 christos {4, 1, 0x2, "s", OQK_OPD_VARIANT},
715 1.8 christos {8, 1, 0x3, "d", OQK_OPD_VARIANT},
716 1.9 christos {16, 1, 0x4, "q", OQK_OPD_VARIANT},
717 1.1 christos {4, 1, 0x0, "4b", OQK_OPD_VARIANT},
718 1.8 christos {4, 1, 0x0, "2h", OQK_OPD_VARIANT},
719 1.1 christos
720 1.1 christos {1, 4, 0x0, "4b", OQK_OPD_VARIANT},
721 1.6 christos {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
722 1.1 christos {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
723 1.1 christos {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
724 1.1 christos {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
725 1.1 christos {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
726 1.1 christos {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
727 1.1 christos {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
728 1.1 christos {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
729 1.1 christos {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
730 1.7 christos {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
731 1.7 christos
732 1.7 christos {0, 0, 0, "z", OQK_OPD_VARIANT},
733 1.8 christos {0, 0, 0, "m", OQK_OPD_VARIANT},
734 1.8 christos
735 1.8 christos /* Qualifier for scaled immediate for Tag granule (stg,st2g,etc). */
736 1.1 christos {16, 0, 0, "tag", OQK_OPD_VARIANT},
737 1.1 christos
738 1.1 christos /* Qualifiers constraining the value range.
739 1.1 christos First 3 fields:
740 1.7 christos Lower bound, higher bound, unused. */
741 1.1 christos
742 1.1 christos {0, 15, 0, "CR", OQK_VALUE_IN_RANGE},
743 1.1 christos {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
744 1.1 christos {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
745 1.1 christos {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
746 1.1 christos {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
747 1.1 christos {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
748 1.1 christos {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
749 1.1 christos
750 1.1 christos /* Qualifiers for miscellaneous purpose.
751 1.1 christos First 3 fields:
752 1.1 christos unused, unused and unused. */
753 1.1 christos
754 1.1 christos {0, 0, 0, "lsl", 0},
755 1.1 christos {0, 0, 0, "msl", 0},
756 1.1 christos
757 1.1 christos {0, 0, 0, "retrieving", 0},
758 1.1 christos };
759 1.1 christos
760 1.1 christos static inline bfd_boolean
761 1.1 christos operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
762 1.1 christos {
763 1.1 christos return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
764 1.1 christos ? TRUE : FALSE;
765 1.1 christos }
766 1.1 christos
767 1.1 christos static inline bfd_boolean
768 1.1 christos qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
769 1.1 christos {
770 1.1 christos return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
771 1.1 christos ? TRUE : FALSE;
772 1.1 christos }
773 1.1 christos
774 1.1 christos const char*
775 1.1 christos aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
776 1.1 christos {
777 1.1 christos return aarch64_opnd_qualifiers[qualifier].desc;
778 1.1 christos }
779 1.1 christos
780 1.1 christos /* Given an operand qualifier, return the expected data element size
781 1.1 christos of a qualified operand. */
782 1.1 christos unsigned char
783 1.1 christos aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
784 1.1 christos {
785 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
786 1.1 christos return aarch64_opnd_qualifiers[qualifier].data0;
787 1.1 christos }
788 1.1 christos
789 1.1 christos unsigned char
790 1.1 christos aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
791 1.1 christos {
792 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
793 1.1 christos return aarch64_opnd_qualifiers[qualifier].data1;
794 1.1 christos }
795 1.1 christos
796 1.1 christos aarch64_insn
797 1.1 christos aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
798 1.1 christos {
799 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
800 1.1 christos return aarch64_opnd_qualifiers[qualifier].data2;
801 1.1 christos }
802 1.1 christos
803 1.1 christos static int
804 1.1 christos get_lower_bound (aarch64_opnd_qualifier_t qualifier)
805 1.1 christos {
806 1.1 christos assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
807 1.1 christos return aarch64_opnd_qualifiers[qualifier].data0;
808 1.1 christos }
809 1.1 christos
810 1.1 christos static int
811 1.1 christos get_upper_bound (aarch64_opnd_qualifier_t qualifier)
812 1.1 christos {
813 1.1 christos assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
814 1.1 christos return aarch64_opnd_qualifiers[qualifier].data1;
815 1.1 christos }
816 1.1 christos
817 1.1 christos #ifdef DEBUG_AARCH64
818 1.1 christos void
819 1.1 christos aarch64_verbose (const char *str, ...)
820 1.1 christos {
821 1.1 christos va_list ap;
822 1.1 christos va_start (ap, str);
823 1.1 christos printf ("#### ");
824 1.1 christos vprintf (str, ap);
825 1.1 christos printf ("\n");
826 1.1 christos va_end (ap);
827 1.1 christos }
828 1.1 christos
829 1.1 christos static inline void
830 1.1 christos dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
831 1.1 christos {
832 1.1 christos int i;
833 1.1 christos printf ("#### \t");
834 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
835 1.1 christos printf ("%s,", aarch64_get_qualifier_name (*qualifier));
836 1.1 christos printf ("\n");
837 1.1 christos }
838 1.1 christos
839 1.1 christos static void
840 1.1 christos dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
841 1.1 christos const aarch64_opnd_qualifier_t *qualifier)
842 1.1 christos {
843 1.1 christos int i;
844 1.1 christos aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
845 1.1 christos
846 1.1 christos aarch64_verbose ("dump_match_qualifiers:");
847 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
848 1.1 christos curr[i] = opnd[i].qualifier;
849 1.1 christos dump_qualifier_sequence (curr);
850 1.1 christos aarch64_verbose ("against");
851 1.1 christos dump_qualifier_sequence (qualifier);
852 1.1 christos }
853 1.8 christos #endif /* DEBUG_AARCH64 */
854 1.8 christos
855 1.8 christos /* This function checks if the given instruction INSN is a destructive
856 1.8 christos instruction based on the usage of the registers. It does not recognize
857 1.8 christos unary destructive instructions. */
858 1.8 christos bfd_boolean
859 1.8 christos aarch64_is_destructive_by_operands (const aarch64_opcode *opcode)
860 1.8 christos {
861 1.8 christos int i = 0;
862 1.8 christos const enum aarch64_opnd *opnds = opcode->operands;
863 1.8 christos
864 1.8 christos if (opnds[0] == AARCH64_OPND_NIL)
865 1.8 christos return FALSE;
866 1.8 christos
867 1.8 christos while (opnds[++i] != AARCH64_OPND_NIL)
868 1.8 christos if (opnds[i] == opnds[0])
869 1.8 christos return TRUE;
870 1.8 christos
871 1.8 christos return FALSE;
872 1.1 christos }
873 1.1 christos
874 1.1 christos /* TODO improve this, we can have an extra field at the runtime to
875 1.1 christos store the number of operands rather than calculating it every time. */
876 1.1 christos
877 1.1 christos int
878 1.1 christos aarch64_num_of_operands (const aarch64_opcode *opcode)
879 1.1 christos {
880 1.1 christos int i = 0;
881 1.1 christos const enum aarch64_opnd *opnds = opcode->operands;
882 1.1 christos while (opnds[i++] != AARCH64_OPND_NIL)
883 1.1 christos ;
884 1.1 christos --i;
885 1.1 christos assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
886 1.1 christos return i;
887 1.1 christos }
888 1.1 christos
889 1.1 christos /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
890 1.1 christos If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
891 1.1 christos
892 1.1 christos N.B. on the entry, it is very likely that only some operands in *INST
893 1.1 christos have had their qualifiers been established.
894 1.1 christos
895 1.1 christos If STOP_AT is not -1, the function will only try to match
896 1.1 christos the qualifier sequence for operands before and including the operand
897 1.1 christos of index STOP_AT; and on success *RET will only be filled with the first
898 1.1 christos (STOP_AT+1) qualifiers.
899 1.1 christos
900 1.1 christos A couple examples of the matching algorithm:
901 1.1 christos
902 1.1 christos X,W,NIL should match
903 1.1 christos X,W,NIL
904 1.1 christos
905 1.1 christos NIL,NIL should match
906 1.1 christos X ,NIL
907 1.1 christos
908 1.1 christos Apart from serving the main encoding routine, this can also be called
909 1.1 christos during or after the operand decoding. */
910 1.1 christos
911 1.1 christos int
912 1.1 christos aarch64_find_best_match (const aarch64_inst *inst,
913 1.1 christos const aarch64_opnd_qualifier_seq_t *qualifiers_list,
914 1.1 christos int stop_at, aarch64_opnd_qualifier_t *ret)
915 1.1 christos {
916 1.1 christos int found = 0;
917 1.1 christos int i, num_opnds;
918 1.1 christos const aarch64_opnd_qualifier_t *qualifiers;
919 1.1 christos
920 1.1 christos num_opnds = aarch64_num_of_operands (inst->opcode);
921 1.1 christos if (num_opnds == 0)
922 1.1 christos {
923 1.1 christos DEBUG_TRACE ("SUCCEED: no operand");
924 1.1 christos return 1;
925 1.1 christos }
926 1.1 christos
927 1.1 christos if (stop_at < 0 || stop_at >= num_opnds)
928 1.1 christos stop_at = num_opnds - 1;
929 1.1 christos
930 1.1 christos /* For each pattern. */
931 1.1 christos for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
932 1.1 christos {
933 1.1 christos int j;
934 1.1 christos qualifiers = *qualifiers_list;
935 1.1 christos
936 1.1 christos /* Start as positive. */
937 1.1 christos found = 1;
938 1.1 christos
939 1.1 christos DEBUG_TRACE ("%d", i);
940 1.1 christos #ifdef DEBUG_AARCH64
941 1.1 christos if (debug_dump)
942 1.1 christos dump_match_qualifiers (inst->operands, qualifiers);
943 1.1 christos #endif
944 1.1 christos
945 1.1 christos /* Most opcodes has much fewer patterns in the list.
946 1.1 christos First NIL qualifier indicates the end in the list. */
947 1.1 christos if (empty_qualifier_sequence_p (qualifiers) == TRUE)
948 1.1 christos {
949 1.1 christos DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
950 1.1 christos if (i)
951 1.1 christos found = 0;
952 1.1 christos break;
953 1.1 christos }
954 1.1 christos
955 1.1 christos for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
956 1.1 christos {
957 1.1 christos if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
958 1.1 christos {
959 1.1 christos /* Either the operand does not have qualifier, or the qualifier
960 1.1 christos for the operand needs to be deduced from the qualifier
961 1.1 christos sequence.
962 1.1 christos In the latter case, any constraint checking related with
963 1.1 christos the obtained qualifier should be done later in
964 1.1 christos operand_general_constraint_met_p. */
965 1.1 christos continue;
966 1.1 christos }
967 1.1 christos else if (*qualifiers != inst->operands[j].qualifier)
968 1.1 christos {
969 1.1 christos /* Unless the target qualifier can also qualify the operand
970 1.1 christos (which has already had a non-nil qualifier), non-equal
971 1.1 christos qualifiers are generally un-matched. */
972 1.1 christos if (operand_also_qualified_p (inst->operands + j, *qualifiers))
973 1.1 christos continue;
974 1.1 christos else
975 1.1 christos {
976 1.1 christos found = 0;
977 1.1 christos break;
978 1.1 christos }
979 1.1 christos }
980 1.1 christos else
981 1.1 christos continue; /* Equal qualifiers are certainly matched. */
982 1.1 christos }
983 1.1 christos
984 1.1 christos /* Qualifiers established. */
985 1.1 christos if (found == 1)
986 1.1 christos break;
987 1.1 christos }
988 1.1 christos
989 1.1 christos if (found == 1)
990 1.1 christos {
991 1.1 christos /* Fill the result in *RET. */
992 1.1 christos int j;
993 1.1 christos qualifiers = *qualifiers_list;
994 1.1 christos
995 1.1 christos DEBUG_TRACE ("complete qualifiers using list %d", i);
996 1.1 christos #ifdef DEBUG_AARCH64
997 1.1 christos if (debug_dump)
998 1.1 christos dump_qualifier_sequence (qualifiers);
999 1.1 christos #endif
1000 1.1 christos
1001 1.1 christos for (j = 0; j <= stop_at; ++j, ++qualifiers)
1002 1.1 christos ret[j] = *qualifiers;
1003 1.1 christos for (; j < AARCH64_MAX_OPND_NUM; ++j)
1004 1.1 christos ret[j] = AARCH64_OPND_QLF_NIL;
1005 1.1 christos
1006 1.1 christos DEBUG_TRACE ("SUCCESS");
1007 1.1 christos return 1;
1008 1.1 christos }
1009 1.1 christos
1010 1.1 christos DEBUG_TRACE ("FAIL");
1011 1.1 christos return 0;
1012 1.1 christos }
1013 1.1 christos
1014 1.1 christos /* Operand qualifier matching and resolving.
1015 1.1 christos
1016 1.1 christos Return 1 if the operand qualifier(s) in *INST match one of the qualifier
1017 1.1 christos sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
1018 1.1 christos
1019 1.1 christos if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
1020 1.1 christos succeeds. */
1021 1.1 christos
1022 1.1 christos static int
1023 1.7 christos match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
1024 1.1 christos {
1025 1.1 christos int i, nops;
1026 1.1 christos aarch64_opnd_qualifier_seq_t qualifiers;
1027 1.1 christos
1028 1.1 christos if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
1029 1.1 christos qualifiers))
1030 1.1 christos {
1031 1.1 christos DEBUG_TRACE ("matching FAIL");
1032 1.1 christos return 0;
1033 1.7 christos }
1034 1.7 christos
1035 1.7 christos if (inst->opcode->flags & F_STRICT)
1036 1.7 christos {
1037 1.7 christos /* Require an exact qualifier match, even for NIL qualifiers. */
1038 1.7 christos nops = aarch64_num_of_operands (inst->opcode);
1039 1.7 christos for (i = 0; i < nops; ++i)
1040 1.7 christos if (inst->operands[i].qualifier != qualifiers[i])
1041 1.7 christos return FALSE;
1042 1.1 christos }
1043 1.1 christos
1044 1.1 christos /* Update the qualifiers. */
1045 1.1 christos if (update_p == TRUE)
1046 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
1047 1.1 christos {
1048 1.1 christos if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
1049 1.1 christos break;
1050 1.1 christos DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
1051 1.1 christos "update %s with %s for operand %d",
1052 1.1 christos aarch64_get_qualifier_name (inst->operands[i].qualifier),
1053 1.1 christos aarch64_get_qualifier_name (qualifiers[i]), i);
1054 1.1 christos inst->operands[i].qualifier = qualifiers[i];
1055 1.1 christos }
1056 1.1 christos
1057 1.1 christos DEBUG_TRACE ("matching SUCCESS");
1058 1.1 christos return 1;
1059 1.1 christos }
1060 1.1 christos
1061 1.1 christos /* Return TRUE if VALUE is a wide constant that can be moved into a general
1062 1.1 christos register by MOVZ.
1063 1.1 christos
1064 1.1 christos IS32 indicates whether value is a 32-bit immediate or not.
1065 1.1 christos If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
1066 1.1 christos amount will be returned in *SHIFT_AMOUNT. */
1067 1.9 christos
1068 1.1 christos bfd_boolean
1069 1.1 christos aarch64_wide_constant_p (uint64_t value, int is32, unsigned int *shift_amount)
1070 1.1 christos {
1071 1.1 christos int amount;
1072 1.1 christos
1073 1.1 christos DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1074 1.1 christos
1075 1.1 christos if (is32)
1076 1.1 christos {
1077 1.1 christos /* Allow all zeros or all ones in top 32-bits, so that
1078 1.9 christos 32-bit constant expressions like ~0x80000000 are
1079 1.1 christos permitted. */
1080 1.1 christos if (value >> 32 != 0 && value >> 32 != 0xffffffff)
1081 1.9 christos /* Immediate out of range. */
1082 1.1 christos return FALSE;
1083 1.1 christos value &= 0xffffffff;
1084 1.1 christos }
1085 1.1 christos
1086 1.9 christos /* first, try movz then movn */
1087 1.1 christos amount = -1;
1088 1.9 christos if ((value & ((uint64_t) 0xffff << 0)) == value)
1089 1.1 christos amount = 0;
1090 1.9 christos else if ((value & ((uint64_t) 0xffff << 16)) == value)
1091 1.1 christos amount = 16;
1092 1.9 christos else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
1093 1.1 christos amount = 32;
1094 1.1 christos else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
1095 1.1 christos amount = 48;
1096 1.1 christos
1097 1.1 christos if (amount == -1)
1098 1.1 christos {
1099 1.1 christos DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1100 1.1 christos return FALSE;
1101 1.1 christos }
1102 1.1 christos
1103 1.1 christos if (shift_amount != NULL)
1104 1.1 christos *shift_amount = amount;
1105 1.1 christos
1106 1.1 christos DEBUG_TRACE ("exit TRUE with amount %d", amount);
1107 1.1 christos
1108 1.1 christos return TRUE;
1109 1.1 christos }
1110 1.1 christos
1111 1.1 christos /* Build the accepted values for immediate logical SIMD instructions.
1112 1.1 christos
1113 1.1 christos The standard encodings of the immediate value are:
1114 1.1 christos N imms immr SIMD size R S
1115 1.1 christos 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
1116 1.1 christos 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
1117 1.1 christos 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
1118 1.1 christos 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
1119 1.1 christos 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
1120 1.1 christos 0 11110s 00000r 2 UInt(r) UInt(s)
1121 1.1 christos where all-ones value of S is reserved.
1122 1.1 christos
1123 1.1 christos Let's call E the SIMD size.
1124 1.1 christos
1125 1.1 christos The immediate value is: S+1 bits '1' rotated to the right by R.
1126 1.1 christos
1127 1.1 christos The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
1128 1.1 christos (remember S != E - 1). */
1129 1.1 christos
1130 1.1 christos #define TOTAL_IMM_NB 5334
1131 1.1 christos
1132 1.1 christos typedef struct
1133 1.1 christos {
1134 1.1 christos uint64_t imm;
1135 1.1 christos aarch64_insn encoding;
1136 1.1 christos } simd_imm_encoding;
1137 1.1 christos
1138 1.1 christos static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
1139 1.1 christos
1140 1.1 christos static int
1141 1.1 christos simd_imm_encoding_cmp(const void *i1, const void *i2)
1142 1.1 christos {
1143 1.1 christos const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
1144 1.1 christos const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
1145 1.1 christos
1146 1.1 christos if (imm1->imm < imm2->imm)
1147 1.1 christos return -1;
1148 1.1 christos if (imm1->imm > imm2->imm)
1149 1.1 christos return +1;
1150 1.1 christos return 0;
1151 1.1 christos }
1152 1.1 christos
1153 1.1 christos /* immediate bitfield standard encoding
1154 1.1 christos imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
1155 1.1 christos 1 ssssss rrrrrr 64 rrrrrr ssssss
1156 1.1 christos 0 0sssss 0rrrrr 32 rrrrr sssss
1157 1.1 christos 0 10ssss 00rrrr 16 rrrr ssss
1158 1.1 christos 0 110sss 000rrr 8 rrr sss
1159 1.1 christos 0 1110ss 0000rr 4 rr ss
1160 1.1 christos 0 11110s 00000r 2 r s */
1161 1.1 christos static inline int
1162 1.1 christos encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
1163 1.1 christos {
1164 1.1 christos return (is64 << 12) | (r << 6) | s;
1165 1.1 christos }
1166 1.1 christos
1167 1.1 christos static void
1168 1.1 christos build_immediate_table (void)
1169 1.1 christos {
1170 1.1 christos uint32_t log_e, e, s, r, s_mask;
1171 1.1 christos uint64_t mask, imm;
1172 1.1 christos int nb_imms;
1173 1.1 christos int is64;
1174 1.1 christos
1175 1.1 christos nb_imms = 0;
1176 1.1 christos for (log_e = 1; log_e <= 6; log_e++)
1177 1.1 christos {
1178 1.1 christos /* Get element size. */
1179 1.1 christos e = 1u << log_e;
1180 1.1 christos if (log_e == 6)
1181 1.1 christos {
1182 1.1 christos is64 = 1;
1183 1.1 christos mask = 0xffffffffffffffffull;
1184 1.1 christos s_mask = 0;
1185 1.1 christos }
1186 1.1 christos else
1187 1.1 christos {
1188 1.1 christos is64 = 0;
1189 1.1 christos mask = (1ull << e) - 1;
1190 1.1 christos /* log_e s_mask
1191 1.1 christos 1 ((1 << 4) - 1) << 2 = 111100
1192 1.1 christos 2 ((1 << 3) - 1) << 3 = 111000
1193 1.1 christos 3 ((1 << 2) - 1) << 4 = 110000
1194 1.1 christos 4 ((1 << 1) - 1) << 5 = 100000
1195 1.1 christos 5 ((1 << 0) - 1) << 6 = 000000 */
1196 1.1 christos s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1197 1.1 christos }
1198 1.1 christos for (s = 0; s < e - 1; s++)
1199 1.1 christos for (r = 0; r < e; r++)
1200 1.1 christos {
1201 1.1 christos /* s+1 consecutive bits to 1 (s < 63) */
1202 1.1 christos imm = (1ull << (s + 1)) - 1;
1203 1.1 christos /* rotate right by r */
1204 1.1 christos if (r != 0)
1205 1.1 christos imm = (imm >> r) | ((imm << (e - r)) & mask);
1206 1.1 christos /* replicate the constant depending on SIMD size */
1207 1.1 christos switch (log_e)
1208 1.7 christos {
1209 1.1 christos case 1: imm = (imm << 2) | imm;
1210 1.7 christos /* Fall through. */
1211 1.1 christos case 2: imm = (imm << 4) | imm;
1212 1.7 christos /* Fall through. */
1213 1.1 christos case 3: imm = (imm << 8) | imm;
1214 1.7 christos /* Fall through. */
1215 1.1 christos case 4: imm = (imm << 16) | imm;
1216 1.7 christos /* Fall through. */
1217 1.1 christos case 5: imm = (imm << 32) | imm;
1218 1.1 christos /* Fall through. */
1219 1.1 christos case 6: break;
1220 1.1 christos default: abort ();
1221 1.1 christos }
1222 1.1 christos simd_immediates[nb_imms].imm = imm;
1223 1.1 christos simd_immediates[nb_imms].encoding =
1224 1.1 christos encode_immediate_bitfield(is64, s | s_mask, r);
1225 1.1 christos nb_imms++;
1226 1.1 christos }
1227 1.1 christos }
1228 1.1 christos assert (nb_imms == TOTAL_IMM_NB);
1229 1.1 christos qsort(simd_immediates, nb_imms,
1230 1.1 christos sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1231 1.1 christos }
1232 1.1 christos
1233 1.1 christos /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1234 1.1 christos be accepted by logical (immediate) instructions
1235 1.7 christos e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1236 1.1 christos
1237 1.1 christos ESIZE is the number of bytes in the decoded immediate value.
1238 1.1 christos If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1239 1.1 christos VALUE will be returned in *ENCODING. */
1240 1.7 christos
1241 1.1 christos bfd_boolean
1242 1.1 christos aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
1243 1.1 christos {
1244 1.1 christos simd_imm_encoding imm_enc;
1245 1.7 christos const simd_imm_encoding *imm_encoding;
1246 1.7 christos static bfd_boolean initialized = FALSE;
1247 1.1 christos uint64_t upper;
1248 1.8 christos int i;
1249 1.8 christos
1250 1.1 christos DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1251 1.8 christos value, esize);
1252 1.1 christos
1253 1.1 christos if (!initialized)
1254 1.1 christos {
1255 1.1 christos build_immediate_table ();
1256 1.1 christos initialized = TRUE;
1257 1.7 christos }
1258 1.7 christos
1259 1.7 christos /* Allow all zeros or all ones in top bits, so that
1260 1.7 christos constant expressions like ~1 are permitted. */
1261 1.7 christos upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1262 1.1 christos if ((value & ~upper) != value && (value | upper) != value)
1263 1.7 christos return FALSE;
1264 1.7 christos
1265 1.7 christos /* Replicate to a full 64-bit value. */
1266 1.7 christos value &= ~upper;
1267 1.1 christos for (i = esize * 8; i < 64; i *= 2)
1268 1.1 christos value |= (value << i);
1269 1.1 christos
1270 1.1 christos imm_enc.imm = value;
1271 1.1 christos imm_encoding = (const simd_imm_encoding *)
1272 1.1 christos bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1273 1.1 christos sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1274 1.1 christos if (imm_encoding == NULL)
1275 1.1 christos {
1276 1.1 christos DEBUG_TRACE ("exit with FALSE");
1277 1.1 christos return FALSE;
1278 1.1 christos }
1279 1.1 christos if (encoding != NULL)
1280 1.1 christos *encoding = imm_encoding->encoding;
1281 1.1 christos DEBUG_TRACE ("exit with TRUE");
1282 1.1 christos return TRUE;
1283 1.1 christos }
1284 1.1 christos
1285 1.1 christos /* If 64-bit immediate IMM is in the format of
1286 1.1 christos "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1287 1.1 christos where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1288 1.1 christos of value "abcdefgh". Otherwise return -1. */
1289 1.1 christos int
1290 1.1 christos aarch64_shrink_expanded_imm8 (uint64_t imm)
1291 1.1 christos {
1292 1.1 christos int i, ret;
1293 1.1 christos uint32_t byte;
1294 1.1 christos
1295 1.1 christos ret = 0;
1296 1.1 christos for (i = 0; i < 8; i++)
1297 1.1 christos {
1298 1.1 christos byte = (imm >> (8 * i)) & 0xff;
1299 1.1 christos if (byte == 0xff)
1300 1.1 christos ret |= 1 << i;
1301 1.1 christos else if (byte != 0x00)
1302 1.1 christos return -1;
1303 1.1 christos }
1304 1.1 christos return ret;
1305 1.1 christos }
1306 1.1 christos
1307 1.1 christos /* Utility inline functions for operand_general_constraint_met_p. */
1308 1.1 christos
1309 1.1 christos static inline void
1310 1.1 christos set_error (aarch64_operand_error *mismatch_detail,
1311 1.1 christos enum aarch64_operand_error_kind kind, int idx,
1312 1.1 christos const char* error)
1313 1.1 christos {
1314 1.1 christos if (mismatch_detail == NULL)
1315 1.1 christos return;
1316 1.1 christos mismatch_detail->kind = kind;
1317 1.1 christos mismatch_detail->index = idx;
1318 1.1 christos mismatch_detail->error = error;
1319 1.1 christos }
1320 1.1 christos
1321 1.1 christos static inline void
1322 1.1 christos set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1323 1.1 christos const char* error)
1324 1.1 christos {
1325 1.1 christos if (mismatch_detail == NULL)
1326 1.1 christos return;
1327 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1328 1.1 christos }
1329 1.1 christos
1330 1.1 christos static inline void
1331 1.1 christos set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1332 1.1 christos int idx, int lower_bound, int upper_bound,
1333 1.1 christos const char* error)
1334 1.1 christos {
1335 1.1 christos if (mismatch_detail == NULL)
1336 1.1 christos return;
1337 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1338 1.1 christos mismatch_detail->data[0] = lower_bound;
1339 1.1 christos mismatch_detail->data[1] = upper_bound;
1340 1.1 christos }
1341 1.1 christos
1342 1.1 christos static inline void
1343 1.1 christos set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1344 1.1 christos int idx, int lower_bound, int upper_bound)
1345 1.1 christos {
1346 1.1 christos if (mismatch_detail == NULL)
1347 1.1 christos return;
1348 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1349 1.1 christos _("immediate value"));
1350 1.1 christos }
1351 1.1 christos
1352 1.1 christos static inline void
1353 1.1 christos set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1354 1.1 christos int idx, int lower_bound, int upper_bound)
1355 1.1 christos {
1356 1.1 christos if (mismatch_detail == NULL)
1357 1.1 christos return;
1358 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1359 1.1 christos _("immediate offset"));
1360 1.1 christos }
1361 1.1 christos
1362 1.1 christos static inline void
1363 1.1 christos set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1364 1.1 christos int idx, int lower_bound, int upper_bound)
1365 1.1 christos {
1366 1.1 christos if (mismatch_detail == NULL)
1367 1.1 christos return;
1368 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1369 1.1 christos _("register number"));
1370 1.1 christos }
1371 1.1 christos
1372 1.1 christos static inline void
1373 1.1 christos set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1374 1.1 christos int idx, int lower_bound, int upper_bound)
1375 1.1 christos {
1376 1.1 christos if (mismatch_detail == NULL)
1377 1.1 christos return;
1378 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1379 1.1 christos _("register element index"));
1380 1.1 christos }
1381 1.1 christos
1382 1.1 christos static inline void
1383 1.1 christos set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1384 1.1 christos int idx, int lower_bound, int upper_bound)
1385 1.1 christos {
1386 1.1 christos if (mismatch_detail == NULL)
1387 1.1 christos return;
1388 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1389 1.1 christos _("shift amount"));
1390 1.7 christos }
1391 1.7 christos
1392 1.7 christos /* Report that the MUL modifier in operand IDX should be in the range
1393 1.7 christos [LOWER_BOUND, UPPER_BOUND]. */
1394 1.7 christos static inline void
1395 1.7 christos set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
1396 1.7 christos int idx, int lower_bound, int upper_bound)
1397 1.7 christos {
1398 1.7 christos if (mismatch_detail == NULL)
1399 1.7 christos return;
1400 1.7 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1401 1.7 christos _("multiplier"));
1402 1.1 christos }
1403 1.1 christos
1404 1.1 christos static inline void
1405 1.1 christos set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1406 1.1 christos int alignment)
1407 1.1 christos {
1408 1.1 christos if (mismatch_detail == NULL)
1409 1.1 christos return;
1410 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1411 1.1 christos mismatch_detail->data[0] = alignment;
1412 1.1 christos }
1413 1.1 christos
1414 1.1 christos static inline void
1415 1.1 christos set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1416 1.1 christos int expected_num)
1417 1.1 christos {
1418 1.1 christos if (mismatch_detail == NULL)
1419 1.1 christos return;
1420 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1421 1.1 christos mismatch_detail->data[0] = expected_num;
1422 1.1 christos }
1423 1.1 christos
1424 1.1 christos static inline void
1425 1.1 christos set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1426 1.1 christos const char* error)
1427 1.1 christos {
1428 1.1 christos if (mismatch_detail == NULL)
1429 1.1 christos return;
1430 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1431 1.1 christos }
1432 1.1 christos
1433 1.1 christos /* General constraint checking based on operand code.
1434 1.1 christos
1435 1.1 christos Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1436 1.1 christos as the IDXth operand of opcode OPCODE. Otherwise return 0.
1437 1.1 christos
1438 1.1 christos This function has to be called after the qualifiers for all operands
1439 1.1 christos have been resolved.
1440 1.1 christos
1441 1.1 christos Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1442 1.1 christos i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1443 1.1 christos of error message during the disassembling where error message is not
1444 1.1 christos wanted. We avoid the dynamic construction of strings of error messages
1445 1.1 christos here (i.e. in libopcodes), as it is costly and complicated; instead, we
1446 1.1 christos use a combination of error code, static string and some integer data to
1447 1.1 christos represent an error. */
1448 1.1 christos
1449 1.1 christos static int
1450 1.1 christos operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1451 1.1 christos enum aarch64_opnd type,
1452 1.1 christos const aarch64_opcode *opcode,
1453 1.7 christos aarch64_operand_error *mismatch_detail)
1454 1.1 christos {
1455 1.7 christos unsigned num, modifiers, shift;
1456 1.7 christos unsigned char size;
1457 1.1 christos int64_t imm, min_value, max_value;
1458 1.1 christos uint64_t uvalue, mask;
1459 1.1 christos const aarch64_opnd_info *opnd = opnds + idx;
1460 1.1 christos aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1461 1.1 christos
1462 1.1 christos assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1463 1.1 christos
1464 1.1 christos switch (aarch64_operands[type].op_class)
1465 1.3 christos {
1466 1.3 christos case AARCH64_OPND_CLASS_INT_REG:
1467 1.3 christos /* Check pair reg constraints for cas* instructions. */
1468 1.3 christos if (type == AARCH64_OPND_PAIRREG)
1469 1.3 christos {
1470 1.3 christos assert (idx == 1 || idx == 3);
1471 1.3 christos if (opnds[idx - 1].reg.regno % 2 != 0)
1472 1.3 christos {
1473 1.3 christos set_syntax_error (mismatch_detail, idx - 1,
1474 1.3 christos _("reg pair must start from even reg"));
1475 1.3 christos return 0;
1476 1.3 christos }
1477 1.3 christos if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1478 1.3 christos {
1479 1.3 christos set_syntax_error (mismatch_detail, idx,
1480 1.3 christos _("reg pair must be contiguous"));
1481 1.3 christos return 0;
1482 1.3 christos }
1483 1.3 christos break;
1484 1.1 christos }
1485 1.1 christos
1486 1.1 christos /* <Xt> may be optional in some IC and TLBI instructions. */
1487 1.1 christos if (type == AARCH64_OPND_Rt_SYS)
1488 1.1 christos {
1489 1.6 christos assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1490 1.6 christos == AARCH64_OPND_CLASS_SYSTEM));
1491 1.1 christos if (opnds[1].present
1492 1.1 christos && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1493 1.1 christos {
1494 1.1 christos set_other_error (mismatch_detail, idx, _("extraneous register"));
1495 1.6 christos return 0;
1496 1.6 christos }
1497 1.1 christos if (!opnds[1].present
1498 1.1 christos && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1499 1.1 christos {
1500 1.1 christos set_other_error (mismatch_detail, idx, _("missing register"));
1501 1.1 christos return 0;
1502 1.1 christos }
1503 1.1 christos }
1504 1.1 christos switch (qualifier)
1505 1.1 christos {
1506 1.1 christos case AARCH64_OPND_QLF_WSP:
1507 1.1 christos case AARCH64_OPND_QLF_SP:
1508 1.1 christos if (!aarch64_stack_pointer_p (opnd))
1509 1.1 christos {
1510 1.1 christos set_other_error (mismatch_detail, idx,
1511 1.1 christos _("stack pointer register expected"));
1512 1.1 christos return 0;
1513 1.1 christos }
1514 1.1 christos break;
1515 1.1 christos default:
1516 1.1 christos break;
1517 1.1 christos }
1518 1.7 christos break;
1519 1.7 christos
1520 1.7 christos case AARCH64_OPND_CLASS_SVE_REG:
1521 1.7 christos switch (type)
1522 1.7 christos {
1523 1.9 christos case AARCH64_OPND_SVE_Zm3_INDEX:
1524 1.9 christos case AARCH64_OPND_SVE_Zm3_22_INDEX:
1525 1.7 christos case AARCH64_OPND_SVE_Zm3_11_INDEX:
1526 1.7 christos case AARCH64_OPND_SVE_Zm4_11_INDEX:
1527 1.7 christos case AARCH64_OPND_SVE_Zm4_INDEX:
1528 1.7 christos size = get_operand_fields_width (get_operand_from_code (type));
1529 1.7 christos shift = get_operand_specific_data (&aarch64_operands[type]);
1530 1.7 christos mask = (1 << shift) - 1;
1531 1.7 christos if (opnd->reg.regno > mask)
1532 1.7 christos {
1533 1.7 christos assert (mask == 7 || mask == 15);
1534 1.7 christos set_other_error (mismatch_detail, idx,
1535 1.7 christos mask == 15
1536 1.7 christos ? _("z0-z15 expected")
1537 1.7 christos : _("z0-z7 expected"));
1538 1.9 christos return 0;
1539 1.7 christos }
1540 1.7 christos mask = (1u << (size - shift)) - 1;
1541 1.7 christos if (!value_in_range_p (opnd->reglane.index, 0, mask))
1542 1.7 christos {
1543 1.7 christos set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, mask);
1544 1.7 christos return 0;
1545 1.7 christos }
1546 1.7 christos break;
1547 1.7 christos
1548 1.7 christos case AARCH64_OPND_SVE_Zn_INDEX:
1549 1.7 christos size = aarch64_get_qualifier_esize (opnd->qualifier);
1550 1.7 christos if (!value_in_range_p (opnd->reglane.index, 0, 64 / size - 1))
1551 1.7 christos {
1552 1.7 christos set_elem_idx_out_of_range_error (mismatch_detail, idx,
1553 1.7 christos 0, 64 / size - 1);
1554 1.7 christos return 0;
1555 1.7 christos }
1556 1.7 christos break;
1557 1.7 christos
1558 1.7 christos case AARCH64_OPND_SVE_ZnxN:
1559 1.7 christos case AARCH64_OPND_SVE_ZtxN:
1560 1.7 christos if (opnd->reglist.num_regs != get_opcode_dependent_value (opcode))
1561 1.7 christos {
1562 1.7 christos set_other_error (mismatch_detail, idx,
1563 1.7 christos _("invalid register list"));
1564 1.7 christos return 0;
1565 1.7 christos }
1566 1.7 christos break;
1567 1.7 christos
1568 1.7 christos default:
1569 1.7 christos break;
1570 1.7 christos }
1571 1.7 christos break;
1572 1.7 christos
1573 1.7 christos case AARCH64_OPND_CLASS_PRED_REG:
1574 1.7 christos if (opnd->reg.regno >= 8
1575 1.7 christos && get_operand_fields_width (get_operand_from_code (type)) == 3)
1576 1.7 christos {
1577 1.7 christos set_other_error (mismatch_detail, idx, _("p0-p7 expected"));
1578 1.7 christos return 0;
1579 1.7 christos }
1580 1.1 christos break;
1581 1.1 christos
1582 1.1 christos case AARCH64_OPND_CLASS_COND:
1583 1.1 christos if (type == AARCH64_OPND_COND1
1584 1.1 christos && (opnds[idx].cond->value & 0xe) == 0xe)
1585 1.1 christos {
1586 1.1 christos /* Not allow AL or NV. */
1587 1.1 christos set_syntax_error (mismatch_detail, idx, NULL);
1588 1.1 christos }
1589 1.1 christos break;
1590 1.1 christos
1591 1.1 christos case AARCH64_OPND_CLASS_ADDRESS:
1592 1.1 christos /* Check writeback. */
1593 1.1 christos switch (opcode->iclass)
1594 1.1 christos {
1595 1.1 christos case ldst_pos:
1596 1.1 christos case ldst_unscaled:
1597 1.1 christos case ldstnapair_offs:
1598 1.1 christos case ldstpair_off:
1599 1.1 christos case ldst_unpriv:
1600 1.1 christos if (opnd->addr.writeback == 1)
1601 1.1 christos {
1602 1.1 christos set_syntax_error (mismatch_detail, idx,
1603 1.1 christos _("unexpected address writeback"));
1604 1.1 christos return 0;
1605 1.7 christos }
1606 1.7 christos break;
1607 1.7 christos case ldst_imm10:
1608 1.7 christos if (opnd->addr.writeback == 1 && opnd->addr.preind != 1)
1609 1.7 christos {
1610 1.7 christos set_syntax_error (mismatch_detail, idx,
1611 1.7 christos _("unexpected address writeback"));
1612 1.7 christos return 0;
1613 1.1 christos }
1614 1.1 christos break;
1615 1.1 christos case ldst_imm9:
1616 1.1 christos case ldstpair_indexed:
1617 1.1 christos case asisdlsep:
1618 1.1 christos case asisdlsop:
1619 1.1 christos if (opnd->addr.writeback == 0)
1620 1.1 christos {
1621 1.1 christos set_syntax_error (mismatch_detail, idx,
1622 1.1 christos _("address writeback expected"));
1623 1.1 christos return 0;
1624 1.1 christos }
1625 1.1 christos break;
1626 1.1 christos default:
1627 1.1 christos assert (opnd->addr.writeback == 0);
1628 1.1 christos break;
1629 1.1 christos }
1630 1.1 christos switch (type)
1631 1.1 christos {
1632 1.1 christos case AARCH64_OPND_ADDR_SIMM7:
1633 1.1 christos /* Scaled signed 7 bits immediate offset. */
1634 1.1 christos /* Get the size of the data element that is accessed, which may be
1635 1.1 christos different from that of the source register size,
1636 1.1 christos e.g. in strb/ldrb. */
1637 1.1 christos size = aarch64_get_qualifier_esize (opnd->qualifier);
1638 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1639 1.1 christos {
1640 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx,
1641 1.1 christos -64 * size, 63 * size);
1642 1.1 christos return 0;
1643 1.1 christos }
1644 1.1 christos if (!value_aligned_p (opnd->addr.offset.imm, size))
1645 1.1 christos {
1646 1.1 christos set_unaligned_error (mismatch_detail, idx, size);
1647 1.1 christos return 0;
1648 1.8 christos }
1649 1.1 christos break;
1650 1.1 christos case AARCH64_OPND_ADDR_OFFSET:
1651 1.1 christos case AARCH64_OPND_ADDR_SIMM9:
1652 1.1 christos /* Unscaled signed 9 bits immediate offset. */
1653 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1654 1.1 christos {
1655 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1656 1.1 christos return 0;
1657 1.1 christos }
1658 1.1 christos break;
1659 1.1 christos
1660 1.1 christos case AARCH64_OPND_ADDR_SIMM9_2:
1661 1.1 christos /* Unscaled signed 9 bits immediate offset, which has to be negative
1662 1.1 christos or unaligned. */
1663 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1664 1.1 christos if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1665 1.1 christos && !value_aligned_p (opnd->addr.offset.imm, size))
1666 1.1 christos || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1667 1.1 christos return 1;
1668 1.1 christos set_other_error (mismatch_detail, idx,
1669 1.1 christos _("negative or unaligned offset expected"));
1670 1.7 christos return 0;
1671 1.7 christos
1672 1.7 christos case AARCH64_OPND_ADDR_SIMM10:
1673 1.7 christos /* Scaled signed 10 bits immediate offset. */
1674 1.7 christos if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4088))
1675 1.7 christos {
1676 1.7 christos set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4088);
1677 1.7 christos return 0;
1678 1.7 christos }
1679 1.7 christos if (!value_aligned_p (opnd->addr.offset.imm, 8))
1680 1.7 christos {
1681 1.7 christos set_unaligned_error (mismatch_detail, idx, 8);
1682 1.7 christos return 0;
1683 1.7 christos }
1684 1.8 christos break;
1685 1.8 christos
1686 1.8 christos case AARCH64_OPND_ADDR_SIMM11:
1687 1.8 christos /* Signed 11 bits immediate offset (multiple of 16). */
1688 1.8 christos if (!value_in_range_p (opnd->addr.offset.imm, -1024, 1008))
1689 1.8 christos {
1690 1.8 christos set_offset_out_of_range_error (mismatch_detail, idx, -1024, 1008);
1691 1.8 christos return 0;
1692 1.8 christos }
1693 1.8 christos
1694 1.8 christos if (!value_aligned_p (opnd->addr.offset.imm, 16))
1695 1.8 christos {
1696 1.8 christos set_unaligned_error (mismatch_detail, idx, 16);
1697 1.8 christos return 0;
1698 1.8 christos }
1699 1.8 christos break;
1700 1.8 christos
1701 1.8 christos case AARCH64_OPND_ADDR_SIMM13:
1702 1.8 christos /* Signed 13 bits immediate offset (multiple of 16). */
1703 1.8 christos if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4080))
1704 1.8 christos {
1705 1.8 christos set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4080);
1706 1.8 christos return 0;
1707 1.8 christos }
1708 1.8 christos
1709 1.8 christos if (!value_aligned_p (opnd->addr.offset.imm, 16))
1710 1.8 christos {
1711 1.8 christos set_unaligned_error (mismatch_detail, idx, 16);
1712 1.8 christos return 0;
1713 1.8 christos }
1714 1.1 christos break;
1715 1.1 christos
1716 1.1 christos case AARCH64_OPND_SIMD_ADDR_POST:
1717 1.1 christos /* AdvSIMD load/store multiple structures, post-index. */
1718 1.1 christos assert (idx == 1);
1719 1.1 christos if (opnd->addr.offset.is_reg)
1720 1.1 christos {
1721 1.1 christos if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1722 1.1 christos return 1;
1723 1.1 christos else
1724 1.1 christos {
1725 1.1 christos set_other_error (mismatch_detail, idx,
1726 1.1 christos _("invalid register offset"));
1727 1.1 christos return 0;
1728 1.1 christos }
1729 1.1 christos }
1730 1.1 christos else
1731 1.1 christos {
1732 1.1 christos const aarch64_opnd_info *prev = &opnds[idx-1];
1733 1.1 christos unsigned num_bytes; /* total number of bytes transferred. */
1734 1.1 christos /* The opcode dependent area stores the number of elements in
1735 1.1 christos each structure to be loaded/stored. */
1736 1.1 christos int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1737 1.1 christos if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1738 1.1 christos /* Special handling of loading single structure to all lane. */
1739 1.1 christos num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1740 1.1 christos * aarch64_get_qualifier_esize (prev->qualifier);
1741 1.1 christos else
1742 1.1 christos num_bytes = prev->reglist.num_regs
1743 1.1 christos * aarch64_get_qualifier_esize (prev->qualifier)
1744 1.1 christos * aarch64_get_qualifier_nelem (prev->qualifier);
1745 1.1 christos if ((int) num_bytes != opnd->addr.offset.imm)
1746 1.1 christos {
1747 1.1 christos set_other_error (mismatch_detail, idx,
1748 1.1 christos _("invalid post-increment amount"));
1749 1.1 christos return 0;
1750 1.1 christos }
1751 1.1 christos }
1752 1.1 christos break;
1753 1.1 christos
1754 1.1 christos case AARCH64_OPND_ADDR_REGOFF:
1755 1.1 christos /* Get the size of the data element that is accessed, which may be
1756 1.1 christos different from that of the source register size,
1757 1.1 christos e.g. in strb/ldrb. */
1758 1.1 christos size = aarch64_get_qualifier_esize (opnd->qualifier);
1759 1.1 christos /* It is either no shift or shift by the binary logarithm of SIZE. */
1760 1.1 christos if (opnd->shifter.amount != 0
1761 1.1 christos && opnd->shifter.amount != (int)get_logsz (size))
1762 1.1 christos {
1763 1.1 christos set_other_error (mismatch_detail, idx,
1764 1.1 christos _("invalid shift amount"));
1765 1.1 christos return 0;
1766 1.1 christos }
1767 1.1 christos /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1768 1.1 christos operators. */
1769 1.1 christos switch (opnd->shifter.kind)
1770 1.1 christos {
1771 1.1 christos case AARCH64_MOD_UXTW:
1772 1.1 christos case AARCH64_MOD_LSL:
1773 1.1 christos case AARCH64_MOD_SXTW:
1774 1.1 christos case AARCH64_MOD_SXTX: break;
1775 1.1 christos default:
1776 1.1 christos set_other_error (mismatch_detail, idx,
1777 1.1 christos _("invalid extend/shift operator"));
1778 1.1 christos return 0;
1779 1.1 christos }
1780 1.1 christos break;
1781 1.1 christos
1782 1.1 christos case AARCH64_OPND_ADDR_UIMM12:
1783 1.1 christos imm = opnd->addr.offset.imm;
1784 1.1 christos /* Get the size of the data element that is accessed, which may be
1785 1.1 christos different from that of the source register size,
1786 1.1 christos e.g. in strb/ldrb. */
1787 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1788 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1789 1.1 christos {
1790 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx,
1791 1.1 christos 0, 4095 * size);
1792 1.1 christos return 0;
1793 1.1 christos }
1794 1.1 christos if (!value_aligned_p (opnd->addr.offset.imm, size))
1795 1.1 christos {
1796 1.1 christos set_unaligned_error (mismatch_detail, idx, size);
1797 1.1 christos return 0;
1798 1.1 christos }
1799 1.1 christos break;
1800 1.1 christos
1801 1.1 christos case AARCH64_OPND_ADDR_PCREL14:
1802 1.1 christos case AARCH64_OPND_ADDR_PCREL19:
1803 1.1 christos case AARCH64_OPND_ADDR_PCREL21:
1804 1.1 christos case AARCH64_OPND_ADDR_PCREL26:
1805 1.1 christos imm = opnd->imm.value;
1806 1.1 christos if (operand_need_shift_by_two (get_operand_from_code (type)))
1807 1.1 christos {
1808 1.1 christos /* The offset value in a PC-relative branch instruction is alway
1809 1.1 christos 4-byte aligned and is encoded without the lowest 2 bits. */
1810 1.1 christos if (!value_aligned_p (imm, 4))
1811 1.1 christos {
1812 1.1 christos set_unaligned_error (mismatch_detail, idx, 4);
1813 1.1 christos return 0;
1814 1.1 christos }
1815 1.1 christos /* Right shift by 2 so that we can carry out the following check
1816 1.1 christos canonically. */
1817 1.1 christos imm >>= 2;
1818 1.1 christos }
1819 1.1 christos size = get_operand_fields_width (get_operand_from_code (type));
1820 1.1 christos if (!value_fit_signed_field_p (imm, size))
1821 1.1 christos {
1822 1.1 christos set_other_error (mismatch_detail, idx,
1823 1.1 christos _("immediate out of range"));
1824 1.1 christos return 0;
1825 1.1 christos }
1826 1.7 christos break;
1827 1.7 christos
1828 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
1829 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
1830 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
1831 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
1832 1.7 christos min_value = -8;
1833 1.7 christos max_value = 7;
1834 1.7 christos sve_imm_offset_vl:
1835 1.7 christos assert (!opnd->addr.offset.is_reg);
1836 1.7 christos assert (opnd->addr.preind);
1837 1.7 christos num = 1 + get_operand_specific_data (&aarch64_operands[type]);
1838 1.7 christos min_value *= num;
1839 1.7 christos max_value *= num;
1840 1.7 christos if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
1841 1.7 christos || (opnd->shifter.operator_present
1842 1.7 christos && opnd->shifter.kind != AARCH64_MOD_MUL_VL))
1843 1.7 christos {
1844 1.7 christos set_other_error (mismatch_detail, idx,
1845 1.7 christos _("invalid addressing mode"));
1846 1.7 christos return 0;
1847 1.7 christos }
1848 1.7 christos if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1849 1.7 christos {
1850 1.7 christos set_offset_out_of_range_error (mismatch_detail, idx,
1851 1.7 christos min_value, max_value);
1852 1.7 christos return 0;
1853 1.7 christos }
1854 1.7 christos if (!value_aligned_p (opnd->addr.offset.imm, num))
1855 1.7 christos {
1856 1.7 christos set_unaligned_error (mismatch_detail, idx, num);
1857 1.7 christos return 0;
1858 1.7 christos }
1859 1.7 christos break;
1860 1.7 christos
1861 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
1862 1.7 christos min_value = -32;
1863 1.7 christos max_value = 31;
1864 1.7 christos goto sve_imm_offset_vl;
1865 1.7 christos
1866 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
1867 1.7 christos min_value = -256;
1868 1.7 christos max_value = 255;
1869 1.7 christos goto sve_imm_offset_vl;
1870 1.7 christos
1871 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6:
1872 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x2:
1873 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x4:
1874 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x8:
1875 1.7 christos min_value = 0;
1876 1.7 christos max_value = 63;
1877 1.7 christos sve_imm_offset:
1878 1.7 christos assert (!opnd->addr.offset.is_reg);
1879 1.7 christos assert (opnd->addr.preind);
1880 1.7 christos num = 1 << get_operand_specific_data (&aarch64_operands[type]);
1881 1.7 christos min_value *= num;
1882 1.7 christos max_value *= num;
1883 1.7 christos if (opnd->shifter.operator_present
1884 1.7 christos || opnd->shifter.amount_present)
1885 1.7 christos {
1886 1.7 christos set_other_error (mismatch_detail, idx,
1887 1.7 christos _("invalid addressing mode"));
1888 1.7 christos return 0;
1889 1.7 christos }
1890 1.7 christos if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1891 1.7 christos {
1892 1.7 christos set_offset_out_of_range_error (mismatch_detail, idx,
1893 1.7 christos min_value, max_value);
1894 1.7 christos return 0;
1895 1.7 christos }
1896 1.7 christos if (!value_aligned_p (opnd->addr.offset.imm, num))
1897 1.7 christos {
1898 1.7 christos set_unaligned_error (mismatch_detail, idx, num);
1899 1.7 christos return 0;
1900 1.7 christos }
1901 1.7 christos break;
1902 1.9 christos
1903 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x16:
1904 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x32:
1905 1.7 christos min_value = -8;
1906 1.7 christos max_value = 7;
1907 1.9 christos goto sve_imm_offset;
1908 1.9 christos
1909 1.9 christos case AARCH64_OPND_SVE_ADDR_ZX:
1910 1.9 christos /* Everything is already ensured by parse_operands or
1911 1.9 christos aarch64_ext_sve_addr_rr_lsl (because this is a very specific
1912 1.9 christos argument type). */
1913 1.9 christos assert (opnd->addr.offset.is_reg);
1914 1.9 christos assert (opnd->addr.preind);
1915 1.9 christos assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
1916 1.9 christos assert (opnd->shifter.kind == AARCH64_MOD_LSL);
1917 1.9 christos assert (opnd->shifter.operator_present == 0);
1918 1.8 christos break;
1919 1.7 christos
1920 1.7 christos case AARCH64_OPND_SVE_ADDR_R:
1921 1.7 christos case AARCH64_OPND_SVE_ADDR_RR:
1922 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL1:
1923 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL2:
1924 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL3:
1925 1.7 christos case AARCH64_OPND_SVE_ADDR_RX:
1926 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL1:
1927 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL2:
1928 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL3:
1929 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ:
1930 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
1931 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
1932 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
1933 1.7 christos modifiers = 1 << AARCH64_MOD_LSL;
1934 1.7 christos sve_rr_operand:
1935 1.7 christos assert (opnd->addr.offset.is_reg);
1936 1.7 christos assert (opnd->addr.preind);
1937 1.7 christos if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
1938 1.7 christos && opnd->addr.offset.regno == 31)
1939 1.7 christos {
1940 1.7 christos set_other_error (mismatch_detail, idx,
1941 1.7 christos _("index register xzr is not allowed"));
1942 1.7 christos return 0;
1943 1.7 christos }
1944 1.7 christos if (((1 << opnd->shifter.kind) & modifiers) == 0
1945 1.7 christos || (opnd->shifter.amount
1946 1.7 christos != get_operand_specific_data (&aarch64_operands[type])))
1947 1.7 christos {
1948 1.7 christos set_other_error (mismatch_detail, idx,
1949 1.7 christos _("invalid addressing mode"));
1950 1.7 christos return 0;
1951 1.7 christos }
1952 1.7 christos break;
1953 1.7 christos
1954 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
1955 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
1956 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
1957 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
1958 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
1959 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
1960 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
1961 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
1962 1.7 christos modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
1963 1.7 christos goto sve_rr_operand;
1964 1.7 christos
1965 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5:
1966 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
1967 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
1968 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
1969 1.7 christos min_value = 0;
1970 1.7 christos max_value = 31;
1971 1.7 christos goto sve_imm_offset;
1972 1.7 christos
1973 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
1974 1.7 christos modifiers = 1 << AARCH64_MOD_LSL;
1975 1.7 christos sve_zz_operand:
1976 1.7 christos assert (opnd->addr.offset.is_reg);
1977 1.7 christos assert (opnd->addr.preind);
1978 1.7 christos if (((1 << opnd->shifter.kind) & modifiers) == 0
1979 1.7 christos || opnd->shifter.amount < 0
1980 1.7 christos || opnd->shifter.amount > 3)
1981 1.7 christos {
1982 1.7 christos set_other_error (mismatch_detail, idx,
1983 1.7 christos _("invalid addressing mode"));
1984 1.7 christos return 0;
1985 1.7 christos }
1986 1.7 christos break;
1987 1.7 christos
1988 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
1989 1.7 christos modifiers = (1 << AARCH64_MOD_SXTW);
1990 1.7 christos goto sve_zz_operand;
1991 1.7 christos
1992 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
1993 1.7 christos modifiers = 1 << AARCH64_MOD_UXTW;
1994 1.1 christos goto sve_zz_operand;
1995 1.1 christos
1996 1.1 christos default:
1997 1.1 christos break;
1998 1.1 christos }
1999 1.1 christos break;
2000 1.6 christos
2001 1.6 christos case AARCH64_OPND_CLASS_SIMD_REGLIST:
2002 1.6 christos if (type == AARCH64_OPND_LEt)
2003 1.6 christos {
2004 1.6 christos /* Get the upper bound for the element index. */
2005 1.6 christos num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2006 1.6 christos if (!value_in_range_p (opnd->reglist.index, 0, num))
2007 1.6 christos {
2008 1.6 christos set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
2009 1.6 christos return 0;
2010 1.1 christos }
2011 1.1 christos }
2012 1.1 christos /* The opcode dependent area stores the number of elements in
2013 1.1 christos each structure to be loaded/stored. */
2014 1.1 christos num = get_opcode_dependent_value (opcode);
2015 1.1 christos switch (type)
2016 1.1 christos {
2017 1.1 christos case AARCH64_OPND_LVt:
2018 1.1 christos assert (num >= 1 && num <= 4);
2019 1.1 christos /* Unless LD1/ST1, the number of registers should be equal to that
2020 1.1 christos of the structure elements. */
2021 1.1 christos if (num != 1 && opnd->reglist.num_regs != num)
2022 1.1 christos {
2023 1.1 christos set_reg_list_error (mismatch_detail, idx, num);
2024 1.1 christos return 0;
2025 1.1 christos }
2026 1.1 christos break;
2027 1.1 christos case AARCH64_OPND_LVt_AL:
2028 1.1 christos case AARCH64_OPND_LEt:
2029 1.1 christos assert (num >= 1 && num <= 4);
2030 1.1 christos /* The number of registers should be equal to that of the structure
2031 1.1 christos elements. */
2032 1.1 christos if (opnd->reglist.num_regs != num)
2033 1.1 christos {
2034 1.1 christos set_reg_list_error (mismatch_detail, idx, num);
2035 1.1 christos return 0;
2036 1.1 christos }
2037 1.1 christos break;
2038 1.1 christos default:
2039 1.1 christos break;
2040 1.1 christos }
2041 1.1 christos break;
2042 1.1 christos
2043 1.1 christos case AARCH64_OPND_CLASS_IMMEDIATE:
2044 1.1 christos /* Constraint check on immediate operand. */
2045 1.1 christos imm = opnd->imm.value;
2046 1.1 christos /* E.g. imm_0_31 constrains value to be 0..31. */
2047 1.1 christos if (qualifier_value_in_range_constraint_p (qualifier)
2048 1.1 christos && !value_in_range_p (imm, get_lower_bound (qualifier),
2049 1.1 christos get_upper_bound (qualifier)))
2050 1.1 christos {
2051 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx,
2052 1.1 christos get_lower_bound (qualifier),
2053 1.1 christos get_upper_bound (qualifier));
2054 1.1 christos return 0;
2055 1.1 christos }
2056 1.1 christos
2057 1.1 christos switch (type)
2058 1.1 christos {
2059 1.1 christos case AARCH64_OPND_AIMM:
2060 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
2061 1.1 christos {
2062 1.1 christos set_other_error (mismatch_detail, idx,
2063 1.1 christos _("invalid shift operator"));
2064 1.1 christos return 0;
2065 1.1 christos }
2066 1.1 christos if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
2067 1.7 christos {
2068 1.1 christos set_other_error (mismatch_detail, idx,
2069 1.1 christos _("shift amount must be 0 or 12"));
2070 1.1 christos return 0;
2071 1.1 christos }
2072 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
2073 1.1 christos {
2074 1.1 christos set_other_error (mismatch_detail, idx,
2075 1.1 christos _("immediate out of range"));
2076 1.1 christos return 0;
2077 1.1 christos }
2078 1.1 christos break;
2079 1.1 christos
2080 1.1 christos case AARCH64_OPND_HALF:
2081 1.1 christos assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
2082 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
2083 1.1 christos {
2084 1.1 christos set_other_error (mismatch_detail, idx,
2085 1.1 christos _("invalid shift operator"));
2086 1.1 christos return 0;
2087 1.1 christos }
2088 1.1 christos size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2089 1.1 christos if (!value_aligned_p (opnd->shifter.amount, 16))
2090 1.7 christos {
2091 1.1 christos set_other_error (mismatch_detail, idx,
2092 1.1 christos _("shift amount must be a multiple of 16"));
2093 1.1 christos return 0;
2094 1.1 christos }
2095 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
2096 1.1 christos {
2097 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx,
2098 1.1 christos 0, size * 8 - 16);
2099 1.1 christos return 0;
2100 1.1 christos }
2101 1.1 christos if (opnd->imm.value < 0)
2102 1.1 christos {
2103 1.1 christos set_other_error (mismatch_detail, idx,
2104 1.1 christos _("negative immediate value not allowed"));
2105 1.1 christos return 0;
2106 1.1 christos }
2107 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
2108 1.1 christos {
2109 1.1 christos set_other_error (mismatch_detail, idx,
2110 1.1 christos _("immediate out of range"));
2111 1.1 christos return 0;
2112 1.1 christos }
2113 1.1 christos break;
2114 1.1 christos
2115 1.7 christos case AARCH64_OPND_IMM_MOV:
2116 1.1 christos {
2117 1.1 christos int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2118 1.1 christos imm = opnd->imm.value;
2119 1.1 christos assert (idx == 1);
2120 1.1 christos switch (opcode->op)
2121 1.1 christos {
2122 1.7 christos case OP_MOV_IMM_WIDEN:
2123 1.1 christos imm = ~imm;
2124 1.7 christos /* Fall through. */
2125 1.1 christos case OP_MOV_IMM_WIDE:
2126 1.1 christos if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
2127 1.1 christos {
2128 1.1 christos set_other_error (mismatch_detail, idx,
2129 1.1 christos _("immediate out of range"));
2130 1.1 christos return 0;
2131 1.1 christos }
2132 1.7 christos break;
2133 1.1 christos case OP_MOV_IMM_LOG:
2134 1.1 christos if (!aarch64_logical_immediate_p (imm, esize, NULL))
2135 1.1 christos {
2136 1.1 christos set_other_error (mismatch_detail, idx,
2137 1.1 christos _("immediate out of range"));
2138 1.1 christos return 0;
2139 1.1 christos }
2140 1.1 christos break;
2141 1.1 christos default:
2142 1.1 christos assert (0);
2143 1.1 christos return 0;
2144 1.1 christos }
2145 1.1 christos }
2146 1.1 christos break;
2147 1.1 christos
2148 1.1 christos case AARCH64_OPND_NZCV:
2149 1.9 christos case AARCH64_OPND_CCMP_IMM:
2150 1.9 christos case AARCH64_OPND_EXCEPTION:
2151 1.1 christos case AARCH64_OPND_UNDEFINED:
2152 1.8 christos case AARCH64_OPND_TME_UIMM16:
2153 1.1 christos case AARCH64_OPND_UIMM4:
2154 1.1 christos case AARCH64_OPND_UIMM4_ADDG:
2155 1.1 christos case AARCH64_OPND_UIMM7:
2156 1.7 christos case AARCH64_OPND_UIMM3_OP1:
2157 1.7 christos case AARCH64_OPND_UIMM3_OP2:
2158 1.7 christos case AARCH64_OPND_SVE_UIMM3:
2159 1.7 christos case AARCH64_OPND_SVE_UIMM7:
2160 1.1 christos case AARCH64_OPND_SVE_UIMM8:
2161 1.1 christos case AARCH64_OPND_SVE_UIMM8_53:
2162 1.1 christos size = get_operand_fields_width (get_operand_from_code (type));
2163 1.1 christos assert (size < 32);
2164 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, size))
2165 1.9 christos {
2166 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0,
2167 1.1 christos (1u << size) - 1);
2168 1.1 christos return 0;
2169 1.1 christos }
2170 1.8 christos break;
2171 1.8 christos
2172 1.8 christos case AARCH64_OPND_UIMM10:
2173 1.8 christos /* Scaled unsigned 10 bits immediate offset. */
2174 1.8 christos if (!value_in_range_p (opnd->imm.value, 0, 1008))
2175 1.8 christos {
2176 1.8 christos set_imm_out_of_range_error (mismatch_detail, idx, 0, 1008);
2177 1.8 christos return 0;
2178 1.8 christos }
2179 1.8 christos
2180 1.8 christos if (!value_aligned_p (opnd->imm.value, 16))
2181 1.8 christos {
2182 1.8 christos set_unaligned_error (mismatch_detail, idx, 16);
2183 1.8 christos return 0;
2184 1.8 christos }
2185 1.7 christos break;
2186 1.7 christos
2187 1.7 christos case AARCH64_OPND_SIMM5:
2188 1.7 christos case AARCH64_OPND_SVE_SIMM5:
2189 1.7 christos case AARCH64_OPND_SVE_SIMM5B:
2190 1.7 christos case AARCH64_OPND_SVE_SIMM6:
2191 1.7 christos case AARCH64_OPND_SVE_SIMM8:
2192 1.7 christos size = get_operand_fields_width (get_operand_from_code (type));
2193 1.7 christos assert (size < 32);
2194 1.7 christos if (!value_fit_signed_field_p (opnd->imm.value, size))
2195 1.7 christos {
2196 1.7 christos set_imm_out_of_range_error (mismatch_detail, idx,
2197 1.7 christos -(1 << (size - 1)),
2198 1.7 christos (1 << (size - 1)) - 1);
2199 1.7 christos return 0;
2200 1.7 christos }
2201 1.1 christos break;
2202 1.6 christos
2203 1.1 christos case AARCH64_OPND_WIDTH:
2204 1.1 christos assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2205 1.1 christos && opnds[0].type == AARCH64_OPND_Rd);
2206 1.1 christos size = get_upper_bound (qualifier);
2207 1.1 christos if (opnd->imm.value + opnds[idx-1].imm.value > size)
2208 1.1 christos /* lsb+width <= reg.size */
2209 1.1 christos {
2210 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 1,
2211 1.1 christos size - opnds[idx-1].imm.value);
2212 1.1 christos return 0;
2213 1.1 christos }
2214 1.1 christos break;
2215 1.7 christos
2216 1.7 christos case AARCH64_OPND_LIMM:
2217 1.7 christos case AARCH64_OPND_SVE_LIMM:
2218 1.7 christos {
2219 1.7 christos int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2220 1.7 christos uint64_t uimm = opnd->imm.value;
2221 1.8 christos if (opcode->op == OP_BIC)
2222 1.7 christos uimm = ~uimm;
2223 1.7 christos if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2224 1.7 christos {
2225 1.7 christos set_other_error (mismatch_detail, idx,
2226 1.7 christos _("immediate out of range"));
2227 1.7 christos return 0;
2228 1.1 christos }
2229 1.1 christos }
2230 1.1 christos break;
2231 1.1 christos
2232 1.1 christos case AARCH64_OPND_IMM0:
2233 1.1 christos case AARCH64_OPND_FPIMM0:
2234 1.1 christos if (opnd->imm.value != 0)
2235 1.1 christos {
2236 1.1 christos set_other_error (mismatch_detail, idx,
2237 1.1 christos _("immediate zero expected"));
2238 1.1 christos return 0;
2239 1.1 christos }
2240 1.7 christos break;
2241 1.7 christos
2242 1.7 christos case AARCH64_OPND_IMM_ROT1:
2243 1.7 christos case AARCH64_OPND_IMM_ROT2:
2244 1.7 christos case AARCH64_OPND_SVE_IMM_ROT2:
2245 1.7 christos if (opnd->imm.value != 0
2246 1.7 christos && opnd->imm.value != 90
2247 1.7 christos && opnd->imm.value != 180
2248 1.7 christos && opnd->imm.value != 270)
2249 1.7 christos {
2250 1.7 christos set_other_error (mismatch_detail, idx,
2251 1.7 christos _("rotate expected to be 0, 90, 180 or 270"));
2252 1.7 christos return 0;
2253 1.7 christos }
2254 1.7 christos break;
2255 1.7 christos
2256 1.9 christos case AARCH64_OPND_IMM_ROT3:
2257 1.7 christos case AARCH64_OPND_SVE_IMM_ROT1:
2258 1.7 christos case AARCH64_OPND_SVE_IMM_ROT3:
2259 1.7 christos if (opnd->imm.value != 90 && opnd->imm.value != 270)
2260 1.7 christos {
2261 1.7 christos set_other_error (mismatch_detail, idx,
2262 1.7 christos _("rotate expected to be 90 or 270"));
2263 1.7 christos return 0;
2264 1.7 christos }
2265 1.1 christos break;
2266 1.1 christos
2267 1.1 christos case AARCH64_OPND_SHLL_IMM:
2268 1.1 christos assert (idx == 2);
2269 1.1 christos size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2270 1.1 christos if (opnd->imm.value != size)
2271 1.1 christos {
2272 1.1 christos set_other_error (mismatch_detail, idx,
2273 1.1 christos _("invalid shift amount"));
2274 1.1 christos return 0;
2275 1.1 christos }
2276 1.1 christos break;
2277 1.1 christos
2278 1.1 christos case AARCH64_OPND_IMM_VLSL:
2279 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
2280 1.1 christos if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
2281 1.1 christos {
2282 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0,
2283 1.1 christos size * 8 - 1);
2284 1.1 christos return 0;
2285 1.1 christos }
2286 1.1 christos break;
2287 1.1 christos
2288 1.1 christos case AARCH64_OPND_IMM_VLSR:
2289 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
2290 1.1 christos if (!value_in_range_p (opnd->imm.value, 1, size * 8))
2291 1.1 christos {
2292 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
2293 1.1 christos return 0;
2294 1.1 christos }
2295 1.1 christos break;
2296 1.1 christos
2297 1.1 christos case AARCH64_OPND_SIMD_IMM:
2298 1.1 christos case AARCH64_OPND_SIMD_IMM_SFT:
2299 1.1 christos /* Qualifier check. */
2300 1.1 christos switch (qualifier)
2301 1.1 christos {
2302 1.1 christos case AARCH64_OPND_QLF_LSL:
2303 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
2304 1.1 christos {
2305 1.1 christos set_other_error (mismatch_detail, idx,
2306 1.1 christos _("invalid shift operator"));
2307 1.1 christos return 0;
2308 1.1 christos }
2309 1.1 christos break;
2310 1.1 christos case AARCH64_OPND_QLF_MSL:
2311 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_MSL)
2312 1.1 christos {
2313 1.1 christos set_other_error (mismatch_detail, idx,
2314 1.1 christos _("invalid shift operator"));
2315 1.1 christos return 0;
2316 1.1 christos }
2317 1.1 christos break;
2318 1.1 christos case AARCH64_OPND_QLF_NIL:
2319 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
2320 1.1 christos {
2321 1.1 christos set_other_error (mismatch_detail, idx,
2322 1.1 christos _("shift is not permitted"));
2323 1.1 christos return 0;
2324 1.1 christos }
2325 1.1 christos break;
2326 1.1 christos default:
2327 1.1 christos assert (0);
2328 1.1 christos return 0;
2329 1.1 christos }
2330 1.1 christos /* Is the immediate valid? */
2331 1.1 christos assert (idx == 1);
2332 1.1 christos if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2333 1.1 christos {
2334 1.1 christos /* uimm8 or simm8 */
2335 1.1 christos if (!value_in_range_p (opnd->imm.value, -128, 255))
2336 1.1 christos {
2337 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
2338 1.1 christos return 0;
2339 1.1 christos }
2340 1.1 christos }
2341 1.1 christos else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
2342 1.1 christos {
2343 1.1 christos /* uimm64 is not
2344 1.1 christos 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
2345 1.1 christos ffffffffgggggggghhhhhhhh'. */
2346 1.1 christos set_other_error (mismatch_detail, idx,
2347 1.1 christos _("invalid value for immediate"));
2348 1.1 christos return 0;
2349 1.1 christos }
2350 1.1 christos /* Is the shift amount valid? */
2351 1.1 christos switch (opnd->shifter.kind)
2352 1.1 christos {
2353 1.1 christos case AARCH64_MOD_LSL:
2354 1.1 christos size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2355 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
2356 1.1 christos {
2357 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
2358 1.1 christos (size - 1) * 8);
2359 1.1 christos return 0;
2360 1.1 christos }
2361 1.1 christos if (!value_aligned_p (opnd->shifter.amount, 8))
2362 1.1 christos {
2363 1.1 christos set_unaligned_error (mismatch_detail, idx, 8);
2364 1.1 christos return 0;
2365 1.1 christos }
2366 1.1 christos break;
2367 1.1 christos case AARCH64_MOD_MSL:
2368 1.1 christos /* Only 8 and 16 are valid shift amount. */
2369 1.1 christos if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
2370 1.7 christos {
2371 1.1 christos set_other_error (mismatch_detail, idx,
2372 1.1 christos _("shift amount must be 0 or 16"));
2373 1.1 christos return 0;
2374 1.1 christos }
2375 1.1 christos break;
2376 1.1 christos default:
2377 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
2378 1.1 christos {
2379 1.1 christos set_other_error (mismatch_detail, idx,
2380 1.1 christos _("invalid shift operator"));
2381 1.1 christos return 0;
2382 1.1 christos }
2383 1.1 christos break;
2384 1.1 christos }
2385 1.1 christos break;
2386 1.1 christos
2387 1.7 christos case AARCH64_OPND_FPIMM:
2388 1.1 christos case AARCH64_OPND_SIMD_FPIMM:
2389 1.1 christos case AARCH64_OPND_SVE_FPIMM8:
2390 1.1 christos if (opnd->imm.is_fp == 0)
2391 1.1 christos {
2392 1.1 christos set_other_error (mismatch_detail, idx,
2393 1.1 christos _("floating-point immediate expected"));
2394 1.1 christos return 0;
2395 1.1 christos }
2396 1.1 christos /* The value is expected to be an 8-bit floating-point constant with
2397 1.1 christos sign, 3-bit exponent and normalized 4 bits of precision, encoded
2398 1.1 christos in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
2399 1.1 christos instruction). */
2400 1.1 christos if (!value_in_range_p (opnd->imm.value, 0, 255))
2401 1.1 christos {
2402 1.1 christos set_other_error (mismatch_detail, idx,
2403 1.1 christos _("immediate out of range"));
2404 1.1 christos return 0;
2405 1.1 christos }
2406 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
2407 1.1 christos {
2408 1.1 christos set_other_error (mismatch_detail, idx,
2409 1.1 christos _("invalid shift operator"));
2410 1.1 christos return 0;
2411 1.1 christos }
2412 1.7 christos break;
2413 1.7 christos
2414 1.7 christos case AARCH64_OPND_SVE_AIMM:
2415 1.7 christos min_value = 0;
2416 1.7 christos sve_aimm:
2417 1.7 christos assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2418 1.7 christos size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2419 1.7 christos mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2420 1.7 christos uvalue = opnd->imm.value;
2421 1.7 christos shift = opnd->shifter.amount;
2422 1.7 christos if (size == 1)
2423 1.7 christos {
2424 1.7 christos if (shift != 0)
2425 1.7 christos {
2426 1.7 christos set_other_error (mismatch_detail, idx,
2427 1.7 christos _("no shift amount allowed for"
2428 1.7 christos " 8-bit constants"));
2429 1.7 christos return 0;
2430 1.7 christos }
2431 1.7 christos }
2432 1.7 christos else
2433 1.7 christos {
2434 1.7 christos if (shift != 0 && shift != 8)
2435 1.7 christos {
2436 1.7 christos set_other_error (mismatch_detail, idx,
2437 1.7 christos _("shift amount must be 0 or 8"));
2438 1.7 christos return 0;
2439 1.7 christos }
2440 1.7 christos if (shift == 0 && (uvalue & 0xff) == 0)
2441 1.7 christos {
2442 1.7 christos shift = 8;
2443 1.7 christos uvalue = (int64_t) uvalue / 256;
2444 1.7 christos }
2445 1.7 christos }
2446 1.7 christos mask >>= shift;
2447 1.7 christos if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2448 1.7 christos {
2449 1.7 christos set_other_error (mismatch_detail, idx,
2450 1.7 christos _("immediate too big for element size"));
2451 1.7 christos return 0;
2452 1.7 christos }
2453 1.7 christos uvalue = (uvalue - min_value) & mask;
2454 1.7 christos if (uvalue > 0xff)
2455 1.7 christos {
2456 1.7 christos set_other_error (mismatch_detail, idx,
2457 1.7 christos _("invalid arithmetic immediate"));
2458 1.7 christos return 0;
2459 1.7 christos }
2460 1.7 christos break;
2461 1.7 christos
2462 1.7 christos case AARCH64_OPND_SVE_ASIMM:
2463 1.7 christos min_value = -128;
2464 1.7 christos goto sve_aimm;
2465 1.7 christos
2466 1.7 christos case AARCH64_OPND_SVE_I1_HALF_ONE:
2467 1.7 christos assert (opnd->imm.is_fp);
2468 1.7 christos if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
2469 1.7 christos {
2470 1.7 christos set_other_error (mismatch_detail, idx,
2471 1.7 christos _("floating-point value must be 0.5 or 1.0"));
2472 1.7 christos return 0;
2473 1.7 christos }
2474 1.7 christos break;
2475 1.7 christos
2476 1.7 christos case AARCH64_OPND_SVE_I1_HALF_TWO:
2477 1.7 christos assert (opnd->imm.is_fp);
2478 1.7 christos if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
2479 1.7 christos {
2480 1.7 christos set_other_error (mismatch_detail, idx,
2481 1.7 christos _("floating-point value must be 0.5 or 2.0"));
2482 1.7 christos return 0;
2483 1.7 christos }
2484 1.7 christos break;
2485 1.7 christos
2486 1.7 christos case AARCH64_OPND_SVE_I1_ZERO_ONE:
2487 1.7 christos assert (opnd->imm.is_fp);
2488 1.7 christos if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
2489 1.7 christos {
2490 1.7 christos set_other_error (mismatch_detail, idx,
2491 1.7 christos _("floating-point value must be 0.0 or 1.0"));
2492 1.7 christos return 0;
2493 1.7 christos }
2494 1.7 christos break;
2495 1.7 christos
2496 1.7 christos case AARCH64_OPND_SVE_INV_LIMM:
2497 1.7 christos {
2498 1.7 christos int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2499 1.7 christos uint64_t uimm = ~opnd->imm.value;
2500 1.7 christos if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2501 1.7 christos {
2502 1.7 christos set_other_error (mismatch_detail, idx,
2503 1.7 christos _("immediate out of range"));
2504 1.7 christos return 0;
2505 1.7 christos }
2506 1.7 christos }
2507 1.7 christos break;
2508 1.7 christos
2509 1.7 christos case AARCH64_OPND_SVE_LIMM_MOV:
2510 1.7 christos {
2511 1.7 christos int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2512 1.7 christos uint64_t uimm = opnd->imm.value;
2513 1.7 christos if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2514 1.7 christos {
2515 1.7 christos set_other_error (mismatch_detail, idx,
2516 1.7 christos _("immediate out of range"));
2517 1.7 christos return 0;
2518 1.7 christos }
2519 1.7 christos if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
2520 1.7 christos {
2521 1.7 christos set_other_error (mismatch_detail, idx,
2522 1.7 christos _("invalid replicated MOV immediate"));
2523 1.7 christos return 0;
2524 1.7 christos }
2525 1.7 christos }
2526 1.7 christos break;
2527 1.7 christos
2528 1.7 christos case AARCH64_OPND_SVE_PATTERN_SCALED:
2529 1.7 christos assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2530 1.7 christos if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2531 1.7 christos {
2532 1.7 christos set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2533 1.7 christos return 0;
2534 1.7 christos }
2535 1.7 christos break;
2536 1.7 christos
2537 1.9 christos case AARCH64_OPND_SVE_SHLIMM_PRED:
2538 1.7 christos case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2539 1.7 christos case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
2540 1.7 christos size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2541 1.7 christos if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
2542 1.7 christos {
2543 1.7 christos set_imm_out_of_range_error (mismatch_detail, idx,
2544 1.7 christos 0, 8 * size - 1);
2545 1.7 christos return 0;
2546 1.7 christos }
2547 1.7 christos break;
2548 1.7 christos
2549 1.9 christos case AARCH64_OPND_SVE_SHRIMM_PRED:
2550 1.9 christos case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2551 1.9 christos case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
2552 1.7 christos num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
2553 1.7 christos size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
2554 1.9 christos if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
2555 1.7 christos {
2556 1.7 christos set_imm_out_of_range_error (mismatch_detail, idx, 1, 8*size);
2557 1.7 christos return 0;
2558 1.7 christos }
2559 1.1 christos break;
2560 1.1 christos
2561 1.1 christos default:
2562 1.1 christos break;
2563 1.1 christos }
2564 1.1 christos break;
2565 1.1 christos
2566 1.1 christos case AARCH64_OPND_CLASS_SYSTEM:
2567 1.1 christos switch (type)
2568 1.1 christos {
2569 1.6 christos case AARCH64_OPND_PSTATEFIELD:
2570 1.6 christos assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
2571 1.8 christos /* MSR UAO, #uimm4
2572 1.6 christos MSR PAN, #uimm4
2573 1.6 christos MSR SSBS,#uimm4
2574 1.8 christos The immediate must be #0 or #1. */
2575 1.8 christos if ((opnd->pstatefield == 0x03 /* UAO. */
2576 1.8 christos || opnd->pstatefield == 0x04 /* PAN. */
2577 1.6 christos || opnd->pstatefield == 0x19 /* SSBS. */
2578 1.6 christos || opnd->pstatefield == 0x1a) /* DIT. */
2579 1.6 christos && opnds[1].imm.value > 1)
2580 1.6 christos {
2581 1.6 christos set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2582 1.1 christos return 0;
2583 1.1 christos }
2584 1.1 christos /* MSR SPSel, #uimm4
2585 1.1 christos Uses uimm4 as a control value to select the stack pointer: if
2586 1.1 christos bit 0 is set it selects the current exception level's stack
2587 1.1 christos pointer, if bit 0 is clear it selects shared EL0 stack pointer.
2588 1.1 christos Bits 1 to 3 of uimm4 are reserved and should be zero. */
2589 1.1 christos if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
2590 1.1 christos {
2591 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2592 1.1 christos return 0;
2593 1.1 christos }
2594 1.1 christos break;
2595 1.1 christos default:
2596 1.1 christos break;
2597 1.1 christos }
2598 1.1 christos break;
2599 1.1 christos
2600 1.7 christos case AARCH64_OPND_CLASS_SIMD_ELEMENT:
2601 1.7 christos /* Get the upper bound for the element index. */
2602 1.7 christos if (opcode->op == OP_FCMLA_ELEM)
2603 1.7 christos /* FCMLA index range depends on the vector size of other operands
2604 1.7 christos and is halfed because complex numbers take two elements. */
2605 1.7 christos num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
2606 1.7 christos * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
2607 1.7 christos else
2608 1.8 christos num = 16;
2609 1.7 christos num = num / aarch64_get_qualifier_esize (qualifier) - 1;
2610 1.1 christos assert (aarch64_get_qualifier_nelem (qualifier) == 1);
2611 1.1 christos
2612 1.1 christos /* Index out-of-range. */
2613 1.1 christos if (!value_in_range_p (opnd->reglane.index, 0, num))
2614 1.1 christos {
2615 1.1 christos set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
2616 1.1 christos return 0;
2617 1.1 christos }
2618 1.1 christos /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
2619 1.1 christos <Vm> Is the vector register (V0-V31) or (V0-V15), whose
2620 1.1 christos number is encoded in "size:M:Rm":
2621 1.1 christos size <Vm>
2622 1.1 christos 00 RESERVED
2623 1.1 christos 01 0:Rm
2624 1.8 christos 10 M:Rm
2625 1.1 christos 11 RESERVED */
2626 1.1 christos if (type == AARCH64_OPND_Em16 && qualifier == AARCH64_OPND_QLF_S_H
2627 1.1 christos && !value_in_range_p (opnd->reglane.regno, 0, 15))
2628 1.1 christos {
2629 1.1 christos set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
2630 1.1 christos return 0;
2631 1.1 christos }
2632 1.1 christos break;
2633 1.1 christos
2634 1.1 christos case AARCH64_OPND_CLASS_MODIFIED_REG:
2635 1.1 christos assert (idx == 1 || idx == 2);
2636 1.1 christos switch (type)
2637 1.8 christos {
2638 1.1 christos case AARCH64_OPND_Rm_EXT:
2639 1.1 christos if (!aarch64_extend_operator_p (opnd->shifter.kind)
2640 1.1 christos && opnd->shifter.kind != AARCH64_MOD_LSL)
2641 1.1 christos {
2642 1.1 christos set_other_error (mismatch_detail, idx,
2643 1.1 christos _("extend operator expected"));
2644 1.1 christos return 0;
2645 1.1 christos }
2646 1.1 christos /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
2647 1.1 christos (i.e. SP), in which case it defaults to LSL. The LSL alias is
2648 1.1 christos only valid when "Rd" or "Rn" is '11111', and is preferred in that
2649 1.1 christos case. */
2650 1.1 christos if (!aarch64_stack_pointer_p (opnds + 0)
2651 1.1 christos && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
2652 1.1 christos {
2653 1.1 christos if (!opnd->shifter.operator_present)
2654 1.1 christos {
2655 1.1 christos set_other_error (mismatch_detail, idx,
2656 1.1 christos _("missing extend operator"));
2657 1.1 christos return 0;
2658 1.1 christos }
2659 1.1 christos else if (opnd->shifter.kind == AARCH64_MOD_LSL)
2660 1.1 christos {
2661 1.1 christos set_other_error (mismatch_detail, idx,
2662 1.1 christos _("'LSL' operator not allowed"));
2663 1.1 christos return 0;
2664 1.1 christos }
2665 1.1 christos }
2666 1.1 christos assert (opnd->shifter.operator_present /* Default to LSL. */
2667 1.1 christos || opnd->shifter.kind == AARCH64_MOD_LSL);
2668 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, 4))
2669 1.1 christos {
2670 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
2671 1.1 christos return 0;
2672 1.1 christos }
2673 1.1 christos /* In the 64-bit form, the final register operand is written as Wm
2674 1.1 christos for all but the (possibly omitted) UXTX/LSL and SXTX
2675 1.1 christos operators.
2676 1.1 christos N.B. GAS allows X register to be used with any operator as a
2677 1.1 christos programming convenience. */
2678 1.1 christos if (qualifier == AARCH64_OPND_QLF_X
2679 1.1 christos && opnd->shifter.kind != AARCH64_MOD_LSL
2680 1.1 christos && opnd->shifter.kind != AARCH64_MOD_UXTX
2681 1.1 christos && opnd->shifter.kind != AARCH64_MOD_SXTX)
2682 1.1 christos {
2683 1.1 christos set_other_error (mismatch_detail, idx, _("W register expected"));
2684 1.1 christos return 0;
2685 1.1 christos }
2686 1.1 christos break;
2687 1.1 christos
2688 1.1 christos case AARCH64_OPND_Rm_SFT:
2689 1.8 christos /* ROR is not available to the shifted register operand in
2690 1.1 christos arithmetic instructions. */
2691 1.1 christos if (!aarch64_shift_operator_p (opnd->shifter.kind))
2692 1.1 christos {
2693 1.1 christos set_other_error (mismatch_detail, idx,
2694 1.1 christos _("shift operator expected"));
2695 1.1 christos return 0;
2696 1.1 christos }
2697 1.1 christos if (opnd->shifter.kind == AARCH64_MOD_ROR
2698 1.1 christos && opcode->iclass != log_shift)
2699 1.1 christos {
2700 1.1 christos set_other_error (mismatch_detail, idx,
2701 1.1 christos _("'ROR' operator not allowed"));
2702 1.1 christos return 0;
2703 1.1 christos }
2704 1.1 christos num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
2705 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, num))
2706 1.1 christos {
2707 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
2708 1.1 christos return 0;
2709 1.1 christos }
2710 1.1 christos break;
2711 1.1 christos
2712 1.1 christos default:
2713 1.1 christos break;
2714 1.1 christos }
2715 1.1 christos break;
2716 1.1 christos
2717 1.1 christos default:
2718 1.1 christos break;
2719 1.1 christos }
2720 1.1 christos
2721 1.1 christos return 1;
2722 1.1 christos }
2723 1.1 christos
2724 1.1 christos /* Main entrypoint for the operand constraint checking.
2725 1.1 christos
2726 1.1 christos Return 1 if operands of *INST meet the constraint applied by the operand
2727 1.1 christos codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
2728 1.1 christos not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
2729 1.1 christos adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
2730 1.1 christos with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
2731 1.1 christos error kind when it is notified that an instruction does not pass the check).
2732 1.1 christos
2733 1.1 christos Un-determined operand qualifiers may get established during the process. */
2734 1.1 christos
2735 1.1 christos int
2736 1.1 christos aarch64_match_operands_constraint (aarch64_inst *inst,
2737 1.1 christos aarch64_operand_error *mismatch_detail)
2738 1.1 christos {
2739 1.1 christos int i;
2740 1.1 christos
2741 1.7 christos DEBUG_TRACE ("enter");
2742 1.7 christos
2743 1.7 christos /* Check for cases where a source register needs to be the same as the
2744 1.7 christos destination register. Do this before matching qualifiers since if
2745 1.7 christos an instruction has both invalid tying and invalid qualifiers,
2746 1.7 christos the error about qualifiers would suggest several alternative
2747 1.7 christos instructions that also have invalid tying. */
2748 1.7 christos i = inst->opcode->tied_operand;
2749 1.7 christos if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
2750 1.7 christos {
2751 1.7 christos if (mismatch_detail)
2752 1.7 christos {
2753 1.7 christos mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
2754 1.7 christos mismatch_detail->index = i;
2755 1.7 christos mismatch_detail->error = NULL;
2756 1.7 christos }
2757 1.7 christos return 0;
2758 1.1 christos }
2759 1.1 christos
2760 1.1 christos /* Match operands' qualifier.
2761 1.1 christos *INST has already had qualifier establish for some, if not all, of
2762 1.1 christos its operands; we need to find out whether these established
2763 1.1 christos qualifiers match one of the qualifier sequence in
2764 1.1 christos INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
2765 1.1 christos with the corresponding qualifier in such a sequence.
2766 1.1 christos Only basic operand constraint checking is done here; the more thorough
2767 1.1 christos constraint checking will carried out by operand_general_constraint_met_p,
2768 1.1 christos which has be to called after this in order to get all of the operands'
2769 1.1 christos qualifiers established. */
2770 1.1 christos if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
2771 1.1 christos {
2772 1.1 christos DEBUG_TRACE ("FAIL on operand qualifier matching");
2773 1.1 christos if (mismatch_detail)
2774 1.1 christos {
2775 1.1 christos /* Return an error type to indicate that it is the qualifier
2776 1.1 christos matching failure; we don't care about which operand as there
2777 1.1 christos are enough information in the opcode table to reproduce it. */
2778 1.1 christos mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
2779 1.1 christos mismatch_detail->index = -1;
2780 1.1 christos mismatch_detail->error = NULL;
2781 1.1 christos }
2782 1.1 christos return 0;
2783 1.1 christos }
2784 1.1 christos
2785 1.1 christos /* Match operands' constraint. */
2786 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2787 1.1 christos {
2788 1.1 christos enum aarch64_opnd type = inst->opcode->operands[i];
2789 1.1 christos if (type == AARCH64_OPND_NIL)
2790 1.1 christos break;
2791 1.1 christos if (inst->operands[i].skip)
2792 1.1 christos {
2793 1.1 christos DEBUG_TRACE ("skip the incomplete operand %d", i);
2794 1.1 christos continue;
2795 1.1 christos }
2796 1.1 christos if (operand_general_constraint_met_p (inst->operands, i, type,
2797 1.1 christos inst->opcode, mismatch_detail) == 0)
2798 1.1 christos {
2799 1.1 christos DEBUG_TRACE ("FAIL on operand %d", i);
2800 1.1 christos return 0;
2801 1.1 christos }
2802 1.1 christos }
2803 1.1 christos
2804 1.1 christos DEBUG_TRACE ("PASS");
2805 1.1 christos
2806 1.1 christos return 1;
2807 1.1 christos }
2808 1.1 christos
2809 1.1 christos /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2810 1.1 christos Also updates the TYPE of each INST->OPERANDS with the corresponding
2811 1.1 christos value of OPCODE->OPERANDS.
2812 1.1 christos
2813 1.1 christos Note that some operand qualifiers may need to be manually cleared by
2814 1.1 christos the caller before it further calls the aarch64_opcode_encode; by
2815 1.1 christos doing this, it helps the qualifier matching facilities work
2816 1.1 christos properly. */
2817 1.1 christos
2818 1.1 christos const aarch64_opcode*
2819 1.1 christos aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2820 1.1 christos {
2821 1.1 christos int i;
2822 1.1 christos const aarch64_opcode *old = inst->opcode;
2823 1.1 christos
2824 1.1 christos inst->opcode = opcode;
2825 1.1 christos
2826 1.1 christos /* Update the operand types. */
2827 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2828 1.1 christos {
2829 1.1 christos inst->operands[i].type = opcode->operands[i];
2830 1.1 christos if (opcode->operands[i] == AARCH64_OPND_NIL)
2831 1.1 christos break;
2832 1.1 christos }
2833 1.1 christos
2834 1.1 christos DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2835 1.1 christos
2836 1.1 christos return old;
2837 1.1 christos }
2838 1.1 christos
2839 1.1 christos int
2840 1.1 christos aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2841 1.1 christos {
2842 1.1 christos int i;
2843 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2844 1.1 christos if (operands[i] == operand)
2845 1.1 christos return i;
2846 1.1 christos else if (operands[i] == AARCH64_OPND_NIL)
2847 1.1 christos break;
2848 1.1 christos return -1;
2849 1.7 christos }
2850 1.7 christos
2851 1.7 christos /* R0...R30, followed by FOR31. */
2853 1.7 christos #define BANK(R, FOR31) \
2854 1.7 christos { R (0), R (1), R (2), R (3), R (4), R (5), R (6), R (7), \
2855 1.1 christos R (8), R (9), R (10), R (11), R (12), R (13), R (14), R (15), \
2856 1.1 christos R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
2857 1.1 christos R (24), R (25), R (26), R (27), R (28), R (29), R (30), FOR31 }
2858 1.1 christos /* [0][0] 32-bit integer regs with sp Wn
2859 1.1 christos [0][1] 64-bit integer regs with sp Xn sf=1
2860 1.7 christos [1][0] 32-bit integer regs with #0 Wn
2861 1.7 christos [1][1] 64-bit integer regs with #0 Xn sf=1 */
2862 1.7 christos static const char *int_reg[2][2][32] = {
2863 1.7 christos #define R32(X) "w" #X
2864 1.1 christos #define R64(X) "x" #X
2865 1.1 christos { BANK (R32, "wsp"), BANK (R64, "sp") },
2866 1.1 christos { BANK (R32, "wzr"), BANK (R64, "xzr") }
2867 1.1 christos #undef R64
2868 1.7 christos #undef R32
2869 1.7 christos };
2870 1.7 christos
2871 1.7 christos /* Names of the SVE vector registers, first with .S suffixes,
2872 1.7 christos then with .D suffixes. */
2873 1.7 christos
2874 1.7 christos static const char *sve_reg[2][32] = {
2875 1.7 christos #define ZS(X) "z" #X ".s"
2876 1.7 christos #define ZD(X) "z" #X ".d"
2877 1.7 christos BANK (ZS, ZS (31)), BANK (ZD, ZD (31))
2878 1.7 christos #undef ZD
2879 1.7 christos #undef ZS
2880 1.1 christos };
2881 1.1 christos #undef BANK
2882 1.1 christos
2883 1.1 christos /* Return the integer register name.
2884 1.1 christos if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2885 1.1 christos
2886 1.1 christos static inline const char *
2887 1.1 christos get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2888 1.1 christos {
2889 1.1 christos const int has_zr = sp_reg_p ? 0 : 1;
2890 1.1 christos const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2891 1.1 christos return int_reg[has_zr][is_64][regno];
2892 1.1 christos }
2893 1.1 christos
2894 1.1 christos /* Like get_int_reg_name, but IS_64 is always 1. */
2895 1.1 christos
2896 1.1 christos static inline const char *
2897 1.1 christos get_64bit_int_reg_name (int regno, int sp_reg_p)
2898 1.1 christos {
2899 1.1 christos const int has_zr = sp_reg_p ? 0 : 1;
2900 1.7 christos return int_reg[has_zr][1][regno];
2901 1.7 christos }
2902 1.7 christos
2903 1.7 christos /* Get the name of the integer offset register in OPND, using the shift type
2904 1.7 christos to decide whether it's a word or doubleword. */
2905 1.7 christos
2906 1.7 christos static inline const char *
2907 1.7 christos get_offset_int_reg_name (const aarch64_opnd_info *opnd)
2908 1.7 christos {
2909 1.7 christos switch (opnd->shifter.kind)
2910 1.7 christos {
2911 1.7 christos case AARCH64_MOD_UXTW:
2912 1.7 christos case AARCH64_MOD_SXTW:
2913 1.7 christos return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
2914 1.7 christos
2915 1.7 christos case AARCH64_MOD_LSL:
2916 1.7 christos case AARCH64_MOD_SXTX:
2917 1.7 christos return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
2918 1.7 christos
2919 1.7 christos default:
2920 1.7 christos abort ();
2921 1.7 christos }
2922 1.7 christos }
2923 1.7 christos
2924 1.7 christos /* Get the name of the SVE vector offset register in OPND, using the operand
2925 1.7 christos qualifier to decide whether the suffix should be .S or .D. */
2926 1.7 christos
2927 1.7 christos static inline const char *
2928 1.7 christos get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
2929 1.7 christos {
2930 1.7 christos assert (qualifier == AARCH64_OPND_QLF_S_S
2931 1.7 christos || qualifier == AARCH64_OPND_QLF_S_D);
2932 1.1 christos return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
2933 1.1 christos }
2934 1.1 christos
2935 1.1 christos /* Types for expanding an encoded 8-bit value to a floating-point value. */
2936 1.1 christos
2937 1.1 christos typedef union
2938 1.1 christos {
2939 1.1 christos uint64_t i;
2940 1.1 christos double d;
2941 1.1 christos } double_conv_t;
2942 1.1 christos
2943 1.1 christos typedef union
2944 1.1 christos {
2945 1.1 christos uint32_t i;
2946 1.6 christos float f;
2947 1.6 christos } single_conv_t;
2948 1.6 christos
2949 1.6 christos typedef union
2950 1.6 christos {
2951 1.6 christos uint32_t i;
2952 1.1 christos float f;
2953 1.1 christos } half_conv_t;
2954 1.1 christos
2955 1.6 christos /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2956 1.6 christos normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2957 1.6 christos (depending on the type of the instruction). IMM8 will be expanded to a
2958 1.6 christos single-precision floating-point value (SIZE == 4) or a double-precision
2959 1.1 christos floating-point value (SIZE == 8). A half-precision floating-point value
2960 1.1 christos (SIZE == 2) is expanded to a single-precision floating-point value. The
2961 1.6 christos expanded value is returned. */
2962 1.1 christos
2963 1.8 christos static uint64_t
2964 1.1 christos expand_fp_imm (int size, uint32_t imm8)
2965 1.1 christos {
2966 1.1 christos uint64_t imm = 0;
2967 1.1 christos uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2968 1.1 christos
2969 1.1 christos imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2970 1.1 christos imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2971 1.6 christos imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2972 1.1 christos imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2973 1.1 christos | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
2974 1.1 christos if (size == 8)
2975 1.1 christos {
2976 1.1 christos imm = (imm8_7 << (63-32)) /* imm8<7> */
2977 1.1 christos | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2978 1.1 christos | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2979 1.1 christos | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2980 1.6 christos | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2981 1.1 christos imm <<= 32;
2982 1.1 christos }
2983 1.1 christos else if (size == 4 || size == 2)
2984 1.1 christos {
2985 1.1 christos imm = (imm8_7 << 31) /* imm8<7> */
2986 1.1 christos | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2987 1.6 christos | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2988 1.6 christos | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2989 1.6 christos }
2990 1.6 christos else
2991 1.6 christos {
2992 1.1 christos /* An unsupported size. */
2993 1.1 christos assert (0);
2994 1.1 christos }
2995 1.1 christos
2996 1.1 christos return imm;
2997 1.7 christos }
2998 1.7 christos
2999 1.1 christos /* Produce the string representation of the register list operand *OPND
3000 1.7 christos in the buffer pointed by BUF of size SIZE. PREFIX is the part of
3001 1.7 christos the register name that comes before the register number, such as "v". */
3002 1.1 christos static void
3003 1.1 christos print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
3004 1.1 christos const char *prefix)
3005 1.1 christos {
3006 1.1 christos const int num_regs = opnd->reglist.num_regs;
3007 1.1 christos const int first_reg = opnd->reglist.first_regno;
3008 1.1 christos const int last_reg = (first_reg + num_regs - 1) & 0x1f;
3009 1.1 christos const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
3010 1.1 christos char tb[8]; /* Temporary buffer. */
3011 1.1 christos
3012 1.1 christos assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
3013 1.1 christos assert (num_regs >= 1 && num_regs <= 4);
3014 1.7 christos
3015 1.7 christos /* Prepare the index if any. */
3016 1.1 christos if (opnd->reglist.has_index)
3017 1.1 christos /* PR 21096: The %100 is to silence a warning about possible truncation. */
3018 1.1 christos snprintf (tb, 8, "[%" PRIi64 "]", (opnd->reglist.index % 100));
3019 1.1 christos else
3020 1.1 christos tb[0] = '\0';
3021 1.1 christos
3022 1.1 christos /* The hyphenated form is preferred for disassembly if there are
3023 1.7 christos more than two registers in the list, and the register numbers
3024 1.7 christos are monotonically increasing in increments of one. */
3025 1.1 christos if (num_regs > 2 && last_reg > first_reg)
3026 1.1 christos snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, qlf_name,
3027 1.1 christos prefix, last_reg, qlf_name, tb);
3028 1.1 christos else
3029 1.1 christos {
3030 1.1 christos const int reg0 = first_reg;
3031 1.1 christos const int reg1 = (first_reg + 1) & 0x1f;
3032 1.1 christos const int reg2 = (first_reg + 2) & 0x1f;
3033 1.1 christos const int reg3 = (first_reg + 3) & 0x1f;
3034 1.1 christos
3035 1.7 christos switch (num_regs)
3036 1.1 christos {
3037 1.1 christos case 1:
3038 1.7 christos snprintf (buf, size, "{%s%d.%s}%s", prefix, reg0, qlf_name, tb);
3039 1.7 christos break;
3040 1.1 christos case 2:
3041 1.1 christos snprintf (buf, size, "{%s%d.%s, %s%d.%s}%s", prefix, reg0, qlf_name,
3042 1.7 christos prefix, reg1, qlf_name, tb);
3043 1.7 christos break;
3044 1.7 christos case 3:
3045 1.1 christos snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s}%s",
3046 1.1 christos prefix, reg0, qlf_name, prefix, reg1, qlf_name,
3047 1.7 christos prefix, reg2, qlf_name, tb);
3048 1.7 christos break;
3049 1.7 christos case 4:
3050 1.1 christos snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s, %s%d.%s}%s",
3051 1.1 christos prefix, reg0, qlf_name, prefix, reg1, qlf_name,
3052 1.1 christos prefix, reg2, qlf_name, prefix, reg3, qlf_name, tb);
3053 1.1 christos break;
3054 1.1 christos }
3055 1.7 christos }
3056 1.7 christos }
3057 1.7 christos
3058 1.7 christos /* Print the register+immediate address in OPND to BUF, which has SIZE
3059 1.7 christos characters. BASE is the name of the base register. */
3060 1.7 christos
3061 1.7 christos static void
3062 1.7 christos print_immediate_offset_address (char *buf, size_t size,
3063 1.7 christos const aarch64_opnd_info *opnd,
3064 1.7 christos const char *base)
3065 1.7 christos {
3066 1.9 christos if (opnd->addr.writeback)
3067 1.9 christos {
3068 1.9 christos if (opnd->addr.preind)
3069 1.9 christos {
3070 1.9 christos if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
3071 1.9 christos snprintf (buf, size, "[%s]!", base);
3072 1.7 christos else
3073 1.7 christos snprintf (buf, size, "[%s, #%d]!", base, opnd->addr.offset.imm);
3074 1.7 christos }
3075 1.7 christos else
3076 1.7 christos snprintf (buf, size, "[%s], #%d", base, opnd->addr.offset.imm);
3077 1.7 christos }
3078 1.7 christos else
3079 1.7 christos {
3080 1.7 christos if (opnd->shifter.operator_present)
3081 1.7 christos {
3082 1.7 christos assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
3083 1.7 christos snprintf (buf, size, "[%s, #%d, mul vl]",
3084 1.7 christos base, opnd->addr.offset.imm);
3085 1.7 christos }
3086 1.7 christos else if (opnd->addr.offset.imm)
3087 1.7 christos snprintf (buf, size, "[%s, #%d]", base, opnd->addr.offset.imm);
3088 1.7 christos else
3089 1.7 christos snprintf (buf, size, "[%s]", base);
3090 1.1 christos }
3091 1.7 christos }
3092 1.7 christos
3093 1.1 christos /* Produce the string representation of the register offset address operand
3094 1.1 christos *OPND in the buffer pointed by BUF of size SIZE. BASE and OFFSET are
3095 1.7 christos the names of the base and offset registers. */
3096 1.7 christos static void
3097 1.1 christos print_register_offset_address (char *buf, size_t size,
3098 1.6 christos const aarch64_opnd_info *opnd,
3099 1.1 christos const char *base, const char *offset)
3100 1.1 christos {
3101 1.1 christos char tb[16]; /* Temporary buffer. */
3102 1.1 christos bfd_boolean print_extend_p = TRUE;
3103 1.1 christos bfd_boolean print_amount_p = TRUE;
3104 1.1 christos const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
3105 1.1 christos
3106 1.1 christos if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
3107 1.1 christos || !opnd->shifter.amount_present))
3108 1.1 christos {
3109 1.1 christos /* Not print the shift/extend amount when the amount is zero and
3110 1.1 christos when it is not the special case of 8-bit load/store instruction. */
3111 1.7 christos print_amount_p = FALSE;
3112 1.1 christos /* Likewise, no need to print the shift operator LSL in such a
3113 1.1 christos situation. */
3114 1.1 christos if (opnd->shifter.kind == AARCH64_MOD_LSL)
3115 1.1 christos print_extend_p = FALSE;
3116 1.1 christos }
3117 1.1 christos
3118 1.1 christos /* Prepare for the extend/shift. */
3119 1.7 christos if (print_extend_p)
3120 1.7 christos {
3121 1.7 christos if (print_amount_p)
3122 1.1 christos snprintf (tb, sizeof (tb), ", %s #%" PRIi64, shift_name,
3123 1.7 christos /* PR 21096: The %100 is to silence a warning about possible truncation. */
3124 1.1 christos (opnd->shifter.amount % 100));
3125 1.1 christos else
3126 1.1 christos snprintf (tb, sizeof (tb), ", %s", shift_name);
3127 1.1 christos }
3128 1.7 christos else
3129 1.1 christos tb[0] = '\0';
3130 1.1 christos
3131 1.1 christos snprintf (buf, size, "[%s, %s%s]", base, offset, tb);
3132 1.1 christos }
3133 1.1 christos
3134 1.1 christos /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
3135 1.1 christos in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
3136 1.1 christos PC, PCREL_P and ADDRESS are used to pass in and return information about
3137 1.1 christos the PC-relative address calculation, where the PC value is passed in
3138 1.1 christos PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
3139 1.1 christos will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
3140 1.1 christos calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
3141 1.1 christos
3142 1.1 christos The function serves both the disassembler and the assembler diagnostics
3143 1.1 christos issuer, which is the reason why it lives in this file. */
3144 1.1 christos
3145 1.1 christos void
3146 1.9 christos aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
3147 1.9 christos const aarch64_opcode *opcode,
3148 1.1 christos const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
3149 1.7 christos bfd_vma *address, char** notes,
3150 1.1 christos aarch64_feature_set features)
3151 1.1 christos {
3152 1.1 christos unsigned int i, num_conds;
3153 1.7 christos const char *name = NULL;
3154 1.1 christos const aarch64_opnd_info *opnd = opnds + idx;
3155 1.1 christos enum aarch64_modifier_kind kind;
3156 1.1 christos uint64_t addr, enum_value;
3157 1.1 christos
3158 1.1 christos buf[0] = '\0';
3159 1.1 christos if (pcrel_p)
3160 1.1 christos *pcrel_p = 0;
3161 1.1 christos
3162 1.1 christos switch (opnd->type)
3163 1.1 christos {
3164 1.1 christos case AARCH64_OPND_Rd:
3165 1.1 christos case AARCH64_OPND_Rn:
3166 1.1 christos case AARCH64_OPND_Rm:
3167 1.1 christos case AARCH64_OPND_Rt:
3168 1.1 christos case AARCH64_OPND_Rt2:
3169 1.3 christos case AARCH64_OPND_Rs:
3170 1.7 christos case AARCH64_OPND_Ra:
3171 1.1 christos case AARCH64_OPND_Rt_SYS:
3172 1.8 christos case AARCH64_OPND_PAIRREG:
3173 1.1 christos case AARCH64_OPND_SVE_Rm:
3174 1.7 christos /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
3175 1.7 christos the <ic_op>, therefore we use opnd->present to override the
3176 1.7 christos generic optional-ness information. */
3177 1.7 christos if (opnd->type == AARCH64_OPND_Rt_SYS)
3178 1.7 christos {
3179 1.1 christos if (!opnd->present)
3180 1.7 christos break;
3181 1.7 christos }
3182 1.7 christos /* Omit the operand, e.g. RET. */
3183 1.1 christos else if (optional_operand_p (opcode, idx)
3184 1.1 christos && (opnd->reg.regno
3185 1.1 christos == get_optional_operand_default_value (opcode)))
3186 1.1 christos break;
3187 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
3188 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X);
3189 1.1 christos snprintf (buf, size, "%s",
3190 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3191 1.1 christos break;
3192 1.9 christos
3193 1.7 christos case AARCH64_OPND_Rd_SP:
3194 1.7 christos case AARCH64_OPND_Rn_SP:
3195 1.1 christos case AARCH64_OPND_Rt_SP:
3196 1.1 christos case AARCH64_OPND_SVE_Rn_SP:
3197 1.1 christos case AARCH64_OPND_Rm_SP:
3198 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
3199 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_WSP
3200 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X
3201 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_SP);
3202 1.1 christos snprintf (buf, size, "%s",
3203 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
3204 1.1 christos break;
3205 1.1 christos
3206 1.1 christos case AARCH64_OPND_Rm_EXT:
3207 1.1 christos kind = opnd->shifter.kind;
3208 1.1 christos assert (idx == 1 || idx == 2);
3209 1.1 christos if ((aarch64_stack_pointer_p (opnds)
3210 1.1 christos || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3211 1.1 christos && ((opnd->qualifier == AARCH64_OPND_QLF_W
3212 1.1 christos && opnds[0].qualifier == AARCH64_OPND_QLF_W
3213 1.1 christos && kind == AARCH64_MOD_UXTW)
3214 1.1 christos || (opnd->qualifier == AARCH64_OPND_QLF_X
3215 1.1 christos && kind == AARCH64_MOD_UXTX)))
3216 1.1 christos {
3217 1.1 christos /* 'LSL' is the preferred form in this case. */
3218 1.1 christos kind = AARCH64_MOD_LSL;
3219 1.1 christos if (opnd->shifter.amount == 0)
3220 1.1 christos {
3221 1.1 christos /* Shifter omitted. */
3222 1.1 christos snprintf (buf, size, "%s",
3223 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3224 1.1 christos break;
3225 1.7 christos }
3226 1.1 christos }
3227 1.1 christos if (opnd->shifter.amount)
3228 1.1 christos snprintf (buf, size, "%s, %s #%" PRIi64,
3229 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3230 1.1 christos aarch64_operand_modifiers[kind].name,
3231 1.1 christos opnd->shifter.amount);
3232 1.1 christos else
3233 1.1 christos snprintf (buf, size, "%s, %s",
3234 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3235 1.1 christos aarch64_operand_modifiers[kind].name);
3236 1.1 christos break;
3237 1.1 christos
3238 1.1 christos case AARCH64_OPND_Rm_SFT:
3239 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
3240 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X);
3241 1.1 christos if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3242 1.7 christos snprintf (buf, size, "%s",
3243 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3244 1.1 christos else
3245 1.1 christos snprintf (buf, size, "%s, %s #%" PRIi64,
3246 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3247 1.1 christos aarch64_operand_modifiers[opnd->shifter.kind].name,
3248 1.1 christos opnd->shifter.amount);
3249 1.1 christos break;
3250 1.1 christos
3251 1.1 christos case AARCH64_OPND_Fd:
3252 1.1 christos case AARCH64_OPND_Fn:
3253 1.1 christos case AARCH64_OPND_Fm:
3254 1.1 christos case AARCH64_OPND_Fa:
3255 1.1 christos case AARCH64_OPND_Ft:
3256 1.1 christos case AARCH64_OPND_Ft2:
3257 1.7 christos case AARCH64_OPND_Sd:
3258 1.7 christos case AARCH64_OPND_Sn:
3259 1.7 christos case AARCH64_OPND_Sm:
3260 1.7 christos case AARCH64_OPND_SVE_VZn:
3261 1.1 christos case AARCH64_OPND_SVE_Vd:
3262 1.1 christos case AARCH64_OPND_SVE_Vm:
3263 1.1 christos case AARCH64_OPND_SVE_Vn:
3264 1.1 christos snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
3265 1.8 christos opnd->reg.regno);
3266 1.1 christos break;
3267 1.1 christos
3268 1.1 christos case AARCH64_OPND_Va:
3269 1.1 christos case AARCH64_OPND_Vd:
3270 1.1 christos case AARCH64_OPND_Vn:
3271 1.1 christos case AARCH64_OPND_Vm:
3272 1.1 christos snprintf (buf, size, "v%d.%s", opnd->reg.regno,
3273 1.1 christos aarch64_get_qualifier_name (opnd->qualifier));
3274 1.1 christos break;
3275 1.1 christos
3276 1.8 christos case AARCH64_OPND_Ed:
3277 1.8 christos case AARCH64_OPND_En:
3278 1.6 christos case AARCH64_OPND_Em:
3279 1.1 christos case AARCH64_OPND_Em16:
3280 1.1 christos case AARCH64_OPND_SM3_IMM2:
3281 1.1 christos snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3282 1.1 christos aarch64_get_qualifier_name (opnd->qualifier),
3283 1.1 christos opnd->reglane.index);
3284 1.1 christos break;
3285 1.1 christos
3286 1.1 christos case AARCH64_OPND_VdD1:
3287 1.1 christos case AARCH64_OPND_VnD1:
3288 1.1 christos snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
3289 1.1 christos break;
3290 1.1 christos
3291 1.1 christos case AARCH64_OPND_LVn:
3292 1.7 christos case AARCH64_OPND_LVt:
3293 1.7 christos case AARCH64_OPND_LVt_AL:
3294 1.7 christos case AARCH64_OPND_LEt:
3295 1.7 christos print_register_list (buf, size, opnd, "v");
3296 1.7 christos break;
3297 1.7 christos
3298 1.7 christos case AARCH64_OPND_SVE_Pd:
3299 1.7 christos case AARCH64_OPND_SVE_Pg3:
3300 1.7 christos case AARCH64_OPND_SVE_Pg4_5:
3301 1.7 christos case AARCH64_OPND_SVE_Pg4_10:
3302 1.7 christos case AARCH64_OPND_SVE_Pg4_16:
3303 1.7 christos case AARCH64_OPND_SVE_Pm:
3304 1.7 christos case AARCH64_OPND_SVE_Pn:
3305 1.7 christos case AARCH64_OPND_SVE_Pt:
3306 1.7 christos if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3307 1.7 christos snprintf (buf, size, "p%d", opnd->reg.regno);
3308 1.7 christos else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
3309 1.7 christos || opnd->qualifier == AARCH64_OPND_QLF_P_M)
3310 1.7 christos snprintf (buf, size, "p%d/%s", opnd->reg.regno,
3311 1.7 christos aarch64_get_qualifier_name (opnd->qualifier));
3312 1.1 christos else
3313 1.1 christos snprintf (buf, size, "p%d.%s", opnd->reg.regno,
3314 1.7 christos aarch64_get_qualifier_name (opnd->qualifier));
3315 1.7 christos break;
3316 1.7 christos
3317 1.7 christos case AARCH64_OPND_SVE_Za_5:
3318 1.7 christos case AARCH64_OPND_SVE_Za_16:
3319 1.7 christos case AARCH64_OPND_SVE_Zd:
3320 1.7 christos case AARCH64_OPND_SVE_Zm_5:
3321 1.7 christos case AARCH64_OPND_SVE_Zm_16:
3322 1.7 christos case AARCH64_OPND_SVE_Zn:
3323 1.7 christos case AARCH64_OPND_SVE_Zt:
3324 1.7 christos if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3325 1.7 christos snprintf (buf, size, "z%d", opnd->reg.regno);
3326 1.7 christos else
3327 1.7 christos snprintf (buf, size, "z%d.%s", opnd->reg.regno,
3328 1.7 christos aarch64_get_qualifier_name (opnd->qualifier));
3329 1.7 christos break;
3330 1.7 christos
3331 1.7 christos case AARCH64_OPND_SVE_ZnxN:
3332 1.7 christos case AARCH64_OPND_SVE_ZtxN:
3333 1.7 christos print_register_list (buf, size, opnd, "z");
3334 1.7 christos break;
3335 1.9 christos
3336 1.9 christos case AARCH64_OPND_SVE_Zm3_INDEX:
3337 1.7 christos case AARCH64_OPND_SVE_Zm3_22_INDEX:
3338 1.7 christos case AARCH64_OPND_SVE_Zm3_11_INDEX:
3339 1.7 christos case AARCH64_OPND_SVE_Zm4_11_INDEX:
3340 1.7 christos case AARCH64_OPND_SVE_Zm4_INDEX:
3341 1.7 christos case AARCH64_OPND_SVE_Zn_INDEX:
3342 1.7 christos snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3343 1.7 christos aarch64_get_qualifier_name (opnd->qualifier),
3344 1.7 christos opnd->reglane.index);
3345 1.7 christos break;
3346 1.7 christos
3347 1.1 christos case AARCH64_OPND_CRn:
3348 1.1 christos case AARCH64_OPND_CRm:
3349 1.1 christos snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
3350 1.8 christos break;
3351 1.1 christos
3352 1.8 christos case AARCH64_OPND_IDX:
3353 1.1 christos case AARCH64_OPND_MASK:
3354 1.1 christos case AARCH64_OPND_IMM:
3355 1.1 christos case AARCH64_OPND_IMM_2:
3356 1.1 christos case AARCH64_OPND_WIDTH:
3357 1.1 christos case AARCH64_OPND_UIMM3_OP1:
3358 1.1 christos case AARCH64_OPND_UIMM3_OP2:
3359 1.1 christos case AARCH64_OPND_BIT_NUM:
3360 1.1 christos case AARCH64_OPND_IMM_VLSL:
3361 1.1 christos case AARCH64_OPND_IMM_VLSR:
3362 1.1 christos case AARCH64_OPND_SHLL_IMM:
3363 1.9 christos case AARCH64_OPND_IMM0:
3364 1.1 christos case AARCH64_OPND_IMMR:
3365 1.9 christos case AARCH64_OPND_IMMS:
3366 1.7 christos case AARCH64_OPND_UNDEFINED:
3367 1.7 christos case AARCH64_OPND_FBITS:
3368 1.7 christos case AARCH64_OPND_TME_UIMM16:
3369 1.9 christos case AARCH64_OPND_SIMM5:
3370 1.7 christos case AARCH64_OPND_SVE_SHLIMM_PRED:
3371 1.7 christos case AARCH64_OPND_SVE_SHLIMM_UNPRED:
3372 1.9 christos case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
3373 1.7 christos case AARCH64_OPND_SVE_SHRIMM_PRED:
3374 1.7 christos case AARCH64_OPND_SVE_SHRIMM_UNPRED:
3375 1.7 christos case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
3376 1.7 christos case AARCH64_OPND_SVE_SIMM5:
3377 1.7 christos case AARCH64_OPND_SVE_SIMM5B:
3378 1.7 christos case AARCH64_OPND_SVE_SIMM6:
3379 1.7 christos case AARCH64_OPND_SVE_SIMM8:
3380 1.7 christos case AARCH64_OPND_SVE_UIMM3:
3381 1.7 christos case AARCH64_OPND_SVE_UIMM7:
3382 1.7 christos case AARCH64_OPND_SVE_UIMM8:
3383 1.7 christos case AARCH64_OPND_SVE_UIMM8_53:
3384 1.7 christos case AARCH64_OPND_IMM_ROT1:
3385 1.7 christos case AARCH64_OPND_IMM_ROT2:
3386 1.9 christos case AARCH64_OPND_IMM_ROT3:
3387 1.1 christos case AARCH64_OPND_SVE_IMM_ROT1:
3388 1.1 christos case AARCH64_OPND_SVE_IMM_ROT2:
3389 1.1 christos case AARCH64_OPND_SVE_IMM_ROT3:
3390 1.7 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3391 1.7 christos break;
3392 1.7 christos
3393 1.7 christos case AARCH64_OPND_SVE_I1_HALF_ONE:
3394 1.7 christos case AARCH64_OPND_SVE_I1_HALF_TWO:
3395 1.7 christos case AARCH64_OPND_SVE_I1_ZERO_ONE:
3396 1.7 christos {
3397 1.7 christos single_conv_t c;
3398 1.7 christos c.i = opnd->imm.value;
3399 1.7 christos snprintf (buf, size, "#%.1f", c.f);
3400 1.7 christos break;
3401 1.7 christos }
3402 1.7 christos
3403 1.7 christos case AARCH64_OPND_SVE_PATTERN:
3404 1.7 christos if (optional_operand_p (opcode, idx)
3405 1.7 christos && opnd->imm.value == get_optional_operand_default_value (opcode))
3406 1.7 christos break;
3407 1.7 christos enum_value = opnd->imm.value;
3408 1.7 christos assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3409 1.7 christos if (aarch64_sve_pattern_array[enum_value])
3410 1.7 christos snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
3411 1.7 christos else
3412 1.7 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3413 1.7 christos break;
3414 1.7 christos
3415 1.7 christos case AARCH64_OPND_SVE_PATTERN_SCALED:
3416 1.7 christos if (optional_operand_p (opcode, idx)
3417 1.7 christos && !opnd->shifter.operator_present
3418 1.7 christos && opnd->imm.value == get_optional_operand_default_value (opcode))
3419 1.7 christos break;
3420 1.7 christos enum_value = opnd->imm.value;
3421 1.7 christos assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3422 1.7 christos if (aarch64_sve_pattern_array[opnd->imm.value])
3423 1.7 christos snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
3424 1.7 christos else
3425 1.7 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3426 1.7 christos if (opnd->shifter.operator_present)
3427 1.7 christos {
3428 1.7 christos size_t len = strlen (buf);
3429 1.7 christos snprintf (buf + len, size - len, ", %s #%" PRIi64,
3430 1.7 christos aarch64_operand_modifiers[opnd->shifter.kind].name,
3431 1.7 christos opnd->shifter.amount);
3432 1.7 christos }
3433 1.7 christos break;
3434 1.7 christos
3435 1.7 christos case AARCH64_OPND_SVE_PRFOP:
3436 1.7 christos enum_value = opnd->imm.value;
3437 1.7 christos assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
3438 1.7 christos if (aarch64_sve_prfop_array[enum_value])
3439 1.7 christos snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
3440 1.7 christos else
3441 1.1 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3442 1.1 christos break;
3443 1.1 christos
3444 1.1 christos case AARCH64_OPND_IMM_MOV:
3445 1.1 christos switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3446 1.1 christos {
3447 1.1 christos case 4: /* e.g. MOV Wd, #<imm32>. */
3448 1.1 christos {
3449 1.1 christos int imm32 = opnd->imm.value;
3450 1.1 christos snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
3451 1.1 christos }
3452 1.1 christos break;
3453 1.1 christos case 8: /* e.g. MOV Xd, #<imm64>. */
3454 1.1 christos snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
3455 1.1 christos opnd->imm.value, opnd->imm.value);
3456 1.1 christos break;
3457 1.1 christos default: assert (0);
3458 1.1 christos }
3459 1.1 christos break;
3460 1.1 christos
3461 1.1 christos case AARCH64_OPND_FPIMM0:
3462 1.1 christos snprintf (buf, size, "#0.0");
3463 1.1 christos break;
3464 1.1 christos
3465 1.7 christos case AARCH64_OPND_LIMM:
3466 1.7 christos case AARCH64_OPND_AIMM:
3467 1.7 christos case AARCH64_OPND_HALF:
3468 1.1 christos case AARCH64_OPND_SVE_INV_LIMM:
3469 1.7 christos case AARCH64_OPND_SVE_LIMM:
3470 1.1 christos case AARCH64_OPND_SVE_LIMM_MOV:
3471 1.1 christos if (opnd->shifter.amount)
3472 1.1 christos snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
3473 1.1 christos opnd->shifter.amount);
3474 1.1 christos else
3475 1.1 christos snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3476 1.1 christos break;
3477 1.1 christos
3478 1.1 christos case AARCH64_OPND_SIMD_IMM:
3479 1.1 christos case AARCH64_OPND_SIMD_IMM_SFT:
3480 1.1 christos if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
3481 1.7 christos || opnd->shifter.kind == AARCH64_MOD_NONE)
3482 1.1 christos snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3483 1.1 christos else
3484 1.1 christos snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
3485 1.1 christos aarch64_operand_modifiers[opnd->shifter.kind].name,
3486 1.7 christos opnd->shifter.amount);
3487 1.7 christos break;
3488 1.7 christos
3489 1.7 christos case AARCH64_OPND_SVE_AIMM:
3490 1.7 christos case AARCH64_OPND_SVE_ASIMM:
3491 1.7 christos if (opnd->shifter.amount)
3492 1.7 christos snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
3493 1.7 christos opnd->shifter.amount);
3494 1.7 christos else
3495 1.1 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3496 1.1 christos break;
3497 1.7 christos
3498 1.1 christos case AARCH64_OPND_FPIMM:
3499 1.1 christos case AARCH64_OPND_SIMD_FPIMM:
3500 1.6 christos case AARCH64_OPND_SVE_FPIMM8:
3501 1.6 christos switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3502 1.6 christos {
3503 1.6 christos case 2: /* e.g. FMOV <Hd>, #<imm>. */
3504 1.6 christos {
3505 1.6 christos half_conv_t c;
3506 1.6 christos c.i = expand_fp_imm (2, opnd->imm.value);
3507 1.1 christos snprintf (buf, size, "#%.18e", c.f);
3508 1.1 christos }
3509 1.1 christos break;
3510 1.6 christos case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
3511 1.1 christos {
3512 1.1 christos single_conv_t c;
3513 1.1 christos c.i = expand_fp_imm (4, opnd->imm.value);
3514 1.1 christos snprintf (buf, size, "#%.18e", c.f);
3515 1.1 christos }
3516 1.1 christos break;
3517 1.6 christos case 8: /* e.g. FMOV <Sd>, #<imm>. */
3518 1.1 christos {
3519 1.1 christos double_conv_t c;
3520 1.1 christos c.i = expand_fp_imm (8, opnd->imm.value);
3521 1.1 christos snprintf (buf, size, "#%.18e", c.d);
3522 1.1 christos }
3523 1.1 christos break;
3524 1.1 christos default: assert (0);
3525 1.1 christos }
3526 1.1 christos break;
3527 1.1 christos
3528 1.1 christos case AARCH64_OPND_CCMP_IMM:
3529 1.8 christos case AARCH64_OPND_NZCV:
3530 1.1 christos case AARCH64_OPND_EXCEPTION:
3531 1.8 christos case AARCH64_OPND_UIMM4:
3532 1.1 christos case AARCH64_OPND_UIMM4_ADDG:
3533 1.1 christos case AARCH64_OPND_UIMM7:
3534 1.1 christos case AARCH64_OPND_UIMM10:
3535 1.1 christos if (optional_operand_p (opcode, idx) == TRUE
3536 1.1 christos && (opnd->imm.value ==
3537 1.1 christos (int64_t) get_optional_operand_default_value (opcode)))
3538 1.1 christos /* Omit the operand, e.g. DCPS1. */
3539 1.1 christos break;
3540 1.1 christos snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
3541 1.1 christos break;
3542 1.1 christos
3543 1.7 christos case AARCH64_OPND_COND:
3544 1.7 christos case AARCH64_OPND_COND1:
3545 1.7 christos snprintf (buf, size, "%s", opnd->cond->names[0]);
3546 1.7 christos num_conds = ARRAY_SIZE (opnd->cond->names);
3547 1.7 christos for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
3548 1.7 christos {
3549 1.7 christos size_t len = strlen (buf);
3550 1.7 christos if (i == 1)
3551 1.7 christos snprintf (buf + len, size - len, " // %s = %s",
3552 1.7 christos opnd->cond->names[0], opnd->cond->names[i]);
3553 1.7 christos else
3554 1.1 christos snprintf (buf + len, size - len, ", %s",
3555 1.1 christos opnd->cond->names[i]);
3556 1.1 christos }
3557 1.1 christos break;
3558 1.1 christos
3559 1.1 christos case AARCH64_OPND_ADDR_ADRP:
3560 1.1 christos addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
3561 1.1 christos + opnd->imm.value;
3562 1.1 christos if (pcrel_p)
3563 1.1 christos *pcrel_p = 1;
3564 1.1 christos if (address)
3565 1.1 christos *address = addr;
3566 1.1 christos /* This is not necessary during the disassembling, as print_address_func
3567 1.1 christos in the disassemble_info will take care of the printing. But some
3568 1.1 christos other callers may be still interested in getting the string in *STR,
3569 1.1 christos so here we do snprintf regardless. */
3570 1.1 christos snprintf (buf, size, "#0x%" PRIx64, addr);
3571 1.1 christos break;
3572 1.1 christos
3573 1.1 christos case AARCH64_OPND_ADDR_PCREL14:
3574 1.1 christos case AARCH64_OPND_ADDR_PCREL19:
3575 1.1 christos case AARCH64_OPND_ADDR_PCREL21:
3576 1.1 christos case AARCH64_OPND_ADDR_PCREL26:
3577 1.1 christos addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
3578 1.1 christos if (pcrel_p)
3579 1.1 christos *pcrel_p = 1;
3580 1.1 christos if (address)
3581 1.1 christos *address = addr;
3582 1.1 christos /* This is not necessary during the disassembling, as print_address_func
3583 1.1 christos in the disassemble_info will take care of the printing. But some
3584 1.1 christos other callers may be still interested in getting the string in *STR,
3585 1.1 christos so here we do snprintf regardless. */
3586 1.1 christos snprintf (buf, size, "#0x%" PRIx64, addr);
3587 1.1 christos break;
3588 1.1 christos
3589 1.1 christos case AARCH64_OPND_ADDR_SIMPLE:
3590 1.1 christos case AARCH64_OPND_SIMD_ADDR_SIMPLE:
3591 1.1 christos case AARCH64_OPND_SIMD_ADDR_POST:
3592 1.1 christos name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3593 1.1 christos if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
3594 1.1 christos {
3595 1.1 christos if (opnd->addr.offset.is_reg)
3596 1.1 christos snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
3597 1.1 christos else
3598 1.1 christos snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
3599 1.1 christos }
3600 1.1 christos else
3601 1.1 christos snprintf (buf, size, "[%s]", name);
3602 1.8 christos break;
3603 1.7 christos
3604 1.7 christos case AARCH64_OPND_ADDR_REGOFF:
3605 1.7 christos case AARCH64_OPND_SVE_ADDR_R:
3606 1.7 christos case AARCH64_OPND_SVE_ADDR_RR:
3607 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL1:
3608 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL2:
3609 1.7 christos case AARCH64_OPND_SVE_ADDR_RR_LSL3:
3610 1.7 christos case AARCH64_OPND_SVE_ADDR_RX:
3611 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL1:
3612 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL2:
3613 1.7 christos case AARCH64_OPND_SVE_ADDR_RX_LSL3:
3614 1.7 christos print_register_offset_address
3615 1.7 christos (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3616 1.9 christos get_offset_int_reg_name (opnd));
3617 1.9 christos break;
3618 1.9 christos
3619 1.9 christos case AARCH64_OPND_SVE_ADDR_ZX:
3620 1.9 christos print_register_offset_address
3621 1.9 christos (buf, size, opnd,
3622 1.9 christos get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
3623 1.7 christos get_64bit_int_reg_name (opnd->addr.offset.regno, 0));
3624 1.7 christos break;
3625 1.7 christos
3626 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ:
3627 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
3628 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
3629 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
3630 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
3631 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
3632 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
3633 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
3634 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
3635 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
3636 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
3637 1.7 christos case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
3638 1.1 christos print_register_offset_address
3639 1.1 christos (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3640 1.1 christos get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3641 1.1 christos break;
3642 1.1 christos
3643 1.7 christos case AARCH64_OPND_ADDR_SIMM7:
3644 1.8 christos case AARCH64_OPND_ADDR_SIMM9:
3645 1.8 christos case AARCH64_OPND_ADDR_SIMM9_2:
3646 1.8 christos case AARCH64_OPND_ADDR_SIMM10:
3647 1.7 christos case AARCH64_OPND_ADDR_SIMM11:
3648 1.9 christos case AARCH64_OPND_ADDR_SIMM13:
3649 1.7 christos case AARCH64_OPND_ADDR_OFFSET:
3650 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x16:
3651 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x32:
3652 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
3653 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
3654 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
3655 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
3656 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
3657 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
3658 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6:
3659 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x2:
3660 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x4:
3661 1.7 christos case AARCH64_OPND_SVE_ADDR_RI_U6x8:
3662 1.7 christos print_immediate_offset_address
3663 1.7 christos (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
3664 1.7 christos break;
3665 1.7 christos
3666 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5:
3667 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
3668 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
3669 1.7 christos case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
3670 1.7 christos print_immediate_offset_address
3671 1.7 christos (buf, size, opnd,
3672 1.7 christos get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier));
3673 1.7 christos break;
3674 1.7 christos
3675 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
3676 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
3677 1.7 christos case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
3678 1.7 christos print_register_offset_address
3679 1.1 christos (buf, size, opnd,
3680 1.1 christos get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
3681 1.1 christos get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3682 1.1 christos break;
3683 1.1 christos
3684 1.7 christos case AARCH64_OPND_ADDR_UIMM12:
3685 1.1 christos name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3686 1.1 christos if (opnd->addr.offset.imm)
3687 1.1 christos snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm);
3688 1.1 christos else
3689 1.1 christos snprintf (buf, size, "[%s]", name);
3690 1.1 christos break;
3691 1.8 christos
3692 1.9 christos case AARCH64_OPND_SYSREG:
3693 1.9 christos for (i = 0; aarch64_sys_regs[i].name; ++i)
3694 1.8 christos {
3695 1.9 christos const aarch64_sys_reg *sr = aarch64_sys_regs + i;
3696 1.9 christos
3697 1.9 christos bfd_boolean exact_match
3698 1.8 christos = (!(sr->flags & (F_REG_READ | F_REG_WRITE))
3699 1.8 christos || (sr->flags & opnd->sysreg.flags) == opnd->sysreg.flags)
3700 1.8 christos && AARCH64_CPU_HAS_FEATURE (features, sr->features);
3701 1.8 christos
3702 1.9 christos /* Try and find an exact match, But if that fails, return the first
3703 1.8 christos partial match that was found. */
3704 1.8 christos if (aarch64_sys_regs[i].value == opnd->sysreg.value
3705 1.8 christos && ! aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
3706 1.8 christos && (name == NULL || exact_match))
3707 1.8 christos {
3708 1.8 christos name = aarch64_sys_regs[i].name;
3709 1.8 christos if (exact_match)
3710 1.8 christos {
3711 1.8 christos if (notes)
3712 1.8 christos *notes = NULL;
3713 1.8 christos break;
3714 1.8 christos }
3715 1.8 christos
3716 1.8 christos /* If we didn't match exactly, that means the presense of a flag
3717 1.8 christos indicates what we didn't want for this instruction. e.g. If
3718 1.8 christos F_REG_READ is there, that means we were looking for a write
3719 1.8 christos register. See aarch64_ext_sysreg. */
3720 1.8 christos if (aarch64_sys_regs[i].flags & F_REG_WRITE)
3721 1.8 christos *notes = _("reading from a write-only register");
3722 1.8 christos else if (aarch64_sys_regs[i].flags & F_REG_READ)
3723 1.8 christos *notes = _("writing to a read-only register");
3724 1.8 christos }
3725 1.8 christos }
3726 1.1 christos
3727 1.1 christos if (name)
3728 1.1 christos snprintf (buf, size, "%s", name);
3729 1.8 christos else
3730 1.1 christos {
3731 1.1 christos /* Implementation defined system register. */
3732 1.1 christos unsigned int value = opnd->sysreg.value;
3733 1.1 christos snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
3734 1.1 christos (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
3735 1.1 christos value & 0x7);
3736 1.1 christos }
3737 1.1 christos break;
3738 1.1 christos
3739 1.1 christos case AARCH64_OPND_PSTATEFIELD:
3740 1.1 christos for (i = 0; aarch64_pstatefields[i].name; ++i)
3741 1.1 christos if (aarch64_pstatefields[i].value == opnd->pstatefield)
3742 1.1 christos break;
3743 1.1 christos assert (aarch64_pstatefields[i].name);
3744 1.1 christos snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
3745 1.1 christos break;
3746 1.1 christos
3747 1.1 christos case AARCH64_OPND_SYSREG_AT:
3748 1.8 christos case AARCH64_OPND_SYSREG_DC:
3749 1.6 christos case AARCH64_OPND_SYSREG_IC:
3750 1.1 christos case AARCH64_OPND_SYSREG_TLBI:
3751 1.1 christos case AARCH64_OPND_SYSREG_SR:
3752 1.1 christos snprintf (buf, size, "%s", opnd->sysins_op->name);
3753 1.1 christos break;
3754 1.1 christos
3755 1.1 christos case AARCH64_OPND_BARRIER:
3756 1.1 christos snprintf (buf, size, "%s", opnd->barrier->name);
3757 1.1 christos break;
3758 1.1 christos
3759 1.1 christos case AARCH64_OPND_BARRIER_ISB:
3760 1.1 christos /* Operand can be omitted, e.g. in DCPS1. */
3761 1.1 christos if (! optional_operand_p (opcode, idx)
3762 1.1 christos || (opnd->barrier->value
3763 1.1 christos != get_optional_operand_default_value (opcode)))
3764 1.1 christos snprintf (buf, size, "#0x%x", opnd->barrier->value);
3765 1.1 christos break;
3766 1.1 christos
3767 1.1 christos case AARCH64_OPND_PRFOP:
3768 1.1 christos if (opnd->prfop->name != NULL)
3769 1.1 christos snprintf (buf, size, "%s", opnd->prfop->name);
3770 1.1 christos else
3771 1.6 christos snprintf (buf, size, "#0x%02x", opnd->prfop->value);
3772 1.9 christos break;
3773 1.9 christos
3774 1.9 christos case AARCH64_OPND_BARRIER_PSB:
3775 1.8 christos snprintf (buf, size, "csync");
3776 1.8 christos break;
3777 1.8 christos
3778 1.6 christos case AARCH64_OPND_BTI_TARGET:
3779 1.6 christos if ((HINT_FLAG (opnd->hint_option->value) & HINT_OPD_F_NOPRINT) == 0)
3780 1.1 christos snprintf (buf, size, "%s", opnd->hint_option->name);
3781 1.1 christos break;
3782 1.1 christos
3783 1.1 christos default:
3784 1.1 christos assert (0);
3785 1.1 christos }
3786 1.1 christos }
3787 1.1 christos
3788 1.1 christos #define CPENC(op0,op1,crn,crm,op2) \
3790 1.1 christos ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
3791 1.1 christos /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
3792 1.1 christos #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
3793 1.1 christos /* for 3.9.10 System Instructions */
3794 1.1 christos #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
3795 1.1 christos
3796 1.1 christos #define C0 0
3797 1.1 christos #define C1 1
3798 1.1 christos #define C2 2
3799 1.1 christos #define C3 3
3800 1.1 christos #define C4 4
3801 1.1 christos #define C5 5
3802 1.1 christos #define C6 6
3803 1.1 christos #define C7 7
3804 1.1 christos #define C8 8
3805 1.1 christos #define C9 9
3806 1.1 christos #define C10 10
3807 1.1 christos #define C11 11
3808 1.1 christos #define C12 12
3809 1.9 christos #define C13 13
3810 1.9 christos #define C14 14
3811 1.9 christos #define C15 15
3812 1.9 christos
3813 1.9 christos #define SYSREG(name, encoding, flags, features) \
3814 1.9 christos { name, encoding, flags, features }
3815 1.9 christos
3816 1.9 christos #define SR_CORE(n,e,f) SYSREG (n,e,f,0)
3817 1.9 christos
3818 1.9 christos #define SR_FEAT(n,e,f,feat) \
3819 1.9 christos SYSREG ((n), (e), (f) | F_ARCHEXT, AARCH64_FEATURE_##feat)
3820 1.9 christos
3821 1.9 christos #define SR_FEAT2(n,e,f,fe1,fe2) \
3822 1.9 christos SYSREG ((n), (e), (f) | F_ARCHEXT, \
3823 1.9 christos AARCH64_FEATURE_##fe1 | AARCH64_FEATURE_##fe2)
3824 1.9 christos
3825 1.9 christos #define SR_RNG(n,e,f) SR_FEAT2(n,e,f,RNG,V8_5)
3826 1.9 christos #define SR_V8_1_A(n,e,f) SR_FEAT2(n,e,f,V8_A,V8_1)
3827 1.9 christos #define SR_V8_4_A(n,e,f) SR_FEAT2(n,e,f,V8_A,V8_4)
3828 1.9 christos
3829 1.9 christos #define SR_V8_A(n,e,f) SR_FEAT (n,e,f,V8_A)
3830 1.9 christos #define SR_V8_R(n,e,f) SR_FEAT (n,e,f,V8_R)
3831 1.9 christos #define SR_V8_1(n,e,f) SR_FEAT (n,e,f,V8_1)
3832 1.9 christos #define SR_V8_2(n,e,f) SR_FEAT (n,e,f,V8_2)
3833 1.9 christos #define SR_V8_3(n,e,f) SR_FEAT (n,e,f,V8_3)
3834 1.9 christos #define SR_V8_4(n,e,f) SR_FEAT (n,e,f,V8_4)
3835 1.9 christos #define SR_V8_4(n,e,f) SR_FEAT (n,e,f,V8_4)
3836 1.9 christos #define SR_PAN(n,e,f) SR_FEAT (n,e,f,PAN)
3837 1.9 christos #define SR_RAS(n,e,f) SR_FEAT (n,e,f,RAS)
3838 1.9 christos #define SR_SSBS(n,e,f) SR_FEAT (n,e,f,SSBS)
3839 1.9 christos #define SR_SVE(n,e,f) SR_FEAT (n,e,f,SVE)
3840 1.9 christos #define SR_ID_PFR2(n,e,f) SR_FEAT (n,e,f,ID_PFR2)
3841 1.9 christos #define SR_PROFILE(n,e,f) SR_FEAT (n,e,f,PROFILE)
3842 1.9 christos #define SR_MEMTAG(n,e,f) SR_FEAT (n,e,f,MEMTAG)
3843 1.9 christos #define SR_SCXTNUM(n,e,f) SR_FEAT (n,e,f,SCXTNUM)
3844 1.9 christos
3845 1.9 christos #define SR_EXPAND_ELx(f,x) \
3846 1.9 christos f (x, 1), \
3847 1.9 christos f (x, 2), \
3848 1.9 christos f (x, 3), \
3849 1.9 christos f (x, 4), \
3850 1.9 christos f (x, 5), \
3851 1.9 christos f (x, 6), \
3852 1.9 christos f (x, 7), \
3853 1.9 christos f (x, 8), \
3854 1.9 christos f (x, 9), \
3855 1.9 christos f (x, 10), \
3856 1.9 christos f (x, 11), \
3857 1.9 christos f (x, 12), \
3858 1.9 christos f (x, 13), \
3859 1.9 christos f (x, 14), \
3860 1.9 christos f (x, 15),
3861 1.9 christos
3862 1.8 christos #define SR_EXPAND_EL12(f) \
3863 1.9 christos SR_EXPAND_ELx (f,1) \
3864 1.9 christos SR_EXPAND_ELx (f,2)
3865 1.9 christos
3866 1.9 christos /* TODO there is one more issues need to be resolved
3867 1.1 christos 1. handle cpu-implementation-defined system registers.
3868 1.1 christos
3869 1.9 christos Note that the F_REG_{READ,WRITE} flags mean read-only and write-only
3870 1.9 christos respectively. If neither of these are set then the register is read-write. */
3871 1.9 christos const aarch64_sys_reg aarch64_sys_regs [] =
3872 1.9 christos {
3873 1.9 christos SR_CORE ("spsr_el1", CPEN_ (0,C0,0), 0), /* = spsr_svc. */
3874 1.9 christos SR_V8_1 ("spsr_el12", CPEN_ (5,C0,0), 0),
3875 1.9 christos SR_CORE ("elr_el1", CPEN_ (0,C0,1), 0),
3876 1.9 christos SR_V8_1 ("elr_el12", CPEN_ (5,C0,1), 0),
3877 1.9 christos SR_CORE ("sp_el0", CPEN_ (0,C1,0), 0),
3878 1.9 christos SR_CORE ("spsel", CPEN_ (0,C2,0), 0),
3879 1.9 christos SR_CORE ("daif", CPEN_ (3,C2,1), 0),
3880 1.9 christos SR_CORE ("currentel", CPEN_ (0,C2,2), F_REG_READ),
3881 1.9 christos SR_PAN ("pan", CPEN_ (0,C2,3), 0),
3882 1.9 christos SR_V8_2 ("uao", CPEN_ (0,C2,4), 0),
3883 1.9 christos SR_CORE ("nzcv", CPEN_ (3,C2,0), 0),
3884 1.9 christos SR_SSBS ("ssbs", CPEN_ (3,C2,6), 0),
3885 1.9 christos SR_CORE ("fpcr", CPEN_ (3,C4,0), 0),
3886 1.9 christos SR_CORE ("fpsr", CPEN_ (3,C4,1), 0),
3887 1.9 christos SR_CORE ("dspsr_el0", CPEN_ (3,C5,0), 0),
3888 1.9 christos SR_CORE ("dlr_el0", CPEN_ (3,C5,1), 0),
3889 1.9 christos SR_CORE ("spsr_el2", CPEN_ (4,C0,0), 0), /* = spsr_hyp. */
3890 1.9 christos SR_CORE ("elr_el2", CPEN_ (4,C0,1), 0),
3891 1.9 christos SR_CORE ("sp_el1", CPEN_ (4,C1,0), 0),
3892 1.9 christos SR_CORE ("spsr_irq", CPEN_ (4,C3,0), 0),
3893 1.9 christos SR_CORE ("spsr_abt", CPEN_ (4,C3,1), 0),
3894 1.9 christos SR_CORE ("spsr_und", CPEN_ (4,C3,2), 0),
3895 1.9 christos SR_CORE ("spsr_fiq", CPEN_ (4,C3,3), 0),
3896 1.9 christos SR_CORE ("spsr_el3", CPEN_ (6,C0,0), 0),
3897 1.9 christos SR_CORE ("elr_el3", CPEN_ (6,C0,1), 0),
3898 1.9 christos SR_CORE ("sp_el2", CPEN_ (6,C1,0), 0),
3899 1.9 christos SR_CORE ("spsr_svc", CPEN_ (0,C0,0), F_DEPRECATED), /* = spsr_el1. */
3900 1.9 christos SR_CORE ("spsr_hyp", CPEN_ (4,C0,0), F_DEPRECATED), /* = spsr_el2. */
3901 1.9 christos SR_CORE ("midr_el1", CPENC (3,0,C0,C0,0), F_REG_READ),
3902 1.9 christos SR_CORE ("ctr_el0", CPENC (3,3,C0,C0,1), F_REG_READ),
3903 1.9 christos SR_CORE ("mpidr_el1", CPENC (3,0,C0,C0,5), F_REG_READ),
3904 1.9 christos SR_CORE ("revidr_el1", CPENC (3,0,C0,C0,6), F_REG_READ),
3905 1.9 christos SR_CORE ("aidr_el1", CPENC (3,1,C0,C0,7), F_REG_READ),
3906 1.9 christos SR_CORE ("dczid_el0", CPENC (3,3,C0,C0,7), F_REG_READ),
3907 1.9 christos SR_CORE ("id_dfr0_el1", CPENC (3,0,C0,C1,2), F_REG_READ),
3908 1.9 christos SR_CORE ("id_pfr0_el1", CPENC (3,0,C0,C1,0), F_REG_READ),
3909 1.9 christos SR_CORE ("id_pfr1_el1", CPENC (3,0,C0,C1,1), F_REG_READ),
3910 1.9 christos SR_ID_PFR2 ("id_pfr2_el1", CPENC (3,0,C0,C3,4), F_REG_READ),
3911 1.9 christos SR_CORE ("id_afr0_el1", CPENC (3,0,C0,C1,3), F_REG_READ),
3912 1.9 christos SR_CORE ("id_mmfr0_el1", CPENC (3,0,C0,C1,4), F_REG_READ),
3913 1.9 christos SR_CORE ("id_mmfr1_el1", CPENC (3,0,C0,C1,5), F_REG_READ),
3914 1.9 christos SR_CORE ("id_mmfr2_el1", CPENC (3,0,C0,C1,6), F_REG_READ),
3915 1.9 christos SR_CORE ("id_mmfr3_el1", CPENC (3,0,C0,C1,7), F_REG_READ),
3916 1.9 christos SR_CORE ("id_mmfr4_el1", CPENC (3,0,C0,C2,6), F_REG_READ),
3917 1.9 christos SR_CORE ("id_isar0_el1", CPENC (3,0,C0,C2,0), F_REG_READ),
3918 1.9 christos SR_CORE ("id_isar1_el1", CPENC (3,0,C0,C2,1), F_REG_READ),
3919 1.9 christos SR_CORE ("id_isar2_el1", CPENC (3,0,C0,C2,2), F_REG_READ),
3920 1.9 christos SR_CORE ("id_isar3_el1", CPENC (3,0,C0,C2,3), F_REG_READ),
3921 1.9 christos SR_CORE ("id_isar4_el1", CPENC (3,0,C0,C2,4), F_REG_READ),
3922 1.9 christos SR_CORE ("id_isar5_el1", CPENC (3,0,C0,C2,5), F_REG_READ),
3923 1.9 christos SR_CORE ("mvfr0_el1", CPENC (3,0,C0,C3,0), F_REG_READ),
3924 1.9 christos SR_CORE ("mvfr1_el1", CPENC (3,0,C0,C3,1), F_REG_READ),
3925 1.9 christos SR_CORE ("mvfr2_el1", CPENC (3,0,C0,C3,2), F_REG_READ),
3926 1.9 christos SR_CORE ("ccsidr_el1", CPENC (3,1,C0,C0,0), F_REG_READ),
3927 1.9 christos SR_CORE ("id_aa64pfr0_el1", CPENC (3,0,C0,C4,0), F_REG_READ),
3928 1.9 christos SR_CORE ("id_aa64pfr1_el1", CPENC (3,0,C0,C4,1), F_REG_READ),
3929 1.9 christos SR_CORE ("id_aa64dfr0_el1", CPENC (3,0,C0,C5,0), F_REG_READ),
3930 1.9 christos SR_CORE ("id_aa64dfr1_el1", CPENC (3,0,C0,C5,1), F_REG_READ),
3931 1.9 christos SR_CORE ("id_aa64isar0_el1", CPENC (3,0,C0,C6,0), F_REG_READ),
3932 1.9 christos SR_CORE ("id_aa64isar1_el1", CPENC (3,0,C0,C6,1), F_REG_READ),
3933 1.9 christos SR_CORE ("id_aa64mmfr0_el1", CPENC (3,0,C0,C7,0), F_REG_READ),
3934 1.9 christos SR_CORE ("id_aa64mmfr1_el1", CPENC (3,0,C0,C7,1), F_REG_READ),
3935 1.9 christos SR_V8_2 ("id_aa64mmfr2_el1", CPENC (3,0,C0,C7,2), F_REG_READ),
3936 1.9 christos SR_CORE ("id_aa64afr0_el1", CPENC (3,0,C0,C5,4), F_REG_READ),
3937 1.9 christos SR_CORE ("id_aa64afr1_el1", CPENC (3,0,C0,C5,5), F_REG_READ),
3938 1.9 christos SR_SVE ("id_aa64zfr0_el1", CPENC (3,0,C0,C4,4), F_REG_READ),
3939 1.9 christos SR_CORE ("clidr_el1", CPENC (3,1,C0,C0,1), F_REG_READ),
3940 1.9 christos SR_CORE ("csselr_el1", CPENC (3,2,C0,C0,0), 0),
3941 1.9 christos SR_CORE ("vpidr_el2", CPENC (3,4,C0,C0,0), 0),
3942 1.9 christos SR_CORE ("vmpidr_el2", CPENC (3,4,C0,C0,5), 0),
3943 1.9 christos SR_CORE ("sctlr_el1", CPENC (3,0,C1,C0,0), 0),
3944 1.9 christos SR_CORE ("sctlr_el2", CPENC (3,4,C1,C0,0), 0),
3945 1.9 christos SR_CORE ("sctlr_el3", CPENC (3,6,C1,C0,0), 0),
3946 1.9 christos SR_V8_1 ("sctlr_el12", CPENC (3,5,C1,C0,0), 0),
3947 1.9 christos SR_CORE ("actlr_el1", CPENC (3,0,C1,C0,1), 0),
3948 1.9 christos SR_CORE ("actlr_el2", CPENC (3,4,C1,C0,1), 0),
3949 1.9 christos SR_CORE ("actlr_el3", CPENC (3,6,C1,C0,1), 0),
3950 1.9 christos SR_CORE ("cpacr_el1", CPENC (3,0,C1,C0,2), 0),
3951 1.9 christos SR_V8_1 ("cpacr_el12", CPENC (3,5,C1,C0,2), 0),
3952 1.9 christos SR_CORE ("cptr_el2", CPENC (3,4,C1,C1,2), 0),
3953 1.9 christos SR_CORE ("cptr_el3", CPENC (3,6,C1,C1,2), 0),
3954 1.9 christos SR_CORE ("scr_el3", CPENC (3,6,C1,C1,0), 0),
3955 1.9 christos SR_CORE ("hcr_el2", CPENC (3,4,C1,C1,0), 0),
3956 1.9 christos SR_CORE ("mdcr_el2", CPENC (3,4,C1,C1,1), 0),
3957 1.9 christos SR_CORE ("mdcr_el3", CPENC (3,6,C1,C3,1), 0),
3958 1.9 christos SR_CORE ("hstr_el2", CPENC (3,4,C1,C1,3), 0),
3959 1.9 christos SR_CORE ("hacr_el2", CPENC (3,4,C1,C1,7), 0),
3960 1.9 christos SR_SVE ("zcr_el1", CPENC (3,0,C1,C2,0), 0),
3961 1.9 christos SR_SVE ("zcr_el12", CPENC (3,5,C1,C2,0), 0),
3962 1.9 christos SR_SVE ("zcr_el2", CPENC (3,4,C1,C2,0), 0),
3963 1.9 christos SR_SVE ("zcr_el3", CPENC (3,6,C1,C2,0), 0),
3964 1.9 christos SR_SVE ("zidr_el1", CPENC (3,0,C0,C0,7), 0),
3965 1.9 christos SR_CORE ("ttbr0_el1", CPENC (3,0,C2,C0,0), 0),
3966 1.9 christos SR_CORE ("ttbr1_el1", CPENC (3,0,C2,C0,1), 0),
3967 1.9 christos SR_V8_A ("ttbr0_el2", CPENC (3,4,C2,C0,0), 0),
3968 1.9 christos SR_V8_1_A ("ttbr1_el2", CPENC (3,4,C2,C0,1), 0),
3969 1.9 christos SR_CORE ("ttbr0_el3", CPENC (3,6,C2,C0,0), 0),
3970 1.9 christos SR_V8_1 ("ttbr0_el12", CPENC (3,5,C2,C0,0), 0),
3971 1.9 christos SR_V8_1 ("ttbr1_el12", CPENC (3,5,C2,C0,1), 0),
3972 1.9 christos SR_V8_A ("vttbr_el2", CPENC (3,4,C2,C1,0), 0),
3973 1.9 christos SR_CORE ("tcr_el1", CPENC (3,0,C2,C0,2), 0),
3974 1.9 christos SR_CORE ("tcr_el2", CPENC (3,4,C2,C0,2), 0),
3975 1.9 christos SR_CORE ("tcr_el3", CPENC (3,6,C2,C0,2), 0),
3976 1.9 christos SR_V8_1 ("tcr_el12", CPENC (3,5,C2,C0,2), 0),
3977 1.9 christos SR_CORE ("vtcr_el2", CPENC (3,4,C2,C1,2), 0),
3978 1.9 christos SR_V8_3 ("apiakeylo_el1", CPENC (3,0,C2,C1,0), 0),
3979 1.9 christos SR_V8_3 ("apiakeyhi_el1", CPENC (3,0,C2,C1,1), 0),
3980 1.9 christos SR_V8_3 ("apibkeylo_el1", CPENC (3,0,C2,C1,2), 0),
3981 1.9 christos SR_V8_3 ("apibkeyhi_el1", CPENC (3,0,C2,C1,3), 0),
3982 1.9 christos SR_V8_3 ("apdakeylo_el1", CPENC (3,0,C2,C2,0), 0),
3983 1.9 christos SR_V8_3 ("apdakeyhi_el1", CPENC (3,0,C2,C2,1), 0),
3984 1.9 christos SR_V8_3 ("apdbkeylo_el1", CPENC (3,0,C2,C2,2), 0),
3985 1.9 christos SR_V8_3 ("apdbkeyhi_el1", CPENC (3,0,C2,C2,3), 0),
3986 1.9 christos SR_V8_3 ("apgakeylo_el1", CPENC (3,0,C2,C3,0), 0),
3987 1.9 christos SR_V8_3 ("apgakeyhi_el1", CPENC (3,0,C2,C3,1), 0),
3988 1.9 christos SR_CORE ("afsr0_el1", CPENC (3,0,C5,C1,0), 0),
3989 1.9 christos SR_CORE ("afsr1_el1", CPENC (3,0,C5,C1,1), 0),
3990 1.9 christos SR_CORE ("afsr0_el2", CPENC (3,4,C5,C1,0), 0),
3991 1.9 christos SR_CORE ("afsr1_el2", CPENC (3,4,C5,C1,1), 0),
3992 1.9 christos SR_CORE ("afsr0_el3", CPENC (3,6,C5,C1,0), 0),
3993 1.9 christos SR_V8_1 ("afsr0_el12", CPENC (3,5,C5,C1,0), 0),
3994 1.9 christos SR_CORE ("afsr1_el3", CPENC (3,6,C5,C1,1), 0),
3995 1.9 christos SR_V8_1 ("afsr1_el12", CPENC (3,5,C5,C1,1), 0),
3996 1.9 christos SR_CORE ("esr_el1", CPENC (3,0,C5,C2,0), 0),
3997 1.9 christos SR_CORE ("esr_el2", CPENC (3,4,C5,C2,0), 0),
3998 1.9 christos SR_CORE ("esr_el3", CPENC (3,6,C5,C2,0), 0),
3999 1.9 christos SR_V8_1 ("esr_el12", CPENC (3,5,C5,C2,0), 0),
4000 1.9 christos SR_RAS ("vsesr_el2", CPENC (3,4,C5,C2,3), 0),
4001 1.9 christos SR_CORE ("fpexc32_el2", CPENC (3,4,C5,C3,0), 0),
4002 1.9 christos SR_RAS ("erridr_el1", CPENC (3,0,C5,C3,0), F_REG_READ),
4003 1.9 christos SR_RAS ("errselr_el1", CPENC (3,0,C5,C3,1), 0),
4004 1.9 christos SR_RAS ("erxfr_el1", CPENC (3,0,C5,C4,0), F_REG_READ),
4005 1.9 christos SR_RAS ("erxctlr_el1", CPENC (3,0,C5,C4,1), 0),
4006 1.9 christos SR_RAS ("erxstatus_el1", CPENC (3,0,C5,C4,2), 0),
4007 1.9 christos SR_RAS ("erxaddr_el1", CPENC (3,0,C5,C4,3), 0),
4008 1.9 christos SR_RAS ("erxmisc0_el1", CPENC (3,0,C5,C5,0), 0),
4009 1.9 christos SR_RAS ("erxmisc1_el1", CPENC (3,0,C5,C5,1), 0),
4010 1.9 christos SR_CORE ("far_el1", CPENC (3,0,C6,C0,0), 0),
4011 1.9 christos SR_CORE ("far_el2", CPENC (3,4,C6,C0,0), 0),
4012 1.9 christos SR_CORE ("far_el3", CPENC (3,6,C6,C0,0), 0),
4013 1.9 christos SR_V8_1 ("far_el12", CPENC (3,5,C6,C0,0), 0),
4014 1.9 christos SR_CORE ("hpfar_el2", CPENC (3,4,C6,C0,4), 0),
4015 1.9 christos SR_CORE ("par_el1", CPENC (3,0,C7,C4,0), 0),
4016 1.9 christos SR_CORE ("mair_el1", CPENC (3,0,C10,C2,0), 0),
4017 1.9 christos SR_CORE ("mair_el2", CPENC (3,4,C10,C2,0), 0),
4018 1.9 christos SR_CORE ("mair_el3", CPENC (3,6,C10,C2,0), 0),
4019 1.9 christos SR_V8_1 ("mair_el12", CPENC (3,5,C10,C2,0), 0),
4020 1.9 christos SR_CORE ("amair_el1", CPENC (3,0,C10,C3,0), 0),
4021 1.9 christos SR_CORE ("amair_el2", CPENC (3,4,C10,C3,0), 0),
4022 1.9 christos SR_CORE ("amair_el3", CPENC (3,6,C10,C3,0), 0),
4023 1.9 christos SR_V8_1 ("amair_el12", CPENC (3,5,C10,C3,0), 0),
4024 1.9 christos SR_CORE ("vbar_el1", CPENC (3,0,C12,C0,0), 0),
4025 1.9 christos SR_CORE ("vbar_el2", CPENC (3,4,C12,C0,0), 0),
4026 1.9 christos SR_CORE ("vbar_el3", CPENC (3,6,C12,C0,0), 0),
4027 1.9 christos SR_V8_1 ("vbar_el12", CPENC (3,5,C12,C0,0), 0),
4028 1.9 christos SR_CORE ("rvbar_el1", CPENC (3,0,C12,C0,1), F_REG_READ),
4029 1.9 christos SR_CORE ("rvbar_el2", CPENC (3,4,C12,C0,1), F_REG_READ),
4030 1.9 christos SR_CORE ("rvbar_el3", CPENC (3,6,C12,C0,1), F_REG_READ),
4031 1.9 christos SR_CORE ("rmr_el1", CPENC (3,0,C12,C0,2), 0),
4032 1.9 christos SR_CORE ("rmr_el2", CPENC (3,4,C12,C0,2), 0),
4033 1.9 christos SR_CORE ("rmr_el3", CPENC (3,6,C12,C0,2), 0),
4034 1.9 christos SR_CORE ("isr_el1", CPENC (3,0,C12,C1,0), F_REG_READ),
4035 1.9 christos SR_RAS ("disr_el1", CPENC (3,0,C12,C1,1), 0),
4036 1.9 christos SR_RAS ("vdisr_el2", CPENC (3,4,C12,C1,1), 0),
4037 1.9 christos SR_CORE ("contextidr_el1", CPENC (3,0,C13,C0,1), 0),
4038 1.9 christos SR_V8_1 ("contextidr_el2", CPENC (3,4,C13,C0,1), 0),
4039 1.9 christos SR_V8_1 ("contextidr_el12", CPENC (3,5,C13,C0,1), 0),
4040 1.9 christos SR_RNG ("rndr", CPENC (3,3,C2,C4,0), F_REG_READ),
4041 1.9 christos SR_RNG ("rndrrs", CPENC (3,3,C2,C4,1), F_REG_READ),
4042 1.9 christos SR_MEMTAG ("tco", CPENC (3,3,C4,C2,7), 0),
4043 1.9 christos SR_MEMTAG ("tfsre0_el1", CPENC (3,0,C5,C6,1), 0),
4044 1.9 christos SR_MEMTAG ("tfsr_el1", CPENC (3,0,C5,C6,0), 0),
4045 1.9 christos SR_MEMTAG ("tfsr_el2", CPENC (3,4,C5,C6,0), 0),
4046 1.9 christos SR_MEMTAG ("tfsr_el3", CPENC (3,6,C5,C6,0), 0),
4047 1.9 christos SR_MEMTAG ("tfsr_el12", CPENC (3,5,C5,C6,0), 0),
4048 1.9 christos SR_MEMTAG ("rgsr_el1", CPENC (3,0,C1,C0,5), 0),
4049 1.9 christos SR_MEMTAG ("gcr_el1", CPENC (3,0,C1,C0,6), 0),
4050 1.9 christos SR_MEMTAG ("gmid_el1", CPENC (3,1,C0,C0,4), F_REG_READ),
4051 1.9 christos SR_CORE ("tpidr_el0", CPENC (3,3,C13,C0,2), 0),
4052 1.9 christos SR_CORE ("tpidrro_el0", CPENC (3,3,C13,C0,3), 0),
4053 1.9 christos SR_CORE ("tpidr_el1", CPENC (3,0,C13,C0,4), 0),
4054 1.9 christos SR_CORE ("tpidr_el2", CPENC (3,4,C13,C0,2), 0),
4055 1.9 christos SR_CORE ("tpidr_el3", CPENC (3,6,C13,C0,2), 0),
4056 1.9 christos SR_SCXTNUM ("scxtnum_el0", CPENC (3,3,C13,C0,7), 0),
4057 1.9 christos SR_SCXTNUM ("scxtnum_el1", CPENC (3,0,C13,C0,7), 0),
4058 1.9 christos SR_SCXTNUM ("scxtnum_el2", CPENC (3,4,C13,C0,7), 0),
4059 1.9 christos SR_SCXTNUM ("scxtnum_el12", CPENC (3,5,C13,C0,7), 0),
4060 1.9 christos SR_SCXTNUM ("scxtnum_el3", CPENC (3,6,C13,C0,7), 0),
4061 1.9 christos SR_CORE ("teecr32_el1", CPENC (2,2,C0, C0,0), 0), /* See section 3.9.7.1. */
4062 1.9 christos SR_CORE ("cntfrq_el0", CPENC (3,3,C14,C0,0), 0),
4063 1.9 christos SR_CORE ("cntpct_el0", CPENC (3,3,C14,C0,1), F_REG_READ),
4064 1.9 christos SR_CORE ("cntvct_el0", CPENC (3,3,C14,C0,2), F_REG_READ),
4065 1.9 christos SR_CORE ("cntvoff_el2", CPENC (3,4,C14,C0,3), 0),
4066 1.9 christos SR_CORE ("cntkctl_el1", CPENC (3,0,C14,C1,0), 0),
4067 1.9 christos SR_V8_1 ("cntkctl_el12", CPENC (3,5,C14,C1,0), 0),
4068 1.9 christos SR_CORE ("cnthctl_el2", CPENC (3,4,C14,C1,0), 0),
4069 1.9 christos SR_CORE ("cntp_tval_el0", CPENC (3,3,C14,C2,0), 0),
4070 1.9 christos SR_V8_1 ("cntp_tval_el02", CPENC (3,5,C14,C2,0), 0),
4071 1.9 christos SR_CORE ("cntp_ctl_el0", CPENC (3,3,C14,C2,1), 0),
4072 1.9 christos SR_V8_1 ("cntp_ctl_el02", CPENC (3,5,C14,C2,1), 0),
4073 1.9 christos SR_CORE ("cntp_cval_el0", CPENC (3,3,C14,C2,2), 0),
4074 1.9 christos SR_V8_1 ("cntp_cval_el02", CPENC (3,5,C14,C2,2), 0),
4075 1.9 christos SR_CORE ("cntv_tval_el0", CPENC (3,3,C14,C3,0), 0),
4076 1.9 christos SR_V8_1 ("cntv_tval_el02", CPENC (3,5,C14,C3,0), 0),
4077 1.9 christos SR_CORE ("cntv_ctl_el0", CPENC (3,3,C14,C3,1), 0),
4078 1.9 christos SR_V8_1 ("cntv_ctl_el02", CPENC (3,5,C14,C3,1), 0),
4079 1.9 christos SR_CORE ("cntv_cval_el0", CPENC (3,3,C14,C3,2), 0),
4080 1.9 christos SR_V8_1 ("cntv_cval_el02", CPENC (3,5,C14,C3,2), 0),
4081 1.9 christos SR_CORE ("cnthp_tval_el2", CPENC (3,4,C14,C2,0), 0),
4082 1.9 christos SR_CORE ("cnthp_ctl_el2", CPENC (3,4,C14,C2,1), 0),
4083 1.9 christos SR_CORE ("cnthp_cval_el2", CPENC (3,4,C14,C2,2), 0),
4084 1.9 christos SR_CORE ("cntps_tval_el1", CPENC (3,7,C14,C2,0), 0),
4085 1.9 christos SR_CORE ("cntps_ctl_el1", CPENC (3,7,C14,C2,1), 0),
4086 1.9 christos SR_CORE ("cntps_cval_el1", CPENC (3,7,C14,C2,2), 0),
4087 1.9 christos SR_V8_1 ("cnthv_tval_el2", CPENC (3,4,C14,C3,0), 0),
4088 1.9 christos SR_V8_1 ("cnthv_ctl_el2", CPENC (3,4,C14,C3,1), 0),
4089 1.9 christos SR_V8_1 ("cnthv_cval_el2", CPENC (3,4,C14,C3,2), 0),
4090 1.9 christos SR_CORE ("dacr32_el2", CPENC (3,4,C3,C0,0), 0),
4091 1.9 christos SR_CORE ("ifsr32_el2", CPENC (3,4,C5,C0,1), 0),
4092 1.9 christos SR_CORE ("teehbr32_el1", CPENC (2,2,C1,C0,0), 0),
4093 1.9 christos SR_CORE ("sder32_el3", CPENC (3,6,C1,C1,1), 0),
4094 1.9 christos SR_CORE ("mdscr_el1", CPENC (2,0,C0,C2,2), 0),
4095 1.9 christos SR_CORE ("mdccsr_el0", CPENC (2,3,C0,C1,0), F_REG_READ),
4096 1.9 christos SR_CORE ("mdccint_el1", CPENC (2,0,C0,C2,0), 0),
4097 1.9 christos SR_CORE ("dbgdtr_el0", CPENC (2,3,C0,C4,0), 0),
4098 1.9 christos SR_CORE ("dbgdtrrx_el0", CPENC (2,3,C0,C5,0), F_REG_READ),
4099 1.9 christos SR_CORE ("dbgdtrtx_el0", CPENC (2,3,C0,C5,0), F_REG_WRITE),
4100 1.9 christos SR_CORE ("osdtrrx_el1", CPENC (2,0,C0,C0,2), 0),
4101 1.9 christos SR_CORE ("osdtrtx_el1", CPENC (2,0,C0,C3,2), 0),
4102 1.9 christos SR_CORE ("oseccr_el1", CPENC (2,0,C0,C6,2), 0),
4103 1.9 christos SR_CORE ("dbgvcr32_el2", CPENC (2,4,C0,C7,0), 0),
4104 1.9 christos SR_CORE ("dbgbvr0_el1", CPENC (2,0,C0,C0,4), 0),
4105 1.9 christos SR_CORE ("dbgbvr1_el1", CPENC (2,0,C0,C1,4), 0),
4106 1.9 christos SR_CORE ("dbgbvr2_el1", CPENC (2,0,C0,C2,4), 0),
4107 1.9 christos SR_CORE ("dbgbvr3_el1", CPENC (2,0,C0,C3,4), 0),
4108 1.9 christos SR_CORE ("dbgbvr4_el1", CPENC (2,0,C0,C4,4), 0),
4109 1.9 christos SR_CORE ("dbgbvr5_el1", CPENC (2,0,C0,C5,4), 0),
4110 1.9 christos SR_CORE ("dbgbvr6_el1", CPENC (2,0,C0,C6,4), 0),
4111 1.9 christos SR_CORE ("dbgbvr7_el1", CPENC (2,0,C0,C7,4), 0),
4112 1.9 christos SR_CORE ("dbgbvr8_el1", CPENC (2,0,C0,C8,4), 0),
4113 1.9 christos SR_CORE ("dbgbvr9_el1", CPENC (2,0,C0,C9,4), 0),
4114 1.9 christos SR_CORE ("dbgbvr10_el1", CPENC (2,0,C0,C10,4), 0),
4115 1.9 christos SR_CORE ("dbgbvr11_el1", CPENC (2,0,C0,C11,4), 0),
4116 1.9 christos SR_CORE ("dbgbvr12_el1", CPENC (2,0,C0,C12,4), 0),
4117 1.9 christos SR_CORE ("dbgbvr13_el1", CPENC (2,0,C0,C13,4), 0),
4118 1.9 christos SR_CORE ("dbgbvr14_el1", CPENC (2,0,C0,C14,4), 0),
4119 1.9 christos SR_CORE ("dbgbvr15_el1", CPENC (2,0,C0,C15,4), 0),
4120 1.9 christos SR_CORE ("dbgbcr0_el1", CPENC (2,0,C0,C0,5), 0),
4121 1.9 christos SR_CORE ("dbgbcr1_el1", CPENC (2,0,C0,C1,5), 0),
4122 1.9 christos SR_CORE ("dbgbcr2_el1", CPENC (2,0,C0,C2,5), 0),
4123 1.9 christos SR_CORE ("dbgbcr3_el1", CPENC (2,0,C0,C3,5), 0),
4124 1.9 christos SR_CORE ("dbgbcr4_el1", CPENC (2,0,C0,C4,5), 0),
4125 1.9 christos SR_CORE ("dbgbcr5_el1", CPENC (2,0,C0,C5,5), 0),
4126 1.9 christos SR_CORE ("dbgbcr6_el1", CPENC (2,0,C0,C6,5), 0),
4127 1.9 christos SR_CORE ("dbgbcr7_el1", CPENC (2,0,C0,C7,5), 0),
4128 1.9 christos SR_CORE ("dbgbcr8_el1", CPENC (2,0,C0,C8,5), 0),
4129 1.9 christos SR_CORE ("dbgbcr9_el1", CPENC (2,0,C0,C9,5), 0),
4130 1.9 christos SR_CORE ("dbgbcr10_el1", CPENC (2,0,C0,C10,5), 0),
4131 1.9 christos SR_CORE ("dbgbcr11_el1", CPENC (2,0,C0,C11,5), 0),
4132 1.9 christos SR_CORE ("dbgbcr12_el1", CPENC (2,0,C0,C12,5), 0),
4133 1.9 christos SR_CORE ("dbgbcr13_el1", CPENC (2,0,C0,C13,5), 0),
4134 1.9 christos SR_CORE ("dbgbcr14_el1", CPENC (2,0,C0,C14,5), 0),
4135 1.9 christos SR_CORE ("dbgbcr15_el1", CPENC (2,0,C0,C15,5), 0),
4136 1.9 christos SR_CORE ("dbgwvr0_el1", CPENC (2,0,C0,C0,6), 0),
4137 1.9 christos SR_CORE ("dbgwvr1_el1", CPENC (2,0,C0,C1,6), 0),
4138 1.9 christos SR_CORE ("dbgwvr2_el1", CPENC (2,0,C0,C2,6), 0),
4139 1.9 christos SR_CORE ("dbgwvr3_el1", CPENC (2,0,C0,C3,6), 0),
4140 1.9 christos SR_CORE ("dbgwvr4_el1", CPENC (2,0,C0,C4,6), 0),
4141 1.9 christos SR_CORE ("dbgwvr5_el1", CPENC (2,0,C0,C5,6), 0),
4142 1.9 christos SR_CORE ("dbgwvr6_el1", CPENC (2,0,C0,C6,6), 0),
4143 1.9 christos SR_CORE ("dbgwvr7_el1", CPENC (2,0,C0,C7,6), 0),
4144 1.9 christos SR_CORE ("dbgwvr8_el1", CPENC (2,0,C0,C8,6), 0),
4145 1.9 christos SR_CORE ("dbgwvr9_el1", CPENC (2,0,C0,C9,6), 0),
4146 1.9 christos SR_CORE ("dbgwvr10_el1", CPENC (2,0,C0,C10,6), 0),
4147 1.9 christos SR_CORE ("dbgwvr11_el1", CPENC (2,0,C0,C11,6), 0),
4148 1.9 christos SR_CORE ("dbgwvr12_el1", CPENC (2,0,C0,C12,6), 0),
4149 1.9 christos SR_CORE ("dbgwvr13_el1", CPENC (2,0,C0,C13,6), 0),
4150 1.9 christos SR_CORE ("dbgwvr14_el1", CPENC (2,0,C0,C14,6), 0),
4151 1.9 christos SR_CORE ("dbgwvr15_el1", CPENC (2,0,C0,C15,6), 0),
4152 1.9 christos SR_CORE ("dbgwcr0_el1", CPENC (2,0,C0,C0,7), 0),
4153 1.9 christos SR_CORE ("dbgwcr1_el1", CPENC (2,0,C0,C1,7), 0),
4154 1.9 christos SR_CORE ("dbgwcr2_el1", CPENC (2,0,C0,C2,7), 0),
4155 1.9 christos SR_CORE ("dbgwcr3_el1", CPENC (2,0,C0,C3,7), 0),
4156 1.9 christos SR_CORE ("dbgwcr4_el1", CPENC (2,0,C0,C4,7), 0),
4157 1.9 christos SR_CORE ("dbgwcr5_el1", CPENC (2,0,C0,C5,7), 0),
4158 1.9 christos SR_CORE ("dbgwcr6_el1", CPENC (2,0,C0,C6,7), 0),
4159 1.9 christos SR_CORE ("dbgwcr7_el1", CPENC (2,0,C0,C7,7), 0),
4160 1.9 christos SR_CORE ("dbgwcr8_el1", CPENC (2,0,C0,C8,7), 0),
4161 1.9 christos SR_CORE ("dbgwcr9_el1", CPENC (2,0,C0,C9,7), 0),
4162 1.9 christos SR_CORE ("dbgwcr10_el1", CPENC (2,0,C0,C10,7), 0),
4163 1.9 christos SR_CORE ("dbgwcr11_el1", CPENC (2,0,C0,C11,7), 0),
4164 1.9 christos SR_CORE ("dbgwcr12_el1", CPENC (2,0,C0,C12,7), 0),
4165 1.9 christos SR_CORE ("dbgwcr13_el1", CPENC (2,0,C0,C13,7), 0),
4166 1.9 christos SR_CORE ("dbgwcr14_el1", CPENC (2,0,C0,C14,7), 0),
4167 1.9 christos SR_CORE ("dbgwcr15_el1", CPENC (2,0,C0,C15,7), 0),
4168 1.9 christos SR_CORE ("mdrar_el1", CPENC (2,0,C1,C0,0), F_REG_READ),
4169 1.9 christos SR_CORE ("oslar_el1", CPENC (2,0,C1,C0,4), F_REG_WRITE),
4170 1.9 christos SR_CORE ("oslsr_el1", CPENC (2,0,C1,C1,4), F_REG_READ),
4171 1.9 christos SR_CORE ("osdlr_el1", CPENC (2,0,C1,C3,4), 0),
4172 1.9 christos SR_CORE ("dbgprcr_el1", CPENC (2,0,C1,C4,4), 0),
4173 1.9 christos SR_CORE ("dbgclaimset_el1", CPENC (2,0,C7,C8,6), 0),
4174 1.9 christos SR_CORE ("dbgclaimclr_el1", CPENC (2,0,C7,C9,6), 0),
4175 1.9 christos SR_CORE ("dbgauthstatus_el1", CPENC (2,0,C7,C14,6), F_REG_READ),
4176 1.9 christos SR_PROFILE ("pmblimitr_el1", CPENC (3,0,C9,C10,0), 0),
4177 1.9 christos SR_PROFILE ("pmbptr_el1", CPENC (3,0,C9,C10,1), 0),
4178 1.9 christos SR_PROFILE ("pmbsr_el1", CPENC (3,0,C9,C10,3), 0),
4179 1.9 christos SR_PROFILE ("pmbidr_el1", CPENC (3,0,C9,C10,7), F_REG_READ),
4180 1.9 christos SR_PROFILE ("pmscr_el1", CPENC (3,0,C9,C9,0), 0),
4181 1.9 christos SR_PROFILE ("pmsicr_el1", CPENC (3,0,C9,C9,2), 0),
4182 1.9 christos SR_PROFILE ("pmsirr_el1", CPENC (3,0,C9,C9,3), 0),
4183 1.9 christos SR_PROFILE ("pmsfcr_el1", CPENC (3,0,C9,C9,4), 0),
4184 1.9 christos SR_PROFILE ("pmsevfr_el1", CPENC (3,0,C9,C9,5), 0),
4185 1.9 christos SR_PROFILE ("pmslatfr_el1", CPENC (3,0,C9,C9,6), 0),
4186 1.9 christos SR_PROFILE ("pmsidr_el1", CPENC (3,0,C9,C9,7), 0),
4187 1.9 christos SR_PROFILE ("pmscr_el2", CPENC (3,4,C9,C9,0), 0),
4188 1.9 christos SR_PROFILE ("pmscr_el12", CPENC (3,5,C9,C9,0), 0),
4189 1.9 christos SR_CORE ("pmcr_el0", CPENC (3,3,C9,C12,0), 0),
4190 1.9 christos SR_CORE ("pmcntenset_el0", CPENC (3,3,C9,C12,1), 0),
4191 1.9 christos SR_CORE ("pmcntenclr_el0", CPENC (3,3,C9,C12,2), 0),
4192 1.9 christos SR_CORE ("pmovsclr_el0", CPENC (3,3,C9,C12,3), 0),
4193 1.9 christos SR_CORE ("pmswinc_el0", CPENC (3,3,C9,C12,4), F_REG_WRITE),
4194 1.9 christos SR_CORE ("pmselr_el0", CPENC (3,3,C9,C12,5), 0),
4195 1.9 christos SR_CORE ("pmceid0_el0", CPENC (3,3,C9,C12,6), F_REG_READ),
4196 1.9 christos SR_CORE ("pmceid1_el0", CPENC (3,3,C9,C12,7), F_REG_READ),
4197 1.9 christos SR_CORE ("pmccntr_el0", CPENC (3,3,C9,C13,0), 0),
4198 1.9 christos SR_CORE ("pmxevtyper_el0", CPENC (3,3,C9,C13,1), 0),
4199 1.9 christos SR_CORE ("pmxevcntr_el0", CPENC (3,3,C9,C13,2), 0),
4200 1.9 christos SR_CORE ("pmuserenr_el0", CPENC (3,3,C9,C14,0), 0),
4201 1.9 christos SR_CORE ("pmintenset_el1", CPENC (3,0,C9,C14,1), 0),
4202 1.9 christos SR_CORE ("pmintenclr_el1", CPENC (3,0,C9,C14,2), 0),
4203 1.9 christos SR_CORE ("pmovsset_el0", CPENC (3,3,C9,C14,3), 0),
4204 1.9 christos SR_CORE ("pmevcntr0_el0", CPENC (3,3,C14,C8,0), 0),
4205 1.9 christos SR_CORE ("pmevcntr1_el0", CPENC (3,3,C14,C8,1), 0),
4206 1.9 christos SR_CORE ("pmevcntr2_el0", CPENC (3,3,C14,C8,2), 0),
4207 1.9 christos SR_CORE ("pmevcntr3_el0", CPENC (3,3,C14,C8,3), 0),
4208 1.9 christos SR_CORE ("pmevcntr4_el0", CPENC (3,3,C14,C8,4), 0),
4209 1.9 christos SR_CORE ("pmevcntr5_el0", CPENC (3,3,C14,C8,5), 0),
4210 1.9 christos SR_CORE ("pmevcntr6_el0", CPENC (3,3,C14,C8,6), 0),
4211 1.9 christos SR_CORE ("pmevcntr7_el0", CPENC (3,3,C14,C8,7), 0),
4212 1.9 christos SR_CORE ("pmevcntr8_el0", CPENC (3,3,C14,C9,0), 0),
4213 1.9 christos SR_CORE ("pmevcntr9_el0", CPENC (3,3,C14,C9,1), 0),
4214 1.9 christos SR_CORE ("pmevcntr10_el0", CPENC (3,3,C14,C9,2), 0),
4215 1.9 christos SR_CORE ("pmevcntr11_el0", CPENC (3,3,C14,C9,3), 0),
4216 1.9 christos SR_CORE ("pmevcntr12_el0", CPENC (3,3,C14,C9,4), 0),
4217 1.9 christos SR_CORE ("pmevcntr13_el0", CPENC (3,3,C14,C9,5), 0),
4218 1.9 christos SR_CORE ("pmevcntr14_el0", CPENC (3,3,C14,C9,6), 0),
4219 1.9 christos SR_CORE ("pmevcntr15_el0", CPENC (3,3,C14,C9,7), 0),
4220 1.9 christos SR_CORE ("pmevcntr16_el0", CPENC (3,3,C14,C10,0), 0),
4221 1.9 christos SR_CORE ("pmevcntr17_el0", CPENC (3,3,C14,C10,1), 0),
4222 1.9 christos SR_CORE ("pmevcntr18_el0", CPENC (3,3,C14,C10,2), 0),
4223 1.9 christos SR_CORE ("pmevcntr19_el0", CPENC (3,3,C14,C10,3), 0),
4224 1.9 christos SR_CORE ("pmevcntr20_el0", CPENC (3,3,C14,C10,4), 0),
4225 1.9 christos SR_CORE ("pmevcntr21_el0", CPENC (3,3,C14,C10,5), 0),
4226 1.9 christos SR_CORE ("pmevcntr22_el0", CPENC (3,3,C14,C10,6), 0),
4227 1.9 christos SR_CORE ("pmevcntr23_el0", CPENC (3,3,C14,C10,7), 0),
4228 1.9 christos SR_CORE ("pmevcntr24_el0", CPENC (3,3,C14,C11,0), 0),
4229 1.9 christos SR_CORE ("pmevcntr25_el0", CPENC (3,3,C14,C11,1), 0),
4230 1.9 christos SR_CORE ("pmevcntr26_el0", CPENC (3,3,C14,C11,2), 0),
4231 1.9 christos SR_CORE ("pmevcntr27_el0", CPENC (3,3,C14,C11,3), 0),
4232 1.9 christos SR_CORE ("pmevcntr28_el0", CPENC (3,3,C14,C11,4), 0),
4233 1.9 christos SR_CORE ("pmevcntr29_el0", CPENC (3,3,C14,C11,5), 0),
4234 1.9 christos SR_CORE ("pmevcntr30_el0", CPENC (3,3,C14,C11,6), 0),
4235 1.9 christos SR_CORE ("pmevtyper0_el0", CPENC (3,3,C14,C12,0), 0),
4236 1.9 christos SR_CORE ("pmevtyper1_el0", CPENC (3,3,C14,C12,1), 0),
4237 1.9 christos SR_CORE ("pmevtyper2_el0", CPENC (3,3,C14,C12,2), 0),
4238 1.9 christos SR_CORE ("pmevtyper3_el0", CPENC (3,3,C14,C12,3), 0),
4239 1.9 christos SR_CORE ("pmevtyper4_el0", CPENC (3,3,C14,C12,4), 0),
4240 1.9 christos SR_CORE ("pmevtyper5_el0", CPENC (3,3,C14,C12,5), 0),
4241 1.9 christos SR_CORE ("pmevtyper6_el0", CPENC (3,3,C14,C12,6), 0),
4242 1.9 christos SR_CORE ("pmevtyper7_el0", CPENC (3,3,C14,C12,7), 0),
4243 1.9 christos SR_CORE ("pmevtyper8_el0", CPENC (3,3,C14,C13,0), 0),
4244 1.9 christos SR_CORE ("pmevtyper9_el0", CPENC (3,3,C14,C13,1), 0),
4245 1.9 christos SR_CORE ("pmevtyper10_el0", CPENC (3,3,C14,C13,2), 0),
4246 1.9 christos SR_CORE ("pmevtyper11_el0", CPENC (3,3,C14,C13,3), 0),
4247 1.9 christos SR_CORE ("pmevtyper12_el0", CPENC (3,3,C14,C13,4), 0),
4248 1.9 christos SR_CORE ("pmevtyper13_el0", CPENC (3,3,C14,C13,5), 0),
4249 1.9 christos SR_CORE ("pmevtyper14_el0", CPENC (3,3,C14,C13,6), 0),
4250 1.9 christos SR_CORE ("pmevtyper15_el0", CPENC (3,3,C14,C13,7), 0),
4251 1.9 christos SR_CORE ("pmevtyper16_el0", CPENC (3,3,C14,C14,0), 0),
4252 1.9 christos SR_CORE ("pmevtyper17_el0", CPENC (3,3,C14,C14,1), 0),
4253 1.9 christos SR_CORE ("pmevtyper18_el0", CPENC (3,3,C14,C14,2), 0),
4254 1.9 christos SR_CORE ("pmevtyper19_el0", CPENC (3,3,C14,C14,3), 0),
4255 1.9 christos SR_CORE ("pmevtyper20_el0", CPENC (3,3,C14,C14,4), 0),
4256 1.9 christos SR_CORE ("pmevtyper21_el0", CPENC (3,3,C14,C14,5), 0),
4257 1.9 christos SR_CORE ("pmevtyper22_el0", CPENC (3,3,C14,C14,6), 0),
4258 1.9 christos SR_CORE ("pmevtyper23_el0", CPENC (3,3,C14,C14,7), 0),
4259 1.9 christos SR_CORE ("pmevtyper24_el0", CPENC (3,3,C14,C15,0), 0),
4260 1.9 christos SR_CORE ("pmevtyper25_el0", CPENC (3,3,C14,C15,1), 0),
4261 1.9 christos SR_CORE ("pmevtyper26_el0", CPENC (3,3,C14,C15,2), 0),
4262 1.9 christos SR_CORE ("pmevtyper27_el0", CPENC (3,3,C14,C15,3), 0),
4263 1.9 christos SR_CORE ("pmevtyper28_el0", CPENC (3,3,C14,C15,4), 0),
4264 1.9 christos SR_CORE ("pmevtyper29_el0", CPENC (3,3,C14,C15,5), 0),
4265 1.9 christos SR_CORE ("pmevtyper30_el0", CPENC (3,3,C14,C15,6), 0),
4266 1.9 christos SR_CORE ("pmccfiltr_el0", CPENC (3,3,C14,C15,7), 0),
4267 1.9 christos
4268 1.9 christos SR_V8_4 ("dit", CPEN_ (3,C2,5), 0),
4269 1.9 christos SR_V8_4 ("vstcr_el2", CPENC (3,4,C2,C6,2), 0),
4270 1.9 christos SR_V8_4_A ("vsttbr_el2", CPENC (3,4,C2,C6,0), 0),
4271 1.9 christos SR_V8_4 ("cnthvs_tval_el2", CPENC (3,4,C14,C4,0), 0),
4272 1.9 christos SR_V8_4 ("cnthvs_cval_el2", CPENC (3,4,C14,C4,2), 0),
4273 1.9 christos SR_V8_4 ("cnthvs_ctl_el2", CPENC (3,4,C14,C4,1), 0),
4274 1.9 christos SR_V8_4 ("cnthps_tval_el2", CPENC (3,4,C14,C5,0), 0),
4275 1.9 christos SR_V8_4 ("cnthps_cval_el2", CPENC (3,4,C14,C5,2), 0),
4276 1.9 christos SR_V8_4 ("cnthps_ctl_el2", CPENC (3,4,C14,C5,1), 0),
4277 1.9 christos SR_V8_4 ("sder32_el2", CPENC (3,4,C1,C3,1), 0),
4278 1.9 christos SR_V8_4 ("vncr_el2", CPENC (3,4,C2,C2,0), 0),
4279 1.9 christos
4280 1.9 christos SR_CORE ("mpam0_el1", CPENC (3,0,C10,C5,1), 0),
4281 1.9 christos SR_CORE ("mpam1_el1", CPENC (3,0,C10,C5,0), 0),
4282 1.9 christos SR_CORE ("mpam1_el12", CPENC (3,5,C10,C5,0), 0),
4283 1.9 christos SR_CORE ("mpam2_el2", CPENC (3,4,C10,C5,0), 0),
4284 1.9 christos SR_CORE ("mpam3_el3", CPENC (3,6,C10,C5,0), 0),
4285 1.9 christos SR_CORE ("mpamhcr_el2", CPENC (3,4,C10,C4,0), 0),
4286 1.9 christos SR_CORE ("mpamidr_el1", CPENC (3,0,C10,C4,4), F_REG_READ),
4287 1.9 christos SR_CORE ("mpamvpm0_el2", CPENC (3,4,C10,C6,0), 0),
4288 1.9 christos SR_CORE ("mpamvpm1_el2", CPENC (3,4,C10,C6,1), 0),
4289 1.9 christos SR_CORE ("mpamvpm2_el2", CPENC (3,4,C10,C6,2), 0),
4290 1.9 christos SR_CORE ("mpamvpm3_el2", CPENC (3,4,C10,C6,3), 0),
4291 1.9 christos SR_CORE ("mpamvpm4_el2", CPENC (3,4,C10,C6,4), 0),
4292 1.9 christos SR_CORE ("mpamvpm5_el2", CPENC (3,4,C10,C6,5), 0),
4293 1.9 christos SR_CORE ("mpamvpm6_el2", CPENC (3,4,C10,C6,6), 0),
4294 1.9 christos SR_CORE ("mpamvpm7_el2", CPENC (3,4,C10,C6,7), 0),
4295 1.9 christos SR_CORE ("mpamvpmv_el2", CPENC (3,4,C10,C4,1), 0),
4296 1.9 christos
4297 1.9 christos SR_V8_R ("mpuir_el1", CPENC (3,0,C0,C0,4), F_REG_READ),
4298 1.9 christos SR_V8_R ("mpuir_el2", CPENC (3,4,C0,C0,4), F_REG_READ),
4299 1.9 christos SR_V8_R ("prbar_el1", CPENC (3,0,C6,C8,0), 0),
4300 1.9 christos SR_V8_R ("prbar_el2", CPENC (3,4,C6,C8,0), 0),
4301 1.9 christos
4302 1.9 christos #define ENC_BARLAR(x,n,lar) \
4303 1.9 christos CPENC (3, (x-1) << 2, C6, 8 | (n >> 1), ((n & 1) << 2) | lar)
4304 1.9 christos
4305 1.9 christos #define PRBARn_ELx(x,n) SR_V8_R ("prbar" #n "_el" #x, ENC_BARLAR (x,n,0), 0)
4306 1.9 christos #define PRLARn_ELx(x,n) SR_V8_R ("prlar" #n "_el" #x, ENC_BARLAR (x,n,1), 0)
4307 1.9 christos
4308 1.9 christos SR_EXPAND_EL12 (PRBARn_ELx)
4309 1.9 christos SR_V8_R ("prenr_el1", CPENC (3,0,C6,C1,1), 0),
4310 1.9 christos SR_V8_R ("prenr_el2", CPENC (3,4,C6,C1,1), 0),
4311 1.9 christos SR_V8_R ("prlar_el1", CPENC (3,0,C6,C8,1), 0),
4312 1.9 christos SR_V8_R ("prlar_el2", CPENC (3,4,C6,C8,1), 0),
4313 1.9 christos SR_EXPAND_EL12 (PRLARn_ELx)
4314 1.9 christos SR_V8_R ("prselr_el1", CPENC (3,0,C6,C2,1), 0),
4315 1.1 christos SR_V8_R ("prselr_el2", CPENC (3,4,C6,C2,1), 0),
4316 1.1 christos SR_V8_R ("vsctlr_el2", CPENC (3,4,C2,C0,0), 0),
4317 1.1 christos
4318 1.9 christos { 0, CPENC (0,0,0,0,0), 0, 0 }
4319 1.1 christos };
4320 1.9 christos
4321 1.5 christos bfd_boolean
4322 1.5 christos aarch64_sys_reg_deprecated_p (const uint32_t reg_flags)
4323 1.8 christos {
4324 1.8 christos return (reg_flags & F_DEPRECATED) != 0;
4325 1.8 christos }
4326 1.8 christos
4327 1.8 christos /* The CPENC below is fairly misleading, the fields
4328 1.8 christos here are not in CPENC form. They are in op2op1 form. The fields are encoded
4329 1.8 christos by ins_pstatefield, which just shifts the value by the width of the fields
4330 1.1 christos in a loop. So if you CPENC them only the first value will be set, the rest
4331 1.1 christos are masked out to 0. As an example. op2 = 3, op1=2. CPENC would produce a
4332 1.9 christos value of 0b110000000001000000 (0x30040) while what you want is
4333 1.9 christos 0b011010 (0x1a). */
4334 1.9 christos const aarch64_sys_reg aarch64_pstatefields [] =
4335 1.9 christos {
4336 1.9 christos SR_CORE ("spsel", 0x05, 0),
4337 1.9 christos SR_CORE ("daifset", 0x1e, 0),
4338 1.9 christos SR_CORE ("daifclr", 0x1f, 0),
4339 1.9 christos SR_PAN ("pan", 0x04, 0),
4340 1.9 christos SR_V8_2 ("uao", 0x03, 0),
4341 1.1 christos SR_SSBS ("ssbs", 0x19, 0),
4342 1.1 christos SR_V8_4 ("dit", 0x1a, 0),
4343 1.5 christos SR_MEMTAG ("tco", 0x1c, 0),
4344 1.5 christos { 0, CPENC (0,0,0,0,0), 0, 0 },
4345 1.5 christos };
4346 1.5 christos
4347 1.5 christos bfd_boolean
4348 1.5 christos aarch64_pstatefield_supported_p (const aarch64_feature_set features,
4349 1.5 christos const aarch64_sys_reg *reg)
4350 1.9 christos {
4351 1.5 christos if (!(reg->flags & F_ARCHEXT))
4352 1.5 christos return TRUE;
4353 1.1 christos
4354 1.1 christos return AARCH64_CPU_HAS_ALL_FEATURES (features, reg->features);
4355 1.1 christos }
4356 1.1 christos
4357 1.6 christos const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
4358 1.1 christos {
4359 1.1 christos { "ialluis", CPENS(0,C7,C1,0), 0 },
4360 1.1 christos { "iallu", CPENS(0,C7,C5,0), 0 },
4361 1.1 christos { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
4362 1.1 christos { 0, CPENS(0,0,0,0), 0 }
4363 1.6 christos };
4364 1.8 christos
4365 1.8 christos const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
4366 1.6 christos {
4367 1.8 christos { "zva", CPENS (3, C7, C4, 1), F_HASXT },
4368 1.8 christos { "gva", CPENS (3, C7, C4, 3), F_HASXT | F_ARCHEXT },
4369 1.6 christos { "gzva", CPENS (3, C7, C4, 4), F_HASXT | F_ARCHEXT },
4370 1.8 christos { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
4371 1.8 christos { "igvac", CPENS (0, C7, C6, 3), F_HASXT | F_ARCHEXT },
4372 1.6 christos { "igsw", CPENS (0, C7, C6, 4), F_HASXT | F_ARCHEXT },
4373 1.8 christos { "isw", CPENS (0, C7, C6, 2), F_HASXT },
4374 1.8 christos { "igdvac", CPENS (0, C7, C6, 5), F_HASXT | F_ARCHEXT },
4375 1.6 christos { "igdsw", CPENS (0, C7, C6, 6), F_HASXT | F_ARCHEXT },
4376 1.8 christos { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
4377 1.8 christos { "cgvac", CPENS (3, C7, C10, 3), F_HASXT | F_ARCHEXT },
4378 1.6 christos { "cgdvac", CPENS (3, C7, C10, 5), F_HASXT | F_ARCHEXT },
4379 1.6 christos { "csw", CPENS (0, C7, C10, 2), F_HASXT },
4380 1.8 christos { "cgsw", CPENS (0, C7, C10, 4), F_HASXT | F_ARCHEXT },
4381 1.8 christos { "cgdsw", CPENS (0, C7, C10, 6), F_HASXT | F_ARCHEXT },
4382 1.8 christos { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
4383 1.8 christos { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
4384 1.8 christos { "cgvap", CPENS (3, C7, C12, 3), F_HASXT | F_ARCHEXT },
4385 1.6 christos { "cgdvap", CPENS (3, C7, C12, 5), F_HASXT | F_ARCHEXT },
4386 1.8 christos { "cvadp", CPENS (3, C7, C13, 1), F_HASXT | F_ARCHEXT },
4387 1.8 christos { "cgvadp", CPENS (3, C7, C13, 3), F_HASXT | F_ARCHEXT },
4388 1.6 christos { "cgdvadp", CPENS (3, C7, C13, 5), F_HASXT | F_ARCHEXT },
4389 1.8 christos { "civac", CPENS (3, C7, C14, 1), F_HASXT },
4390 1.8 christos { "cigvac", CPENS (3, C7, C14, 3), F_HASXT | F_ARCHEXT },
4391 1.1 christos { "cigdvac", CPENS (3, C7, C14, 5), F_HASXT | F_ARCHEXT },
4392 1.1 christos { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
4393 1.1 christos { "cigsw", CPENS (0, C7, C14, 4), F_HASXT | F_ARCHEXT },
4394 1.1 christos { "cigdsw", CPENS (0, C7, C14, 6), F_HASXT | F_ARCHEXT },
4395 1.1 christos { 0, CPENS(0,0,0,0), 0 }
4396 1.6 christos };
4397 1.6 christos
4398 1.6 christos const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
4399 1.6 christos {
4400 1.6 christos { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
4401 1.6 christos { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
4402 1.6 christos { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
4403 1.6 christos { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
4404 1.6 christos { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
4405 1.6 christos { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
4406 1.6 christos { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
4407 1.6 christos { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
4408 1.6 christos { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
4409 1.6 christos { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
4410 1.1 christos { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
4411 1.1 christos { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
4412 1.1 christos { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
4413 1.1 christos { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
4414 1.1 christos { 0, CPENS(0,0,0,0), 0 }
4415 1.1 christos };
4416 1.6 christos
4417 1.6 christos const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
4418 1.6 christos {
4419 1.1 christos { "vmalle1", CPENS(0,C8,C7,0), 0 },
4420 1.6 christos { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
4421 1.6 christos { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
4422 1.6 christos { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
4423 1.6 christos { "vmalle1is", CPENS(0,C8,C3,0), 0 },
4424 1.6 christos { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
4425 1.6 christos { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
4426 1.6 christos { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
4427 1.6 christos { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
4428 1.6 christos { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
4429 1.1 christos { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
4430 1.1 christos { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
4431 1.6 christos { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
4432 1.6 christos { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
4433 1.1 christos { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
4434 1.1 christos { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
4435 1.1 christos { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
4436 1.1 christos { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
4437 1.1 christos { "alle2", CPENS(4,C8,C7,0), 0 },
4438 1.1 christos { "alle2is", CPENS(4,C8,C3,0), 0 },
4439 1.6 christos { "alle1", CPENS(4,C8,C7,4), 0 },
4440 1.6 christos { "alle1is", CPENS(4,C8,C3,4), 0 },
4441 1.6 christos { "alle3", CPENS(6,C8,C7,0), 0 },
4442 1.6 christos { "alle3is", CPENS(6,C8,C3,0), 0 },
4443 1.6 christos { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
4444 1.6 christos { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
4445 1.6 christos { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
4446 1.6 christos { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
4447 1.8 christos { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
4448 1.8 christos { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
4449 1.8 christos { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
4450 1.8 christos { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
4451 1.8 christos
4452 1.8 christos { "vmalle1os", CPENS (0, C8, C1, 0), F_ARCHEXT },
4453 1.8 christos { "vae1os", CPENS (0, C8, C1, 1), F_HASXT | F_ARCHEXT },
4454 1.8 christos { "aside1os", CPENS (0, C8, C1, 2), F_HASXT | F_ARCHEXT },
4455 1.8 christos { "vaae1os", CPENS (0, C8, C1, 3), F_HASXT | F_ARCHEXT },
4456 1.8 christos { "vale1os", CPENS (0, C8, C1, 5), F_HASXT | F_ARCHEXT },
4457 1.8 christos { "vaale1os", CPENS (0, C8, C1, 7), F_HASXT | F_ARCHEXT },
4458 1.8 christos { "ipas2e1os", CPENS (4, C8, C4, 0), F_HASXT | F_ARCHEXT },
4459 1.8 christos { "ipas2le1os", CPENS (4, C8, C4, 4), F_HASXT | F_ARCHEXT },
4460 1.8 christos { "vae2os", CPENS (4, C8, C1, 1), F_HASXT | F_ARCHEXT },
4461 1.8 christos { "vale2os", CPENS (4, C8, C1, 5), F_HASXT | F_ARCHEXT },
4462 1.8 christos { "vmalls12e1os", CPENS (4, C8, C1, 6), F_ARCHEXT },
4463 1.8 christos { "vae3os", CPENS (6, C8, C1, 1), F_HASXT | F_ARCHEXT },
4464 1.8 christos { "vale3os", CPENS (6, C8, C1, 5), F_HASXT | F_ARCHEXT },
4465 1.8 christos { "alle2os", CPENS (4, C8, C1, 0), F_ARCHEXT },
4466 1.8 christos { "alle1os", CPENS (4, C8, C1, 4), F_ARCHEXT },
4467 1.8 christos { "alle3os", CPENS (6, C8, C1, 0), F_ARCHEXT },
4468 1.8 christos
4469 1.8 christos { "rvae1", CPENS (0, C8, C6, 1), F_HASXT | F_ARCHEXT },
4470 1.8 christos { "rvaae1", CPENS (0, C8, C6, 3), F_HASXT | F_ARCHEXT },
4471 1.8 christos { "rvale1", CPENS (0, C8, C6, 5), F_HASXT | F_ARCHEXT },
4472 1.8 christos { "rvaale1", CPENS (0, C8, C6, 7), F_HASXT | F_ARCHEXT },
4473 1.8 christos { "rvae1is", CPENS (0, C8, C2, 1), F_HASXT | F_ARCHEXT },
4474 1.8 christos { "rvaae1is", CPENS (0, C8, C2, 3), F_HASXT | F_ARCHEXT },
4475 1.8 christos { "rvale1is", CPENS (0, C8, C2, 5), F_HASXT | F_ARCHEXT },
4476 1.8 christos { "rvaale1is", CPENS (0, C8, C2, 7), F_HASXT | F_ARCHEXT },
4477 1.8 christos { "rvae1os", CPENS (0, C8, C5, 1), F_HASXT | F_ARCHEXT },
4478 1.8 christos { "rvaae1os", CPENS (0, C8, C5, 3), F_HASXT | F_ARCHEXT },
4479 1.8 christos { "rvale1os", CPENS (0, C8, C5, 5), F_HASXT | F_ARCHEXT },
4480 1.8 christos { "rvaale1os", CPENS (0, C8, C5, 7), F_HASXT | F_ARCHEXT },
4481 1.8 christos { "ripas2e1is", CPENS (4, C8, C0, 2), F_HASXT | F_ARCHEXT },
4482 1.8 christos { "ripas2le1is",CPENS (4, C8, C0, 6), F_HASXT | F_ARCHEXT },
4483 1.8 christos { "ripas2e1", CPENS (4, C8, C4, 2), F_HASXT | F_ARCHEXT },
4484 1.8 christos { "ripas2le1", CPENS (4, C8, C4, 6), F_HASXT | F_ARCHEXT },
4485 1.8 christos { "ripas2e1os", CPENS (4, C8, C4, 3), F_HASXT | F_ARCHEXT },
4486 1.8 christos { "ripas2le1os",CPENS (4, C8, C4, 7), F_HASXT | F_ARCHEXT },
4487 1.8 christos { "rvae2", CPENS (4, C8, C6, 1), F_HASXT | F_ARCHEXT },
4488 1.8 christos { "rvale2", CPENS (4, C8, C6, 5), F_HASXT | F_ARCHEXT },
4489 1.8 christos { "rvae2is", CPENS (4, C8, C2, 1), F_HASXT | F_ARCHEXT },
4490 1.8 christos { "rvale2is", CPENS (4, C8, C2, 5), F_HASXT | F_ARCHEXT },
4491 1.8 christos { "rvae2os", CPENS (4, C8, C5, 1), F_HASXT | F_ARCHEXT },
4492 1.8 christos { "rvale2os", CPENS (4, C8, C5, 5), F_HASXT | F_ARCHEXT },
4493 1.8 christos { "rvae3", CPENS (6, C8, C6, 1), F_HASXT | F_ARCHEXT },
4494 1.8 christos { "rvale3", CPENS (6, C8, C6, 5), F_HASXT | F_ARCHEXT },
4495 1.8 christos { "rvae3is", CPENS (6, C8, C2, 1), F_HASXT | F_ARCHEXT },
4496 1.8 christos { "rvale3is", CPENS (6, C8, C2, 5), F_HASXT | F_ARCHEXT },
4497 1.8 christos { "rvae3os", CPENS (6, C8, C5, 1), F_HASXT | F_ARCHEXT },
4498 1.8 christos { "rvale3os", CPENS (6, C8, C5, 5), F_HASXT | F_ARCHEXT },
4499 1.8 christos
4500 1.8 christos { 0, CPENS(0,0,0,0), 0 }
4501 1.8 christos };
4502 1.8 christos
4503 1.8 christos const aarch64_sys_ins_reg aarch64_sys_regs_sr[] =
4504 1.8 christos {
4505 1.8 christos /* RCTX is somewhat unique in a way that it has different values
4506 1.8 christos (op2) based on the instruction in which it is used (cfp/dvp/cpp).
4507 1.1 christos Thus op2 is masked out and instead encoded directly in the
4508 1.1 christos aarch64_opcode_table entries for the respective instructions. */
4509 1.1 christos { "rctx", CPENS(3,C7,C3,0), F_HASXT | F_ARCHEXT | F_REG_WRITE}, /* WO */
4510 1.6 christos
4511 1.6 christos { 0, CPENS(0,0,0,0), 0 }
4512 1.6 christos };
4513 1.6 christos
4514 1.6 christos bfd_boolean
4515 1.6 christos aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
4516 1.6 christos {
4517 1.6 christos return (sys_ins_reg->flags & F_HASXT) != 0;
4518 1.9 christos }
4519 1.9 christos
4520 1.9 christos extern bfd_boolean
4521 1.9 christos aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
4522 1.6 christos const char *reg_name,
4523 1.9 christos aarch64_insn reg_value,
4524 1.9 christos uint32_t reg_flags,
4525 1.9 christos aarch64_feature_set reg_features)
4526 1.9 christos {
4527 1.9 christos /* Armv8-R has no EL3. */
4528 1.9 christos if (AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_R))
4529 1.9 christos {
4530 1.9 christos const char *suffix = strrchr (reg_name, '_');
4531 1.9 christos if (suffix && !strcmp (suffix, "_el3"))
4532 1.9 christos return FALSE;
4533 1.9 christos }
4534 1.9 christos
4535 1.9 christos if (!(reg_flags & F_ARCHEXT))
4536 1.9 christos return TRUE;
4537 1.9 christos
4538 1.9 christos if (reg_features
4539 1.9 christos && AARCH64_CPU_HAS_ALL_FEATURES (features, reg_features))
4540 1.9 christos return TRUE;
4541 1.9 christos
4542 1.9 christos /* ARMv8.4 TLB instructions. */
4543 1.9 christos if ((reg_value == CPENS (0, C8, C1, 0)
4544 1.9 christos || reg_value == CPENS (0, C8, C1, 1)
4545 1.9 christos || reg_value == CPENS (0, C8, C1, 2)
4546 1.9 christos || reg_value == CPENS (0, C8, C1, 3)
4547 1.9 christos || reg_value == CPENS (0, C8, C1, 5)
4548 1.9 christos || reg_value == CPENS (0, C8, C1, 7)
4549 1.9 christos || reg_value == CPENS (4, C8, C4, 0)
4550 1.9 christos || reg_value == CPENS (4, C8, C4, 4)
4551 1.9 christos || reg_value == CPENS (4, C8, C1, 1)
4552 1.9 christos || reg_value == CPENS (4, C8, C1, 5)
4553 1.9 christos || reg_value == CPENS (4, C8, C1, 6)
4554 1.9 christos || reg_value == CPENS (6, C8, C1, 1)
4555 1.9 christos || reg_value == CPENS (6, C8, C1, 5)
4556 1.9 christos || reg_value == CPENS (4, C8, C1, 0)
4557 1.9 christos || reg_value == CPENS (4, C8, C1, 4)
4558 1.9 christos || reg_value == CPENS (6, C8, C1, 0)
4559 1.9 christos || reg_value == CPENS (0, C8, C6, 1)
4560 1.9 christos || reg_value == CPENS (0, C8, C6, 3)
4561 1.9 christos || reg_value == CPENS (0, C8, C6, 5)
4562 1.9 christos || reg_value == CPENS (0, C8, C6, 7)
4563 1.9 christos || reg_value == CPENS (0, C8, C2, 1)
4564 1.9 christos || reg_value == CPENS (0, C8, C2, 3)
4565 1.9 christos || reg_value == CPENS (0, C8, C2, 5)
4566 1.9 christos || reg_value == CPENS (0, C8, C2, 7)
4567 1.9 christos || reg_value == CPENS (0, C8, C5, 1)
4568 1.9 christos || reg_value == CPENS (0, C8, C5, 3)
4569 1.9 christos || reg_value == CPENS (0, C8, C5, 5)
4570 1.9 christos || reg_value == CPENS (0, C8, C5, 7)
4571 1.9 christos || reg_value == CPENS (4, C8, C0, 2)
4572 1.9 christos || reg_value == CPENS (4, C8, C0, 6)
4573 1.9 christos || reg_value == CPENS (4, C8, C4, 2)
4574 1.9 christos || reg_value == CPENS (4, C8, C4, 6)
4575 1.9 christos || reg_value == CPENS (4, C8, C4, 3)
4576 1.9 christos || reg_value == CPENS (4, C8, C4, 7)
4577 1.9 christos || reg_value == CPENS (4, C8, C6, 1)
4578 1.9 christos || reg_value == CPENS (4, C8, C6, 5)
4579 1.9 christos || reg_value == CPENS (4, C8, C2, 1)
4580 1.9 christos || reg_value == CPENS (4, C8, C2, 5)
4581 1.9 christos || reg_value == CPENS (4, C8, C5, 1)
4582 1.9 christos || reg_value == CPENS (4, C8, C5, 5)
4583 1.9 christos || reg_value == CPENS (6, C8, C6, 1)
4584 1.9 christos || reg_value == CPENS (6, C8, C6, 5)
4585 1.9 christos || reg_value == CPENS (6, C8, C2, 1)
4586 1.6 christos || reg_value == CPENS (6, C8, C2, 5)
4587 1.6 christos || reg_value == CPENS (6, C8, C5, 1)
4588 1.6 christos || reg_value == CPENS (6, C8, C5, 5))
4589 1.9 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_4))
4590 1.9 christos return TRUE;
4591 1.9 christos
4592 1.6 christos /* DC CVAP. Values are from aarch64_sys_regs_dc. */
4593 1.8 christos if (reg_value == CPENS (3, C7, C12, 1)
4594 1.9 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4595 1.9 christos return TRUE;
4596 1.9 christos
4597 1.8 christos /* DC CVADP. Values are from aarch64_sys_regs_dc. */
4598 1.8 christos if (reg_value == CPENS (3, C7, C13, 1)
4599 1.9 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_CVADP))
4600 1.9 christos return TRUE;
4601 1.9 christos
4602 1.9 christos /* DC <dc_op> for ARMv8.5-A Memory Tagging Extension. */
4603 1.9 christos if ((reg_value == CPENS (0, C7, C6, 3)
4604 1.9 christos || reg_value == CPENS (0, C7, C6, 4)
4605 1.9 christos || reg_value == CPENS (0, C7, C10, 4)
4606 1.9 christos || reg_value == CPENS (0, C7, C14, 4)
4607 1.9 christos || reg_value == CPENS (3, C7, C10, 3)
4608 1.9 christos || reg_value == CPENS (3, C7, C12, 3)
4609 1.9 christos || reg_value == CPENS (3, C7, C13, 3)
4610 1.9 christos || reg_value == CPENS (3, C7, C14, 3)
4611 1.9 christos || reg_value == CPENS (3, C7, C4, 3)
4612 1.9 christos || reg_value == CPENS (0, C7, C6, 5)
4613 1.9 christos || reg_value == CPENS (0, C7, C6, 6)
4614 1.9 christos || reg_value == CPENS (0, C7, C10, 6)
4615 1.9 christos || reg_value == CPENS (0, C7, C14, 6)
4616 1.9 christos || reg_value == CPENS (3, C7, C10, 5)
4617 1.9 christos || reg_value == CPENS (3, C7, C12, 5)
4618 1.9 christos || reg_value == CPENS (3, C7, C13, 5)
4619 1.8 christos || reg_value == CPENS (3, C7, C14, 5)
4620 1.6 christos || reg_value == CPENS (3, C7, C4, 4))
4621 1.9 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_MEMTAG))
4622 1.9 christos return TRUE;
4623 1.9 christos
4624 1.9 christos /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
4625 1.6 christos if ((reg_value == CPENS (0, C7, C9, 0)
4626 1.8 christos || reg_value == CPENS (0, C7, C9, 1))
4627 1.9 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4628 1.9 christos return TRUE;
4629 1.9 christos
4630 1.8 christos /* CFP/DVP/CPP RCTX : Value are from aarch64_sys_regs_sr. */
4631 1.9 christos if (reg_value == CPENS (3, C7, C3, 0)
4632 1.6 christos && AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PREDRES))
4633 1.6 christos return TRUE;
4634 1.1 christos
4635 1.1 christos return FALSE;
4636 1.1 christos }
4637 1.1 christos
4638 1.1 christos #undef C0
4639 1.1 christos #undef C1
4640 1.1 christos #undef C2
4641 1.1 christos #undef C3
4642 1.1 christos #undef C4
4643 1.1 christos #undef C5
4644 1.1 christos #undef C6
4645 1.1 christos #undef C7
4646 1.1 christos #undef C8
4647 1.1 christos #undef C9
4648 1.1 christos #undef C10
4649 1.1 christos #undef C11
4650 1.1 christos #undef C12
4651 1.6 christos #undef C13
4652 1.6 christos #undef C14
4653 1.6 christos #undef C15
4654 1.8 christos
4655 1.8 christos #define BIT(INSN,BT) (((INSN) >> (BT)) & 1)
4656 1.8 christos #define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
4657 1.8 christos
4658 1.8 christos static enum err_type
4659 1.8 christos verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED,
4660 1.6 christos const aarch64_insn insn, bfd_vma pc ATTRIBUTE_UNUSED,
4661 1.6 christos bfd_boolean encoding ATTRIBUTE_UNUSED,
4662 1.6 christos aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
4663 1.6 christos aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
4664 1.6 christos {
4665 1.6 christos int t = BITS (insn, 4, 0);
4666 1.6 christos int n = BITS (insn, 9, 5);
4667 1.6 christos int t2 = BITS (insn, 14, 10);
4668 1.6 christos
4669 1.8 christos if (BIT (insn, 23))
4670 1.6 christos {
4671 1.6 christos /* Write back enabled. */
4672 1.6 christos if ((t == n || t2 == n) && n != 31)
4673 1.6 christos return ERR_UND;
4674 1.6 christos }
4675 1.6 christos
4676 1.8 christos if (BIT (insn, 22))
4677 1.8 christos {
4678 1.8 christos /* Load */
4679 1.8 christos if (t == t2)
4680 1.8 christos return ERR_UND;
4681 1.8 christos }
4682 1.8 christos
4683 1.8 christos return ERR_OK;
4684 1.8 christos }
4685 1.8 christos
4686 1.8 christos /* Verifier for vector by element 3 operands functions where the
4687 1.8 christos conditions `if sz:L == 11 then UNDEFINED` holds. */
4688 1.8 christos
4689 1.8 christos static enum err_type
4690 1.8 christos verify_elem_sd (const struct aarch64_inst *inst, const aarch64_insn insn,
4691 1.8 christos bfd_vma pc ATTRIBUTE_UNUSED, bfd_boolean encoding,
4692 1.8 christos aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
4693 1.8 christos aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
4694 1.8 christos {
4695 1.8 christos const aarch64_insn undef_pattern = 0x3;
4696 1.8 christos aarch64_insn value;
4697 1.8 christos
4698 1.8 christos assert (inst->opcode);
4699 1.8 christos assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
4700 1.8 christos value = encoding ? inst->value : insn;
4701 1.8 christos assert (value);
4702 1.8 christos
4703 1.8 christos if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
4704 1.8 christos return ERR_UND;
4705 1.8 christos
4706 1.8 christos return ERR_OK;
4707 1.8 christos }
4708 1.8 christos
4709 1.8 christos /* Initialize an instruction sequence insn_sequence with the instruction INST.
4710 1.8 christos If INST is NULL the given insn_sequence is cleared and the sequence is left
4711 1.8 christos uninitialized. */
4712 1.8 christos
4713 1.8 christos void
4714 1.8 christos init_insn_sequence (const struct aarch64_inst *inst,
4715 1.8 christos aarch64_instr_sequence *insn_sequence)
4716 1.8 christos {
4717 1.8 christos int num_req_entries = 0;
4718 1.8 christos insn_sequence->next_insn = 0;
4719 1.8 christos insn_sequence->num_insns = num_req_entries;
4720 1.8 christos if (insn_sequence->instr)
4721 1.8 christos XDELETE (insn_sequence->instr);
4722 1.8 christos insn_sequence->instr = NULL;
4723 1.8 christos
4724 1.8 christos if (inst)
4725 1.8 christos {
4726 1.8 christos insn_sequence->instr = XNEW (aarch64_inst);
4727 1.8 christos memcpy (insn_sequence->instr, inst, sizeof (aarch64_inst));
4728 1.8 christos }
4729 1.8 christos
4730 1.8 christos /* Handle all the cases here. May need to think of something smarter than
4731 1.8 christos a giant if/else chain if this grows. At that time, a lookup table may be
4732 1.8 christos best. */
4733 1.8 christos if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
4734 1.8 christos num_req_entries = 1;
4735 1.8 christos
4736 1.8 christos if (insn_sequence->current_insns)
4737 1.8 christos XDELETEVEC (insn_sequence->current_insns);
4738 1.8 christos insn_sequence->current_insns = NULL;
4739 1.8 christos
4740 1.8 christos if (num_req_entries != 0)
4741 1.8 christos {
4742 1.8 christos size_t size = num_req_entries * sizeof (aarch64_inst);
4743 1.8 christos insn_sequence->current_insns
4744 1.8 christos = (aarch64_inst**) XNEWVEC (aarch64_inst, num_req_entries);
4745 1.8 christos memset (insn_sequence->current_insns, 0, size);
4746 1.8 christos }
4747 1.8 christos }
4748 1.8 christos
4749 1.8 christos
4750 1.8 christos /* This function verifies that the instruction INST adheres to its specified
4751 1.8 christos constraints. If it does then ERR_OK is returned, if not then ERR_VFI is
4752 1.8 christos returned and MISMATCH_DETAIL contains the reason why verification failed.
4753 1.8 christos
4754 1.8 christos The function is called both during assembly and disassembly. If assembling
4755 1.8 christos then ENCODING will be TRUE, else FALSE. If dissassembling PC will be set
4756 1.8 christos and will contain the PC of the current instruction w.r.t to the section.
4757 1.8 christos
4758 1.8 christos If ENCODING and PC=0 then you are at a start of a section. The constraints
4759 1.8 christos are verified against the given state insn_sequence which is updated as it
4760 1.8 christos transitions through the verification. */
4761 1.8 christos
4762 1.8 christos enum err_type
4763 1.8 christos verify_constraints (const struct aarch64_inst *inst,
4764 1.8 christos const aarch64_insn insn ATTRIBUTE_UNUSED,
4765 1.8 christos bfd_vma pc,
4766 1.8 christos bfd_boolean encoding,
4767 1.8 christos aarch64_operand_error *mismatch_detail,
4768 1.8 christos aarch64_instr_sequence *insn_sequence)
4769 1.8 christos {
4770 1.8 christos assert (inst);
4771 1.8 christos assert (inst->opcode);
4772 1.8 christos
4773 1.8 christos const struct aarch64_opcode *opcode = inst->opcode;
4774 1.8 christos if (!opcode->constraints && !insn_sequence->instr)
4775 1.8 christos return ERR_OK;
4776 1.8 christos
4777 1.8 christos assert (insn_sequence);
4778 1.8 christos
4779 1.8 christos enum err_type res = ERR_OK;
4780 1.8 christos
4781 1.8 christos /* This instruction puts a constraint on the insn_sequence. */
4782 1.8 christos if (opcode->flags & F_SCAN)
4783 1.8 christos {
4784 1.8 christos if (insn_sequence->instr)
4785 1.8 christos {
4786 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4787 1.8 christos mismatch_detail->error = _("instruction opens new dependency "
4788 1.8 christos "sequence without ending previous one");
4789 1.8 christos mismatch_detail->index = -1;
4790 1.8 christos mismatch_detail->non_fatal = TRUE;
4791 1.8 christos res = ERR_VFI;
4792 1.8 christos }
4793 1.8 christos
4794 1.8 christos init_insn_sequence (inst, insn_sequence);
4795 1.8 christos return res;
4796 1.8 christos }
4797 1.8 christos
4798 1.8 christos /* Verify constraints on an existing sequence. */
4799 1.8 christos if (insn_sequence->instr)
4800 1.8 christos {
4801 1.8 christos const struct aarch64_opcode* inst_opcode = insn_sequence->instr->opcode;
4802 1.8 christos /* If we're decoding and we hit PC=0 with an open sequence then we haven't
4803 1.8 christos closed a previous one that we should have. */
4804 1.8 christos if (!encoding && pc == 0)
4805 1.8 christos {
4806 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4807 1.8 christos mismatch_detail->error = _("previous `movprfx' sequence not closed");
4808 1.8 christos mismatch_detail->index = -1;
4809 1.8 christos mismatch_detail->non_fatal = TRUE;
4810 1.8 christos res = ERR_VFI;
4811 1.8 christos /* Reset the sequence. */
4812 1.8 christos init_insn_sequence (NULL, insn_sequence);
4813 1.8 christos return res;
4814 1.8 christos }
4815 1.8 christos
4816 1.8 christos /* Validate C_SCAN_MOVPRFX constraints. Move this to a lookup table. */
4817 1.9 christos if (inst_opcode->constraints & C_SCAN_MOVPRFX)
4818 1.9 christos {
4819 1.9 christos /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
4820 1.8 christos instruction for better error messages. */
4821 1.8 christos if (!opcode->avariant
4822 1.8 christos || !(*opcode->avariant &
4823 1.8 christos (AARCH64_FEATURE_SVE | AARCH64_FEATURE_SVE2)))
4824 1.8 christos {
4825 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4826 1.8 christos mismatch_detail->error = _("SVE instruction expected after "
4827 1.8 christos "`movprfx'");
4828 1.8 christos mismatch_detail->index = -1;
4829 1.8 christos mismatch_detail->non_fatal = TRUE;
4830 1.8 christos res = ERR_VFI;
4831 1.8 christos goto done;
4832 1.8 christos }
4833 1.8 christos
4834 1.8 christos /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
4835 1.8 christos instruction that is allowed to be used with a MOVPRFX. */
4836 1.8 christos if (!(opcode->constraints & C_SCAN_MOVPRFX))
4837 1.8 christos {
4838 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4839 1.8 christos mismatch_detail->error = _("SVE `movprfx' compatible instruction "
4840 1.8 christos "expected");
4841 1.8 christos mismatch_detail->index = -1;
4842 1.8 christos mismatch_detail->non_fatal = TRUE;
4843 1.8 christos res = ERR_VFI;
4844 1.8 christos goto done;
4845 1.8 christos }
4846 1.8 christos
4847 1.8 christos /* Next check for usage of the predicate register. */
4848 1.8 christos aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
4849 1.8 christos aarch64_opnd_info blk_pred, inst_pred;
4850 1.8 christos memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
4851 1.8 christos memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
4852 1.8 christos bfd_boolean predicated = FALSE;
4853 1.8 christos assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
4854 1.8 christos
4855 1.8 christos /* Determine if the movprfx instruction used is predicated or not. */
4856 1.8 christos if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
4857 1.8 christos {
4858 1.8 christos predicated = TRUE;
4859 1.8 christos blk_pred = insn_sequence->instr->operands[1];
4860 1.8 christos }
4861 1.8 christos
4862 1.8 christos unsigned char max_elem_size = 0;
4863 1.8 christos unsigned char current_elem_size;
4864 1.8 christos int num_op_used = 0, last_op_usage = 0;
4865 1.8 christos int i, inst_pred_idx = -1;
4866 1.8 christos int num_ops = aarch64_num_of_operands (opcode);
4867 1.8 christos for (i = 0; i < num_ops; i++)
4868 1.8 christos {
4869 1.8 christos aarch64_opnd_info inst_op = inst->operands[i];
4870 1.8 christos switch (inst_op.type)
4871 1.8 christos {
4872 1.8 christos case AARCH64_OPND_SVE_Zd:
4873 1.8 christos case AARCH64_OPND_SVE_Zm_5:
4874 1.8 christos case AARCH64_OPND_SVE_Zm_16:
4875 1.8 christos case AARCH64_OPND_SVE_Zn:
4876 1.8 christos case AARCH64_OPND_SVE_Zt:
4877 1.8 christos case AARCH64_OPND_SVE_Vm:
4878 1.8 christos case AARCH64_OPND_SVE_Vn:
4879 1.8 christos case AARCH64_OPND_Va:
4880 1.8 christos case AARCH64_OPND_Vn:
4881 1.8 christos case AARCH64_OPND_Vm:
4882 1.8 christos case AARCH64_OPND_Sn:
4883 1.8 christos case AARCH64_OPND_Sm:
4884 1.8 christos if (inst_op.reg.regno == blk_dest.reg.regno)
4885 1.8 christos {
4886 1.8 christos num_op_used++;
4887 1.8 christos last_op_usage = i;
4888 1.8 christos }
4889 1.8 christos current_elem_size
4890 1.8 christos = aarch64_get_qualifier_esize (inst_op.qualifier);
4891 1.8 christos if (current_elem_size > max_elem_size)
4892 1.8 christos max_elem_size = current_elem_size;
4893 1.8 christos break;
4894 1.8 christos case AARCH64_OPND_SVE_Pd:
4895 1.8 christos case AARCH64_OPND_SVE_Pg3:
4896 1.8 christos case AARCH64_OPND_SVE_Pg4_5:
4897 1.8 christos case AARCH64_OPND_SVE_Pg4_10:
4898 1.8 christos case AARCH64_OPND_SVE_Pg4_16:
4899 1.8 christos case AARCH64_OPND_SVE_Pm:
4900 1.8 christos case AARCH64_OPND_SVE_Pn:
4901 1.8 christos case AARCH64_OPND_SVE_Pt:
4902 1.8 christos inst_pred = inst_op;
4903 1.8 christos inst_pred_idx = i;
4904 1.8 christos break;
4905 1.8 christos default:
4906 1.8 christos break;
4907 1.8 christos }
4908 1.8 christos }
4909 1.8 christos
4910 1.8 christos assert (max_elem_size != 0);
4911 1.8 christos aarch64_opnd_info inst_dest = inst->operands[0];
4912 1.8 christos /* Determine the size that should be used to compare against the
4913 1.8 christos movprfx size. */
4914 1.8 christos current_elem_size
4915 1.8 christos = opcode->constraints & C_MAX_ELEM
4916 1.8 christos ? max_elem_size
4917 1.8 christos : aarch64_get_qualifier_esize (inst_dest.qualifier);
4918 1.8 christos
4919 1.8 christos /* If movprfx is predicated do some extra checks. */
4920 1.8 christos if (predicated)
4921 1.8 christos {
4922 1.8 christos /* The instruction must be predicated. */
4923 1.8 christos if (inst_pred_idx < 0)
4924 1.8 christos {
4925 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4926 1.8 christos mismatch_detail->error = _("predicated instruction expected "
4927 1.8 christos "after `movprfx'");
4928 1.8 christos mismatch_detail->index = -1;
4929 1.8 christos mismatch_detail->non_fatal = TRUE;
4930 1.8 christos res = ERR_VFI;
4931 1.8 christos goto done;
4932 1.8 christos }
4933 1.8 christos
4934 1.8 christos /* The instruction must have a merging predicate. */
4935 1.8 christos if (inst_pred.qualifier != AARCH64_OPND_QLF_P_M)
4936 1.8 christos {
4937 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4938 1.8 christos mismatch_detail->error = _("merging predicate expected due "
4939 1.8 christos "to preceding `movprfx'");
4940 1.8 christos mismatch_detail->index = inst_pred_idx;
4941 1.8 christos mismatch_detail->non_fatal = TRUE;
4942 1.8 christos res = ERR_VFI;
4943 1.8 christos goto done;
4944 1.8 christos }
4945 1.8 christos
4946 1.8 christos /* The same register must be used in instruction. */
4947 1.8 christos if (blk_pred.reg.regno != inst_pred.reg.regno)
4948 1.8 christos {
4949 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4950 1.8 christos mismatch_detail->error = _("predicate register differs "
4951 1.8 christos "from that in preceding "
4952 1.8 christos "`movprfx'");
4953 1.8 christos mismatch_detail->index = inst_pred_idx;
4954 1.8 christos mismatch_detail->non_fatal = TRUE;
4955 1.8 christos res = ERR_VFI;
4956 1.8 christos goto done;
4957 1.8 christos }
4958 1.8 christos }
4959 1.8 christos
4960 1.8 christos /* Destructive operations by definition must allow one usage of the
4961 1.8 christos same register. */
4962 1.8 christos int allowed_usage
4963 1.8 christos = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
4964 1.8 christos
4965 1.8 christos /* Operand is not used at all. */
4966 1.8 christos if (num_op_used == 0)
4967 1.8 christos {
4968 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4969 1.8 christos mismatch_detail->error = _("output register of preceding "
4970 1.8 christos "`movprfx' not used in current "
4971 1.8 christos "instruction");
4972 1.8 christos mismatch_detail->index = 0;
4973 1.8 christos mismatch_detail->non_fatal = TRUE;
4974 1.8 christos res = ERR_VFI;
4975 1.8 christos goto done;
4976 1.8 christos }
4977 1.8 christos
4978 1.8 christos /* We now know it's used, now determine exactly where it's used. */
4979 1.8 christos if (blk_dest.reg.regno != inst_dest.reg.regno)
4980 1.8 christos {
4981 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4982 1.8 christos mismatch_detail->error = _("output register of preceding "
4983 1.8 christos "`movprfx' expected as output");
4984 1.8 christos mismatch_detail->index = 0;
4985 1.8 christos mismatch_detail->non_fatal = TRUE;
4986 1.8 christos res = ERR_VFI;
4987 1.8 christos goto done;
4988 1.8 christos }
4989 1.8 christos
4990 1.8 christos /* Operand used more than allowed for the specific opcode type. */
4991 1.8 christos if (num_op_used > allowed_usage)
4992 1.8 christos {
4993 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
4994 1.8 christos mismatch_detail->error = _("output register of preceding "
4995 1.8 christos "`movprfx' used as input");
4996 1.8 christos mismatch_detail->index = last_op_usage;
4997 1.8 christos mismatch_detail->non_fatal = TRUE;
4998 1.8 christos res = ERR_VFI;
4999 1.8 christos goto done;
5000 1.8 christos }
5001 1.8 christos
5002 1.8 christos /* Now the only thing left is the qualifiers checks. The register
5003 1.8 christos must have the same maximum element size. */
5004 1.8 christos if (inst_dest.qualifier
5005 1.8 christos && blk_dest.qualifier
5006 1.8 christos && current_elem_size
5007 1.8 christos != aarch64_get_qualifier_esize (blk_dest.qualifier))
5008 1.8 christos {
5009 1.8 christos mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5010 1.8 christos mismatch_detail->error = _("register size not compatible with "
5011 1.8 christos "previous `movprfx'");
5012 1.8 christos mismatch_detail->index = 0;
5013 1.8 christos mismatch_detail->non_fatal = TRUE;
5014 1.8 christos res = ERR_VFI;
5015 1.9 christos goto done;
5016 1.8 christos }
5017 1.8 christos }
5018 1.8 christos
5019 1.8 christos done:
5020 1.8 christos /* Add the new instruction to the sequence. */
5021 1.8 christos memcpy (insn_sequence->current_insns + insn_sequence->next_insn++,
5022 1.8 christos inst, sizeof (aarch64_inst));
5023 1.8 christos
5024 1.8 christos /* Check if sequence is now full. */
5025 1.8 christos if (insn_sequence->next_insn >= insn_sequence->num_insns)
5026 1.8 christos {
5027 1.6 christos /* Sequence is full, but we don't have anything special to do for now,
5028 1.6 christos so clear and reset it. */
5029 1.8 christos init_insn_sequence (NULL, insn_sequence);
5030 1.6 christos }
5031 1.6 christos }
5032 1.8 christos
5033 1.7 christos return res;
5034 1.7 christos }
5035 1.7 christos
5036 1.7 christos
5037 1.7 christos /* Return true if VALUE cannot be moved into an SVE register using DUP
5038 1.7 christos (with any element size, not just ESIZE) and if using DUPM would
5039 1.7 christos therefore be OK. ESIZE is the number of bytes in the immediate. */
5040 1.7 christos
5041 1.7 christos bfd_boolean
5042 1.7 christos aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
5043 1.7 christos {
5044 1.7 christos int64_t svalue = uvalue;
5045 1.7 christos uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
5046 1.7 christos
5047 1.7 christos if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
5048 1.7 christos return FALSE;
5049 1.7 christos if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
5050 1.7 christos {
5051 1.7 christos svalue = (int32_t) uvalue;
5052 1.7 christos if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
5053 1.7 christos {
5054 1.7 christos svalue = (int16_t) uvalue;
5055 1.7 christos if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
5056 1.7 christos return FALSE;
5057 1.7 christos }
5058 1.7 christos }
5059 1.7 christos if ((svalue & 0xff) == 0)
5060 1.1 christos svalue /= 256;
5061 1.1 christos return svalue < -128 || svalue >= 128;
5062 1.6 christos }
5063 1.1 christos
5064 /* Include the opcode description table as well as the operand description
5065 table. */
5066 #define VERIFIER(x) verify_##x
5067 #include "aarch64-tbl.h"
5068