aarch64-dis.c revision 1.6 1 1.1 christos /* aarch64-dis.c -- AArch64 disassembler.
2 1.6 christos Copyright (C) 2009-2018 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 "bfd_stdint.h"
23 1.6 christos #include "disassemble.h"
24 1.1 christos #include "libiberty.h"
25 1.1 christos #include "opintl.h"
26 1.1 christos #include "aarch64-dis.h"
27 1.1 christos #include "elf-bfd.h"
28 1.1 christos
29 1.1 christos #define ERR_OK 0
30 1.1 christos #define ERR_UND -1
31 1.1 christos #define ERR_UNP -3
32 1.1 christos #define ERR_NYI -5
33 1.1 christos
34 1.1 christos #define INSNLEN 4
35 1.1 christos
36 1.1 christos /* Cached mapping symbol state. */
37 1.1 christos enum map_type
38 1.1 christos {
39 1.1 christos MAP_INSN,
40 1.1 christos MAP_DATA
41 1.1 christos };
42 1.1 christos
43 1.1 christos static enum map_type last_type;
44 1.1 christos static int last_mapping_sym = -1;
45 1.1 christos static bfd_vma last_mapping_addr = 0;
46 1.1 christos
47 1.1 christos /* Other options */
48 1.1 christos static int no_aliases = 0; /* If set disassemble as most general inst. */
49 1.6 christos static int no_notes = 1; /* If set do not print disassemble notes in the
51 1.1 christos output as comments. */
52 1.1 christos
53 1.1 christos static void
54 1.1 christos set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
55 1.1 christos {
56 1.1 christos }
57 1.1 christos
58 1.1 christos static void
59 1.1 christos parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
60 1.1 christos {
61 1.1 christos /* Try to match options that are simple flags */
62 1.1 christos if (CONST_STRNEQ (option, "no-aliases"))
63 1.1 christos {
64 1.1 christos no_aliases = 1;
65 1.1 christos return;
66 1.1 christos }
67 1.1 christos
68 1.1 christos if (CONST_STRNEQ (option, "aliases"))
69 1.1 christos {
70 1.1 christos no_aliases = 0;
71 1.1 christos return;
72 1.1 christos }
73 1.6 christos
74 1.6 christos if (CONST_STRNEQ (option, "no-notes"))
75 1.6 christos {
76 1.6 christos no_notes = 1;
77 1.6 christos return;
78 1.6 christos }
79 1.6 christos
80 1.6 christos if (CONST_STRNEQ (option, "notes"))
81 1.6 christos {
82 1.6 christos no_notes = 0;
83 1.6 christos return;
84 1.6 christos }
85 1.1 christos
86 1.1 christos #ifdef DEBUG_AARCH64
87 1.1 christos if (CONST_STRNEQ (option, "debug_dump"))
88 1.1 christos {
89 1.1 christos debug_dump = 1;
90 1.1 christos return;
91 1.1 christos }
92 1.1 christos #endif /* DEBUG_AARCH64 */
93 1.1 christos
94 1.6 christos /* Invalid option. */
95 1.1 christos opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
96 1.1 christos }
97 1.1 christos
98 1.1 christos static void
99 1.1 christos parse_aarch64_dis_options (const char *options)
100 1.1 christos {
101 1.1 christos const char *option_end;
102 1.1 christos
103 1.1 christos if (options == NULL)
104 1.1 christos return;
105 1.1 christos
106 1.1 christos while (*options != '\0')
107 1.1 christos {
108 1.1 christos /* Skip empty options. */
109 1.1 christos if (*options == ',')
110 1.1 christos {
111 1.1 christos options++;
112 1.1 christos continue;
113 1.1 christos }
114 1.1 christos
115 1.1 christos /* We know that *options is neither NUL or a comma. */
116 1.1 christos option_end = options + 1;
117 1.1 christos while (*option_end != ',' && *option_end != '\0')
118 1.1 christos option_end++;
119 1.1 christos
120 1.1 christos parse_aarch64_dis_option (options, option_end - options);
121 1.1 christos
122 1.1 christos /* Go on to the next one. If option_end points to a comma, it
123 1.1 christos will be skipped above. */
124 1.1 christos options = option_end;
125 1.1 christos }
126 1.1 christos }
127 1.1 christos
128 1.1 christos /* Functions doing the instruction disassembling. */
130 1.1 christos
131 1.1 christos /* The unnamed arguments consist of the number of fields and information about
132 1.1 christos these fields where the VALUE will be extracted from CODE and returned.
133 1.1 christos MASK can be zero or the base mask of the opcode.
134 1.1 christos
135 1.1 christos N.B. the fields are required to be in such an order than the most signficant
136 1.3 christos field for VALUE comes the first, e.g. the <index> in
137 1.1 christos SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
138 1.1 christos is encoded in H:L:M in some cases, the fields H:L:M should be passed in
139 1.6 christos the order of H, L, M. */
140 1.1 christos
141 1.1 christos aarch64_insn
142 1.1 christos extract_fields (aarch64_insn code, aarch64_insn mask, ...)
143 1.1 christos {
144 1.1 christos uint32_t num;
145 1.1 christos const aarch64_field *field;
146 1.3 christos enum aarch64_field_kind kind;
147 1.1 christos va_list va;
148 1.1 christos
149 1.1 christos va_start (va, mask);
150 1.1 christos num = va_arg (va, uint32_t);
151 1.1 christos assert (num <= 5);
152 1.1 christos aarch64_insn value = 0x0;
153 1.1 christos while (num--)
154 1.1 christos {
155 1.1 christos kind = va_arg (va, enum aarch64_field_kind);
156 1.1 christos field = &fields[kind];
157 1.1 christos value <<= field->width;
158 1.1 christos value |= extract_field (kind, code, mask);
159 1.1 christos }
160 1.1 christos return value;
161 1.6 christos }
162 1.6 christos
163 1.6 christos /* Extract the value of all fields in SELF->fields from instruction CODE.
164 1.6 christos The least significant bit comes from the final field. */
165 1.6 christos
166 1.6 christos static aarch64_insn
167 1.6 christos extract_all_fields (const aarch64_operand *self, aarch64_insn code)
168 1.6 christos {
169 1.6 christos aarch64_insn value;
170 1.6 christos unsigned int i;
171 1.6 christos enum aarch64_field_kind kind;
172 1.6 christos
173 1.6 christos value = 0;
174 1.6 christos for (i = 0; i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i)
175 1.6 christos {
176 1.6 christos kind = self->fields[i];
177 1.6 christos value <<= fields[kind].width;
178 1.6 christos value |= extract_field (kind, code, 0);
179 1.6 christos }
180 1.6 christos return value;
181 1.1 christos }
182 1.1 christos
183 1.1 christos /* Sign-extend bit I of VALUE. */
184 1.1 christos static inline int32_t
185 1.1 christos sign_extend (aarch64_insn value, unsigned i)
186 1.3 christos {
187 1.1 christos uint32_t ret = value;
188 1.1 christos
189 1.1 christos assert (i < 32);
190 1.1 christos if ((value >> i) & 0x1)
191 1.1 christos {
192 1.1 christos uint32_t val = (uint32_t)(-1) << i;
193 1.1 christos ret = ret | val;
194 1.1 christos }
195 1.1 christos return (int32_t) ret;
196 1.1 christos }
197 1.1 christos
198 1.1 christos /* N.B. the following inline helpfer functions create a dependency on the
199 1.1 christos order of operand qualifier enumerators. */
200 1.1 christos
201 1.1 christos /* Given VALUE, return qualifier for a general purpose register. */
202 1.1 christos static inline enum aarch64_opnd_qualifier
203 1.1 christos get_greg_qualifier_from_value (aarch64_insn value)
204 1.1 christos {
205 1.1 christos enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
206 1.1 christos assert (value <= 0x1
207 1.1 christos && aarch64_get_qualifier_standard_value (qualifier) == value);
208 1.1 christos return qualifier;
209 1.3 christos }
210 1.3 christos
211 1.3 christos /* Given VALUE, return qualifier for a vector register. This does not support
212 1.1 christos decoding instructions that accept the 2H vector type. */
213 1.1 christos
214 1.1 christos static inline enum aarch64_opnd_qualifier
215 1.1 christos get_vreg_qualifier_from_value (aarch64_insn value)
216 1.3 christos {
217 1.3 christos enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
218 1.3 christos
219 1.3 christos /* Instructions using vector type 2H should not call this function. Skip over
220 1.3 christos the 2H qualifier. */
221 1.3 christos if (qualifier >= AARCH64_OPND_QLF_V_2H)
222 1.1 christos qualifier += 1;
223 1.1 christos
224 1.1 christos assert (value <= 0x8
225 1.1 christos && aarch64_get_qualifier_standard_value (qualifier) == value);
226 1.1 christos return qualifier;
227 1.1 christos }
228 1.1 christos
229 1.1 christos /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
230 1.1 christos static inline enum aarch64_opnd_qualifier
231 1.1 christos get_sreg_qualifier_from_value (aarch64_insn value)
232 1.3 christos {
233 1.1 christos enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
234 1.1 christos
235 1.1 christos assert (value <= 0x4
236 1.1 christos && aarch64_get_qualifier_standard_value (qualifier) == value);
237 1.1 christos return qualifier;
238 1.1 christos }
239 1.1 christos
240 1.1 christos /* Given the instruction in *INST which is probably half way through the
241 1.1 christos decoding and our caller wants to know the expected qualifier for operand
242 1.1 christos I. Return such a qualifier if we can establish it; otherwise return
243 1.1 christos AARCH64_OPND_QLF_NIL. */
244 1.1 christos
245 1.1 christos static aarch64_opnd_qualifier_t
246 1.1 christos get_expected_qualifier (const aarch64_inst *inst, int i)
247 1.1 christos {
248 1.1 christos aarch64_opnd_qualifier_seq_t qualifiers;
249 1.1 christos /* Should not be called if the qualifier is known. */
250 1.1 christos assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
251 1.1 christos if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
252 1.1 christos i, qualifiers))
253 1.1 christos return qualifiers[i];
254 1.1 christos else
255 1.1 christos return AARCH64_OPND_QLF_NIL;
256 1.1 christos }
257 1.1 christos
258 1.6 christos /* Operand extractors. */
259 1.1 christos
260 1.1 christos bfd_boolean
261 1.6 christos aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
262 1.6 christos const aarch64_insn code,
263 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
264 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
265 1.6 christos {
266 1.1 christos info->reg.regno = extract_field (self->fields[0], code, 0);
267 1.1 christos return TRUE;
268 1.6 christos }
269 1.3 christos
270 1.3 christos bfd_boolean
271 1.6 christos aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
272 1.6 christos const aarch64_insn code ATTRIBUTE_UNUSED,
273 1.3 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
274 1.3 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
275 1.3 christos {
276 1.3 christos assert (info->idx == 1
277 1.6 christos || info->idx ==3);
278 1.3 christos info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
279 1.3 christos return TRUE;
280 1.1 christos }
281 1.6 christos
282 1.1 christos /* e.g. IC <ic_op>{, <Xt>}. */
283 1.1 christos bfd_boolean
284 1.6 christos aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
285 1.6 christos const aarch64_insn code,
286 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
287 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
288 1.1 christos {
289 1.1 christos info->reg.regno = extract_field (self->fields[0], code, 0);
290 1.1 christos assert (info->idx == 1
291 1.1 christos && (aarch64_get_operand_class (inst->operands[0].type)
292 1.1 christos == AARCH64_OPND_CLASS_SYSTEM));
293 1.1 christos /* This will make the constraint checking happy and more importantly will
294 1.3 christos help the disassembler determine whether this operand is optional or
295 1.1 christos not. */
296 1.6 christos info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
297 1.1 christos
298 1.1 christos return TRUE;
299 1.1 christos }
300 1.6 christos
301 1.1 christos /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
302 1.1 christos bfd_boolean
303 1.6 christos aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
304 1.6 christos const aarch64_insn code,
305 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
306 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
307 1.1 christos {
308 1.1 christos /* regno */
309 1.1 christos info->reglane.regno = extract_field (self->fields[0], code,
310 1.3 christos inst->opcode->mask);
311 1.1 christos
312 1.1 christos /* Index and/or type. */
313 1.1 christos if (inst->opcode->iclass == asisdone
314 1.1 christos || inst->opcode->iclass == asimdins)
315 1.1 christos {
316 1.1 christos if (info->type == AARCH64_OPND_En
317 1.1 christos && inst->opcode->operands[0] == AARCH64_OPND_Ed)
318 1.1 christos {
319 1.1 christos unsigned shift;
320 1.1 christos /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
321 1.1 christos assert (info->idx == 1); /* Vn */
322 1.1 christos aarch64_insn value = extract_field (FLD_imm4, code, 0);
323 1.1 christos /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
324 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
325 1.1 christos shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
326 1.1 christos info->reglane.index = value >> shift;
327 1.1 christos }
328 1.1 christos else
329 1.1 christos {
330 1.1 christos /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
331 1.1 christos imm5<3:0> <V>
332 1.1 christos 0000 RESERVED
333 1.1 christos xxx1 B
334 1.1 christos xx10 H
335 1.1 christos x100 S
336 1.1 christos 1000 D */
337 1.1 christos int pos = -1;
338 1.1 christos aarch64_insn value = extract_field (FLD_imm5, code, 0);
339 1.1 christos while (++pos <= 3 && (value & 0x1) == 0)
340 1.6 christos value >>= 1;
341 1.1 christos if (pos > 3)
342 1.1 christos return FALSE;
343 1.1 christos info->qualifier = get_sreg_qualifier_from_value (pos);
344 1.1 christos info->reglane.index = (unsigned) (value >> 1);
345 1.6 christos }
346 1.6 christos }
347 1.6 christos else if (inst->opcode->iclass == dotproduct)
348 1.6 christos {
349 1.6 christos /* Need information in other operand(s) to help decoding. */
350 1.6 christos info->qualifier = get_expected_qualifier (inst, info->idx);
351 1.6 christos switch (info->qualifier)
352 1.6 christos {
353 1.6 christos case AARCH64_OPND_QLF_S_4B:
354 1.6 christos /* L:H */
355 1.6 christos info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
356 1.6 christos info->reglane.regno &= 0x1f;
357 1.6 christos break;
358 1.6 christos default:
359 1.6 christos return FALSE;
360 1.6 christos }
361 1.6 christos }
362 1.6 christos else if (inst->opcode->iclass == cryptosm3)
363 1.6 christos {
364 1.6 christos /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
365 1.1 christos info->reglane.index = extract_field (FLD_SM3_imm2, code, 0);
366 1.1 christos }
367 1.3 christos else
368 1.1 christos {
369 1.1 christos /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
370 1.1 christos or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
371 1.1 christos
372 1.1 christos /* Need information in other operand(s) to help decoding. */
373 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
374 1.1 christos switch (info->qualifier)
375 1.6 christos {
376 1.6 christos case AARCH64_OPND_QLF_S_H:
377 1.6 christos if (info->type == AARCH64_OPND_Em16)
378 1.6 christos {
379 1.6 christos /* h:l:m */
380 1.6 christos info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
381 1.6 christos FLD_M);
382 1.6 christos info->reglane.regno &= 0xf;
383 1.6 christos }
384 1.6 christos else
385 1.6 christos {
386 1.6 christos /* h:l */
387 1.1 christos info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
388 1.1 christos }
389 1.1 christos break;
390 1.1 christos case AARCH64_OPND_QLF_S_S:
391 1.1 christos /* h:l */
392 1.1 christos info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
393 1.1 christos break;
394 1.1 christos case AARCH64_OPND_QLF_S_D:
395 1.1 christos /* H */
396 1.1 christos info->reglane.index = extract_field (FLD_H, code, 0);
397 1.6 christos break;
398 1.6 christos default:
399 1.6 christos return FALSE;
400 1.6 christos }
401 1.6 christos
402 1.6 christos if (inst->opcode->op == OP_FCMLA_ELEM
403 1.6 christos && info->qualifier != AARCH64_OPND_QLF_S_H)
404 1.6 christos {
405 1.6 christos /* Complex operand takes two elements. */
406 1.6 christos if (info->reglane.index & 1)
407 1.1 christos return FALSE;
408 1.1 christos info->reglane.index /= 2;
409 1.1 christos }
410 1.6 christos }
411 1.1 christos
412 1.1 christos return TRUE;
413 1.6 christos }
414 1.1 christos
415 1.1 christos bfd_boolean
416 1.6 christos aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
417 1.6 christos const aarch64_insn code,
418 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
419 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
420 1.1 christos {
421 1.1 christos /* R */
422 1.1 christos info->reglist.first_regno = extract_field (self->fields[0], code, 0);
423 1.6 christos /* len */
424 1.1 christos info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
425 1.1 christos return TRUE;
426 1.1 christos }
427 1.6 christos
428 1.1 christos /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
429 1.1 christos bfd_boolean
430 1.6 christos aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
431 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
432 1.1 christos const aarch64_inst *inst,
433 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
434 1.1 christos {
435 1.1 christos aarch64_insn value;
436 1.1 christos /* Number of elements in each structure to be loaded/stored. */
437 1.1 christos unsigned expected_num = get_opcode_dependent_value (inst->opcode);
438 1.1 christos
439 1.1 christos struct
440 1.1 christos {
441 1.1 christos unsigned is_reserved;
442 1.1 christos unsigned num_regs;
443 1.1 christos unsigned num_elements;
444 1.1 christos } data [] =
445 1.1 christos { {0, 4, 4},
446 1.1 christos {1, 4, 4},
447 1.1 christos {0, 4, 1},
448 1.1 christos {0, 4, 2},
449 1.1 christos {0, 3, 3},
450 1.1 christos {1, 3, 3},
451 1.1 christos {0, 3, 1},
452 1.1 christos {0, 1, 1},
453 1.1 christos {0, 2, 2},
454 1.1 christos {1, 2, 2},
455 1.1 christos {0, 2, 1},
456 1.1 christos };
457 1.1 christos
458 1.1 christos /* Rt */
459 1.1 christos info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
460 1.6 christos /* opcode */
461 1.6 christos value = extract_field (FLD_opcode, code, 0);
462 1.6 christos /* PR 21595: Check for a bogus value. */
463 1.1 christos if (value >= ARRAY_SIZE (data))
464 1.6 christos return FALSE;
465 1.1 christos if (expected_num != data[value].num_elements || data[value].is_reserved)
466 1.1 christos return FALSE;
467 1.6 christos info->reglist.num_regs = data[value].num_regs;
468 1.1 christos
469 1.1 christos return TRUE;
470 1.1 christos }
471 1.1 christos
472 1.6 christos /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
473 1.1 christos lanes instructions. */
474 1.1 christos bfd_boolean
475 1.6 christos aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
476 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
477 1.1 christos const aarch64_inst *inst,
478 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
479 1.1 christos {
480 1.1 christos aarch64_insn value;
481 1.1 christos
482 1.1 christos /* Rt */
483 1.1 christos info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
484 1.1 christos /* S */
485 1.1 christos value = extract_field (FLD_S, code, 0);
486 1.1 christos
487 1.1 christos /* Number of registers is equal to the number of elements in
488 1.1 christos each structure to be loaded/stored. */
489 1.1 christos info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
490 1.1 christos assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
491 1.1 christos
492 1.1 christos /* Except when it is LD1R. */
493 1.1 christos if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
494 1.6 christos info->reglist.num_regs = 2;
495 1.1 christos
496 1.1 christos return TRUE;
497 1.1 christos }
498 1.1 christos
499 1.6 christos /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
500 1.1 christos load/store single element instructions. */
501 1.1 christos bfd_boolean
502 1.6 christos aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
503 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
504 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
505 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
506 1.1 christos {
507 1.1 christos aarch64_field field = {0, 0};
508 1.1 christos aarch64_insn QSsize; /* fields Q:S:size. */
509 1.1 christos aarch64_insn opcodeh2; /* opcode<2:1> */
510 1.1 christos
511 1.1 christos /* Rt */
512 1.1 christos info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
513 1.1 christos
514 1.1 christos /* Decode the index, opcode<2:1> and size. */
515 1.1 christos gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
516 1.1 christos opcodeh2 = extract_field_2 (&field, code, 0);
517 1.1 christos QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
518 1.1 christos switch (opcodeh2)
519 1.1 christos {
520 1.1 christos case 0x0:
521 1.1 christos info->qualifier = AARCH64_OPND_QLF_S_B;
522 1.1 christos /* Index encoded in "Q:S:size". */
523 1.1 christos info->reglist.index = QSsize;
524 1.3 christos break;
525 1.3 christos case 0x1:
526 1.6 christos if (QSsize & 0x1)
527 1.1 christos /* UND. */
528 1.1 christos return FALSE;
529 1.1 christos info->qualifier = AARCH64_OPND_QLF_S_H;
530 1.1 christos /* Index encoded in "Q:S:size<1>". */
531 1.1 christos info->reglist.index = QSsize >> 1;
532 1.3 christos break;
533 1.3 christos case 0x2:
534 1.6 christos if ((QSsize >> 1) & 0x1)
535 1.1 christos /* UND. */
536 1.1 christos return FALSE;
537 1.1 christos if ((QSsize & 0x1) == 0)
538 1.1 christos {
539 1.1 christos info->qualifier = AARCH64_OPND_QLF_S_S;
540 1.1 christos /* Index encoded in "Q:S". */
541 1.1 christos info->reglist.index = QSsize >> 2;
542 1.1 christos }
543 1.3 christos else
544 1.3 christos {
545 1.6 christos if (extract_field (FLD_S, code, 0))
546 1.1 christos /* UND */
547 1.1 christos return FALSE;
548 1.1 christos info->qualifier = AARCH64_OPND_QLF_S_D;
549 1.1 christos /* Index encoded in "Q". */
550 1.1 christos info->reglist.index = QSsize >> 3;
551 1.1 christos }
552 1.6 christos break;
553 1.1 christos default:
554 1.1 christos return FALSE;
555 1.1 christos }
556 1.1 christos
557 1.1 christos info->reglist.has_index = 1;
558 1.1 christos info->reglist.num_regs = 0;
559 1.1 christos /* Number of registers is equal to the number of elements in
560 1.1 christos each structure to be loaded/stored. */
561 1.1 christos info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
562 1.6 christos assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
563 1.1 christos
564 1.1 christos return TRUE;
565 1.1 christos }
566 1.1 christos
567 1.1 christos /* Decode fields immh:immb and/or Q for e.g.
568 1.1 christos SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
569 1.6 christos or SSHR <V><d>, <V><n>, #<shift>. */
570 1.1 christos
571 1.1 christos bfd_boolean
572 1.6 christos aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
573 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
574 1.1 christos const aarch64_inst *inst,
575 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
576 1.1 christos {
577 1.1 christos int pos;
578 1.1 christos aarch64_insn Q, imm, immh;
579 1.1 christos enum aarch64_insn_class iclass = inst->opcode->iclass;
580 1.1 christos
581 1.6 christos immh = extract_field (FLD_immh, code, 0);
582 1.1 christos if (immh == 0)
583 1.1 christos return FALSE;
584 1.1 christos imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
585 1.1 christos pos = 4;
586 1.1 christos /* Get highest set bit in immh. */
587 1.1 christos while (--pos >= 0 && (immh & 0x8) == 0)
588 1.1 christos immh <<= 1;
589 1.1 christos
590 1.1 christos assert ((iclass == asimdshf || iclass == asisdshf)
591 1.1 christos && (info->type == AARCH64_OPND_IMM_VLSR
592 1.1 christos || info->type == AARCH64_OPND_IMM_VLSL));
593 1.1 christos
594 1.1 christos if (iclass == asimdshf)
595 1.1 christos {
596 1.1 christos Q = extract_field (FLD_Q, code, 0);
597 1.1 christos /* immh Q <T>
598 1.1 christos 0000 x SEE AdvSIMD modified immediate
599 1.1 christos 0001 0 8B
600 1.1 christos 0001 1 16B
601 1.1 christos 001x 0 4H
602 1.1 christos 001x 1 8H
603 1.1 christos 01xx 0 2S
604 1.1 christos 01xx 1 4S
605 1.1 christos 1xxx 0 RESERVED
606 1.1 christos 1xxx 1 2D */
607 1.1 christos info->qualifier =
608 1.1 christos get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
609 1.1 christos }
610 1.1 christos else
611 1.1 christos info->qualifier = get_sreg_qualifier_from_value (pos);
612 1.1 christos
613 1.1 christos if (info->type == AARCH64_OPND_IMM_VLSR)
614 1.1 christos /* immh <shift>
615 1.1 christos 0000 SEE AdvSIMD modified immediate
616 1.1 christos 0001 (16-UInt(immh:immb))
617 1.1 christos 001x (32-UInt(immh:immb))
618 1.1 christos 01xx (64-UInt(immh:immb))
619 1.1 christos 1xxx (128-UInt(immh:immb)) */
620 1.1 christos info->imm.value = (16 << pos) - imm;
621 1.1 christos else
622 1.1 christos /* immh:immb
623 1.1 christos immh <shift>
624 1.1 christos 0000 SEE AdvSIMD modified immediate
625 1.1 christos 0001 (UInt(immh:immb)-8)
626 1.1 christos 001x (UInt(immh:immb)-16)
627 1.1 christos 01xx (UInt(immh:immb)-32)
628 1.1 christos 1xxx (UInt(immh:immb)-64) */
629 1.6 christos info->imm.value = imm - (8 << pos);
630 1.1 christos
631 1.1 christos return TRUE;
632 1.1 christos }
633 1.6 christos
634 1.1 christos /* Decode shift immediate for e.g. sshr (imm). */
635 1.1 christos bfd_boolean
636 1.6 christos aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
637 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
638 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
639 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
640 1.1 christos {
641 1.1 christos int64_t imm;
642 1.1 christos aarch64_insn val;
643 1.1 christos val = extract_field (FLD_size, code, 0);
644 1.1 christos switch (val)
645 1.1 christos {
646 1.1 christos case 0: imm = 8; break;
647 1.6 christos case 1: imm = 16; break;
648 1.1 christos case 2: imm = 32; break;
649 1.1 christos default: return FALSE;
650 1.6 christos }
651 1.1 christos info->imm.value = imm;
652 1.1 christos return TRUE;
653 1.1 christos }
654 1.1 christos
655 1.6 christos /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
656 1.1 christos value in the field(s) will be extracted as unsigned immediate value. */
657 1.1 christos bfd_boolean
658 1.6 christos aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
659 1.6 christos const aarch64_insn code,
660 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
661 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
662 1.1 christos {
663 1.6 christos int64_t imm;
664 1.1 christos
665 1.1 christos imm = extract_all_fields (self, code);
666 1.1 christos
667 1.1 christos if (operand_need_sign_extension (self))
668 1.1 christos imm = sign_extend (imm, get_operand_fields_width (self) - 1);
669 1.1 christos
670 1.1 christos if (operand_need_shift_by_two (self))
671 1.1 christos imm <<= 2;
672 1.1 christos
673 1.1 christos if (info->type == AARCH64_OPND_ADDR_ADRP)
674 1.1 christos imm <<= 12;
675 1.6 christos
676 1.1 christos info->imm.value = imm;
677 1.1 christos return TRUE;
678 1.1 christos }
679 1.6 christos
680 1.1 christos /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
681 1.1 christos bfd_boolean
682 1.6 christos aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
683 1.6 christos const aarch64_insn code,
684 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
685 1.6 christos aarch64_operand_error *errors)
686 1.1 christos {
687 1.1 christos aarch64_ext_imm (self, info, code, inst, errors);
688 1.6 christos info->shifter.kind = AARCH64_MOD_LSL;
689 1.1 christos info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
690 1.1 christos return TRUE;
691 1.1 christos }
692 1.1 christos
693 1.6 christos /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
694 1.1 christos MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
695 1.1 christos bfd_boolean
696 1.1 christos aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
697 1.6 christos aarch64_opnd_info *info,
698 1.6 christos const aarch64_insn code,
699 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
700 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
701 1.1 christos {
702 1.1 christos uint64_t imm;
703 1.1 christos enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
704 1.1 christos aarch64_field field = {0, 0};
705 1.1 christos
706 1.1 christos assert (info->idx == 1);
707 1.1 christos
708 1.1 christos if (info->type == AARCH64_OPND_SIMD_FPIMM)
709 1.1 christos info->imm.is_fp = 1;
710 1.1 christos
711 1.1 christos /* a:b:c:d:e:f:g:h */
712 1.1 christos imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
713 1.1 christos if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
714 1.1 christos {
715 1.1 christos /* Either MOVI <Dd>, #<imm>
716 1.1 christos or MOVI <Vd>.2D, #<imm>.
717 1.1 christos <imm> is a 64-bit immediate
718 1.1 christos 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
719 1.1 christos encoded in "a:b:c:d:e:f:g:h". */
720 1.1 christos int i;
721 1.1 christos unsigned abcdefgh = imm;
722 1.1 christos for (imm = 0ull, i = 0; i < 8; i++)
723 1.1 christos if (((abcdefgh >> i) & 0x1) != 0)
724 1.1 christos imm |= 0xffull << (8 * i);
725 1.1 christos }
726 1.1 christos info->imm.value = imm;
727 1.1 christos
728 1.1 christos /* cmode */
729 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
730 1.1 christos switch (info->qualifier)
731 1.1 christos {
732 1.1 christos case AARCH64_OPND_QLF_NIL:
733 1.1 christos /* no shift */
734 1.1 christos info->shifter.kind = AARCH64_MOD_NONE;
735 1.1 christos return 1;
736 1.1 christos case AARCH64_OPND_QLF_LSL:
737 1.1 christos /* shift zeros */
738 1.1 christos info->shifter.kind = AARCH64_MOD_LSL;
739 1.1 christos switch (aarch64_get_qualifier_esize (opnd0_qualifier))
740 1.1 christos {
741 1.3 christos case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
742 1.6 christos case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
743 1.1 christos case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
744 1.1 christos default: assert (0); return FALSE;
745 1.1 christos }
746 1.1 christos /* 00: 0; 01: 8; 10:16; 11:24. */
747 1.1 christos info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
748 1.1 christos break;
749 1.1 christos case AARCH64_OPND_QLF_MSL:
750 1.1 christos /* shift ones */
751 1.1 christos info->shifter.kind = AARCH64_MOD_MSL;
752 1.1 christos gen_sub_field (FLD_cmode, 0, 1, &field); /* per word */
753 1.1 christos info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
754 1.1 christos break;
755 1.6 christos default:
756 1.1 christos assert (0);
757 1.1 christos return FALSE;
758 1.6 christos }
759 1.6 christos
760 1.6 christos return TRUE;
761 1.6 christos }
762 1.6 christos
763 1.6 christos /* Decode an 8-bit floating-point immediate. */
764 1.6 christos bfd_boolean
765 1.6 christos aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info,
766 1.6 christos const aarch64_insn code,
767 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
768 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
769 1.6 christos {
770 1.6 christos info->imm.value = extract_all_fields (self, code);
771 1.6 christos info->imm.is_fp = 1;
772 1.6 christos return TRUE;
773 1.6 christos }
774 1.6 christos
775 1.6 christos /* Decode a 1-bit rotate immediate (#90 or #270). */
776 1.6 christos bfd_boolean
777 1.6 christos aarch64_ext_imm_rotate1 (const aarch64_operand *self, aarch64_opnd_info *info,
778 1.6 christos const aarch64_insn code,
779 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
780 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
781 1.6 christos {
782 1.6 christos uint64_t rot = extract_field (self->fields[0], code, 0);
783 1.6 christos assert (rot < 2U);
784 1.6 christos info->imm.value = rot * 180 + 90;
785 1.6 christos return TRUE;
786 1.6 christos }
787 1.6 christos
788 1.6 christos /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */
789 1.6 christos bfd_boolean
790 1.6 christos aarch64_ext_imm_rotate2 (const aarch64_operand *self, aarch64_opnd_info *info,
791 1.6 christos const aarch64_insn code,
792 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
793 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
794 1.6 christos {
795 1.6 christos uint64_t rot = extract_field (self->fields[0], code, 0);
796 1.6 christos assert (rot < 4U);
797 1.1 christos info->imm.value = rot * 90;
798 1.1 christos return TRUE;
799 1.1 christos }
800 1.6 christos
801 1.1 christos /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
802 1.1 christos bfd_boolean
803 1.6 christos aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
804 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
805 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
806 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
807 1.6 christos {
808 1.1 christos info->imm.value = 64- extract_field (FLD_scale, code, 0);
809 1.1 christos return TRUE;
810 1.1 christos }
811 1.1 christos
812 1.6 christos /* Decode arithmetic immediate for e.g.
813 1.1 christos SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
814 1.1 christos bfd_boolean
815 1.6 christos aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
816 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
817 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
818 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
819 1.1 christos {
820 1.1 christos aarch64_insn value;
821 1.1 christos
822 1.1 christos info->shifter.kind = AARCH64_MOD_LSL;
823 1.1 christos /* shift */
824 1.6 christos value = extract_field (FLD_shift, code, 0);
825 1.1 christos if (value >= 2)
826 1.1 christos return FALSE;
827 1.1 christos info->shifter.amount = value ? 12 : 0;
828 1.1 christos /* imm12 (unsigned) */
829 1.6 christos info->imm.value = extract_field (FLD_imm12, code, 0);
830 1.1 christos
831 1.1 christos return TRUE;
832 1.6 christos }
833 1.6 christos
834 1.6 christos /* Return true if VALUE is a valid logical immediate encoding, storing the
835 1.6 christos decoded value in *RESULT if so. ESIZE is the number of bytes in the
836 1.6 christos decoded immediate. */
837 1.1 christos static bfd_boolean
838 1.1 christos decode_limm (uint32_t esize, aarch64_insn value, int64_t *result)
839 1.1 christos {
840 1.1 christos uint64_t imm, mask;
841 1.1 christos uint32_t N, R, S;
842 1.1 christos unsigned simd_size;
843 1.1 christos
844 1.1 christos /* value is N:immr:imms. */
845 1.1 christos S = value & 0x3f;
846 1.1 christos R = (value >> 6) & 0x3f;
847 1.1 christos N = (value >> 12) & 0x1;
848 1.3 christos
849 1.1 christos /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
850 1.1 christos (in other words, right rotated by R), then replicated. */
851 1.1 christos if (N != 0)
852 1.1 christos {
853 1.1 christos simd_size = 64;
854 1.1 christos mask = 0xffffffffffffffffull;
855 1.1 christos }
856 1.1 christos else
857 1.1 christos {
858 1.1 christos switch (S)
859 1.1 christos {
860 1.1 christos case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break;
861 1.1 christos case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
862 1.1 christos case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break;
863 1.6 christos case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break;
864 1.1 christos case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break;
865 1.1 christos default: return FALSE;
866 1.1 christos }
867 1.1 christos mask = (1ull << simd_size) - 1;
868 1.1 christos /* Top bits are IGNORED. */
869 1.6 christos R &= simd_size - 1;
870 1.6 christos }
871 1.6 christos
872 1.6 christos if (simd_size > esize * 8)
873 1.1 christos return FALSE;
874 1.1 christos
875 1.6 christos /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
876 1.1 christos if (S == simd_size - 1)
877 1.1 christos return FALSE;
878 1.1 christos /* S+1 consecutive bits to 1. */
879 1.1 christos /* NOTE: S can't be 63 due to detection above. */
880 1.1 christos imm = (1ull << (S + 1)) - 1;
881 1.1 christos /* Rotate to the left by simd_size - R. */
882 1.1 christos if (R != 0)
883 1.1 christos imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
884 1.1 christos /* Replicate the value according to SIMD size. */
885 1.1 christos switch (simd_size)
886 1.6 christos {
887 1.1 christos case 2: imm = (imm << 2) | imm;
888 1.6 christos /* Fall through. */
889 1.1 christos case 4: imm = (imm << 4) | imm;
890 1.6 christos /* Fall through. */
891 1.1 christos case 8: imm = (imm << 8) | imm;
892 1.6 christos /* Fall through. */
893 1.1 christos case 16: imm = (imm << 16) | imm;
894 1.6 christos /* Fall through. */
895 1.1 christos case 32: imm = (imm << 32) | imm;
896 1.1 christos /* Fall through. */
897 1.1 christos case 64: break;
898 1.1 christos default: assert (0); return 0;
899 1.6 christos }
900 1.6 christos
901 1.6 christos *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
902 1.6 christos
903 1.6 christos return TRUE;
904 1.6 christos }
905 1.6 christos
906 1.6 christos /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
907 1.6 christos bfd_boolean
908 1.6 christos aarch64_ext_limm (const aarch64_operand *self,
909 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
910 1.6 christos const aarch64_inst *inst,
911 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
912 1.6 christos {
913 1.6 christos uint32_t esize;
914 1.6 christos aarch64_insn value;
915 1.6 christos
916 1.6 christos value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
917 1.6 christos self->fields[2]);
918 1.6 christos esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
919 1.1 christos return decode_limm (esize, value, &info->imm.value);
920 1.6 christos }
921 1.6 christos
922 1.6 christos /* Decode a logical immediate for the BIC alias of AND (etc.). */
923 1.6 christos bfd_boolean
924 1.6 christos aarch64_ext_inv_limm (const aarch64_operand *self,
925 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
926 1.6 christos const aarch64_inst *inst,
927 1.6 christos aarch64_operand_error *errors)
928 1.6 christos {
929 1.6 christos if (!aarch64_ext_limm (self, info, code, inst, errors))
930 1.6 christos return FALSE;
931 1.1 christos info->imm.value = ~info->imm.value;
932 1.1 christos return TRUE;
933 1.1 christos }
934 1.1 christos
935 1.6 christos /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
936 1.1 christos or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
937 1.1 christos bfd_boolean
938 1.6 christos aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
939 1.6 christos aarch64_opnd_info *info,
940 1.1 christos const aarch64_insn code, const aarch64_inst *inst,
941 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
942 1.1 christos {
943 1.1 christos aarch64_insn value;
944 1.1 christos
945 1.1 christos /* Rt */
946 1.1 christos info->reg.regno = extract_field (FLD_Rt, code, 0);
947 1.1 christos
948 1.1 christos /* size */
949 1.1 christos value = extract_field (FLD_ldst_size, code, 0);
950 1.1 christos if (inst->opcode->iclass == ldstpair_indexed
951 1.1 christos || inst->opcode->iclass == ldstnapair_offs
952 1.1 christos || inst->opcode->iclass == ldstpair_off
953 1.1 christos || inst->opcode->iclass == loadlit)
954 1.1 christos {
955 1.1 christos enum aarch64_opnd_qualifier qualifier;
956 1.1 christos switch (value)
957 1.1 christos {
958 1.1 christos case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
959 1.6 christos case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
960 1.1 christos case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
961 1.1 christos default: return FALSE;
962 1.1 christos }
963 1.1 christos info->qualifier = qualifier;
964 1.1 christos }
965 1.1 christos else
966 1.1 christos {
967 1.1 christos /* opc1:size */
968 1.6 christos value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
969 1.1 christos if (value > 0x4)
970 1.1 christos return FALSE;
971 1.1 christos info->qualifier = get_sreg_qualifier_from_value (value);
972 1.6 christos }
973 1.1 christos
974 1.1 christos return TRUE;
975 1.1 christos }
976 1.6 christos
977 1.1 christos /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
978 1.1 christos bfd_boolean
979 1.1 christos aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
980 1.6 christos aarch64_opnd_info *info,
981 1.6 christos aarch64_insn code,
982 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
983 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
984 1.1 christos {
985 1.6 christos /* Rn */
986 1.6 christos info->addr.base_regno = extract_field (FLD_Rn, code, 0);
987 1.6 christos return TRUE;
988 1.6 christos }
989 1.6 christos
990 1.6 christos /* Decode the address operand for e.g.
991 1.6 christos stlur <Xt>, [<Xn|SP>{, <amount>}]. */
992 1.6 christos bfd_boolean
993 1.6 christos aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
994 1.6 christos aarch64_opnd_info *info,
995 1.6 christos aarch64_insn code, const aarch64_inst *inst,
996 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
997 1.6 christos {
998 1.6 christos info->qualifier = get_expected_qualifier (inst, info->idx);
999 1.6 christos
1000 1.6 christos /* Rn */
1001 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1002 1.6 christos
1003 1.6 christos /* simm9 */
1004 1.6 christos aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
1005 1.6 christos info->addr.offset.imm = sign_extend (imm, 8);
1006 1.6 christos if (extract_field (self->fields[2], code, 0) == 1) {
1007 1.6 christos info->addr.writeback = 1;
1008 1.6 christos info->addr.preind = 1;
1009 1.1 christos }
1010 1.1 christos return TRUE;
1011 1.1 christos }
1012 1.1 christos
1013 1.6 christos /* Decode the address operand for e.g.
1014 1.1 christos STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1015 1.1 christos bfd_boolean
1016 1.6 christos aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
1017 1.6 christos aarch64_opnd_info *info,
1018 1.1 christos aarch64_insn code, const aarch64_inst *inst,
1019 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1020 1.1 christos {
1021 1.1 christos aarch64_insn S, value;
1022 1.1 christos
1023 1.1 christos /* Rn */
1024 1.1 christos info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1025 1.1 christos /* Rm */
1026 1.1 christos info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1027 1.1 christos /* option */
1028 1.1 christos value = extract_field (FLD_option, code, 0);
1029 1.1 christos info->shifter.kind =
1030 1.1 christos aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1031 1.1 christos /* Fix-up the shifter kind; although the table-driven approach is
1032 1.1 christos efficient, it is slightly inflexible, thus needing this fix-up. */
1033 1.1 christos if (info->shifter.kind == AARCH64_MOD_UXTX)
1034 1.1 christos info->shifter.kind = AARCH64_MOD_LSL;
1035 1.1 christos /* S */
1036 1.1 christos S = extract_field (FLD_S, code, 0);
1037 1.1 christos if (S == 0)
1038 1.1 christos {
1039 1.1 christos info->shifter.amount = 0;
1040 1.1 christos info->shifter.amount_present = 0;
1041 1.1 christos }
1042 1.1 christos else
1043 1.1 christos {
1044 1.1 christos int size;
1045 1.1 christos /* Need information in other operand(s) to help achieve the decoding
1046 1.1 christos from 'S' field. */
1047 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
1048 1.1 christos /* Get the size of the data element that is accessed, which may be
1049 1.1 christos different from that of the source register size, e.g. in strb/ldrb. */
1050 1.1 christos size = aarch64_get_qualifier_esize (info->qualifier);
1051 1.1 christos info->shifter.amount = get_logsz (size);
1052 1.1 christos info->shifter.amount_present = 1;
1053 1.6 christos }
1054 1.1 christos
1055 1.1 christos return TRUE;
1056 1.1 christos }
1057 1.6 christos
1058 1.1 christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
1059 1.6 christos bfd_boolean
1060 1.6 christos aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
1061 1.1 christos aarch64_insn code, const aarch64_inst *inst,
1062 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1063 1.1 christos {
1064 1.1 christos aarch64_insn imm;
1065 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
1066 1.1 christos
1067 1.1 christos /* Rn */
1068 1.1 christos info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1069 1.1 christos /* simm (imm9 or imm7) */
1070 1.1 christos imm = extract_field (self->fields[0], code, 0);
1071 1.1 christos info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
1072 1.1 christos if (self->fields[0] == FLD_imm7)
1073 1.1 christos /* scaled immediate in ld/st pair instructions. */
1074 1.1 christos info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
1075 1.1 christos /* qualifier */
1076 1.1 christos if (inst->opcode->iclass == ldst_unscaled
1077 1.1 christos || inst->opcode->iclass == ldstnapair_offs
1078 1.1 christos || inst->opcode->iclass == ldstpair_off
1079 1.1 christos || inst->opcode->iclass == ldst_unpriv)
1080 1.1 christos info->addr.writeback = 0;
1081 1.1 christos else
1082 1.1 christos {
1083 1.1 christos /* pre/post- index */
1084 1.1 christos info->addr.writeback = 1;
1085 1.1 christos if (extract_field (self->fields[1], code, 0) == 1)
1086 1.1 christos info->addr.preind = 1;
1087 1.1 christos else
1088 1.1 christos info->addr.postind = 1;
1089 1.6 christos }
1090 1.1 christos
1091 1.1 christos return TRUE;
1092 1.1 christos }
1093 1.6 christos
1094 1.1 christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
1095 1.1 christos bfd_boolean
1096 1.6 christos aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
1097 1.6 christos aarch64_insn code,
1098 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1099 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1100 1.1 christos {
1101 1.1 christos int shift;
1102 1.1 christos info->qualifier = get_expected_qualifier (inst, info->idx);
1103 1.1 christos shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
1104 1.1 christos /* Rn */
1105 1.1 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1106 1.6 christos /* uimm12 */
1107 1.6 christos info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
1108 1.6 christos return TRUE;
1109 1.6 christos }
1110 1.6 christos
1111 1.6 christos /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
1112 1.6 christos bfd_boolean
1113 1.6 christos aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info,
1114 1.6 christos aarch64_insn code,
1115 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1116 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1117 1.6 christos {
1118 1.6 christos aarch64_insn imm;
1119 1.6 christos
1120 1.6 christos info->qualifier = get_expected_qualifier (inst, info->idx);
1121 1.6 christos /* Rn */
1122 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1123 1.6 christos /* simm10 */
1124 1.6 christos imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
1125 1.6 christos info->addr.offset.imm = sign_extend (imm, 9) << 3;
1126 1.6 christos if (extract_field (self->fields[3], code, 0) == 1) {
1127 1.6 christos info->addr.writeback = 1;
1128 1.6 christos info->addr.preind = 1;
1129 1.1 christos }
1130 1.1 christos return TRUE;
1131 1.1 christos }
1132 1.1 christos
1133 1.6 christos /* Decode the address operand for e.g.
1134 1.1 christos LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
1135 1.1 christos bfd_boolean
1136 1.6 christos aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
1137 1.6 christos aarch64_opnd_info *info,
1138 1.1 christos aarch64_insn code, const aarch64_inst *inst,
1139 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1140 1.1 christos {
1141 1.1 christos /* The opcode dependent area stores the number of elements in
1142 1.1 christos each structure to be loaded/stored. */
1143 1.1 christos int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
1144 1.1 christos
1145 1.1 christos /* Rn */
1146 1.1 christos info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1147 1.1 christos /* Rm | #<amount> */
1148 1.1 christos info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1149 1.1 christos if (info->addr.offset.regno == 31)
1150 1.1 christos {
1151 1.1 christos if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
1152 1.1 christos /* Special handling of loading single structure to all lane. */
1153 1.1 christos info->addr.offset.imm = (is_ld1r ? 1
1154 1.1 christos : inst->operands[0].reglist.num_regs)
1155 1.1 christos * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1156 1.1 christos else
1157 1.1 christos info->addr.offset.imm = inst->operands[0].reglist.num_regs
1158 1.1 christos * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
1159 1.1 christos * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
1160 1.1 christos }
1161 1.1 christos else
1162 1.1 christos info->addr.offset.is_reg = 1;
1163 1.6 christos info->addr.writeback = 1;
1164 1.1 christos
1165 1.1 christos return TRUE;
1166 1.1 christos }
1167 1.6 christos
1168 1.1 christos /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
1169 1.1 christos bfd_boolean
1170 1.6 christos aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
1171 1.6 christos aarch64_opnd_info *info,
1172 1.1 christos aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1173 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1174 1.1 christos {
1175 1.1 christos aarch64_insn value;
1176 1.1 christos /* cond */
1177 1.6 christos value = extract_field (FLD_cond, code, 0);
1178 1.1 christos info->cond = get_cond_from_value (value);
1179 1.1 christos return TRUE;
1180 1.1 christos }
1181 1.6 christos
1182 1.1 christos /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1183 1.1 christos bfd_boolean
1184 1.1 christos aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
1185 1.6 christos aarch64_opnd_info *info,
1186 1.6 christos aarch64_insn code,
1187 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1188 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1189 1.6 christos {
1190 1.6 christos /* op0:op1:CRn:CRm:op2 */
1191 1.6 christos info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
1192 1.6 christos FLD_CRm, FLD_op2);
1193 1.6 christos info->sysreg.flags = 0;
1194 1.6 christos
1195 1.6 christos /* If a system instruction, check which restrictions should be on the register
1196 1.6 christos value during decoding, these will be enforced then. */
1197 1.6 christos if (inst->opcode->iclass == ic_system)
1198 1.6 christos {
1199 1.6 christos /* Check to see if it's read-only, else check if it's write only.
1200 1.6 christos if it's both or unspecified don't care. */
1201 1.6 christos if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ)
1202 1.6 christos info->sysreg.flags = F_REG_READ;
1203 1.6 christos else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE))
1204 1.6 christos == F_SYS_WRITE)
1205 1.6 christos info->sysreg.flags = F_REG_WRITE;
1206 1.6 christos }
1207 1.1 christos
1208 1.1 christos return TRUE;
1209 1.1 christos }
1210 1.6 christos
1211 1.1 christos /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1212 1.1 christos bfd_boolean
1213 1.6 christos aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
1214 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1215 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1216 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1217 1.1 christos {
1218 1.1 christos int i;
1219 1.1 christos /* op1:op2 */
1220 1.1 christos info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1221 1.6 christos for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1222 1.1 christos if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1223 1.6 christos return TRUE;
1224 1.1 christos /* Reserved value in <pstatefield>. */
1225 1.1 christos return FALSE;
1226 1.1 christos }
1227 1.6 christos
1228 1.1 christos /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1229 1.1 christos bfd_boolean
1230 1.1 christos aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
1231 1.6 christos aarch64_opnd_info *info,
1232 1.6 christos aarch64_insn code,
1233 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1234 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1235 1.1 christos {
1236 1.1 christos int i;
1237 1.1 christos aarch64_insn value;
1238 1.1 christos const aarch64_sys_ins_reg *sysins_ops;
1239 1.1 christos /* op0:op1:CRn:CRm:op2 */
1240 1.1 christos value = extract_fields (code, 0, 5,
1241 1.1 christos FLD_op0, FLD_op1, FLD_CRn,
1242 1.1 christos FLD_CRm, FLD_op2);
1243 1.1 christos
1244 1.1 christos switch (info->type)
1245 1.1 christos {
1246 1.1 christos case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1247 1.1 christos case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1248 1.6 christos case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1249 1.1 christos case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1250 1.1 christos default: assert (0); return FALSE;
1251 1.3 christos }
1252 1.1 christos
1253 1.1 christos for (i = 0; sysins_ops[i].name != NULL; ++i)
1254 1.1 christos if (sysins_ops[i].value == value)
1255 1.1 christos {
1256 1.3 christos info->sysins_op = sysins_ops + i;
1257 1.1 christos DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1258 1.3 christos info->sysins_op->name,
1259 1.6 christos (unsigned)info->sysins_op->value,
1260 1.1 christos aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1261 1.1 christos return TRUE;
1262 1.6 christos }
1263 1.1 christos
1264 1.1 christos return FALSE;
1265 1.1 christos }
1266 1.1 christos
1267 1.6 christos /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1268 1.1 christos
1269 1.1 christos bfd_boolean
1270 1.1 christos aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
1271 1.6 christos aarch64_opnd_info *info,
1272 1.6 christos aarch64_insn code,
1273 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1274 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1275 1.1 christos {
1276 1.6 christos /* CRm */
1277 1.1 christos info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1278 1.1 christos return TRUE;
1279 1.1 christos }
1280 1.1 christos
1281 1.1 christos /* Decode the prefetch operation option operand for e.g.
1282 1.6 christos PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1283 1.1 christos
1284 1.1 christos bfd_boolean
1285 1.6 christos aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
1286 1.6 christos aarch64_opnd_info *info,
1287 1.1 christos aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1288 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1289 1.1 christos {
1290 1.6 christos /* prfop in Rt */
1291 1.1 christos info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1292 1.1 christos return TRUE;
1293 1.3 christos }
1294 1.3 christos
1295 1.3 christos /* Decode the hint number for an alias taking an operand. Set info->hint_option
1296 1.6 christos to the matching name/value pair in aarch64_hint_options. */
1297 1.3 christos
1298 1.3 christos bfd_boolean
1299 1.3 christos aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
1300 1.6 christos aarch64_opnd_info *info,
1301 1.6 christos aarch64_insn code,
1302 1.3 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1303 1.3 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1304 1.3 christos {
1305 1.3 christos /* CRm:op2. */
1306 1.3 christos unsigned hint_number;
1307 1.3 christos int i;
1308 1.3 christos
1309 1.3 christos hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1310 1.3 christos
1311 1.3 christos for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1312 1.3 christos {
1313 1.3 christos if (hint_number == aarch64_hint_options[i].value)
1314 1.6 christos {
1315 1.3 christos info->hint_option = &(aarch64_hint_options[i]);
1316 1.3 christos return TRUE;
1317 1.3 christos }
1318 1.6 christos }
1319 1.3 christos
1320 1.3 christos return FALSE;
1321 1.1 christos }
1322 1.1 christos
1323 1.6 christos /* Decode the extended register operand for e.g.
1324 1.1 christos STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1325 1.1 christos bfd_boolean
1326 1.1 christos aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
1327 1.6 christos aarch64_opnd_info *info,
1328 1.6 christos aarch64_insn code,
1329 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1330 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1331 1.1 christos {
1332 1.1 christos aarch64_insn value;
1333 1.1 christos
1334 1.1 christos /* Rm */
1335 1.1 christos info->reg.regno = extract_field (FLD_Rm, code, 0);
1336 1.1 christos /* option */
1337 1.1 christos value = extract_field (FLD_option, code, 0);
1338 1.1 christos info->shifter.kind =
1339 1.1 christos aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1340 1.1 christos /* imm3 */
1341 1.1 christos info->shifter.amount = extract_field (FLD_imm3, code, 0);
1342 1.1 christos
1343 1.1 christos /* This makes the constraint checking happy. */
1344 1.1 christos info->shifter.operator_present = 1;
1345 1.1 christos
1346 1.1 christos /* Assume inst->operands[0].qualifier has been resolved. */
1347 1.1 christos assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
1348 1.1 christos info->qualifier = AARCH64_OPND_QLF_W;
1349 1.1 christos if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1350 1.1 christos && (info->shifter.kind == AARCH64_MOD_UXTX
1351 1.1 christos || info->shifter.kind == AARCH64_MOD_SXTX))
1352 1.6 christos info->qualifier = AARCH64_OPND_QLF_X;
1353 1.1 christos
1354 1.1 christos return TRUE;
1355 1.1 christos }
1356 1.1 christos
1357 1.6 christos /* Decode the shifted register operand for e.g.
1358 1.1 christos SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1359 1.1 christos bfd_boolean
1360 1.1 christos aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
1361 1.6 christos aarch64_opnd_info *info,
1362 1.6 christos aarch64_insn code,
1363 1.1 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1364 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1365 1.1 christos {
1366 1.1 christos aarch64_insn value;
1367 1.1 christos
1368 1.1 christos /* Rm */
1369 1.1 christos info->reg.regno = extract_field (FLD_Rm, code, 0);
1370 1.1 christos /* shift */
1371 1.1 christos value = extract_field (FLD_shift, code, 0);
1372 1.1 christos info->shifter.kind =
1373 1.1 christos aarch64_get_operand_modifier_from_value (value, FALSE /* extend_p */);
1374 1.1 christos if (info->shifter.kind == AARCH64_MOD_ROR
1375 1.1 christos && inst->opcode->iclass != log_shift)
1376 1.6 christos /* ROR is not available for the shifted register operand in arithmetic
1377 1.1 christos instructions. */
1378 1.1 christos return FALSE;
1379 1.1 christos /* imm6 */
1380 1.1 christos info->shifter.amount = extract_field (FLD_imm6, code, 0);
1381 1.1 christos
1382 1.1 christos /* This makes the constraint checking happy. */
1383 1.6 christos info->shifter.operator_present = 1;
1384 1.6 christos
1385 1.6 christos return TRUE;
1386 1.6 christos }
1387 1.6 christos
1388 1.6 christos /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1389 1.6 christos where <offset> is given by the OFFSET parameter and where <factor> is
1390 1.6 christos 1 plus SELF's operand-dependent value. fields[0] specifies the field
1391 1.6 christos that holds <base>. */
1392 1.6 christos static bfd_boolean
1393 1.6 christos aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand *self,
1394 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1395 1.6 christos int64_t offset)
1396 1.6 christos {
1397 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1398 1.6 christos info->addr.offset.imm = offset * (1 + get_operand_specific_data (self));
1399 1.6 christos info->addr.offset.is_reg = FALSE;
1400 1.6 christos info->addr.writeback = FALSE;
1401 1.6 christos info->addr.preind = TRUE;
1402 1.6 christos if (offset != 0)
1403 1.6 christos info->shifter.kind = AARCH64_MOD_MUL_VL;
1404 1.6 christos info->shifter.amount = 1;
1405 1.6 christos info->shifter.operator_present = (info->addr.offset.imm != 0);
1406 1.6 christos info->shifter.amount_present = FALSE;
1407 1.6 christos return TRUE;
1408 1.6 christos }
1409 1.6 christos
1410 1.6 christos /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1411 1.6 christos where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1412 1.6 christos SELF's operand-dependent value. fields[0] specifies the field that
1413 1.6 christos holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1414 1.6 christos bfd_boolean
1415 1.6 christos aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand *self,
1416 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1417 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1418 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1419 1.6 christos {
1420 1.6 christos int offset;
1421 1.6 christos
1422 1.6 christos offset = extract_field (FLD_SVE_imm4, code, 0);
1423 1.6 christos offset = ((offset + 8) & 15) - 8;
1424 1.6 christos return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1425 1.6 christos }
1426 1.6 christos
1427 1.6 christos /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1428 1.6 christos where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1429 1.6 christos SELF's operand-dependent value. fields[0] specifies the field that
1430 1.6 christos holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1431 1.6 christos bfd_boolean
1432 1.6 christos aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand *self,
1433 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1434 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1435 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1436 1.6 christos {
1437 1.6 christos int offset;
1438 1.6 christos
1439 1.6 christos offset = extract_field (FLD_SVE_imm6, code, 0);
1440 1.6 christos offset = (((offset + 32) & 63) - 32);
1441 1.6 christos return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1442 1.6 christos }
1443 1.6 christos
1444 1.6 christos /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1445 1.6 christos where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1446 1.6 christos SELF's operand-dependent value. fields[0] specifies the field that
1447 1.6 christos holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1448 1.6 christos and imm3 fields, with imm3 being the less-significant part. */
1449 1.6 christos bfd_boolean
1450 1.6 christos aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand *self,
1451 1.6 christos aarch64_opnd_info *info,
1452 1.6 christos aarch64_insn code,
1453 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1454 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1455 1.6 christos {
1456 1.6 christos int offset;
1457 1.6 christos
1458 1.6 christos offset = extract_fields (code, 0, 2, FLD_SVE_imm6, FLD_imm3);
1459 1.6 christos offset = (((offset + 256) & 511) - 256);
1460 1.6 christos return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1461 1.6 christos }
1462 1.6 christos
1463 1.6 christos /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1464 1.6 christos is given by the OFFSET parameter and where <shift> is SELF's operand-
1465 1.6 christos dependent value. fields[0] specifies the base register field <base>. */
1466 1.6 christos static bfd_boolean
1467 1.6 christos aarch64_ext_sve_addr_reg_imm (const aarch64_operand *self,
1468 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1469 1.6 christos int64_t offset)
1470 1.6 christos {
1471 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1472 1.6 christos info->addr.offset.imm = offset * (1 << get_operand_specific_data (self));
1473 1.6 christos info->addr.offset.is_reg = FALSE;
1474 1.6 christos info->addr.writeback = FALSE;
1475 1.6 christos info->addr.preind = TRUE;
1476 1.6 christos info->shifter.operator_present = FALSE;
1477 1.6 christos info->shifter.amount_present = FALSE;
1478 1.6 christos return TRUE;
1479 1.6 christos }
1480 1.6 christos
1481 1.6 christos /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1482 1.6 christos is a 4-bit signed number and where <shift> is SELF's operand-dependent
1483 1.6 christos value. fields[0] specifies the base register field. */
1484 1.6 christos bfd_boolean
1485 1.6 christos aarch64_ext_sve_addr_ri_s4 (const aarch64_operand *self,
1486 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1487 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1488 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1489 1.6 christos {
1490 1.6 christos int offset = sign_extend (extract_field (FLD_SVE_imm4, code, 0), 3);
1491 1.6 christos return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1492 1.6 christos }
1493 1.6 christos
1494 1.6 christos /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1495 1.6 christos is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1496 1.6 christos value. fields[0] specifies the base register field. */
1497 1.6 christos bfd_boolean
1498 1.6 christos aarch64_ext_sve_addr_ri_u6 (const aarch64_operand *self,
1499 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1500 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1501 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1502 1.6 christos {
1503 1.6 christos int offset = extract_field (FLD_SVE_imm6, code, 0);
1504 1.6 christos return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1505 1.6 christos }
1506 1.6 christos
1507 1.6 christos /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1508 1.6 christos is SELF's operand-dependent value. fields[0] specifies the base
1509 1.6 christos register field and fields[1] specifies the offset register field. */
1510 1.6 christos bfd_boolean
1511 1.6 christos aarch64_ext_sve_addr_rr_lsl (const aarch64_operand *self,
1512 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1513 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1514 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1515 1.6 christos {
1516 1.6 christos int index_regno;
1517 1.6 christos
1518 1.6 christos index_regno = extract_field (self->fields[1], code, 0);
1519 1.6 christos if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
1520 1.6 christos return FALSE;
1521 1.6 christos
1522 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1523 1.6 christos info->addr.offset.regno = index_regno;
1524 1.6 christos info->addr.offset.is_reg = TRUE;
1525 1.6 christos info->addr.writeback = FALSE;
1526 1.6 christos info->addr.preind = TRUE;
1527 1.6 christos info->shifter.kind = AARCH64_MOD_LSL;
1528 1.6 christos info->shifter.amount = get_operand_specific_data (self);
1529 1.6 christos info->shifter.operator_present = (info->shifter.amount != 0);
1530 1.6 christos info->shifter.amount_present = (info->shifter.amount != 0);
1531 1.6 christos return TRUE;
1532 1.6 christos }
1533 1.6 christos
1534 1.6 christos /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1535 1.6 christos <shift> is SELF's operand-dependent value. fields[0] specifies the
1536 1.6 christos base register field, fields[1] specifies the offset register field and
1537 1.6 christos fields[2] is a single-bit field that selects SXTW over UXTW. */
1538 1.6 christos bfd_boolean
1539 1.6 christos aarch64_ext_sve_addr_rz_xtw (const aarch64_operand *self,
1540 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1541 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1542 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1543 1.6 christos {
1544 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1545 1.6 christos info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1546 1.6 christos info->addr.offset.is_reg = TRUE;
1547 1.6 christos info->addr.writeback = FALSE;
1548 1.6 christos info->addr.preind = TRUE;
1549 1.6 christos if (extract_field (self->fields[2], code, 0))
1550 1.6 christos info->shifter.kind = AARCH64_MOD_SXTW;
1551 1.6 christos else
1552 1.6 christos info->shifter.kind = AARCH64_MOD_UXTW;
1553 1.6 christos info->shifter.amount = get_operand_specific_data (self);
1554 1.6 christos info->shifter.operator_present = TRUE;
1555 1.6 christos info->shifter.amount_present = (info->shifter.amount != 0);
1556 1.6 christos return TRUE;
1557 1.6 christos }
1558 1.6 christos
1559 1.6 christos /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1560 1.6 christos 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1561 1.6 christos fields[0] specifies the base register field. */
1562 1.6 christos bfd_boolean
1563 1.6 christos aarch64_ext_sve_addr_zi_u5 (const aarch64_operand *self,
1564 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1565 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1566 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1567 1.6 christos {
1568 1.6 christos int offset = extract_field (FLD_imm5, code, 0);
1569 1.6 christos return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1570 1.6 christos }
1571 1.6 christos
1572 1.6 christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1573 1.6 christos where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1574 1.6 christos number. fields[0] specifies the base register field and fields[1]
1575 1.6 christos specifies the offset register field. */
1576 1.6 christos static bfd_boolean
1577 1.6 christos aarch64_ext_sve_addr_zz (const aarch64_operand *self, aarch64_opnd_info *info,
1578 1.6 christos aarch64_insn code, enum aarch64_modifier_kind kind)
1579 1.6 christos {
1580 1.6 christos info->addr.base_regno = extract_field (self->fields[0], code, 0);
1581 1.6 christos info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1582 1.6 christos info->addr.offset.is_reg = TRUE;
1583 1.6 christos info->addr.writeback = FALSE;
1584 1.6 christos info->addr.preind = TRUE;
1585 1.6 christos info->shifter.kind = kind;
1586 1.6 christos info->shifter.amount = extract_field (FLD_SVE_msz, code, 0);
1587 1.6 christos info->shifter.operator_present = (kind != AARCH64_MOD_LSL
1588 1.6 christos || info->shifter.amount != 0);
1589 1.6 christos info->shifter.amount_present = (info->shifter.amount != 0);
1590 1.6 christos return TRUE;
1591 1.6 christos }
1592 1.6 christos
1593 1.6 christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1594 1.6 christos <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1595 1.6 christos field and fields[1] specifies the offset register field. */
1596 1.6 christos bfd_boolean
1597 1.6 christos aarch64_ext_sve_addr_zz_lsl (const aarch64_operand *self,
1598 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1599 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1600 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1601 1.6 christos {
1602 1.6 christos return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_LSL);
1603 1.6 christos }
1604 1.6 christos
1605 1.6 christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1606 1.6 christos <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1607 1.6 christos field and fields[1] specifies the offset register field. */
1608 1.6 christos bfd_boolean
1609 1.6 christos aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand *self,
1610 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1611 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1612 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1613 1.6 christos {
1614 1.6 christos return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_SXTW);
1615 1.6 christos }
1616 1.6 christos
1617 1.6 christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1618 1.6 christos <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1619 1.6 christos field and fields[1] specifies the offset register field. */
1620 1.6 christos bfd_boolean
1621 1.6 christos aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand *self,
1622 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1623 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1624 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1625 1.6 christos {
1626 1.6 christos return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
1627 1.6 christos }
1628 1.6 christos
1629 1.6 christos /* Finish decoding an SVE arithmetic immediate, given that INFO already
1630 1.6 christos has the raw field value and that the low 8 bits decode to VALUE. */
1631 1.6 christos static bfd_boolean
1632 1.6 christos decode_sve_aimm (aarch64_opnd_info *info, int64_t value)
1633 1.6 christos {
1634 1.6 christos info->shifter.kind = AARCH64_MOD_LSL;
1635 1.6 christos info->shifter.amount = 0;
1636 1.6 christos if (info->imm.value & 0x100)
1637 1.6 christos {
1638 1.6 christos if (value == 0)
1639 1.6 christos /* Decode 0x100 as #0, LSL #8. */
1640 1.6 christos info->shifter.amount = 8;
1641 1.6 christos else
1642 1.6 christos value *= 256;
1643 1.6 christos }
1644 1.6 christos info->shifter.operator_present = (info->shifter.amount != 0);
1645 1.6 christos info->shifter.amount_present = (info->shifter.amount != 0);
1646 1.6 christos info->imm.value = value;
1647 1.6 christos return TRUE;
1648 1.6 christos }
1649 1.6 christos
1650 1.6 christos /* Decode an SVE ADD/SUB immediate. */
1651 1.6 christos bfd_boolean
1652 1.6 christos aarch64_ext_sve_aimm (const aarch64_operand *self,
1653 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
1654 1.6 christos const aarch64_inst *inst,
1655 1.6 christos aarch64_operand_error *errors)
1656 1.6 christos {
1657 1.6 christos return (aarch64_ext_imm (self, info, code, inst, errors)
1658 1.6 christos && decode_sve_aimm (info, (uint8_t) info->imm.value));
1659 1.6 christos }
1660 1.6 christos
1661 1.6 christos /* Decode an SVE CPY/DUP immediate. */
1662 1.6 christos bfd_boolean
1663 1.6 christos aarch64_ext_sve_asimm (const aarch64_operand *self,
1664 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
1665 1.6 christos const aarch64_inst *inst,
1666 1.6 christos aarch64_operand_error *errors)
1667 1.6 christos {
1668 1.6 christos return (aarch64_ext_imm (self, info, code, inst, errors)
1669 1.6 christos && decode_sve_aimm (info, (int8_t) info->imm.value));
1670 1.6 christos }
1671 1.6 christos
1672 1.6 christos /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1673 1.6 christos The fields array specifies which field to use. */
1674 1.6 christos bfd_boolean
1675 1.6 christos aarch64_ext_sve_float_half_one (const aarch64_operand *self,
1676 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1677 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1678 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1679 1.6 christos {
1680 1.6 christos if (extract_field (self->fields[0], code, 0))
1681 1.6 christos info->imm.value = 0x3f800000;
1682 1.6 christos else
1683 1.6 christos info->imm.value = 0x3f000000;
1684 1.6 christos info->imm.is_fp = TRUE;
1685 1.6 christos return TRUE;
1686 1.6 christos }
1687 1.6 christos
1688 1.6 christos /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1689 1.6 christos The fields array specifies which field to use. */
1690 1.6 christos bfd_boolean
1691 1.6 christos aarch64_ext_sve_float_half_two (const aarch64_operand *self,
1692 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1693 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1694 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1695 1.6 christos {
1696 1.6 christos if (extract_field (self->fields[0], code, 0))
1697 1.6 christos info->imm.value = 0x40000000;
1698 1.6 christos else
1699 1.6 christos info->imm.value = 0x3f000000;
1700 1.6 christos info->imm.is_fp = TRUE;
1701 1.6 christos return TRUE;
1702 1.6 christos }
1703 1.6 christos
1704 1.6 christos /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1705 1.6 christos The fields array specifies which field to use. */
1706 1.6 christos bfd_boolean
1707 1.6 christos aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
1708 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1709 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1710 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1711 1.6 christos {
1712 1.6 christos if (extract_field (self->fields[0], code, 0))
1713 1.6 christos info->imm.value = 0x3f800000;
1714 1.6 christos else
1715 1.6 christos info->imm.value = 0x0;
1716 1.6 christos info->imm.is_fp = TRUE;
1717 1.6 christos return TRUE;
1718 1.6 christos }
1719 1.6 christos
1720 1.6 christos /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1721 1.6 christos array specifies which field to use for Zn. MM is encoded in the
1722 1.6 christos concatenation of imm5 and SVE_tszh, with imm5 being the less
1723 1.6 christos significant part. */
1724 1.6 christos bfd_boolean
1725 1.6 christos aarch64_ext_sve_index (const aarch64_operand *self,
1726 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1727 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1728 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1729 1.6 christos {
1730 1.6 christos int val;
1731 1.6 christos
1732 1.6 christos info->reglane.regno = extract_field (self->fields[0], code, 0);
1733 1.6 christos val = extract_fields (code, 0, 2, FLD_SVE_tszh, FLD_imm5);
1734 1.6 christos if ((val & 31) == 0)
1735 1.6 christos return 0;
1736 1.6 christos while ((val & 1) == 0)
1737 1.6 christos val /= 2;
1738 1.6 christos info->reglane.index = val / 2;
1739 1.6 christos return TRUE;
1740 1.6 christos }
1741 1.6 christos
1742 1.6 christos /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1743 1.6 christos bfd_boolean
1744 1.6 christos aarch64_ext_sve_limm_mov (const aarch64_operand *self,
1745 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
1746 1.6 christos const aarch64_inst *inst,
1747 1.6 christos aarch64_operand_error *errors)
1748 1.6 christos {
1749 1.6 christos int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1750 1.6 christos return (aarch64_ext_limm (self, info, code, inst, errors)
1751 1.6 christos && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
1752 1.6 christos }
1753 1.6 christos
1754 1.6 christos /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1755 1.6 christos and where MM occupies the most-significant part. The operand-dependent
1756 1.6 christos value specifies the number of bits in Zn. */
1757 1.6 christos bfd_boolean
1758 1.6 christos aarch64_ext_sve_quad_index (const aarch64_operand *self,
1759 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1760 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1761 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1762 1.6 christos {
1763 1.6 christos unsigned int reg_bits = get_operand_specific_data (self);
1764 1.6 christos unsigned int val = extract_all_fields (self, code);
1765 1.6 christos info->reglane.regno = val & ((1 << reg_bits) - 1);
1766 1.6 christos info->reglane.index = val >> reg_bits;
1767 1.6 christos return TRUE;
1768 1.6 christos }
1769 1.6 christos
1770 1.6 christos /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1771 1.6 christos to use for Zn. The opcode-dependent value specifies the number
1772 1.6 christos of registers in the list. */
1773 1.6 christos bfd_boolean
1774 1.6 christos aarch64_ext_sve_reglist (const aarch64_operand *self,
1775 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1776 1.6 christos const aarch64_inst *inst ATTRIBUTE_UNUSED,
1777 1.6 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1778 1.6 christos {
1779 1.6 christos info->reglist.first_regno = extract_field (self->fields[0], code, 0);
1780 1.6 christos info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
1781 1.6 christos return TRUE;
1782 1.6 christos }
1783 1.6 christos
1784 1.6 christos /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
1785 1.6 christos fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1786 1.6 christos field. */
1787 1.6 christos bfd_boolean
1788 1.6 christos aarch64_ext_sve_scale (const aarch64_operand *self,
1789 1.6 christos aarch64_opnd_info *info, aarch64_insn code,
1790 1.6 christos const aarch64_inst *inst, aarch64_operand_error *errors)
1791 1.6 christos {
1792 1.6 christos int val;
1793 1.6 christos
1794 1.6 christos if (!aarch64_ext_imm (self, info, code, inst, errors))
1795 1.6 christos return FALSE;
1796 1.6 christos val = extract_field (FLD_SVE_imm4, code, 0);
1797 1.6 christos info->shifter.kind = AARCH64_MOD_MUL;
1798 1.6 christos info->shifter.amount = val + 1;
1799 1.6 christos info->shifter.operator_present = (val != 0);
1800 1.6 christos info->shifter.amount_present = (val != 0);
1801 1.6 christos return TRUE;
1802 1.6 christos }
1803 1.6 christos
1804 1.6 christos /* Return the top set bit in VALUE, which is expected to be relatively
1805 1.6 christos small. */
1806 1.6 christos static uint64_t
1807 1.6 christos get_top_bit (uint64_t value)
1808 1.6 christos {
1809 1.6 christos while ((value & -value) != value)
1810 1.6 christos value -= value & -value;
1811 1.6 christos return value;
1812 1.6 christos }
1813 1.6 christos
1814 1.6 christos /* Decode an SVE shift-left immediate. */
1815 1.6 christos bfd_boolean
1816 1.6 christos aarch64_ext_sve_shlimm (const aarch64_operand *self,
1817 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
1818 1.6 christos const aarch64_inst *inst, aarch64_operand_error *errors)
1819 1.6 christos {
1820 1.6 christos if (!aarch64_ext_imm (self, info, code, inst, errors)
1821 1.6 christos || info->imm.value == 0)
1822 1.6 christos return FALSE;
1823 1.6 christos
1824 1.6 christos info->imm.value -= get_top_bit (info->imm.value);
1825 1.6 christos return TRUE;
1826 1.6 christos }
1827 1.6 christos
1828 1.6 christos /* Decode an SVE shift-right immediate. */
1829 1.6 christos bfd_boolean
1830 1.6 christos aarch64_ext_sve_shrimm (const aarch64_operand *self,
1831 1.6 christos aarch64_opnd_info *info, const aarch64_insn code,
1832 1.6 christos const aarch64_inst *inst, aarch64_operand_error *errors)
1833 1.6 christos {
1834 1.6 christos if (!aarch64_ext_imm (self, info, code, inst, errors)
1835 1.6 christos || info->imm.value == 0)
1836 1.6 christos return FALSE;
1837 1.6 christos
1838 1.1 christos info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
1839 1.1 christos return TRUE;
1840 1.1 christos }
1841 1.1 christos
1842 1.1 christos /* Bitfields that are commonly used to encode certain operands' information
1844 1.1 christos may be partially used as part of the base opcode in some instructions.
1845 1.1 christos For example, the bit 1 of the field 'size' in
1846 1.1 christos FCVTXN <Vb><d>, <Va><n>
1847 1.1 christos is actually part of the base opcode, while only size<0> is available
1848 1.1 christos for encoding the register type. Another example is the AdvSIMD
1849 1.1 christos instruction ORR (register), in which the field 'size' is also used for
1850 1.1 christos the base opcode, leaving only the field 'Q' available to encode the
1851 1.1 christos vector register arrangement specifier '8B' or '16B'.
1852 1.1 christos
1853 1.1 christos This function tries to deduce the qualifier from the value of partially
1854 1.1 christos constrained field(s). Given the VALUE of such a field or fields, the
1855 1.1 christos qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1856 1.1 christos operand encoding), the function returns the matching qualifier or
1857 1.1 christos AARCH64_OPND_QLF_NIL if nothing matches.
1858 1.1 christos
1859 1.1 christos N.B. CANDIDATES is a group of possible qualifiers that are valid for
1860 1.1 christos one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1861 1.1 christos may end with AARCH64_OPND_QLF_NIL. */
1862 1.1 christos
1863 1.1 christos static enum aarch64_opnd_qualifier
1864 1.1 christos get_qualifier_from_partial_encoding (aarch64_insn value,
1865 1.1 christos const enum aarch64_opnd_qualifier* \
1866 1.1 christos candidates,
1867 1.1 christos aarch64_insn mask)
1868 1.1 christos {
1869 1.1 christos int i;
1870 1.1 christos DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
1871 1.1 christos for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1872 1.1 christos {
1873 1.1 christos aarch64_insn standard_value;
1874 1.1 christos if (candidates[i] == AARCH64_OPND_QLF_NIL)
1875 1.1 christos break;
1876 1.1 christos standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
1877 1.1 christos if ((standard_value & mask) == (value & mask))
1878 1.1 christos return candidates[i];
1879 1.1 christos }
1880 1.1 christos return AARCH64_OPND_QLF_NIL;
1881 1.1 christos }
1882 1.1 christos
1883 1.1 christos /* Given a list of qualifier sequences, return all possible valid qualifiers
1884 1.1 christos for operand IDX in QUALIFIERS.
1885 1.1 christos Assume QUALIFIERS is an array whose length is large enough. */
1886 1.1 christos
1887 1.1 christos static void
1888 1.1 christos get_operand_possible_qualifiers (int idx,
1889 1.1 christos const aarch64_opnd_qualifier_seq_t *list,
1890 1.1 christos enum aarch64_opnd_qualifier *qualifiers)
1891 1.1 christos {
1892 1.1 christos int i;
1893 1.1 christos for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1894 1.1 christos if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
1895 1.1 christos break;
1896 1.1 christos }
1897 1.1 christos
1898 1.1 christos /* Decode the size Q field for e.g. SHADD.
1899 1.1 christos We tag one operand with the qualifer according to the code;
1900 1.1 christos whether the qualifier is valid for this opcode or not, it is the
1901 1.1 christos duty of the semantic checking. */
1902 1.1 christos
1903 1.1 christos static int
1904 1.1 christos decode_sizeq (aarch64_inst *inst)
1905 1.1 christos {
1906 1.1 christos int idx;
1907 1.1 christos enum aarch64_opnd_qualifier qualifier;
1908 1.1 christos aarch64_insn code;
1909 1.1 christos aarch64_insn value, mask;
1910 1.1 christos enum aarch64_field_kind fld_sz;
1911 1.1 christos enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1912 1.1 christos
1913 1.1 christos if (inst->opcode->iclass == asisdlse
1914 1.1 christos || inst->opcode->iclass == asisdlsep
1915 1.1 christos || inst->opcode->iclass == asisdlso
1916 1.1 christos || inst->opcode->iclass == asisdlsop)
1917 1.1 christos fld_sz = FLD_vldst_size;
1918 1.1 christos else
1919 1.1 christos fld_sz = FLD_size;
1920 1.1 christos
1921 1.1 christos code = inst->value;
1922 1.1 christos value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
1923 1.1 christos /* Obtain the info that which bits of fields Q and size are actually
1924 1.1 christos available for operand encoding. Opcodes like FMAXNM and FMLA have
1925 1.1 christos size[1] unavailable. */
1926 1.1 christos mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
1927 1.1 christos
1928 1.1 christos /* The index of the operand we are going to tag a qualifier and the qualifer
1929 1.1 christos itself are reasoned from the value of the size and Q fields and the
1930 1.1 christos possible valid qualifier lists. */
1931 1.1 christos idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
1932 1.1 christos DEBUG_TRACE ("key idx: %d", idx);
1933 1.1 christos
1934 1.1 christos /* For most related instruciton, size:Q are fully available for operand
1935 1.1 christos encoding. */
1936 1.1 christos if (mask == 0x7)
1937 1.1 christos {
1938 1.1 christos inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
1939 1.1 christos return 1;
1940 1.1 christos }
1941 1.1 christos
1942 1.1 christos get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1943 1.1 christos candidates);
1944 1.1 christos #ifdef DEBUG_AARCH64
1945 1.1 christos if (debug_dump)
1946 1.1 christos {
1947 1.1 christos int i;
1948 1.1 christos for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
1949 1.1 christos && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1950 1.1 christos DEBUG_TRACE ("qualifier %d: %s", i,
1951 1.1 christos aarch64_get_qualifier_name(candidates[i]));
1952 1.1 christos DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
1953 1.1 christos }
1954 1.1 christos #endif /* DEBUG_AARCH64 */
1955 1.1 christos
1956 1.1 christos qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
1957 1.1 christos
1958 1.1 christos if (qualifier == AARCH64_OPND_QLF_NIL)
1959 1.1 christos return 0;
1960 1.1 christos
1961 1.1 christos inst->operands[idx].qualifier = qualifier;
1962 1.1 christos return 1;
1963 1.1 christos }
1964 1.1 christos
1965 1.1 christos /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1966 1.1 christos e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1967 1.1 christos
1968 1.1 christos static int
1969 1.1 christos decode_asimd_fcvt (aarch64_inst *inst)
1970 1.1 christos {
1971 1.1 christos aarch64_field field = {0, 0};
1972 1.1 christos aarch64_insn value;
1973 1.1 christos enum aarch64_opnd_qualifier qualifier;
1974 1.1 christos
1975 1.1 christos gen_sub_field (FLD_size, 0, 1, &field);
1976 1.1 christos value = extract_field_2 (&field, inst->value, 0);
1977 1.1 christos qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
1978 1.1 christos : AARCH64_OPND_QLF_V_2D;
1979 1.1 christos switch (inst->opcode->op)
1980 1.1 christos {
1981 1.1 christos case OP_FCVTN:
1982 1.1 christos case OP_FCVTN2:
1983 1.1 christos /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1984 1.1 christos inst->operands[1].qualifier = qualifier;
1985 1.1 christos break;
1986 1.1 christos case OP_FCVTL:
1987 1.1 christos case OP_FCVTL2:
1988 1.1 christos /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1989 1.1 christos inst->operands[0].qualifier = qualifier;
1990 1.1 christos break;
1991 1.1 christos default:
1992 1.1 christos assert (0);
1993 1.1 christos return 0;
1994 1.1 christos }
1995 1.1 christos
1996 1.1 christos return 1;
1997 1.1 christos }
1998 1.1 christos
1999 1.1 christos /* Decode size[0], i.e. bit 22, for
2000 1.1 christos e.g. FCVTXN <Vb><d>, <Va><n>. */
2001 1.1 christos
2002 1.1 christos static int
2003 1.1 christos decode_asisd_fcvtxn (aarch64_inst *inst)
2004 1.1 christos {
2005 1.1 christos aarch64_field field = {0, 0};
2006 1.1 christos gen_sub_field (FLD_size, 0, 1, &field);
2007 1.1 christos if (!extract_field_2 (&field, inst->value, 0))
2008 1.1 christos return 0;
2009 1.1 christos inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
2010 1.1 christos return 1;
2011 1.1 christos }
2012 1.1 christos
2013 1.1 christos /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
2014 1.1 christos static int
2015 1.1 christos decode_fcvt (aarch64_inst *inst)
2016 1.1 christos {
2017 1.1 christos enum aarch64_opnd_qualifier qualifier;
2018 1.1 christos aarch64_insn value;
2019 1.1 christos const aarch64_field field = {15, 2};
2020 1.1 christos
2021 1.1 christos /* opc dstsize */
2022 1.1 christos value = extract_field_2 (&field, inst->value, 0);
2023 1.1 christos switch (value)
2024 1.1 christos {
2025 1.1 christos case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
2026 1.1 christos case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
2027 1.1 christos case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
2028 1.1 christos default: return 0;
2029 1.1 christos }
2030 1.1 christos inst->operands[0].qualifier = qualifier;
2031 1.1 christos
2032 1.1 christos return 1;
2033 1.1 christos }
2034 1.1 christos
2035 1.1 christos /* Do miscellaneous decodings that are not common enough to be driven by
2036 1.1 christos flags. */
2037 1.1 christos
2038 1.6 christos static int
2039 1.1 christos do_misc_decoding (aarch64_inst *inst)
2040 1.1 christos {
2041 1.1 christos unsigned int value;
2042 1.1 christos switch (inst->opcode->op)
2043 1.6 christos {
2044 1.1 christos case OP_FCVT:
2045 1.1 christos return decode_fcvt (inst);
2046 1.1 christos
2047 1.1 christos case OP_FCVTN:
2048 1.1 christos case OP_FCVTN2:
2049 1.6 christos case OP_FCVTL:
2050 1.1 christos case OP_FCVTL2:
2051 1.1 christos return decode_asimd_fcvt (inst);
2052 1.6 christos
2053 1.6 christos case OP_FCVTXN_S:
2054 1.6 christos return decode_asisd_fcvtxn (inst);
2055 1.6 christos
2056 1.6 christos case OP_MOV_P_P:
2057 1.6 christos case OP_MOVS_P_P:
2058 1.6 christos value = extract_field (FLD_SVE_Pn, inst->value, 0);
2059 1.6 christos return (value == extract_field (FLD_SVE_Pm, inst->value, 0)
2060 1.6 christos && value == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2061 1.6 christos
2062 1.6 christos case OP_MOV_Z_P_Z:
2063 1.6 christos return (extract_field (FLD_SVE_Zd, inst->value, 0)
2064 1.6 christos == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2065 1.6 christos
2066 1.6 christos case OP_MOV_Z_V:
2067 1.6 christos /* Index must be zero. */
2068 1.6 christos value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2069 1.6 christos return value > 0 && value <= 16 && value == (value & -value);
2070 1.6 christos
2071 1.6 christos case OP_MOV_Z_Z:
2072 1.6 christos return (extract_field (FLD_SVE_Zn, inst->value, 0)
2073 1.6 christos == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2074 1.6 christos
2075 1.6 christos case OP_MOV_Z_Zi:
2076 1.6 christos /* Index must be nonzero. */
2077 1.6 christos value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2078 1.6 christos return value > 0 && value != (value & -value);
2079 1.6 christos
2080 1.6 christos case OP_MOVM_P_P_P:
2081 1.6 christos return (extract_field (FLD_SVE_Pd, inst->value, 0)
2082 1.6 christos == extract_field (FLD_SVE_Pm, inst->value, 0));
2083 1.6 christos
2084 1.6 christos case OP_MOVZS_P_P_P:
2085 1.6 christos case OP_MOVZ_P_P_P:
2086 1.6 christos return (extract_field (FLD_SVE_Pn, inst->value, 0)
2087 1.6 christos == extract_field (FLD_SVE_Pm, inst->value, 0));
2088 1.6 christos
2089 1.6 christos case OP_NOTS_P_P_P_Z:
2090 1.6 christos case OP_NOT_P_P_P_Z:
2091 1.1 christos return (extract_field (FLD_SVE_Pm, inst->value, 0)
2092 1.1 christos == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2093 1.1 christos
2094 1.1 christos default:
2095 1.1 christos return 0;
2096 1.1 christos }
2097 1.1 christos }
2098 1.1 christos
2099 1.1 christos /* Opcodes that have fields shared by multiple operands are usually flagged
2100 1.1 christos with flags. In this function, we detect such flags, decode the related
2101 1.1 christos field(s) and store the information in one of the related operands. The
2102 1.1 christos 'one' operand is not any operand but one of the operands that can
2103 1.1 christos accommadate all the information that has been decoded. */
2104 1.1 christos
2105 1.1 christos static int
2106 1.1 christos do_special_decoding (aarch64_inst *inst)
2107 1.1 christos {
2108 1.1 christos int idx;
2109 1.1 christos aarch64_insn value;
2110 1.1 christos /* Condition for truly conditional executed instructions, e.g. b.cond. */
2111 1.1 christos if (inst->opcode->flags & F_COND)
2112 1.1 christos {
2113 1.1 christos value = extract_field (FLD_cond2, inst->value, 0);
2114 1.1 christos inst->cond = get_cond_from_value (value);
2115 1.1 christos }
2116 1.1 christos /* 'sf' field. */
2117 1.1 christos if (inst->opcode->flags & F_SF)
2118 1.1 christos {
2119 1.1 christos idx = select_operand_for_sf_field_coding (inst->opcode);
2120 1.1 christos value = extract_field (FLD_sf, inst->value, 0);
2121 1.1 christos inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2122 1.1 christos if ((inst->opcode->flags & F_N)
2123 1.3 christos && extract_field (FLD_N, inst->value, 0) != value)
2124 1.3 christos return 0;
2125 1.3 christos }
2126 1.3 christos /* 'sf' field. */
2127 1.3 christos if (inst->opcode->flags & F_LSE_SZ)
2128 1.3 christos {
2129 1.3 christos idx = select_operand_for_sf_field_coding (inst->opcode);
2130 1.1 christos value = extract_field (FLD_lse_sz, inst->value, 0);
2131 1.1 christos inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2132 1.1 christos }
2133 1.1 christos /* size:Q fields. */
2134 1.1 christos if (inst->opcode->flags & F_SIZEQ)
2135 1.1 christos return decode_sizeq (inst);
2136 1.1 christos
2137 1.1 christos if (inst->opcode->flags & F_FPTYPE)
2138 1.1 christos {
2139 1.1 christos idx = select_operand_for_fptype_field_coding (inst->opcode);
2140 1.1 christos value = extract_field (FLD_type, inst->value, 0);
2141 1.1 christos switch (value)
2142 1.1 christos {
2143 1.1 christos case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
2144 1.1 christos case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
2145 1.1 christos case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
2146 1.1 christos default: return 0;
2147 1.1 christos }
2148 1.1 christos }
2149 1.1 christos
2150 1.1 christos if (inst->opcode->flags & F_SSIZE)
2151 1.1 christos {
2152 1.1 christos /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2153 1.1 christos of the base opcode. */
2154 1.1 christos aarch64_insn mask;
2155 1.1 christos enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2156 1.1 christos idx = select_operand_for_scalar_size_field_coding (inst->opcode);
2157 1.1 christos value = extract_field (FLD_size, inst->value, inst->opcode->mask);
2158 1.1 christos mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
2159 1.1 christos /* For most related instruciton, the 'size' field is fully available for
2160 1.1 christos operand encoding. */
2161 1.1 christos if (mask == 0x3)
2162 1.1 christos inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
2163 1.1 christos else
2164 1.1 christos {
2165 1.1 christos get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2166 1.1 christos candidates);
2167 1.1 christos inst->operands[idx].qualifier
2168 1.1 christos = get_qualifier_from_partial_encoding (value, candidates, mask);
2169 1.1 christos }
2170 1.1 christos }
2171 1.1 christos
2172 1.1 christos if (inst->opcode->flags & F_T)
2173 1.1 christos {
2174 1.1 christos /* Num of consecutive '0's on the right side of imm5<3:0>. */
2175 1.1 christos int num = 0;
2176 1.1 christos unsigned val, Q;
2177 1.1 christos assert (aarch64_get_operand_class (inst->opcode->operands[0])
2178 1.1 christos == AARCH64_OPND_CLASS_SIMD_REG);
2179 1.1 christos /* imm5<3:0> q <t>
2180 1.1 christos 0000 x reserved
2181 1.1 christos xxx1 0 8b
2182 1.1 christos xxx1 1 16b
2183 1.1 christos xx10 0 4h
2184 1.1 christos xx10 1 8h
2185 1.1 christos x100 0 2s
2186 1.1 christos x100 1 4s
2187 1.1 christos 1000 0 reserved
2188 1.1 christos 1000 1 2d */
2189 1.1 christos val = extract_field (FLD_imm5, inst->value, 0);
2190 1.1 christos while ((val & 0x1) == 0 && ++num <= 3)
2191 1.1 christos val >>= 1;
2192 1.1 christos if (num > 3)
2193 1.1 christos return 0;
2194 1.1 christos Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
2195 1.1 christos inst->operands[0].qualifier =
2196 1.1 christos get_vreg_qualifier_from_value ((num << 1) | Q);
2197 1.1 christos }
2198 1.1 christos
2199 1.1 christos if (inst->opcode->flags & F_GPRSIZE_IN_Q)
2200 1.1 christos {
2201 1.1 christos /* Use Rt to encode in the case of e.g.
2202 1.1 christos STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2203 1.1 christos idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
2204 1.1 christos if (idx == -1)
2205 1.1 christos {
2206 1.1 christos /* Otherwise use the result operand, which has to be a integer
2207 1.1 christos register. */
2208 1.1 christos assert (aarch64_get_operand_class (inst->opcode->operands[0])
2209 1.1 christos == AARCH64_OPND_CLASS_INT_REG);
2210 1.1 christos idx = 0;
2211 1.1 christos }
2212 1.1 christos assert (idx == 0 || idx == 1);
2213 1.1 christos value = extract_field (FLD_Q, inst->value, 0);
2214 1.1 christos inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2215 1.1 christos }
2216 1.1 christos
2217 1.1 christos if (inst->opcode->flags & F_LDS_SIZE)
2218 1.1 christos {
2219 1.1 christos aarch64_field field = {0, 0};
2220 1.1 christos assert (aarch64_get_operand_class (inst->opcode->operands[0])
2221 1.1 christos == AARCH64_OPND_CLASS_INT_REG);
2222 1.1 christos gen_sub_field (FLD_opc, 0, 1, &field);
2223 1.1 christos value = extract_field_2 (&field, inst->value, 0);
2224 1.1 christos inst->operands[0].qualifier
2225 1.1 christos = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
2226 1.1 christos }
2227 1.1 christos
2228 1.1 christos /* Miscellaneous decoding; done as the last step. */
2229 1.1 christos if (inst->opcode->flags & F_MISC)
2230 1.1 christos return do_misc_decoding (inst);
2231 1.1 christos
2232 1.1 christos return 1;
2233 1.1 christos }
2234 1.1 christos
2235 1.1 christos /* Converters converting a real opcode instruction to its alias form. */
2236 1.1 christos
2237 1.1 christos /* ROR <Wd>, <Ws>, #<shift>
2238 1.1 christos is equivalent to:
2239 1.1 christos EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2240 1.1 christos static int
2241 1.1 christos convert_extr_to_ror (aarch64_inst *inst)
2242 1.1 christos {
2243 1.1 christos if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2244 1.1 christos {
2245 1.1 christos copy_operand_info (inst, 2, 3);
2246 1.1 christos inst->operands[3].type = AARCH64_OPND_NIL;
2247 1.1 christos return 1;
2248 1.1 christos }
2249 1.1 christos return 0;
2250 1.1 christos }
2251 1.1 christos
2252 1.1 christos /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2253 1.1 christos is equivalent to:
2254 1.1 christos USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2255 1.1 christos static int
2256 1.1 christos convert_shll_to_xtl (aarch64_inst *inst)
2257 1.1 christos {
2258 1.1 christos if (inst->operands[2].imm.value == 0)
2259 1.1 christos {
2260 1.1 christos inst->operands[2].type = AARCH64_OPND_NIL;
2261 1.1 christos return 1;
2262 1.1 christos }
2263 1.1 christos return 0;
2264 1.1 christos }
2265 1.1 christos
2266 1.1 christos /* Convert
2267 1.1 christos UBFM <Xd>, <Xn>, #<shift>, #63.
2268 1.1 christos to
2269 1.1 christos LSR <Xd>, <Xn>, #<shift>. */
2270 1.1 christos static int
2271 1.1 christos convert_bfm_to_sr (aarch64_inst *inst)
2272 1.1 christos {
2273 1.1 christos int64_t imms, val;
2274 1.1 christos
2275 1.1 christos imms = inst->operands[3].imm.value;
2276 1.1 christos val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2277 1.1 christos if (imms == val)
2278 1.1 christos {
2279 1.1 christos inst->operands[3].type = AARCH64_OPND_NIL;
2280 1.1 christos return 1;
2281 1.1 christos }
2282 1.1 christos
2283 1.1 christos return 0;
2284 1.1 christos }
2285 1.1 christos
2286 1.1 christos /* Convert MOV to ORR. */
2287 1.1 christos static int
2288 1.1 christos convert_orr_to_mov (aarch64_inst *inst)
2289 1.1 christos {
2290 1.1 christos /* MOV <Vd>.<T>, <Vn>.<T>
2291 1.1 christos is equivalent to:
2292 1.1 christos ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2293 1.1 christos if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2294 1.1 christos {
2295 1.1 christos inst->operands[2].type = AARCH64_OPND_NIL;
2296 1.1 christos return 1;
2297 1.1 christos }
2298 1.1 christos return 0;
2299 1.1 christos }
2300 1.1 christos
2301 1.1 christos /* When <imms> >= <immr>, the instruction written:
2302 1.1 christos SBFX <Xd>, <Xn>, #<lsb>, #<width>
2303 1.1 christos is equivalent to:
2304 1.1 christos SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2305 1.1 christos
2306 1.1 christos static int
2307 1.1 christos convert_bfm_to_bfx (aarch64_inst *inst)
2308 1.1 christos {
2309 1.1 christos int64_t immr, imms;
2310 1.1 christos
2311 1.1 christos immr = inst->operands[2].imm.value;
2312 1.1 christos imms = inst->operands[3].imm.value;
2313 1.1 christos if (imms >= immr)
2314 1.1 christos {
2315 1.1 christos int64_t lsb = immr;
2316 1.1 christos inst->operands[2].imm.value = lsb;
2317 1.1 christos inst->operands[3].imm.value = imms + 1 - lsb;
2318 1.1 christos /* The two opcodes have different qualifiers for
2319 1.1 christos the immediate operands; reset to help the checking. */
2320 1.1 christos reset_operand_qualifier (inst, 2);
2321 1.1 christos reset_operand_qualifier (inst, 3);
2322 1.1 christos return 1;
2323 1.1 christos }
2324 1.1 christos
2325 1.1 christos return 0;
2326 1.1 christos }
2327 1.1 christos
2328 1.1 christos /* When <imms> < <immr>, the instruction written:
2329 1.1 christos SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2330 1.1 christos is equivalent to:
2331 1.1 christos SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2332 1.1 christos
2333 1.1 christos static int
2334 1.1 christos convert_bfm_to_bfi (aarch64_inst *inst)
2335 1.1 christos {
2336 1.1 christos int64_t immr, imms, val;
2337 1.1 christos
2338 1.1 christos immr = inst->operands[2].imm.value;
2339 1.1 christos imms = inst->operands[3].imm.value;
2340 1.1 christos val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2341 1.1 christos if (imms < immr)
2342 1.1 christos {
2343 1.1 christos inst->operands[2].imm.value = (val - immr) & (val - 1);
2344 1.1 christos inst->operands[3].imm.value = imms + 1;
2345 1.1 christos /* The two opcodes have different qualifiers for
2346 1.1 christos the immediate operands; reset to help the checking. */
2347 1.1 christos reset_operand_qualifier (inst, 2);
2348 1.1 christos reset_operand_qualifier (inst, 3);
2349 1.1 christos return 1;
2350 1.1 christos }
2351 1.1 christos
2352 1.1 christos return 0;
2353 1.3 christos }
2354 1.3 christos
2355 1.3 christos /* The instruction written:
2356 1.3 christos BFC <Xd>, #<lsb>, #<width>
2357 1.3 christos is equivalent to:
2358 1.3 christos BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2359 1.3 christos
2360 1.3 christos static int
2361 1.3 christos convert_bfm_to_bfc (aarch64_inst *inst)
2362 1.3 christos {
2363 1.3 christos int64_t immr, imms, val;
2364 1.3 christos
2365 1.3 christos /* Should have been assured by the base opcode value. */
2366 1.3 christos assert (inst->operands[1].reg.regno == 0x1f);
2367 1.3 christos
2368 1.3 christos immr = inst->operands[2].imm.value;
2369 1.3 christos imms = inst->operands[3].imm.value;
2370 1.3 christos val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2371 1.3 christos if (imms < immr)
2372 1.3 christos {
2373 1.3 christos /* Drop XZR from the second operand. */
2374 1.3 christos copy_operand_info (inst, 1, 2);
2375 1.3 christos copy_operand_info (inst, 2, 3);
2376 1.3 christos inst->operands[3].type = AARCH64_OPND_NIL;
2377 1.3 christos
2378 1.3 christos /* Recalculate the immediates. */
2379 1.3 christos inst->operands[1].imm.value = (val - immr) & (val - 1);
2380 1.3 christos inst->operands[2].imm.value = imms + 1;
2381 1.3 christos
2382 1.3 christos /* The two opcodes have different qualifiers for the operands; reset to
2383 1.3 christos help the checking. */
2384 1.3 christos reset_operand_qualifier (inst, 1);
2385 1.3 christos reset_operand_qualifier (inst, 2);
2386 1.3 christos reset_operand_qualifier (inst, 3);
2387 1.3 christos
2388 1.3 christos return 1;
2389 1.3 christos }
2390 1.3 christos
2391 1.3 christos return 0;
2392 1.1 christos }
2393 1.1 christos
2394 1.1 christos /* The instruction written:
2395 1.1 christos LSL <Xd>, <Xn>, #<shift>
2396 1.1 christos is equivalent to:
2397 1.1 christos UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2398 1.1 christos
2399 1.1 christos static int
2400 1.1 christos convert_ubfm_to_lsl (aarch64_inst *inst)
2401 1.1 christos {
2402 1.1 christos int64_t immr = inst->operands[2].imm.value;
2403 1.1 christos int64_t imms = inst->operands[3].imm.value;
2404 1.1 christos int64_t val
2405 1.1 christos = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2406 1.1 christos
2407 1.1 christos if ((immr == 0 && imms == val) || immr == imms + 1)
2408 1.1 christos {
2409 1.1 christos inst->operands[3].type = AARCH64_OPND_NIL;
2410 1.1 christos inst->operands[2].imm.value = val - imms;
2411 1.1 christos return 1;
2412 1.1 christos }
2413 1.1 christos
2414 1.1 christos return 0;
2415 1.1 christos }
2416 1.3 christos
2417 1.3 christos /* CINC <Wd>, <Wn>, <cond>
2418 1.1 christos is equivalent to:
2419 1.1 christos CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2420 1.1 christos where <cond> is not AL or NV. */
2421 1.1 christos
2422 1.3 christos static int
2423 1.3 christos convert_from_csel (aarch64_inst *inst)
2424 1.1 christos {
2425 1.1 christos if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
2426 1.1 christos && (inst->operands[3].cond->value & 0xe) != 0xe)
2427 1.1 christos {
2428 1.1 christos copy_operand_info (inst, 2, 3);
2429 1.1 christos inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
2430 1.1 christos inst->operands[3].type = AARCH64_OPND_NIL;
2431 1.1 christos return 1;
2432 1.1 christos }
2433 1.1 christos return 0;
2434 1.1 christos }
2435 1.3 christos
2436 1.3 christos /* CSET <Wd>, <cond>
2437 1.1 christos is equivalent to:
2438 1.1 christos CSINC <Wd>, WZR, WZR, invert(<cond>)
2439 1.1 christos where <cond> is not AL or NV. */
2440 1.1 christos
2441 1.1 christos static int
2442 1.3 christos convert_csinc_to_cset (aarch64_inst *inst)
2443 1.3 christos {
2444 1.1 christos if (inst->operands[1].reg.regno == 0x1f
2445 1.1 christos && inst->operands[2].reg.regno == 0x1f
2446 1.1 christos && (inst->operands[3].cond->value & 0xe) != 0xe)
2447 1.1 christos {
2448 1.1 christos copy_operand_info (inst, 1, 3);
2449 1.1 christos inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
2450 1.1 christos inst->operands[3].type = AARCH64_OPND_NIL;
2451 1.1 christos inst->operands[2].type = AARCH64_OPND_NIL;
2452 1.1 christos return 1;
2453 1.1 christos }
2454 1.1 christos return 0;
2455 1.1 christos }
2456 1.1 christos
2457 1.1 christos /* MOV <Wd>, #<imm>
2458 1.1 christos is equivalent to:
2459 1.1 christos MOVZ <Wd>, #<imm16>, LSL #<shift>.
2460 1.1 christos
2461 1.1 christos A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2462 1.1 christos ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2463 1.1 christos or where a MOVN has an immediate that could be encoded by MOVZ, or where
2464 1.1 christos MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2465 1.1 christos machine-instruction mnemonic must be used. */
2466 1.1 christos
2467 1.1 christos static int
2468 1.1 christos convert_movewide_to_mov (aarch64_inst *inst)
2469 1.1 christos {
2470 1.1 christos uint64_t value = inst->operands[1].imm.value;
2471 1.1 christos /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2472 1.1 christos if (value == 0 && inst->operands[1].shifter.amount != 0)
2473 1.1 christos return 0;
2474 1.1 christos inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2475 1.1 christos inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
2476 1.1 christos value <<= inst->operands[1].shifter.amount;
2477 1.1 christos /* As an alias convertor, it has to be clear that the INST->OPCODE
2478 1.1 christos is the opcode of the real instruction. */
2479 1.1 christos if (inst->opcode->op == OP_MOVN)
2480 1.1 christos {
2481 1.6 christos int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2482 1.1 christos value = ~value;
2483 1.1 christos /* A MOVN has an immediate that could be encoded by MOVZ. */
2484 1.1 christos if (aarch64_wide_constant_p (value, is32, NULL))
2485 1.1 christos return 0;
2486 1.1 christos }
2487 1.1 christos inst->operands[1].imm.value = value;
2488 1.1 christos inst->operands[1].shifter.amount = 0;
2489 1.1 christos return 1;
2490 1.1 christos }
2491 1.1 christos
2492 1.1 christos /* MOV <Wd>, #<imm>
2493 1.1 christos is equivalent to:
2494 1.1 christos ORR <Wd>, WZR, #<imm>.
2495 1.1 christos
2496 1.1 christos A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2497 1.1 christos ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2498 1.1 christos or where a MOVN has an immediate that could be encoded by MOVZ, or where
2499 1.1 christos MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2500 1.1 christos machine-instruction mnemonic must be used. */
2501 1.1 christos
2502 1.1 christos static int
2503 1.1 christos convert_movebitmask_to_mov (aarch64_inst *inst)
2504 1.1 christos {
2505 1.1 christos int is32;
2506 1.1 christos uint64_t value;
2507 1.1 christos
2508 1.1 christos /* Should have been assured by the base opcode value. */
2509 1.1 christos assert (inst->operands[1].reg.regno == 0x1f);
2510 1.1 christos copy_operand_info (inst, 1, 2);
2511 1.1 christos is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2512 1.1 christos inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2513 1.1 christos value = inst->operands[1].imm.value;
2514 1.6 christos /* ORR has an immediate that could be generated by a MOVZ or MOVN
2515 1.6 christos instruction. */
2516 1.1 christos if (inst->operands[0].reg.regno != 0x1f
2517 1.1 christos && (aarch64_wide_constant_p (value, is32, NULL)
2518 1.1 christos || aarch64_wide_constant_p (~value, is32, NULL)))
2519 1.1 christos return 0;
2520 1.1 christos
2521 1.1 christos inst->operands[2].type = AARCH64_OPND_NIL;
2522 1.1 christos return 1;
2523 1.1 christos }
2524 1.1 christos
2525 1.1 christos /* Some alias opcodes are disassembled by being converted from their real-form.
2526 1.1 christos N.B. INST->OPCODE is the real opcode rather than the alias. */
2527 1.1 christos
2528 1.1 christos static int
2529 1.1 christos convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
2530 1.1 christos {
2531 1.1 christos switch (alias->op)
2532 1.1 christos {
2533 1.1 christos case OP_ASR_IMM:
2534 1.1 christos case OP_LSR_IMM:
2535 1.1 christos return convert_bfm_to_sr (inst);
2536 1.1 christos case OP_LSL_IMM:
2537 1.1 christos return convert_ubfm_to_lsl (inst);
2538 1.1 christos case OP_CINC:
2539 1.1 christos case OP_CINV:
2540 1.1 christos case OP_CNEG:
2541 1.1 christos return convert_from_csel (inst);
2542 1.1 christos case OP_CSET:
2543 1.1 christos case OP_CSETM:
2544 1.1 christos return convert_csinc_to_cset (inst);
2545 1.1 christos case OP_UBFX:
2546 1.1 christos case OP_BFXIL:
2547 1.1 christos case OP_SBFX:
2548 1.1 christos return convert_bfm_to_bfx (inst);
2549 1.1 christos case OP_SBFIZ:
2550 1.3 christos case OP_BFI:
2551 1.3 christos case OP_UBFIZ:
2552 1.1 christos return convert_bfm_to_bfi (inst);
2553 1.1 christos case OP_BFC:
2554 1.1 christos return convert_bfm_to_bfc (inst);
2555 1.1 christos case OP_MOV_V:
2556 1.1 christos return convert_orr_to_mov (inst);
2557 1.1 christos case OP_MOV_IMM_WIDE:
2558 1.1 christos case OP_MOV_IMM_WIDEN:
2559 1.1 christos return convert_movewide_to_mov (inst);
2560 1.1 christos case OP_MOV_IMM_LOG:
2561 1.1 christos return convert_movebitmask_to_mov (inst);
2562 1.1 christos case OP_ROR_IMM:
2563 1.1 christos return convert_extr_to_ror (inst);
2564 1.1 christos case OP_SXTL:
2565 1.1 christos case OP_SXTL2:
2566 1.1 christos case OP_UXTL:
2567 1.1 christos case OP_UXTL2:
2568 1.1 christos return convert_shll_to_xtl (inst);
2569 1.1 christos default:
2570 1.1 christos return 0;
2571 1.6 christos }
2572 1.6 christos }
2573 1.6 christos
2574 1.1 christos static bfd_boolean
2575 1.1 christos aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
2576 1.1 christos aarch64_inst *, int, aarch64_operand_error *errors);
2577 1.1 christos
2578 1.1 christos /* Given the instruction information in *INST, check if the instruction has
2579 1.1 christos any alias form that can be used to represent *INST. If the answer is yes,
2580 1.1 christos update *INST to be in the form of the determined alias. */
2581 1.1 christos
2582 1.1 christos /* In the opcode description table, the following flags are used in opcode
2583 1.1 christos entries to help establish the relations between the real and alias opcodes:
2584 1.1 christos
2585 1.1 christos F_ALIAS: opcode is an alias
2586 1.1 christos F_HAS_ALIAS: opcode has alias(es)
2587 1.1 christos F_P1
2588 1.1 christos F_P2
2589 1.1 christos F_P3: Disassembly preference priority 1-3 (the larger the
2590 1.1 christos higher). If nothing is specified, it is the priority
2591 1.1 christos 0 by default, i.e. the lowest priority.
2592 1.1 christos
2593 1.1 christos Although the relation between the machine and the alias instructions are not
2594 1.1 christos explicitly described, it can be easily determined from the base opcode
2595 1.1 christos values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2596 1.1 christos description entries:
2597 1.1 christos
2598 1.1 christos The mask of an alias opcode must be equal to or a super-set (i.e. more
2599 1.1 christos constrained) of that of the aliased opcode; so is the base opcode value.
2600 1.1 christos
2601 1.1 christos if (opcode_has_alias (real) && alias_opcode_p (opcode)
2602 1.1 christos && (opcode->mask & real->mask) == real->mask
2603 1.1 christos && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2604 1.1 christos then OPCODE is an alias of, and only of, the REAL instruction
2605 1.1 christos
2606 1.1 christos The alias relationship is forced flat-structured to keep related algorithm
2607 1.1 christos simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2608 1.1 christos
2609 1.1 christos During the disassembling, the decoding decision tree (in
2610 1.1 christos opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2611 1.1 christos if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2612 1.1 christos not specified), the disassembler will check whether there is any alias
2613 1.1 christos instruction exists for this real instruction. If there is, the disassembler
2614 1.1 christos will try to disassemble the 32-bit binary again using the alias's rule, or
2615 1.1 christos try to convert the IR to the form of the alias. In the case of the multiple
2616 1.1 christos aliases, the aliases are tried one by one from the highest priority
2617 1.1 christos (currently the flag F_P3) to the lowest priority (no priority flag), and the
2618 1.1 christos first succeeds first adopted.
2619 1.1 christos
2620 1.1 christos You may ask why there is a need for the conversion of IR from one form to
2621 1.1 christos another in handling certain aliases. This is because on one hand it avoids
2622 1.1 christos adding more operand code to handle unusual encoding/decoding; on other
2623 1.1 christos hand, during the disassembling, the conversion is an effective approach to
2624 1.1 christos check the condition of an alias (as an alias may be adopted only if certain
2625 1.1 christos conditions are met).
2626 1.1 christos
2627 1.1 christos In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2628 1.1 christos aarch64_opcode_table and generated aarch64_find_alias_opcode and
2629 1.6 christos aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2630 1.6 christos
2631 1.1 christos static void
2632 1.1 christos determine_disassembling_preference (struct aarch64_inst *inst,
2633 1.1 christos aarch64_operand_error *errors)
2634 1.1 christos {
2635 1.1 christos const aarch64_opcode *opcode;
2636 1.1 christos const aarch64_opcode *alias;
2637 1.1 christos
2638 1.6 christos opcode = inst->opcode;
2639 1.1 christos
2640 1.1 christos /* This opcode does not have an alias, so use itself. */
2641 1.1 christos if (!opcode_has_alias (opcode))
2642 1.1 christos return;
2643 1.1 christos
2644 1.1 christos alias = aarch64_find_alias_opcode (opcode);
2645 1.1 christos assert (alias);
2646 1.1 christos
2647 1.1 christos #ifdef DEBUG_AARCH64
2648 1.1 christos if (debug_dump)
2649 1.1 christos {
2650 1.1 christos const aarch64_opcode *tmp = alias;
2651 1.1 christos printf ("#### LIST orderd: ");
2652 1.1 christos while (tmp)
2653 1.1 christos {
2654 1.1 christos printf ("%s, ", tmp->name);
2655 1.1 christos tmp = aarch64_find_next_alias_opcode (tmp);
2656 1.1 christos }
2657 1.1 christos printf ("\n");
2658 1.1 christos }
2659 1.1 christos #endif /* DEBUG_AARCH64 */
2660 1.1 christos
2661 1.3 christos for (; alias; alias = aarch64_find_next_alias_opcode (alias))
2662 1.1 christos {
2663 1.1 christos DEBUG_TRACE ("try %s", alias->name);
2664 1.1 christos assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
2665 1.1 christos
2666 1.1 christos /* An alias can be a pseudo opcode which will never be used in the
2667 1.1 christos disassembly, e.g. BIC logical immediate is such a pseudo opcode
2668 1.1 christos aliasing AND. */
2669 1.1 christos if (pseudo_opcode_p (alias))
2670 1.1 christos {
2671 1.1 christos DEBUG_TRACE ("skip pseudo %s", alias->name);
2672 1.1 christos continue;
2673 1.1 christos }
2674 1.1 christos
2675 1.1 christos if ((inst->value & alias->mask) != alias->opcode)
2676 1.1 christos {
2677 1.1 christos DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
2678 1.1 christos continue;
2679 1.1 christos }
2680 1.1 christos /* No need to do any complicated transformation on operands, if the alias
2681 1.1 christos opcode does not have any operand. */
2682 1.1 christos if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
2683 1.1 christos {
2684 1.1 christos DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
2685 1.1 christos aarch64_replace_opcode (inst, alias);
2686 1.1 christos return;
2687 1.1 christos }
2688 1.1 christos if (alias->flags & F_CONV)
2689 1.1 christos {
2690 1.1 christos aarch64_inst copy;
2691 1.1 christos memcpy (©, inst, sizeof (aarch64_inst));
2692 1.1 christos /* ALIAS is the preference as long as the instruction can be
2693 1.1 christos successfully converted to the form of ALIAS. */
2694 1.1 christos if (convert_to_alias (©, alias) == 1)
2695 1.1 christos {
2696 1.1 christos aarch64_replace_opcode (©, alias);
2697 1.1 christos assert (aarch64_match_operands_constraint (©, NULL));
2698 1.1 christos DEBUG_TRACE ("succeed with %s via conversion", alias->name);
2699 1.1 christos memcpy (inst, ©, sizeof (aarch64_inst));
2700 1.1 christos return;
2701 1.1 christos }
2702 1.1 christos }
2703 1.1 christos else
2704 1.1 christos {
2705 1.6 christos /* Directly decode the alias opcode. */
2706 1.1 christos aarch64_inst temp;
2707 1.1 christos memset (&temp, '\0', sizeof (aarch64_inst));
2708 1.1 christos if (aarch64_opcode_decode (alias, inst->value, &temp, 1, errors) == 1)
2709 1.1 christos {
2710 1.1 christos DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
2711 1.1 christos memcpy (inst, &temp, sizeof (aarch64_inst));
2712 1.1 christos return;
2713 1.1 christos }
2714 1.1 christos }
2715 1.6 christos }
2716 1.6 christos }
2717 1.6 christos
2718 1.6 christos /* Some instructions (including all SVE ones) use the instruction class
2719 1.6 christos to describe how a qualifiers_list index is represented in the instruction
2720 1.6 christos encoding. If INST is such an instruction, decode the appropriate fields
2721 1.6 christos and fill in the operand qualifiers accordingly. Return true if no
2722 1.6 christos problems are found. */
2723 1.6 christos
2724 1.6 christos static bfd_boolean
2725 1.6 christos aarch64_decode_variant_using_iclass (aarch64_inst *inst)
2726 1.6 christos {
2727 1.6 christos int i, variant;
2728 1.6 christos
2729 1.6 christos variant = 0;
2730 1.6 christos switch (inst->opcode->iclass)
2731 1.6 christos {
2732 1.6 christos case sve_cpy:
2733 1.6 christos variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_14);
2734 1.6 christos break;
2735 1.6 christos
2736 1.6 christos case sve_index:
2737 1.6 christos i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2738 1.6 christos if ((i & 31) == 0)
2739 1.6 christos return FALSE;
2740 1.6 christos while ((i & 1) == 0)
2741 1.6 christos {
2742 1.6 christos i >>= 1;
2743 1.6 christos variant += 1;
2744 1.6 christos }
2745 1.6 christos break;
2746 1.6 christos
2747 1.6 christos case sve_limm:
2748 1.6 christos /* Pick the smallest applicable element size. */
2749 1.6 christos if ((inst->value & 0x20600) == 0x600)
2750 1.6 christos variant = 0;
2751 1.6 christos else if ((inst->value & 0x20400) == 0x400)
2752 1.6 christos variant = 1;
2753 1.6 christos else if ((inst->value & 0x20000) == 0)
2754 1.6 christos variant = 2;
2755 1.6 christos else
2756 1.6 christos variant = 3;
2757 1.6 christos break;
2758 1.6 christos
2759 1.6 christos case sve_misc:
2760 1.6 christos /* sve_misc instructions have only a single variant. */
2761 1.6 christos break;
2762 1.6 christos
2763 1.6 christos case sve_movprfx:
2764 1.6 christos variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_16);
2765 1.6 christos break;
2766 1.6 christos
2767 1.6 christos case sve_pred_zm:
2768 1.6 christos variant = extract_field (FLD_SVE_M_4, inst->value, 0);
2769 1.6 christos break;
2770 1.6 christos
2771 1.6 christos case sve_shift_pred:
2772 1.6 christos i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_8);
2773 1.6 christos sve_shift:
2774 1.6 christos if (i == 0)
2775 1.6 christos return FALSE;
2776 1.6 christos while (i != 1)
2777 1.6 christos {
2778 1.6 christos i >>= 1;
2779 1.6 christos variant += 1;
2780 1.6 christos }
2781 1.6 christos break;
2782 1.6 christos
2783 1.6 christos case sve_shift_unpred:
2784 1.6 christos i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
2785 1.6 christos goto sve_shift;
2786 1.6 christos
2787 1.6 christos case sve_size_bhs:
2788 1.6 christos variant = extract_field (FLD_size, inst->value, 0);
2789 1.6 christos if (variant >= 3)
2790 1.6 christos return FALSE;
2791 1.6 christos break;
2792 1.6 christos
2793 1.6 christos case sve_size_bhsd:
2794 1.6 christos variant = extract_field (FLD_size, inst->value, 0);
2795 1.6 christos break;
2796 1.6 christos
2797 1.6 christos case sve_size_hsd:
2798 1.6 christos i = extract_field (FLD_size, inst->value, 0);
2799 1.6 christos if (i < 1)
2800 1.6 christos return FALSE;
2801 1.6 christos variant = i - 1;
2802 1.6 christos break;
2803 1.6 christos
2804 1.6 christos case sve_size_sd:
2805 1.6 christos variant = extract_field (FLD_SVE_sz, inst->value, 0);
2806 1.6 christos break;
2807 1.6 christos
2808 1.6 christos default:
2809 1.6 christos /* No mapping between instruction class and qualifiers. */
2810 1.6 christos return TRUE;
2811 1.6 christos }
2812 1.6 christos
2813 1.6 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2814 1.1 christos inst->operands[i].qualifier = inst->opcode->qualifiers_list[variant][i];
2815 1.1 christos return TRUE;
2816 1.1 christos }
2817 1.1 christos /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2818 1.1 christos fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2819 1.1 christos return 1.
2820 1.1 christos
2821 1.1 christos If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2822 1.6 christos determined and used to disassemble CODE; this is done just before the
2823 1.1 christos return. */
2824 1.6 christos
2825 1.6 christos static bfd_boolean
2826 1.1 christos aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
2827 1.1 christos aarch64_inst *inst, int noaliases_p,
2828 1.1 christos aarch64_operand_error *errors)
2829 1.1 christos {
2830 1.1 christos int i;
2831 1.1 christos
2832 1.1 christos DEBUG_TRACE ("enter with %s", opcode->name);
2833 1.6 christos
2834 1.6 christos assert (opcode && inst);
2835 1.6 christos
2836 1.1 christos /* Clear inst. */
2837 1.1 christos memset (inst, '\0', sizeof (aarch64_inst));
2838 1.1 christos
2839 1.1 christos /* Check the base opcode. */
2840 1.1 christos if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
2841 1.1 christos {
2842 1.1 christos DEBUG_TRACE ("base opcode match FAIL");
2843 1.1 christos goto decode_fail;
2844 1.1 christos }
2845 1.1 christos
2846 1.1 christos inst->opcode = opcode;
2847 1.1 christos inst->value = code;
2848 1.1 christos
2849 1.1 christos /* Assign operand codes and indexes. */
2850 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2851 1.1 christos {
2852 1.1 christos if (opcode->operands[i] == AARCH64_OPND_NIL)
2853 1.1 christos break;
2854 1.1 christos inst->operands[i].type = opcode->operands[i];
2855 1.1 christos inst->operands[i].idx = i;
2856 1.1 christos }
2857 1.1 christos
2858 1.1 christos /* Call the opcode decoder indicated by flags. */
2859 1.1 christos if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
2860 1.1 christos {
2861 1.1 christos DEBUG_TRACE ("opcode flag-based decoder FAIL");
2862 1.6 christos goto decode_fail;
2863 1.6 christos }
2864 1.6 christos
2865 1.6 christos /* Possibly use the instruction class to determine the correct
2866 1.6 christos qualifier. */
2867 1.6 christos if (!aarch64_decode_variant_using_iclass (inst))
2868 1.6 christos {
2869 1.6 christos DEBUG_TRACE ("iclass-based decoder FAIL");
2870 1.1 christos goto decode_fail;
2871 1.1 christos }
2872 1.1 christos
2873 1.1 christos /* Call operand decoders. */
2874 1.1 christos for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2875 1.5 christos {
2876 1.1 christos const aarch64_operand *opnd;
2877 1.1 christos enum aarch64_opnd type;
2878 1.1 christos
2879 1.1 christos type = opcode->operands[i];
2880 1.1 christos if (type == AARCH64_OPND_NIL)
2881 1.6 christos break;
2882 1.6 christos opnd = &aarch64_operands[type];
2883 1.1 christos if (operand_has_extractor (opnd)
2884 1.1 christos && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst,
2885 1.1 christos errors)))
2886 1.1 christos {
2887 1.1 christos DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
2888 1.1 christos goto decode_fail;
2889 1.5 christos }
2890 1.5 christos }
2891 1.5 christos
2892 1.5 christos /* If the opcode has a verifier, then check it now. */
2893 1.5 christos if (opcode->verifier && ! opcode->verifier (opcode, code))
2894 1.5 christos {
2895 1.5 christos DEBUG_TRACE ("operand verifier FAIL");
2896 1.1 christos goto decode_fail;
2897 1.1 christos }
2898 1.1 christos
2899 1.1 christos /* Match the qualifiers. */
2900 1.1 christos if (aarch64_match_operands_constraint (inst, NULL) == 1)
2901 1.1 christos {
2902 1.1 christos /* Arriving here, the CODE has been determined as a valid instruction
2903 1.1 christos of OPCODE and *INST has been filled with information of this OPCODE
2904 1.1 christos instruction. Before the return, check if the instruction has any
2905 1.6 christos alias and should be disassembled in the form of its alias instead.
2906 1.1 christos If the answer is yes, *INST will be updated. */
2907 1.6 christos if (!noaliases_p)
2908 1.1 christos determine_disassembling_preference (inst, errors);
2909 1.1 christos DEBUG_TRACE ("SUCCESS");
2910 1.1 christos return TRUE;
2911 1.1 christos }
2912 1.1 christos else
2913 1.1 christos {
2914 1.1 christos DEBUG_TRACE ("constraint matching FAIL");
2915 1.6 christos }
2916 1.1 christos
2917 1.1 christos decode_fail:
2918 1.1 christos return FALSE;
2919 1.1 christos }
2920 1.1 christos
2921 1.1 christos /* This does some user-friendly fix-up to *INST. It is currently focus on
2923 1.1 christos the adjustment of qualifiers to help the printed instruction
2924 1.1 christos recognized/understood more easily. */
2925 1.1 christos
2926 1.1 christos static void
2927 1.1 christos user_friendly_fixup (aarch64_inst *inst)
2928 1.1 christos {
2929 1.1 christos switch (inst->opcode->iclass)
2930 1.1 christos {
2931 1.1 christos case testbranch:
2932 1.1 christos /* TBNZ Xn|Wn, #uimm6, label
2933 1.1 christos Test and Branch Not Zero: conditionally jumps to label if bit number
2934 1.1 christos uimm6 in register Xn is not zero. The bit number implies the width of
2935 1.1 christos the register, which may be written and should be disassembled as Wn if
2936 1.1 christos uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2937 1.1 christos */
2938 1.1 christos if (inst->operands[1].imm.value < 32)
2939 1.1 christos inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
2940 1.1 christos break;
2941 1.3 christos default: break;
2942 1.3 christos }
2943 1.3 christos }
2944 1.1 christos
2945 1.3 christos /* Decode INSN and fill in *INST the instruction information. An alias
2946 1.3 christos opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2947 1.6 christos success. */
2948 1.6 christos
2949 1.1 christos int
2950 1.1 christos aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
2951 1.1 christos bfd_boolean noaliases_p,
2952 1.1 christos aarch64_operand_error *errors)
2953 1.1 christos {
2954 1.1 christos const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
2955 1.1 christos
2956 1.1 christos #ifdef DEBUG_AARCH64
2957 1.1 christos if (debug_dump)
2958 1.1 christos {
2959 1.1 christos const aarch64_opcode *tmp = opcode;
2960 1.1 christos printf ("\n");
2961 1.1 christos DEBUG_TRACE ("opcode lookup:");
2962 1.1 christos while (tmp != NULL)
2963 1.1 christos {
2964 1.1 christos aarch64_verbose (" %s", tmp->name);
2965 1.1 christos tmp = aarch64_find_next_opcode (tmp);
2966 1.1 christos }
2967 1.1 christos }
2968 1.1 christos #endif /* DEBUG_AARCH64 */
2969 1.1 christos
2970 1.1 christos /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2971 1.1 christos distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2972 1.1 christos opcode field and value, apart from the difference that one of them has an
2973 1.1 christos extra field as part of the opcode, but such a field is used for operand
2974 1.1 christos encoding in other opcode(s) ('immh' in the case of the example). */
2975 1.6 christos while (opcode != NULL)
2976 1.1 christos {
2977 1.1 christos /* But only one opcode can be decoded successfully for, as the
2978 1.1 christos decoding routine will check the constraint carefully. */
2979 1.1 christos if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p, errors) == 1)
2980 1.1 christos return ERR_OK;
2981 1.1 christos opcode = aarch64_find_next_opcode (opcode);
2982 1.1 christos }
2983 1.1 christos
2984 1.1 christos return ERR_UND;
2985 1.1 christos }
2986 1.1 christos
2987 1.1 christos /* Print operands. */
2988 1.1 christos
2989 1.1 christos static void
2990 1.6 christos print_operands (bfd_vma pc, const aarch64_opcode *opcode,
2991 1.1 christos const aarch64_opnd_info *opnds, struct disassemble_info *info)
2992 1.1 christos {
2993 1.5 christos int i, pcrel_p, num_printed;
2994 1.1 christos char *notes = NULL;
2995 1.1 christos for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2996 1.1 christos {
2997 1.1 christos char str[128];
2998 1.1 christos /* We regard the opcode operand info more, however we also look into
2999 1.1 christos the inst->operands to support the disassembling of the optional
3000 1.1 christos operand.
3001 1.1 christos The two operand code should be the same in all cases, apart from
3002 1.1 christos when the operand can be optional. */
3003 1.1 christos if (opcode->operands[i] == AARCH64_OPND_NIL
3004 1.5 christos || opnds[i].type == AARCH64_OPND_NIL)
3005 1.6 christos break;
3006 1.1 christos
3007 1.1 christos /* Generate the operand string in STR. */
3008 1.1 christos aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
3009 1.1 christos &info->target, ¬es);
3010 1.1 christos
3011 1.1 christos /* Print the delimiter (taking account of omitted operand(s)). */
3012 1.1 christos if (str[0] != '\0')
3013 1.1 christos (*info->fprintf_func) (info->stream, "%s",
3014 1.1 christos num_printed++ == 0 ? "\t" : ", ");
3015 1.1 christos
3016 1.1 christos /* Print the operand. */
3017 1.1 christos if (pcrel_p)
3018 1.6 christos (*info->print_address_func) (info->target, info);
3019 1.6 christos else
3020 1.6 christos (*info->fprintf_func) (info->stream, "%s", str);
3021 1.6 christos }
3022 1.6 christos
3023 1.6 christos if (notes && !no_notes)
3024 1.6 christos (*info->fprintf_func) (info->stream, "\t; note: %s", notes);
3025 1.6 christos }
3026 1.6 christos
3027 1.6 christos /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
3028 1.6 christos
3029 1.6 christos static void
3030 1.6 christos remove_dot_suffix (char *name, const aarch64_inst *inst)
3031 1.6 christos {
3032 1.6 christos char *ptr;
3033 1.6 christos size_t len;
3034 1.6 christos
3035 1.6 christos ptr = strchr (inst->opcode->name, '.');
3036 1.6 christos assert (ptr && inst->cond);
3037 1.1 christos len = ptr - inst->opcode->name;
3038 1.1 christos assert (len < 8);
3039 1.1 christos strncpy (name, inst->opcode->name, len);
3040 1.1 christos name[len] = '\0';
3041 1.1 christos }
3042 1.1 christos
3043 1.1 christos /* Print the instruction mnemonic name. */
3044 1.1 christos
3045 1.1 christos static void
3046 1.1 christos print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
3047 1.1 christos {
3048 1.1 christos if (inst->opcode->flags & F_COND)
3049 1.6 christos {
3050 1.3 christos /* For instructions that are truly conditionally executed, e.g. b.cond,
3051 1.6 christos prepare the full mnemonic name with the corresponding condition
3052 1.1 christos suffix. */
3053 1.1 christos char name[8];
3054 1.1 christos
3055 1.1 christos remove_dot_suffix (name, inst);
3056 1.1 christos (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
3057 1.1 christos }
3058 1.6 christos else
3059 1.6 christos (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
3060 1.6 christos }
3061 1.6 christos
3062 1.6 christos /* Decide whether we need to print a comment after the operands of
3063 1.6 christos instruction INST. */
3064 1.6 christos
3065 1.6 christos static void
3066 1.6 christos print_comment (const aarch64_inst *inst, struct disassemble_info *info)
3067 1.6 christos {
3068 1.6 christos if (inst->opcode->flags & F_COND)
3069 1.6 christos {
3070 1.6 christos char name[8];
3071 1.6 christos unsigned int i, num_conds;
3072 1.6 christos
3073 1.6 christos remove_dot_suffix (name, inst);
3074 1.6 christos num_conds = ARRAY_SIZE (inst->cond->names);
3075 1.6 christos for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
3076 1.6 christos (*info->fprintf_func) (info->stream, "%s %s.%s",
3077 1.6 christos i == 1 ? " //" : ",",
3078 1.1 christos name, inst->cond->names[i]);
3079 1.1 christos }
3080 1.1 christos }
3081 1.1 christos
3082 1.1 christos /* Print the instruction according to *INST. */
3083 1.1 christos
3084 1.1 christos static void
3085 1.1 christos print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
3086 1.6 christos struct disassemble_info *info)
3087 1.1 christos {
3088 1.1 christos print_mnemonic_name (inst, info);
3089 1.1 christos print_operands (pc, inst->opcode, inst->operands, info);
3090 1.1 christos print_comment (inst, info);
3091 1.1 christos }
3092 1.1 christos
3093 1.1 christos /* Entry-point of the instruction disassembler and printer. */
3094 1.6 christos
3095 1.6 christos static void
3096 1.1 christos print_insn_aarch64_word (bfd_vma pc,
3097 1.1 christos uint32_t word,
3098 1.1 christos struct disassemble_info *info,
3099 1.1 christos aarch64_operand_error *errors)
3100 1.1 christos {
3101 1.1 christos static const char *err_msg[6] =
3102 1.1 christos {
3103 1.1 christos [ERR_OK] = "_",
3104 1.1 christos [-ERR_UND] = "undefined",
3105 1.1 christos [-ERR_UNP] = "unpredictable",
3106 1.1 christos [-ERR_NYI] = "NYI"
3107 1.1 christos };
3108 1.1 christos
3109 1.1 christos int ret;
3110 1.1 christos aarch64_inst inst;
3111 1.1 christos
3112 1.1 christos info->insn_info_valid = 1;
3113 1.1 christos info->branch_delay_insns = 0;
3114 1.1 christos info->data_size = 0;
3115 1.1 christos info->target = 0;
3116 1.1 christos info->target2 = 0;
3117 1.1 christos
3118 1.1 christos if (info->flags & INSN_HAS_RELOC)
3119 1.1 christos /* If the instruction has a reloc associated with it, then
3120 1.1 christos the offset field in the instruction will actually be the
3121 1.1 christos addend for the reloc. (If we are using REL type relocs).
3122 1.6 christos In such cases, we can ignore the pc when computing
3123 1.1 christos addresses, since the addend is not currently pc-relative. */
3124 1.1 christos pc = 0;
3125 1.1 christos
3126 1.3 christos ret = aarch64_decode_insn (word, &inst, no_aliases, errors);
3127 1.1 christos
3128 1.1 christos if (((word >> 21) & 0x3ff) == 1)
3129 1.1 christos {
3130 1.1 christos /* RESERVED for ALES. */
3131 1.1 christos assert (ret != ERR_OK);
3132 1.1 christos ret = ERR_NYI;
3133 1.1 christos }
3134 1.1 christos
3135 1.1 christos switch (ret)
3136 1.1 christos {
3137 1.1 christos case ERR_UND:
3138 1.1 christos case ERR_UNP:
3139 1.1 christos case ERR_NYI:
3140 1.1 christos /* Handle undefined instructions. */
3141 1.1 christos info->insn_type = dis_noninsn;
3142 1.1 christos (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
3143 1.1 christos word, err_msg[-ret]);
3144 1.1 christos break;
3145 1.1 christos case ERR_OK:
3146 1.1 christos user_friendly_fixup (&inst);
3147 1.1 christos print_aarch64_insn (pc, &inst, info);
3148 1.1 christos break;
3149 1.1 christos default:
3150 1.1 christos abort ();
3151 1.1 christos }
3152 1.1 christos }
3153 1.1 christos
3154 1.1 christos /* Disallow mapping symbols ($x, $d etc) from
3155 1.1 christos being displayed in symbol relative addresses. */
3156 1.1 christos
3157 1.1 christos bfd_boolean
3158 1.1 christos aarch64_symbol_is_valid (asymbol * sym,
3159 1.1 christos struct disassemble_info * info ATTRIBUTE_UNUSED)
3160 1.1 christos {
3161 1.1 christos const char * name;
3162 1.1 christos
3163 1.1 christos if (sym == NULL)
3164 1.1 christos return FALSE;
3165 1.1 christos
3166 1.1 christos name = bfd_asymbol_name (sym);
3167 1.1 christos
3168 1.1 christos return name
3169 1.1 christos && (name[0] != '$'
3170 1.1 christos || (name[1] != 'x' && name[1] != 'd')
3171 1.1 christos || (name[2] != '\0' && name[2] != '.'));
3172 1.1 christos }
3173 1.1 christos
3174 1.1 christos /* Print data bytes on INFO->STREAM. */
3175 1.6 christos
3176 1.6 christos static void
3177 1.1 christos print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3178 1.1 christos uint32_t word,
3179 1.1 christos struct disassemble_info *info,
3180 1.1 christos aarch64_operand_error *errors ATTRIBUTE_UNUSED)
3181 1.1 christos {
3182 1.1 christos switch (info->bytes_per_chunk)
3183 1.1 christos {
3184 1.1 christos case 1:
3185 1.1 christos info->fprintf_func (info->stream, ".byte\t0x%02x", word);
3186 1.1 christos break;
3187 1.1 christos case 2:
3188 1.1 christos info->fprintf_func (info->stream, ".short\t0x%04x", word);
3189 1.1 christos break;
3190 1.1 christos case 4:
3191 1.1 christos info->fprintf_func (info->stream, ".word\t0x%08x", word);
3192 1.1 christos break;
3193 1.1 christos default:
3194 1.1 christos abort ();
3195 1.1 christos }
3196 1.1 christos }
3197 1.1 christos
3198 1.1 christos /* Try to infer the code or data type from a symbol.
3199 1.1 christos Returns nonzero if *MAP_TYPE was set. */
3200 1.1 christos
3201 1.1 christos static int
3202 1.1 christos get_sym_code_type (struct disassemble_info *info, int n,
3203 1.1 christos enum map_type *map_type)
3204 1.1 christos {
3205 1.6 christos elf_symbol_type *es;
3206 1.6 christos unsigned int type;
3207 1.6 christos const char *name;
3208 1.6 christos
3209 1.1 christos /* If the symbol is in a different section, ignore it. */
3210 1.1 christos if (info->section != NULL && info->section != info->symtab[n]->section)
3211 1.1 christos return FALSE;
3212 1.1 christos
3213 1.1 christos es = *(elf_symbol_type **)(info->symtab + n);
3214 1.1 christos type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3215 1.1 christos
3216 1.1 christos /* If the symbol has function type then use that. */
3217 1.1 christos if (type == STT_FUNC)
3218 1.1 christos {
3219 1.1 christos *map_type = MAP_INSN;
3220 1.1 christos return TRUE;
3221 1.1 christos }
3222 1.1 christos
3223 1.1 christos /* Check for mapping symbols. */
3224 1.1 christos name = bfd_asymbol_name(info->symtab[n]);
3225 1.1 christos if (name[0] == '$'
3226 1.1 christos && (name[1] == 'x' || name[1] == 'd')
3227 1.1 christos && (name[2] == '\0' || name[2] == '.'))
3228 1.1 christos {
3229 1.1 christos *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
3230 1.1 christos return TRUE;
3231 1.1 christos }
3232 1.1 christos
3233 1.1 christos return FALSE;
3234 1.1 christos }
3235 1.1 christos
3236 1.1 christos /* Entry-point of the AArch64 disassembler. */
3237 1.1 christos
3238 1.1 christos int
3239 1.1 christos print_insn_aarch64 (bfd_vma pc,
3240 1.6 christos struct disassemble_info *info)
3241 1.6 christos {
3242 1.1 christos bfd_byte buffer[INSNLEN];
3243 1.1 christos int status;
3244 1.1 christos void (*printer) (bfd_vma, uint32_t, struct disassemble_info *,
3245 1.6 christos aarch64_operand_error *);
3246 1.1 christos bfd_boolean found = FALSE;
3247 1.1 christos unsigned int size = 4;
3248 1.1 christos unsigned long data;
3249 1.1 christos aarch64_operand_error errors;
3250 1.1 christos
3251 1.1 christos if (info->disassembler_options)
3252 1.1 christos {
3253 1.1 christos set_default_aarch64_dis_options (info);
3254 1.1 christos
3255 1.1 christos parse_aarch64_dis_options (info->disassembler_options);
3256 1.1 christos
3257 1.1 christos /* To avoid repeated parsing of these options, we remove them here. */
3258 1.1 christos info->disassembler_options = NULL;
3259 1.1 christos }
3260 1.1 christos
3261 1.1 christos /* Aarch64 instructions are always little-endian */
3262 1.1 christos info->endian_code = BFD_ENDIAN_LITTLE;
3263 1.1 christos
3264 1.1 christos /* First check the full symtab for a mapping symbol, even if there
3265 1.1 christos are no usable non-mapping symbols for this address. */
3266 1.1 christos if (info->symtab_size != 0
3267 1.1 christos && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3268 1.1 christos {
3269 1.1 christos enum map_type type = MAP_INSN;
3270 1.1 christos int last_sym = -1;
3271 1.1 christos bfd_vma addr;
3272 1.1 christos int n;
3273 1.1 christos
3274 1.1 christos if (pc <= last_mapping_addr)
3275 1.1 christos last_mapping_sym = -1;
3276 1.1 christos
3277 1.1 christos /* Start scanning at the start of the function, or wherever
3278 1.1 christos we finished last time. */
3279 1.1 christos n = info->symtab_pos + 1;
3280 1.1 christos if (n < last_mapping_sym)
3281 1.1 christos n = last_mapping_sym;
3282 1.1 christos
3283 1.1 christos /* Scan up to the location being disassembled. */
3284 1.1 christos for (; n < info->symtab_size; n++)
3285 1.6 christos {
3286 1.1 christos addr = bfd_asymbol_value (info->symtab[n]);
3287 1.1 christos if (addr > pc)
3288 1.1 christos break;
3289 1.1 christos if (get_sym_code_type (info, n, &type))
3290 1.1 christos {
3291 1.1 christos last_sym = n;
3292 1.1 christos found = TRUE;
3293 1.1 christos }
3294 1.1 christos }
3295 1.1 christos
3296 1.1 christos if (!found)
3297 1.1 christos {
3298 1.1 christos n = info->symtab_pos;
3299 1.1 christos if (n < last_mapping_sym)
3300 1.1 christos n = last_mapping_sym;
3301 1.1 christos
3302 1.1 christos /* No mapping symbol found at this address. Look backwards
3303 1.1 christos for a preceeding one. */
3304 1.1 christos for (; n >= 0; n--)
3305 1.1 christos {
3306 1.1 christos if (get_sym_code_type (info, n, &type))
3307 1.1 christos {
3308 1.1 christos last_sym = n;
3309 1.1 christos found = TRUE;
3310 1.1 christos break;
3311 1.1 christos }
3312 1.1 christos }
3313 1.1 christos }
3314 1.1 christos
3315 1.1 christos last_mapping_sym = last_sym;
3316 1.1 christos last_type = type;
3317 1.1 christos
3318 1.1 christos /* Look a little bit ahead to see if we should print out
3319 1.1 christos less than four bytes of data. If there's a symbol,
3320 1.1 christos mapping or otherwise, after two bytes then don't
3321 1.1 christos print more. */
3322 1.1 christos if (last_type == MAP_DATA)
3323 1.1 christos {
3324 1.1 christos size = 4 - (pc & 3);
3325 1.1 christos for (n = last_sym + 1; n < info->symtab_size; n++)
3326 1.1 christos {
3327 1.1 christos addr = bfd_asymbol_value (info->symtab[n]);
3328 1.1 christos if (addr > pc)
3329 1.1 christos {
3330 1.1 christos if (addr - pc < size)
3331 1.1 christos size = addr - pc;
3332 1.1 christos break;
3333 1.1 christos }
3334 1.1 christos }
3335 1.1 christos /* If the next symbol is after three bytes, we need to
3336 1.1 christos print only part of the data, so that we can use either
3337 1.1 christos .byte or .short. */
3338 1.1 christos if (size == 3)
3339 1.1 christos size = (pc & 1) ? 1 : 2;
3340 1.1 christos }
3341 1.1 christos }
3342 1.1 christos
3343 1.1 christos if (last_type == MAP_DATA)
3344 1.1 christos {
3345 1.1 christos /* size was set above. */
3346 1.1 christos info->bytes_per_chunk = size;
3347 1.1 christos info->display_endian = info->endian;
3348 1.1 christos printer = print_insn_data;
3349 1.1 christos }
3350 1.1 christos else
3351 1.1 christos {
3352 1.1 christos info->bytes_per_chunk = size = INSNLEN;
3353 1.1 christos info->display_endian = info->endian_code;
3354 1.1 christos printer = print_insn_aarch64_word;
3355 1.1 christos }
3356 1.1 christos
3357 1.1 christos status = (*info->read_memory_func) (pc, buffer, size, info);
3358 1.1 christos if (status != 0)
3359 1.1 christos {
3360 1.1 christos (*info->memory_error_func) (status, pc, info);
3361 1.1 christos return -1;
3362 1.1 christos }
3363 1.6 christos
3364 1.1 christos data = bfd_get_bits (buffer, size * 8,
3365 1.1 christos info->display_endian == BFD_ENDIAN_BIG);
3366 1.1 christos
3367 1.1 christos (*printer) (pc, data, info, &errors);
3368 1.1 christos
3369 1.1 christos return size;
3370 1.1 christos }
3371 1.1 christos
3372 1.1 christos void
3374 1.1 christos print_aarch64_disassembler_options (FILE *stream)
3375 1.1 christos {
3376 1.1 christos fprintf (stream, _("\n\
3377 1.1 christos The following AARCH64 specific disassembler options are supported for use\n\
3378 1.1 christos with the -M switch (multiple options should be separated by commas):\n"));
3379 1.1 christos
3380 1.1 christos fprintf (stream, _("\n\
3381 1.6 christos no-aliases Don't print instruction aliases.\n"));
3382 1.6 christos
3383 1.6 christos fprintf (stream, _("\n\
3384 1.6 christos aliases Do print instruction aliases.\n"));
3385 1.6 christos
3386 1.6 christos fprintf (stream, _("\n\
3387 1.1 christos no-notes Don't print instruction notes.\n"));
3388 1.1 christos
3389 1.1 christos fprintf (stream, _("\n\
3390 1.1 christos notes Do print instruction notes.\n"));
3391 1.1 christos
3392 1.1 christos #ifdef DEBUG_AARCH64
3393 1.1 christos fprintf (stream, _("\n\
3394 debug_dump Temp switch for debug trace.\n"));
3395 #endif /* DEBUG_AARCH64 */
3396
3397 fprintf (stream, _("\n"));
3398 }
3399