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