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