aarch64-opc.c revision 1.1.1.2 1 1.1 christos /* aarch64-opc.c -- AArch64 opcode support.
2 1.1.1.2 christos Copyright (C) 2009-2015 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.1 christos #include <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.1 christos
31 1.1 christos #include "aarch64-opc.h"
32 1.1 christos
33 1.1 christos #ifdef DEBUG_AARCH64
34 1.1 christos int debug_dump = FALSE;
35 1.1 christos #endif /* DEBUG_AARCH64 */
36 1.1 christos
37 1.1 christos /* Helper functions to determine which operand to be used to encode/decode
38 1.1 christos the size:Q fields for AdvSIMD instructions. */
39 1.1 christos
40 1.1 christos static inline bfd_boolean
41 1.1 christos vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
42 1.1 christos {
43 1.1 christos return ((qualifier >= AARCH64_OPND_QLF_V_8B
44 1.1 christos && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
45 1.1 christos : FALSE);
46 1.1 christos }
47 1.1 christos
48 1.1 christos static inline bfd_boolean
49 1.1 christos fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
50 1.1 christos {
51 1.1 christos return ((qualifier >= AARCH64_OPND_QLF_S_B
52 1.1 christos && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
53 1.1 christos : FALSE);
54 1.1 christos }
55 1.1 christos
56 1.1 christos enum data_pattern
57 1.1 christos {
58 1.1 christos DP_UNKNOWN,
59 1.1 christos DP_VECTOR_3SAME,
60 1.1 christos DP_VECTOR_LONG,
61 1.1 christos DP_VECTOR_WIDE,
62 1.1 christos DP_VECTOR_ACROSS_LANES,
63 1.1 christos };
64 1.1 christos
65 1.1 christos static const char significant_operand_index [] =
66 1.1 christos {
67 1.1 christos 0, /* DP_UNKNOWN, by default using operand 0. */
68 1.1 christos 0, /* DP_VECTOR_3SAME */
69 1.1 christos 1, /* DP_VECTOR_LONG */
70 1.1 christos 2, /* DP_VECTOR_WIDE */
71 1.1 christos 1, /* DP_VECTOR_ACROSS_LANES */
72 1.1 christos };
73 1.1 christos
74 1.1 christos /* Given a sequence of qualifiers in QUALIFIERS, determine and return
75 1.1 christos the data pattern.
76 1.1 christos N.B. QUALIFIERS is a possible sequence of qualifiers each of which
77 1.1 christos corresponds to one of a sequence of operands. */
78 1.1 christos
79 1.1 christos static enum data_pattern
80 1.1 christos get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
81 1.1 christos {
82 1.1 christos if (vector_qualifier_p (qualifiers[0]) == TRUE)
83 1.1 christos {
84 1.1 christos /* e.g. v.4s, v.4s, v.4s
85 1.1 christos or v.4h, v.4h, v.h[3]. */
86 1.1 christos if (qualifiers[0] == qualifiers[1]
87 1.1 christos && vector_qualifier_p (qualifiers[2]) == TRUE
88 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
89 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1]))
90 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
91 1.1 christos == aarch64_get_qualifier_esize (qualifiers[2])))
92 1.1 christos return DP_VECTOR_3SAME;
93 1.1 christos /* e.g. v.8h, v.8b, v.8b.
94 1.1 christos or v.4s, v.4h, v.h[2].
95 1.1 christos or v.8h, v.16b. */
96 1.1 christos if (vector_qualifier_p (qualifiers[1]) == TRUE
97 1.1 christos && aarch64_get_qualifier_esize (qualifiers[0]) != 0
98 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
99 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
100 1.1 christos return DP_VECTOR_LONG;
101 1.1 christos /* e.g. v.8h, v.8h, v.8b. */
102 1.1 christos if (qualifiers[0] == qualifiers[1]
103 1.1 christos && vector_qualifier_p (qualifiers[2]) == TRUE
104 1.1 christos && aarch64_get_qualifier_esize (qualifiers[0]) != 0
105 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
106 1.1 christos == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
107 1.1 christos && (aarch64_get_qualifier_esize (qualifiers[0])
108 1.1 christos == aarch64_get_qualifier_esize (qualifiers[1])))
109 1.1 christos return DP_VECTOR_WIDE;
110 1.1 christos }
111 1.1 christos else if (fp_qualifier_p (qualifiers[0]) == TRUE)
112 1.1 christos {
113 1.1 christos /* e.g. SADDLV <V><d>, <Vn>.<T>. */
114 1.1 christos if (vector_qualifier_p (qualifiers[1]) == TRUE
115 1.1 christos && qualifiers[2] == AARCH64_OPND_QLF_NIL)
116 1.1 christos return DP_VECTOR_ACROSS_LANES;
117 1.1 christos }
118 1.1 christos
119 1.1 christos return DP_UNKNOWN;
120 1.1 christos }
121 1.1 christos
122 1.1 christos /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
123 1.1 christos the AdvSIMD instructions. */
124 1.1 christos /* N.B. it is possible to do some optimization that doesn't call
125 1.1 christos get_data_pattern each time when we need to select an operand. We can
126 1.1 christos either buffer the caculated the result or statically generate the data,
127 1.1 christos however, it is not obvious that the optimization will bring significant
128 1.1 christos benefit. */
129 1.1 christos
130 1.1 christos int
131 1.1 christos aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
132 1.1 christos {
133 1.1 christos return
134 1.1 christos significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
135 1.1 christos }
136 1.1 christos
137 1.1 christos const aarch64_field fields[] =
139 1.1 christos {
140 1.1 christos { 0, 0 }, /* NIL. */
141 1.1 christos { 0, 4 }, /* cond2: condition in truly conditional-executed inst. */
142 1.1 christos { 0, 4 }, /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
143 1.1 christos { 5, 5 }, /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
144 1.1 christos { 16, 3 }, /* abc: a:b:c bits in AdvSIMD modified immediate. */
145 1.1 christos { 5, 19 }, /* imm19: e.g. in CBZ. */
146 1.1 christos { 5, 19 }, /* immhi: e.g. in ADRP. */
147 1.1 christos { 29, 2 }, /* immlo: e.g. in ADRP. */
148 1.1 christos { 22, 2 }, /* size: in most AdvSIMD and floating-point instructions. */
149 1.1 christos { 10, 2 }, /* vldst_size: size field in the AdvSIMD load/store inst. */
150 1.1 christos { 29, 1 }, /* op: in AdvSIMD modified immediate instructions. */
151 1.1 christos { 30, 1 }, /* Q: in most AdvSIMD instructions. */
152 1.1 christos { 0, 5 }, /* Rt: in load/store instructions. */
153 1.1 christos { 0, 5 }, /* Rd: in many integer instructions. */
154 1.1 christos { 5, 5 }, /* Rn: in many integer instructions. */
155 1.1 christos { 10, 5 }, /* Rt2: in load/store pair instructions. */
156 1.1 christos { 10, 5 }, /* Ra: in fp instructions. */
157 1.1 christos { 5, 3 }, /* op2: in the system instructions. */
158 1.1 christos { 8, 4 }, /* CRm: in the system instructions. */
159 1.1 christos { 12, 4 }, /* CRn: in the system instructions. */
160 1.1 christos { 16, 3 }, /* op1: in the system instructions. */
161 1.1 christos { 19, 2 }, /* op0: in the system instructions. */
162 1.1 christos { 10, 3 }, /* imm3: in add/sub extended reg instructions. */
163 1.1 christos { 12, 4 }, /* cond: condition flags as a source operand. */
164 1.1 christos { 12, 4 }, /* opcode: in advsimd load/store instructions. */
165 1.1 christos { 12, 4 }, /* cmode: in advsimd modified immediate instructions. */
166 1.1 christos { 13, 3 }, /* asisdlso_opcode: opcode in advsimd ld/st single element. */
167 1.1 christos { 13, 2 }, /* len: in advsimd tbl/tbx instructions. */
168 1.1 christos { 16, 5 }, /* Rm: in ld/st reg offset and some integer inst. */
169 1.1 christos { 16, 5 }, /* Rs: in load/store exclusive instructions. */
170 1.1 christos { 13, 3 }, /* option: in ld/st reg offset + add/sub extended reg inst. */
171 1.1 christos { 12, 1 }, /* S: in load/store reg offset instructions. */
172 1.1 christos { 21, 2 }, /* hw: in move wide constant instructions. */
173 1.1 christos { 22, 2 }, /* opc: in load/store reg offset instructions. */
174 1.1 christos { 23, 1 }, /* opc1: in load/store reg offset instructions. */
175 1.1 christos { 22, 2 }, /* shift: in add/sub reg/imm shifted instructions. */
176 1.1 christos { 22, 2 }, /* type: floating point type field in fp data inst. */
177 1.1 christos { 30, 2 }, /* ldst_size: size field in ld/st reg offset inst. */
178 1.1 christos { 10, 6 }, /* imm6: in add/sub reg shifted instructions. */
179 1.1 christos { 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
180 1.1 christos { 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
181 1.1 christos { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
182 1.1 christos { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
183 1.1 christos { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
184 1.1 christos { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
185 1.1 christos { 5, 14 }, /* imm14: in test bit and branch instructions. */
186 1.1 christos { 5, 16 }, /* imm16: in exception instructions. */
187 1.1 christos { 0, 26 }, /* imm26: in unconditional branch instructions. */
188 1.1 christos { 10, 6 }, /* imms: in bitfield and logical immediate instructions. */
189 1.1 christos { 16, 6 }, /* immr: in bitfield and logical immediate instructions. */
190 1.1 christos { 16, 3 }, /* immb: in advsimd shift by immediate instructions. */
191 1.1 christos { 19, 4 }, /* immh: in advsimd shift by immediate instructions. */
192 1.1 christos { 22, 1 }, /* N: in logical (immediate) instructions. */
193 1.1 christos { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
194 1.1 christos { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
195 1.1.1.2 christos { 31, 1 }, /* sf: in integer data processing instructions. */
196 1.1 christos { 30, 1 }, /* lse_size: in LSE extension atomic instructions. */
197 1.1 christos { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
198 1.1 christos { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
199 1.1 christos { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
200 1.1 christos { 31, 1 }, /* b5: in the test bit and branch instructions. */
201 1.1 christos { 19, 5 }, /* b40: in the test bit and branch instructions. */
202 1.1 christos { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
203 1.1 christos };
204 1.1 christos
205 1.1 christos enum aarch64_operand_class
206 1.1 christos aarch64_get_operand_class (enum aarch64_opnd type)
207 1.1 christos {
208 1.1 christos return aarch64_operands[type].op_class;
209 1.1 christos }
210 1.1.1.2 christos
211 1.1 christos const char *
212 1.1 christos aarch64_get_operand_name (enum aarch64_opnd type)
213 1.1 christos {
214 1.1 christos return aarch64_operands[type].name;
215 1.1 christos }
216 1.1 christos
217 1.1 christos /* Get operand description string.
218 1.1.1.2 christos This is usually for the diagnosis purpose. */
219 1.1 christos const char *
220 1.1 christos aarch64_get_operand_desc (enum aarch64_opnd type)
221 1.1 christos {
222 1.1 christos return aarch64_operands[type].desc;
223 1.1 christos }
224 1.1 christos
225 1.1 christos /* Table of all conditional affixes. */
226 1.1 christos const aarch64_cond aarch64_conds[16] =
227 1.1 christos {
228 1.1 christos {{"eq"}, 0x0},
229 1.1 christos {{"ne"}, 0x1},
230 1.1 christos {{"cs", "hs"}, 0x2},
231 1.1 christos {{"cc", "lo", "ul"}, 0x3},
232 1.1 christos {{"mi"}, 0x4},
233 1.1 christos {{"pl"}, 0x5},
234 1.1 christos {{"vs"}, 0x6},
235 1.1 christos {{"vc"}, 0x7},
236 1.1 christos {{"hi"}, 0x8},
237 1.1 christos {{"ls"}, 0x9},
238 1.1 christos {{"ge"}, 0xa},
239 1.1 christos {{"lt"}, 0xb},
240 1.1 christos {{"gt"}, 0xc},
241 1.1 christos {{"le"}, 0xd},
242 1.1 christos {{"al"}, 0xe},
243 1.1 christos {{"nv"}, 0xf},
244 1.1 christos };
245 1.1.1.2 christos
246 1.1 christos const aarch64_cond *
247 1.1 christos get_cond_from_value (aarch64_insn value)
248 1.1 christos {
249 1.1 christos assert (value < 16);
250 1.1 christos return &aarch64_conds[(unsigned int) value];
251 1.1 christos }
252 1.1.1.2 christos
253 1.1 christos const aarch64_cond *
254 1.1 christos get_inverted_cond (const aarch64_cond *cond)
255 1.1 christos {
256 1.1 christos return &aarch64_conds[cond->value ^ 0x1];
257 1.1 christos }
258 1.1 christos
259 1.1 christos /* Table describing the operand extension/shifting operators; indexed by
260 1.1 christos enum aarch64_modifier_kind.
261 1.1 christos
262 1.1 christos The value column provides the most common values for encoding modifiers,
263 1.1 christos which enables table-driven encoding/decoding for the modifiers. */
264 1.1 christos const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
265 1.1 christos {
266 1.1 christos {"none", 0x0},
267 1.1 christos {"msl", 0x0},
268 1.1 christos {"ror", 0x3},
269 1.1 christos {"asr", 0x2},
270 1.1 christos {"lsr", 0x1},
271 1.1 christos {"lsl", 0x0},
272 1.1 christos {"uxtb", 0x0},
273 1.1 christos {"uxth", 0x1},
274 1.1 christos {"uxtw", 0x2},
275 1.1 christos {"uxtx", 0x3},
276 1.1 christos {"sxtb", 0x4},
277 1.1 christos {"sxth", 0x5},
278 1.1 christos {"sxtw", 0x6},
279 1.1 christos {"sxtx", 0x7},
280 1.1 christos {NULL, 0},
281 1.1 christos };
282 1.1 christos
283 1.1 christos enum aarch64_modifier_kind
284 1.1 christos aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
285 1.1 christos {
286 1.1 christos return desc - aarch64_operand_modifiers;
287 1.1 christos }
288 1.1 christos
289 1.1 christos aarch64_insn
290 1.1 christos aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
291 1.1 christos {
292 1.1 christos return aarch64_operand_modifiers[kind].value;
293 1.1 christos }
294 1.1 christos
295 1.1 christos enum aarch64_modifier_kind
296 1.1 christos aarch64_get_operand_modifier_from_value (aarch64_insn value,
297 1.1 christos bfd_boolean extend_p)
298 1.1 christos {
299 1.1 christos if (extend_p == TRUE)
300 1.1 christos return AARCH64_MOD_UXTB + value;
301 1.1 christos else
302 1.1 christos return AARCH64_MOD_LSL - value;
303 1.1 christos }
304 1.1 christos
305 1.1 christos bfd_boolean
306 1.1 christos aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
307 1.1 christos {
308 1.1 christos return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
309 1.1 christos ? TRUE : FALSE;
310 1.1 christos }
311 1.1 christos
312 1.1 christos static inline bfd_boolean
313 1.1 christos aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
314 1.1 christos {
315 1.1 christos return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
316 1.1 christos ? TRUE : FALSE;
317 1.1 christos }
318 1.1 christos
319 1.1 christos const struct aarch64_name_value_pair aarch64_barrier_options[16] =
320 1.1 christos {
321 1.1 christos { "#0x00", 0x0 },
322 1.1 christos { "oshld", 0x1 },
323 1.1 christos { "oshst", 0x2 },
324 1.1 christos { "osh", 0x3 },
325 1.1 christos { "#0x04", 0x4 },
326 1.1 christos { "nshld", 0x5 },
327 1.1 christos { "nshst", 0x6 },
328 1.1 christos { "nsh", 0x7 },
329 1.1 christos { "#0x08", 0x8 },
330 1.1 christos { "ishld", 0x9 },
331 1.1 christos { "ishst", 0xa },
332 1.1 christos { "ish", 0xb },
333 1.1 christos { "#0x0c", 0xc },
334 1.1 christos { "ld", 0xd },
335 1.1 christos { "st", 0xe },
336 1.1 christos { "sy", 0xf },
337 1.1 christos };
338 1.1.1.2 christos
339 1.1.1.2 christos /* Table describing the operands supported by the aliases of the HINT
340 1.1.1.2 christos instruction.
341 1.1.1.2 christos
342 1.1.1.2 christos The name column is the operand that is accepted for the alias. The value
343 1.1.1.2 christos column is the hint number of the alias. The list of operands is terminated
344 1.1.1.2 christos by NULL in the name column. */
345 1.1.1.2 christos
346 1.1.1.2 christos const struct aarch64_name_value_pair aarch64_hint_options[] =
347 1.1.1.2 christos {
348 1.1.1.2 christos { "csync", 0x11 }, /* PSB CSYNC. */
349 1.1.1.2 christos { NULL, 0x0 },
350 1.1.1.2 christos };
351 1.1 christos
352 1.1 christos /* op -> op: load = 0 instruction = 1 store = 2
353 1.1 christos l -> level: 1-3
354 1.1 christos t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
355 1.1 christos #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
356 1.1 christos const struct aarch64_name_value_pair aarch64_prfops[32] =
357 1.1 christos {
358 1.1 christos { "pldl1keep", B(0, 1, 0) },
359 1.1 christos { "pldl1strm", B(0, 1, 1) },
360 1.1 christos { "pldl2keep", B(0, 2, 0) },
361 1.1 christos { "pldl2strm", B(0, 2, 1) },
362 1.1 christos { "pldl3keep", B(0, 3, 0) },
363 1.1 christos { "pldl3strm", B(0, 3, 1) },
364 1.1 christos { NULL, 0x06 },
365 1.1 christos { NULL, 0x07 },
366 1.1 christos { "plil1keep", B(1, 1, 0) },
367 1.1 christos { "plil1strm", B(1, 1, 1) },
368 1.1 christos { "plil2keep", B(1, 2, 0) },
369 1.1 christos { "plil2strm", B(1, 2, 1) },
370 1.1 christos { "plil3keep", B(1, 3, 0) },
371 1.1 christos { "plil3strm", B(1, 3, 1) },
372 1.1 christos { NULL, 0x0e },
373 1.1 christos { NULL, 0x0f },
374 1.1 christos { "pstl1keep", B(2, 1, 0) },
375 1.1 christos { "pstl1strm", B(2, 1, 1) },
376 1.1 christos { "pstl2keep", B(2, 2, 0) },
377 1.1 christos { "pstl2strm", B(2, 2, 1) },
378 1.1 christos { "pstl3keep", B(2, 3, 0) },
379 1.1 christos { "pstl3strm", B(2, 3, 1) },
380 1.1 christos { NULL, 0x16 },
381 1.1 christos { NULL, 0x17 },
382 1.1 christos { NULL, 0x18 },
383 1.1 christos { NULL, 0x19 },
384 1.1 christos { NULL, 0x1a },
385 1.1 christos { NULL, 0x1b },
386 1.1 christos { NULL, 0x1c },
387 1.1 christos { NULL, 0x1d },
388 1.1 christos { NULL, 0x1e },
389 1.1 christos { NULL, 0x1f },
390 1.1 christos };
391 1.1 christos #undef B
392 1.1 christos
393 1.1 christos /* Utilities on value constraint. */
395 1.1 christos
396 1.1 christos static inline int
397 1.1 christos value_in_range_p (int64_t value, int low, int high)
398 1.1 christos {
399 1.1 christos return (value >= low && value <= high) ? 1 : 0;
400 1.1 christos }
401 1.1 christos
402 1.1 christos static inline int
403 1.1 christos value_aligned_p (int64_t value, int align)
404 1.1 christos {
405 1.1 christos return ((value & (align - 1)) == 0) ? 1 : 0;
406 1.1 christos }
407 1.1 christos
408 1.1 christos /* A signed value fits in a field. */
409 1.1 christos static inline int
410 1.1 christos value_fit_signed_field_p (int64_t value, unsigned width)
411 1.1 christos {
412 1.1 christos assert (width < 32);
413 1.1 christos if (width < sizeof (value) * 8)
414 1.1 christos {
415 1.1 christos int64_t lim = (int64_t)1 << (width - 1);
416 1.1 christos if (value >= -lim && value < lim)
417 1.1 christos return 1;
418 1.1 christos }
419 1.1 christos return 0;
420 1.1 christos }
421 1.1 christos
422 1.1 christos /* An unsigned value fits in a field. */
423 1.1 christos static inline int
424 1.1 christos value_fit_unsigned_field_p (int64_t value, unsigned width)
425 1.1 christos {
426 1.1 christos assert (width < 32);
427 1.1 christos if (width < sizeof (value) * 8)
428 1.1 christos {
429 1.1 christos int64_t lim = (int64_t)1 << width;
430 1.1 christos if (value >= 0 && value < lim)
431 1.1 christos return 1;
432 1.1 christos }
433 1.1 christos return 0;
434 1.1 christos }
435 1.1 christos
436 1.1 christos /* Return 1 if OPERAND is SP or WSP. */
437 1.1 christos int
438 1.1 christos aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
439 1.1 christos {
440 1.1 christos return ((aarch64_get_operand_class (operand->type)
441 1.1 christos == AARCH64_OPND_CLASS_INT_REG)
442 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type)
443 1.1 christos && operand->reg.regno == 31);
444 1.1 christos }
445 1.1 christos
446 1.1 christos /* Return 1 if OPERAND is XZR or WZP. */
447 1.1 christos int
448 1.1 christos aarch64_zero_register_p (const aarch64_opnd_info *operand)
449 1.1 christos {
450 1.1 christos return ((aarch64_get_operand_class (operand->type)
451 1.1 christos == AARCH64_OPND_CLASS_INT_REG)
452 1.1 christos && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
453 1.1 christos && operand->reg.regno == 31);
454 1.1 christos }
455 1.1 christos
456 1.1 christos /* Return true if the operand *OPERAND that has the operand code
457 1.1 christos OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
458 1.1 christos qualified by the qualifier TARGET. */
459 1.1 christos
460 1.1 christos static inline int
461 1.1 christos operand_also_qualified_p (const struct aarch64_opnd_info *operand,
462 1.1 christos aarch64_opnd_qualifier_t target)
463 1.1 christos {
464 1.1 christos switch (operand->qualifier)
465 1.1 christos {
466 1.1 christos case AARCH64_OPND_QLF_W:
467 1.1 christos if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
468 1.1 christos return 1;
469 1.1 christos break;
470 1.1 christos case AARCH64_OPND_QLF_X:
471 1.1 christos if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
472 1.1 christos return 1;
473 1.1 christos break;
474 1.1 christos case AARCH64_OPND_QLF_WSP:
475 1.1 christos if (target == AARCH64_OPND_QLF_W
476 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type))
477 1.1 christos return 1;
478 1.1 christos break;
479 1.1 christos case AARCH64_OPND_QLF_SP:
480 1.1 christos if (target == AARCH64_OPND_QLF_X
481 1.1 christos && operand_maybe_stack_pointer (aarch64_operands + operand->type))
482 1.1 christos return 1;
483 1.1 christos break;
484 1.1 christos default:
485 1.1 christos break;
486 1.1 christos }
487 1.1 christos
488 1.1 christos return 0;
489 1.1 christos }
490 1.1 christos
491 1.1 christos /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
492 1.1 christos for operand KNOWN_IDX, return the expected qualifier for operand IDX.
493 1.1 christos
494 1.1 christos Return NIL if more than one expected qualifiers are found. */
495 1.1 christos
496 1.1 christos aarch64_opnd_qualifier_t
497 1.1 christos aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
498 1.1 christos int idx,
499 1.1 christos const aarch64_opnd_qualifier_t known_qlf,
500 1.1 christos int known_idx)
501 1.1 christos {
502 1.1 christos int i, saved_i;
503 1.1 christos
504 1.1 christos /* Special case.
505 1.1 christos
506 1.1 christos When the known qualifier is NIL, we have to assume that there is only
507 1.1 christos one qualifier sequence in the *QSEQ_LIST and return the corresponding
508 1.1 christos qualifier directly. One scenario is that for instruction
509 1.1 christos PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
510 1.1 christos which has only one possible valid qualifier sequence
511 1.1 christos NIL, S_D
512 1.1 christos the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
513 1.1 christos determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
514 1.1 christos
515 1.1 christos Because the qualifier NIL has dual roles in the qualifier sequence:
516 1.1 christos it can mean no qualifier for the operand, or the qualifer sequence is
517 1.1 christos not in use (when all qualifiers in the sequence are NILs), we have to
518 1.1 christos handle this special case here. */
519 1.1 christos if (known_qlf == AARCH64_OPND_NIL)
520 1.1 christos {
521 1.1 christos assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
522 1.1 christos return qseq_list[0][idx];
523 1.1 christos }
524 1.1 christos
525 1.1 christos for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
526 1.1 christos {
527 1.1 christos if (qseq_list[i][known_idx] == known_qlf)
528 1.1 christos {
529 1.1 christos if (saved_i != -1)
530 1.1 christos /* More than one sequences are found to have KNOWN_QLF at
531 1.1 christos KNOWN_IDX. */
532 1.1 christos return AARCH64_OPND_NIL;
533 1.1 christos saved_i = i;
534 1.1 christos }
535 1.1 christos }
536 1.1 christos
537 1.1 christos return qseq_list[saved_i][idx];
538 1.1 christos }
539 1.1 christos
540 1.1 christos enum operand_qualifier_kind
541 1.1 christos {
542 1.1 christos OQK_NIL,
543 1.1 christos OQK_OPD_VARIANT,
544 1.1 christos OQK_VALUE_IN_RANGE,
545 1.1 christos OQK_MISC,
546 1.1 christos };
547 1.1 christos
548 1.1 christos /* Operand qualifier description. */
549 1.1 christos struct operand_qualifier_data
550 1.1 christos {
551 1.1 christos /* The usage of the three data fields depends on the qualifier kind. */
552 1.1 christos int data0;
553 1.1 christos int data1;
554 1.1 christos int data2;
555 1.1 christos /* Description. */
556 1.1 christos const char *desc;
557 1.1 christos /* Kind. */
558 1.1 christos enum operand_qualifier_kind kind;
559 1.1 christos };
560 1.1 christos
561 1.1 christos /* Indexed by the operand qualifier enumerators. */
562 1.1 christos struct operand_qualifier_data aarch64_opnd_qualifiers[] =
563 1.1 christos {
564 1.1 christos {0, 0, 0, "NIL", OQK_NIL},
565 1.1 christos
566 1.1 christos /* Operand variant qualifiers.
567 1.1 christos First 3 fields:
568 1.1 christos element size, number of elements and common value for encoding. */
569 1.1 christos
570 1.1 christos {4, 1, 0x0, "w", OQK_OPD_VARIANT},
571 1.1 christos {8, 1, 0x1, "x", OQK_OPD_VARIANT},
572 1.1 christos {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
573 1.1 christos {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
574 1.1 christos
575 1.1 christos {1, 1, 0x0, "b", OQK_OPD_VARIANT},
576 1.1 christos {2, 1, 0x1, "h", OQK_OPD_VARIANT},
577 1.1 christos {4, 1, 0x2, "s", OQK_OPD_VARIANT},
578 1.1 christos {8, 1, 0x3, "d", OQK_OPD_VARIANT},
579 1.1 christos {16, 1, 0x4, "q", OQK_OPD_VARIANT},
580 1.1 christos
581 1.1.1.2 christos {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
582 1.1 christos {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
583 1.1 christos {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
584 1.1 christos {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
585 1.1 christos {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
586 1.1 christos {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
587 1.1 christos {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
588 1.1 christos {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
589 1.1 christos {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
590 1.1 christos {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
591 1.1 christos
592 1.1 christos /* Qualifiers constraining the value range.
593 1.1 christos First 3 fields:
594 1.1 christos Lower bound, higher bound, unused. */
595 1.1 christos
596 1.1 christos {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
597 1.1 christos {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
598 1.1 christos {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
599 1.1 christos {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
600 1.1 christos {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
601 1.1 christos {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
602 1.1 christos
603 1.1 christos /* Qualifiers for miscellaneous purpose.
604 1.1 christos First 3 fields:
605 1.1 christos unused, unused and unused. */
606 1.1 christos
607 1.1 christos {0, 0, 0, "lsl", 0},
608 1.1 christos {0, 0, 0, "msl", 0},
609 1.1 christos
610 1.1 christos {0, 0, 0, "retrieving", 0},
611 1.1 christos };
612 1.1 christos
613 1.1 christos static inline bfd_boolean
614 1.1 christos operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
615 1.1 christos {
616 1.1 christos return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
617 1.1 christos ? TRUE : FALSE;
618 1.1 christos }
619 1.1 christos
620 1.1 christos static inline bfd_boolean
621 1.1 christos qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
622 1.1 christos {
623 1.1 christos return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
624 1.1 christos ? TRUE : FALSE;
625 1.1 christos }
626 1.1 christos
627 1.1 christos const char*
628 1.1 christos aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
629 1.1 christos {
630 1.1 christos return aarch64_opnd_qualifiers[qualifier].desc;
631 1.1 christos }
632 1.1 christos
633 1.1 christos /* Given an operand qualifier, return the expected data element size
634 1.1 christos of a qualified operand. */
635 1.1 christos unsigned char
636 1.1 christos aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
637 1.1 christos {
638 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
639 1.1 christos return aarch64_opnd_qualifiers[qualifier].data0;
640 1.1 christos }
641 1.1 christos
642 1.1 christos unsigned char
643 1.1 christos aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
644 1.1 christos {
645 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
646 1.1 christos return aarch64_opnd_qualifiers[qualifier].data1;
647 1.1 christos }
648 1.1 christos
649 1.1 christos aarch64_insn
650 1.1 christos aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
651 1.1 christos {
652 1.1 christos assert (operand_variant_qualifier_p (qualifier) == TRUE);
653 1.1 christos return aarch64_opnd_qualifiers[qualifier].data2;
654 1.1 christos }
655 1.1 christos
656 1.1 christos static int
657 1.1 christos get_lower_bound (aarch64_opnd_qualifier_t qualifier)
658 1.1 christos {
659 1.1 christos assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
660 1.1 christos return aarch64_opnd_qualifiers[qualifier].data0;
661 1.1 christos }
662 1.1 christos
663 1.1 christos static int
664 1.1 christos get_upper_bound (aarch64_opnd_qualifier_t qualifier)
665 1.1 christos {
666 1.1 christos assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
667 1.1 christos return aarch64_opnd_qualifiers[qualifier].data1;
668 1.1 christos }
669 1.1 christos
670 1.1 christos #ifdef DEBUG_AARCH64
671 1.1 christos void
672 1.1 christos aarch64_verbose (const char *str, ...)
673 1.1 christos {
674 1.1 christos va_list ap;
675 1.1 christos va_start (ap, str);
676 1.1 christos printf ("#### ");
677 1.1 christos vprintf (str, ap);
678 1.1 christos printf ("\n");
679 1.1 christos va_end (ap);
680 1.1 christos }
681 1.1 christos
682 1.1 christos static inline void
683 1.1 christos dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
684 1.1 christos {
685 1.1 christos int i;
686 1.1 christos printf ("#### \t");
687 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
688 1.1 christos printf ("%s,", aarch64_get_qualifier_name (*qualifier));
689 1.1 christos printf ("\n");
690 1.1 christos }
691 1.1 christos
692 1.1 christos static void
693 1.1 christos dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
694 1.1 christos const aarch64_opnd_qualifier_t *qualifier)
695 1.1 christos {
696 1.1 christos int i;
697 1.1 christos aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
698 1.1 christos
699 1.1 christos aarch64_verbose ("dump_match_qualifiers:");
700 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
701 1.1 christos curr[i] = opnd[i].qualifier;
702 1.1 christos dump_qualifier_sequence (curr);
703 1.1 christos aarch64_verbose ("against");
704 1.1 christos dump_qualifier_sequence (qualifier);
705 1.1 christos }
706 1.1 christos #endif /* DEBUG_AARCH64 */
707 1.1 christos
708 1.1 christos /* TODO improve this, we can have an extra field at the runtime to
709 1.1 christos store the number of operands rather than calculating it every time. */
710 1.1 christos
711 1.1 christos int
712 1.1 christos aarch64_num_of_operands (const aarch64_opcode *opcode)
713 1.1 christos {
714 1.1 christos int i = 0;
715 1.1 christos const enum aarch64_opnd *opnds = opcode->operands;
716 1.1 christos while (opnds[i++] != AARCH64_OPND_NIL)
717 1.1 christos ;
718 1.1 christos --i;
719 1.1 christos assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
720 1.1 christos return i;
721 1.1 christos }
722 1.1 christos
723 1.1 christos /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
724 1.1 christos If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
725 1.1 christos
726 1.1 christos N.B. on the entry, it is very likely that only some operands in *INST
727 1.1 christos have had their qualifiers been established.
728 1.1 christos
729 1.1 christos If STOP_AT is not -1, the function will only try to match
730 1.1 christos the qualifier sequence for operands before and including the operand
731 1.1 christos of index STOP_AT; and on success *RET will only be filled with the first
732 1.1 christos (STOP_AT+1) qualifiers.
733 1.1 christos
734 1.1 christos A couple examples of the matching algorithm:
735 1.1 christos
736 1.1 christos X,W,NIL should match
737 1.1 christos X,W,NIL
738 1.1 christos
739 1.1 christos NIL,NIL should match
740 1.1 christos X ,NIL
741 1.1 christos
742 1.1 christos Apart from serving the main encoding routine, this can also be called
743 1.1 christos during or after the operand decoding. */
744 1.1 christos
745 1.1 christos int
746 1.1 christos aarch64_find_best_match (const aarch64_inst *inst,
747 1.1 christos const aarch64_opnd_qualifier_seq_t *qualifiers_list,
748 1.1 christos int stop_at, aarch64_opnd_qualifier_t *ret)
749 1.1 christos {
750 1.1 christos int found = 0;
751 1.1 christos int i, num_opnds;
752 1.1 christos const aarch64_opnd_qualifier_t *qualifiers;
753 1.1 christos
754 1.1 christos num_opnds = aarch64_num_of_operands (inst->opcode);
755 1.1 christos if (num_opnds == 0)
756 1.1 christos {
757 1.1 christos DEBUG_TRACE ("SUCCEED: no operand");
758 1.1 christos return 1;
759 1.1 christos }
760 1.1 christos
761 1.1 christos if (stop_at < 0 || stop_at >= num_opnds)
762 1.1 christos stop_at = num_opnds - 1;
763 1.1 christos
764 1.1 christos /* For each pattern. */
765 1.1 christos for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
766 1.1 christos {
767 1.1 christos int j;
768 1.1 christos qualifiers = *qualifiers_list;
769 1.1 christos
770 1.1 christos /* Start as positive. */
771 1.1 christos found = 1;
772 1.1 christos
773 1.1 christos DEBUG_TRACE ("%d", i);
774 1.1 christos #ifdef DEBUG_AARCH64
775 1.1 christos if (debug_dump)
776 1.1 christos dump_match_qualifiers (inst->operands, qualifiers);
777 1.1 christos #endif
778 1.1 christos
779 1.1 christos /* Most opcodes has much fewer patterns in the list.
780 1.1 christos First NIL qualifier indicates the end in the list. */
781 1.1 christos if (empty_qualifier_sequence_p (qualifiers) == TRUE)
782 1.1 christos {
783 1.1 christos DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
784 1.1 christos if (i)
785 1.1 christos found = 0;
786 1.1 christos break;
787 1.1 christos }
788 1.1 christos
789 1.1 christos for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
790 1.1 christos {
791 1.1 christos if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
792 1.1 christos {
793 1.1 christos /* Either the operand does not have qualifier, or the qualifier
794 1.1 christos for the operand needs to be deduced from the qualifier
795 1.1 christos sequence.
796 1.1 christos In the latter case, any constraint checking related with
797 1.1 christos the obtained qualifier should be done later in
798 1.1 christos operand_general_constraint_met_p. */
799 1.1 christos continue;
800 1.1 christos }
801 1.1 christos else if (*qualifiers != inst->operands[j].qualifier)
802 1.1 christos {
803 1.1 christos /* Unless the target qualifier can also qualify the operand
804 1.1 christos (which has already had a non-nil qualifier), non-equal
805 1.1 christos qualifiers are generally un-matched. */
806 1.1 christos if (operand_also_qualified_p (inst->operands + j, *qualifiers))
807 1.1 christos continue;
808 1.1 christos else
809 1.1 christos {
810 1.1 christos found = 0;
811 1.1 christos break;
812 1.1 christos }
813 1.1 christos }
814 1.1 christos else
815 1.1 christos continue; /* Equal qualifiers are certainly matched. */
816 1.1 christos }
817 1.1 christos
818 1.1 christos /* Qualifiers established. */
819 1.1 christos if (found == 1)
820 1.1 christos break;
821 1.1 christos }
822 1.1 christos
823 1.1 christos if (found == 1)
824 1.1 christos {
825 1.1 christos /* Fill the result in *RET. */
826 1.1 christos int j;
827 1.1 christos qualifiers = *qualifiers_list;
828 1.1 christos
829 1.1 christos DEBUG_TRACE ("complete qualifiers using list %d", i);
830 1.1 christos #ifdef DEBUG_AARCH64
831 1.1 christos if (debug_dump)
832 1.1 christos dump_qualifier_sequence (qualifiers);
833 1.1 christos #endif
834 1.1 christos
835 1.1 christos for (j = 0; j <= stop_at; ++j, ++qualifiers)
836 1.1 christos ret[j] = *qualifiers;
837 1.1 christos for (; j < AARCH64_MAX_OPND_NUM; ++j)
838 1.1 christos ret[j] = AARCH64_OPND_QLF_NIL;
839 1.1 christos
840 1.1 christos DEBUG_TRACE ("SUCCESS");
841 1.1 christos return 1;
842 1.1 christos }
843 1.1 christos
844 1.1 christos DEBUG_TRACE ("FAIL");
845 1.1 christos return 0;
846 1.1 christos }
847 1.1 christos
848 1.1 christos /* Operand qualifier matching and resolving.
849 1.1 christos
850 1.1 christos Return 1 if the operand qualifier(s) in *INST match one of the qualifier
851 1.1 christos sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
852 1.1 christos
853 1.1 christos if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
854 1.1 christos succeeds. */
855 1.1 christos
856 1.1 christos static int
857 1.1 christos match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
858 1.1 christos {
859 1.1 christos int i;
860 1.1 christos aarch64_opnd_qualifier_seq_t qualifiers;
861 1.1 christos
862 1.1 christos if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
863 1.1 christos qualifiers))
864 1.1 christos {
865 1.1 christos DEBUG_TRACE ("matching FAIL");
866 1.1 christos return 0;
867 1.1 christos }
868 1.1 christos
869 1.1 christos /* Update the qualifiers. */
870 1.1 christos if (update_p == TRUE)
871 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
872 1.1 christos {
873 1.1 christos if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
874 1.1 christos break;
875 1.1 christos DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
876 1.1 christos "update %s with %s for operand %d",
877 1.1 christos aarch64_get_qualifier_name (inst->operands[i].qualifier),
878 1.1 christos aarch64_get_qualifier_name (qualifiers[i]), i);
879 1.1 christos inst->operands[i].qualifier = qualifiers[i];
880 1.1 christos }
881 1.1 christos
882 1.1 christos DEBUG_TRACE ("matching SUCCESS");
883 1.1 christos return 1;
884 1.1 christos }
885 1.1 christos
886 1.1 christos /* Return TRUE if VALUE is a wide constant that can be moved into a general
887 1.1 christos register by MOVZ.
888 1.1 christos
889 1.1 christos IS32 indicates whether value is a 32-bit immediate or not.
890 1.1 christos If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
891 1.1 christos amount will be returned in *SHIFT_AMOUNT. */
892 1.1 christos
893 1.1 christos bfd_boolean
894 1.1 christos aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
895 1.1 christos {
896 1.1 christos int amount;
897 1.1 christos
898 1.1 christos DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
899 1.1 christos
900 1.1 christos if (is32)
901 1.1 christos {
902 1.1 christos /* Allow all zeros or all ones in top 32-bits, so that
903 1.1 christos 32-bit constant expressions like ~0x80000000 are
904 1.1 christos permitted. */
905 1.1 christos uint64_t ext = value;
906 1.1 christos if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
907 1.1 christos /* Immediate out of range. */
908 1.1 christos return FALSE;
909 1.1 christos value &= (int64_t) 0xffffffff;
910 1.1 christos }
911 1.1 christos
912 1.1 christos /* first, try movz then movn */
913 1.1 christos amount = -1;
914 1.1 christos if ((value & ((int64_t) 0xffff << 0)) == value)
915 1.1 christos amount = 0;
916 1.1 christos else if ((value & ((int64_t) 0xffff << 16)) == value)
917 1.1 christos amount = 16;
918 1.1 christos else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
919 1.1 christos amount = 32;
920 1.1 christos else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
921 1.1 christos amount = 48;
922 1.1 christos
923 1.1 christos if (amount == -1)
924 1.1 christos {
925 1.1 christos DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
926 1.1 christos return FALSE;
927 1.1 christos }
928 1.1 christos
929 1.1 christos if (shift_amount != NULL)
930 1.1 christos *shift_amount = amount;
931 1.1 christos
932 1.1 christos DEBUG_TRACE ("exit TRUE with amount %d", amount);
933 1.1 christos
934 1.1 christos return TRUE;
935 1.1 christos }
936 1.1 christos
937 1.1 christos /* Build the accepted values for immediate logical SIMD instructions.
938 1.1 christos
939 1.1 christos The standard encodings of the immediate value are:
940 1.1 christos N imms immr SIMD size R S
941 1.1 christos 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
942 1.1 christos 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
943 1.1 christos 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
944 1.1 christos 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
945 1.1 christos 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
946 1.1 christos 0 11110s 00000r 2 UInt(r) UInt(s)
947 1.1 christos where all-ones value of S is reserved.
948 1.1 christos
949 1.1 christos Let's call E the SIMD size.
950 1.1 christos
951 1.1 christos The immediate value is: S+1 bits '1' rotated to the right by R.
952 1.1 christos
953 1.1 christos The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
954 1.1 christos (remember S != E - 1). */
955 1.1 christos
956 1.1 christos #define TOTAL_IMM_NB 5334
957 1.1 christos
958 1.1 christos typedef struct
959 1.1 christos {
960 1.1 christos uint64_t imm;
961 1.1 christos aarch64_insn encoding;
962 1.1 christos } simd_imm_encoding;
963 1.1 christos
964 1.1 christos static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
965 1.1 christos
966 1.1 christos static int
967 1.1 christos simd_imm_encoding_cmp(const void *i1, const void *i2)
968 1.1 christos {
969 1.1 christos const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
970 1.1 christos const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
971 1.1 christos
972 1.1 christos if (imm1->imm < imm2->imm)
973 1.1 christos return -1;
974 1.1 christos if (imm1->imm > imm2->imm)
975 1.1 christos return +1;
976 1.1 christos return 0;
977 1.1 christos }
978 1.1 christos
979 1.1 christos /* immediate bitfield standard encoding
980 1.1 christos imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
981 1.1 christos 1 ssssss rrrrrr 64 rrrrrr ssssss
982 1.1 christos 0 0sssss 0rrrrr 32 rrrrr sssss
983 1.1 christos 0 10ssss 00rrrr 16 rrrr ssss
984 1.1 christos 0 110sss 000rrr 8 rrr sss
985 1.1 christos 0 1110ss 0000rr 4 rr ss
986 1.1 christos 0 11110s 00000r 2 r s */
987 1.1 christos static inline int
988 1.1 christos encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
989 1.1 christos {
990 1.1 christos return (is64 << 12) | (r << 6) | s;
991 1.1 christos }
992 1.1 christos
993 1.1 christos static void
994 1.1 christos build_immediate_table (void)
995 1.1 christos {
996 1.1 christos uint32_t log_e, e, s, r, s_mask;
997 1.1 christos uint64_t mask, imm;
998 1.1 christos int nb_imms;
999 1.1 christos int is64;
1000 1.1 christos
1001 1.1 christos nb_imms = 0;
1002 1.1 christos for (log_e = 1; log_e <= 6; log_e++)
1003 1.1 christos {
1004 1.1 christos /* Get element size. */
1005 1.1 christos e = 1u << log_e;
1006 1.1 christos if (log_e == 6)
1007 1.1 christos {
1008 1.1 christos is64 = 1;
1009 1.1 christos mask = 0xffffffffffffffffull;
1010 1.1 christos s_mask = 0;
1011 1.1 christos }
1012 1.1 christos else
1013 1.1 christos {
1014 1.1 christos is64 = 0;
1015 1.1 christos mask = (1ull << e) - 1;
1016 1.1 christos /* log_e s_mask
1017 1.1 christos 1 ((1 << 4) - 1) << 2 = 111100
1018 1.1 christos 2 ((1 << 3) - 1) << 3 = 111000
1019 1.1 christos 3 ((1 << 2) - 1) << 4 = 110000
1020 1.1 christos 4 ((1 << 1) - 1) << 5 = 100000
1021 1.1 christos 5 ((1 << 0) - 1) << 6 = 000000 */
1022 1.1 christos s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1023 1.1 christos }
1024 1.1 christos for (s = 0; s < e - 1; s++)
1025 1.1 christos for (r = 0; r < e; r++)
1026 1.1 christos {
1027 1.1 christos /* s+1 consecutive bits to 1 (s < 63) */
1028 1.1 christos imm = (1ull << (s + 1)) - 1;
1029 1.1 christos /* rotate right by r */
1030 1.1 christos if (r != 0)
1031 1.1 christos imm = (imm >> r) | ((imm << (e - r)) & mask);
1032 1.1 christos /* replicate the constant depending on SIMD size */
1033 1.1 christos switch (log_e)
1034 1.1 christos {
1035 1.1 christos case 1: imm = (imm << 2) | imm;
1036 1.1 christos case 2: imm = (imm << 4) | imm;
1037 1.1 christos case 3: imm = (imm << 8) | imm;
1038 1.1 christos case 4: imm = (imm << 16) | imm;
1039 1.1 christos case 5: imm = (imm << 32) | imm;
1040 1.1 christos case 6: break;
1041 1.1 christos default: abort ();
1042 1.1 christos }
1043 1.1 christos simd_immediates[nb_imms].imm = imm;
1044 1.1 christos simd_immediates[nb_imms].encoding =
1045 1.1 christos encode_immediate_bitfield(is64, s | s_mask, r);
1046 1.1 christos nb_imms++;
1047 1.1 christos }
1048 1.1 christos }
1049 1.1 christos assert (nb_imms == TOTAL_IMM_NB);
1050 1.1 christos qsort(simd_immediates, nb_imms,
1051 1.1 christos sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1052 1.1 christos }
1053 1.1 christos
1054 1.1 christos /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1055 1.1 christos be accepted by logical (immediate) instructions
1056 1.1 christos e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1057 1.1 christos
1058 1.1 christos IS32 indicates whether or not VALUE is a 32-bit immediate.
1059 1.1 christos If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1060 1.1 christos VALUE will be returned in *ENCODING. */
1061 1.1 christos
1062 1.1 christos bfd_boolean
1063 1.1 christos aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
1064 1.1 christos {
1065 1.1 christos simd_imm_encoding imm_enc;
1066 1.1 christos const simd_imm_encoding *imm_encoding;
1067 1.1 christos static bfd_boolean initialized = FALSE;
1068 1.1 christos
1069 1.1 christos DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
1070 1.1 christos value, is32);
1071 1.1 christos
1072 1.1 christos if (initialized == FALSE)
1073 1.1 christos {
1074 1.1 christos build_immediate_table ();
1075 1.1 christos initialized = TRUE;
1076 1.1 christos }
1077 1.1 christos
1078 1.1 christos if (is32)
1079 1.1.1.2 christos {
1080 1.1 christos /* Allow all zeros or all ones in top 32-bits, so that
1081 1.1.1.2 christos constant expressions like ~1 are permitted. */
1082 1.1.1.2 christos if (value >> 32 != 0 && value >> 32 != 0xffffffff)
1083 1.1 christos return FALSE;
1084 1.1 christos
1085 1.1 christos /* Replicate the 32 lower bits to the 32 upper bits. */
1086 1.1 christos value &= 0xffffffff;
1087 1.1 christos value |= value << 32;
1088 1.1 christos }
1089 1.1 christos
1090 1.1 christos imm_enc.imm = value;
1091 1.1 christos imm_encoding = (const simd_imm_encoding *)
1092 1.1 christos bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1093 1.1 christos sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1094 1.1 christos if (imm_encoding == NULL)
1095 1.1 christos {
1096 1.1 christos DEBUG_TRACE ("exit with FALSE");
1097 1.1 christos return FALSE;
1098 1.1 christos }
1099 1.1 christos if (encoding != NULL)
1100 1.1 christos *encoding = imm_encoding->encoding;
1101 1.1 christos DEBUG_TRACE ("exit with TRUE");
1102 1.1 christos return TRUE;
1103 1.1 christos }
1104 1.1 christos
1105 1.1 christos /* If 64-bit immediate IMM is in the format of
1106 1.1 christos "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1107 1.1 christos where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1108 1.1 christos of value "abcdefgh". Otherwise return -1. */
1109 1.1 christos int
1110 1.1 christos aarch64_shrink_expanded_imm8 (uint64_t imm)
1111 1.1 christos {
1112 1.1 christos int i, ret;
1113 1.1 christos uint32_t byte;
1114 1.1 christos
1115 1.1 christos ret = 0;
1116 1.1 christos for (i = 0; i < 8; i++)
1117 1.1 christos {
1118 1.1 christos byte = (imm >> (8 * i)) & 0xff;
1119 1.1 christos if (byte == 0xff)
1120 1.1 christos ret |= 1 << i;
1121 1.1 christos else if (byte != 0x00)
1122 1.1 christos return -1;
1123 1.1 christos }
1124 1.1 christos return ret;
1125 1.1 christos }
1126 1.1 christos
1127 1.1 christos /* Utility inline functions for operand_general_constraint_met_p. */
1128 1.1 christos
1129 1.1 christos static inline void
1130 1.1 christos set_error (aarch64_operand_error *mismatch_detail,
1131 1.1 christos enum aarch64_operand_error_kind kind, int idx,
1132 1.1 christos const char* error)
1133 1.1 christos {
1134 1.1 christos if (mismatch_detail == NULL)
1135 1.1 christos return;
1136 1.1 christos mismatch_detail->kind = kind;
1137 1.1 christos mismatch_detail->index = idx;
1138 1.1 christos mismatch_detail->error = error;
1139 1.1 christos }
1140 1.1.1.2 christos
1141 1.1.1.2 christos static inline void
1142 1.1.1.2 christos set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1143 1.1.1.2 christos const char* error)
1144 1.1.1.2 christos {
1145 1.1.1.2 christos if (mismatch_detail == NULL)
1146 1.1.1.2 christos return;
1147 1.1.1.2 christos set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1148 1.1.1.2 christos }
1149 1.1 christos
1150 1.1 christos static inline void
1151 1.1 christos set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1152 1.1 christos int idx, int lower_bound, int upper_bound,
1153 1.1 christos const char* error)
1154 1.1 christos {
1155 1.1 christos if (mismatch_detail == NULL)
1156 1.1 christos return;
1157 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1158 1.1 christos mismatch_detail->data[0] = lower_bound;
1159 1.1 christos mismatch_detail->data[1] = upper_bound;
1160 1.1 christos }
1161 1.1 christos
1162 1.1 christos static inline void
1163 1.1 christos set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1164 1.1 christos int idx, int lower_bound, int upper_bound)
1165 1.1 christos {
1166 1.1 christos if (mismatch_detail == NULL)
1167 1.1 christos return;
1168 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1169 1.1 christos _("immediate value"));
1170 1.1 christos }
1171 1.1 christos
1172 1.1 christos static inline void
1173 1.1 christos set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1174 1.1 christos int idx, int lower_bound, int upper_bound)
1175 1.1 christos {
1176 1.1 christos if (mismatch_detail == NULL)
1177 1.1 christos return;
1178 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1179 1.1 christos _("immediate offset"));
1180 1.1 christos }
1181 1.1 christos
1182 1.1 christos static inline void
1183 1.1 christos set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1184 1.1 christos int idx, int lower_bound, int upper_bound)
1185 1.1 christos {
1186 1.1 christos if (mismatch_detail == NULL)
1187 1.1 christos return;
1188 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1189 1.1 christos _("register number"));
1190 1.1 christos }
1191 1.1 christos
1192 1.1 christos static inline void
1193 1.1 christos set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1194 1.1 christos int idx, int lower_bound, int upper_bound)
1195 1.1 christos {
1196 1.1 christos if (mismatch_detail == NULL)
1197 1.1 christos return;
1198 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1199 1.1 christos _("register element index"));
1200 1.1 christos }
1201 1.1 christos
1202 1.1 christos static inline void
1203 1.1 christos set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1204 1.1 christos int idx, int lower_bound, int upper_bound)
1205 1.1 christos {
1206 1.1 christos if (mismatch_detail == NULL)
1207 1.1 christos return;
1208 1.1 christos set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1209 1.1 christos _("shift amount"));
1210 1.1 christos }
1211 1.1 christos
1212 1.1 christos static inline void
1213 1.1 christos set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1214 1.1 christos int alignment)
1215 1.1 christos {
1216 1.1 christos if (mismatch_detail == NULL)
1217 1.1 christos return;
1218 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1219 1.1 christos mismatch_detail->data[0] = alignment;
1220 1.1 christos }
1221 1.1 christos
1222 1.1 christos static inline void
1223 1.1 christos set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1224 1.1 christos int expected_num)
1225 1.1 christos {
1226 1.1 christos if (mismatch_detail == NULL)
1227 1.1 christos return;
1228 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1229 1.1 christos mismatch_detail->data[0] = expected_num;
1230 1.1 christos }
1231 1.1 christos
1232 1.1 christos static inline void
1233 1.1 christos set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1234 1.1 christos const char* error)
1235 1.1 christos {
1236 1.1 christos if (mismatch_detail == NULL)
1237 1.1 christos return;
1238 1.1 christos set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1239 1.1 christos }
1240 1.1 christos
1241 1.1 christos /* General constraint checking based on operand code.
1242 1.1 christos
1243 1.1 christos Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1244 1.1 christos as the IDXth operand of opcode OPCODE. Otherwise return 0.
1245 1.1 christos
1246 1.1 christos This function has to be called after the qualifiers for all operands
1247 1.1 christos have been resolved.
1248 1.1 christos
1249 1.1 christos Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1250 1.1 christos i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1251 1.1 christos of error message during the disassembling where error message is not
1252 1.1 christos wanted. We avoid the dynamic construction of strings of error messages
1253 1.1 christos here (i.e. in libopcodes), as it is costly and complicated; instead, we
1254 1.1 christos use a combination of error code, static string and some integer data to
1255 1.1 christos represent an error. */
1256 1.1 christos
1257 1.1 christos static int
1258 1.1 christos operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1259 1.1 christos enum aarch64_opnd type,
1260 1.1 christos const aarch64_opcode *opcode,
1261 1.1 christos aarch64_operand_error *mismatch_detail)
1262 1.1 christos {
1263 1.1 christos unsigned num;
1264 1.1 christos unsigned char size;
1265 1.1 christos int64_t imm;
1266 1.1 christos const aarch64_opnd_info *opnd = opnds + idx;
1267 1.1 christos aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1268 1.1 christos
1269 1.1 christos assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1270 1.1 christos
1271 1.1 christos switch (aarch64_operands[type].op_class)
1272 1.1.1.2 christos {
1273 1.1.1.2 christos case AARCH64_OPND_CLASS_INT_REG:
1274 1.1.1.2 christos /* Check pair reg constraints for cas* instructions. */
1275 1.1.1.2 christos if (type == AARCH64_OPND_PAIRREG)
1276 1.1.1.2 christos {
1277 1.1.1.2 christos assert (idx == 1 || idx == 3);
1278 1.1.1.2 christos if (opnds[idx - 1].reg.regno % 2 != 0)
1279 1.1.1.2 christos {
1280 1.1.1.2 christos set_syntax_error (mismatch_detail, idx - 1,
1281 1.1.1.2 christos _("reg pair must start from even reg"));
1282 1.1.1.2 christos return 0;
1283 1.1.1.2 christos }
1284 1.1.1.2 christos if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1285 1.1.1.2 christos {
1286 1.1.1.2 christos set_syntax_error (mismatch_detail, idx,
1287 1.1.1.2 christos _("reg pair must be contiguous"));
1288 1.1.1.2 christos return 0;
1289 1.1.1.2 christos }
1290 1.1.1.2 christos break;
1291 1.1 christos }
1292 1.1 christos
1293 1.1 christos /* <Xt> may be optional in some IC and TLBI instructions. */
1294 1.1 christos if (type == AARCH64_OPND_Rt_SYS)
1295 1.1 christos {
1296 1.1.1.2 christos assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1297 1.1.1.2 christos == AARCH64_OPND_CLASS_SYSTEM));
1298 1.1 christos if (opnds[1].present
1299 1.1 christos && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1300 1.1 christos {
1301 1.1 christos set_other_error (mismatch_detail, idx, _("extraneous register"));
1302 1.1.1.2 christos return 0;
1303 1.1.1.2 christos }
1304 1.1 christos if (!opnds[1].present
1305 1.1 christos && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1306 1.1 christos {
1307 1.1 christos set_other_error (mismatch_detail, idx, _("missing register"));
1308 1.1 christos return 0;
1309 1.1 christos }
1310 1.1 christos }
1311 1.1 christos switch (qualifier)
1312 1.1 christos {
1313 1.1 christos case AARCH64_OPND_QLF_WSP:
1314 1.1 christos case AARCH64_OPND_QLF_SP:
1315 1.1 christos if (!aarch64_stack_pointer_p (opnd))
1316 1.1 christos {
1317 1.1 christos set_other_error (mismatch_detail, idx,
1318 1.1 christos _("stack pointer register expected"));
1319 1.1 christos return 0;
1320 1.1 christos }
1321 1.1 christos break;
1322 1.1 christos default:
1323 1.1 christos break;
1324 1.1 christos }
1325 1.1.1.2 christos break;
1326 1.1.1.2 christos
1327 1.1.1.2 christos case AARCH64_OPND_CLASS_COND:
1328 1.1.1.2 christos if (type == AARCH64_OPND_COND1
1329 1.1.1.2 christos && (opnds[idx].cond->value & 0xe) == 0xe)
1330 1.1.1.2 christos {
1331 1.1.1.2 christos /* Not allow AL or NV. */
1332 1.1.1.2 christos set_syntax_error (mismatch_detail, idx, NULL);
1333 1.1.1.2 christos }
1334 1.1 christos break;
1335 1.1 christos
1336 1.1 christos case AARCH64_OPND_CLASS_ADDRESS:
1337 1.1 christos /* Check writeback. */
1338 1.1 christos switch (opcode->iclass)
1339 1.1 christos {
1340 1.1 christos case ldst_pos:
1341 1.1 christos case ldst_unscaled:
1342 1.1 christos case ldstnapair_offs:
1343 1.1 christos case ldstpair_off:
1344 1.1 christos case ldst_unpriv:
1345 1.1.1.2 christos if (opnd->addr.writeback == 1)
1346 1.1.1.2 christos {
1347 1.1 christos set_syntax_error (mismatch_detail, idx,
1348 1.1 christos _("unexpected address writeback"));
1349 1.1 christos return 0;
1350 1.1 christos }
1351 1.1 christos break;
1352 1.1 christos case ldst_imm9:
1353 1.1 christos case ldstpair_indexed:
1354 1.1 christos case asisdlsep:
1355 1.1 christos case asisdlsop:
1356 1.1.1.2 christos if (opnd->addr.writeback == 0)
1357 1.1.1.2 christos {
1358 1.1 christos set_syntax_error (mismatch_detail, idx,
1359 1.1 christos _("address writeback expected"));
1360 1.1 christos return 0;
1361 1.1 christos }
1362 1.1 christos break;
1363 1.1 christos default:
1364 1.1 christos assert (opnd->addr.writeback == 0);
1365 1.1 christos break;
1366 1.1 christos }
1367 1.1 christos switch (type)
1368 1.1 christos {
1369 1.1 christos case AARCH64_OPND_ADDR_SIMM7:
1370 1.1 christos /* Scaled signed 7 bits immediate offset. */
1371 1.1 christos /* Get the size of the data element that is accessed, which may be
1372 1.1 christos different from that of the source register size,
1373 1.1 christos e.g. in strb/ldrb. */
1374 1.1 christos size = aarch64_get_qualifier_esize (opnd->qualifier);
1375 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1376 1.1 christos {
1377 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx,
1378 1.1 christos -64 * size, 63 * size);
1379 1.1 christos return 0;
1380 1.1 christos }
1381 1.1 christos if (!value_aligned_p (opnd->addr.offset.imm, size))
1382 1.1 christos {
1383 1.1 christos set_unaligned_error (mismatch_detail, idx, size);
1384 1.1 christos return 0;
1385 1.1 christos }
1386 1.1 christos break;
1387 1.1 christos case AARCH64_OPND_ADDR_SIMM9:
1388 1.1 christos /* Unscaled signed 9 bits immediate offset. */
1389 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1390 1.1 christos {
1391 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1392 1.1 christos return 0;
1393 1.1 christos }
1394 1.1 christos break;
1395 1.1 christos
1396 1.1 christos case AARCH64_OPND_ADDR_SIMM9_2:
1397 1.1 christos /* Unscaled signed 9 bits immediate offset, which has to be negative
1398 1.1 christos or unaligned. */
1399 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1400 1.1 christos if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1401 1.1 christos && !value_aligned_p (opnd->addr.offset.imm, size))
1402 1.1 christos || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1403 1.1 christos return 1;
1404 1.1 christos set_other_error (mismatch_detail, idx,
1405 1.1 christos _("negative or unaligned offset expected"));
1406 1.1 christos return 0;
1407 1.1 christos
1408 1.1 christos case AARCH64_OPND_SIMD_ADDR_POST:
1409 1.1 christos /* AdvSIMD load/store multiple structures, post-index. */
1410 1.1 christos assert (idx == 1);
1411 1.1 christos if (opnd->addr.offset.is_reg)
1412 1.1 christos {
1413 1.1 christos if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1414 1.1 christos return 1;
1415 1.1 christos else
1416 1.1 christos {
1417 1.1 christos set_other_error (mismatch_detail, idx,
1418 1.1 christos _("invalid register offset"));
1419 1.1 christos return 0;
1420 1.1 christos }
1421 1.1 christos }
1422 1.1 christos else
1423 1.1 christos {
1424 1.1 christos const aarch64_opnd_info *prev = &opnds[idx-1];
1425 1.1 christos unsigned num_bytes; /* total number of bytes transferred. */
1426 1.1 christos /* The opcode dependent area stores the number of elements in
1427 1.1 christos each structure to be loaded/stored. */
1428 1.1 christos int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1429 1.1 christos if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1430 1.1 christos /* Special handling of loading single structure to all lane. */
1431 1.1 christos num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1432 1.1 christos * aarch64_get_qualifier_esize (prev->qualifier);
1433 1.1 christos else
1434 1.1 christos num_bytes = prev->reglist.num_regs
1435 1.1 christos * aarch64_get_qualifier_esize (prev->qualifier)
1436 1.1 christos * aarch64_get_qualifier_nelem (prev->qualifier);
1437 1.1 christos if ((int) num_bytes != opnd->addr.offset.imm)
1438 1.1 christos {
1439 1.1 christos set_other_error (mismatch_detail, idx,
1440 1.1 christos _("invalid post-increment amount"));
1441 1.1 christos return 0;
1442 1.1 christos }
1443 1.1 christos }
1444 1.1 christos break;
1445 1.1 christos
1446 1.1 christos case AARCH64_OPND_ADDR_REGOFF:
1447 1.1 christos /* Get the size of the data element that is accessed, which may be
1448 1.1 christos different from that of the source register size,
1449 1.1 christos e.g. in strb/ldrb. */
1450 1.1 christos size = aarch64_get_qualifier_esize (opnd->qualifier);
1451 1.1 christos /* It is either no shift or shift by the binary logarithm of SIZE. */
1452 1.1 christos if (opnd->shifter.amount != 0
1453 1.1 christos && opnd->shifter.amount != (int)get_logsz (size))
1454 1.1 christos {
1455 1.1 christos set_other_error (mismatch_detail, idx,
1456 1.1 christos _("invalid shift amount"));
1457 1.1 christos return 0;
1458 1.1 christos }
1459 1.1 christos /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1460 1.1 christos operators. */
1461 1.1 christos switch (opnd->shifter.kind)
1462 1.1 christos {
1463 1.1 christos case AARCH64_MOD_UXTW:
1464 1.1 christos case AARCH64_MOD_LSL:
1465 1.1 christos case AARCH64_MOD_SXTW:
1466 1.1 christos case AARCH64_MOD_SXTX: break;
1467 1.1 christos default:
1468 1.1 christos set_other_error (mismatch_detail, idx,
1469 1.1 christos _("invalid extend/shift operator"));
1470 1.1 christos return 0;
1471 1.1 christos }
1472 1.1 christos break;
1473 1.1 christos
1474 1.1 christos case AARCH64_OPND_ADDR_UIMM12:
1475 1.1 christos imm = opnd->addr.offset.imm;
1476 1.1 christos /* Get the size of the data element that is accessed, which may be
1477 1.1 christos different from that of the source register size,
1478 1.1 christos e.g. in strb/ldrb. */
1479 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1480 1.1 christos if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1481 1.1 christos {
1482 1.1 christos set_offset_out_of_range_error (mismatch_detail, idx,
1483 1.1 christos 0, 4095 * size);
1484 1.1 christos return 0;
1485 1.1 christos }
1486 1.1 christos if (!value_aligned_p (opnd->addr.offset.imm, size))
1487 1.1 christos {
1488 1.1 christos set_unaligned_error (mismatch_detail, idx, size);
1489 1.1 christos return 0;
1490 1.1 christos }
1491 1.1 christos break;
1492 1.1 christos
1493 1.1 christos case AARCH64_OPND_ADDR_PCREL14:
1494 1.1 christos case AARCH64_OPND_ADDR_PCREL19:
1495 1.1 christos case AARCH64_OPND_ADDR_PCREL21:
1496 1.1 christos case AARCH64_OPND_ADDR_PCREL26:
1497 1.1 christos imm = opnd->imm.value;
1498 1.1 christos if (operand_need_shift_by_two (get_operand_from_code (type)))
1499 1.1 christos {
1500 1.1 christos /* The offset value in a PC-relative branch instruction is alway
1501 1.1 christos 4-byte aligned and is encoded without the lowest 2 bits. */
1502 1.1 christos if (!value_aligned_p (imm, 4))
1503 1.1 christos {
1504 1.1 christos set_unaligned_error (mismatch_detail, idx, 4);
1505 1.1 christos return 0;
1506 1.1 christos }
1507 1.1 christos /* Right shift by 2 so that we can carry out the following check
1508 1.1 christos canonically. */
1509 1.1 christos imm >>= 2;
1510 1.1 christos }
1511 1.1 christos size = get_operand_fields_width (get_operand_from_code (type));
1512 1.1 christos if (!value_fit_signed_field_p (imm, size))
1513 1.1 christos {
1514 1.1 christos set_other_error (mismatch_detail, idx,
1515 1.1 christos _("immediate out of range"));
1516 1.1 christos return 0;
1517 1.1 christos }
1518 1.1 christos break;
1519 1.1 christos
1520 1.1 christos default:
1521 1.1 christos break;
1522 1.1 christos }
1523 1.1 christos break;
1524 1.1 christos
1525 1.1 christos case AARCH64_OPND_CLASS_SIMD_REGLIST:
1526 1.1 christos /* The opcode dependent area stores the number of elements in
1527 1.1 christos each structure to be loaded/stored. */
1528 1.1 christos num = get_opcode_dependent_value (opcode);
1529 1.1 christos switch (type)
1530 1.1 christos {
1531 1.1 christos case AARCH64_OPND_LVt:
1532 1.1 christos assert (num >= 1 && num <= 4);
1533 1.1 christos /* Unless LD1/ST1, the number of registers should be equal to that
1534 1.1 christos of the structure elements. */
1535 1.1 christos if (num != 1 && opnd->reglist.num_regs != num)
1536 1.1 christos {
1537 1.1 christos set_reg_list_error (mismatch_detail, idx, num);
1538 1.1 christos return 0;
1539 1.1 christos }
1540 1.1 christos break;
1541 1.1 christos case AARCH64_OPND_LVt_AL:
1542 1.1 christos case AARCH64_OPND_LEt:
1543 1.1 christos assert (num >= 1 && num <= 4);
1544 1.1 christos /* The number of registers should be equal to that of the structure
1545 1.1 christos elements. */
1546 1.1 christos if (opnd->reglist.num_regs != num)
1547 1.1 christos {
1548 1.1 christos set_reg_list_error (mismatch_detail, idx, num);
1549 1.1 christos return 0;
1550 1.1 christos }
1551 1.1 christos break;
1552 1.1 christos default:
1553 1.1 christos break;
1554 1.1 christos }
1555 1.1 christos break;
1556 1.1 christos
1557 1.1 christos case AARCH64_OPND_CLASS_IMMEDIATE:
1558 1.1 christos /* Constraint check on immediate operand. */
1559 1.1 christos imm = opnd->imm.value;
1560 1.1 christos /* E.g. imm_0_31 constrains value to be 0..31. */
1561 1.1 christos if (qualifier_value_in_range_constraint_p (qualifier)
1562 1.1 christos && !value_in_range_p (imm, get_lower_bound (qualifier),
1563 1.1 christos get_upper_bound (qualifier)))
1564 1.1 christos {
1565 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx,
1566 1.1 christos get_lower_bound (qualifier),
1567 1.1 christos get_upper_bound (qualifier));
1568 1.1 christos return 0;
1569 1.1 christos }
1570 1.1 christos
1571 1.1 christos switch (type)
1572 1.1 christos {
1573 1.1 christos case AARCH64_OPND_AIMM:
1574 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
1575 1.1 christos {
1576 1.1 christos set_other_error (mismatch_detail, idx,
1577 1.1 christos _("invalid shift operator"));
1578 1.1 christos return 0;
1579 1.1 christos }
1580 1.1 christos if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
1581 1.1 christos {
1582 1.1 christos set_other_error (mismatch_detail, idx,
1583 1.1 christos _("shift amount expected to be 0 or 12"));
1584 1.1 christos return 0;
1585 1.1 christos }
1586 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
1587 1.1 christos {
1588 1.1 christos set_other_error (mismatch_detail, idx,
1589 1.1 christos _("immediate out of range"));
1590 1.1 christos return 0;
1591 1.1 christos }
1592 1.1 christos break;
1593 1.1 christos
1594 1.1 christos case AARCH64_OPND_HALF:
1595 1.1 christos assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
1596 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
1597 1.1 christos {
1598 1.1 christos set_other_error (mismatch_detail, idx,
1599 1.1 christos _("invalid shift operator"));
1600 1.1 christos return 0;
1601 1.1 christos }
1602 1.1 christos size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1603 1.1 christos if (!value_aligned_p (opnd->shifter.amount, 16))
1604 1.1 christos {
1605 1.1 christos set_other_error (mismatch_detail, idx,
1606 1.1 christos _("shift amount should be a multiple of 16"));
1607 1.1 christos return 0;
1608 1.1 christos }
1609 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
1610 1.1 christos {
1611 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx,
1612 1.1 christos 0, size * 8 - 16);
1613 1.1 christos return 0;
1614 1.1 christos }
1615 1.1 christos if (opnd->imm.value < 0)
1616 1.1 christos {
1617 1.1 christos set_other_error (mismatch_detail, idx,
1618 1.1 christos _("negative immediate value not allowed"));
1619 1.1 christos return 0;
1620 1.1 christos }
1621 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
1622 1.1 christos {
1623 1.1 christos set_other_error (mismatch_detail, idx,
1624 1.1 christos _("immediate out of range"));
1625 1.1 christos return 0;
1626 1.1 christos }
1627 1.1 christos break;
1628 1.1 christos
1629 1.1 christos case AARCH64_OPND_IMM_MOV:
1630 1.1 christos {
1631 1.1 christos int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
1632 1.1 christos imm = opnd->imm.value;
1633 1.1 christos assert (idx == 1);
1634 1.1 christos switch (opcode->op)
1635 1.1 christos {
1636 1.1.1.2 christos case OP_MOV_IMM_WIDEN:
1637 1.1 christos imm = ~imm;
1638 1.1 christos /* Fall through... */
1639 1.1 christos case OP_MOV_IMM_WIDE:
1640 1.1 christos if (!aarch64_wide_constant_p (imm, is32, NULL))
1641 1.1 christos {
1642 1.1 christos set_other_error (mismatch_detail, idx,
1643 1.1 christos _("immediate out of range"));
1644 1.1 christos return 0;
1645 1.1 christos }
1646 1.1 christos break;
1647 1.1 christos case OP_MOV_IMM_LOG:
1648 1.1 christos if (!aarch64_logical_immediate_p (imm, is32, NULL))
1649 1.1 christos {
1650 1.1 christos set_other_error (mismatch_detail, idx,
1651 1.1 christos _("immediate out of range"));
1652 1.1 christos return 0;
1653 1.1 christos }
1654 1.1 christos break;
1655 1.1 christos default:
1656 1.1 christos assert (0);
1657 1.1 christos return 0;
1658 1.1 christos }
1659 1.1 christos }
1660 1.1 christos break;
1661 1.1 christos
1662 1.1 christos case AARCH64_OPND_NZCV:
1663 1.1 christos case AARCH64_OPND_CCMP_IMM:
1664 1.1 christos case AARCH64_OPND_EXCEPTION:
1665 1.1 christos case AARCH64_OPND_UIMM4:
1666 1.1 christos case AARCH64_OPND_UIMM7:
1667 1.1 christos case AARCH64_OPND_UIMM3_OP1:
1668 1.1 christos case AARCH64_OPND_UIMM3_OP2:
1669 1.1 christos size = get_operand_fields_width (get_operand_from_code (type));
1670 1.1 christos assert (size < 32);
1671 1.1 christos if (!value_fit_unsigned_field_p (opnd->imm.value, size))
1672 1.1 christos {
1673 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0,
1674 1.1 christos (1 << size) - 1);
1675 1.1 christos return 0;
1676 1.1 christos }
1677 1.1 christos break;
1678 1.1.1.2 christos
1679 1.1 christos case AARCH64_OPND_WIDTH:
1680 1.1 christos assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
1681 1.1 christos && opnds[0].type == AARCH64_OPND_Rd);
1682 1.1 christos size = get_upper_bound (qualifier);
1683 1.1 christos if (opnd->imm.value + opnds[idx-1].imm.value > size)
1684 1.1 christos /* lsb+width <= reg.size */
1685 1.1 christos {
1686 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 1,
1687 1.1 christos size - opnds[idx-1].imm.value);
1688 1.1 christos return 0;
1689 1.1 christos }
1690 1.1 christos break;
1691 1.1 christos
1692 1.1 christos case AARCH64_OPND_LIMM:
1693 1.1 christos {
1694 1.1 christos int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
1695 1.1 christos uint64_t uimm = opnd->imm.value;
1696 1.1 christos if (opcode->op == OP_BIC)
1697 1.1 christos uimm = ~uimm;
1698 1.1 christos if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
1699 1.1 christos {
1700 1.1 christos set_other_error (mismatch_detail, idx,
1701 1.1 christos _("immediate out of range"));
1702 1.1 christos return 0;
1703 1.1 christos }
1704 1.1 christos }
1705 1.1 christos break;
1706 1.1 christos
1707 1.1 christos case AARCH64_OPND_IMM0:
1708 1.1 christos case AARCH64_OPND_FPIMM0:
1709 1.1 christos if (opnd->imm.value != 0)
1710 1.1 christos {
1711 1.1 christos set_other_error (mismatch_detail, idx,
1712 1.1 christos _("immediate zero expected"));
1713 1.1 christos return 0;
1714 1.1 christos }
1715 1.1 christos break;
1716 1.1 christos
1717 1.1 christos case AARCH64_OPND_SHLL_IMM:
1718 1.1 christos assert (idx == 2);
1719 1.1 christos size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
1720 1.1 christos if (opnd->imm.value != size)
1721 1.1 christos {
1722 1.1 christos set_other_error (mismatch_detail, idx,
1723 1.1 christos _("invalid shift amount"));
1724 1.1 christos return 0;
1725 1.1 christos }
1726 1.1 christos break;
1727 1.1 christos
1728 1.1 christos case AARCH64_OPND_IMM_VLSL:
1729 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1730 1.1 christos if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
1731 1.1 christos {
1732 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0,
1733 1.1 christos size * 8 - 1);
1734 1.1 christos return 0;
1735 1.1 christos }
1736 1.1 christos break;
1737 1.1 christos
1738 1.1 christos case AARCH64_OPND_IMM_VLSR:
1739 1.1 christos size = aarch64_get_qualifier_esize (qualifier);
1740 1.1 christos if (!value_in_range_p (opnd->imm.value, 1, size * 8))
1741 1.1 christos {
1742 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
1743 1.1 christos return 0;
1744 1.1 christos }
1745 1.1 christos break;
1746 1.1 christos
1747 1.1 christos case AARCH64_OPND_SIMD_IMM:
1748 1.1 christos case AARCH64_OPND_SIMD_IMM_SFT:
1749 1.1 christos /* Qualifier check. */
1750 1.1 christos switch (qualifier)
1751 1.1 christos {
1752 1.1 christos case AARCH64_OPND_QLF_LSL:
1753 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_LSL)
1754 1.1 christos {
1755 1.1 christos set_other_error (mismatch_detail, idx,
1756 1.1 christos _("invalid shift operator"));
1757 1.1 christos return 0;
1758 1.1 christos }
1759 1.1 christos break;
1760 1.1 christos case AARCH64_OPND_QLF_MSL:
1761 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_MSL)
1762 1.1 christos {
1763 1.1 christos set_other_error (mismatch_detail, idx,
1764 1.1 christos _("invalid shift operator"));
1765 1.1 christos return 0;
1766 1.1 christos }
1767 1.1 christos break;
1768 1.1 christos case AARCH64_OPND_QLF_NIL:
1769 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
1770 1.1 christos {
1771 1.1 christos set_other_error (mismatch_detail, idx,
1772 1.1 christos _("shift is not permitted"));
1773 1.1 christos return 0;
1774 1.1 christos }
1775 1.1 christos break;
1776 1.1 christos default:
1777 1.1 christos assert (0);
1778 1.1 christos return 0;
1779 1.1 christos }
1780 1.1 christos /* Is the immediate valid? */
1781 1.1 christos assert (idx == 1);
1782 1.1.1.2 christos if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
1783 1.1.1.2 christos {
1784 1.1 christos /* uimm8 or simm8 */
1785 1.1.1.2 christos if (!value_in_range_p (opnd->imm.value, -128, 255))
1786 1.1 christos {
1787 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
1788 1.1 christos return 0;
1789 1.1 christos }
1790 1.1 christos }
1791 1.1 christos else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
1792 1.1 christos {
1793 1.1 christos /* uimm64 is not
1794 1.1 christos 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
1795 1.1 christos ffffffffgggggggghhhhhhhh'. */
1796 1.1 christos set_other_error (mismatch_detail, idx,
1797 1.1 christos _("invalid value for immediate"));
1798 1.1 christos return 0;
1799 1.1 christos }
1800 1.1 christos /* Is the shift amount valid? */
1801 1.1 christos switch (opnd->shifter.kind)
1802 1.1 christos {
1803 1.1.1.2 christos case AARCH64_MOD_LSL:
1804 1.1 christos size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1805 1.1.1.2 christos if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
1806 1.1.1.2 christos {
1807 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
1808 1.1 christos (size - 1) * 8);
1809 1.1.1.2 christos return 0;
1810 1.1 christos }
1811 1.1.1.2 christos if (!value_aligned_p (opnd->shifter.amount, 8))
1812 1.1 christos {
1813 1.1 christos set_unaligned_error (mismatch_detail, idx, 8);
1814 1.1 christos return 0;
1815 1.1 christos }
1816 1.1 christos break;
1817 1.1 christos case AARCH64_MOD_MSL:
1818 1.1 christos /* Only 8 and 16 are valid shift amount. */
1819 1.1 christos if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
1820 1.1 christos {
1821 1.1 christos set_other_error (mismatch_detail, idx,
1822 1.1 christos _("shift amount expected to be 0 or 16"));
1823 1.1 christos return 0;
1824 1.1 christos }
1825 1.1 christos break;
1826 1.1 christos default:
1827 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
1828 1.1 christos {
1829 1.1 christos set_other_error (mismatch_detail, idx,
1830 1.1 christos _("invalid shift operator"));
1831 1.1 christos return 0;
1832 1.1 christos }
1833 1.1 christos break;
1834 1.1 christos }
1835 1.1 christos break;
1836 1.1 christos
1837 1.1 christos case AARCH64_OPND_FPIMM:
1838 1.1 christos case AARCH64_OPND_SIMD_FPIMM:
1839 1.1 christos if (opnd->imm.is_fp == 0)
1840 1.1 christos {
1841 1.1 christos set_other_error (mismatch_detail, idx,
1842 1.1 christos _("floating-point immediate expected"));
1843 1.1 christos return 0;
1844 1.1 christos }
1845 1.1 christos /* The value is expected to be an 8-bit floating-point constant with
1846 1.1 christos sign, 3-bit exponent and normalized 4 bits of precision, encoded
1847 1.1 christos in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
1848 1.1 christos instruction). */
1849 1.1 christos if (!value_in_range_p (opnd->imm.value, 0, 255))
1850 1.1 christos {
1851 1.1 christos set_other_error (mismatch_detail, idx,
1852 1.1 christos _("immediate out of range"));
1853 1.1 christos return 0;
1854 1.1 christos }
1855 1.1 christos if (opnd->shifter.kind != AARCH64_MOD_NONE)
1856 1.1 christos {
1857 1.1 christos set_other_error (mismatch_detail, idx,
1858 1.1 christos _("invalid shift operator"));
1859 1.1 christos return 0;
1860 1.1 christos }
1861 1.1 christos break;
1862 1.1 christos
1863 1.1 christos default:
1864 1.1 christos break;
1865 1.1 christos }
1866 1.1 christos break;
1867 1.1 christos
1868 1.1 christos case AARCH64_OPND_CLASS_CP_REG:
1869 1.1 christos /* Cn or Cm: 4-bit opcode field named for historical reasons.
1870 1.1 christos valid range: C0 - C15. */
1871 1.1 christos if (opnd->reg.regno > 15)
1872 1.1 christos {
1873 1.1 christos set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1874 1.1 christos return 0;
1875 1.1 christos }
1876 1.1 christos break;
1877 1.1 christos
1878 1.1 christos case AARCH64_OPND_CLASS_SYSTEM:
1879 1.1 christos switch (type)
1880 1.1 christos {
1881 1.1 christos case AARCH64_OPND_PSTATEFIELD:
1882 1.1 christos assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
1883 1.1 christos /* MSR SPSel, #uimm4
1884 1.1 christos Uses uimm4 as a control value to select the stack pointer: if
1885 1.1 christos bit 0 is set it selects the current exception level's stack
1886 1.1 christos pointer, if bit 0 is clear it selects shared EL0 stack pointer.
1887 1.1 christos Bits 1 to 3 of uimm4 are reserved and should be zero. */
1888 1.1 christos if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
1889 1.1 christos {
1890 1.1 christos set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
1891 1.1 christos return 0;
1892 1.1 christos }
1893 1.1 christos break;
1894 1.1 christos default:
1895 1.1 christos break;
1896 1.1 christos }
1897 1.1 christos break;
1898 1.1 christos
1899 1.1 christos case AARCH64_OPND_CLASS_SIMD_ELEMENT:
1900 1.1 christos /* Get the upper bound for the element index. */
1901 1.1 christos num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
1902 1.1 christos /* Index out-of-range. */
1903 1.1 christos if (!value_in_range_p (opnd->reglane.index, 0, num))
1904 1.1 christos {
1905 1.1 christos set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
1906 1.1 christos return 0;
1907 1.1 christos }
1908 1.1 christos /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
1909 1.1 christos <Vm> Is the vector register (V0-V31) or (V0-V15), whose
1910 1.1 christos number is encoded in "size:M:Rm":
1911 1.1 christos size <Vm>
1912 1.1 christos 00 RESERVED
1913 1.1 christos 01 0:Rm
1914 1.1 christos 10 M:Rm
1915 1.1 christos 11 RESERVED */
1916 1.1 christos if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
1917 1.1 christos && !value_in_range_p (opnd->reglane.regno, 0, 15))
1918 1.1 christos {
1919 1.1 christos set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1920 1.1 christos return 0;
1921 1.1 christos }
1922 1.1 christos break;
1923 1.1 christos
1924 1.1 christos case AARCH64_OPND_CLASS_MODIFIED_REG:
1925 1.1 christos assert (idx == 1 || idx == 2);
1926 1.1 christos switch (type)
1927 1.1 christos {
1928 1.1 christos case AARCH64_OPND_Rm_EXT:
1929 1.1 christos if (aarch64_extend_operator_p (opnd->shifter.kind) == FALSE
1930 1.1 christos && opnd->shifter.kind != AARCH64_MOD_LSL)
1931 1.1 christos {
1932 1.1 christos set_other_error (mismatch_detail, idx,
1933 1.1 christos _("extend operator expected"));
1934 1.1 christos return 0;
1935 1.1 christos }
1936 1.1 christos /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
1937 1.1 christos (i.e. SP), in which case it defaults to LSL. The LSL alias is
1938 1.1 christos only valid when "Rd" or "Rn" is '11111', and is preferred in that
1939 1.1 christos case. */
1940 1.1 christos if (!aarch64_stack_pointer_p (opnds + 0)
1941 1.1 christos && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
1942 1.1 christos {
1943 1.1 christos if (!opnd->shifter.operator_present)
1944 1.1 christos {
1945 1.1 christos set_other_error (mismatch_detail, idx,
1946 1.1 christos _("missing extend operator"));
1947 1.1 christos return 0;
1948 1.1 christos }
1949 1.1 christos else if (opnd->shifter.kind == AARCH64_MOD_LSL)
1950 1.1 christos {
1951 1.1 christos set_other_error (mismatch_detail, idx,
1952 1.1 christos _("'LSL' operator not allowed"));
1953 1.1 christos return 0;
1954 1.1 christos }
1955 1.1 christos }
1956 1.1 christos assert (opnd->shifter.operator_present /* Default to LSL. */
1957 1.1 christos || opnd->shifter.kind == AARCH64_MOD_LSL);
1958 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, 4))
1959 1.1 christos {
1960 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
1961 1.1 christos return 0;
1962 1.1 christos }
1963 1.1 christos /* In the 64-bit form, the final register operand is written as Wm
1964 1.1 christos for all but the (possibly omitted) UXTX/LSL and SXTX
1965 1.1 christos operators.
1966 1.1 christos N.B. GAS allows X register to be used with any operator as a
1967 1.1 christos programming convenience. */
1968 1.1 christos if (qualifier == AARCH64_OPND_QLF_X
1969 1.1 christos && opnd->shifter.kind != AARCH64_MOD_LSL
1970 1.1 christos && opnd->shifter.kind != AARCH64_MOD_UXTX
1971 1.1 christos && opnd->shifter.kind != AARCH64_MOD_SXTX)
1972 1.1 christos {
1973 1.1 christos set_other_error (mismatch_detail, idx, _("W register expected"));
1974 1.1 christos return 0;
1975 1.1 christos }
1976 1.1 christos break;
1977 1.1 christos
1978 1.1 christos case AARCH64_OPND_Rm_SFT:
1979 1.1 christos /* ROR is not available to the shifted register operand in
1980 1.1 christos arithmetic instructions. */
1981 1.1 christos if (aarch64_shift_operator_p (opnd->shifter.kind) == FALSE)
1982 1.1 christos {
1983 1.1 christos set_other_error (mismatch_detail, idx,
1984 1.1 christos _("shift operator expected"));
1985 1.1 christos return 0;
1986 1.1 christos }
1987 1.1 christos if (opnd->shifter.kind == AARCH64_MOD_ROR
1988 1.1 christos && opcode->iclass != log_shift)
1989 1.1 christos {
1990 1.1 christos set_other_error (mismatch_detail, idx,
1991 1.1 christos _("'ROR' operator not allowed"));
1992 1.1 christos return 0;
1993 1.1 christos }
1994 1.1 christos num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
1995 1.1 christos if (!value_in_range_p (opnd->shifter.amount, 0, num))
1996 1.1 christos {
1997 1.1 christos set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
1998 1.1 christos return 0;
1999 1.1 christos }
2000 1.1 christos break;
2001 1.1 christos
2002 1.1 christos default:
2003 1.1 christos break;
2004 1.1 christos }
2005 1.1 christos break;
2006 1.1 christos
2007 1.1 christos default:
2008 1.1 christos break;
2009 1.1 christos }
2010 1.1 christos
2011 1.1 christos return 1;
2012 1.1 christos }
2013 1.1 christos
2014 1.1 christos /* Main entrypoint for the operand constraint checking.
2015 1.1 christos
2016 1.1 christos Return 1 if operands of *INST meet the constraint applied by the operand
2017 1.1 christos codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
2018 1.1 christos not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
2019 1.1 christos adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
2020 1.1 christos with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
2021 1.1 christos error kind when it is notified that an instruction does not pass the check).
2022 1.1 christos
2023 1.1 christos Un-determined operand qualifiers may get established during the process. */
2024 1.1 christos
2025 1.1 christos int
2026 1.1 christos aarch64_match_operands_constraint (aarch64_inst *inst,
2027 1.1 christos aarch64_operand_error *mismatch_detail)
2028 1.1 christos {
2029 1.1 christos int i;
2030 1.1 christos
2031 1.1 christos DEBUG_TRACE ("enter");
2032 1.1 christos
2033 1.1 christos /* Match operands' qualifier.
2034 1.1 christos *INST has already had qualifier establish for some, if not all, of
2035 1.1 christos its operands; we need to find out whether these established
2036 1.1 christos qualifiers match one of the qualifier sequence in
2037 1.1 christos INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
2038 1.1 christos with the corresponding qualifier in such a sequence.
2039 1.1 christos Only basic operand constraint checking is done here; the more thorough
2040 1.1 christos constraint checking will carried out by operand_general_constraint_met_p,
2041 1.1 christos which has be to called after this in order to get all of the operands'
2042 1.1 christos qualifiers established. */
2043 1.1 christos if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
2044 1.1 christos {
2045 1.1 christos DEBUG_TRACE ("FAIL on operand qualifier matching");
2046 1.1 christos if (mismatch_detail)
2047 1.1 christos {
2048 1.1 christos /* Return an error type to indicate that it is the qualifier
2049 1.1 christos matching failure; we don't care about which operand as there
2050 1.1 christos are enough information in the opcode table to reproduce it. */
2051 1.1 christos mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
2052 1.1 christos mismatch_detail->index = -1;
2053 1.1 christos mismatch_detail->error = NULL;
2054 1.1 christos }
2055 1.1 christos return 0;
2056 1.1 christos }
2057 1.1 christos
2058 1.1 christos /* Match operands' constraint. */
2059 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2060 1.1 christos {
2061 1.1 christos enum aarch64_opnd type = inst->opcode->operands[i];
2062 1.1 christos if (type == AARCH64_OPND_NIL)
2063 1.1 christos break;
2064 1.1 christos if (inst->operands[i].skip)
2065 1.1 christos {
2066 1.1 christos DEBUG_TRACE ("skip the incomplete operand %d", i);
2067 1.1 christos continue;
2068 1.1 christos }
2069 1.1 christos if (operand_general_constraint_met_p (inst->operands, i, type,
2070 1.1 christos inst->opcode, mismatch_detail) == 0)
2071 1.1 christos {
2072 1.1 christos DEBUG_TRACE ("FAIL on operand %d", i);
2073 1.1 christos return 0;
2074 1.1 christos }
2075 1.1 christos }
2076 1.1 christos
2077 1.1 christos DEBUG_TRACE ("PASS");
2078 1.1 christos
2079 1.1 christos return 1;
2080 1.1 christos }
2081 1.1 christos
2082 1.1 christos /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2083 1.1 christos Also updates the TYPE of each INST->OPERANDS with the corresponding
2084 1.1 christos value of OPCODE->OPERANDS.
2085 1.1 christos
2086 1.1 christos Note that some operand qualifiers may need to be manually cleared by
2087 1.1 christos the caller before it further calls the aarch64_opcode_encode; by
2088 1.1 christos doing this, it helps the qualifier matching facilities work
2089 1.1 christos properly. */
2090 1.1 christos
2091 1.1 christos const aarch64_opcode*
2092 1.1 christos aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2093 1.1 christos {
2094 1.1 christos int i;
2095 1.1 christos const aarch64_opcode *old = inst->opcode;
2096 1.1 christos
2097 1.1 christos inst->opcode = opcode;
2098 1.1 christos
2099 1.1 christos /* Update the operand types. */
2100 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2101 1.1 christos {
2102 1.1 christos inst->operands[i].type = opcode->operands[i];
2103 1.1 christos if (opcode->operands[i] == AARCH64_OPND_NIL)
2104 1.1 christos break;
2105 1.1 christos }
2106 1.1 christos
2107 1.1 christos DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2108 1.1 christos
2109 1.1 christos return old;
2110 1.1 christos }
2111 1.1 christos
2112 1.1 christos int
2113 1.1 christos aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2114 1.1 christos {
2115 1.1 christos int i;
2116 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2117 1.1 christos if (operands[i] == operand)
2118 1.1 christos return i;
2119 1.1 christos else if (operands[i] == AARCH64_OPND_NIL)
2120 1.1 christos break;
2121 1.1 christos return -1;
2122 1.1 christos }
2123 1.1 christos
2124 1.1 christos /* [0][0] 32-bit integer regs with sp Wn
2126 1.1 christos [0][1] 64-bit integer regs with sp Xn sf=1
2127 1.1 christos [1][0] 32-bit integer regs with #0 Wn
2128 1.1 christos [1][1] 64-bit integer regs with #0 Xn sf=1 */
2129 1.1 christos static const char *int_reg[2][2][32] = {
2130 1.1 christos #define R32 "w"
2131 1.1 christos #define R64 "x"
2132 1.1 christos { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2133 1.1 christos R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2134 1.1 christos R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2135 1.1 christos R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", "wsp" },
2136 1.1 christos { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2137 1.1 christos R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2138 1.1 christos R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2139 1.1 christos R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", "sp" } },
2140 1.1 christos { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2141 1.1 christos R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2142 1.1 christos R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2143 1.1 christos R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", R32 "zr" },
2144 1.1 christos { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2145 1.1 christos R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2146 1.1 christos R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2147 1.1 christos R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", R64 "zr" } }
2148 1.1 christos #undef R64
2149 1.1 christos #undef R32
2150 1.1 christos };
2151 1.1 christos
2152 1.1 christos /* Return the integer register name.
2153 1.1 christos if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2154 1.1 christos
2155 1.1 christos static inline const char *
2156 1.1 christos get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2157 1.1 christos {
2158 1.1 christos const int has_zr = sp_reg_p ? 0 : 1;
2159 1.1 christos const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2160 1.1 christos return int_reg[has_zr][is_64][regno];
2161 1.1 christos }
2162 1.1 christos
2163 1.1 christos /* Like get_int_reg_name, but IS_64 is always 1. */
2164 1.1 christos
2165 1.1 christos static inline const char *
2166 1.1 christos get_64bit_int_reg_name (int regno, int sp_reg_p)
2167 1.1 christos {
2168 1.1 christos const int has_zr = sp_reg_p ? 0 : 1;
2169 1.1 christos return int_reg[has_zr][1][regno];
2170 1.1 christos }
2171 1.1 christos
2172 1.1 christos /* Types for expanding an encoded 8-bit value to a floating-point value. */
2173 1.1 christos
2174 1.1 christos typedef union
2175 1.1 christos {
2176 1.1 christos uint64_t i;
2177 1.1 christos double d;
2178 1.1 christos } double_conv_t;
2179 1.1 christos
2180 1.1 christos typedef union
2181 1.1 christos {
2182 1.1 christos uint32_t i;
2183 1.1.1.2 christos float f;
2184 1.1.1.2 christos } single_conv_t;
2185 1.1.1.2 christos
2186 1.1.1.2 christos typedef union
2187 1.1.1.2 christos {
2188 1.1.1.2 christos uint32_t i;
2189 1.1 christos float f;
2190 1.1 christos } half_conv_t;
2191 1.1 christos
2192 1.1.1.2 christos /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2193 1.1.1.2 christos normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2194 1.1.1.2 christos (depending on the type of the instruction). IMM8 will be expanded to a
2195 1.1.1.2 christos single-precision floating-point value (SIZE == 4) or a double-precision
2196 1.1 christos floating-point value (SIZE == 8). A half-precision floating-point value
2197 1.1 christos (SIZE == 2) is expanded to a single-precision floating-point value. The
2198 1.1.1.2 christos expanded value is returned. */
2199 1.1 christos
2200 1.1 christos static uint64_t
2201 1.1 christos expand_fp_imm (int size, uint32_t imm8)
2202 1.1 christos {
2203 1.1 christos uint64_t imm;
2204 1.1 christos uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2205 1.1 christos
2206 1.1 christos imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2207 1.1 christos imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2208 1.1.1.2 christos imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2209 1.1 christos imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2210 1.1 christos | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
2211 1.1 christos if (size == 8)
2212 1.1 christos {
2213 1.1 christos imm = (imm8_7 << (63-32)) /* imm8<7> */
2214 1.1 christos | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2215 1.1 christos | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2216 1.1 christos | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2217 1.1.1.2 christos | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2218 1.1 christos imm <<= 32;
2219 1.1 christos }
2220 1.1 christos else if (size == 4 || size == 2)
2221 1.1 christos {
2222 1.1 christos imm = (imm8_7 << 31) /* imm8<7> */
2223 1.1 christos | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2224 1.1.1.2 christos | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2225 1.1.1.2 christos | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2226 1.1.1.2 christos }
2227 1.1.1.2 christos else
2228 1.1.1.2 christos {
2229 1.1 christos /* An unsupported size. */
2230 1.1 christos assert (0);
2231 1.1 christos }
2232 1.1 christos
2233 1.1 christos return imm;
2234 1.1 christos }
2235 1.1 christos
2236 1.1 christos /* Produce the string representation of the register list operand *OPND
2237 1.1 christos in the buffer pointed by BUF of size SIZE. */
2238 1.1 christos static void
2239 1.1 christos print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
2240 1.1 christos {
2241 1.1 christos const int num_regs = opnd->reglist.num_regs;
2242 1.1 christos const int first_reg = opnd->reglist.first_regno;
2243 1.1 christos const int last_reg = (first_reg + num_regs - 1) & 0x1f;
2244 1.1 christos const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
2245 1.1 christos char tb[8]; /* Temporary buffer. */
2246 1.1 christos
2247 1.1 christos assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
2248 1.1 christos assert (num_regs >= 1 && num_regs <= 4);
2249 1.1 christos
2250 1.1 christos /* Prepare the index if any. */
2251 1.1 christos if (opnd->reglist.has_index)
2252 1.1 christos snprintf (tb, 8, "[%d]", opnd->reglist.index);
2253 1.1 christos else
2254 1.1 christos tb[0] = '\0';
2255 1.1 christos
2256 1.1 christos /* The hyphenated form is preferred for disassembly if there are
2257 1.1 christos more than two registers in the list, and the register numbers
2258 1.1 christos are monotonically increasing in increments of one. */
2259 1.1 christos if (num_regs > 2 && last_reg > first_reg)
2260 1.1 christos snprintf (buf, size, "{v%d.%s-v%d.%s}%s", first_reg, qlf_name,
2261 1.1 christos last_reg, qlf_name, tb);
2262 1.1 christos else
2263 1.1 christos {
2264 1.1 christos const int reg0 = first_reg;
2265 1.1 christos const int reg1 = (first_reg + 1) & 0x1f;
2266 1.1 christos const int reg2 = (first_reg + 2) & 0x1f;
2267 1.1 christos const int reg3 = (first_reg + 3) & 0x1f;
2268 1.1 christos
2269 1.1 christos switch (num_regs)
2270 1.1 christos {
2271 1.1 christos case 1:
2272 1.1 christos snprintf (buf, size, "{v%d.%s}%s", reg0, qlf_name, tb);
2273 1.1 christos break;
2274 1.1 christos case 2:
2275 1.1 christos snprintf (buf, size, "{v%d.%s, v%d.%s}%s", reg0, qlf_name,
2276 1.1 christos reg1, qlf_name, tb);
2277 1.1 christos break;
2278 1.1 christos case 3:
2279 1.1 christos snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s}%s", reg0, qlf_name,
2280 1.1 christos reg1, qlf_name, reg2, qlf_name, tb);
2281 1.1 christos break;
2282 1.1 christos case 4:
2283 1.1 christos snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s, v%d.%s}%s",
2284 1.1 christos reg0, qlf_name, reg1, qlf_name, reg2, qlf_name,
2285 1.1 christos reg3, qlf_name, tb);
2286 1.1 christos break;
2287 1.1 christos }
2288 1.1 christos }
2289 1.1 christos }
2290 1.1 christos
2291 1.1 christos /* Produce the string representation of the register offset address operand
2292 1.1 christos *OPND in the buffer pointed by BUF of size SIZE. */
2293 1.1 christos static void
2294 1.1 christos print_register_offset_address (char *buf, size_t size,
2295 1.1 christos const aarch64_opnd_info *opnd)
2296 1.1 christos {
2297 1.1 christos const size_t tblen = 16;
2298 1.1 christos char tb[tblen]; /* Temporary buffer. */
2299 1.1 christos bfd_boolean lsl_p = FALSE; /* Is LSL shift operator? */
2300 1.1 christos bfd_boolean wm_p = FALSE; /* Should Rm be Wm? */
2301 1.1 christos bfd_boolean print_extend_p = TRUE;
2302 1.1 christos bfd_boolean print_amount_p = TRUE;
2303 1.1 christos const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
2304 1.1 christos
2305 1.1 christos switch (opnd->shifter.kind)
2306 1.1 christos {
2307 1.1 christos case AARCH64_MOD_UXTW: wm_p = TRUE; break;
2308 1.1 christos case AARCH64_MOD_LSL : lsl_p = TRUE; break;
2309 1.1 christos case AARCH64_MOD_SXTW: wm_p = TRUE; break;
2310 1.1 christos case AARCH64_MOD_SXTX: break;
2311 1.1 christos default: assert (0);
2312 1.1 christos }
2313 1.1 christos
2314 1.1 christos if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
2315 1.1 christos || !opnd->shifter.amount_present))
2316 1.1 christos {
2317 1.1 christos /* Not print the shift/extend amount when the amount is zero and
2318 1.1 christos when it is not the special case of 8-bit load/store instruction. */
2319 1.1 christos print_amount_p = FALSE;
2320 1.1 christos /* Likewise, no need to print the shift operator LSL in such a
2321 1.1 christos situation. */
2322 1.1 christos if (lsl_p)
2323 1.1 christos print_extend_p = FALSE;
2324 1.1 christos }
2325 1.1 christos
2326 1.1 christos /* Prepare for the extend/shift. */
2327 1.1 christos if (print_extend_p)
2328 1.1 christos {
2329 1.1 christos if (print_amount_p)
2330 1.1 christos snprintf (tb, tblen, ",%s #%d", shift_name, opnd->shifter.amount);
2331 1.1 christos else
2332 1.1 christos snprintf (tb, tblen, ",%s", shift_name);
2333 1.1 christos }
2334 1.1.1.2 christos else
2335 1.1 christos tb[0] = '\0';
2336 1.1.1.2 christos
2337 1.1.1.2 christos snprintf (buf, size, "[%s,%s%s]",
2338 1.1.1.2 christos get_64bit_int_reg_name (opnd->addr.base_regno, 1),
2339 1.1.1.2 christos get_int_reg_name (opnd->addr.offset.regno,
2340 1.1 christos wm_p ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X,
2341 1.1 christos 0 /* sp_reg_p */),
2342 1.1 christos tb);
2343 1.1 christos }
2344 1.1 christos
2345 1.1 christos /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
2346 1.1 christos in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
2347 1.1 christos PC, PCREL_P and ADDRESS are used to pass in and return information about
2348 1.1 christos the PC-relative address calculation, where the PC value is passed in
2349 1.1 christos PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
2350 1.1 christos will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
2351 1.1 christos calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
2352 1.1 christos
2353 1.1 christos The function serves both the disassembler and the assembler diagnostics
2354 1.1 christos issuer, which is the reason why it lives in this file. */
2355 1.1 christos
2356 1.1 christos void
2357 1.1 christos aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
2358 1.1 christos const aarch64_opcode *opcode,
2359 1.1 christos const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
2360 1.1 christos bfd_vma *address)
2361 1.1 christos {
2362 1.1 christos int i;
2363 1.1 christos const char *name = NULL;
2364 1.1 christos const aarch64_opnd_info *opnd = opnds + idx;
2365 1.1 christos enum aarch64_modifier_kind kind;
2366 1.1 christos uint64_t addr;
2367 1.1 christos
2368 1.1 christos buf[0] = '\0';
2369 1.1 christos if (pcrel_p)
2370 1.1 christos *pcrel_p = 0;
2371 1.1 christos
2372 1.1 christos switch (opnd->type)
2373 1.1 christos {
2374 1.1 christos case AARCH64_OPND_Rd:
2375 1.1 christos case AARCH64_OPND_Rn:
2376 1.1 christos case AARCH64_OPND_Rm:
2377 1.1 christos case AARCH64_OPND_Rt:
2378 1.1 christos case AARCH64_OPND_Rt2:
2379 1.1.1.2 christos case AARCH64_OPND_Rs:
2380 1.1 christos case AARCH64_OPND_Ra:
2381 1.1 christos case AARCH64_OPND_Rt_SYS:
2382 1.1 christos case AARCH64_OPND_PAIRREG:
2383 1.1 christos /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
2384 1.1 christos the <ic_op>, therefore we we use opnd->present to override the
2385 1.1 christos generic optional-ness information. */
2386 1.1 christos if (opnd->type == AARCH64_OPND_Rt_SYS && !opnd->present)
2387 1.1 christos break;
2388 1.1 christos /* Omit the operand, e.g. RET. */
2389 1.1 christos if (optional_operand_p (opcode, idx)
2390 1.1 christos && opnd->reg.regno == get_optional_operand_default_value (opcode))
2391 1.1 christos break;
2392 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
2393 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X);
2394 1.1 christos snprintf (buf, size, "%s",
2395 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2396 1.1 christos break;
2397 1.1 christos
2398 1.1 christos case AARCH64_OPND_Rd_SP:
2399 1.1 christos case AARCH64_OPND_Rn_SP:
2400 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
2401 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_WSP
2402 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X
2403 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_SP);
2404 1.1 christos snprintf (buf, size, "%s",
2405 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
2406 1.1 christos break;
2407 1.1 christos
2408 1.1 christos case AARCH64_OPND_Rm_EXT:
2409 1.1 christos kind = opnd->shifter.kind;
2410 1.1 christos assert (idx == 1 || idx == 2);
2411 1.1 christos if ((aarch64_stack_pointer_p (opnds)
2412 1.1 christos || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
2413 1.1 christos && ((opnd->qualifier == AARCH64_OPND_QLF_W
2414 1.1 christos && opnds[0].qualifier == AARCH64_OPND_QLF_W
2415 1.1 christos && kind == AARCH64_MOD_UXTW)
2416 1.1 christos || (opnd->qualifier == AARCH64_OPND_QLF_X
2417 1.1 christos && kind == AARCH64_MOD_UXTX)))
2418 1.1 christos {
2419 1.1 christos /* 'LSL' is the preferred form in this case. */
2420 1.1 christos kind = AARCH64_MOD_LSL;
2421 1.1 christos if (opnd->shifter.amount == 0)
2422 1.1 christos {
2423 1.1 christos /* Shifter omitted. */
2424 1.1 christos snprintf (buf, size, "%s",
2425 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2426 1.1 christos break;
2427 1.1 christos }
2428 1.1 christos }
2429 1.1 christos if (opnd->shifter.amount)
2430 1.1 christos snprintf (buf, size, "%s, %s #%d",
2431 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2432 1.1 christos aarch64_operand_modifiers[kind].name,
2433 1.1 christos opnd->shifter.amount);
2434 1.1 christos else
2435 1.1 christos snprintf (buf, size, "%s, %s",
2436 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2437 1.1 christos aarch64_operand_modifiers[kind].name);
2438 1.1 christos break;
2439 1.1 christos
2440 1.1 christos case AARCH64_OPND_Rm_SFT:
2441 1.1 christos assert (opnd->qualifier == AARCH64_OPND_QLF_W
2442 1.1 christos || opnd->qualifier == AARCH64_OPND_QLF_X);
2443 1.1 christos if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
2444 1.1 christos snprintf (buf, size, "%s",
2445 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2446 1.1 christos else
2447 1.1 christos snprintf (buf, size, "%s, %s #%d",
2448 1.1 christos get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2449 1.1 christos aarch64_operand_modifiers[opnd->shifter.kind].name,
2450 1.1 christos opnd->shifter.amount);
2451 1.1 christos break;
2452 1.1 christos
2453 1.1 christos case AARCH64_OPND_Fd:
2454 1.1 christos case AARCH64_OPND_Fn:
2455 1.1 christos case AARCH64_OPND_Fm:
2456 1.1 christos case AARCH64_OPND_Fa:
2457 1.1 christos case AARCH64_OPND_Ft:
2458 1.1 christos case AARCH64_OPND_Ft2:
2459 1.1 christos case AARCH64_OPND_Sd:
2460 1.1 christos case AARCH64_OPND_Sn:
2461 1.1 christos case AARCH64_OPND_Sm:
2462 1.1 christos snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
2463 1.1 christos opnd->reg.regno);
2464 1.1 christos break;
2465 1.1 christos
2466 1.1 christos case AARCH64_OPND_Vd:
2467 1.1 christos case AARCH64_OPND_Vn:
2468 1.1 christos case AARCH64_OPND_Vm:
2469 1.1 christos snprintf (buf, size, "v%d.%s", opnd->reg.regno,
2470 1.1 christos aarch64_get_qualifier_name (opnd->qualifier));
2471 1.1 christos break;
2472 1.1 christos
2473 1.1 christos case AARCH64_OPND_Ed:
2474 1.1 christos case AARCH64_OPND_En:
2475 1.1 christos case AARCH64_OPND_Em:
2476 1.1 christos snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
2477 1.1 christos aarch64_get_qualifier_name (opnd->qualifier),
2478 1.1 christos opnd->reglane.index);
2479 1.1 christos break;
2480 1.1 christos
2481 1.1 christos case AARCH64_OPND_VdD1:
2482 1.1 christos case AARCH64_OPND_VnD1:
2483 1.1 christos snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
2484 1.1 christos break;
2485 1.1 christos
2486 1.1 christos case AARCH64_OPND_LVn:
2487 1.1 christos case AARCH64_OPND_LVt:
2488 1.1 christos case AARCH64_OPND_LVt_AL:
2489 1.1 christos case AARCH64_OPND_LEt:
2490 1.1 christos print_register_list (buf, size, opnd);
2491 1.1 christos break;
2492 1.1 christos
2493 1.1 christos case AARCH64_OPND_Cn:
2494 1.1 christos case AARCH64_OPND_Cm:
2495 1.1 christos snprintf (buf, size, "C%d", opnd->reg.regno);
2496 1.1 christos break;
2497 1.1 christos
2498 1.1 christos case AARCH64_OPND_IDX:
2499 1.1 christos case AARCH64_OPND_IMM:
2500 1.1 christos case AARCH64_OPND_WIDTH:
2501 1.1 christos case AARCH64_OPND_UIMM3_OP1:
2502 1.1 christos case AARCH64_OPND_UIMM3_OP2:
2503 1.1 christos case AARCH64_OPND_BIT_NUM:
2504 1.1 christos case AARCH64_OPND_IMM_VLSL:
2505 1.1 christos case AARCH64_OPND_IMM_VLSR:
2506 1.1 christos case AARCH64_OPND_SHLL_IMM:
2507 1.1 christos case AARCH64_OPND_IMM0:
2508 1.1 christos case AARCH64_OPND_IMMR:
2509 1.1 christos case AARCH64_OPND_IMMS:
2510 1.1 christos case AARCH64_OPND_FBITS:
2511 1.1 christos snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
2512 1.1 christos break;
2513 1.1 christos
2514 1.1 christos case AARCH64_OPND_IMM_MOV:
2515 1.1 christos switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2516 1.1 christos {
2517 1.1 christos case 4: /* e.g. MOV Wd, #<imm32>. */
2518 1.1 christos {
2519 1.1 christos int imm32 = opnd->imm.value;
2520 1.1 christos snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
2521 1.1 christos }
2522 1.1 christos break;
2523 1.1 christos case 8: /* e.g. MOV Xd, #<imm64>. */
2524 1.1 christos snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
2525 1.1 christos opnd->imm.value, opnd->imm.value);
2526 1.1 christos break;
2527 1.1 christos default: assert (0);
2528 1.1 christos }
2529 1.1 christos break;
2530 1.1 christos
2531 1.1 christos case AARCH64_OPND_FPIMM0:
2532 1.1 christos snprintf (buf, size, "#0.0");
2533 1.1 christos break;
2534 1.1 christos
2535 1.1 christos case AARCH64_OPND_LIMM:
2536 1.1 christos case AARCH64_OPND_AIMM:
2537 1.1 christos case AARCH64_OPND_HALF:
2538 1.1 christos if (opnd->shifter.amount)
2539 1.1 christos snprintf (buf, size, "#0x%" PRIx64 ", lsl #%d", opnd->imm.value,
2540 1.1 christos opnd->shifter.amount);
2541 1.1 christos else
2542 1.1 christos snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2543 1.1 christos break;
2544 1.1 christos
2545 1.1 christos case AARCH64_OPND_SIMD_IMM:
2546 1.1 christos case AARCH64_OPND_SIMD_IMM_SFT:
2547 1.1 christos if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
2548 1.1 christos || opnd->shifter.kind == AARCH64_MOD_NONE)
2549 1.1 christos snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2550 1.1 christos else
2551 1.1 christos snprintf (buf, size, "#0x%" PRIx64 ", %s #%d", opnd->imm.value,
2552 1.1 christos aarch64_operand_modifiers[opnd->shifter.kind].name,
2553 1.1 christos opnd->shifter.amount);
2554 1.1 christos break;
2555 1.1 christos
2556 1.1 christos case AARCH64_OPND_FPIMM:
2557 1.1.1.2 christos case AARCH64_OPND_SIMD_FPIMM:
2558 1.1.1.2 christos switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2559 1.1.1.2 christos {
2560 1.1.1.2 christos case 2: /* e.g. FMOV <Hd>, #<imm>. */
2561 1.1.1.2 christos {
2562 1.1.1.2 christos half_conv_t c;
2563 1.1.1.2 christos c.i = expand_fp_imm (2, opnd->imm.value);
2564 1.1 christos snprintf (buf, size, "#%.18e", c.f);
2565 1.1 christos }
2566 1.1 christos break;
2567 1.1.1.2 christos case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
2568 1.1 christos {
2569 1.1 christos single_conv_t c;
2570 1.1 christos c.i = expand_fp_imm (4, opnd->imm.value);
2571 1.1 christos snprintf (buf, size, "#%.18e", c.f);
2572 1.1 christos }
2573 1.1 christos break;
2574 1.1.1.2 christos case 8: /* e.g. FMOV <Sd>, #<imm>. */
2575 1.1 christos {
2576 1.1 christos double_conv_t c;
2577 1.1 christos c.i = expand_fp_imm (8, opnd->imm.value);
2578 1.1 christos snprintf (buf, size, "#%.18e", c.d);
2579 1.1 christos }
2580 1.1 christos break;
2581 1.1 christos default: assert (0);
2582 1.1 christos }
2583 1.1 christos break;
2584 1.1 christos
2585 1.1 christos case AARCH64_OPND_CCMP_IMM:
2586 1.1 christos case AARCH64_OPND_NZCV:
2587 1.1 christos case AARCH64_OPND_EXCEPTION:
2588 1.1 christos case AARCH64_OPND_UIMM4:
2589 1.1 christos case AARCH64_OPND_UIMM7:
2590 1.1 christos if (optional_operand_p (opcode, idx) == TRUE
2591 1.1 christos && (opnd->imm.value ==
2592 1.1 christos (int64_t) get_optional_operand_default_value (opcode)))
2593 1.1 christos /* Omit the operand, e.g. DCPS1. */
2594 1.1 christos break;
2595 1.1 christos snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
2596 1.1.1.2 christos break;
2597 1.1 christos
2598 1.1 christos case AARCH64_OPND_COND:
2599 1.1 christos case AARCH64_OPND_COND1:
2600 1.1 christos snprintf (buf, size, "%s", opnd->cond->names[0]);
2601 1.1 christos break;
2602 1.1 christos
2603 1.1 christos case AARCH64_OPND_ADDR_ADRP:
2604 1.1 christos addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
2605 1.1 christos + opnd->imm.value;
2606 1.1 christos if (pcrel_p)
2607 1.1 christos *pcrel_p = 1;
2608 1.1 christos if (address)
2609 1.1 christos *address = addr;
2610 1.1 christos /* This is not necessary during the disassembling, as print_address_func
2611 1.1 christos in the disassemble_info will take care of the printing. But some
2612 1.1 christos other callers may be still interested in getting the string in *STR,
2613 1.1 christos so here we do snprintf regardless. */
2614 1.1 christos snprintf (buf, size, "#0x%" PRIx64, addr);
2615 1.1 christos break;
2616 1.1 christos
2617 1.1 christos case AARCH64_OPND_ADDR_PCREL14:
2618 1.1 christos case AARCH64_OPND_ADDR_PCREL19:
2619 1.1 christos case AARCH64_OPND_ADDR_PCREL21:
2620 1.1 christos case AARCH64_OPND_ADDR_PCREL26:
2621 1.1 christos addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
2622 1.1 christos if (pcrel_p)
2623 1.1 christos *pcrel_p = 1;
2624 1.1 christos if (address)
2625 1.1 christos *address = addr;
2626 1.1 christos /* This is not necessary during the disassembling, as print_address_func
2627 1.1 christos in the disassemble_info will take care of the printing. But some
2628 1.1 christos other callers may be still interested in getting the string in *STR,
2629 1.1 christos so here we do snprintf regardless. */
2630 1.1 christos snprintf (buf, size, "#0x%" PRIx64, addr);
2631 1.1 christos break;
2632 1.1 christos
2633 1.1 christos case AARCH64_OPND_ADDR_SIMPLE:
2634 1.1 christos case AARCH64_OPND_SIMD_ADDR_SIMPLE:
2635 1.1 christos case AARCH64_OPND_SIMD_ADDR_POST:
2636 1.1 christos name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2637 1.1 christos if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
2638 1.1 christos {
2639 1.1 christos if (opnd->addr.offset.is_reg)
2640 1.1 christos snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
2641 1.1 christos else
2642 1.1 christos snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
2643 1.1 christos }
2644 1.1 christos else
2645 1.1 christos snprintf (buf, size, "[%s]", name);
2646 1.1 christos break;
2647 1.1 christos
2648 1.1 christos case AARCH64_OPND_ADDR_REGOFF:
2649 1.1 christos print_register_offset_address (buf, size, opnd);
2650 1.1 christos break;
2651 1.1 christos
2652 1.1 christos case AARCH64_OPND_ADDR_SIMM7:
2653 1.1 christos case AARCH64_OPND_ADDR_SIMM9:
2654 1.1 christos case AARCH64_OPND_ADDR_SIMM9_2:
2655 1.1 christos name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2656 1.1 christos if (opnd->addr.writeback)
2657 1.1 christos {
2658 1.1 christos if (opnd->addr.preind)
2659 1.1 christos snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
2660 1.1 christos else
2661 1.1 christos snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
2662 1.1 christos }
2663 1.1 christos else
2664 1.1 christos {
2665 1.1 christos if (opnd->addr.offset.imm)
2666 1.1 christos snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2667 1.1 christos else
2668 1.1 christos snprintf (buf, size, "[%s]", name);
2669 1.1 christos }
2670 1.1 christos break;
2671 1.1 christos
2672 1.1 christos case AARCH64_OPND_ADDR_UIMM12:
2673 1.1 christos name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2674 1.1 christos if (opnd->addr.offset.imm)
2675 1.1 christos snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2676 1.1 christos else
2677 1.1 christos snprintf (buf, size, "[%s]", name);
2678 1.1 christos break;
2679 1.1.1.2 christos
2680 1.1.1.2 christos case AARCH64_OPND_SYSREG:
2681 1.1 christos for (i = 0; aarch64_sys_regs[i].name; ++i)
2682 1.1 christos if (aarch64_sys_regs[i].value == opnd->sysreg
2683 1.1 christos && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
2684 1.1 christos break;
2685 1.1 christos if (aarch64_sys_regs[i].name)
2686 1.1 christos snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
2687 1.1 christos else
2688 1.1 christos {
2689 1.1 christos /* Implementation defined system register. */
2690 1.1 christos unsigned int value = opnd->sysreg;
2691 1.1 christos snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
2692 1.1 christos (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
2693 1.1 christos value & 0x7);
2694 1.1 christos }
2695 1.1 christos break;
2696 1.1 christos
2697 1.1 christos case AARCH64_OPND_PSTATEFIELD:
2698 1.1 christos for (i = 0; aarch64_pstatefields[i].name; ++i)
2699 1.1 christos if (aarch64_pstatefields[i].value == opnd->pstatefield)
2700 1.1 christos break;
2701 1.1 christos assert (aarch64_pstatefields[i].name);
2702 1.1 christos snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
2703 1.1 christos break;
2704 1.1 christos
2705 1.1 christos case AARCH64_OPND_SYSREG_AT:
2706 1.1.1.2 christos case AARCH64_OPND_SYSREG_DC:
2707 1.1 christos case AARCH64_OPND_SYSREG_IC:
2708 1.1 christos case AARCH64_OPND_SYSREG_TLBI:
2709 1.1 christos snprintf (buf, size, "%s", opnd->sysins_op->name);
2710 1.1 christos break;
2711 1.1 christos
2712 1.1 christos case AARCH64_OPND_BARRIER:
2713 1.1 christos snprintf (buf, size, "%s", opnd->barrier->name);
2714 1.1 christos break;
2715 1.1 christos
2716 1.1 christos case AARCH64_OPND_BARRIER_ISB:
2717 1.1 christos /* Operand can be omitted, e.g. in DCPS1. */
2718 1.1 christos if (! optional_operand_p (opcode, idx)
2719 1.1 christos || (opnd->barrier->value
2720 1.1 christos != get_optional_operand_default_value (opcode)))
2721 1.1 christos snprintf (buf, size, "#0x%x", opnd->barrier->value);
2722 1.1 christos break;
2723 1.1 christos
2724 1.1 christos case AARCH64_OPND_PRFOP:
2725 1.1 christos if (opnd->prfop->name != NULL)
2726 1.1 christos snprintf (buf, size, "%s", opnd->prfop->name);
2727 1.1 christos else
2728 1.1.1.2 christos snprintf (buf, size, "#0x%02x", opnd->prfop->value);
2729 1.1.1.2 christos break;
2730 1.1.1.2 christos
2731 1.1.1.2 christos case AARCH64_OPND_BARRIER_PSB:
2732 1.1 christos snprintf (buf, size, "%s", opnd->hint_option->name);
2733 1.1 christos break;
2734 1.1 christos
2735 1.1 christos default:
2736 1.1 christos assert (0);
2737 1.1 christos }
2738 1.1 christos }
2739 1.1 christos
2740 1.1 christos #define CPENC(op0,op1,crn,crm,op2) \
2742 1.1 christos ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
2743 1.1 christos /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
2744 1.1 christos #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
2745 1.1 christos /* for 3.9.10 System Instructions */
2746 1.1 christos #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
2747 1.1 christos
2748 1.1 christos #define C0 0
2749 1.1 christos #define C1 1
2750 1.1 christos #define C2 2
2751 1.1 christos #define C3 3
2752 1.1 christos #define C4 4
2753 1.1 christos #define C5 5
2754 1.1 christos #define C6 6
2755 1.1 christos #define C7 7
2756 1.1 christos #define C8 8
2757 1.1 christos #define C9 9
2758 1.1 christos #define C10 10
2759 1.1 christos #define C11 11
2760 1.1 christos #define C12 12
2761 1.1.1.2 christos #define C13 13
2762 1.1.1.2 christos #define C14 14
2763 1.1.1.2 christos #define C15 15
2764 1.1.1.2 christos
2765 1.1.1.2 christos #ifdef F_DEPRECATED
2766 1.1.1.2 christos #undef F_DEPRECATED
2767 1.1.1.2 christos #endif
2768 1.1.1.2 christos #define F_DEPRECATED 0x1 /* Deprecated system register. */
2769 1.1.1.2 christos
2770 1.1.1.2 christos #ifdef F_ARCHEXT
2771 1.1.1.2 christos #undef F_ARCHEXT
2772 1.1.1.2 christos #endif
2773 1.1.1.2 christos #define F_ARCHEXT 0x2 /* Architecture dependent system register. */
2774 1.1.1.2 christos
2775 1.1.1.2 christos #ifdef F_HASXT
2776 1.1.1.2 christos #undef F_HASXT
2777 1.1.1.2 christos #endif
2778 1.1 christos #define F_HASXT 0x4 /* System instruction register <Xt>
2779 1.1 christos operand. */
2780 1.1 christos
2781 1.1.1.2 christos
2782 1.1 christos /* TODO there are two more issues need to be resolved
2783 1.1.1.2 christos 1. handle read-only and write-only system registers
2784 1.1.1.2 christos 2. handle cpu-implementation-defined system registers. */
2785 1.1.1.2 christos const aarch64_sys_reg aarch64_sys_regs [] =
2786 1.1.1.2 christos {
2787 1.1.1.2 christos { "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
2788 1.1.1.2 christos { "spsr_el12", CPEN_ (5, C0, 0), F_ARCHEXT },
2789 1.1.1.2 christos { "elr_el1", CPEN_(0,C0,1), 0 },
2790 1.1.1.2 christos { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
2791 1.1.1.2 christos { "sp_el0", CPEN_(0,C1,0), 0 },
2792 1.1.1.2 christos { "spsel", CPEN_(0,C2,0), 0 },
2793 1.1.1.2 christos { "daif", CPEN_(3,C2,1), 0 },
2794 1.1.1.2 christos { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
2795 1.1.1.2 christos { "pan", CPEN_(0,C2,3), F_ARCHEXT },
2796 1.1.1.2 christos { "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
2797 1.1.1.2 christos { "nzcv", CPEN_(3,C2,0), 0 },
2798 1.1.1.2 christos { "fpcr", CPEN_(3,C4,0), 0 },
2799 1.1.1.2 christos { "fpsr", CPEN_(3,C4,1), 0 },
2800 1.1.1.2 christos { "dspsr_el0", CPEN_(3,C5,0), 0 },
2801 1.1.1.2 christos { "dlr_el0", CPEN_(3,C5,1), 0 },
2802 1.1.1.2 christos { "spsr_el2", CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
2803 1.1.1.2 christos { "elr_el2", CPEN_(4,C0,1), 0 },
2804 1.1.1.2 christos { "sp_el1", CPEN_(4,C1,0), 0 },
2805 1.1.1.2 christos { "spsr_irq", CPEN_(4,C3,0), 0 },
2806 1.1.1.2 christos { "spsr_abt", CPEN_(4,C3,1), 0 },
2807 1.1.1.2 christos { "spsr_und", CPEN_(4,C3,2), 0 },
2808 1.1.1.2 christos { "spsr_fiq", CPEN_(4,C3,3), 0 },
2809 1.1.1.2 christos { "spsr_el3", CPEN_(6,C0,0), 0 },
2810 1.1.1.2 christos { "elr_el3", CPEN_(6,C0,1), 0 },
2811 1.1.1.2 christos { "sp_el2", CPEN_(6,C1,0), 0 },
2812 1.1.1.2 christos { "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
2813 1.1.1.2 christos { "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
2814 1.1.1.2 christos { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
2815 1.1.1.2 christos { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
2816 1.1.1.2 christos { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
2817 1.1.1.2 christos { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
2818 1.1.1.2 christos { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
2819 1.1.1.2 christos { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
2820 1.1.1.2 christos { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
2821 1.1.1.2 christos { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
2822 1.1.1.2 christos { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
2823 1.1.1.2 christos { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
2824 1.1.1.2 christos { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
2825 1.1.1.2 christos { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
2826 1.1.1.2 christos { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
2827 1.1.1.2 christos { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
2828 1.1.1.2 christos { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
2829 1.1.1.2 christos { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
2830 1.1.1.2 christos { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
2831 1.1.1.2 christos { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
2832 1.1.1.2 christos { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
2833 1.1.1.2 christos { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
2834 1.1.1.2 christos { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
2835 1.1.1.2 christos { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
2836 1.1.1.2 christos { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
2837 1.1.1.2 christos { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
2838 1.1.1.2 christos { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
2839 1.1.1.2 christos { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
2840 1.1.1.2 christos { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
2841 1.1.1.2 christos { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
2842 1.1.1.2 christos { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
2843 1.1.1.2 christos { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
2844 1.1.1.2 christos { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
2845 1.1.1.2 christos { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
2846 1.1.1.2 christos { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
2847 1.1.1.2 christos { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
2848 1.1.1.2 christos { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
2849 1.1.1.2 christos { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
2850 1.1.1.2 christos { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
2851 1.1.1.2 christos { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
2852 1.1.1.2 christos { "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
2853 1.1.1.2 christos { "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
2854 1.1.1.2 christos { "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
2855 1.1.1.2 christos { "sctlr_el2", CPENC(3,4,C1,C0,0), 0 },
2856 1.1.1.2 christos { "sctlr_el3", CPENC(3,6,C1,C0,0), 0 },
2857 1.1.1.2 christos { "sctlr_el12", CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
2858 1.1.1.2 christos { "actlr_el1", CPENC(3,0,C1,C0,1), 0 },
2859 1.1.1.2 christos { "actlr_el2", CPENC(3,4,C1,C0,1), 0 },
2860 1.1.1.2 christos { "actlr_el3", CPENC(3,6,C1,C0,1), 0 },
2861 1.1.1.2 christos { "cpacr_el1", CPENC(3,0,C1,C0,2), 0 },
2862 1.1.1.2 christos { "cpacr_el12", CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
2863 1.1.1.2 christos { "cptr_el2", CPENC(3,4,C1,C1,2), 0 },
2864 1.1.1.2 christos { "cptr_el3", CPENC(3,6,C1,C1,2), 0 },
2865 1.1.1.2 christos { "scr_el3", CPENC(3,6,C1,C1,0), 0 },
2866 1.1.1.2 christos { "hcr_el2", CPENC(3,4,C1,C1,0), 0 },
2867 1.1.1.2 christos { "mdcr_el2", CPENC(3,4,C1,C1,1), 0 },
2868 1.1.1.2 christos { "mdcr_el3", CPENC(3,6,C1,C3,1), 0 },
2869 1.1.1.2 christos { "hstr_el2", CPENC(3,4,C1,C1,3), 0 },
2870 1.1.1.2 christos { "hacr_el2", CPENC(3,4,C1,C1,7), 0 },
2871 1.1.1.2 christos { "ttbr0_el1", CPENC(3,0,C2,C0,0), 0 },
2872 1.1.1.2 christos { "ttbr1_el1", CPENC(3,0,C2,C0,1), 0 },
2873 1.1.1.2 christos { "ttbr0_el2", CPENC(3,4,C2,C0,0), 0 },
2874 1.1.1.2 christos { "ttbr1_el2", CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
2875 1.1.1.2 christos { "ttbr0_el3", CPENC(3,6,C2,C0,0), 0 },
2876 1.1.1.2 christos { "ttbr0_el12", CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
2877 1.1.1.2 christos { "ttbr1_el12", CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
2878 1.1.1.2 christos { "vttbr_el2", CPENC(3,4,C2,C1,0), 0 },
2879 1.1.1.2 christos { "tcr_el1", CPENC(3,0,C2,C0,2), 0 },
2880 1.1.1.2 christos { "tcr_el2", CPENC(3,4,C2,C0,2), 0 },
2881 1.1.1.2 christos { "tcr_el3", CPENC(3,6,C2,C0,2), 0 },
2882 1.1.1.2 christos { "tcr_el12", CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
2883 1.1.1.2 christos { "vtcr_el2", CPENC(3,4,C2,C1,2), 0 },
2884 1.1.1.2 christos { "afsr0_el1", CPENC(3,0,C5,C1,0), 0 },
2885 1.1.1.2 christos { "afsr1_el1", CPENC(3,0,C5,C1,1), 0 },
2886 1.1.1.2 christos { "afsr0_el2", CPENC(3,4,C5,C1,0), 0 },
2887 1.1.1.2 christos { "afsr1_el2", CPENC(3,4,C5,C1,1), 0 },
2888 1.1.1.2 christos { "afsr0_el3", CPENC(3,6,C5,C1,0), 0 },
2889 1.1.1.2 christos { "afsr0_el12", CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
2890 1.1.1.2 christos { "afsr1_el3", CPENC(3,6,C5,C1,1), 0 },
2891 1.1.1.2 christos { "afsr1_el12", CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
2892 1.1.1.2 christos { "esr_el1", CPENC(3,0,C5,C2,0), 0 },
2893 1.1.1.2 christos { "esr_el2", CPENC(3,4,C5,C2,0), 0 },
2894 1.1.1.2 christos { "esr_el3", CPENC(3,6,C5,C2,0), 0 },
2895 1.1.1.2 christos { "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
2896 1.1.1.2 christos { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
2897 1.1.1.2 christos { "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
2898 1.1.1.2 christos { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
2899 1.1.1.2 christos { "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
2900 1.1.1.2 christos { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
2901 1.1.1.2 christos { "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
2902 1.1.1.2 christos { "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
2903 1.1.1.2 christos { "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
2904 1.1.1.2 christos { "erxmisc0_el1", CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
2905 1.1.1.2 christos { "erxmisc1_el1", CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
2906 1.1.1.2 christos { "far_el1", CPENC(3,0,C6,C0,0), 0 },
2907 1.1.1.2 christos { "far_el2", CPENC(3,4,C6,C0,0), 0 },
2908 1.1.1.2 christos { "far_el3", CPENC(3,6,C6,C0,0), 0 },
2909 1.1.1.2 christos { "far_el12", CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
2910 1.1.1.2 christos { "hpfar_el2", CPENC(3,4,C6,C0,4), 0 },
2911 1.1.1.2 christos { "par_el1", CPENC(3,0,C7,C4,0), 0 },
2912 1.1.1.2 christos { "mair_el1", CPENC(3,0,C10,C2,0), 0 },
2913 1.1.1.2 christos { "mair_el2", CPENC(3,4,C10,C2,0), 0 },
2914 1.1.1.2 christos { "mair_el3", CPENC(3,6,C10,C2,0), 0 },
2915 1.1.1.2 christos { "mair_el12", CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
2916 1.1.1.2 christos { "amair_el1", CPENC(3,0,C10,C3,0), 0 },
2917 1.1.1.2 christos { "amair_el2", CPENC(3,4,C10,C3,0), 0 },
2918 1.1.1.2 christos { "amair_el3", CPENC(3,6,C10,C3,0), 0 },
2919 1.1.1.2 christos { "amair_el12", CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
2920 1.1.1.2 christos { "vbar_el1", CPENC(3,0,C12,C0,0), 0 },
2921 1.1.1.2 christos { "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
2922 1.1.1.2 christos { "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
2923 1.1.1.2 christos { "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
2924 1.1.1.2 christos { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
2925 1.1.1.2 christos { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
2926 1.1.1.2 christos { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
2927 1.1.1.2 christos { "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
2928 1.1.1.2 christos { "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
2929 1.1.1.2 christos { "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
2930 1.1.1.2 christos { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
2931 1.1.1.2 christos { "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
2932 1.1.1.2 christos { "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
2933 1.1.1.2 christos { "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
2934 1.1.1.2 christos { "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
2935 1.1.1.2 christos { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
2936 1.1.1.2 christos { "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
2937 1.1.1.2 christos { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
2938 1.1.1.2 christos { "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
2939 1.1.1.2 christos { "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
2940 1.1.1.2 christos { "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
2941 1.1.1.2 christos { "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
2942 1.1.1.2 christos { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
2943 1.1.1.2 christos { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
2944 1.1.1.2 christos { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
2945 1.1.1.2 christos { "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
2946 1.1.1.2 christos { "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
2947 1.1.1.2 christos { "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
2948 1.1.1.2 christos { "cnthctl_el2", CPENC(3,4,C14,C1,0), 0 },
2949 1.1.1.2 christos { "cntp_tval_el0", CPENC(3,3,C14,C2,0), 0 },
2950 1.1.1.2 christos { "cntp_tval_el02", CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
2951 1.1.1.2 christos { "cntp_ctl_el0", CPENC(3,3,C14,C2,1), 0 },
2952 1.1.1.2 christos { "cntp_ctl_el02", CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
2953 1.1.1.2 christos { "cntp_cval_el0", CPENC(3,3,C14,C2,2), 0 },
2954 1.1.1.2 christos { "cntp_cval_el02", CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
2955 1.1.1.2 christos { "cntv_tval_el0", CPENC(3,3,C14,C3,0), 0 },
2956 1.1.1.2 christos { "cntv_tval_el02", CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
2957 1.1.1.2 christos { "cntv_ctl_el0", CPENC(3,3,C14,C3,1), 0 },
2958 1.1.1.2 christos { "cntv_ctl_el02", CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
2959 1.1.1.2 christos { "cntv_cval_el0", CPENC(3,3,C14,C3,2), 0 },
2960 1.1.1.2 christos { "cntv_cval_el02", CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
2961 1.1.1.2 christos { "cnthp_tval_el2", CPENC(3,4,C14,C2,0), 0 },
2962 1.1.1.2 christos { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1), 0 },
2963 1.1.1.2 christos { "cnthp_cval_el2", CPENC(3,4,C14,C2,2), 0 },
2964 1.1.1.2 christos { "cntps_tval_el1", CPENC(3,7,C14,C2,0), 0 },
2965 1.1.1.2 christos { "cntps_ctl_el1", CPENC(3,7,C14,C2,1), 0 },
2966 1.1.1.2 christos { "cntps_cval_el1", CPENC(3,7,C14,C2,2), 0 },
2967 1.1.1.2 christos { "cnthv_tval_el2", CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
2968 1.1.1.2 christos { "cnthv_ctl_el2", CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
2969 1.1.1.2 christos { "cnthv_cval_el2", CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
2970 1.1.1.2 christos { "dacr32_el2", CPENC(3,4,C3,C0,0), 0 },
2971 1.1.1.2 christos { "ifsr32_el2", CPENC(3,4,C5,C0,1), 0 },
2972 1.1.1.2 christos { "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
2973 1.1.1.2 christos { "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
2974 1.1.1.2 christos { "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
2975 1.1.1.2 christos { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
2976 1.1.1.2 christos { "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
2977 1.1.1.2 christos { "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
2978 1.1.1.2 christos { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
2979 1.1.1.2 christos { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
2980 1.1.1.2 christos { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
2981 1.1.1.2 christos { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
2982 1.1.1.2 christos { "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
2983 1.1.1.2 christos { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
2984 1.1.1.2 christos { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
2985 1.1.1.2 christos { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4), 0 },
2986 1.1.1.2 christos { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4), 0 },
2987 1.1.1.2 christos { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4), 0 },
2988 1.1.1.2 christos { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4), 0 },
2989 1.1.1.2 christos { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4), 0 },
2990 1.1.1.2 christos { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4), 0 },
2991 1.1.1.2 christos { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4), 0 },
2992 1.1.1.2 christos { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4), 0 },
2993 1.1.1.2 christos { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4), 0 },
2994 1.1.1.2 christos { "dbgbvr10_el1", CPENC(2,0,C0, C10,4), 0 },
2995 1.1.1.2 christos { "dbgbvr11_el1", CPENC(2,0,C0, C11,4), 0 },
2996 1.1.1.2 christos { "dbgbvr12_el1", CPENC(2,0,C0, C12,4), 0 },
2997 1.1.1.2 christos { "dbgbvr13_el1", CPENC(2,0,C0, C13,4), 0 },
2998 1.1.1.2 christos { "dbgbvr14_el1", CPENC(2,0,C0, C14,4), 0 },
2999 1.1.1.2 christos { "dbgbvr15_el1", CPENC(2,0,C0, C15,4), 0 },
3000 1.1.1.2 christos { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5), 0 },
3001 1.1.1.2 christos { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5), 0 },
3002 1.1.1.2 christos { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5), 0 },
3003 1.1.1.2 christos { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5), 0 },
3004 1.1.1.2 christos { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5), 0 },
3005 1.1.1.2 christos { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5), 0 },
3006 1.1.1.2 christos { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5), 0 },
3007 1.1.1.2 christos { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5), 0 },
3008 1.1.1.2 christos { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5), 0 },
3009 1.1.1.2 christos { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5), 0 },
3010 1.1.1.2 christos { "dbgbcr10_el1", CPENC(2,0,C0, C10,5), 0 },
3011 1.1.1.2 christos { "dbgbcr11_el1", CPENC(2,0,C0, C11,5), 0 },
3012 1.1.1.2 christos { "dbgbcr12_el1", CPENC(2,0,C0, C12,5), 0 },
3013 1.1.1.2 christos { "dbgbcr13_el1", CPENC(2,0,C0, C13,5), 0 },
3014 1.1.1.2 christos { "dbgbcr14_el1", CPENC(2,0,C0, C14,5), 0 },
3015 1.1.1.2 christos { "dbgbcr15_el1", CPENC(2,0,C0, C15,5), 0 },
3016 1.1.1.2 christos { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6), 0 },
3017 1.1.1.2 christos { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6), 0 },
3018 1.1.1.2 christos { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6), 0 },
3019 1.1.1.2 christos { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6), 0 },
3020 1.1.1.2 christos { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6), 0 },
3021 1.1.1.2 christos { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6), 0 },
3022 1.1.1.2 christos { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6), 0 },
3023 1.1.1.2 christos { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6), 0 },
3024 1.1.1.2 christos { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6), 0 },
3025 1.1.1.2 christos { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6), 0 },
3026 1.1.1.2 christos { "dbgwvr10_el1", CPENC(2,0,C0, C10,6), 0 },
3027 1.1.1.2 christos { "dbgwvr11_el1", CPENC(2,0,C0, C11,6), 0 },
3028 1.1.1.2 christos { "dbgwvr12_el1", CPENC(2,0,C0, C12,6), 0 },
3029 1.1.1.2 christos { "dbgwvr13_el1", CPENC(2,0,C0, C13,6), 0 },
3030 1.1.1.2 christos { "dbgwvr14_el1", CPENC(2,0,C0, C14,6), 0 },
3031 1.1.1.2 christos { "dbgwvr15_el1", CPENC(2,0,C0, C15,6), 0 },
3032 1.1.1.2 christos { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7), 0 },
3033 1.1.1.2 christos { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7), 0 },
3034 1.1.1.2 christos { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7), 0 },
3035 1.1.1.2 christos { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7), 0 },
3036 1.1.1.2 christos { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7), 0 },
3037 1.1.1.2 christos { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7), 0 },
3038 1.1.1.2 christos { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7), 0 },
3039 1.1.1.2 christos { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7), 0 },
3040 1.1.1.2 christos { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7), 0 },
3041 1.1.1.2 christos { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7), 0 },
3042 1.1.1.2 christos { "dbgwcr10_el1", CPENC(2,0,C0, C10,7), 0 },
3043 1.1.1.2 christos { "dbgwcr11_el1", CPENC(2,0,C0, C11,7), 0 },
3044 1.1.1.2 christos { "dbgwcr12_el1", CPENC(2,0,C0, C12,7), 0 },
3045 1.1.1.2 christos { "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
3046 1.1.1.2 christos { "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
3047 1.1.1.2 christos { "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
3048 1.1.1.2 christos { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
3049 1.1.1.2 christos { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
3050 1.1.1.2 christos { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
3051 1.1.1.2 christos { "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
3052 1.1.1.2 christos { "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
3053 1.1.1.2 christos { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
3054 1.1.1.2 christos { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
3055 1.1.1.2 christos { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
3056 1.1.1.2 christos { "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
3057 1.1.1.2 christos { "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
3058 1.1.1.2 christos { "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
3059 1.1.1.2 christos { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
3060 1.1.1.2 christos { "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
3061 1.1.1.2 christos { "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
3062 1.1.1.2 christos { "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
3063 1.1.1.2 christos { "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
3064 1.1.1.2 christos { "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
3065 1.1.1.2 christos { "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
3066 1.1.1.2 christos { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
3067 1.1.1.2 christos { "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
3068 1.1.1.2 christos { "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
3069 1.1.1.2 christos { "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
3070 1.1.1.2 christos { "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
3071 1.1.1.2 christos { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
3072 1.1.1.2 christos { "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
3073 1.1.1.2 christos { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
3074 1.1.1.2 christos { "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
3075 1.1.1.2 christos { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
3076 1.1.1.2 christos { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
3077 1.1.1.2 christos { "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
3078 1.1.1.2 christos { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
3079 1.1.1.2 christos { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },
3080 1.1.1.2 christos { "pmuserenr_el0", CPENC(3,3,C9,C14, 0), 0 },
3081 1.1.1.2 christos { "pmintenset_el1", CPENC(3,0,C9,C14, 1), 0 },
3082 1.1.1.2 christos { "pmintenclr_el1", CPENC(3,0,C9,C14, 2), 0 },
3083 1.1.1.2 christos { "pmovsset_el0", CPENC(3,3,C9,C14, 3), 0 },
3084 1.1.1.2 christos { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0), 0 },
3085 1.1.1.2 christos { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1), 0 },
3086 1.1.1.2 christos { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2), 0 },
3087 1.1.1.2 christos { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3), 0 },
3088 1.1.1.2 christos { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4), 0 },
3089 1.1.1.2 christos { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5), 0 },
3090 1.1.1.2 christos { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6), 0 },
3091 1.1.1.2 christos { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7), 0 },
3092 1.1.1.2 christos { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0), 0 },
3093 1.1.1.2 christos { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1), 0 },
3094 1.1.1.2 christos { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2), 0 },
3095 1.1.1.2 christos { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3), 0 },
3096 1.1.1.2 christos { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4), 0 },
3097 1.1.1.2 christos { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5), 0 },
3098 1.1.1.2 christos { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6), 0 },
3099 1.1.1.2 christos { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7), 0 },
3100 1.1.1.2 christos { "pmevcntr16_el0", CPENC(3,3,C14,C10,0), 0 },
3101 1.1.1.2 christos { "pmevcntr17_el0", CPENC(3,3,C14,C10,1), 0 },
3102 1.1.1.2 christos { "pmevcntr18_el0", CPENC(3,3,C14,C10,2), 0 },
3103 1.1.1.2 christos { "pmevcntr19_el0", CPENC(3,3,C14,C10,3), 0 },
3104 1.1.1.2 christos { "pmevcntr20_el0", CPENC(3,3,C14,C10,4), 0 },
3105 1.1.1.2 christos { "pmevcntr21_el0", CPENC(3,3,C14,C10,5), 0 },
3106 1.1.1.2 christos { "pmevcntr22_el0", CPENC(3,3,C14,C10,6), 0 },
3107 1.1.1.2 christos { "pmevcntr23_el0", CPENC(3,3,C14,C10,7), 0 },
3108 1.1.1.2 christos { "pmevcntr24_el0", CPENC(3,3,C14,C11,0), 0 },
3109 1.1.1.2 christos { "pmevcntr25_el0", CPENC(3,3,C14,C11,1), 0 },
3110 1.1.1.2 christos { "pmevcntr26_el0", CPENC(3,3,C14,C11,2), 0 },
3111 1.1.1.2 christos { "pmevcntr27_el0", CPENC(3,3,C14,C11,3), 0 },
3112 1.1.1.2 christos { "pmevcntr28_el0", CPENC(3,3,C14,C11,4), 0 },
3113 1.1.1.2 christos { "pmevcntr29_el0", CPENC(3,3,C14,C11,5), 0 },
3114 1.1.1.2 christos { "pmevcntr30_el0", CPENC(3,3,C14,C11,6), 0 },
3115 1.1.1.2 christos { "pmevtyper0_el0", CPENC(3,3,C14,C12,0), 0 },
3116 1.1.1.2 christos { "pmevtyper1_el0", CPENC(3,3,C14,C12,1), 0 },
3117 1.1.1.2 christos { "pmevtyper2_el0", CPENC(3,3,C14,C12,2), 0 },
3118 1.1.1.2 christos { "pmevtyper3_el0", CPENC(3,3,C14,C12,3), 0 },
3119 1.1.1.2 christos { "pmevtyper4_el0", CPENC(3,3,C14,C12,4), 0 },
3120 1.1.1.2 christos { "pmevtyper5_el0", CPENC(3,3,C14,C12,5), 0 },
3121 1.1.1.2 christos { "pmevtyper6_el0", CPENC(3,3,C14,C12,6), 0 },
3122 1.1.1.2 christos { "pmevtyper7_el0", CPENC(3,3,C14,C12,7), 0 },
3123 1.1.1.2 christos { "pmevtyper8_el0", CPENC(3,3,C14,C13,0), 0 },
3124 1.1.1.2 christos { "pmevtyper9_el0", CPENC(3,3,C14,C13,1), 0 },
3125 1.1.1.2 christos { "pmevtyper10_el0", CPENC(3,3,C14,C13,2), 0 },
3126 1.1.1.2 christos { "pmevtyper11_el0", CPENC(3,3,C14,C13,3), 0 },
3127 1.1.1.2 christos { "pmevtyper12_el0", CPENC(3,3,C14,C13,4), 0 },
3128 1.1.1.2 christos { "pmevtyper13_el0", CPENC(3,3,C14,C13,5), 0 },
3129 1.1.1.2 christos { "pmevtyper14_el0", CPENC(3,3,C14,C13,6), 0 },
3130 1.1.1.2 christos { "pmevtyper15_el0", CPENC(3,3,C14,C13,7), 0 },
3131 1.1.1.2 christos { "pmevtyper16_el0", CPENC(3,3,C14,C14,0), 0 },
3132 1.1.1.2 christos { "pmevtyper17_el0", CPENC(3,3,C14,C14,1), 0 },
3133 1.1.1.2 christos { "pmevtyper18_el0", CPENC(3,3,C14,C14,2), 0 },
3134 1.1.1.2 christos { "pmevtyper19_el0", CPENC(3,3,C14,C14,3), 0 },
3135 1.1.1.2 christos { "pmevtyper20_el0", CPENC(3,3,C14,C14,4), 0 },
3136 1.1.1.2 christos { "pmevtyper21_el0", CPENC(3,3,C14,C14,5), 0 },
3137 1.1.1.2 christos { "pmevtyper22_el0", CPENC(3,3,C14,C14,6), 0 },
3138 1.1.1.2 christos { "pmevtyper23_el0", CPENC(3,3,C14,C14,7), 0 },
3139 1.1.1.2 christos { "pmevtyper24_el0", CPENC(3,3,C14,C15,0), 0 },
3140 1.1.1.2 christos { "pmevtyper25_el0", CPENC(3,3,C14,C15,1), 0 },
3141 1.1.1.2 christos { "pmevtyper26_el0", CPENC(3,3,C14,C15,2), 0 },
3142 1.1.1.2 christos { "pmevtyper27_el0", CPENC(3,3,C14,C15,3), 0 },
3143 1.1.1.2 christos { "pmevtyper28_el0", CPENC(3,3,C14,C15,4), 0 },
3144 1.1 christos { "pmevtyper29_el0", CPENC(3,3,C14,C15,5), 0 },
3145 1.1 christos { "pmevtyper30_el0", CPENC(3,3,C14,C15,6), 0 },
3146 1.1.1.2 christos { "pmccfiltr_el0", CPENC(3,3,C14,C15,7), 0 },
3147 1.1.1.2 christos { 0, CPENC(0,0,0,0,0), 0 },
3148 1.1 christos };
3149 1.1.1.2 christos
3150 1.1.1.2 christos bfd_boolean
3151 1.1.1.2 christos aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
3152 1.1.1.2 christos {
3153 1.1.1.2 christos return (reg->flags & F_DEPRECATED) != 0;
3154 1.1.1.2 christos }
3155 1.1.1.2 christos
3156 1.1.1.2 christos bfd_boolean
3157 1.1.1.2 christos aarch64_sys_reg_supported_p (const aarch64_feature_set features,
3158 1.1.1.2 christos const aarch64_sys_reg *reg)
3159 1.1.1.2 christos {
3160 1.1.1.2 christos if (!(reg->flags & F_ARCHEXT))
3161 1.1.1.2 christos return TRUE;
3162 1.1.1.2 christos
3163 1.1.1.2 christos /* PAN. Values are from aarch64_sys_regs. */
3164 1.1.1.2 christos if (reg->value == CPEN_(0,C2,3)
3165 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3166 1.1.1.2 christos return FALSE;
3167 1.1.1.2 christos
3168 1.1.1.2 christos /* Virtualization host extensions: system registers. */
3169 1.1.1.2 christos if ((reg->value == CPENC (3, 4, C2, C0, 1)
3170 1.1.1.2 christos || reg->value == CPENC (3, 4, C13, C0, 1)
3171 1.1.1.2 christos || reg->value == CPENC (3, 4, C14, C3, 0)
3172 1.1.1.2 christos || reg->value == CPENC (3, 4, C14, C3, 1)
3173 1.1.1.2 christos || reg->value == CPENC (3, 4, C14, C3, 2))
3174 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3175 1.1.1.2 christos return FALSE;
3176 1.1.1.2 christos
3177 1.1.1.2 christos /* Virtualization host extensions: *_el12 names of *_el1 registers. */
3178 1.1.1.2 christos if ((reg->value == CPEN_ (5, C0, 0)
3179 1.1.1.2 christos || reg->value == CPEN_ (5, C0, 1)
3180 1.1.1.2 christos || reg->value == CPENC (3, 5, C1, C0, 0)
3181 1.1.1.2 christos || reg->value == CPENC (3, 5, C1, C0, 2)
3182 1.1.1.2 christos || reg->value == CPENC (3, 5, C2, C0, 0)
3183 1.1.1.2 christos || reg->value == CPENC (3, 5, C2, C0, 1)
3184 1.1.1.2 christos || reg->value == CPENC (3, 5, C2, C0, 2)
3185 1.1.1.2 christos || reg->value == CPENC (3, 5, C5, C1, 0)
3186 1.1.1.2 christos || reg->value == CPENC (3, 5, C5, C1, 1)
3187 1.1.1.2 christos || reg->value == CPENC (3, 5, C5, C2, 0)
3188 1.1.1.2 christos || reg->value == CPENC (3, 5, C6, C0, 0)
3189 1.1.1.2 christos || reg->value == CPENC (3, 5, C10, C2, 0)
3190 1.1.1.2 christos || reg->value == CPENC (3, 5, C10, C3, 0)
3191 1.1.1.2 christos || reg->value == CPENC (3, 5, C12, C0, 0)
3192 1.1.1.2 christos || reg->value == CPENC (3, 5, C13, C0, 1)
3193 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C1, 0))
3194 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3195 1.1.1.2 christos return FALSE;
3196 1.1.1.2 christos
3197 1.1.1.2 christos /* Virtualization host extensions: *_el02 names of *_el0 registers. */
3198 1.1.1.2 christos if ((reg->value == CPENC (3, 5, C14, C2, 0)
3199 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C2, 1)
3200 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C2, 2)
3201 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C3, 0)
3202 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C3, 1)
3203 1.1.1.2 christos || reg->value == CPENC (3, 5, C14, C3, 2))
3204 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3205 1.1.1.2 christos return FALSE;
3206 1.1.1.2 christos
3207 1.1.1.2 christos /* ARMv8.2 features. */
3208 1.1.1.2 christos
3209 1.1.1.2 christos /* ID_AA64MMFR2_EL1. */
3210 1.1.1.2 christos if (reg->value == CPENC (3, 0, C0, C7, 2)
3211 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3212 1.1.1.2 christos return FALSE;
3213 1.1.1.2 christos
3214 1.1.1.2 christos /* PSTATE.UAO. */
3215 1.1.1.2 christos if (reg->value == CPEN_ (0, C2, 4)
3216 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3217 1.1.1.2 christos return FALSE;
3218 1.1.1.2 christos
3219 1.1.1.2 christos /* RAS extension. */
3220 1.1.1.2 christos
3221 1.1.1.2 christos /* ERRIDR_EL1 and ERRSELR_EL1. */
3222 1.1.1.2 christos if ((reg->value == CPENC (3, 0, C5, C3, 0)
3223 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C3, 1))
3224 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
3225 1.1.1.2 christos return FALSE;
3226 1.1.1.2 christos
3227 1.1.1.2 christos /* ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1, ERXMISC0_EL1 AND
3228 1.1.1.2 christos ERXMISC1_EL1. */
3229 1.1.1.2 christos if ((reg->value == CPENC (3, 0, C5, C3, 0)
3230 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C3 ,1)
3231 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C3, 2)
3232 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C3, 3)
3233 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C5, 0)
3234 1.1.1.2 christos || reg->value == CPENC (3, 0, C5, C5, 1))
3235 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
3236 1.1.1.2 christos return FALSE;
3237 1.1.1.2 christos
3238 1.1.1.2 christos /* VSESR_EL2, DISR_EL1 and VDISR_EL2. */
3239 1.1.1.2 christos if ((reg->value == CPENC (3, 4, C5, C2, 3)
3240 1.1.1.2 christos || reg->value == CPENC (3, 0, C12, C1, 1)
3241 1.1.1.2 christos || reg->value == CPENC (3, 4, C12, C1, 1))
3242 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
3243 1.1.1.2 christos return FALSE;
3244 1.1.1.2 christos
3245 1.1.1.2 christos /* Statistical Profiling extension. */
3246 1.1.1.2 christos if ((reg->value == CPENC (3, 0, C9, C10, 0)
3247 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C10, 1)
3248 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C10, 3)
3249 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C10, 7)
3250 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 0)
3251 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 2)
3252 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 3)
3253 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 4)
3254 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 5)
3255 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 6)
3256 1.1.1.2 christos || reg->value == CPENC (3, 0, C9, C9, 7)
3257 1.1.1.2 christos || reg->value == CPENC (3, 4, C9, C9, 0)
3258 1.1.1.2 christos || reg->value == CPENC (3, 5, C9, C9, 0))
3259 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
3260 1.1.1.2 christos return FALSE;
3261 1.1.1.2 christos
3262 1.1.1.2 christos return TRUE;
3263 1.1.1.2 christos }
3264 1.1.1.2 christos
3265 1.1.1.2 christos const aarch64_sys_reg aarch64_pstatefields [] =
3266 1.1.1.2 christos {
3267 1.1.1.2 christos { "spsel", 0x05, 0 },
3268 1.1.1.2 christos { "daifset", 0x1e, 0 },
3269 1.1 christos { "daifclr", 0x1f, 0 },
3270 1.1 christos { "pan", 0x04, F_ARCHEXT },
3271 1.1.1.2 christos { "uao", 0x03, F_ARCHEXT },
3272 1.1.1.2 christos { 0, CPENC(0,0,0,0,0), 0 },
3273 1.1.1.2 christos };
3274 1.1.1.2 christos
3275 1.1.1.2 christos bfd_boolean
3276 1.1.1.2 christos aarch64_pstatefield_supported_p (const aarch64_feature_set features,
3277 1.1.1.2 christos const aarch64_sys_reg *reg)
3278 1.1.1.2 christos {
3279 1.1.1.2 christos if (!(reg->flags & F_ARCHEXT))
3280 1.1.1.2 christos return TRUE;
3281 1.1.1.2 christos
3282 1.1.1.2 christos /* PAN. Values are from aarch64_pstatefields. */
3283 1.1.1.2 christos if (reg->value == 0x04
3284 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3285 1.1.1.2 christos return FALSE;
3286 1.1.1.2 christos
3287 1.1.1.2 christos /* UAO. Values are from aarch64_pstatefields. */
3288 1.1.1.2 christos if (reg->value == 0x03
3289 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3290 1.1.1.2 christos return FALSE;
3291 1.1 christos
3292 1.1 christos return TRUE;
3293 1.1 christos }
3294 1.1 christos
3295 1.1.1.2 christos const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
3296 1.1 christos {
3297 1.1 christos { "ialluis", CPENS(0,C7,C1,0), 0 },
3298 1.1 christos { "iallu", CPENS(0,C7,C5,0), 0 },
3299 1.1 christos { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
3300 1.1 christos { 0, CPENS(0,0,0,0), 0 }
3301 1.1.1.2 christos };
3302 1.1.1.2 christos
3303 1.1.1.2 christos const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
3304 1.1.1.2 christos {
3305 1.1.1.2 christos { "zva", CPENS (3, C7, C4, 1), F_HASXT },
3306 1.1.1.2 christos { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
3307 1.1.1.2 christos { "isw", CPENS (0, C7, C6, 2), F_HASXT },
3308 1.1.1.2 christos { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
3309 1.1.1.2 christos { "csw", CPENS (0, C7, C10, 2), F_HASXT },
3310 1.1 christos { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
3311 1.1 christos { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
3312 1.1 christos { "civac", CPENS (3, C7, C14, 1), F_HASXT },
3313 1.1 christos { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
3314 1.1 christos { 0, CPENS(0,0,0,0), 0 }
3315 1.1.1.2 christos };
3316 1.1.1.2 christos
3317 1.1.1.2 christos const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
3318 1.1.1.2 christos {
3319 1.1.1.2 christos { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
3320 1.1.1.2 christos { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
3321 1.1.1.2 christos { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
3322 1.1.1.2 christos { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
3323 1.1.1.2 christos { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
3324 1.1.1.2 christos { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
3325 1.1.1.2 christos { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
3326 1.1.1.2 christos { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
3327 1.1.1.2 christos { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
3328 1.1.1.2 christos { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
3329 1.1 christos { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
3330 1.1 christos { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
3331 1.1 christos { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
3332 1.1 christos { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
3333 1.1 christos { 0, CPENS(0,0,0,0), 0 }
3334 1.1 christos };
3335 1.1.1.2 christos
3336 1.1.1.2 christos const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
3337 1.1.1.2 christos {
3338 1.1 christos { "vmalle1", CPENS(0,C8,C7,0), 0 },
3339 1.1.1.2 christos { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
3340 1.1.1.2 christos { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
3341 1.1.1.2 christos { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
3342 1.1.1.2 christos { "vmalle1is", CPENS(0,C8,C3,0), 0 },
3343 1.1.1.2 christos { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
3344 1.1.1.2 christos { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
3345 1.1.1.2 christos { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
3346 1.1.1.2 christos { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
3347 1.1.1.2 christos { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
3348 1.1 christos { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
3349 1.1 christos { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
3350 1.1.1.2 christos { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
3351 1.1.1.2 christos { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
3352 1.1 christos { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
3353 1.1 christos { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
3354 1.1 christos { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
3355 1.1 christos { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
3356 1.1 christos { "alle2", CPENS(4,C8,C7,0), 0 },
3357 1.1 christos { "alle2is", CPENS(4,C8,C3,0), 0 },
3358 1.1.1.2 christos { "alle1", CPENS(4,C8,C7,4), 0 },
3359 1.1.1.2 christos { "alle1is", CPENS(4,C8,C3,4), 0 },
3360 1.1.1.2 christos { "alle3", CPENS(6,C8,C7,0), 0 },
3361 1.1.1.2 christos { "alle3is", CPENS(6,C8,C3,0), 0 },
3362 1.1.1.2 christos { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
3363 1.1.1.2 christos { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
3364 1.1.1.2 christos { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
3365 1.1.1.2 christos { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
3366 1.1 christos { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
3367 1.1 christos { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
3368 1.1 christos { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
3369 1.1.1.2 christos { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
3370 1.1.1.2 christos { 0, CPENS(0,0,0,0), 0 }
3371 1.1.1.2 christos };
3372 1.1.1.2 christos
3373 1.1.1.2 christos bfd_boolean
3374 1.1.1.2 christos aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
3375 1.1.1.2 christos {
3376 1.1.1.2 christos return (sys_ins_reg->flags & F_HASXT) != 0;
3377 1.1.1.2 christos }
3378 1.1.1.2 christos
3379 1.1.1.2 christos extern bfd_boolean
3380 1.1.1.2 christos aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
3381 1.1.1.2 christos const aarch64_sys_ins_reg *reg)
3382 1.1.1.2 christos {
3383 1.1.1.2 christos if (!(reg->flags & F_ARCHEXT))
3384 1.1.1.2 christos return TRUE;
3385 1.1.1.2 christos
3386 1.1.1.2 christos /* DC CVAP. Values are from aarch64_sys_regs_dc. */
3387 1.1.1.2 christos if (reg->value == CPENS (3, C7, C12, 1)
3388 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3389 1.1.1.2 christos return FALSE;
3390 1.1.1.2 christos
3391 1.1.1.2 christos /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
3392 1.1.1.2 christos if ((reg->value == CPENS (0, C7, C9, 0)
3393 1.1.1.2 christos || reg->value == CPENS (0, C7, C9, 1))
3394 1.1.1.2 christos && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3395 1.1.1.2 christos return FALSE;
3396 1.1 christos
3397 1.1 christos return TRUE;
3398 1.1 christos }
3399 1.1 christos
3400 1.1 christos #undef C0
3401 1.1 christos #undef C1
3402 1.1 christos #undef C2
3403 1.1 christos #undef C3
3404 1.1 christos #undef C4
3405 1.1 christos #undef C5
3406 1.1 christos #undef C6
3407 1.1 christos #undef C7
3408 1.1 christos #undef C8
3409 1.1 christos #undef C9
3410 1.1 christos #undef C10
3411 1.1 christos #undef C11
3412 1.1 christos #undef C12
3413 1.1 christos #undef C13
3414 1.1 christos #undef C14
3415 1.1 christos #undef C15
3416
3417 /* Include the opcode description table as well as the operand description
3418 table. */
3419 #include "aarch64-tbl.h"
3420