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