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