Home | History | Annotate | Line # | Download | only in opcodes
      1   1.1  christos /* aarch64-dis.c -- AArch64 disassembler.
      2  1.10  christos    Copyright (C) 2009-2025 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by ARM Ltd.
      4   1.1  christos 
      5   1.1  christos    This file is part of the GNU opcodes library.
      6   1.1  christos 
      7   1.1  christos    This library is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     10   1.1  christos    any later version.
     11   1.1  christos 
     12   1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT
     13   1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14   1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15   1.1  christos    License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with this program; see the file COPYING3. If not,
     19   1.1  christos    see <http://www.gnu.org/licenses/>.  */
     20   1.1  christos 
     21   1.1  christos #include "sysdep.h"
     22   1.8  christos #include <stdint.h>
     23   1.6  christos #include "disassemble.h"
     24   1.1  christos #include "libiberty.h"
     25   1.1  christos #include "opintl.h"
     26   1.1  christos #include "aarch64-dis.h"
     27   1.1  christos #include "elf-bfd.h"
     28   1.9  christos #include "safe-ctype.h"
     29   1.9  christos #include "obstack.h"
     30   1.9  christos 
     31   1.9  christos #define obstack_chunk_alloc xmalloc
     32   1.9  christos #define obstack_chunk_free free
     33   1.1  christos 
     34   1.1  christos #define INSNLEN 4
     35   1.1  christos 
     36   1.9  christos /* This character is used to encode style information within the output
     37   1.9  christos    buffers.  See get_style_text and print_operands for more details.  */
     38   1.9  christos #define STYLE_MARKER_CHAR '\002'
     39   1.9  christos 
     40   1.1  christos /* Cached mapping symbol state.  */
     41   1.1  christos enum map_type
     42   1.1  christos {
     43   1.1  christos   MAP_INSN,
     44   1.1  christos   MAP_DATA
     45   1.1  christos };
     46   1.1  christos 
     47   1.8  christos static aarch64_feature_set arch_variant; /* See select_aarch64_variant.  */
     48   1.1  christos static enum map_type last_type;
     49   1.1  christos static int last_mapping_sym = -1;
     50   1.7  christos static bfd_vma last_stop_offset = 0;
     51   1.1  christos static bfd_vma last_mapping_addr = 0;
     52   1.1  christos 
     53   1.1  christos /* Other options */
     54   1.1  christos static int no_aliases = 0;	/* If set disassemble as most general inst.  */
     55   1.6  christos static int no_notes = 1;	/* If set do not print disassemble notes in the
     57   1.1  christos 				  output as comments.  */
     58   1.7  christos 
     59   1.7  christos /* Currently active instruction sequence.  */
     60   1.7  christos static aarch64_instr_sequence insn_sequence;
     61   1.1  christos 
     62   1.1  christos static void
     63   1.1  christos set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
     64   1.1  christos {
     65   1.1  christos }
     66   1.1  christos 
     67   1.1  christos static void
     68   1.1  christos parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
     69   1.1  christos {
     70   1.8  christos   /* Try to match options that are simple flags */
     71   1.1  christos   if (startswith (option, "no-aliases"))
     72   1.1  christos     {
     73   1.1  christos       no_aliases = 1;
     74   1.1  christos       return;
     75   1.1  christos     }
     76   1.8  christos 
     77   1.1  christos   if (startswith (option, "aliases"))
     78   1.1  christos     {
     79   1.1  christos       no_aliases = 0;
     80   1.1  christos       return;
     81   1.1  christos     }
     82   1.8  christos 
     83   1.6  christos   if (startswith (option, "no-notes"))
     84   1.6  christos     {
     85   1.6  christos       no_notes = 1;
     86   1.6  christos       return;
     87   1.6  christos     }
     88   1.8  christos 
     89   1.6  christos   if (startswith (option, "notes"))
     90   1.6  christos     {
     91   1.6  christos       no_notes = 0;
     92   1.6  christos       return;
     93   1.6  christos     }
     94   1.1  christos 
     95   1.8  christos #ifdef DEBUG_AARCH64
     96   1.1  christos   if (startswith (option, "debug_dump"))
     97   1.1  christos     {
     98   1.1  christos       debug_dump = 1;
     99   1.1  christos       return;
    100   1.1  christos     }
    101   1.1  christos #endif /* DEBUG_AARCH64 */
    102   1.1  christos 
    103   1.6  christos   /* Invalid option.  */
    104   1.1  christos   opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
    105   1.1  christos }
    106   1.1  christos 
    107   1.1  christos static void
    108   1.1  christos parse_aarch64_dis_options (const char *options)
    109   1.1  christos {
    110   1.1  christos   const char *option_end;
    111   1.1  christos 
    112   1.1  christos   if (options == NULL)
    113   1.1  christos     return;
    114   1.1  christos 
    115   1.1  christos   while (*options != '\0')
    116   1.1  christos     {
    117   1.1  christos       /* Skip empty options.  */
    118   1.1  christos       if (*options == ',')
    119   1.1  christos 	{
    120   1.1  christos 	  options++;
    121   1.1  christos 	  continue;
    122   1.1  christos 	}
    123   1.1  christos 
    124   1.1  christos       /* We know that *options is neither NUL or a comma.  */
    125   1.1  christos       option_end = options + 1;
    126   1.1  christos       while (*option_end != ',' && *option_end != '\0')
    127   1.1  christos 	option_end++;
    128   1.1  christos 
    129   1.1  christos       parse_aarch64_dis_option (options, option_end - options);
    130   1.1  christos 
    131   1.1  christos       /* Go on to the next one.  If option_end points to a comma, it
    132   1.1  christos 	 will be skipped above.  */
    133   1.1  christos       options = option_end;
    134   1.1  christos     }
    135   1.1  christos }
    136   1.1  christos 
    137   1.1  christos /* Functions doing the instruction disassembling.  */
    139   1.1  christos 
    140   1.1  christos /* The unnamed arguments consist of the number of fields and information about
    141   1.1  christos    these fields where the VALUE will be extracted from CODE and returned.
    142   1.1  christos    MASK can be zero or the base mask of the opcode.
    143   1.1  christos 
    144   1.1  christos    N.B. the fields are required to be in such an order than the most signficant
    145   1.3  christos    field for VALUE comes the first, e.g. the <index> in
    146   1.1  christos     SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    147   1.1  christos    is encoded in H:L:M in some cases, the fields H:L:M should be passed in
    148   1.6  christos    the order of H, L, M.  */
    149   1.1  christos 
    150   1.1  christos aarch64_insn
    151   1.1  christos extract_fields (aarch64_insn code, aarch64_insn mask, ...)
    152   1.1  christos {
    153   1.1  christos   uint32_t num;
    154   1.1  christos   const aarch64_field *field;
    155   1.3  christos   enum aarch64_field_kind kind;
    156   1.1  christos   va_list va;
    157   1.1  christos 
    158   1.1  christos   va_start (va, mask);
    159   1.1  christos   num = va_arg (va, uint32_t);
    160   1.1  christos   assert (num <= 5);
    161   1.1  christos   aarch64_insn value = 0x0;
    162   1.1  christos   while (num--)
    163   1.1  christos     {
    164   1.1  christos       kind = va_arg (va, enum aarch64_field_kind);
    165   1.1  christos       field = &fields[kind];
    166   1.1  christos       value <<= field->width;
    167   1.8  christos       value |= extract_field (kind, code, mask);
    168   1.1  christos     }
    169   1.1  christos   va_end (va);
    170   1.1  christos   return value;
    171   1.9  christos }
    172   1.9  christos 
    173   1.6  christos /* Extract the value of all fields in SELF->fields after START from
    174   1.6  christos    instruction CODE.  The least significant bit comes from the final field.  */
    175   1.9  christos 
    176   1.9  christos static aarch64_insn
    177   1.6  christos extract_all_fields_after (const aarch64_operand *self, unsigned int start,
    178   1.6  christos 			  aarch64_insn code)
    179   1.6  christos {
    180   1.6  christos   aarch64_insn value;
    181   1.6  christos   unsigned int i;
    182   1.6  christos   enum aarch64_field_kind kind;
    183   1.9  christos 
    184   1.9  christos   value = 0;
    185   1.6  christos   for (i = start;
    186   1.6  christos        i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i)
    187   1.6  christos     {
    188   1.6  christos       kind = self->fields[i];
    189   1.6  christos       value <<= fields[kind].width;
    190   1.6  christos       value |= extract_field (kind, code, 0);
    191   1.6  christos     }
    192   1.6  christos   return value;
    193   1.9  christos }
    194   1.9  christos 
    195   1.9  christos /* Extract the value of all fields in SELF->fields from instruction CODE.
    196   1.9  christos    The least significant bit comes from the final field.  */
    197   1.9  christos 
    198   1.9  christos static aarch64_insn
    199   1.9  christos extract_all_fields (const aarch64_operand *self, aarch64_insn code)
    200   1.9  christos {
    201   1.9  christos   return extract_all_fields_after (self, 0, code);
    202   1.1  christos }
    203   1.7  christos 
    204   1.1  christos /* Sign-extend bit I of VALUE.  */
    205   1.1  christos static inline uint64_t
    206   1.7  christos sign_extend (aarch64_insn value, unsigned i)
    207   1.3  christos {
    208   1.1  christos   uint64_t ret, sign;
    209   1.7  christos 
    210   1.7  christos   assert (i < 32);
    211   1.7  christos   ret = value;
    212   1.1  christos   sign = (uint64_t) 1 << i;
    213   1.1  christos   return ((ret & (sign + sign - 1)) ^ sign) - sign;
    214   1.1  christos }
    215   1.1  christos 
    216   1.1  christos /* N.B. the following inline helpfer functions create a dependency on the
    217   1.1  christos    order of operand qualifier enumerators.  */
    218   1.1  christos 
    219   1.1  christos /* Given VALUE, return qualifier for a general purpose register.  */
    220   1.1  christos static inline enum aarch64_opnd_qualifier
    221   1.1  christos get_greg_qualifier_from_value (aarch64_insn value)
    222  1.10  christos {
    223  1.10  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
    224  1.10  christos   if (value <= 0x1
    225  1.10  christos       && aarch64_get_qualifier_standard_value (qualifier) == value)
    226   1.1  christos     return qualifier;
    227   1.1  christos   return AARCH64_OPND_QLF_ERR;
    228   1.3  christos }
    229   1.3  christos 
    230   1.3  christos /* Given VALUE, return qualifier for a vector register.  This does not support
    231   1.1  christos    decoding instructions that accept the 2H vector type.  */
    232   1.1  christos 
    233   1.1  christos static inline enum aarch64_opnd_qualifier
    234   1.1  christos get_vreg_qualifier_from_value (aarch64_insn value)
    235   1.3  christos {
    236   1.3  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
    237   1.3  christos 
    238   1.3  christos   /* Instructions using vector type 2H should not call this function.  Skip over
    239   1.3  christos      the 2H qualifier.  */
    240   1.3  christos   if (qualifier >= AARCH64_OPND_QLF_V_2H)
    241  1.10  christos     qualifier += 1;
    242  1.10  christos 
    243  1.10  christos   if (value <= 0x8
    244  1.10  christos       && aarch64_get_qualifier_standard_value (qualifier) == value)
    245   1.1  christos     return qualifier;
    246   1.1  christos   return AARCH64_OPND_QLF_ERR;
    247   1.1  christos }
    248   1.1  christos 
    249   1.1  christos /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register.  */
    250   1.1  christos static inline enum aarch64_opnd_qualifier
    251   1.1  christos get_sreg_qualifier_from_value (aarch64_insn value)
    252   1.3  christos {
    253  1.10  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
    254  1.10  christos 
    255  1.10  christos   if (value <= 0x4
    256  1.10  christos       && aarch64_get_qualifier_standard_value (qualifier) == value)
    257   1.1  christos     return qualifier;
    258   1.1  christos   return AARCH64_OPND_QLF_ERR;
    259   1.1  christos }
    260   1.1  christos 
    261   1.1  christos /* Given the instruction in *INST which is probably half way through the
    262   1.1  christos    decoding and our caller wants to know the expected qualifier for operand
    263   1.1  christos    I.  Return such a qualifier if we can establish it; otherwise return
    264   1.1  christos    AARCH64_OPND_QLF_NIL.  */
    265   1.1  christos 
    266   1.1  christos static aarch64_opnd_qualifier_t
    267   1.1  christos get_expected_qualifier (const aarch64_inst *inst, int i)
    268   1.1  christos {
    269  1.10  christos   aarch64_opnd_qualifier_seq_t qualifiers;
    270  1.10  christos   /* Should not be called if the qualifier is known.  */
    271  1.10  christos   if (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL)
    272  1.10  christos     {
    273  1.10  christos       int invalid_count;
    274  1.10  christos       if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
    275  1.10  christos 				   i, qualifiers, &invalid_count))
    276  1.10  christos 	return qualifiers[i];
    277  1.10  christos       else
    278   1.1  christos 	return AARCH64_OPND_QLF_NIL;
    279  1.10  christos     }
    280   1.1  christos   else
    281   1.1  christos     return AARCH64_OPND_QLF_ERR;
    282   1.1  christos }
    283   1.1  christos 
    284   1.8  christos /* Operand extractors.  */
    285   1.8  christos 
    286   1.8  christos bool
    287   1.8  christos aarch64_ext_none (const aarch64_operand *self ATTRIBUTE_UNUSED,
    288   1.8  christos 		  aarch64_opnd_info *info ATTRIBUTE_UNUSED,
    289   1.8  christos 		  const aarch64_insn code ATTRIBUTE_UNUSED,
    290   1.8  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED,
    291   1.8  christos 		  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    292   1.8  christos {
    293   1.8  christos   return true;
    294   1.8  christos }
    295   1.1  christos 
    296   1.1  christos bool
    297   1.6  christos aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
    298   1.6  christos 		   const aarch64_insn code,
    299   1.1  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED,
    300   1.9  christos 		   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    301   1.9  christos {
    302   1.8  christos   info->reg.regno = (extract_field (self->fields[0], code, 0)
    303   1.1  christos 		     + get_operand_specific_data (self));
    304   1.1  christos   return true;
    305   1.8  christos }
    306   1.3  christos 
    307   1.3  christos bool
    308   1.6  christos aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
    309   1.6  christos 		   const aarch64_insn code ATTRIBUTE_UNUSED,
    310   1.3  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED,
    311   1.3  christos 		   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    312   1.9  christos {
    313   1.9  christos   assert (info->idx == 1
    314   1.9  christos 	  || info->idx == 2
    315   1.9  christos 	  || info->idx == 3
    316   1.9  christos 	  || info->idx == 5);
    317   1.9  christos 
    318   1.9  christos   unsigned prev_regno = inst->operands[info->idx - 1].reg.regno;
    319   1.8  christos   info->reg.regno = (prev_regno == 0x1f) ? 0x1f
    320   1.3  christos 					 : prev_regno + 1;
    321   1.3  christos   return true;
    322   1.1  christos }
    323   1.8  christos 
    324   1.1  christos /* e.g. IC <ic_op>{, <Xt>}.  */
    325   1.1  christos bool
    326   1.6  christos aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
    327   1.6  christos 			  const aarch64_insn code,
    328   1.1  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED,
    329   1.1  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    330   1.1  christos {
    331   1.1  christos   info->reg.regno = extract_field (self->fields[0], code, 0);
    332   1.1  christos   assert (info->idx == 1
    333   1.1  christos 	  && (aarch64_get_operand_class (inst->operands[0].type)
    334   1.1  christos 	      == AARCH64_OPND_CLASS_SYSTEM));
    335   1.1  christos   /* This will make the constraint checking happy and more importantly will
    336   1.3  christos      help the disassembler determine whether this operand is optional or
    337   1.1  christos      not.  */
    338   1.8  christos   info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
    339   1.1  christos 
    340   1.1  christos   return true;
    341   1.1  christos }
    342   1.8  christos 
    343   1.1  christos /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
    344   1.1  christos bool
    345   1.6  christos aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
    346   1.6  christos 		     const aarch64_insn code,
    347   1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED,
    348   1.1  christos 		     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    349   1.1  christos {
    350   1.1  christos   /* regno */
    351   1.1  christos   info->reglane.regno = extract_field (self->fields[0], code,
    352   1.3  christos 				       inst->opcode->mask);
    353   1.1  christos 
    354   1.1  christos   /* Index and/or type.  */
    355   1.1  christos   if (inst->opcode->iclass == asisdone
    356   1.1  christos     || inst->opcode->iclass == asimdins)
    357   1.1  christos     {
    358   1.1  christos       if (info->type == AARCH64_OPND_En
    359   1.1  christos 	  && inst->opcode->operands[0] == AARCH64_OPND_Ed)
    360   1.1  christos 	{
    361   1.1  christos 	  unsigned shift;
    362   1.9  christos 	  /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>].  */
    363   1.1  christos 	  assert (info->idx == 1);	/* Vn */
    364   1.1  christos 	  aarch64_insn value = extract_field (FLD_imm4_11, code, 0);
    365  1.10  christos 	  /* Depend on AARCH64_OPND_Ed to determine the qualifier.  */
    366  1.10  christos 	  info->qualifier = get_expected_qualifier (inst, info->idx);
    367   1.1  christos 	  if (info->qualifier == AARCH64_OPND_QLF_ERR)
    368   1.1  christos 	    return 0;
    369   1.1  christos 	  shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
    370   1.1  christos 	  info->reglane.index = value >> shift;
    371   1.1  christos 	}
    372   1.1  christos       else
    373   1.1  christos 	{
    374   1.1  christos 	  /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
    375   1.1  christos 	     imm5<3:0>	<V>
    376   1.1  christos 	     0000	RESERVED
    377   1.1  christos 	     xxx1	B
    378   1.1  christos 	     xx10	H
    379   1.1  christos 	     x100	S
    380   1.1  christos 	     1000	D  */
    381   1.1  christos 	  int pos = -1;
    382   1.1  christos 	  aarch64_insn value = extract_field (FLD_imm5, code, 0);
    383   1.1  christos 	  while (++pos <= 3 && (value & 0x1) == 0)
    384   1.8  christos 	    value >>= 1;
    385   1.1  christos 	  if (pos > 3)
    386  1.10  christos 	    return false;
    387  1.10  christos 	  info->qualifier = get_sreg_qualifier_from_value (pos);
    388   1.1  christos 	  if (info->qualifier == AARCH64_OPND_QLF_ERR)
    389   1.1  christos 	    return 0;
    390   1.1  christos 	  info->reglane.index = (unsigned) (value >> 1);
    391   1.6  christos 	}
    392   1.6  christos     }
    393   1.6  christos   else if (inst->opcode->iclass == dotproduct)
    394   1.6  christos     {
    395  1.10  christos       /* Need information in other operand(s) to help decoding.  */
    396  1.10  christos       info->qualifier = get_expected_qualifier (inst, info->idx);
    397   1.6  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
    398   1.6  christos 	return 0;
    399   1.6  christos       switch (info->qualifier)
    400   1.7  christos 	{
    401   1.6  christos 	case AARCH64_OPND_QLF_S_4B:
    402   1.6  christos 	case AARCH64_OPND_QLF_S_2H:
    403   1.6  christos 	  /* L:H */
    404   1.6  christos 	  info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
    405  1.10  christos 	  info->reglane.regno &= 0x1f;
    406  1.10  christos 	  break;
    407  1.10  christos 	case AARCH64_OPND_QLF_S_2B:
    408  1.10  christos 	  /* h:l:m */
    409  1.10  christos 	  info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
    410  1.10  christos 						FLD_M);
    411   1.6  christos 	  info->reglane.regno &= 0xf;
    412   1.8  christos 	  break;
    413   1.6  christos 	default:
    414   1.6  christos 	  return false;
    415   1.6  christos 	}
    416   1.6  christos     }
    417   1.6  christos   else if (inst->opcode->iclass == cryptosm3)
    418   1.6  christos     {
    419   1.6  christos       /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>].  */
    420   1.1  christos       info->reglane.index = extract_field (FLD_SM3_imm2, code, 0);
    421   1.1  christos     }
    422   1.3  christos   else
    423   1.1  christos     {
    424   1.1  christos       /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    425   1.1  christos          or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
    426   1.1  christos 
    427  1.10  christos       /* Need information in other operand(s) to help decoding.  */
    428  1.10  christos       info->qualifier = get_expected_qualifier (inst, info->idx);
    429   1.1  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
    430   1.1  christos 	return 0;
    431  1.10  christos       switch (info->qualifier)
    432  1.10  christos 	{
    433  1.10  christos 	case AARCH64_OPND_QLF_S_B:
    434  1.10  christos 	  /* H:imm3 */
    435  1.10  christos 	  info->reglane.index = extract_fields (code, 0, 2, FLD_H,
    436  1.10  christos 						FLD_imm3_19);
    437  1.10  christos 	  info->reglane.regno &= 0x7;
    438   1.1  christos 	  break;
    439  1.10  christos 
    440   1.6  christos 	case AARCH64_OPND_QLF_S_H:
    441   1.6  christos 	case AARCH64_OPND_QLF_S_2B:
    442   1.6  christos 	  if (info->type == AARCH64_OPND_Em16)
    443   1.6  christos 	    {
    444   1.6  christos 	      /* h:l:m */
    445   1.6  christos 	      info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
    446   1.6  christos 						    FLD_M);
    447   1.6  christos 	      info->reglane.regno &= 0xf;
    448   1.6  christos 	    }
    449   1.6  christos 	  else
    450   1.6  christos 	    {
    451   1.6  christos 	      /* h:l */
    452   1.1  christos 	      info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
    453   1.1  christos 	    }
    454  1.10  christos 	  break;
    455   1.1  christos 	case AARCH64_OPND_QLF_S_S:
    456   1.1  christos 	case AARCH64_OPND_QLF_S_4B:
    457   1.1  christos 	  /* h:l */
    458   1.1  christos 	  info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
    459   1.1  christos 	  break;
    460   1.1  christos 	case AARCH64_OPND_QLF_S_D:
    461   1.1  christos 	  /* H */
    462   1.1  christos 	  info->reglane.index = extract_field (FLD_H, code, 0);
    463   1.8  christos 	  break;
    464   1.6  christos 	default:
    465   1.6  christos 	  return false;
    466   1.6  christos 	}
    467   1.6  christos 
    468   1.6  christos       if (inst->opcode->op == OP_FCMLA_ELEM
    469   1.6  christos 	  && info->qualifier != AARCH64_OPND_QLF_S_H)
    470   1.6  christos 	{
    471   1.8  christos 	  /* Complex operand takes two elements.  */
    472   1.6  christos 	  if (info->reglane.index & 1)
    473   1.1  christos 	    return false;
    474   1.1  christos 	  info->reglane.index /= 2;
    475   1.1  christos 	}
    476   1.8  christos     }
    477   1.1  christos 
    478   1.1  christos   return true;
    479   1.8  christos }
    480   1.1  christos 
    481   1.1  christos bool
    482   1.6  christos aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
    483   1.6  christos 		     const aarch64_insn code,
    484   1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED,
    485   1.1  christos 		     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    486   1.1  christos {
    487   1.1  christos   /* R */
    488   1.1  christos   info->reglist.first_regno = extract_field (self->fields[0], code, 0);
    489   1.9  christos   /* len */
    490   1.8  christos   info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
    491   1.1  christos   info->reglist.stride = 1;
    492   1.1  christos   return true;
    493   1.1  christos }
    494   1.8  christos 
    495   1.1  christos /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions.  */
    496   1.1  christos bool
    497   1.6  christos aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
    498   1.6  christos 			  aarch64_opnd_info *info, const aarch64_insn code,
    499   1.1  christos 			  const aarch64_inst *inst,
    500   1.1  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    501   1.1  christos {
    502   1.1  christos   aarch64_insn value;
    503   1.1  christos   /* Number of elements in each structure to be loaded/stored.  */
    504   1.1  christos   unsigned expected_num = get_opcode_dependent_value (inst->opcode);
    505   1.1  christos 
    506   1.1  christos   struct
    507   1.1  christos     {
    508   1.1  christos       unsigned is_reserved;
    509   1.1  christos       unsigned num_regs;
    510   1.1  christos       unsigned num_elements;
    511   1.1  christos     } data [] =
    512   1.1  christos   {   {0, 4, 4},
    513   1.1  christos       {1, 4, 4},
    514   1.1  christos       {0, 4, 1},
    515   1.1  christos       {0, 4, 2},
    516   1.1  christos       {0, 3, 3},
    517   1.1  christos       {1, 3, 3},
    518   1.1  christos       {0, 3, 1},
    519   1.1  christos       {0, 1, 1},
    520   1.1  christos       {0, 2, 2},
    521   1.1  christos       {1, 2, 2},
    522   1.1  christos       {0, 2, 1},
    523   1.1  christos   };
    524   1.1  christos 
    525   1.1  christos   /* Rt */
    526   1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    527   1.6  christos   /* opcode */
    528   1.6  christos   value = extract_field (FLD_opcode, code, 0);
    529   1.8  christos   /* PR 21595: Check for a bogus value.  */
    530   1.1  christos   if (value >= ARRAY_SIZE (data))
    531   1.8  christos     return false;
    532   1.1  christos   if (expected_num != data[value].num_elements || data[value].is_reserved)
    533   1.9  christos     return false;
    534   1.1  christos   info->reglist.num_regs = data[value].num_regs;
    535   1.8  christos   info->reglist.stride = 1;
    536   1.1  christos 
    537   1.1  christos   return true;
    538   1.1  christos }
    539   1.1  christos 
    540   1.8  christos /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
    541   1.1  christos    lanes instructions.  */
    542   1.1  christos bool
    543   1.6  christos aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
    544   1.6  christos 			    aarch64_opnd_info *info, const aarch64_insn code,
    545   1.1  christos 			    const aarch64_inst *inst,
    546   1.1  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    547   1.1  christos {
    548   1.1  christos   aarch64_insn value;
    549   1.1  christos 
    550   1.1  christos   /* Rt */
    551   1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    552   1.1  christos   /* S */
    553   1.1  christos   value = extract_field (FLD_S, code, 0);
    554   1.1  christos 
    555   1.1  christos   /* Number of registers is equal to the number of elements in
    556   1.1  christos      each structure to be loaded/stored.  */
    557   1.1  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
    558   1.1  christos   assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
    559   1.1  christos 
    560   1.1  christos   /* Except when it is LD1R.  */
    561   1.1  christos   if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
    562   1.9  christos     info->reglist.num_regs = 2;
    563   1.8  christos 
    564   1.1  christos   info->reglist.stride = 1;
    565   1.1  christos   return true;
    566  1.10  christos }
    567  1.10  christos 
    568  1.10  christos /* Decode AdvSIMD vector register list for AdvSIMD lut instructions.
    569  1.10  christos    The number of of registers in the list is determined by the opcode
    570  1.10  christos    flag.  */
    571  1.10  christos bool
    572  1.10  christos aarch64_ext_lut_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
    573  1.10  christos 		     const aarch64_insn code,
    574  1.10  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED,
    575  1.10  christos 		     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    576  1.10  christos {
    577  1.10  christos   info->reglist.first_regno = extract_field (self->fields[0], code, 0);
    578  1.10  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
    579  1.10  christos   info->reglist.stride = 1;
    580  1.10  christos   return true;
    581   1.1  christos }
    582   1.1  christos 
    583   1.8  christos /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
    584   1.1  christos    load/store single element instructions.  */
    585   1.1  christos bool
    586   1.6  christos aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
    587   1.6  christos 			   aarch64_opnd_info *info, const aarch64_insn code,
    588   1.1  christos 			   const aarch64_inst *inst ATTRIBUTE_UNUSED,
    589   1.1  christos 			   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    590   1.1  christos {
    591   1.1  christos   aarch64_field field = {0, 0};
    592   1.1  christos   aarch64_insn QSsize;		/* fields Q:S:size.  */
    593   1.1  christos   aarch64_insn opcodeh2;	/* opcode<2:1> */
    594   1.1  christos 
    595   1.1  christos   /* Rt */
    596   1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    597   1.1  christos 
    598   1.1  christos   /* Decode the index, opcode<2:1> and size.  */
    599   1.1  christos   gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
    600   1.1  christos   opcodeh2 = extract_field_2 (&field, code, 0);
    601   1.1  christos   QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
    602   1.1  christos   switch (opcodeh2)
    603   1.1  christos     {
    604   1.1  christos     case 0x0:
    605   1.1  christos       info->qualifier = AARCH64_OPND_QLF_S_B;
    606   1.1  christos       /* Index encoded in "Q:S:size".  */
    607   1.1  christos       info->reglist.index = QSsize;
    608   1.3  christos       break;
    609   1.3  christos     case 0x1:
    610   1.8  christos       if (QSsize & 0x1)
    611   1.1  christos 	/* UND.  */
    612   1.1  christos 	return false;
    613   1.1  christos       info->qualifier = AARCH64_OPND_QLF_S_H;
    614   1.1  christos       /* Index encoded in "Q:S:size<1>".  */
    615   1.1  christos       info->reglist.index = QSsize >> 1;
    616   1.3  christos       break;
    617   1.3  christos     case 0x2:
    618   1.8  christos       if ((QSsize >> 1) & 0x1)
    619   1.1  christos 	/* UND.  */
    620   1.1  christos 	return false;
    621   1.1  christos       if ((QSsize & 0x1) == 0)
    622   1.1  christos 	{
    623   1.1  christos 	  info->qualifier = AARCH64_OPND_QLF_S_S;
    624   1.1  christos 	  /* Index encoded in "Q:S".  */
    625   1.1  christos 	  info->reglist.index = QSsize >> 2;
    626   1.1  christos 	}
    627   1.3  christos       else
    628   1.3  christos 	{
    629   1.8  christos 	  if (extract_field (FLD_S, code, 0))
    630   1.1  christos 	    /* UND */
    631   1.1  christos 	    return false;
    632   1.1  christos 	  info->qualifier = AARCH64_OPND_QLF_S_D;
    633   1.1  christos 	  /* Index encoded in "Q".  */
    634   1.1  christos 	  info->reglist.index = QSsize >> 3;
    635   1.1  christos 	}
    636   1.8  christos       break;
    637   1.1  christos     default:
    638   1.1  christos       return false;
    639   1.1  christos     }
    640   1.1  christos 
    641   1.9  christos   info->reglist.has_index = 1;
    642   1.1  christos   info->reglist.num_regs = 0;
    643   1.1  christos   info->reglist.stride = 1;
    644   1.1  christos   /* Number of registers is equal to the number of elements in
    645   1.1  christos      each structure to be loaded/stored.  */
    646   1.1  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
    647   1.8  christos   assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
    648   1.1  christos 
    649   1.1  christos   return true;
    650   1.1  christos }
    651   1.1  christos 
    652   1.1  christos /* Decode fields immh:immb and/or Q for e.g.
    653   1.1  christos    SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
    654   1.8  christos    or SSHR <V><d>, <V><n>, #<shift>.  */
    655   1.1  christos 
    656   1.1  christos bool
    657   1.6  christos aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
    658   1.6  christos 			       aarch64_opnd_info *info, const aarch64_insn code,
    659   1.1  christos 			       const aarch64_inst *inst,
    660   1.1  christos 			       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    661   1.1  christos {
    662   1.1  christos   int pos;
    663   1.1  christos   aarch64_insn Q, imm, immh;
    664   1.1  christos   enum aarch64_insn_class iclass = inst->opcode->iclass;
    665   1.1  christos 
    666   1.8  christos   immh = extract_field (FLD_immh, code, 0);
    667   1.1  christos   if (immh == 0)
    668   1.1  christos     return false;
    669   1.1  christos   imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
    670   1.1  christos   pos = 4;
    671   1.1  christos   /* Get highest set bit in immh.  */
    672   1.1  christos   while (--pos >= 0 && (immh & 0x8) == 0)
    673   1.1  christos     immh <<= 1;
    674   1.1  christos 
    675   1.1  christos   assert ((iclass == asimdshf || iclass == asisdshf)
    676   1.1  christos 	  && (info->type == AARCH64_OPND_IMM_VLSR
    677   1.1  christos 	      || info->type == AARCH64_OPND_IMM_VLSL));
    678   1.1  christos 
    679   1.1  christos   if (iclass == asimdshf)
    680   1.1  christos     {
    681   1.1  christos       Q = extract_field (FLD_Q, code, 0);
    682   1.1  christos       /* immh	Q	<T>
    683   1.1  christos 	 0000	x	SEE AdvSIMD modified immediate
    684   1.1  christos 	 0001	0	8B
    685   1.1  christos 	 0001	1	16B
    686   1.1  christos 	 001x	0	4H
    687   1.1  christos 	 001x	1	8H
    688   1.1  christos 	 01xx	0	2S
    689   1.1  christos 	 01xx	1	4S
    690   1.1  christos 	 1xxx	0	RESERVED
    691   1.1  christos 	 1xxx	1	2D  */
    692  1.10  christos       info->qualifier =
    693  1.10  christos 	get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
    694   1.1  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
    695   1.1  christos 	return false;
    696  1.10  christos     }
    697  1.10  christos   else
    698  1.10  christos     {
    699  1.10  christos       info->qualifier = get_sreg_qualifier_from_value (pos);
    700  1.10  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
    701   1.1  christos 	return 0;
    702   1.1  christos     }
    703   1.1  christos 
    704   1.1  christos   if (info->type == AARCH64_OPND_IMM_VLSR)
    705   1.1  christos     /* immh	<shift>
    706   1.1  christos        0000	SEE AdvSIMD modified immediate
    707   1.1  christos        0001	(16-UInt(immh:immb))
    708   1.1  christos        001x	(32-UInt(immh:immb))
    709   1.1  christos        01xx	(64-UInt(immh:immb))
    710   1.1  christos        1xxx	(128-UInt(immh:immb))  */
    711   1.1  christos     info->imm.value = (16 << pos) - imm;
    712   1.1  christos   else
    713   1.1  christos     /* immh:immb
    714   1.1  christos        immh	<shift>
    715   1.1  christos        0000	SEE AdvSIMD modified immediate
    716   1.1  christos        0001	(UInt(immh:immb)-8)
    717   1.1  christos        001x	(UInt(immh:immb)-16)
    718   1.1  christos        01xx	(UInt(immh:immb)-32)
    719   1.1  christos        1xxx	(UInt(immh:immb)-64)  */
    720   1.8  christos     info->imm.value = imm - (8 << pos);
    721   1.1  christos 
    722   1.1  christos   return true;
    723   1.1  christos }
    724   1.8  christos 
    725   1.1  christos /* Decode shift immediate for e.g. sshr (imm).  */
    726   1.1  christos bool
    727   1.6  christos aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
    728   1.6  christos 		      aarch64_opnd_info *info, const aarch64_insn code,
    729   1.1  christos 		      const aarch64_inst *inst ATTRIBUTE_UNUSED,
    730   1.1  christos 		      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    731   1.1  christos {
    732   1.1  christos   int64_t imm;
    733   1.1  christos   aarch64_insn val;
    734   1.1  christos   val = extract_field (FLD_size, code, 0);
    735   1.1  christos   switch (val)
    736   1.1  christos     {
    737   1.1  christos     case 0: imm = 8; break;
    738   1.8  christos     case 1: imm = 16; break;
    739   1.1  christos     case 2: imm = 32; break;
    740   1.1  christos     default: return false;
    741   1.8  christos     }
    742   1.1  christos   info->imm.value = imm;
    743   1.1  christos   return true;
    744   1.1  christos }
    745   1.1  christos 
    746   1.8  christos /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
    747   1.1  christos    value in the field(s) will be extracted as unsigned immediate value.  */
    748   1.1  christos bool
    749   1.8  christos aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
    750   1.6  christos 		 const aarch64_insn code,
    751   1.1  christos 		 const aarch64_inst *inst,
    752   1.7  christos 		 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    753   1.1  christos {
    754   1.6  christos   uint64_t imm;
    755   1.1  christos 
    756   1.1  christos   imm = extract_all_fields (self, code);
    757   1.1  christos 
    758   1.1  christos   if (operand_need_sign_extension (self))
    759   1.1  christos     imm = sign_extend (imm, get_operand_fields_width (self) - 1);
    760   1.1  christos 
    761   1.9  christos   if (operand_need_shift_by_two (self))
    762   1.9  christos     imm <<= 2;
    763   1.7  christos   else if (operand_need_shift_by_three (self))
    764   1.7  christos     imm <<= 3;
    765   1.1  christos   else if (operand_need_shift_by_four (self))
    766   1.1  christos     imm <<= 4;
    767   1.1  christos 
    768   1.1  christos   if (info->type == AARCH64_OPND_ADDR_ADRP)
    769   1.8  christos     imm <<= 12;
    770   1.8  christos 
    771   1.8  christos   if (inst->operands[0].type == AARCH64_OPND_PSTATEFIELD
    772   1.8  christos       && inst->operands[0].sysreg.flags & F_IMM_IN_CRM)
    773   1.1  christos     imm &= PSTATE_DECODE_CRM_IMM (inst->operands[0].sysreg.flags);
    774   1.8  christos 
    775   1.1  christos   info->imm.value = imm;
    776   1.1  christos   return true;
    777   1.1  christos }
    778   1.8  christos 
    779   1.1  christos /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}.  */
    780   1.1  christos bool
    781   1.6  christos aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
    782   1.6  christos 		      const aarch64_insn code,
    783   1.1  christos 		      const aarch64_inst *inst ATTRIBUTE_UNUSED,
    784   1.6  christos 		      aarch64_operand_error *errors)
    785   1.1  christos {
    786   1.1  christos   aarch64_ext_imm (self, info, code, inst, errors);
    787   1.8  christos   info->shifter.kind = AARCH64_MOD_LSL;
    788   1.1  christos   info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
    789   1.1  christos   return true;
    790   1.1  christos }
    791   1.1  christos 
    792   1.8  christos /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
    793   1.1  christos      MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}.  */
    794   1.1  christos bool
    795   1.1  christos aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
    796   1.6  christos 				  aarch64_opnd_info *info,
    797   1.6  christos 				  const aarch64_insn code,
    798   1.1  christos 				  const aarch64_inst *inst ATTRIBUTE_UNUSED,
    799   1.1  christos 				  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    800   1.1  christos {
    801   1.1  christos   uint64_t imm;
    802   1.1  christos   enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
    803   1.1  christos   aarch64_field field = {0, 0};
    804   1.1  christos 
    805   1.1  christos   assert (info->idx == 1);
    806   1.1  christos 
    807   1.1  christos   if (info->type == AARCH64_OPND_SIMD_FPIMM)
    808   1.1  christos     info->imm.is_fp = 1;
    809   1.1  christos 
    810   1.1  christos   /* a:b:c:d:e:f:g:h */
    811   1.1  christos   imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
    812   1.1  christos   if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
    813   1.1  christos     {
    814   1.1  christos       /* Either MOVI <Dd>, #<imm>
    815   1.1  christos 	 or     MOVI <Vd>.2D, #<imm>.
    816   1.1  christos 	 <imm> is a 64-bit immediate
    817   1.1  christos 	 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
    818   1.1  christos 	 encoded in "a:b:c:d:e:f:g:h".	*/
    819   1.1  christos       int i;
    820   1.1  christos       unsigned abcdefgh = imm;
    821   1.1  christos       for (imm = 0ull, i = 0; i < 8; i++)
    822   1.1  christos 	if (((abcdefgh >> i) & 0x1) != 0)
    823   1.1  christos 	  imm |= 0xffull << (8 * i);
    824   1.1  christos     }
    825   1.1  christos   info->imm.value = imm;
    826   1.1  christos 
    827  1.10  christos   /* cmode */
    828  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
    829   1.1  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
    830   1.1  christos     return 0;
    831   1.1  christos   switch (info->qualifier)
    832   1.1  christos     {
    833   1.1  christos     case AARCH64_OPND_QLF_NIL:
    834   1.1  christos       /* no shift */
    835   1.1  christos       info->shifter.kind = AARCH64_MOD_NONE;
    836   1.1  christos       return 1;
    837   1.1  christos     case AARCH64_OPND_QLF_LSL:
    838   1.1  christos       /* shift zeros */
    839   1.1  christos       info->shifter.kind = AARCH64_MOD_LSL;
    840   1.1  christos       switch (aarch64_get_qualifier_esize (opnd0_qualifier))
    841   1.1  christos 	{
    842   1.3  christos 	case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break;	/* per word */
    843   1.8  christos 	case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break;	/* per half */
    844   1.1  christos 	case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break;	/* per byte */
    845   1.1  christos 	default: return false;
    846   1.1  christos 	}
    847   1.1  christos       /* 00: 0; 01: 8; 10:16; 11:24.  */
    848   1.1  christos       info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
    849   1.1  christos       break;
    850   1.1  christos     case AARCH64_OPND_QLF_MSL:
    851   1.1  christos       /* shift ones */
    852   1.1  christos       info->shifter.kind = AARCH64_MOD_MSL;
    853   1.1  christos       gen_sub_field (FLD_cmode, 0, 1, &field);		/* per word */
    854   1.1  christos       info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
    855   1.8  christos       break;
    856   1.1  christos     default:
    857   1.1  christos       return false;
    858   1.8  christos     }
    859   1.6  christos 
    860   1.6  christos   return true;
    861   1.6  christos }
    862   1.8  christos 
    863   1.6  christos /* Decode an 8-bit floating-point immediate.  */
    864   1.6  christos bool
    865   1.6  christos aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info,
    866   1.6  christos 		   const aarch64_insn code,
    867   1.6  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED,
    868   1.6  christos 		   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    869   1.6  christos {
    870   1.8  christos   info->imm.value = extract_all_fields (self, code);
    871   1.6  christos   info->imm.is_fp = 1;
    872   1.6  christos   return true;
    873   1.6  christos }
    874   1.8  christos 
    875   1.6  christos /* Decode a 1-bit rotate immediate (#90 or #270).  */
    876   1.6  christos bool
    877   1.6  christos aarch64_ext_imm_rotate1 (const aarch64_operand *self, aarch64_opnd_info *info,
    878   1.6  christos 			 const aarch64_insn code,
    879   1.6  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
    880   1.6  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    881   1.6  christos {
    882   1.6  christos   uint64_t rot = extract_field (self->fields[0], code, 0);
    883   1.8  christos   assert (rot < 2U);
    884   1.6  christos   info->imm.value = rot * 180 + 90;
    885   1.6  christos   return true;
    886   1.6  christos }
    887   1.8  christos 
    888   1.6  christos /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270).  */
    889   1.6  christos bool
    890   1.6  christos aarch64_ext_imm_rotate2 (const aarch64_operand *self, aarch64_opnd_info *info,
    891   1.6  christos 			 const aarch64_insn code,
    892   1.6  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
    893   1.6  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    894   1.6  christos {
    895   1.6  christos   uint64_t rot = extract_field (self->fields[0], code, 0);
    896   1.8  christos   assert (rot < 4U);
    897   1.1  christos   info->imm.value = rot * 90;
    898   1.1  christos   return true;
    899   1.1  christos }
    900   1.8  christos 
    901   1.1  christos /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>.  */
    902   1.1  christos bool
    903   1.6  christos aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
    904   1.6  christos 		   aarch64_opnd_info *info, const aarch64_insn code,
    905   1.1  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED,
    906   1.1  christos 		   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    907   1.8  christos {
    908   1.1  christos   info->imm.value = 64- extract_field (FLD_scale, code, 0);
    909   1.1  christos   return true;
    910   1.1  christos }
    911   1.1  christos 
    912   1.8  christos /* Decode arithmetic immediate for e.g.
    913   1.1  christos      SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}.  */
    914   1.1  christos bool
    915   1.6  christos aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
    916   1.6  christos 		  aarch64_opnd_info *info, const aarch64_insn code,
    917   1.1  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED,
    918   1.1  christos 		  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
    919   1.1  christos {
    920   1.1  christos   aarch64_insn value;
    921   1.1  christos 
    922   1.1  christos   info->shifter.kind = AARCH64_MOD_LSL;
    923   1.1  christos   /* shift */
    924   1.8  christos   value = extract_field (FLD_shift, code, 0);
    925   1.1  christos   if (value >= 2)
    926   1.1  christos     return false;
    927   1.1  christos   info->shifter.amount = value ? 12 : 0;
    928   1.1  christos   /* imm12 (unsigned) */
    929   1.8  christos   info->imm.value = extract_field (FLD_imm12, code, 0);
    930   1.1  christos 
    931   1.1  christos   return true;
    932   1.6  christos }
    933   1.6  christos 
    934   1.6  christos /* Return true if VALUE is a valid logical immediate encoding, storing the
    935   1.8  christos    decoded value in *RESULT if so.  ESIZE is the number of bytes in the
    936   1.6  christos    decoded immediate.  */
    937   1.1  christos static bool
    938   1.1  christos decode_limm (uint32_t esize, aarch64_insn value, int64_t *result)
    939   1.1  christos {
    940   1.1  christos   uint64_t imm, mask;
    941   1.1  christos   uint32_t N, R, S;
    942   1.1  christos   unsigned simd_size;
    943   1.1  christos 
    944   1.1  christos   /* value is N:immr:imms.  */
    945   1.1  christos   S = value & 0x3f;
    946   1.1  christos   R = (value >> 6) & 0x3f;
    947   1.1  christos   N = (value >> 12) & 0x1;
    948   1.3  christos 
    949   1.1  christos   /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
    950   1.1  christos      (in other words, right rotated by R), then replicated.  */
    951   1.1  christos   if (N != 0)
    952   1.1  christos     {
    953   1.1  christos       simd_size = 64;
    954   1.1  christos       mask = 0xffffffffffffffffull;
    955   1.1  christos     }
    956   1.1  christos   else
    957   1.1  christos     {
    958   1.1  christos       switch (S)
    959   1.1  christos 	{
    960   1.1  christos 	case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32;           break;
    961   1.1  christos 	case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
    962   1.1  christos 	case 0x30 ... 0x37: /* 110xxx */ simd_size =  8; S &= 0x7; break;
    963   1.8  christos 	case 0x38 ... 0x3b: /* 1110xx */ simd_size =  4; S &= 0x3; break;
    964   1.1  christos 	case 0x3c ... 0x3d: /* 11110x */ simd_size =  2; S &= 0x1; break;
    965   1.1  christos 	default: return false;
    966   1.1  christos 	}
    967   1.1  christos       mask = (1ull << simd_size) - 1;
    968   1.1  christos       /* Top bits are IGNORED.  */
    969   1.6  christos       R &= simd_size - 1;
    970   1.6  christos     }
    971   1.8  christos 
    972   1.6  christos   if (simd_size > esize * 8)
    973   1.1  christos     return false;
    974   1.1  christos 
    975   1.8  christos   /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
    976   1.1  christos   if (S == simd_size - 1)
    977   1.1  christos     return false;
    978   1.1  christos   /* S+1 consecutive bits to 1.  */
    979   1.1  christos   /* NOTE: S can't be 63 due to detection above.  */
    980   1.1  christos   imm = (1ull << (S + 1)) - 1;
    981   1.1  christos   /* Rotate to the left by simd_size - R.  */
    982   1.1  christos   if (R != 0)
    983   1.1  christos     imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
    984   1.1  christos   /* Replicate the value according to SIMD size.  */
    985   1.1  christos   switch (simd_size)
    986   1.6  christos     {
    987   1.1  christos     case  2: imm = (imm <<  2) | imm;
    988   1.6  christos       /* Fall through.  */
    989   1.1  christos     case  4: imm = (imm <<  4) | imm;
    990   1.6  christos       /* Fall through.  */
    991   1.1  christos     case  8: imm = (imm <<  8) | imm;
    992   1.6  christos       /* Fall through.  */
    993   1.1  christos     case 16: imm = (imm << 16) | imm;
    994   1.6  christos       /* Fall through.  */
    995   1.1  christos     case 32: imm = (imm << 32) | imm;
    996   1.8  christos       /* Fall through.  */
    997   1.1  christos     case 64: break;
    998   1.1  christos     default: return 0;
    999   1.6  christos     }
   1000   1.6  christos 
   1001   1.8  christos   *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
   1002   1.6  christos 
   1003   1.6  christos   return true;
   1004   1.6  christos }
   1005   1.8  christos 
   1006   1.6  christos /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */
   1007   1.6  christos bool
   1008   1.6  christos aarch64_ext_limm (const aarch64_operand *self,
   1009   1.6  christos 		  aarch64_opnd_info *info, const aarch64_insn code,
   1010   1.6  christos 		  const aarch64_inst *inst,
   1011   1.6  christos 		  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1012   1.6  christos {
   1013   1.6  christos   uint32_t esize;
   1014   1.6  christos   aarch64_insn value;
   1015   1.6  christos 
   1016   1.6  christos   value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
   1017   1.6  christos 			  self->fields[2]);
   1018   1.6  christos   esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
   1019   1.1  christos   return decode_limm (esize, value, &info->imm.value);
   1020   1.6  christos }
   1021   1.8  christos 
   1022   1.6  christos /* Decode a logical immediate for the BIC alias of AND (etc.).  */
   1023   1.6  christos bool
   1024   1.6  christos aarch64_ext_inv_limm (const aarch64_operand *self,
   1025   1.6  christos 		      aarch64_opnd_info *info, const aarch64_insn code,
   1026   1.6  christos 		      const aarch64_inst *inst,
   1027   1.6  christos 		      aarch64_operand_error *errors)
   1028   1.8  christos {
   1029   1.6  christos   if (!aarch64_ext_limm (self, info, code, inst, errors))
   1030   1.8  christos     return false;
   1031   1.1  christos   info->imm.value = ~info->imm.value;
   1032   1.1  christos   return true;
   1033   1.1  christos }
   1034   1.1  christos 
   1035   1.8  christos /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
   1036   1.1  christos    or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>.  */
   1037   1.1  christos bool
   1038   1.6  christos aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1039   1.6  christos 		aarch64_opnd_info *info,
   1040   1.1  christos 		const aarch64_insn code, const aarch64_inst *inst,
   1041   1.1  christos 		aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1042   1.1  christos {
   1043   1.1  christos   aarch64_insn value;
   1044   1.1  christos 
   1045   1.1  christos   /* Rt */
   1046   1.1  christos   info->reg.regno = extract_field (FLD_Rt, code, 0);
   1047   1.1  christos 
   1048   1.1  christos   /* size */
   1049   1.1  christos   value = extract_field (FLD_ldst_size, code, 0);
   1050   1.1  christos   if (inst->opcode->iclass == ldstpair_indexed
   1051   1.1  christos       || inst->opcode->iclass == ldstnapair_offs
   1052   1.1  christos       || inst->opcode->iclass == ldstpair_off
   1053   1.1  christos       || inst->opcode->iclass == loadlit)
   1054   1.1  christos     {
   1055   1.1  christos       enum aarch64_opnd_qualifier qualifier;
   1056   1.1  christos       switch (value)
   1057   1.1  christos 	{
   1058   1.1  christos 	case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
   1059   1.8  christos 	case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
   1060   1.1  christos 	case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
   1061   1.1  christos 	default: return false;
   1062   1.1  christos 	}
   1063   1.1  christos       info->qualifier = qualifier;
   1064   1.1  christos     }
   1065   1.1  christos   else
   1066   1.1  christos     {
   1067   1.1  christos       /* opc1:size */
   1068   1.8  christos       value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
   1069   1.1  christos       if (value > 0x4)
   1070  1.10  christos 	return false;
   1071  1.10  christos       info->qualifier = get_sreg_qualifier_from_value (value);
   1072   1.1  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1073   1.1  christos 	return false;
   1074   1.8  christos     }
   1075   1.1  christos 
   1076   1.1  christos   return true;
   1077   1.1  christos }
   1078   1.8  christos 
   1079   1.1  christos /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}].  */
   1080   1.1  christos bool
   1081   1.1  christos aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1082   1.6  christos 			 aarch64_opnd_info *info,
   1083   1.6  christos 			 aarch64_insn code,
   1084   1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1085   1.1  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1086   1.1  christos {
   1087   1.8  christos   /* Rn */
   1088   1.6  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
   1089   1.6  christos   return true;
   1090   1.9  christos }
   1091   1.9  christos 
   1092   1.9  christos /* Decode the address operand for rcpc3 instructions with optional load/store
   1093   1.9  christos    datasize offset, e.g. STILPP <Xs>, <Xt>, [<Xn|SP>{,#-16}]! and
   1094   1.9  christos    LIDAP <Xs>, <Xt>, [<Xn|SP>]{,#-16}.  */
   1095   1.9  christos bool
   1096   1.9  christos aarch64_ext_rcpc3_addr_opt_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1097   1.9  christos 				   aarch64_opnd_info *info,
   1098   1.9  christos 				   aarch64_insn code,
   1099   1.9  christos 				   const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1100   1.9  christos 				   aarch64_operand_error *err ATTRIBUTE_UNUSED)
   1101   1.9  christos {
   1102   1.9  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
   1103   1.9  christos   if (!extract_field (FLD_opc2, code, 0))
   1104   1.9  christos     {
   1105   1.9  christos       info->addr.writeback = 1;
   1106   1.9  christos 
   1107   1.9  christos       enum aarch64_opnd type;
   1108   1.9  christos       for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
   1109   1.9  christos 	{
   1110   1.9  christos 	  aarch64_opnd_info opnd = info[i];
   1111   1.9  christos 	  type = opnd.type;
   1112   1.9  christos 	  if (aarch64_operands[type].op_class == AARCH64_OPND_CLASS_ADDRESS)
   1113   1.9  christos 	    break;
   1114   1.9  christos 	}
   1115   1.9  christos 
   1116   1.9  christos       assert (aarch64_operands[type].op_class == AARCH64_OPND_CLASS_ADDRESS);
   1117   1.9  christos       int offset = calc_ldst_datasize (inst->operands);
   1118   1.9  christos 
   1119   1.9  christos       switch (type)
   1120   1.9  christos 	{
   1121   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
   1122   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
   1123   1.9  christos 	  info->addr.offset.imm = -offset;
   1124   1.9  christos 	  info->addr.preind = 1;
   1125   1.9  christos 	  break;
   1126   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
   1127   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_POSTIND:
   1128   1.9  christos 	  info->addr.offset.imm = offset;
   1129   1.9  christos 	  info->addr.postind = 1;
   1130   1.9  christos 	  break;
   1131   1.9  christos 	default:
   1132   1.9  christos 	  return false;
   1133   1.9  christos 	}
   1134   1.9  christos     }
   1135   1.9  christos   return true;
   1136   1.9  christos }
   1137   1.9  christos 
   1138   1.9  christos bool
   1139   1.9  christos aarch64_ext_rcpc3_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1140   1.9  christos 			       aarch64_opnd_info *info,
   1141   1.9  christos 			       aarch64_insn code,
   1142   1.9  christos 			       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1143   1.9  christos 			       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1144  1.10  christos {
   1145  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
   1146   1.9  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1147   1.9  christos     return 0;
   1148   1.9  christos 
   1149   1.9  christos   /* Rn */
   1150   1.9  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1151   1.9  christos 
   1152   1.9  christos   /* simm9 */
   1153   1.9  christos   aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
   1154   1.9  christos   info->addr.offset.imm = sign_extend (imm, 8);
   1155   1.9  christos   return true;
   1156   1.6  christos }
   1157   1.6  christos 
   1158   1.8  christos /* Decode the address operand for e.g.
   1159   1.6  christos      stlur <Xt>, [<Xn|SP>{, <amount>}].  */
   1160   1.6  christos bool
   1161   1.6  christos aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1162   1.6  christos 			 aarch64_opnd_info *info,
   1163   1.6  christos 			 aarch64_insn code, const aarch64_inst *inst,
   1164   1.6  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1165  1.10  christos {
   1166  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
   1167   1.6  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1168   1.6  christos     return 0;
   1169   1.6  christos 
   1170   1.6  christos   /* Rn */
   1171   1.6  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1172   1.6  christos 
   1173   1.6  christos   /* simm9 */
   1174   1.6  christos   aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
   1175   1.6  christos   info->addr.offset.imm = sign_extend (imm, 8);
   1176   1.6  christos   if (extract_field (self->fields[2], code, 0) == 1) {
   1177   1.6  christos     info->addr.writeback = 1;
   1178   1.8  christos     info->addr.preind = 1;
   1179   1.1  christos   }
   1180   1.1  christos   return true;
   1181   1.1  christos }
   1182   1.1  christos 
   1183   1.8  christos /* Decode the address operand for e.g.
   1184   1.1  christos      STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
   1185   1.1  christos bool
   1186   1.6  christos aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1187   1.6  christos 			 aarch64_opnd_info *info,
   1188   1.1  christos 			 aarch64_insn code, const aarch64_inst *inst,
   1189   1.1  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1190   1.1  christos {
   1191   1.1  christos   aarch64_insn S, value;
   1192   1.1  christos 
   1193   1.1  christos   /* Rn */
   1194   1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
   1195   1.1  christos   /* Rm */
   1196   1.1  christos   info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
   1197   1.1  christos   /* option */
   1198   1.8  christos   value = extract_field (FLD_option, code, 0);
   1199   1.1  christos   info->shifter.kind =
   1200   1.1  christos     aarch64_get_operand_modifier_from_value (value, true /* extend_p */);
   1201   1.1  christos   /* Fix-up the shifter kind; although the table-driven approach is
   1202   1.1  christos      efficient, it is slightly inflexible, thus needing this fix-up.  */
   1203   1.1  christos   if (info->shifter.kind == AARCH64_MOD_UXTX)
   1204   1.1  christos     info->shifter.kind = AARCH64_MOD_LSL;
   1205   1.1  christos   /* S */
   1206   1.1  christos   S = extract_field (FLD_S, code, 0);
   1207   1.1  christos   if (S == 0)
   1208   1.1  christos     {
   1209   1.1  christos       info->shifter.amount = 0;
   1210   1.1  christos       info->shifter.amount_present = 0;
   1211   1.1  christos     }
   1212   1.1  christos   else
   1213   1.1  christos     {
   1214   1.1  christos       int size;
   1215   1.1  christos       /* Need information in other operand(s) to help achieve the decoding
   1216  1.10  christos 	 from 'S' field.  */
   1217  1.10  christos       info->qualifier = get_expected_qualifier (inst, info->idx);
   1218   1.1  christos       if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1219   1.1  christos 	return 0;
   1220   1.1  christos       /* Get the size of the data element that is accessed, which may be
   1221   1.1  christos 	 different from that of the source register size, e.g. in strb/ldrb.  */
   1222   1.1  christos       size = aarch64_get_qualifier_esize (info->qualifier);
   1223   1.1  christos       info->shifter.amount = get_logsz (size);
   1224   1.1  christos       info->shifter.amount_present = 1;
   1225   1.8  christos     }
   1226   1.1  christos 
   1227   1.1  christos   return true;
   1228   1.1  christos }
   1229   1.8  christos 
   1230   1.1  christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>.  */
   1231   1.6  christos bool
   1232   1.6  christos aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
   1233   1.1  christos 		       aarch64_insn code, const aarch64_inst *inst,
   1234   1.1  christos 		       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1235   1.1  christos {
   1236  1.10  christos   aarch64_insn imm;
   1237  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
   1238   1.1  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1239   1.1  christos     return 0;
   1240   1.1  christos 
   1241   1.1  christos   /* Rn */
   1242   1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
   1243   1.1  christos   /* simm (imm9 or imm7)  */
   1244   1.7  christos   imm = extract_field (self->fields[0], code, 0);
   1245   1.7  christos   info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
   1246   1.1  christos   if (self->fields[0] == FLD_imm7
   1247   1.1  christos       || info->qualifier == AARCH64_OPND_QLF_imm_tag)
   1248   1.1  christos     /* scaled immediate in ld/st pair instructions.  */
   1249   1.1  christos     info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
   1250   1.1  christos   /* qualifier */
   1251   1.1  christos   if (inst->opcode->iclass == ldst_unscaled
   1252   1.1  christos       || inst->opcode->iclass == ldstnapair_offs
   1253   1.1  christos       || inst->opcode->iclass == ldstpair_off
   1254   1.1  christos       || inst->opcode->iclass == ldst_unpriv)
   1255   1.1  christos     info->addr.writeback = 0;
   1256   1.1  christos   else
   1257   1.1  christos     {
   1258   1.1  christos       /* pre/post- index */
   1259   1.1  christos       info->addr.writeback = 1;
   1260   1.1  christos       if (extract_field (self->fields[1], code, 0) == 1)
   1261   1.1  christos 	info->addr.preind = 1;
   1262   1.1  christos       else
   1263   1.1  christos 	info->addr.postind = 1;
   1264   1.8  christos     }
   1265   1.1  christos 
   1266   1.1  christos   return true;
   1267   1.1  christos }
   1268   1.8  christos 
   1269   1.1  christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}].  */
   1270   1.1  christos bool
   1271   1.6  christos aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
   1272   1.6  christos 			 aarch64_insn code,
   1273   1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1274   1.1  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1275   1.1  christos {
   1276  1.10  christos   int shift;
   1277  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
   1278   1.1  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1279   1.1  christos     return 0;
   1280   1.1  christos   shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
   1281   1.1  christos   /* Rn */
   1282   1.1  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1283   1.8  christos   /* uimm12 */
   1284   1.6  christos   info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
   1285   1.6  christos   return true;
   1286   1.6  christos }
   1287   1.8  christos 
   1288   1.6  christos /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}].  */
   1289   1.6  christos bool
   1290   1.6  christos aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info,
   1291   1.6  christos 			 aarch64_insn code,
   1292   1.6  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1293   1.6  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1294   1.6  christos {
   1295   1.6  christos   aarch64_insn imm;
   1296  1.10  christos 
   1297  1.10  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
   1298   1.6  christos   if (info->qualifier == AARCH64_OPND_QLF_ERR)
   1299   1.6  christos     return 0;
   1300   1.6  christos   /* Rn */
   1301   1.6  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1302   1.6  christos   /* simm10 */
   1303   1.6  christos   imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
   1304   1.6  christos   info->addr.offset.imm = sign_extend (imm, 9) << 3;
   1305   1.6  christos   if (extract_field (self->fields[3], code, 0) == 1) {
   1306   1.6  christos     info->addr.writeback = 1;
   1307   1.8  christos     info->addr.preind = 1;
   1308   1.1  christos   }
   1309   1.1  christos   return true;
   1310   1.1  christos }
   1311   1.1  christos 
   1312   1.8  christos /* Decode the address operand for e.g.
   1313   1.1  christos      LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>.  */
   1314   1.1  christos bool
   1315   1.6  christos aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1316   1.6  christos 			    aarch64_opnd_info *info,
   1317   1.1  christos 			    aarch64_insn code, const aarch64_inst *inst,
   1318   1.1  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1319   1.1  christos {
   1320   1.1  christos   /* The opcode dependent area stores the number of elements in
   1321   1.1  christos      each structure to be loaded/stored.  */
   1322   1.1  christos   int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
   1323   1.1  christos 
   1324   1.1  christos   /* Rn */
   1325   1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
   1326   1.1  christos   /* Rm | #<amount>  */
   1327   1.1  christos   info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
   1328   1.1  christos   if (info->addr.offset.regno == 31)
   1329   1.1  christos     {
   1330   1.1  christos       if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
   1331   1.1  christos 	/* Special handling of loading single structure to all lane.  */
   1332   1.1  christos 	info->addr.offset.imm = (is_ld1r ? 1
   1333   1.1  christos 				 : inst->operands[0].reglist.num_regs)
   1334   1.1  christos 	  * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
   1335   1.1  christos       else
   1336   1.1  christos 	info->addr.offset.imm = inst->operands[0].reglist.num_regs
   1337   1.1  christos 	  * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
   1338   1.1  christos 	  * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
   1339   1.1  christos     }
   1340   1.1  christos   else
   1341   1.1  christos     info->addr.offset.is_reg = 1;
   1342   1.8  christos   info->addr.writeback = 1;
   1343   1.1  christos 
   1344   1.1  christos   return true;
   1345   1.1  christos }
   1346   1.8  christos 
   1347   1.1  christos /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>.  */
   1348   1.1  christos bool
   1349   1.6  christos aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1350   1.6  christos 		  aarch64_opnd_info *info,
   1351   1.1  christos 		  aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1352   1.1  christos 		  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1353   1.1  christos {
   1354   1.1  christos   aarch64_insn value;
   1355   1.1  christos   /* cond */
   1356   1.8  christos   value = extract_field (FLD_cond, code, 0);
   1357   1.1  christos   info->cond = get_cond_from_value (value);
   1358   1.1  christos   return true;
   1359   1.1  christos }
   1360   1.8  christos 
   1361   1.1  christos /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>.  */
   1362   1.1  christos bool
   1363   1.1  christos aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1364   1.6  christos 		    aarch64_opnd_info *info,
   1365   1.6  christos 		    aarch64_insn code,
   1366   1.1  christos 		    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1367   1.1  christos 		    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1368   1.6  christos {
   1369   1.6  christos   /* op0:op1:CRn:CRm:op2 */
   1370   1.6  christos   info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
   1371   1.6  christos 				       FLD_CRm, FLD_op2);
   1372   1.6  christos   info->sysreg.flags = 0;
   1373   1.6  christos 
   1374   1.6  christos   /* If a system instruction, check which restrictions should be on the register
   1375   1.6  christos      value during decoding, these will be enforced then.  */
   1376   1.6  christos   if (inst->opcode->iclass == ic_system)
   1377   1.6  christos     {
   1378   1.6  christos       /* Check to see if it's read-only, else check if it's write only.
   1379   1.6  christos 	 if it's both or unspecified don't care.  */
   1380   1.6  christos       if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ)
   1381   1.6  christos 	info->sysreg.flags = F_REG_READ;
   1382   1.6  christos       else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE))
   1383   1.6  christos 	       == F_SYS_WRITE)
   1384   1.6  christos 	info->sysreg.flags = F_REG_WRITE;
   1385   1.8  christos     }
   1386   1.1  christos 
   1387   1.1  christos   return true;
   1388   1.1  christos }
   1389   1.8  christos 
   1390   1.1  christos /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>.  */
   1391   1.1  christos bool
   1392   1.6  christos aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1393   1.6  christos 			 aarch64_opnd_info *info, aarch64_insn code,
   1394   1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1395   1.1  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1396   1.8  christos {
   1397   1.1  christos   int i;
   1398   1.1  christos   aarch64_insn fld_crm = extract_field (FLD_CRm, code, 0);
   1399   1.1  christos   /* op1:op2 */
   1400   1.1  christos   info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
   1401   1.8  christos   for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
   1402   1.8  christos     if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
   1403   1.8  christos       {
   1404   1.8  christos         /* PSTATEFIELD name can be encoded partially in CRm[3:1].  */
   1405   1.8  christos         uint32_t flags = aarch64_pstatefields[i].flags;
   1406   1.8  christos         if ((flags & F_REG_IN_CRM)
   1407   1.8  christos             && ((fld_crm & 0xe) != PSTATE_DECODE_CRM (flags)))
   1408   1.8  christos           continue;
   1409   1.8  christos         info->sysreg.flags = flags;
   1410   1.1  christos         return true;
   1411   1.8  christos       }
   1412   1.1  christos   /* Reserved value in <pstatefield>.  */
   1413   1.1  christos   return false;
   1414   1.1  christos }
   1415   1.8  christos 
   1416   1.1  christos /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>.  */
   1417   1.1  christos bool
   1418   1.1  christos aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1419   1.6  christos 		       aarch64_opnd_info *info,
   1420   1.6  christos 		       aarch64_insn code,
   1421   1.1  christos 		       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1422   1.1  christos 		       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1423   1.1  christos {
   1424   1.1  christos   int i;
   1425   1.1  christos   aarch64_insn value;
   1426   1.1  christos   const aarch64_sys_ins_reg *sysins_ops;
   1427   1.1  christos   /* op0:op1:CRn:CRm:op2 */
   1428   1.1  christos   value = extract_fields (code, 0, 5,
   1429   1.1  christos 			  FLD_op0, FLD_op1, FLD_CRn,
   1430   1.1  christos 			  FLD_CRm, FLD_op2);
   1431   1.1  christos 
   1432   1.1  christos   switch (info->type)
   1433   1.1  christos     {
   1434   1.1  christos     case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
   1435   1.1  christos     case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
   1436   1.9  christos     case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
   1437   1.7  christos     case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
   1438   1.7  christos     case AARCH64_OPND_SYSREG_TLBIP: sysins_ops = aarch64_sys_regs_tlbi; break;
   1439   1.7  christos     case AARCH64_OPND_SYSREG_SR:
   1440   1.7  christos 	sysins_ops = aarch64_sys_regs_sr;
   1441   1.7  christos 	 /* Let's remove op2 for rctx.  Refer to comments in the definition of
   1442   1.7  christos 	    aarch64_sys_regs_sr[].  */
   1443   1.8  christos 	value = value & ~(0x7);
   1444   1.1  christos 	break;
   1445   1.1  christos     default: return false;
   1446   1.3  christos     }
   1447   1.1  christos 
   1448   1.1  christos   for (i = 0; sysins_ops[i].name != NULL; ++i)
   1449   1.1  christos     if (sysins_ops[i].value == value)
   1450   1.1  christos       {
   1451   1.3  christos 	info->sysins_op = sysins_ops + i;
   1452   1.1  christos 	DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
   1453   1.3  christos 		     info->sysins_op->name,
   1454   1.8  christos 		     (unsigned)info->sysins_op->value,
   1455   1.1  christos 		     aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
   1456   1.1  christos 	return true;
   1457   1.8  christos       }
   1458   1.1  christos 
   1459   1.1  christos   return false;
   1460   1.1  christos }
   1461   1.1  christos 
   1462   1.8  christos /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>.  */
   1463   1.1  christos 
   1464   1.1  christos bool
   1465   1.1  christos aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1466   1.6  christos 		     aarch64_opnd_info *info,
   1467   1.6  christos 		     aarch64_insn code,
   1468   1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1469   1.1  christos 		     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1470   1.1  christos {
   1471   1.8  christos   /* CRm */
   1472   1.8  christos   info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
   1473   1.8  christos   return true;
   1474   1.8  christos }
   1475   1.8  christos 
   1476   1.8  christos /* Decode the memory barrier option operand for DSB <option>nXS|#<imm>.  */
   1477   1.8  christos 
   1478   1.8  christos bool
   1479   1.8  christos aarch64_ext_barrier_dsb_nxs (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1480   1.8  christos 		     aarch64_opnd_info *info,
   1481   1.8  christos 		     aarch64_insn code,
   1482   1.8  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1483   1.8  christos 		     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1484   1.8  christos {
   1485   1.8  christos   /* For the DSB nXS barrier variant immediate is encoded in 2-bit field.  */
   1486   1.8  christos   aarch64_insn field = extract_field (FLD_CRm_dsb_nxs, code, 0);
   1487   1.1  christos   info->barrier = aarch64_barrier_dsb_nxs_options + field;
   1488   1.1  christos   return true;
   1489   1.1  christos }
   1490   1.1  christos 
   1491   1.1  christos /* Decode the prefetch operation option operand for e.g.
   1492   1.8  christos      PRFM <prfop>, [<Xn|SP>{, #<pimm>}].  */
   1493   1.1  christos 
   1494   1.1  christos bool
   1495   1.6  christos aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1496   1.6  christos 		   aarch64_opnd_info *info,
   1497   1.1  christos 		   aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1498   1.1  christos 		   aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1499   1.1  christos {
   1500   1.8  christos   /* prfop in Rt */
   1501   1.1  christos   info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
   1502   1.1  christos   return true;
   1503   1.3  christos }
   1504   1.3  christos 
   1505   1.3  christos /* Decode the hint number for an alias taking an operand.  Set info->hint_option
   1506   1.8  christos    to the matching name/value pair in aarch64_hint_options.  */
   1507   1.3  christos 
   1508   1.3  christos bool
   1509   1.3  christos aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1510   1.6  christos 		  aarch64_opnd_info *info,
   1511   1.6  christos 		  aarch64_insn code,
   1512   1.3  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1513   1.3  christos 		  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1514   1.3  christos {
   1515   1.3  christos   /* CRm:op2.  */
   1516   1.3  christos   unsigned hint_number;
   1517   1.3  christos   int i;
   1518   1.3  christos 
   1519   1.3  christos   hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
   1520   1.3  christos 
   1521   1.7  christos   for (i = 0; aarch64_hint_options[i].name != NULL; i++)
   1522   1.3  christos     {
   1523   1.3  christos       if (hint_number == HINT_VAL (aarch64_hint_options[i].value))
   1524   1.8  christos 	{
   1525   1.3  christos 	  info->hint_option = &(aarch64_hint_options[i]);
   1526   1.3  christos 	  return true;
   1527   1.3  christos 	}
   1528   1.8  christos     }
   1529   1.3  christos 
   1530   1.3  christos   return false;
   1531   1.1  christos }
   1532   1.1  christos 
   1533   1.8  christos /* Decode the extended register operand for e.g.
   1534   1.1  christos      STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
   1535   1.1  christos bool
   1536   1.1  christos aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1537   1.6  christos 			  aarch64_opnd_info *info,
   1538   1.6  christos 			  aarch64_insn code,
   1539   1.1  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1540   1.1  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1541   1.1  christos {
   1542   1.1  christos   aarch64_insn value;
   1543   1.1  christos 
   1544   1.1  christos   /* Rm */
   1545   1.1  christos   info->reg.regno = extract_field (FLD_Rm, code, 0);
   1546   1.1  christos   /* option */
   1547   1.8  christos   value = extract_field (FLD_option, code, 0);
   1548   1.1  christos   info->shifter.kind =
   1549   1.9  christos     aarch64_get_operand_modifier_from_value (value, true /* extend_p */);
   1550   1.1  christos   /* imm3 */
   1551   1.1  christos   info->shifter.amount = extract_field (FLD_imm3_10, code,  0);
   1552   1.1  christos 
   1553   1.1  christos   /* This makes the constraint checking happy.  */
   1554   1.1  christos   info->shifter.operator_present = 1;
   1555   1.1  christos 
   1556   1.1  christos   /* Assume inst->operands[0].qualifier has been resolved.  */
   1557   1.1  christos   assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
   1558   1.1  christos   info->qualifier = AARCH64_OPND_QLF_W;
   1559   1.1  christos   if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
   1560   1.1  christos       && (info->shifter.kind == AARCH64_MOD_UXTX
   1561   1.1  christos 	  || info->shifter.kind == AARCH64_MOD_SXTX))
   1562   1.8  christos     info->qualifier = AARCH64_OPND_QLF_X;
   1563   1.1  christos 
   1564   1.1  christos   return true;
   1565   1.1  christos }
   1566   1.1  christos 
   1567   1.8  christos /* Decode the shifted register operand for e.g.
   1568   1.1  christos      SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}.  */
   1569   1.1  christos bool
   1570   1.1  christos aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1571   1.6  christos 			 aarch64_opnd_info *info,
   1572   1.6  christos 			 aarch64_insn code,
   1573   1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1574   1.1  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1575   1.1  christos {
   1576   1.1  christos   aarch64_insn value;
   1577   1.1  christos 
   1578   1.1  christos   /* Rm */
   1579   1.1  christos   info->reg.regno = extract_field (FLD_Rm, code, 0);
   1580   1.1  christos   /* shift */
   1581   1.8  christos   value = extract_field (FLD_shift, code, 0);
   1582   1.1  christos   info->shifter.kind =
   1583   1.1  christos     aarch64_get_operand_modifier_from_value (value, false /* extend_p */);
   1584   1.1  christos   if (info->shifter.kind == AARCH64_MOD_ROR
   1585   1.1  christos       && inst->opcode->iclass != log_shift)
   1586   1.8  christos     /* ROR is not available for the shifted register operand in arithmetic
   1587   1.1  christos        instructions.  */
   1588   1.9  christos     return false;
   1589   1.1  christos   /* imm6 */
   1590   1.1  christos   info->shifter.amount = extract_field (FLD_imm6_10, code,  0);
   1591   1.1  christos 
   1592   1.1  christos   /* This makes the constraint checking happy.  */
   1593   1.8  christos   info->shifter.operator_present = 1;
   1594   1.6  christos 
   1595   1.6  christos   return true;
   1596  1.10  christos }
   1597  1.10  christos 
   1598  1.10  christos /* Decode the LSL-shifted register operand for e.g.
   1599  1.10  christos      ADDPT <Xd|SP>, <Xn|SP>, <Xm>{, LSL #<amount>}.  */
   1600  1.10  christos bool
   1601  1.10  christos aarch64_ext_reg_lsl_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1602  1.10  christos 			     aarch64_opnd_info *info,
   1603  1.10  christos 			     aarch64_insn code,
   1604  1.10  christos 			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1605  1.10  christos 			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1606  1.10  christos {
   1607  1.10  christos   /* Rm */
   1608  1.10  christos   info->reg.regno = extract_field (FLD_Rm, code, 0);
   1609  1.10  christos   /* imm3 */
   1610  1.10  christos   info->shifter.kind = AARCH64_MOD_LSL;
   1611  1.10  christos   info->shifter.amount = extract_field (FLD_imm3_10, code,  0);
   1612  1.10  christos   return true;
   1613   1.6  christos }
   1614   1.6  christos 
   1615   1.6  christos /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
   1616   1.6  christos    where <offset> is given by the OFFSET parameter and where <factor> is
   1617   1.8  christos    1 plus SELF's operand-dependent value.  fields[0] specifies the field
   1618   1.6  christos    that holds <base>.  */
   1619   1.6  christos static bool
   1620   1.6  christos aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand *self,
   1621   1.6  christos 				 aarch64_opnd_info *info, aarch64_insn code,
   1622   1.6  christos 				 int64_t offset)
   1623   1.6  christos {
   1624   1.8  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1625   1.8  christos   info->addr.offset.imm = offset * (1 + get_operand_specific_data (self));
   1626   1.8  christos   info->addr.offset.is_reg = false;
   1627   1.6  christos   info->addr.writeback = false;
   1628   1.6  christos   info->addr.preind = true;
   1629   1.6  christos   if (offset != 0)
   1630   1.6  christos     info->shifter.kind = AARCH64_MOD_MUL_VL;
   1631   1.8  christos   info->shifter.amount = 1;
   1632   1.8  christos   info->shifter.operator_present = (info->addr.offset.imm != 0);
   1633   1.6  christos   info->shifter.amount_present = false;
   1634   1.6  christos   return true;
   1635   1.6  christos }
   1636   1.6  christos 
   1637   1.6  christos /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
   1638   1.6  christos    where <simm4> is a 4-bit signed value and where <factor> is 1 plus
   1639   1.8  christos    SELF's operand-dependent value.  fields[0] specifies the field that
   1640   1.6  christos    holds <base>.  <simm4> is encoded in the SVE_imm4 field.  */
   1641   1.6  christos bool
   1642   1.6  christos aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand *self,
   1643   1.6  christos 			       aarch64_opnd_info *info, aarch64_insn code,
   1644   1.6  christos 			       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1645   1.6  christos 			       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1646   1.6  christos {
   1647   1.6  christos   int offset;
   1648   1.6  christos 
   1649   1.6  christos   offset = extract_field (FLD_SVE_imm4, code, 0);
   1650   1.6  christos   offset = ((offset + 8) & 15) - 8;
   1651   1.6  christos   return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
   1652   1.6  christos }
   1653   1.6  christos 
   1654   1.6  christos /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
   1655   1.6  christos    where <simm6> is a 6-bit signed value and where <factor> is 1 plus
   1656   1.8  christos    SELF's operand-dependent value.  fields[0] specifies the field that
   1657   1.6  christos    holds <base>.  <simm6> is encoded in the SVE_imm6 field.  */
   1658   1.6  christos bool
   1659   1.6  christos aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand *self,
   1660   1.6  christos 			       aarch64_opnd_info *info, aarch64_insn code,
   1661   1.6  christos 			       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1662   1.6  christos 			       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1663   1.6  christos {
   1664   1.6  christos   int offset;
   1665   1.6  christos 
   1666   1.6  christos   offset = extract_field (FLD_SVE_imm6, code, 0);
   1667   1.6  christos   offset = (((offset + 32) & 63) - 32);
   1668   1.6  christos   return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
   1669   1.6  christos }
   1670   1.6  christos 
   1671   1.6  christos /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
   1672   1.6  christos    where <simm9> is a 9-bit signed value and where <factor> is 1 plus
   1673   1.6  christos    SELF's operand-dependent value.  fields[0] specifies the field that
   1674   1.8  christos    holds <base>.  <simm9> is encoded in the concatenation of the SVE_imm6
   1675   1.6  christos    and imm3 fields, with imm3 being the less-significant part.  */
   1676   1.6  christos bool
   1677   1.6  christos aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand *self,
   1678   1.6  christos 			       aarch64_opnd_info *info,
   1679   1.6  christos 			       aarch64_insn code,
   1680   1.6  christos 			       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1681   1.6  christos 			       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1682   1.6  christos {
   1683   1.9  christos   int offset;
   1684   1.6  christos 
   1685   1.6  christos   offset = extract_fields (code, 0, 2, FLD_SVE_imm6, FLD_imm3_10);
   1686   1.6  christos   offset = (((offset + 256) & 511) - 256);
   1687   1.6  christos   return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
   1688   1.6  christos }
   1689   1.6  christos 
   1690   1.6  christos /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
   1691   1.8  christos    is given by the OFFSET parameter and where <shift> is SELF's operand-
   1692   1.6  christos    dependent value.  fields[0] specifies the base register field <base>.  */
   1693   1.6  christos static bool
   1694   1.6  christos aarch64_ext_sve_addr_reg_imm (const aarch64_operand *self,
   1695   1.6  christos 			      aarch64_opnd_info *info, aarch64_insn code,
   1696   1.6  christos 			      int64_t offset)
   1697   1.6  christos {
   1698   1.8  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1699   1.8  christos   info->addr.offset.imm = offset * (1 << get_operand_specific_data (self));
   1700   1.8  christos   info->addr.offset.is_reg = false;
   1701   1.8  christos   info->addr.writeback = false;
   1702   1.8  christos   info->addr.preind = true;
   1703   1.8  christos   info->shifter.operator_present = false;
   1704   1.6  christos   info->shifter.amount_present = false;
   1705   1.6  christos   return true;
   1706   1.6  christos }
   1707   1.6  christos 
   1708   1.6  christos /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
   1709   1.8  christos    is a 4-bit signed number and where <shift> is SELF's operand-dependent
   1710   1.6  christos    value.  fields[0] specifies the base register field.  */
   1711   1.6  christos bool
   1712   1.6  christos aarch64_ext_sve_addr_ri_s4 (const aarch64_operand *self,
   1713   1.6  christos 			    aarch64_opnd_info *info, aarch64_insn code,
   1714   1.6  christos 			    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1715   1.6  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1716   1.6  christos {
   1717   1.6  christos   int offset = sign_extend (extract_field (FLD_SVE_imm4, code, 0), 3);
   1718   1.6  christos   return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
   1719   1.6  christos }
   1720   1.6  christos 
   1721   1.6  christos /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
   1722   1.8  christos    is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
   1723   1.6  christos    value.  fields[0] specifies the base register field.  */
   1724   1.6  christos bool
   1725   1.6  christos aarch64_ext_sve_addr_ri_u6 (const aarch64_operand *self,
   1726   1.6  christos 			    aarch64_opnd_info *info, aarch64_insn code,
   1727   1.6  christos 			    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1728   1.6  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1729   1.6  christos {
   1730   1.6  christos   int offset = extract_field (FLD_SVE_imm6, code, 0);
   1731   1.6  christos   return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
   1732   1.6  christos }
   1733   1.6  christos 
   1734   1.6  christos /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
   1735   1.8  christos    is SELF's operand-dependent value.  fields[0] specifies the base
   1736   1.6  christos    register field and fields[1] specifies the offset register field.  */
   1737   1.6  christos bool
   1738   1.6  christos aarch64_ext_sve_addr_rr_lsl (const aarch64_operand *self,
   1739   1.6  christos 			     aarch64_opnd_info *info, aarch64_insn code,
   1740   1.6  christos 			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1741   1.6  christos 			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1742   1.6  christos {
   1743   1.6  christos   int index_regno;
   1744   1.6  christos 
   1745   1.8  christos   index_regno = extract_field (self->fields[1], code, 0);
   1746   1.6  christos   if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
   1747   1.6  christos     return false;
   1748   1.6  christos 
   1749   1.8  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1750   1.8  christos   info->addr.offset.regno = index_regno;
   1751   1.8  christos   info->addr.offset.is_reg = true;
   1752   1.6  christos   info->addr.writeback = false;
   1753   1.6  christos   info->addr.preind = true;
   1754   1.6  christos   info->shifter.kind = AARCH64_MOD_LSL;
   1755   1.6  christos   info->shifter.amount = get_operand_specific_data (self);
   1756   1.8  christos   info->shifter.operator_present = (info->shifter.amount != 0);
   1757   1.6  christos   info->shifter.amount_present = (info->shifter.amount != 0);
   1758   1.6  christos   return true;
   1759   1.6  christos }
   1760   1.6  christos 
   1761   1.6  christos /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
   1762   1.6  christos    <shift> is SELF's operand-dependent value.  fields[0] specifies the
   1763   1.8  christos    base register field, fields[1] specifies the offset register field and
   1764   1.6  christos    fields[2] is a single-bit field that selects SXTW over UXTW.  */
   1765   1.6  christos bool
   1766   1.6  christos aarch64_ext_sve_addr_rz_xtw (const aarch64_operand *self,
   1767   1.6  christos 			     aarch64_opnd_info *info, aarch64_insn code,
   1768   1.6  christos 			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1769   1.6  christos 			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1770   1.6  christos {
   1771   1.8  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1772   1.8  christos   info->addr.offset.regno = extract_field (self->fields[1], code, 0);
   1773   1.8  christos   info->addr.offset.is_reg = true;
   1774   1.6  christos   info->addr.writeback = false;
   1775   1.6  christos   info->addr.preind = true;
   1776   1.6  christos   if (extract_field (self->fields[2], code, 0))
   1777   1.6  christos     info->shifter.kind = AARCH64_MOD_SXTW;
   1778   1.6  christos   else
   1779   1.8  christos     info->shifter.kind = AARCH64_MOD_UXTW;
   1780   1.6  christos   info->shifter.amount = get_operand_specific_data (self);
   1781   1.8  christos   info->shifter.operator_present = true;
   1782   1.6  christos   info->shifter.amount_present = (info->shifter.amount != 0);
   1783   1.6  christos   return true;
   1784   1.6  christos }
   1785   1.6  christos 
   1786   1.6  christos /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
   1787   1.8  christos    5-bit unsigned number and where <shift> is SELF's operand-dependent value.
   1788   1.6  christos    fields[0] specifies the base register field.  */
   1789   1.6  christos bool
   1790   1.6  christos aarch64_ext_sve_addr_zi_u5 (const aarch64_operand *self,
   1791   1.6  christos 			    aarch64_opnd_info *info, aarch64_insn code,
   1792   1.6  christos 			    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1793   1.6  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1794   1.6  christos {
   1795   1.6  christos   int offset = extract_field (FLD_imm5, code, 0);
   1796   1.6  christos   return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
   1797   1.6  christos }
   1798   1.6  christos 
   1799   1.6  christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
   1800   1.6  christos    where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
   1801   1.8  christos    number.  fields[0] specifies the base register field and fields[1]
   1802   1.6  christos    specifies the offset register field.  */
   1803   1.6  christos static bool
   1804   1.6  christos aarch64_ext_sve_addr_zz (const aarch64_operand *self, aarch64_opnd_info *info,
   1805   1.6  christos 			 aarch64_insn code, enum aarch64_modifier_kind kind)
   1806   1.6  christos {
   1807   1.8  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
   1808   1.8  christos   info->addr.offset.regno = extract_field (self->fields[1], code, 0);
   1809   1.8  christos   info->addr.offset.is_reg = true;
   1810   1.6  christos   info->addr.writeback = false;
   1811   1.6  christos   info->addr.preind = true;
   1812   1.6  christos   info->shifter.kind = kind;
   1813   1.6  christos   info->shifter.amount = extract_field (FLD_SVE_msz, code, 0);
   1814   1.6  christos   info->shifter.operator_present = (kind != AARCH64_MOD_LSL
   1815   1.8  christos 				    || info->shifter.amount != 0);
   1816   1.6  christos   info->shifter.amount_present = (info->shifter.amount != 0);
   1817   1.6  christos   return true;
   1818   1.6  christos }
   1819   1.6  christos 
   1820   1.6  christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
   1821   1.8  christos    <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
   1822   1.6  christos    field and fields[1] specifies the offset register field.  */
   1823   1.6  christos bool
   1824   1.6  christos aarch64_ext_sve_addr_zz_lsl (const aarch64_operand *self,
   1825   1.6  christos 			     aarch64_opnd_info *info, aarch64_insn code,
   1826   1.6  christos 			     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1827   1.6  christos 			     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1828   1.6  christos {
   1829   1.6  christos   return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_LSL);
   1830   1.6  christos }
   1831   1.6  christos 
   1832   1.6  christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
   1833   1.8  christos    <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
   1834   1.6  christos    field and fields[1] specifies the offset register field.  */
   1835   1.6  christos bool
   1836   1.6  christos aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand *self,
   1837   1.6  christos 			      aarch64_opnd_info *info, aarch64_insn code,
   1838   1.6  christos 			      const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1839   1.6  christos 			      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1840   1.6  christos {
   1841   1.6  christos   return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_SXTW);
   1842   1.6  christos }
   1843   1.6  christos 
   1844   1.6  christos /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
   1845   1.8  christos    <msz> is a 2-bit unsigned number.  fields[0] specifies the base register
   1846   1.6  christos    field and fields[1] specifies the offset register field.  */
   1847   1.6  christos bool
   1848   1.6  christos aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand *self,
   1849   1.6  christos 			      aarch64_opnd_info *info, aarch64_insn code,
   1850   1.6  christos 			      const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1851   1.6  christos 			      aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1852   1.6  christos {
   1853   1.6  christos   return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
   1854   1.6  christos }
   1855   1.6  christos 
   1856   1.8  christos /* Finish decoding an SVE arithmetic immediate, given that INFO already
   1857   1.6  christos    has the raw field value and that the low 8 bits decode to VALUE.  */
   1858   1.6  christos static bool
   1859   1.6  christos decode_sve_aimm (aarch64_opnd_info *info, int64_t value)
   1860   1.6  christos {
   1861   1.6  christos   info->shifter.kind = AARCH64_MOD_LSL;
   1862   1.6  christos   info->shifter.amount = 0;
   1863   1.6  christos   if (info->imm.value & 0x100)
   1864   1.6  christos     {
   1865   1.6  christos       if (value == 0)
   1866   1.6  christos 	/* Decode 0x100 as #0, LSL #8.  */
   1867   1.6  christos 	info->shifter.amount = 8;
   1868   1.6  christos       else
   1869   1.6  christos 	value *= 256;
   1870   1.6  christos     }
   1871   1.6  christos   info->shifter.operator_present = (info->shifter.amount != 0);
   1872   1.8  christos   info->shifter.amount_present = (info->shifter.amount != 0);
   1873   1.6  christos   info->imm.value = value;
   1874   1.6  christos   return true;
   1875   1.6  christos }
   1876   1.8  christos 
   1877   1.6  christos /* Decode an SVE ADD/SUB immediate.  */
   1878   1.6  christos bool
   1879   1.6  christos aarch64_ext_sve_aimm (const aarch64_operand *self,
   1880   1.6  christos 		      aarch64_opnd_info *info, const aarch64_insn code,
   1881   1.6  christos 		      const aarch64_inst *inst,
   1882   1.6  christos 		      aarch64_operand_error *errors)
   1883   1.6  christos {
   1884   1.6  christos   return (aarch64_ext_imm (self, info, code, inst, errors)
   1885   1.6  christos 	  && decode_sve_aimm (info, (uint8_t) info->imm.value));
   1886   1.9  christos }
   1887   1.9  christos 
   1888   1.9  christos bool
   1889   1.9  christos aarch64_ext_sve_aligned_reglist (const aarch64_operand *self,
   1890   1.9  christos 				 aarch64_opnd_info *info, aarch64_insn code,
   1891   1.9  christos 				 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1892   1.9  christos 				 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1893   1.9  christos {
   1894   1.9  christos   unsigned int num_regs = get_operand_specific_data (self);
   1895   1.9  christos   unsigned int val = extract_field (self->fields[0], code, 0);
   1896   1.9  christos   info->reglist.first_regno = val * num_regs;
   1897   1.9  christos   info->reglist.num_regs = num_regs;
   1898   1.9  christos   info->reglist.stride = 1;
   1899   1.9  christos   return true;
   1900   1.6  christos }
   1901   1.8  christos 
   1902   1.6  christos /* Decode an SVE CPY/DUP immediate.  */
   1903   1.6  christos bool
   1904   1.6  christos aarch64_ext_sve_asimm (const aarch64_operand *self,
   1905   1.6  christos 		       aarch64_opnd_info *info, const aarch64_insn code,
   1906   1.6  christos 		       const aarch64_inst *inst,
   1907   1.6  christos 		       aarch64_operand_error *errors)
   1908   1.6  christos {
   1909   1.6  christos   return (aarch64_ext_imm (self, info, code, inst, errors)
   1910   1.6  christos 	  && decode_sve_aimm (info, (int8_t) info->imm.value));
   1911   1.6  christos }
   1912   1.6  christos 
   1913   1.8  christos /* Decode a single-bit immediate that selects between #0.5 and #1.0.
   1914   1.6  christos    The fields array specifies which field to use.  */
   1915   1.6  christos bool
   1916   1.6  christos aarch64_ext_sve_float_half_one (const aarch64_operand *self,
   1917   1.6  christos 				aarch64_opnd_info *info, aarch64_insn code,
   1918   1.6  christos 				const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1919   1.6  christos 				aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1920   1.6  christos {
   1921   1.6  christos   if (extract_field (self->fields[0], code, 0))
   1922   1.6  christos     info->imm.value = 0x3f800000;
   1923   1.8  christos   else
   1924   1.8  christos     info->imm.value = 0x3f000000;
   1925   1.6  christos   info->imm.is_fp = true;
   1926   1.6  christos   return true;
   1927   1.6  christos }
   1928   1.6  christos 
   1929   1.8  christos /* Decode a single-bit immediate that selects between #0.5 and #2.0.
   1930   1.6  christos    The fields array specifies which field to use.  */
   1931   1.6  christos bool
   1932   1.6  christos aarch64_ext_sve_float_half_two (const aarch64_operand *self,
   1933   1.6  christos 				aarch64_opnd_info *info, aarch64_insn code,
   1934   1.6  christos 				const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1935   1.6  christos 				aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1936   1.6  christos {
   1937   1.6  christos   if (extract_field (self->fields[0], code, 0))
   1938   1.6  christos     info->imm.value = 0x40000000;
   1939   1.8  christos   else
   1940   1.8  christos     info->imm.value = 0x3f000000;
   1941   1.6  christos   info->imm.is_fp = true;
   1942   1.6  christos   return true;
   1943   1.6  christos }
   1944   1.6  christos 
   1945   1.8  christos /* Decode a single-bit immediate that selects between #0.0 and #1.0.
   1946   1.6  christos    The fields array specifies which field to use.  */
   1947   1.6  christos bool
   1948   1.6  christos aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
   1949   1.6  christos 				aarch64_opnd_info *info, aarch64_insn code,
   1950   1.6  christos 				const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1951   1.6  christos 				aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1952   1.6  christos {
   1953   1.6  christos   if (extract_field (self->fields[0], code, 0))
   1954   1.6  christos     info->imm.value = 0x3f800000;
   1955   1.8  christos   else
   1956   1.8  christos     info->imm.value = 0x0;
   1957   1.8  christos   info->imm.is_fp = true;
   1958   1.8  christos   return true;
   1959  1.10  christos }
   1960  1.10  christos 
   1961  1.10  christos /* Decode SME instruction such as MOVZA ZA tile slice to vector.  */
   1962  1.10  christos bool
   1963  1.10  christos aarch64_ext_sme_za_tile_to_vec (const aarch64_operand *self,
   1964  1.10  christos 				aarch64_opnd_info *info, aarch64_insn code,
   1965  1.10  christos 				const aarch64_inst *inst ATTRIBUTE_UNUSED,
   1966  1.10  christos 				aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   1967  1.10  christos {
   1968  1.10  christos   aarch64_insn Qsize;		/* fields Q:S:size.  */
   1969  1.10  christos   int fld_v = extract_field (self->fields[0], code, 0);
   1970  1.10  christos   int fld_rv = extract_field (self->fields[1], code, 0);
   1971  1.10  christos   int fld_zan_imm =  extract_field (FLD_imm4_5, code, 0);
   1972  1.10  christos 
   1973  1.10  christos   Qsize = extract_fields (inst->value, 0, 2, FLD_SME_size_22, FLD_SME_Q);
   1974  1.10  christos   switch (Qsize)
   1975  1.10  christos     {
   1976  1.10  christos     case 0x0:
   1977  1.10  christos       info->qualifier = AARCH64_OPND_QLF_S_B;
   1978  1.10  christos       info->indexed_za.regno = 0;
   1979  1.10  christos       info->indexed_za.index.imm = fld_zan_imm;
   1980  1.10  christos       break;
   1981  1.10  christos     case 0x2:
   1982  1.10  christos       info->qualifier = AARCH64_OPND_QLF_S_H;
   1983  1.10  christos       info->indexed_za.regno = fld_zan_imm >> 3;
   1984  1.10  christos       info->indexed_za.index.imm = fld_zan_imm & 0x07;
   1985  1.10  christos       break;
   1986  1.10  christos     case 0x4:
   1987  1.10  christos       info->qualifier = AARCH64_OPND_QLF_S_S;
   1988  1.10  christos       info->indexed_za.regno = fld_zan_imm >> 2;
   1989  1.10  christos       info->indexed_za.index.imm = fld_zan_imm & 0x03;
   1990  1.10  christos       break;
   1991  1.10  christos     case 0x6:
   1992  1.10  christos       info->qualifier = AARCH64_OPND_QLF_S_D;
   1993  1.10  christos       info->indexed_za.regno = fld_zan_imm >> 1;
   1994  1.10  christos       info->indexed_za.index.imm = fld_zan_imm & 0x01;
   1995  1.10  christos       break;
   1996  1.10  christos     case 0x7:
   1997  1.10  christos       info->qualifier = AARCH64_OPND_QLF_S_Q;
   1998  1.10  christos       info->indexed_za.regno = fld_zan_imm;
   1999  1.10  christos       break;
   2000  1.10  christos     default:
   2001  1.10  christos       return false;
   2002  1.10  christos     }
   2003  1.10  christos 
   2004  1.10  christos   info->indexed_za.index.regno = fld_rv + 12;
   2005  1.10  christos   info->indexed_za.v = fld_v;
   2006  1.10  christos 
   2007  1.10  christos   return true;
   2008   1.8  christos }
   2009   1.8  christos 
   2010   1.8  christos /* Decode ZA tile vector, vector indicator, vector selector, qualifier and
   2011   1.8  christos    immediate on numerous SME instruction fields such as MOVA.  */
   2012   1.8  christos bool
   2013   1.8  christos aarch64_ext_sme_za_hv_tiles (const aarch64_operand *self,
   2014   1.8  christos                              aarch64_opnd_info *info, aarch64_insn code,
   2015   1.8  christos                              const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2016   1.8  christos                              aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2017   1.8  christos {
   2018   1.8  christos   int fld_size = extract_field (self->fields[0], code, 0);
   2019   1.8  christos   int fld_q = extract_field (self->fields[1], code, 0);
   2020   1.8  christos   int fld_v = extract_field (self->fields[2], code, 0);
   2021   1.8  christos   int fld_rv = extract_field (self->fields[3], code, 0);
   2022   1.8  christos   int fld_zan_imm = extract_field (self->fields[4], code, 0);
   2023   1.8  christos 
   2024   1.9  christos   /* Deduce qualifier encoded in size and Q fields.  */
   2025   1.9  christos   if (fld_size == 0)
   2026   1.9  christos     {
   2027   1.9  christos       info->indexed_za.regno = 0;
   2028   1.8  christos       info->indexed_za.index.imm = fld_zan_imm;
   2029   1.9  christos     }
   2030   1.9  christos   else if (fld_size == 1)
   2031   1.9  christos     {
   2032   1.9  christos       info->indexed_za.regno = fld_zan_imm >> 3;
   2033   1.8  christos       info->indexed_za.index.imm = fld_zan_imm & 0x07;
   2034   1.9  christos     }
   2035   1.9  christos   else if (fld_size == 2)
   2036   1.9  christos     {
   2037   1.9  christos       info->indexed_za.regno = fld_zan_imm >> 2;
   2038   1.8  christos       info->indexed_za.index.imm = fld_zan_imm & 0x03;
   2039   1.9  christos     }
   2040   1.9  christos   else if (fld_size == 3 && fld_q == 0)
   2041   1.9  christos     {
   2042   1.9  christos       info->indexed_za.regno = fld_zan_imm >> 1;
   2043   1.8  christos       info->indexed_za.index.imm = fld_zan_imm & 0x01;
   2044   1.9  christos     }
   2045   1.9  christos   else if (fld_size == 3 && fld_q == 1)
   2046   1.9  christos     {
   2047   1.9  christos       info->indexed_za.regno = fld_zan_imm;
   2048   1.9  christos       info->indexed_za.index.imm = 0;
   2049   1.9  christos     }
   2050   1.8  christos   else
   2051   1.9  christos     return false;
   2052   1.9  christos 
   2053   1.9  christos   info->indexed_za.index.regno = fld_rv + 12;
   2054   1.9  christos   info->indexed_za.v = fld_v;
   2055   1.9  christos 
   2056   1.9  christos   return true;
   2057   1.9  christos }
   2058   1.9  christos 
   2059   1.9  christos bool
   2060   1.9  christos aarch64_ext_sme_za_hv_tiles_range (const aarch64_operand *self,
   2061   1.9  christos 				   aarch64_opnd_info *info, aarch64_insn code,
   2062   1.9  christos 				   const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2063   1.9  christos 				   aarch64_operand_error *errors
   2064   1.9  christos 				     ATTRIBUTE_UNUSED)
   2065   1.9  christos {
   2066   1.9  christos   int ebytes = aarch64_get_qualifier_esize (info->qualifier);
   2067   1.9  christos   int range_size = get_opcode_dependent_value (inst->opcode);
   2068   1.9  christos   int fld_v = extract_field (self->fields[0], code, 0);
   2069   1.9  christos   int fld_rv = extract_field (self->fields[1], code, 0);
   2070   1.8  christos   int fld_zan_imm = extract_field (self->fields[2], code, 0);
   2071   1.9  christos   int max_value = 16 / range_size / ebytes;
   2072   1.9  christos 
   2073   1.9  christos   if (max_value == 0)
   2074   1.9  christos     max_value = 1;
   2075   1.9  christos 
   2076   1.9  christos   int regno = fld_zan_imm / max_value;
   2077   1.9  christos   if (regno >= ebytes)
   2078   1.9  christos     return false;
   2079   1.9  christos 
   2080   1.9  christos   info->indexed_za.regno = regno;
   2081   1.9  christos   info->indexed_za.index.imm = (fld_zan_imm % max_value) * range_size;
   2082   1.9  christos   info->indexed_za.index.countm1 = range_size - 1;
   2083   1.8  christos   info->indexed_za.index.regno = fld_rv + 12;
   2084   1.8  christos   info->indexed_za.v = fld_v;
   2085   1.8  christos 
   2086   1.8  christos   return true;
   2087   1.8  christos }
   2088   1.8  christos 
   2089   1.8  christos /* Decode in SME instruction ZERO list of up to eight 64-bit element tile names
   2090   1.8  christos    separated by commas, encoded in the "imm8" field.
   2091   1.8  christos 
   2092   1.8  christos    For programmer convenience an assembler must also accept the names of
   2093   1.8  christos    32-bit, 16-bit and 8-bit element tiles which are converted into the
   2094   1.8  christos    corresponding set of 64-bit element tiles.
   2095   1.8  christos */
   2096   1.8  christos bool
   2097   1.8  christos aarch64_ext_sme_za_list (const aarch64_operand *self,
   2098   1.8  christos                          aarch64_opnd_info *info, aarch64_insn code,
   2099   1.8  christos                          const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2100   1.8  christos                          aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2101   1.8  christos {
   2102   1.8  christos   int mask = extract_field (self->fields[0], code, 0);
   2103   1.8  christos   info->imm.value = mask;
   2104   1.8  christos   return true;
   2105   1.8  christos }
   2106   1.9  christos 
   2107   1.8  christos /* Decode ZA array vector select register (Rv field), optional vector and
   2108   1.8  christos    memory offset (imm4_11 field).
   2109   1.8  christos */
   2110   1.8  christos bool
   2111   1.9  christos aarch64_ext_sme_za_array (const aarch64_operand *self,
   2112   1.8  christos                           aarch64_opnd_info *info, aarch64_insn code,
   2113   1.8  christos                           const aarch64_inst *inst,
   2114   1.9  christos                           aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2115   1.9  christos {
   2116   1.9  christos   int regno = extract_field (self->fields[0], code, 0);
   2117   1.9  christos   if (info->type == AARCH64_OPND_SME_ZA_array_off4)
   2118   1.9  christos     regno += 12;
   2119   1.8  christos   else
   2120   1.9  christos     regno += 8;
   2121   1.9  christos   int imm = extract_field (self->fields[1], code, 0);
   2122   1.9  christos   int num_offsets = get_operand_specific_data (self);
   2123   1.9  christos   if (num_offsets == 0)
   2124   1.9  christos     num_offsets = 1;
   2125   1.9  christos   info->indexed_za.index.regno = regno;
   2126   1.9  christos   info->indexed_za.index.imm = imm * num_offsets;
   2127   1.9  christos   info->indexed_za.index.countm1 = num_offsets - 1;
   2128   1.9  christos   info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
   2129   1.9  christos   return true;
   2130   1.9  christos }
   2131   1.9  christos 
   2132   1.9  christos /* Decode two ZA tile slice (V, Rv, off3| ZAn ,off2 | ZAn, ol| ZAn) feilds.  */
   2133   1.9  christos bool
   2134   1.9  christos aarch64_ext_sme_za_vrs1 (const aarch64_operand *self,
   2135   1.9  christos 			  aarch64_opnd_info *info, aarch64_insn code,
   2136   1.9  christos 			  const aarch64_inst *inst,
   2137   1.9  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2138   1.9  christos {
   2139   1.9  christos   int v = extract_field (self->fields[0], code, 0);
   2140   1.9  christos   int regno = 12 + extract_field (self->fields[1], code, 0);
   2141   1.9  christos   int imm, za_reg, num_offset = 2;
   2142   1.9  christos 
   2143   1.9  christos   switch (info->qualifier)
   2144   1.9  christos     {
   2145   1.9  christos     case AARCH64_OPND_QLF_S_B:
   2146   1.9  christos       imm = extract_field (self->fields[2], code, 0);
   2147   1.9  christos       info->indexed_za.index.imm = imm * num_offset;
   2148   1.9  christos       break;
   2149   1.9  christos     case AARCH64_OPND_QLF_S_H:
   2150   1.9  christos     case AARCH64_OPND_QLF_S_S:
   2151   1.9  christos       za_reg = extract_field (self->fields[2], code, 0);
   2152   1.9  christos       imm = extract_field (self->fields[3], code, 0);
   2153   1.9  christos       info->indexed_za.index.imm = imm * num_offset;
   2154   1.9  christos       info->indexed_za.regno = za_reg;
   2155   1.9  christos       break;
   2156   1.9  christos     case AARCH64_OPND_QLF_S_D:
   2157   1.9  christos       za_reg = extract_field (self->fields[2], code, 0);
   2158   1.9  christos       info->indexed_za.regno = za_reg;
   2159   1.9  christos       break;
   2160   1.9  christos     default:
   2161   1.9  christos       return false;
   2162   1.9  christos     }
   2163   1.9  christos 
   2164   1.9  christos   info->indexed_za.index.regno = regno;
   2165   1.9  christos   info->indexed_za.index.countm1 = num_offset - 1;
   2166   1.9  christos   info->indexed_za.v = v;
   2167   1.9  christos   info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
   2168   1.9  christos   return true;
   2169   1.9  christos }
   2170   1.9  christos 
   2171   1.9  christos /* Decode four ZA tile slice (V, Rv, off3| ZAn ,off2 | ZAn, ol| ZAn) feilds.  */
   2172   1.9  christos bool
   2173   1.9  christos aarch64_ext_sme_za_vrs2 (const aarch64_operand *self,
   2174   1.9  christos 			  aarch64_opnd_info *info, aarch64_insn code,
   2175   1.9  christos 			  const aarch64_inst *inst,
   2176   1.9  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2177   1.9  christos {
   2178   1.9  christos   int v = extract_field (self->fields[0], code, 0);
   2179   1.9  christos   int regno = 12 + extract_field (self->fields[1], code, 0);
   2180   1.9  christos   int imm, za_reg, num_offset =4;
   2181   1.9  christos 
   2182   1.9  christos   switch (info->qualifier)
   2183   1.9  christos     {
   2184   1.9  christos     case AARCH64_OPND_QLF_S_B:
   2185   1.9  christos       imm = extract_field (self->fields[2], code, 0);
   2186   1.9  christos       info->indexed_za.index.imm = imm * num_offset;
   2187   1.9  christos       break;
   2188   1.9  christos     case AARCH64_OPND_QLF_S_H:
   2189   1.9  christos       za_reg = extract_field (self->fields[2], code, 0);
   2190   1.9  christos       imm = extract_field (self->fields[3], code, 0);
   2191   1.9  christos       info->indexed_za.index.imm = imm * num_offset;
   2192   1.9  christos       info->indexed_za.regno = za_reg;
   2193   1.9  christos       break;
   2194   1.9  christos     case AARCH64_OPND_QLF_S_S:
   2195   1.9  christos     case AARCH64_OPND_QLF_S_D:
   2196   1.9  christos       za_reg = extract_field (self->fields[2], code, 0);
   2197   1.9  christos       info->indexed_za.regno = za_reg;
   2198   1.9  christos       break;
   2199   1.9  christos     default:
   2200   1.9  christos       return false;
   2201   1.9  christos     }
   2202   1.9  christos 
   2203   1.9  christos   info->indexed_za.index.regno = regno;
   2204   1.9  christos   info->indexed_za.index.countm1 = num_offset - 1;
   2205   1.8  christos   info->indexed_za.v = v;
   2206   1.8  christos   info->indexed_za.group_size = get_opcode_dependent_value (inst->opcode);
   2207   1.8  christos   return true;
   2208   1.8  christos }
   2209   1.8  christos 
   2210   1.8  christos bool
   2211   1.8  christos aarch64_ext_sme_addr_ri_u4xvl (const aarch64_operand *self,
   2212   1.8  christos                                aarch64_opnd_info *info, aarch64_insn code,
   2213   1.8  christos                                const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2214   1.8  christos                                aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2215   1.8  christos {
   2216   1.8  christos   int regno = extract_field (self->fields[0], code, 0);
   2217   1.8  christos   int imm = extract_field (self->fields[1], code, 0);
   2218   1.8  christos   info->addr.base_regno = regno;
   2219   1.8  christos   info->addr.offset.imm = imm;
   2220   1.8  christos   /* MUL VL operator is always present for this operand.  */
   2221   1.8  christos   info->shifter.kind = AARCH64_MOD_MUL_VL;
   2222   1.8  christos   info->shifter.operator_present = (imm != 0);
   2223   1.8  christos   return true;
   2224   1.8  christos }
   2225   1.8  christos 
   2226   1.8  christos /* Decode {SM|ZA} filed for SMSTART and SMSTOP instructions.  */
   2227   1.8  christos bool
   2228   1.8  christos aarch64_ext_sme_sm_za (const aarch64_operand *self,
   2229   1.8  christos                        aarch64_opnd_info *info, aarch64_insn code,
   2230   1.8  christos                        const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2231   1.8  christos                        aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2232   1.8  christos {
   2233   1.8  christos   info->pstatefield = 0x1b;
   2234   1.8  christos   aarch64_insn fld_crm = extract_field (self->fields[0], code, 0);
   2235   1.8  christos   fld_crm >>= 1;    /* CRm[3:1].  */
   2236   1.8  christos 
   2237   1.8  christos   if (fld_crm == 0x1)
   2238   1.8  christos     info->reg.regno = 's';
   2239   1.8  christos   else if (fld_crm == 0x2)
   2240   1.8  christos     info->reg.regno = 'z';
   2241   1.8  christos   else
   2242   1.8  christos     return false;
   2243   1.8  christos 
   2244   1.8  christos   return true;
   2245   1.8  christos }
   2246   1.8  christos 
   2247   1.8  christos bool
   2248   1.8  christos aarch64_ext_sme_pred_reg_with_index (const aarch64_operand *self,
   2249   1.8  christos 				     aarch64_opnd_info *info, aarch64_insn code,
   2250   1.8  christos 				     const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2251   1.8  christos 				     aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2252   1.8  christos {
   2253   1.8  christos   aarch64_insn fld_rm = extract_field (self->fields[0], code, 0);
   2254   1.8  christos   aarch64_insn fld_pn = extract_field (self->fields[1], code, 0);
   2255   1.8  christos   aarch64_insn fld_i1 = extract_field (self->fields[2], code, 0);
   2256   1.8  christos   aarch64_insn fld_tszh = extract_field (self->fields[3], code, 0);
   2257   1.8  christos   aarch64_insn fld_tszl = extract_field (self->fields[4], code, 0);
   2258   1.9  christos   int imm;
   2259   1.9  christos 
   2260   1.8  christos   info->indexed_za.regno = fld_pn;
   2261   1.9  christos   info->indexed_za.index.regno = fld_rm + 12;
   2262   1.9  christos 
   2263   1.9  christos   if (fld_tszl & 0x1)
   2264   1.9  christos     imm = (fld_i1 << 3) | (fld_tszh << 2) | (fld_tszl >> 1);
   2265   1.9  christos   else if (fld_tszl & 0x2)
   2266   1.9  christos     imm = (fld_i1 << 2) | (fld_tszh << 1) | (fld_tszl >> 2);
   2267   1.9  christos   else if (fld_tszl & 0x4)
   2268   1.9  christos     imm = (fld_i1 << 1) | fld_tszh;
   2269   1.8  christos   else if (fld_tszh)
   2270   1.8  christos     imm = fld_i1;
   2271   1.8  christos   else
   2272   1.9  christos     return false;
   2273   1.8  christos 
   2274   1.6  christos   info->indexed_za.index.imm = imm;
   2275   1.6  christos   return true;
   2276   1.6  christos }
   2277   1.6  christos 
   2278   1.6  christos /* Decode Zn[MM], where MM has a 7-bit triangular encoding.  The fields
   2279   1.6  christos    array specifies which field to use for Zn.  MM is encoded in the
   2280   1.8  christos    concatenation of imm5 and SVE_tszh, with imm5 being the less
   2281   1.6  christos    significant part.  */
   2282   1.6  christos bool
   2283   1.6  christos aarch64_ext_sve_index (const aarch64_operand *self,
   2284   1.6  christos 		       aarch64_opnd_info *info, aarch64_insn code,
   2285   1.6  christos 		       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2286   1.6  christos 		       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2287   1.6  christos {
   2288   1.6  christos   int val;
   2289  1.10  christos 
   2290   1.6  christos   info->reglane.regno = extract_field (self->fields[0], code, 0);
   2291   1.6  christos   val = extract_all_fields_after (self, 1, code);
   2292   1.6  christos   if ((val & 31) == 0)
   2293   1.6  christos     return 0;
   2294   1.6  christos   while ((val & 1) == 0)
   2295   1.8  christos     val /= 2;
   2296   1.6  christos   info->reglane.index = val / 2;
   2297   1.6  christos   return true;
   2298   1.6  christos }
   2299   1.8  christos 
   2300   1.6  christos /* Decode a logical immediate for the MOV alias of SVE DUPM.  */
   2301   1.6  christos bool
   2302   1.6  christos aarch64_ext_sve_limm_mov (const aarch64_operand *self,
   2303   1.6  christos 			  aarch64_opnd_info *info, const aarch64_insn code,
   2304   1.6  christos 			  const aarch64_inst *inst,
   2305   1.6  christos 			  aarch64_operand_error *errors)
   2306   1.6  christos {
   2307   1.6  christos   int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
   2308   1.6  christos   return (aarch64_ext_limm (self, info, code, inst, errors)
   2309   1.6  christos 	  && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
   2310   1.6  christos }
   2311   1.6  christos 
   2312   1.6  christos /* Decode Zn[MM], where Zn occupies the least-significant part of the field
   2313   1.8  christos    and where MM occupies the most-significant part.  The operand-dependent
   2314   1.6  christos    value specifies the number of bits in Zn.  */
   2315   1.6  christos bool
   2316   1.6  christos aarch64_ext_sve_quad_index (const aarch64_operand *self,
   2317   1.6  christos 			    aarch64_opnd_info *info, aarch64_insn code,
   2318   1.6  christos 			    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2319   1.6  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2320   1.6  christos {
   2321   1.6  christos   unsigned int reg_bits = get_operand_specific_data (self);
   2322   1.6  christos   unsigned int val = extract_all_fields (self, code);
   2323   1.8  christos   info->reglane.regno = val & ((1 << reg_bits) - 1);
   2324   1.6  christos   info->reglane.index = val >> reg_bits;
   2325   1.6  christos   return true;
   2326   1.6  christos }
   2327   1.6  christos 
   2328   1.6  christos /* Decode {Zn.<T> - Zm.<T>}.  The fields array specifies which field
   2329   1.8  christos    to use for Zn.  The opcode-dependent value specifies the number
   2330   1.6  christos    of registers in the list.  */
   2331   1.6  christos bool
   2332   1.6  christos aarch64_ext_sve_reglist (const aarch64_operand *self,
   2333   1.6  christos 			 aarch64_opnd_info *info, aarch64_insn code,
   2334   1.6  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2335   1.6  christos 			 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2336   1.6  christos {
   2337   1.9  christos   info->reglist.first_regno = extract_field (self->fields[0], code, 0);
   2338   1.9  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
   2339   1.9  christos   info->reglist.stride = 1;
   2340   1.9  christos   return true;
   2341   1.9  christos }
   2342   1.9  christos 
   2343   1.9  christos /* Decode {Zn.<T> , Zm.<T>}.  The fields array specifies which field
   2344   1.9  christos    to use for Zn.  The opcode-dependent value specifies the number
   2345   1.9  christos    of registers in the list.  */
   2346   1.9  christos bool
   2347   1.9  christos aarch64_ext_sve_reglist_zt (const aarch64_operand *self,
   2348   1.9  christos 			    aarch64_opnd_info *info, aarch64_insn code,
   2349   1.9  christos 			    const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2350   1.9  christos 			    aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2351   1.9  christos {
   2352   1.9  christos   info->reglist.first_regno = extract_field (self->fields[0], code, 0);
   2353   1.9  christos   info->reglist.num_regs = get_operand_specific_data (self);
   2354   1.9  christos   info->reglist.stride = 1;
   2355   1.9  christos   return true;
   2356   1.9  christos }
   2357   1.9  christos 
   2358   1.9  christos /* Decode a strided register list.  The first field holds the top bit
   2359   1.9  christos    (0 or 16) and the second field holds the lower bits.  The stride is
   2360   1.9  christos    16 divided by the list length.  */
   2361   1.9  christos bool
   2362   1.9  christos aarch64_ext_sve_strided_reglist (const aarch64_operand *self,
   2363   1.9  christos 				 aarch64_opnd_info *info, aarch64_insn code,
   2364   1.9  christos 				 const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2365   1.9  christos 				 aarch64_operand_error *errors
   2366   1.9  christos 				   ATTRIBUTE_UNUSED)
   2367   1.9  christos {
   2368   1.9  christos   unsigned int upper = extract_field (self->fields[0], code, 0);
   2369   1.9  christos   unsigned int lower = extract_field (self->fields[1], code, 0);
   2370   1.9  christos   info->reglist.first_regno = upper * 16 + lower;
   2371   1.8  christos   info->reglist.num_regs = get_operand_specific_data (self);
   2372   1.6  christos   info->reglist.stride = 16 / info->reglist.num_regs;
   2373   1.6  christos   return true;
   2374   1.6  christos }
   2375   1.6  christos 
   2376   1.6  christos /* Decode <pattern>{, MUL #<amount>}.  The fields array specifies which
   2377   1.8  christos    fields to use for <pattern>.  <amount> - 1 is encoded in the SVE_imm4
   2378   1.6  christos    field.  */
   2379   1.6  christos bool
   2380   1.6  christos aarch64_ext_sve_scale (const aarch64_operand *self,
   2381   1.6  christos 		       aarch64_opnd_info *info, aarch64_insn code,
   2382   1.6  christos 		       const aarch64_inst *inst, aarch64_operand_error *errors)
   2383   1.6  christos {
   2384   1.6  christos   int val;
   2385   1.8  christos 
   2386   1.6  christos   if (!aarch64_ext_imm (self, info, code, inst, errors))
   2387   1.6  christos     return false;
   2388   1.6  christos   val = extract_field (FLD_SVE_imm4, code, 0);
   2389   1.6  christos   info->shifter.kind = AARCH64_MOD_MUL;
   2390   1.6  christos   info->shifter.amount = val + 1;
   2391   1.8  christos   info->shifter.operator_present = (val != 0);
   2392   1.6  christos   info->shifter.amount_present = (val != 0);
   2393   1.6  christos   return true;
   2394   1.6  christos }
   2395   1.6  christos 
   2396   1.6  christos /* Return the top set bit in VALUE, which is expected to be relatively
   2397   1.6  christos    small.  */
   2398   1.6  christos static uint64_t
   2399   1.6  christos get_top_bit (uint64_t value)
   2400   1.6  christos {
   2401   1.6  christos   while ((value & -value) != value)
   2402   1.6  christos     value -= value & -value;
   2403   1.6  christos   return value;
   2404   1.6  christos }
   2405   1.8  christos 
   2406   1.6  christos /* Decode an SVE shift-left immediate.  */
   2407   1.6  christos bool
   2408   1.6  christos aarch64_ext_sve_shlimm (const aarch64_operand *self,
   2409   1.6  christos 			aarch64_opnd_info *info, const aarch64_insn code,
   2410   1.6  christos 			const aarch64_inst *inst, aarch64_operand_error *errors)
   2411   1.6  christos {
   2412   1.8  christos   if (!aarch64_ext_imm (self, info, code, inst, errors)
   2413   1.6  christos       || info->imm.value == 0)
   2414   1.6  christos     return false;
   2415   1.8  christos 
   2416   1.6  christos   info->imm.value -= get_top_bit (info->imm.value);
   2417   1.6  christos   return true;
   2418   1.6  christos }
   2419   1.8  christos 
   2420   1.6  christos /* Decode an SVE shift-right immediate.  */
   2421   1.6  christos bool
   2422   1.6  christos aarch64_ext_sve_shrimm (const aarch64_operand *self,
   2423   1.6  christos 			aarch64_opnd_info *info, const aarch64_insn code,
   2424   1.6  christos 			const aarch64_inst *inst, aarch64_operand_error *errors)
   2425   1.6  christos {
   2426   1.8  christos   if (!aarch64_ext_imm (self, info, code, inst, errors)
   2427   1.6  christos       || info->imm.value == 0)
   2428   1.6  christos     return false;
   2429   1.8  christos 
   2430   1.8  christos   info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
   2431   1.8  christos   return true;
   2432   1.8  christos }
   2433   1.8  christos 
   2434   1.8  christos /* Decode X0-X30.  Register 31 is unallocated.  */
   2435   1.8  christos bool
   2436   1.8  christos aarch64_ext_x0_to_x30 (const aarch64_operand *self, aarch64_opnd_info *info,
   2437   1.8  christos 		       const aarch64_insn code,
   2438   1.8  christos 		       const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2439   1.8  christos 		       aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2440   1.8  christos {
   2441   1.1  christos   info->reg.regno = extract_field (self->fields[0], code, 0);
   2442   1.9  christos   return info->reg.regno <= 30;
   2443   1.9  christos }
   2444   1.9  christos 
   2445   1.9  christos /* Decode an indexed register, with the first field being the register
   2446   1.9  christos    number and the remaining fields being the index.  */
   2447   1.9  christos bool
   2448   1.9  christos aarch64_ext_simple_index (const aarch64_operand *self, aarch64_opnd_info *info,
   2449   1.9  christos 			  const aarch64_insn code,
   2450   1.9  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2451   1.9  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2452   1.9  christos {
   2453   1.9  christos   int bias = get_operand_specific_data (self);
   2454   1.9  christos   info->reglane.regno = extract_field (self->fields[0], code, 0) + bias;
   2455   1.9  christos   info->reglane.index = extract_all_fields_after (self, 1, code);
   2456   1.9  christos   return true;
   2457   1.9  christos }
   2458   1.9  christos 
   2459   1.9  christos /* Decode a plain shift-right immediate, when there is only a single
   2460   1.9  christos    element size.  */
   2461   1.9  christos bool
   2462   1.9  christos aarch64_ext_plain_shrimm (const aarch64_operand *self, aarch64_opnd_info *info,
   2463   1.9  christos 			  const aarch64_insn code,
   2464   1.9  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED,
   2465   1.9  christos 			  aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   2466   1.9  christos {
   2467   1.9  christos   unsigned int base = 1 << get_operand_field_width (self, 0);
   2468   1.9  christos   info->imm.value = base - extract_field (self->fields[0], code, 0);
   2469   1.1  christos   return true;
   2470   1.1  christos }
   2471   1.1  christos 
   2472   1.1  christos /* Bitfields that are commonly used to encode certain operands' information
   2474   1.1  christos    may be partially used as part of the base opcode in some instructions.
   2475   1.1  christos    For example, the bit 1 of the field 'size' in
   2476   1.1  christos      FCVTXN <Vb><d>, <Va><n>
   2477   1.1  christos    is actually part of the base opcode, while only size<0> is available
   2478   1.1  christos    for encoding the register type.  Another example is the AdvSIMD
   2479   1.1  christos    instruction ORR (register), in which the field 'size' is also used for
   2480   1.1  christos    the base opcode, leaving only the field 'Q' available to encode the
   2481   1.1  christos    vector register arrangement specifier '8B' or '16B'.
   2482   1.1  christos 
   2483   1.1  christos    This function tries to deduce the qualifier from the value of partially
   2484   1.1  christos    constrained field(s).  Given the VALUE of such a field or fields, the
   2485   1.1  christos    qualifiers CANDIDATES and the MASK (indicating which bits are valid for
   2486   1.1  christos    operand encoding), the function returns the matching qualifier or
   2487   1.1  christos    AARCH64_OPND_QLF_NIL if nothing matches.
   2488   1.1  christos 
   2489   1.1  christos    N.B. CANDIDATES is a group of possible qualifiers that are valid for
   2490   1.1  christos    one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
   2491   1.1  christos    may end with AARCH64_OPND_QLF_NIL.  */
   2492   1.1  christos 
   2493   1.1  christos static enum aarch64_opnd_qualifier
   2494   1.1  christos get_qualifier_from_partial_encoding (aarch64_insn value,
   2495   1.1  christos 				     const enum aarch64_opnd_qualifier* \
   2496   1.1  christos 				     candidates,
   2497   1.1  christos 				     aarch64_insn mask)
   2498   1.1  christos {
   2499   1.1  christos   int i;
   2500   1.1  christos   DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
   2501   1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   2502   1.1  christos     {
   2503   1.1  christos       aarch64_insn standard_value;
   2504   1.1  christos       if (candidates[i] == AARCH64_OPND_QLF_NIL)
   2505   1.1  christos 	break;
   2506   1.1  christos       standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
   2507   1.1  christos       if ((standard_value & mask) == (value & mask))
   2508   1.1  christos 	return candidates[i];
   2509   1.1  christos     }
   2510   1.1  christos   return AARCH64_OPND_QLF_NIL;
   2511   1.1  christos }
   2512   1.1  christos 
   2513   1.1  christos /* Given a list of qualifier sequences, return all possible valid qualifiers
   2514   1.1  christos    for operand IDX in QUALIFIERS.
   2515   1.1  christos    Assume QUALIFIERS is an array whose length is large enough.  */
   2516   1.1  christos 
   2517   1.1  christos static void
   2518   1.1  christos get_operand_possible_qualifiers (int idx,
   2519   1.1  christos 				 const aarch64_opnd_qualifier_seq_t *list,
   2520   1.1  christos 				 enum aarch64_opnd_qualifier *qualifiers)
   2521   1.1  christos {
   2522   1.1  christos   int i;
   2523   1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   2524   1.1  christos     if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
   2525   1.1  christos       break;
   2526   1.1  christos }
   2527   1.1  christos 
   2528   1.1  christos /* Decode the size Q field for e.g. SHADD.
   2529   1.1  christos    We tag one operand with the qualifer according to the code;
   2530   1.1  christos    whether the qualifier is valid for this opcode or not, it is the
   2531   1.1  christos    duty of the semantic checking.  */
   2532   1.1  christos 
   2533   1.1  christos static int
   2534   1.1  christos decode_sizeq (aarch64_inst *inst)
   2535   1.1  christos {
   2536   1.1  christos   int idx;
   2537   1.1  christos   enum aarch64_opnd_qualifier qualifier;
   2538   1.1  christos   aarch64_insn code;
   2539   1.1  christos   aarch64_insn value, mask;
   2540   1.1  christos   enum aarch64_field_kind fld_sz;
   2541   1.1  christos   enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
   2542   1.1  christos 
   2543   1.1  christos   if (inst->opcode->iclass == asisdlse
   2544   1.1  christos      || inst->opcode->iclass == asisdlsep
   2545   1.1  christos      || inst->opcode->iclass == asisdlso
   2546   1.1  christos      || inst->opcode->iclass == asisdlsop)
   2547   1.1  christos     fld_sz = FLD_vldst_size;
   2548   1.1  christos   else
   2549   1.1  christos     fld_sz = FLD_size;
   2550   1.1  christos 
   2551   1.1  christos   code = inst->value;
   2552   1.1  christos   value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
   2553   1.1  christos   /* Obtain the info that which bits of fields Q and size are actually
   2554   1.1  christos      available for operand encoding.  Opcodes like FMAXNM and FMLA have
   2555   1.1  christos      size[1] unavailable.  */
   2556   1.1  christos   mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
   2557   1.1  christos 
   2558   1.1  christos   /* The index of the operand we are going to tag a qualifier and the qualifer
   2559   1.1  christos      itself are reasoned from the value of the size and Q fields and the
   2560   1.1  christos      possible valid qualifier lists.  */
   2561   1.1  christos   idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
   2562   1.1  christos   DEBUG_TRACE ("key idx: %d", idx);
   2563   1.1  christos 
   2564   1.1  christos   /* For most related instruciton, size:Q are fully available for operand
   2565   1.1  christos      encoding.  */
   2566  1.10  christos   if (mask == 0x7)
   2567  1.10  christos     {
   2568   1.1  christos       inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
   2569   1.1  christos       if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
   2570   1.1  christos 	return 0;
   2571   1.1  christos       return 1;
   2572   1.1  christos     }
   2573   1.1  christos 
   2574   1.1  christos   get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
   2575   1.1  christos 				   candidates);
   2576   1.1  christos #ifdef DEBUG_AARCH64
   2577   1.1  christos   if (debug_dump)
   2578   1.1  christos     {
   2579   1.1  christos       int i;
   2580   1.1  christos       for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
   2581   1.1  christos 	   && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   2582   1.1  christos 	DEBUG_TRACE ("qualifier %d: %s", i,
   2583   1.1  christos 		     aarch64_get_qualifier_name(candidates[i]));
   2584   1.1  christos       DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
   2585   1.1  christos     }
   2586   1.1  christos #endif /* DEBUG_AARCH64 */
   2587   1.1  christos 
   2588   1.1  christos   qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
   2589   1.1  christos 
   2590   1.1  christos   if (qualifier == AARCH64_OPND_QLF_NIL)
   2591   1.1  christos     return 0;
   2592   1.1  christos 
   2593   1.1  christos   inst->operands[idx].qualifier = qualifier;
   2594   1.1  christos   return 1;
   2595   1.1  christos }
   2596   1.1  christos 
   2597   1.1  christos /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
   2598   1.1  christos      e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
   2599   1.1  christos 
   2600   1.1  christos static int
   2601   1.1  christos decode_asimd_fcvt (aarch64_inst *inst)
   2602   1.1  christos {
   2603   1.1  christos   aarch64_field field = {0, 0};
   2604   1.1  christos   aarch64_insn value;
   2605   1.1  christos   enum aarch64_opnd_qualifier qualifier;
   2606   1.1  christos 
   2607   1.1  christos   gen_sub_field (FLD_size, 0, 1, &field);
   2608   1.1  christos   value = extract_field_2 (&field, inst->value, 0);
   2609   1.1  christos   qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
   2610   1.1  christos     : AARCH64_OPND_QLF_V_2D;
   2611   1.1  christos   switch (inst->opcode->op)
   2612   1.1  christos     {
   2613   1.1  christos     case OP_FCVTN:
   2614   1.1  christos     case OP_FCVTN2:
   2615   1.1  christos       /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
   2616   1.1  christos       inst->operands[1].qualifier = qualifier;
   2617   1.1  christos       break;
   2618   1.1  christos     case OP_FCVTL:
   2619   1.1  christos     case OP_FCVTL2:
   2620   1.1  christos       /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>.  */
   2621   1.1  christos       inst->operands[0].qualifier = qualifier;
   2622   1.1  christos       break;
   2623   1.1  christos     default:
   2624   1.1  christos       return 0;
   2625   1.1  christos     }
   2626   1.1  christos 
   2627   1.1  christos   return 1;
   2628   1.1  christos }
   2629   1.1  christos 
   2630   1.1  christos /* Decode size[0], i.e. bit 22, for
   2631   1.1  christos      e.g. FCVTXN <Vb><d>, <Va><n>.  */
   2632   1.1  christos 
   2633   1.1  christos static int
   2634   1.1  christos decode_asisd_fcvtxn (aarch64_inst *inst)
   2635   1.1  christos {
   2636   1.1  christos   aarch64_field field = {0, 0};
   2637   1.1  christos   gen_sub_field (FLD_size, 0, 1, &field);
   2638   1.1  christos   if (!extract_field_2 (&field, inst->value, 0))
   2639   1.1  christos     return 0;
   2640   1.1  christos   inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
   2641   1.1  christos   return 1;
   2642   1.1  christos }
   2643   1.1  christos 
   2644   1.1  christos /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>.  */
   2645   1.1  christos static int
   2646   1.1  christos decode_fcvt (aarch64_inst *inst)
   2647   1.1  christos {
   2648   1.1  christos   enum aarch64_opnd_qualifier qualifier;
   2649   1.1  christos   aarch64_insn value;
   2650   1.1  christos   const aarch64_field field = {15, 2};
   2651   1.1  christos 
   2652   1.1  christos   /* opc dstsize */
   2653   1.1  christos   value = extract_field_2 (&field, inst->value, 0);
   2654   1.1  christos   switch (value)
   2655   1.1  christos     {
   2656   1.1  christos     case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
   2657   1.1  christos     case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
   2658   1.1  christos     case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
   2659   1.1  christos     default: return 0;
   2660   1.1  christos     }
   2661   1.1  christos   inst->operands[0].qualifier = qualifier;
   2662   1.1  christos 
   2663   1.1  christos   return 1;
   2664   1.1  christos }
   2665   1.1  christos 
   2666   1.1  christos /* Do miscellaneous decodings that are not common enough to be driven by
   2667   1.1  christos    flags.  */
   2668   1.1  christos 
   2669   1.6  christos static int
   2670   1.1  christos do_misc_decoding (aarch64_inst *inst)
   2671   1.1  christos {
   2672   1.1  christos   unsigned int value;
   2673   1.1  christos   switch (inst->opcode->op)
   2674   1.6  christos     {
   2675   1.1  christos     case OP_FCVT:
   2676   1.1  christos       return decode_fcvt (inst);
   2677   1.1  christos 
   2678   1.1  christos     case OP_FCVTN:
   2679   1.1  christos     case OP_FCVTN2:
   2680   1.6  christos     case OP_FCVTL:
   2681   1.1  christos     case OP_FCVTL2:
   2682   1.1  christos       return decode_asimd_fcvt (inst);
   2683   1.6  christos 
   2684   1.6  christos     case OP_FCVTXN_S:
   2685   1.6  christos       return decode_asisd_fcvtxn (inst);
   2686   1.6  christos 
   2687   1.6  christos     case OP_MOV_P_P:
   2688   1.6  christos     case OP_MOVS_P_P:
   2689   1.6  christos       value = extract_field (FLD_SVE_Pn, inst->value, 0);
   2690   1.6  christos       return (value == extract_field (FLD_SVE_Pm, inst->value, 0)
   2691   1.6  christos 	      && value == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
   2692   1.6  christos 
   2693   1.6  christos     case OP_MOV_Z_P_Z:
   2694   1.6  christos       return (extract_field (FLD_SVE_Zd, inst->value, 0)
   2695   1.6  christos 	      == extract_field (FLD_SVE_Zm_16, inst->value, 0));
   2696   1.6  christos 
   2697   1.6  christos     case OP_MOV_Z_V:
   2698   1.6  christos       /* Index must be zero.  */
   2699   1.6  christos       value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
   2700   1.6  christos       return value > 0 && value <= 16 && value == (value & -value);
   2701   1.6  christos 
   2702   1.6  christos     case OP_MOV_Z_Z:
   2703   1.6  christos       return (extract_field (FLD_SVE_Zn, inst->value, 0)
   2704   1.6  christos 	      == extract_field (FLD_SVE_Zm_16, inst->value, 0));
   2705   1.6  christos 
   2706   1.6  christos     case OP_MOV_Z_Zi:
   2707   1.6  christos       /* Index must be nonzero.  */
   2708   1.6  christos       value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
   2709   1.6  christos       return value > 0 && value != (value & -value);
   2710   1.6  christos 
   2711   1.6  christos     case OP_MOVM_P_P_P:
   2712   1.6  christos       return (extract_field (FLD_SVE_Pd, inst->value, 0)
   2713   1.6  christos 	      == extract_field (FLD_SVE_Pm, inst->value, 0));
   2714   1.6  christos 
   2715   1.6  christos     case OP_MOVZS_P_P_P:
   2716   1.6  christos     case OP_MOVZ_P_P_P:
   2717   1.6  christos       return (extract_field (FLD_SVE_Pn, inst->value, 0)
   2718   1.6  christos 	      == extract_field (FLD_SVE_Pm, inst->value, 0));
   2719   1.6  christos 
   2720   1.6  christos     case OP_NOTS_P_P_P_Z:
   2721   1.6  christos     case OP_NOT_P_P_P_Z:
   2722   1.1  christos       return (extract_field (FLD_SVE_Pm, inst->value, 0)
   2723   1.1  christos 	      == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
   2724   1.1  christos 
   2725   1.1  christos     default:
   2726   1.1  christos       return 0;
   2727   1.1  christos     }
   2728   1.1  christos }
   2729   1.1  christos 
   2730   1.1  christos /* Opcodes that have fields shared by multiple operands are usually flagged
   2731   1.1  christos    with flags.  In this function, we detect such flags, decode the related
   2732   1.1  christos    field(s) and store the information in one of the related operands.  The
   2733   1.1  christos    'one' operand is not any operand but one of the operands that can
   2734   1.1  christos    accommadate all the information that has been decoded.  */
   2735   1.1  christos 
   2736   1.1  christos static int
   2737   1.1  christos do_special_decoding (aarch64_inst *inst)
   2738   1.1  christos {
   2739   1.1  christos   int idx;
   2740   1.1  christos   aarch64_insn value;
   2741   1.1  christos   /* Condition for truly conditional executed instructions, e.g. b.cond.  */
   2742   1.1  christos   if (inst->opcode->flags & F_COND)
   2743   1.1  christos     {
   2744   1.1  christos       value = extract_field (FLD_cond2, inst->value, 0);
   2745   1.1  christos       inst->cond = get_cond_from_value (value);
   2746   1.1  christos     }
   2747   1.1  christos   /* 'sf' field.  */
   2748   1.1  christos   if (inst->opcode->flags & F_SF)
   2749  1.10  christos     {
   2750  1.10  christos       idx = select_operand_for_sf_field_coding (inst->opcode);
   2751  1.10  christos       value = extract_field (FLD_sf, inst->value, 0);
   2752  1.10  christos       if (inst->opcode->iclass == fprcvtfloat2int
   2753  1.10  christos 	  || inst->opcode->iclass == fprcvtint2float)
   2754  1.10  christos 	{
   2755  1.10  christos 	  if (value == 0)
   2756  1.10  christos 	    inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S;
   2757  1.10  christos 	  else
   2758  1.10  christos 	    inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D;
   2759  1.10  christos 	}
   2760  1.10  christos       else
   2761   1.1  christos 	inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   2762   1.1  christos       if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
   2763   1.1  christos 	return 0;
   2764   1.1  christos       if ((inst->opcode->flags & F_N)
   2765   1.3  christos 	  && extract_field (FLD_N, inst->value, 0) != value)
   2766   1.3  christos 	return 0;
   2767   1.3  christos     }
   2768   1.3  christos   /* 'sf' field.  */
   2769   1.3  christos   if (inst->opcode->flags & F_LSE_SZ)
   2770   1.3  christos     {
   2771  1.10  christos       idx = select_operand_for_sf_field_coding (inst->opcode);
   2772  1.10  christos       value = extract_field (FLD_lse_sz, inst->value, 0);
   2773   1.3  christos       inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   2774   1.9  christos       if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
   2775   1.9  christos 	return 0;
   2776   1.9  christos     }
   2777   1.9  christos   /* rcpc3 'size' field.  */
   2778   1.9  christos   if (inst->opcode->flags & F_RCPC3_SIZE)
   2779   1.9  christos     {
   2780   1.9  christos       value = extract_field (FLD_rcpc3_size, inst->value, 0);
   2781   1.9  christos       for (int i = 0;
   2782   1.9  christos 	   aarch64_operands[inst->operands[i].type].op_class != AARCH64_OPND_CLASS_ADDRESS;
   2783   1.9  christos 	   i++)
   2784  1.10  christos 	{
   2785  1.10  christos 	  if (aarch64_operands[inst->operands[i].type].op_class
   2786  1.10  christos 	      == AARCH64_OPND_CLASS_INT_REG)
   2787  1.10  christos 	    {
   2788  1.10  christos 	      inst->operands[i].qualifier = get_greg_qualifier_from_value (value & 1);
   2789   1.9  christos 	      if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
   2790   1.9  christos 		return 0;
   2791   1.9  christos 	    }
   2792   1.9  christos 	  else if (aarch64_operands[inst->operands[i].type].op_class
   2793   1.9  christos 	      == AARCH64_OPND_CLASS_FP_REG)
   2794  1.10  christos 	    {
   2795  1.10  christos 	      value += (extract_field (FLD_opc1, inst->value, 0) << 2);
   2796   1.9  christos 	      inst->operands[i].qualifier = get_sreg_qualifier_from_value (value);
   2797   1.9  christos 	      if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
   2798   1.9  christos 		return 0;
   2799   1.9  christos 	    }
   2800   1.1  christos 	}
   2801   1.1  christos     }
   2802   1.1  christos 
   2803   1.1  christos   /* size:Q fields.  */
   2804   1.1  christos   if (inst->opcode->flags & F_SIZEQ)
   2805   1.1  christos     return decode_sizeq (inst);
   2806   1.1  christos 
   2807   1.1  christos   if (inst->opcode->flags & F_FPTYPE)
   2808   1.1  christos     {
   2809   1.1  christos       idx = select_operand_for_fptype_field_coding (inst->opcode);
   2810   1.1  christos       value = extract_field (FLD_type, inst->value, 0);
   2811   1.1  christos       switch (value)
   2812   1.1  christos 	{
   2813   1.1  christos 	case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
   2814   1.1  christos 	case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
   2815   1.1  christos 	case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
   2816   1.1  christos 	default: return 0;
   2817   1.1  christos 	}
   2818   1.1  christos     }
   2819   1.1  christos 
   2820   1.1  christos   if (inst->opcode->flags & F_SSIZE)
   2821   1.1  christos     {
   2822   1.1  christos       /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
   2823   1.1  christos 	 of the base opcode.  */
   2824   1.1  christos       aarch64_insn mask;
   2825   1.1  christos       enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
   2826   1.1  christos       idx = select_operand_for_scalar_size_field_coding (inst->opcode);
   2827   1.1  christos       value = extract_field (FLD_size, inst->value, inst->opcode->mask);
   2828   1.1  christos       mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
   2829  1.10  christos       /* For most related instruciton, the 'size' field is fully available for
   2830  1.10  christos 	 operand encoding.  */
   2831  1.10  christos       if (mask == 0x3)
   2832  1.10  christos 	{
   2833  1.10  christos 	  inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
   2834   1.1  christos 	  if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
   2835   1.1  christos 	    return 0;
   2836   1.1  christos 	}
   2837   1.1  christos       else
   2838   1.1  christos 	{
   2839   1.1  christos 	  get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
   2840   1.1  christos 					   candidates);
   2841   1.1  christos 	  inst->operands[idx].qualifier
   2842   1.1  christos 	    = get_qualifier_from_partial_encoding (value, candidates, mask);
   2843  1.10  christos 	}
   2844  1.10  christos     }
   2845  1.10  christos 
   2846  1.10  christos   if (inst->opcode->flags & F_LSFE_SZ)
   2847  1.10  christos     {
   2848  1.10  christos       value = extract_field (FLD_ldst_size, inst->value, 0);
   2849  1.10  christos 
   2850  1.10  christos       if (value > 0x3)
   2851  1.10  christos 	return 0;
   2852  1.10  christos 
   2853  1.10  christos       for (int i = 0;
   2854  1.10  christos 	   aarch64_operands[inst->operands[i].type].op_class != AARCH64_OPND_CLASS_ADDRESS;
   2855  1.10  christos 	   i++)
   2856  1.10  christos 	{
   2857  1.10  christos 	  inst->operands[i].qualifier = get_sreg_qualifier_from_value (value);
   2858  1.10  christos 	  if (inst->operands[i].qualifier == AARCH64_OPND_QLF_ERR)
   2859  1.10  christos 	    return 0;
   2860   1.1  christos 	}
   2861   1.1  christos     }
   2862   1.1  christos 
   2863   1.1  christos   if (inst->opcode->flags & F_T)
   2864   1.1  christos     {
   2865   1.1  christos       /* Num of consecutive '0's on the right side of imm5<3:0>.  */
   2866   1.1  christos       int num = 0;
   2867   1.1  christos       unsigned val, Q;
   2868   1.1  christos       assert (aarch64_get_operand_class (inst->opcode->operands[0])
   2869   1.1  christos 	      == AARCH64_OPND_CLASS_SIMD_REG);
   2870   1.1  christos       /* imm5<3:0>	q	<t>
   2871   1.1  christos 	 0000		x	reserved
   2872   1.1  christos 	 xxx1		0	8b
   2873   1.1  christos 	 xxx1		1	16b
   2874   1.1  christos 	 xx10		0	4h
   2875   1.1  christos 	 xx10		1	8h
   2876   1.1  christos 	 x100		0	2s
   2877   1.1  christos 	 x100		1	4s
   2878   1.1  christos 	 1000		0	reserved
   2879   1.1  christos 	 1000		1	2d  */
   2880   1.1  christos       val = extract_field (FLD_imm5, inst->value, 0);
   2881   1.1  christos       while ((val & 0x1) == 0 && ++num <= 3)
   2882   1.1  christos 	val >>= 1;
   2883   1.1  christos       if (num > 3)
   2884   1.1  christos 	return 0;
   2885  1.10  christos       Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
   2886  1.10  christos       inst->operands[0].qualifier =
   2887  1.10  christos 	get_vreg_qualifier_from_value ((num << 1) | Q);
   2888   1.1  christos       if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR)
   2889   1.1  christos 	return 0;
   2890   1.9  christos 
   2891   1.9  christos     }
   2892   1.9  christos 
   2893   1.9  christos   if ((inst->opcode->flags & F_OPD_SIZE) && inst->opcode->iclass == sve2_urqvs)
   2894   1.9  christos     {
   2895   1.9  christos       unsigned size;
   2896   1.9  christos       size = (unsigned) extract_field (FLD_size, inst->value,
   2897  1.10  christos 				       inst->opcode->mask);
   2898  1.10  christos       inst->operands[0].qualifier
   2899   1.9  christos 	= get_vreg_qualifier_from_value (1 + (size << 1));
   2900  1.10  christos       if (inst->operands[0].qualifier == AARCH64_OPND_QLF_ERR)
   2901  1.10  christos 	return 0;
   2902   1.9  christos       inst->operands[2].qualifier = get_sreg_qualifier_from_value (size);
   2903   1.9  christos       if (inst->operands[2].qualifier == AARCH64_OPND_QLF_ERR)
   2904   1.1  christos 	return 0;
   2905   1.1  christos     }
   2906   1.1  christos 
   2907   1.1  christos   if (inst->opcode->flags & F_GPRSIZE_IN_Q)
   2908   1.1  christos     {
   2909   1.1  christos       /* Use Rt to encode in the case of e.g.
   2910   1.1  christos 	 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}].  */
   2911   1.1  christos       idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
   2912   1.1  christos       if (idx == -1)
   2913   1.1  christos 	{
   2914   1.1  christos 	  /* Otherwise use the result operand, which has to be a integer
   2915   1.1  christos 	     register.  */
   2916   1.1  christos 	  assert (aarch64_get_operand_class (inst->opcode->operands[0])
   2917   1.1  christos 		  == AARCH64_OPND_CLASS_INT_REG);
   2918   1.1  christos 	  idx = 0;
   2919   1.1  christos 	}
   2920  1.10  christos       assert (idx == 0 || idx == 1);
   2921  1.10  christos       value = extract_field (FLD_Q, inst->value, 0);
   2922   1.1  christos       inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   2923   1.1  christos       if (inst->operands[idx].qualifier == AARCH64_OPND_QLF_ERR)
   2924   1.1  christos 	return 0;
   2925   1.1  christos     }
   2926   1.1  christos 
   2927   1.1  christos   if (inst->opcode->flags & F_LDS_SIZE)
   2928   1.1  christos     {
   2929   1.1  christos       aarch64_field field = {0, 0};
   2930   1.1  christos       assert (aarch64_get_operand_class (inst->opcode->operands[0])
   2931   1.1  christos 	      == AARCH64_OPND_CLASS_INT_REG);
   2932   1.1  christos       gen_sub_field (FLD_opc, 0, 1, &field);
   2933   1.1  christos       value = extract_field_2 (&field, inst->value, 0);
   2934   1.1  christos       inst->operands[0].qualifier
   2935   1.1  christos 	= value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
   2936   1.1  christos     }
   2937   1.1  christos 
   2938   1.1  christos   /* Miscellaneous decoding; done as the last step.  */
   2939   1.1  christos   if (inst->opcode->flags & F_MISC)
   2940   1.1  christos     return do_misc_decoding (inst);
   2941   1.1  christos 
   2942   1.1  christos   return 1;
   2943   1.1  christos }
   2944   1.1  christos 
   2945   1.1  christos /* Converters converting a real opcode instruction to its alias form.  */
   2946   1.1  christos 
   2947   1.1  christos /* ROR <Wd>, <Ws>, #<shift>
   2948   1.1  christos      is equivalent to:
   2949   1.1  christos    EXTR <Wd>, <Ws>, <Ws>, #<shift>.  */
   2950   1.1  christos static int
   2951   1.1  christos convert_extr_to_ror (aarch64_inst *inst)
   2952   1.1  christos {
   2953   1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
   2954   1.1  christos     {
   2955   1.1  christos       copy_operand_info (inst, 2, 3);
   2956   1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   2957   1.1  christos       return 1;
   2958   1.1  christos     }
   2959   1.1  christos   return 0;
   2960   1.1  christos }
   2961   1.1  christos 
   2962   1.1  christos /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
   2963   1.1  christos      is equivalent to:
   2964   1.1  christos    USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0.  */
   2965   1.1  christos static int
   2966   1.1  christos convert_shll_to_xtl (aarch64_inst *inst)
   2967   1.1  christos {
   2968   1.1  christos   if (inst->operands[2].imm.value == 0)
   2969   1.1  christos     {
   2970   1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   2971   1.1  christos       return 1;
   2972   1.1  christos     }
   2973   1.1  christos   return 0;
   2974   1.1  christos }
   2975   1.1  christos 
   2976   1.1  christos /* Convert
   2977   1.1  christos      UBFM <Xd>, <Xn>, #<shift>, #63.
   2978   1.1  christos    to
   2979   1.1  christos      LSR <Xd>, <Xn>, #<shift>.  */
   2980   1.1  christos static int
   2981   1.1  christos convert_bfm_to_sr (aarch64_inst *inst)
   2982   1.1  christos {
   2983   1.1  christos   int64_t imms, val;
   2984   1.1  christos 
   2985   1.1  christos   imms = inst->operands[3].imm.value;
   2986   1.1  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
   2987   1.1  christos   if (imms == val)
   2988   1.1  christos     {
   2989   1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   2990   1.1  christos       return 1;
   2991   1.1  christos     }
   2992   1.1  christos 
   2993   1.1  christos   return 0;
   2994   1.1  christos }
   2995   1.1  christos 
   2996   1.1  christos /* Convert MOV to ORR.  */
   2997   1.1  christos static int
   2998   1.1  christos convert_orr_to_mov (aarch64_inst *inst)
   2999   1.1  christos {
   3000   1.1  christos   /* MOV <Vd>.<T>, <Vn>.<T>
   3001   1.1  christos      is equivalent to:
   3002   1.1  christos      ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>.  */
   3003   1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
   3004   1.1  christos     {
   3005   1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   3006   1.1  christos       return 1;
   3007   1.1  christos     }
   3008   1.1  christos   return 0;
   3009   1.1  christos }
   3010   1.1  christos 
   3011   1.1  christos /* When <imms> >= <immr>, the instruction written:
   3012   1.1  christos      SBFX <Xd>, <Xn>, #<lsb>, #<width>
   3013   1.1  christos    is equivalent to:
   3014   1.1  christos      SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1).  */
   3015   1.1  christos 
   3016   1.1  christos static int
   3017   1.1  christos convert_bfm_to_bfx (aarch64_inst *inst)
   3018   1.1  christos {
   3019   1.1  christos   int64_t immr, imms;
   3020   1.1  christos 
   3021   1.1  christos   immr = inst->operands[2].imm.value;
   3022   1.1  christos   imms = inst->operands[3].imm.value;
   3023   1.1  christos   if (imms >= immr)
   3024   1.1  christos     {
   3025   1.1  christos       int64_t lsb = immr;
   3026   1.1  christos       inst->operands[2].imm.value = lsb;
   3027   1.1  christos       inst->operands[3].imm.value = imms + 1 - lsb;
   3028   1.1  christos       /* The two opcodes have different qualifiers for
   3029   1.1  christos 	 the immediate operands; reset to help the checking.  */
   3030   1.1  christos       reset_operand_qualifier (inst, 2);
   3031   1.1  christos       reset_operand_qualifier (inst, 3);
   3032   1.1  christos       return 1;
   3033   1.1  christos     }
   3034   1.1  christos 
   3035   1.1  christos   return 0;
   3036   1.1  christos }
   3037   1.1  christos 
   3038   1.1  christos /* When <imms> < <immr>, the instruction written:
   3039   1.1  christos      SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
   3040   1.1  christos    is equivalent to:
   3041   1.1  christos      SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1).  */
   3042   1.1  christos 
   3043   1.1  christos static int
   3044   1.1  christos convert_bfm_to_bfi (aarch64_inst *inst)
   3045   1.1  christos {
   3046   1.1  christos   int64_t immr, imms, val;
   3047   1.1  christos 
   3048   1.1  christos   immr = inst->operands[2].imm.value;
   3049   1.1  christos   imms = inst->operands[3].imm.value;
   3050   1.1  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
   3051   1.1  christos   if (imms < immr)
   3052   1.1  christos     {
   3053   1.1  christos       inst->operands[2].imm.value = (val - immr) & (val - 1);
   3054   1.1  christos       inst->operands[3].imm.value = imms + 1;
   3055   1.1  christos       /* The two opcodes have different qualifiers for
   3056   1.1  christos 	 the immediate operands; reset to help the checking.  */
   3057   1.1  christos       reset_operand_qualifier (inst, 2);
   3058   1.1  christos       reset_operand_qualifier (inst, 3);
   3059   1.1  christos       return 1;
   3060   1.1  christos     }
   3061   1.1  christos 
   3062   1.1  christos   return 0;
   3063   1.3  christos }
   3064   1.3  christos 
   3065   1.3  christos /* The instruction written:
   3066   1.3  christos      BFC <Xd>, #<lsb>, #<width>
   3067   1.3  christos    is equivalent to:
   3068   1.3  christos      BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1).  */
   3069   1.3  christos 
   3070   1.3  christos static int
   3071   1.3  christos convert_bfm_to_bfc (aarch64_inst *inst)
   3072   1.3  christos {
   3073   1.3  christos   int64_t immr, imms, val;
   3074   1.3  christos 
   3075   1.3  christos   /* Should have been assured by the base opcode value.  */
   3076   1.3  christos   assert (inst->operands[1].reg.regno == 0x1f);
   3077   1.3  christos 
   3078   1.3  christos   immr = inst->operands[2].imm.value;
   3079   1.3  christos   imms = inst->operands[3].imm.value;
   3080   1.3  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
   3081   1.3  christos   if (imms < immr)
   3082   1.3  christos     {
   3083   1.3  christos       /* Drop XZR from the second operand.  */
   3084   1.3  christos       copy_operand_info (inst, 1, 2);
   3085   1.3  christos       copy_operand_info (inst, 2, 3);
   3086   1.3  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   3087   1.3  christos 
   3088   1.3  christos       /* Recalculate the immediates.  */
   3089   1.3  christos       inst->operands[1].imm.value = (val - immr) & (val - 1);
   3090   1.3  christos       inst->operands[2].imm.value = imms + 1;
   3091   1.3  christos 
   3092   1.3  christos       /* The two opcodes have different qualifiers for the operands; reset to
   3093   1.3  christos 	 help the checking.  */
   3094   1.3  christos       reset_operand_qualifier (inst, 1);
   3095   1.3  christos       reset_operand_qualifier (inst, 2);
   3096   1.3  christos       reset_operand_qualifier (inst, 3);
   3097   1.3  christos 
   3098   1.3  christos       return 1;
   3099   1.3  christos     }
   3100   1.3  christos 
   3101   1.3  christos   return 0;
   3102   1.1  christos }
   3103   1.1  christos 
   3104   1.1  christos /* The instruction written:
   3105   1.1  christos      LSL <Xd>, <Xn>, #<shift>
   3106   1.1  christos    is equivalent to:
   3107   1.1  christos      UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>).  */
   3108   1.1  christos 
   3109   1.1  christos static int
   3110   1.1  christos convert_ubfm_to_lsl (aarch64_inst *inst)
   3111   1.1  christos {
   3112   1.1  christos   int64_t immr = inst->operands[2].imm.value;
   3113   1.1  christos   int64_t imms = inst->operands[3].imm.value;
   3114   1.1  christos   int64_t val
   3115   1.1  christos     = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
   3116   1.1  christos 
   3117   1.1  christos   if ((immr == 0 && imms == val) || immr == imms + 1)
   3118   1.1  christos     {
   3119   1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   3120   1.1  christos       inst->operands[2].imm.value = val - imms;
   3121   1.1  christos       return 1;
   3122   1.1  christos     }
   3123   1.1  christos 
   3124   1.1  christos   return 0;
   3125   1.1  christos }
   3126   1.3  christos 
   3127   1.3  christos /* CINC <Wd>, <Wn>, <cond>
   3128   1.1  christos      is equivalent to:
   3129   1.1  christos    CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
   3130   1.1  christos      where <cond> is not AL or NV.  */
   3131   1.1  christos 
   3132   1.3  christos static int
   3133   1.3  christos convert_from_csel (aarch64_inst *inst)
   3134   1.1  christos {
   3135   1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
   3136   1.1  christos       && (inst->operands[3].cond->value & 0xe) != 0xe)
   3137   1.1  christos     {
   3138   1.1  christos       copy_operand_info (inst, 2, 3);
   3139   1.1  christos       inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
   3140   1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   3141   1.1  christos       return 1;
   3142   1.1  christos     }
   3143   1.1  christos   return 0;
   3144   1.1  christos }
   3145   1.3  christos 
   3146   1.3  christos /* CSET <Wd>, <cond>
   3147   1.1  christos      is equivalent to:
   3148   1.1  christos    CSINC <Wd>, WZR, WZR, invert(<cond>)
   3149   1.1  christos      where <cond> is not AL or NV.  */
   3150   1.1  christos 
   3151   1.1  christos static int
   3152   1.3  christos convert_csinc_to_cset (aarch64_inst *inst)
   3153   1.3  christos {
   3154   1.1  christos   if (inst->operands[1].reg.regno == 0x1f
   3155   1.1  christos       && inst->operands[2].reg.regno == 0x1f
   3156   1.1  christos       && (inst->operands[3].cond->value & 0xe) != 0xe)
   3157   1.1  christos     {
   3158   1.1  christos       copy_operand_info (inst, 1, 3);
   3159   1.1  christos       inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
   3160   1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   3161   1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   3162   1.1  christos       return 1;
   3163   1.1  christos     }
   3164   1.1  christos   return 0;
   3165   1.1  christos }
   3166   1.9  christos 
   3167   1.1  christos /* MOV <Wd>, #<imm>
   3168   1.1  christos      is equivalent to:
   3169   1.1  christos    MOVZ <Wd>, #<imm16_5>, LSL #<shift>.
   3170   1.1  christos 
   3171   1.1  christos    A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
   3172   1.1  christos    ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
   3173   1.1  christos    or where a MOVN has an immediate that could be encoded by MOVZ, or where
   3174   1.1  christos    MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
   3175   1.1  christos    machine-instruction mnemonic must be used.  */
   3176   1.1  christos 
   3177   1.1  christos static int
   3178   1.1  christos convert_movewide_to_mov (aarch64_inst *inst)
   3179   1.1  christos {
   3180   1.1  christos   uint64_t value = inst->operands[1].imm.value;
   3181   1.1  christos   /* MOVZ/MOVN #0 have a shift amount other than LSL #0.  */
   3182   1.1  christos   if (value == 0 && inst->operands[1].shifter.amount != 0)
   3183   1.1  christos     return 0;
   3184   1.1  christos   inst->operands[1].type = AARCH64_OPND_IMM_MOV;
   3185   1.1  christos   inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
   3186   1.1  christos   value <<= inst->operands[1].shifter.amount;
   3187   1.1  christos   /* As an alias convertor, it has to be clear that the INST->OPCODE
   3188   1.1  christos      is the opcode of the real instruction.  */
   3189   1.1  christos   if (inst->opcode->op == OP_MOVN)
   3190   1.1  christos     {
   3191   1.6  christos       int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
   3192   1.1  christos       value = ~value;
   3193   1.1  christos       /* A MOVN has an immediate that could be encoded by MOVZ.  */
   3194   1.1  christos       if (aarch64_wide_constant_p (value, is32, NULL))
   3195   1.1  christos 	return 0;
   3196   1.1  christos     }
   3197   1.1  christos   inst->operands[1].imm.value = value;
   3198   1.1  christos   inst->operands[1].shifter.amount = 0;
   3199   1.1  christos   return 1;
   3200   1.1  christos }
   3201   1.1  christos 
   3202   1.1  christos /* MOV <Wd>, #<imm>
   3203   1.1  christos      is equivalent to:
   3204   1.1  christos    ORR <Wd>, WZR, #<imm>.
   3205   1.1  christos 
   3206   1.1  christos    A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
   3207   1.1  christos    ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
   3208   1.1  christos    or where a MOVN has an immediate that could be encoded by MOVZ, or where
   3209   1.1  christos    MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
   3210   1.1  christos    machine-instruction mnemonic must be used.  */
   3211   1.1  christos 
   3212   1.1  christos static int
   3213   1.1  christos convert_movebitmask_to_mov (aarch64_inst *inst)
   3214   1.1  christos {
   3215   1.1  christos   int is32;
   3216   1.1  christos   uint64_t value;
   3217   1.1  christos 
   3218   1.1  christos   /* Should have been assured by the base opcode value.  */
   3219   1.1  christos   assert (inst->operands[1].reg.regno == 0x1f);
   3220   1.1  christos   copy_operand_info (inst, 1, 2);
   3221   1.1  christos   is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
   3222   1.1  christos   inst->operands[1].type = AARCH64_OPND_IMM_MOV;
   3223   1.1  christos   value = inst->operands[1].imm.value;
   3224   1.6  christos   /* ORR has an immediate that could be generated by a MOVZ or MOVN
   3225   1.6  christos      instruction.  */
   3226   1.1  christos   if (inst->operands[0].reg.regno != 0x1f
   3227   1.1  christos       && (aarch64_wide_constant_p (value, is32, NULL)
   3228   1.1  christos 	  || aarch64_wide_constant_p (~value, is32, NULL)))
   3229   1.1  christos     return 0;
   3230   1.1  christos 
   3231   1.1  christos   inst->operands[2].type = AARCH64_OPND_NIL;
   3232   1.1  christos   return 1;
   3233   1.1  christos }
   3234   1.1  christos 
   3235   1.1  christos /* Some alias opcodes are disassembled by being converted from their real-form.
   3236   1.1  christos    N.B. INST->OPCODE is the real opcode rather than the alias.  */
   3237   1.1  christos 
   3238   1.1  christos static int
   3239   1.1  christos convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
   3240   1.1  christos {
   3241   1.1  christos   switch (alias->op)
   3242   1.1  christos     {
   3243   1.1  christos     case OP_ASR_IMM:
   3244   1.1  christos     case OP_LSR_IMM:
   3245   1.1  christos       return convert_bfm_to_sr (inst);
   3246   1.1  christos     case OP_LSL_IMM:
   3247   1.1  christos       return convert_ubfm_to_lsl (inst);
   3248   1.1  christos     case OP_CINC:
   3249   1.1  christos     case OP_CINV:
   3250   1.1  christos     case OP_CNEG:
   3251   1.1  christos       return convert_from_csel (inst);
   3252   1.1  christos     case OP_CSET:
   3253   1.1  christos     case OP_CSETM:
   3254   1.1  christos       return convert_csinc_to_cset (inst);
   3255   1.1  christos     case OP_UBFX:
   3256   1.1  christos     case OP_BFXIL:
   3257   1.1  christos     case OP_SBFX:
   3258   1.1  christos       return convert_bfm_to_bfx (inst);
   3259   1.1  christos     case OP_SBFIZ:
   3260   1.3  christos     case OP_BFI:
   3261   1.3  christos     case OP_UBFIZ:
   3262   1.1  christos       return convert_bfm_to_bfi (inst);
   3263   1.1  christos     case OP_BFC:
   3264   1.1  christos       return convert_bfm_to_bfc (inst);
   3265   1.1  christos     case OP_MOV_V:
   3266   1.1  christos       return convert_orr_to_mov (inst);
   3267   1.1  christos     case OP_MOV_IMM_WIDE:
   3268   1.1  christos     case OP_MOV_IMM_WIDEN:
   3269   1.1  christos       return convert_movewide_to_mov (inst);
   3270   1.1  christos     case OP_MOV_IMM_LOG:
   3271   1.1  christos       return convert_movebitmask_to_mov (inst);
   3272   1.1  christos     case OP_ROR_IMM:
   3273   1.1  christos       return convert_extr_to_ror (inst);
   3274   1.1  christos     case OP_SXTL:
   3275   1.1  christos     case OP_SXTL2:
   3276   1.1  christos     case OP_UXTL:
   3277   1.1  christos     case OP_UXTL2:
   3278   1.1  christos       return convert_shll_to_xtl (inst);
   3279   1.1  christos     default:
   3280   1.1  christos       return 0;
   3281   1.8  christos     }
   3282   1.6  christos }
   3283   1.6  christos 
   3284   1.1  christos static bool
   3285   1.1  christos aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
   3286   1.1  christos 		       aarch64_inst *, int, aarch64_operand_error *errors);
   3287   1.1  christos 
   3288   1.1  christos /* Given the instruction information in *INST, check if the instruction has
   3289   1.1  christos    any alias form that can be used to represent *INST.  If the answer is yes,
   3290   1.1  christos    update *INST to be in the form of the determined alias.  */
   3291   1.1  christos 
   3292   1.1  christos /* In the opcode description table, the following flags are used in opcode
   3293   1.1  christos    entries to help establish the relations between the real and alias opcodes:
   3294   1.1  christos 
   3295   1.1  christos 	F_ALIAS:	opcode is an alias
   3296   1.1  christos 	F_HAS_ALIAS:	opcode has alias(es)
   3297   1.1  christos 	F_P1
   3298   1.1  christos 	F_P2
   3299   1.1  christos 	F_P3:		Disassembly preference priority 1-3 (the larger the
   3300   1.1  christos 			higher).  If nothing is specified, it is the priority
   3301   1.1  christos 			0 by default, i.e. the lowest priority.
   3302   1.1  christos 
   3303   1.1  christos    Although the relation between the machine and the alias instructions are not
   3304   1.1  christos    explicitly described, it can be easily determined from the base opcode
   3305   1.1  christos    values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
   3306   1.1  christos    description entries:
   3307   1.1  christos 
   3308   1.1  christos    The mask of an alias opcode must be equal to or a super-set (i.e. more
   3309   1.1  christos    constrained) of that of the aliased opcode; so is the base opcode value.
   3310   1.1  christos 
   3311   1.1  christos    if (opcode_has_alias (real) && alias_opcode_p (opcode)
   3312   1.1  christos        && (opcode->mask & real->mask) == real->mask
   3313   1.1  christos        && (real->mask & opcode->opcode) == (real->mask & real->opcode))
   3314   1.1  christos    then OPCODE is an alias of, and only of, the REAL instruction
   3315   1.1  christos 
   3316   1.1  christos    The alias relationship is forced flat-structured to keep related algorithm
   3317   1.1  christos    simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
   3318   1.1  christos 
   3319   1.1  christos    During the disassembling, the decoding decision tree (in
   3320   1.1  christos    opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
   3321   1.1  christos    if the decoding of such a machine instruction succeeds (and -Mno-aliases is
   3322   1.1  christos    not specified), the disassembler will check whether there is any alias
   3323   1.1  christos    instruction exists for this real instruction.  If there is, the disassembler
   3324   1.1  christos    will try to disassemble the 32-bit binary again using the alias's rule, or
   3325   1.1  christos    try to convert the IR to the form of the alias.  In the case of the multiple
   3326   1.1  christos    aliases, the aliases are tried one by one from the highest priority
   3327   1.1  christos    (currently the flag F_P3) to the lowest priority (no priority flag), and the
   3328   1.1  christos    first succeeds first adopted.
   3329   1.1  christos 
   3330   1.1  christos    You may ask why there is a need for the conversion of IR from one form to
   3331   1.1  christos    another in handling certain aliases.  This is because on one hand it avoids
   3332   1.1  christos    adding more operand code to handle unusual encoding/decoding; on other
   3333   1.1  christos    hand, during the disassembling, the conversion is an effective approach to
   3334   1.1  christos    check the condition of an alias (as an alias may be adopted only if certain
   3335   1.1  christos    conditions are met).
   3336   1.1  christos 
   3337   1.1  christos    In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
   3338   1.1  christos    aarch64_opcode_table and generated aarch64_find_alias_opcode and
   3339   1.6  christos    aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help.  */
   3340   1.6  christos 
   3341   1.1  christos static void
   3342   1.1  christos determine_disassembling_preference (struct aarch64_inst *inst,
   3343   1.1  christos 				    aarch64_operand_error *errors)
   3344   1.1  christos {
   3345   1.1  christos   const aarch64_opcode *opcode;
   3346   1.1  christos   const aarch64_opcode *alias;
   3347   1.1  christos 
   3348   1.6  christos   opcode = inst->opcode;
   3349   1.1  christos 
   3350   1.1  christos   /* This opcode does not have an alias, so use itself.  */
   3351   1.1  christos   if (!opcode_has_alias (opcode))
   3352   1.1  christos     return;
   3353   1.1  christos 
   3354   1.1  christos   alias = aarch64_find_alias_opcode (opcode);
   3355   1.1  christos   assert (alias);
   3356   1.1  christos 
   3357   1.1  christos #ifdef DEBUG_AARCH64
   3358   1.1  christos   if (debug_dump)
   3359   1.1  christos     {
   3360   1.1  christos       const aarch64_opcode *tmp = alias;
   3361   1.1  christos       printf ("####   LIST    orderd: ");
   3362   1.1  christos       while (tmp)
   3363   1.1  christos 	{
   3364   1.1  christos 	  printf ("%s, ", tmp->name);
   3365   1.1  christos 	  tmp = aarch64_find_next_alias_opcode (tmp);
   3366   1.1  christos 	}
   3367   1.1  christos       printf ("\n");
   3368   1.1  christos     }
   3369   1.1  christos #endif /* DEBUG_AARCH64 */
   3370   1.1  christos 
   3371   1.3  christos   for (; alias; alias = aarch64_find_next_alias_opcode (alias))
   3372   1.1  christos     {
   3373   1.1  christos       DEBUG_TRACE ("try %s", alias->name);
   3374   1.1  christos       assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
   3375   1.1  christos 
   3376   1.1  christos       /* An alias can be a pseudo opcode which will never be used in the
   3377   1.1  christos 	 disassembly, e.g. BIC logical immediate is such a pseudo opcode
   3378   1.1  christos 	 aliasing AND.  */
   3379   1.1  christos       if (pseudo_opcode_p (alias))
   3380   1.1  christos 	{
   3381   1.1  christos 	  DEBUG_TRACE ("skip pseudo %s", alias->name);
   3382   1.1  christos 	  continue;
   3383   1.1  christos 	}
   3384   1.1  christos 
   3385   1.1  christos       if ((inst->value & alias->mask) != alias->opcode)
   3386   1.1  christos 	{
   3387   1.8  christos 	  DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
   3388   1.9  christos 	  continue;
   3389   1.8  christos 	}
   3390   1.8  christos 
   3391   1.8  christos       if (!AARCH64_CPU_HAS_ALL_FEATURES (arch_variant, *alias->avariant))
   3392   1.8  christos 	{
   3393   1.8  christos 	  DEBUG_TRACE ("skip %s: we're missing features", alias->name);
   3394   1.1  christos 	  continue;
   3395   1.1  christos 	}
   3396   1.1  christos 
   3397   1.1  christos       /* No need to do any complicated transformation on operands, if the alias
   3398   1.1  christos 	 opcode does not have any operand.  */
   3399   1.1  christos       if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
   3400   1.1  christos 	{
   3401   1.1  christos 	  DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
   3402   1.1  christos 	  aarch64_replace_opcode (inst, alias);
   3403   1.1  christos 	  return;
   3404   1.1  christos 	}
   3405   1.1  christos       if (alias->flags & F_CONV)
   3406   1.1  christos 	{
   3407   1.1  christos 	  aarch64_inst copy;
   3408   1.1  christos 	  memcpy (&copy, inst, sizeof (aarch64_inst));
   3409   1.1  christos 	  /* ALIAS is the preference as long as the instruction can be
   3410   1.1  christos 	     successfully converted to the form of ALIAS.  */
   3411   1.8  christos 	  if (convert_to_alias (&copy, alias) == 1)
   3412   1.8  christos 	    {
   3413   1.8  christos 	      aarch64_replace_opcode (&copy, alias);
   3414   1.8  christos 	      if (aarch64_match_operands_constraint (&copy, NULL) != 1)
   3415   1.8  christos 		{
   3416   1.8  christos 		  DEBUG_TRACE ("FAILED with alias %s ", alias->name);
   3417   1.8  christos 		}
   3418   1.8  christos 	      else
   3419   1.8  christos 		{
   3420   1.1  christos 		  DEBUG_TRACE ("succeed with %s via conversion", alias->name);
   3421   1.1  christos 		  memcpy (inst, &copy, sizeof (aarch64_inst));
   3422   1.1  christos 		}
   3423   1.1  christos 	      return;
   3424   1.1  christos 	    }
   3425   1.1  christos 	}
   3426   1.1  christos       else
   3427   1.1  christos 	{
   3428   1.6  christos 	  /* Directly decode the alias opcode.  */
   3429   1.1  christos 	  aarch64_inst temp;
   3430   1.1  christos 	  memset (&temp, '\0', sizeof (aarch64_inst));
   3431   1.1  christos 	  if (aarch64_opcode_decode (alias, inst->value, &temp, 1, errors) == 1)
   3432   1.1  christos 	    {
   3433   1.1  christos 	      DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
   3434   1.1  christos 	      memcpy (inst, &temp, sizeof (aarch64_inst));
   3435   1.1  christos 	      return;
   3436   1.1  christos 	    }
   3437   1.1  christos 	}
   3438   1.6  christos     }
   3439   1.6  christos }
   3440   1.6  christos 
   3441   1.6  christos /* Some instructions (including all SVE ones) use the instruction class
   3442   1.6  christos    to describe how a qualifiers_list index is represented in the instruction
   3443   1.6  christos    encoding.  If INST is such an instruction, decode the appropriate fields
   3444   1.8  christos    and fill in the operand qualifiers accordingly.  Return true if no
   3445   1.6  christos    problems are found.  */
   3446   1.6  christos 
   3447   1.6  christos static bool
   3448   1.6  christos aarch64_decode_variant_using_iclass (aarch64_inst *inst)
   3449   1.6  christos {
   3450   1.6  christos   int i, variant;
   3451   1.6  christos 
   3452   1.9  christos   variant = 0;
   3453   1.9  christos   switch (inst->opcode->iclass)
   3454   1.9  christos     {
   3455   1.9  christos     case sme_mov:
   3456   1.9  christos       variant = extract_fields (inst->value, 0, 2, FLD_SME_Q, FLD_SME_size_22);
   3457   1.9  christos       if (variant >= 4 && variant < 7)
   3458   1.9  christos 	return false;
   3459   1.9  christos       if (variant == 7)
   3460   1.9  christos 	variant = 4;
   3461   1.9  christos       break;
   3462   1.9  christos 
   3463   1.9  christos     case sme_psel:
   3464   1.9  christos       i = extract_fields (inst->value, 0, 2, FLD_SME_tszh, FLD_SME_tszl);
   3465   1.9  christos       if (i == 0)
   3466   1.9  christos 	return false;
   3467   1.9  christos       while ((i & 1) == 0)
   3468   1.9  christos 	{
   3469   1.9  christos 	  i >>= 1;
   3470   1.9  christos 	  variant += 1;
   3471   1.9  christos 	}
   3472   1.9  christos       break;
   3473   1.9  christos 
   3474   1.9  christos     case sme_shift:
   3475  1.10  christos       i = extract_field (FLD_SVE_tszh, inst->value, 0);
   3476  1.10  christos       goto sve_shift;
   3477  1.10  christos 
   3478  1.10  christos     case sme_size_12_bh:
   3479  1.10  christos       variant = extract_field (FLD_S, inst->value, 0);
   3480  1.10  christos       if (variant > 1)
   3481   1.9  christos 	return false;
   3482   1.9  christos       break;
   3483   1.9  christos 
   3484   1.9  christos     case sme_size_12_bhs:
   3485   1.9  christos       variant = extract_field (FLD_SME_size_12, inst->value, 0);
   3486   1.9  christos       if (variant >= 3)
   3487   1.9  christos 	return false;
   3488   1.9  christos       break;
   3489   1.9  christos 
   3490   1.9  christos     case sme_size_12_hs:
   3491   1.9  christos       variant = extract_field (FLD_SME_size_12, inst->value, 0);
   3492   1.9  christos       if (variant != 1 && variant != 2)
   3493   1.9  christos 	return false;
   3494  1.10  christos       variant -= 1;
   3495  1.10  christos       break;
   3496  1.10  christos 
   3497  1.10  christos     case sme_size_12_b:
   3498  1.10  christos       variant = extract_field (FLD_SME_size_12, inst->value, 0);
   3499  1.10  christos       if (variant != 0)
   3500   1.9  christos 	return false;
   3501   1.9  christos       break;
   3502   1.9  christos 
   3503   1.9  christos     case sme_size_22:
   3504   1.9  christos       variant = extract_field (FLD_SME_size_22, inst->value, 0);
   3505   1.9  christos       break;
   3506   1.9  christos 
   3507   1.9  christos     case sme_size_22_hsd:
   3508   1.9  christos       variant = extract_field (FLD_SME_size_22, inst->value, 0);
   3509   1.9  christos       if (variant < 1)
   3510   1.9  christos 	return false;
   3511   1.9  christos       variant -= 1;
   3512   1.9  christos       break;
   3513   1.9  christos 
   3514   1.9  christos     case sme_sz_23:
   3515   1.6  christos       variant = extract_field (FLD_SME_sz_23, inst->value, 0);
   3516   1.6  christos       break;
   3517   1.6  christos 
   3518   1.6  christos     case sve_cpy:
   3519   1.6  christos       variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_14);
   3520  1.10  christos       break;
   3521  1.10  christos 
   3522   1.6  christos     case sve_index:
   3523   1.8  christos       i = extract_field (FLD_imm5, inst->value, 0);
   3524   1.6  christos 
   3525   1.6  christos       if ((i & 31) == 0)
   3526   1.6  christos 	return false;
   3527   1.6  christos       while ((i & 1) == 0)
   3528   1.6  christos 	{
   3529   1.6  christos 	  i >>= 1;
   3530   1.6  christos 	  variant += 1;
   3531   1.6  christos 	}
   3532   1.6  christos       break;
   3533   1.6  christos 
   3534   1.6  christos     case sve_limm:
   3535   1.6  christos       /* Pick the smallest applicable element size.  */
   3536   1.6  christos       if ((inst->value & 0x20600) == 0x600)
   3537   1.6  christos 	variant = 0;
   3538   1.6  christos       else if ((inst->value & 0x20400) == 0x400)
   3539   1.6  christos 	variant = 1;
   3540   1.6  christos       else if ((inst->value & 0x20000) == 0)
   3541   1.6  christos 	variant = 2;
   3542   1.6  christos       else
   3543   1.9  christos 	variant = 3;
   3544   1.9  christos       break;
   3545   1.9  christos 
   3546   1.9  christos     case sme2_mov:
   3547   1.9  christos       /* .D is preferred over the other sizes in disassembly.  */
   3548   1.9  christos       variant = 3;
   3549   1.9  christos       break;
   3550   1.6  christos 
   3551   1.9  christos     case sme2_movaz:
   3552   1.6  christos     case sme_misc:
   3553   1.6  christos     case sve_misc:
   3554   1.6  christos       /* These instructions have only a single variant.  */
   3555   1.6  christos       break;
   3556   1.6  christos 
   3557   1.6  christos     case sve_movprfx:
   3558   1.6  christos       variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_16);
   3559   1.6  christos       break;
   3560   1.6  christos 
   3561   1.6  christos     case sve_pred_zm:
   3562   1.6  christos       variant = extract_field (FLD_SVE_M_4, inst->value, 0);
   3563   1.6  christos       break;
   3564   1.6  christos 
   3565   1.6  christos     case sve_shift_pred:
   3566   1.8  christos       i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_8);
   3567   1.6  christos     sve_shift:
   3568   1.6  christos       if (i == 0)
   3569   1.6  christos 	return false;
   3570   1.6  christos       while (i != 1)
   3571   1.6  christos 	{
   3572   1.6  christos 	  i >>= 1;
   3573   1.6  christos 	  variant += 1;
   3574   1.6  christos 	}
   3575   1.6  christos       break;
   3576   1.6  christos 
   3577   1.6  christos     case sve_shift_unpred:
   3578   1.6  christos       i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
   3579   1.6  christos       goto sve_shift;
   3580   1.6  christos 
   3581   1.8  christos     case sve_size_bhs:
   3582   1.6  christos       variant = extract_field (FLD_size, inst->value, 0);
   3583   1.6  christos       if (variant >= 3)
   3584   1.6  christos 	return false;
   3585   1.6  christos       break;
   3586   1.6  christos 
   3587   1.6  christos     case sve_size_bhsd:
   3588   1.6  christos       variant = extract_field (FLD_size, inst->value, 0);
   3589   1.6  christos       break;
   3590   1.6  christos 
   3591   1.8  christos     case sve_size_hsd:
   3592   1.6  christos       i = extract_field (FLD_size, inst->value, 0);
   3593   1.6  christos       if (i < 1)
   3594   1.6  christos 	return false;
   3595   1.9  christos       variant = i - 1;
   3596   1.9  christos       break;
   3597   1.7  christos 
   3598   1.6  christos     case sme_fp_sd:
   3599   1.6  christos     case sme_int_sd:
   3600   1.6  christos     case sve_size_bh:
   3601   1.6  christos     case sve_size_sd:
   3602   1.7  christos       variant = extract_field (FLD_SVE_sz, inst->value, 0);
   3603   1.7  christos       break;
   3604   1.7  christos 
   3605   1.7  christos     case sve_size_sd2:
   3606  1.10  christos       variant = extract_field (FLD_SVE_sz2, inst->value, 0);
   3607  1.10  christos       break;
   3608  1.10  christos 
   3609  1.10  christos     case sve_size_sd3:
   3610  1.10  christos       variant = extract_field (FLD_SVE_sz3, inst->value, 0);
   3611  1.10  christos       break;
   3612  1.10  christos 
   3613  1.10  christos     case sve_size_sd4:
   3614   1.7  christos       variant = extract_field (FLD_SVE_sz4, inst->value, 0);
   3615   1.7  christos       break;
   3616   1.7  christos 
   3617   1.8  christos     case sve_size_hsd2:
   3618   1.7  christos       i = extract_field (FLD_SVE_size, inst->value, 0);
   3619   1.7  christos       if (i < 1)
   3620   1.7  christos 	return false;
   3621  1.10  christos       variant = i - 1;
   3622  1.10  christos       break;
   3623  1.10  christos 
   3624  1.10  christos     case sve_size_hsd3:
   3625  1.10  christos       i = extract_field (FLD_len, inst->value, 0);
   3626  1.10  christos       if (i < 1)
   3627  1.10  christos 	return false;
   3628   1.7  christos       variant = i - 1;
   3629   1.7  christos       break;
   3630   1.7  christos 
   3631   1.7  christos     case sve_size_13:
   3632   1.7  christos       /* Ignore low bit of this field since that is set in the opcode for
   3633   1.7  christos 	 instructions of this iclass.  */
   3634   1.7  christos       i = (extract_field (FLD_size, inst->value, 0) & 2);
   3635   1.7  christos       variant = (i >> 1);
   3636   1.7  christos       break;
   3637   1.7  christos 
   3638   1.8  christos     case sve_shift_tsz_bhsd:
   3639   1.7  christos       i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
   3640   1.7  christos       if (i == 0)
   3641   1.7  christos 	return false;
   3642   1.7  christos       while (i != 1)
   3643   1.7  christos 	{
   3644   1.7  christos 	  i >>= 1;
   3645   1.7  christos 	  variant += 1;
   3646   1.7  christos 	}
   3647   1.7  christos       break;
   3648   1.7  christos 
   3649   1.8  christos     case sve_size_tsz_bhs:
   3650   1.7  christos       i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
   3651   1.7  christos       if (i == 0)
   3652   1.7  christos 	return false;
   3653   1.8  christos       while (i != 1)
   3654   1.7  christos 	{
   3655   1.7  christos 	  if (i & 1)
   3656   1.7  christos 	    return false;
   3657   1.7  christos 	  i >>= 1;
   3658   1.7  christos 	  variant += 1;
   3659   1.7  christos 	}
   3660   1.7  christos       break;
   3661   1.7  christos 
   3662   1.8  christos     case sve_shift_tsz_hsd:
   3663   1.7  christos       i = extract_fields (inst->value, 0, 2, FLD_SVE_sz, FLD_SVE_tszl_19);
   3664   1.7  christos       if (i == 0)
   3665   1.7  christos 	return false;
   3666   1.7  christos       while (i != 1)
   3667   1.7  christos 	{
   3668   1.7  christos 	  i >>= 1;
   3669   1.7  christos 	  variant += 1;
   3670   1.6  christos 	}
   3671   1.6  christos       break;
   3672   1.8  christos 
   3673   1.6  christos     default:
   3674   1.6  christos       /* No mapping between instruction class and qualifiers.  */
   3675   1.6  christos       return true;
   3676   1.6  christos     }
   3677   1.8  christos 
   3678   1.6  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3679   1.1  christos     inst->operands[i].qualifier = inst->opcode->qualifiers_list[variant][i];
   3680   1.1  christos   return true;
   3681   1.1  christos }
   3682   1.1  christos /* Decode the CODE according to OPCODE; fill INST.  Return 0 if the decoding
   3683   1.1  christos    fails, which meanes that CODE is not an instruction of OPCODE; otherwise
   3684   1.1  christos    return 1.
   3685   1.1  christos 
   3686   1.1  christos    If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
   3687   1.8  christos    determined and used to disassemble CODE; this is done just before the
   3688   1.1  christos    return.  */
   3689   1.6  christos 
   3690   1.6  christos static bool
   3691   1.1  christos aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
   3692   1.1  christos 		       aarch64_inst *inst, int noaliases_p,
   3693   1.1  christos 		       aarch64_operand_error *errors)
   3694   1.1  christos {
   3695   1.1  christos   int i;
   3696   1.1  christos 
   3697   1.1  christos   DEBUG_TRACE ("enter with %s", opcode->name);
   3698   1.6  christos 
   3699   1.6  christos   assert (opcode && inst);
   3700   1.6  christos 
   3701   1.1  christos   /* Clear inst.  */
   3702   1.1  christos   memset (inst, '\0', sizeof (aarch64_inst));
   3703   1.1  christos 
   3704   1.1  christos   /* Check the base opcode.  */
   3705   1.1  christos   if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
   3706   1.1  christos     {
   3707   1.1  christos       DEBUG_TRACE ("base opcode match FAIL");
   3708   1.1  christos       goto decode_fail;
   3709   1.1  christos     }
   3710   1.1  christos 
   3711   1.1  christos   inst->opcode = opcode;
   3712   1.1  christos   inst->value = code;
   3713   1.1  christos 
   3714   1.1  christos   /* Assign operand codes and indexes.  */
   3715   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3716   1.1  christos     {
   3717   1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL)
   3718   1.1  christos 	break;
   3719   1.1  christos       inst->operands[i].type = opcode->operands[i];
   3720   1.1  christos       inst->operands[i].idx = i;
   3721   1.1  christos     }
   3722   1.1  christos 
   3723   1.1  christos   /* Call the opcode decoder indicated by flags.  */
   3724   1.1  christos   if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
   3725   1.1  christos     {
   3726   1.1  christos       DEBUG_TRACE ("opcode flag-based decoder FAIL");
   3727   1.6  christos       goto decode_fail;
   3728   1.6  christos     }
   3729   1.6  christos 
   3730   1.6  christos   /* Possibly use the instruction class to determine the correct
   3731   1.6  christos      qualifier.  */
   3732   1.6  christos   if (!aarch64_decode_variant_using_iclass (inst))
   3733   1.6  christos     {
   3734   1.6  christos       DEBUG_TRACE ("iclass-based decoder FAIL");
   3735   1.1  christos       goto decode_fail;
   3736   1.1  christos     }
   3737   1.1  christos 
   3738   1.1  christos   /* Call operand decoders.  */
   3739   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3740   1.5  christos     {
   3741   1.1  christos       const aarch64_operand *opnd;
   3742   1.1  christos       enum aarch64_opnd type;
   3743   1.1  christos 
   3744   1.1  christos       type = opcode->operands[i];
   3745   1.1  christos       if (type == AARCH64_OPND_NIL)
   3746   1.6  christos 	break;
   3747   1.6  christos       opnd = &aarch64_operands[type];
   3748   1.1  christos       if (operand_has_extractor (opnd)
   3749   1.1  christos 	  && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst,
   3750   1.1  christos 					 errors)))
   3751   1.1  christos 	{
   3752   1.1  christos 	  DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
   3753   1.1  christos 	  goto decode_fail;
   3754   1.5  christos 	}
   3755   1.7  christos     }
   3756   1.8  christos 
   3757   1.5  christos   /* If the opcode has a verifier, then check it now.  */
   3758   1.5  christos   if (opcode->verifier
   3759   1.5  christos       && opcode->verifier (inst, code, 0, false, errors, NULL) != ERR_OK)
   3760   1.5  christos     {
   3761   1.5  christos       DEBUG_TRACE ("operand verifier FAIL");
   3762   1.1  christos       goto decode_fail;
   3763   1.1  christos     }
   3764   1.1  christos 
   3765   1.1  christos   /* Match the qualifiers.  */
   3766   1.1  christos   if (aarch64_match_operands_constraint (inst, NULL) == 1)
   3767   1.1  christos     {
   3768   1.1  christos       /* Arriving here, the CODE has been determined as a valid instruction
   3769   1.1  christos 	 of OPCODE and *INST has been filled with information of this OPCODE
   3770   1.1  christos 	 instruction.  Before the return, check if the instruction has any
   3771   1.6  christos 	 alias and should be disassembled in the form of its alias instead.
   3772   1.1  christos 	 If the answer is yes, *INST will be updated.  */
   3773   1.8  christos       if (!noaliases_p)
   3774   1.1  christos 	determine_disassembling_preference (inst, errors);
   3775   1.1  christos       DEBUG_TRACE ("SUCCESS");
   3776   1.1  christos       return true;
   3777   1.1  christos     }
   3778   1.1  christos   else
   3779   1.1  christos     {
   3780   1.8  christos       DEBUG_TRACE ("constraint matching FAIL");
   3781   1.8  christos     }
   3782   1.1  christos 
   3783   1.1  christos  decode_fail:
   3784   1.1  christos   return false;
   3785   1.1  christos }
   3786   1.1  christos 
   3787   1.1  christos /* This does some user-friendly fix-up to *INST.  It is currently focus on
   3789   1.1  christos    the adjustment of qualifiers to help the printed instruction
   3790   1.1  christos    recognized/understood more easily.  */
   3791   1.1  christos 
   3792   1.1  christos static void
   3793   1.1  christos user_friendly_fixup (aarch64_inst *inst)
   3794   1.1  christos {
   3795   1.1  christos   switch (inst->opcode->iclass)
   3796   1.1  christos     {
   3797   1.1  christos     case testbranch:
   3798   1.1  christos       /* TBNZ Xn|Wn, #uimm6, label
   3799   1.1  christos 	 Test and Branch Not Zero: conditionally jumps to label if bit number
   3800   1.1  christos 	 uimm6 in register Xn is not zero.  The bit number implies the width of
   3801   1.1  christos 	 the register, which may be written and should be disassembled as Wn if
   3802   1.1  christos 	 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
   3803   1.1  christos 	 */
   3804   1.1  christos       if (inst->operands[1].imm.value < 32)
   3805   1.1  christos 	inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
   3806   1.1  christos       break;
   3807   1.3  christos     default: break;
   3808   1.3  christos     }
   3809   1.3  christos }
   3810   1.1  christos 
   3811   1.7  christos /* Decode INSN and fill in *INST the instruction information.  An alias
   3812   1.3  christos    opcode may be filled in *INSN if NOALIASES_P is FALSE.  Return zero on
   3813   1.8  christos    success.  */
   3814   1.6  christos 
   3815   1.1  christos enum err_type
   3816   1.1  christos aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
   3817   1.1  christos 		     bool noaliases_p,
   3818   1.1  christos 		     aarch64_operand_error *errors)
   3819   1.1  christos {
   3820   1.1  christos   const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
   3821   1.1  christos 
   3822   1.1  christos #ifdef DEBUG_AARCH64
   3823   1.1  christos   if (debug_dump)
   3824   1.1  christos     {
   3825   1.1  christos       const aarch64_opcode *tmp = opcode;
   3826   1.1  christos       printf ("\n");
   3827   1.1  christos       DEBUG_TRACE ("opcode lookup:");
   3828   1.1  christos       while (tmp != NULL)
   3829   1.1  christos 	{
   3830   1.1  christos 	  aarch64_verbose ("  %s", tmp->name);
   3831   1.1  christos 	  tmp = aarch64_find_next_opcode (tmp);
   3832   1.1  christos 	}
   3833   1.1  christos     }
   3834   1.1  christos #endif /* DEBUG_AARCH64 */
   3835   1.1  christos 
   3836   1.1  christos   /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
   3837   1.1  christos      distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
   3838   1.1  christos      opcode field and value, apart from the difference that one of them has an
   3839   1.1  christos      extra field as part of the opcode, but such a field is used for operand
   3840   1.1  christos      encoding in other opcode(s) ('immh' in the case of the example).  */
   3841   1.6  christos   while (opcode != NULL)
   3842   1.1  christos     {
   3843   1.1  christos       /* But only one opcode can be decoded successfully for, as the
   3844   1.1  christos 	 decoding routine will check the constraint carefully.  */
   3845   1.1  christos       if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p, errors) == 1)
   3846   1.1  christos 	return ERR_OK;
   3847   1.1  christos       opcode = aarch64_find_next_opcode (opcode);
   3848   1.1  christos     }
   3849   1.9  christos 
   3850   1.9  christos   return ERR_UND;
   3851   1.9  christos }
   3852   1.9  christos 
   3853   1.9  christos /* Return a short string to indicate a switch to STYLE.  These strings
   3854   1.9  christos    will be embedded into the disassembled operand text (as produced by
   3855   1.9  christos    aarch64_print_operand), and then spotted in the print_operands function
   3856   1.9  christos    so that the disassembler output can be split by style.  */
   3857   1.9  christos 
   3858   1.9  christos static const char *
   3859   1.9  christos get_style_text (enum disassembler_style style)
   3860   1.9  christos {
   3861   1.9  christos   static bool init = false;
   3862   1.9  christos   static char formats[16][4];
   3863   1.9  christos   unsigned num;
   3864   1.9  christos 
   3865   1.9  christos   /* First time through we build a string for every possible format.  This
   3866   1.9  christos      code relies on there being no more than 16 different styles (there's
   3867   1.9  christos      an assert below for this).  */
   3868   1.9  christos   if (!init)
   3869   1.9  christos     {
   3870   1.9  christos       int i;
   3871   1.9  christos 
   3872   1.9  christos       for (i = 0; i <= 0xf; ++i)
   3873   1.9  christos 	{
   3874   1.9  christos 	  int res ATTRIBUTE_UNUSED
   3875   1.9  christos 	    = snprintf (&formats[i][0], sizeof (formats[i]), "%c%x%c",
   3876   1.9  christos 			STYLE_MARKER_CHAR, i, STYLE_MARKER_CHAR);
   3877   1.9  christos 	  assert (res == 3);
   3878   1.9  christos 	}
   3879   1.9  christos 
   3880   1.9  christos       init = true;
   3881   1.9  christos     }
   3882   1.9  christos 
   3883   1.9  christos   /* Return the string that marks switching to STYLE.  */
   3884   1.9  christos   num = (unsigned) style;
   3885   1.9  christos   assert (style <= 0xf);
   3886   1.9  christos   return formats[num];
   3887   1.9  christos }
   3888   1.9  christos 
   3889   1.9  christos /* Callback used by aarch64_print_operand to apply STYLE to the
   3890   1.9  christos    disassembler output created from FMT and ARGS.  The STYLER object holds
   3891   1.9  christos    any required state.  Must return a pointer to a string (created from FMT
   3892   1.9  christos    and ARGS) that will continue to be valid until the complete disassembled
   3893   1.9  christos    instruction has been printed.
   3894   1.9  christos 
   3895   1.9  christos    We return a string that includes two embedded style markers, the first,
   3896   1.9  christos    places at the start of the string, indicates a switch to STYLE, and the
   3897   1.9  christos    second, placed at the end of the string, indicates a switch back to the
   3898   1.9  christos    default text style.
   3899   1.9  christos 
   3900   1.9  christos    Later, when we print the operand text we take care to collapse any
   3901   1.9  christos    adjacent style markers, and to ignore any style markers that appear at
   3902   1.9  christos    the very end of a complete operand string.  */
   3903   1.9  christos 
   3904   1.9  christos static const char *aarch64_apply_style (struct aarch64_styler *styler,
   3905   1.9  christos 					enum disassembler_style style,
   3906   1.9  christos 					const char *fmt,
   3907   1.9  christos 					va_list args)
   3908   1.9  christos {
   3909   1.9  christos   int res;
   3910   1.9  christos   char *ptr, *tmp;
   3911   1.9  christos   struct obstack *stack = (struct obstack *) styler->state;
   3912   1.9  christos   va_list ap;
   3913   1.9  christos 
   3914   1.9  christos   /* These are the two strings for switching styles.  */
   3915   1.9  christos   const char *style_on = get_style_text (style);
   3916   1.9  christos   const char *style_off = get_style_text (dis_style_text);
   3917   1.9  christos 
   3918   1.9  christos   /* Calculate space needed once FMT and ARGS are expanded.  */
   3919   1.9  christos   va_copy (ap, args);
   3920   1.9  christos   res = vsnprintf (NULL, 0, fmt, ap);
   3921   1.9  christos   va_end (ap);
   3922   1.9  christos   assert (res >= 0);
   3923   1.9  christos 
   3924   1.9  christos   /* Allocate space on the obstack for the expanded FMT and ARGS, as well
   3925   1.9  christos      as the two strings for switching styles, then write all of these
   3926   1.9  christos      strings onto the obstack.  */
   3927   1.9  christos   ptr = (char *) obstack_alloc (stack, res + strlen (style_on)
   3928   1.9  christos 				+ strlen (style_off) + 1);
   3929   1.9  christos   tmp = stpcpy (ptr, style_on);
   3930   1.9  christos   res = vsnprintf (tmp, (res + 1), fmt, args);
   3931   1.9  christos   assert (res >= 0);
   3932   1.9  christos   tmp += res;
   3933   1.9  christos   strcpy (tmp, style_off);
   3934   1.1  christos 
   3935   1.1  christos   return ptr;
   3936   1.1  christos }
   3937   1.1  christos 
   3938   1.7  christos /* Print operands.  */
   3939   1.8  christos 
   3940   1.1  christos static void
   3941   1.7  christos print_operands (bfd_vma pc, const aarch64_opcode *opcode,
   3942   1.1  christos 		const aarch64_opnd_info *opnds, struct disassemble_info *info,
   3943   1.9  christos 		bool *has_notes)
   3944   1.9  christos {
   3945   1.9  christos   char *notes = NULL;
   3946   1.9  christos   int i, pcrel_p, num_printed;
   3947   1.9  christos   struct aarch64_styler styler;
   3948   1.9  christos   struct obstack content;
   3949   1.9  christos   obstack_init (&content);
   3950   1.1  christos 
   3951   1.1  christos   styler.apply_style = aarch64_apply_style;
   3952   1.5  christos   styler.state = (void *) &content;
   3953   1.8  christos 
   3954   1.8  christos   for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3955   1.1  christos     {
   3956   1.1  christos       char str[128];
   3957   1.1  christos       char cmt[128];
   3958   1.1  christos 
   3959   1.1  christos       /* We regard the opcode operand info more, however we also look into
   3960   1.1  christos 	 the inst->operands to support the disassembling of the optional
   3961   1.1  christos 	 operand.
   3962   1.1  christos 	 The two operand code should be the same in all cases, apart from
   3963   1.1  christos 	 when the operand can be optional.  */
   3964   1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL
   3965   1.5  christos 	  || opnds[i].type == AARCH64_OPND_NIL)
   3966   1.8  christos 	break;
   3967   1.9  christos 
   3968   1.1  christos       /* Generate the operand string in STR.  */
   3969   1.1  christos       aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
   3970   1.1  christos 			     &info->target, &notes, cmt, sizeof (cmt),
   3971   1.9  christos 			     arch_variant, &styler);
   3972   1.9  christos 
   3973   1.1  christos       /* Print the delimiter (taking account of omitted operand(s)).  */
   3974   1.1  christos       if (str[0] != '\0')
   3975   1.1  christos 	(*info->fprintf_styled_func) (info->stream, dis_style_text, "%s",
   3976   1.1  christos 				      num_printed++ == 0 ? "\t" : ", ");
   3977   1.1  christos 
   3978   1.8  christos       /* Print the operand.  */
   3979   1.9  christos       if (pcrel_p)
   3980   1.9  christos 	(*info->print_address_func) (info->target, info);
   3981   1.9  christos       else
   3982   1.9  christos 	{
   3983   1.9  christos 	  /* This operand came from aarch64_print_operand, and will include
   3984   1.9  christos 	     embedded strings indicating which style each character should
   3985   1.9  christos 	     have.  In the following code we split the text based on
   3986   1.9  christos 	     CURR_STYLE, and call the styled print callback to print each
   3987   1.9  christos 	     block of text in the appropriate style.  */
   3988   1.9  christos 	  char *start, *curr;
   3989   1.9  christos 	  enum disassembler_style curr_style = dis_style_text;
   3990   1.9  christos 
   3991   1.9  christos 	  start = curr = str;
   3992   1.9  christos 	  do
   3993   1.9  christos 	    {
   3994   1.9  christos 	      if (*curr == '\0'
   3995   1.9  christos 		  || (*curr == STYLE_MARKER_CHAR
   3996   1.9  christos 		      && ISXDIGIT (*(curr + 1))
   3997   1.9  christos 		      && *(curr + 2) == STYLE_MARKER_CHAR))
   3998   1.9  christos 		{
   3999   1.9  christos 		  /* Output content between our START position and CURR.  */
   4000   1.9  christos 		  int len = curr - start;
   4001   1.9  christos 		  if (len > 0)
   4002   1.9  christos 		    {
   4003   1.9  christos 		      if ((*info->fprintf_styled_func) (info->stream,
   4004   1.9  christos 							curr_style,
   4005   1.9  christos 							"%.*s",
   4006   1.9  christos 							len, start) < 0)
   4007   1.9  christos 			break;
   4008   1.9  christos 		    }
   4009   1.9  christos 
   4010   1.9  christos 		  if (*curr == '\0')
   4011   1.9  christos 		    break;
   4012   1.9  christos 
   4013   1.9  christos 		  /* Skip over the initial STYLE_MARKER_CHAR.  */
   4014   1.9  christos 		  ++curr;
   4015   1.9  christos 
   4016   1.9  christos 		  /* Update the CURR_STYLE.  As there are less than 16
   4017   1.9  christos 		     styles, it is possible, that if the input is corrupted
   4018   1.9  christos 		     in some way, that we might set CURR_STYLE to an
   4019   1.9  christos 		     invalid value.  Don't worry though, we check for this
   4020   1.9  christos 		     situation.  */
   4021   1.9  christos 		  if (*curr >= '0' && *curr <= '9')
   4022   1.9  christos 		    curr_style = (enum disassembler_style) (*curr - '0');
   4023   1.9  christos 		  else if (*curr >= 'a' && *curr <= 'f')
   4024   1.9  christos 		    curr_style = (enum disassembler_style) (*curr - 'a' + 10);
   4025   1.9  christos 		  else
   4026   1.9  christos 		    curr_style = dis_style_text;
   4027   1.9  christos 
   4028   1.9  christos 		  /* Check for an invalid style having been selected.  This
   4029   1.8  christos 		     should never happen, but it doesn't hurt to be a
   4030   1.9  christos 		     little paranoid.  */
   4031   1.9  christos 		  if (curr_style > dis_style_comment_start)
   4032   1.9  christos 		    curr_style = dis_style_text;
   4033   1.9  christos 
   4034   1.9  christos 		  /* Skip the hex character, and the closing STYLE_MARKER_CHAR.  */
   4035   1.9  christos 		  curr += 2;
   4036   1.9  christos 
   4037   1.9  christos 		  /* Reset the START to after the style marker.  */
   4038   1.9  christos 		  start = curr;
   4039   1.9  christos 		}
   4040   1.8  christos 	      else
   4041   1.9  christos 		++curr;
   4042   1.9  christos 	    }
   4043   1.9  christos 	  while (true);
   4044   1.9  christos 	}
   4045   1.9  christos 
   4046   1.9  christos       /* Print the comment.  This works because only the last operand ever
   4047   1.9  christos 	 adds a comment.  If that ever changes then we'll need to be
   4048   1.1  christos 	 smarter here.  */
   4049   1.6  christos       if (cmt[0] != '\0')
   4050   1.6  christos 	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
   4051   1.7  christos 				      "\t// %s", cmt);
   4052   1.8  christos     }
   4053   1.9  christos 
   4054   1.9  christos     if (notes && !no_notes)
   4055   1.7  christos       {
   4056   1.9  christos 	*has_notes = true;
   4057   1.9  christos 	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
   4058   1.6  christos 				      "  // note: %s", notes);
   4059   1.6  christos       }
   4060   1.6  christos 
   4061   1.6  christos     obstack_free (&content, NULL);
   4062   1.6  christos }
   4063   1.6  christos 
   4064   1.6  christos /* Set NAME to a copy of INST's mnemonic with the "." suffix removed.  */
   4065   1.6  christos 
   4066   1.6  christos static void
   4067   1.6  christos remove_dot_suffix (char *name, const aarch64_inst *inst)
   4068   1.6  christos {
   4069   1.6  christos   char *ptr;
   4070   1.6  christos   size_t len;
   4071   1.6  christos 
   4072   1.6  christos   ptr = strchr (inst->opcode->name, '.');
   4073   1.6  christos   assert (ptr && inst->cond);
   4074   1.1  christos   len = ptr - inst->opcode->name;
   4075   1.1  christos   assert (len < 8);
   4076   1.1  christos   strncpy (name, inst->opcode->name, len);
   4077   1.1  christos   name[len] = '\0';
   4078   1.1  christos }
   4079   1.1  christos 
   4080   1.1  christos /* Print the instruction mnemonic name.  */
   4081   1.1  christos 
   4082   1.1  christos static void
   4083   1.1  christos print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
   4084   1.1  christos {
   4085   1.1  christos   if (inst->opcode->flags & F_COND)
   4086   1.6  christos     {
   4087   1.3  christos       /* For instructions that are truly conditionally executed, e.g. b.cond,
   4088   1.6  christos 	 prepare the full mnemonic name with the corresponding condition
   4089   1.9  christos 	 suffix.  */
   4090   1.9  christos       char name[8];
   4091   1.1  christos 
   4092   1.1  christos       remove_dot_suffix (name, inst);
   4093   1.9  christos       (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
   4094   1.9  christos 				    "%s.%s", name, inst->cond->names[0]);
   4095   1.1  christos     }
   4096   1.1  christos   else
   4097   1.6  christos     (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
   4098   1.6  christos 				  "%s", inst->opcode->name);
   4099   1.6  christos }
   4100   1.6  christos 
   4101   1.6  christos /* Decide whether we need to print a comment after the operands of
   4102   1.6  christos    instruction INST.  */
   4103   1.6  christos 
   4104   1.6  christos static void
   4105   1.6  christos print_comment (const aarch64_inst *inst, struct disassemble_info *info)
   4106   1.6  christos {
   4107   1.6  christos   if (inst->opcode->flags & F_COND)
   4108   1.6  christos     {
   4109   1.6  christos       char name[8];
   4110   1.6  christos       unsigned int i, num_conds;
   4111   1.9  christos 
   4112   1.9  christos       remove_dot_suffix (name, inst);
   4113   1.9  christos       num_conds = ARRAY_SIZE (inst->cond->names);
   4114   1.9  christos       for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
   4115   1.6  christos 	(*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
   4116   1.6  christos 				      "%s %s.%s",
   4117   1.6  christos 				      i == 1 ? "  //" : ",",
   4118   1.7  christos 				      name, inst->cond->names[i]);
   4119   1.7  christos     }
   4120   1.7  christos }
   4121   1.7  christos 
   4122   1.7  christos /* Build notes from verifiers into a string for printing.  */
   4123   1.7  christos 
   4124   1.7  christos static void
   4125   1.7  christos print_verifier_notes (aarch64_operand_error *detail,
   4126   1.7  christos 		      struct disassemble_info *info)
   4127   1.7  christos {
   4128   1.7  christos   if (no_notes)
   4129   1.7  christos     return;
   4130   1.7  christos 
   4131   1.9  christos   /* The output of the verifier cannot be a fatal error, otherwise the assembly
   4132   1.9  christos      would not have succeeded.  We can safely ignore these.  */
   4133   1.8  christos   assert (detail->non_fatal);
   4134   1.8  christos 
   4135   1.8  christos   (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
   4136   1.9  christos 				"  // note: ");
   4137   1.9  christos   switch (detail->kind)
   4138   1.9  christos     {
   4139   1.9  christos     case AARCH64_OPDE_A_SHOULD_FOLLOW_B:
   4140   1.8  christos       (*info->fprintf_styled_func) (info->stream, dis_style_text,
   4141   1.8  christos 				    _("this `%s' should have an immediately"
   4142   1.8  christos 				      " preceding `%s'"),
   4143   1.9  christos 				    detail->data[0].s, detail->data[1].s);
   4144   1.9  christos       break;
   4145   1.9  christos 
   4146   1.8  christos     case AARCH64_OPDE_EXPECTED_A_AFTER_B:
   4147   1.8  christos       (*info->fprintf_styled_func) (info->stream, dis_style_text,
   4148   1.8  christos 				    _("expected `%s' after previous `%s'"),
   4149   1.8  christos 				    detail->data[0].s, detail->data[1].s);
   4150   1.9  christos       break;
   4151   1.9  christos 
   4152   1.8  christos     default:
   4153   1.9  christos       assert (detail->error);
   4154   1.9  christos       (*info->fprintf_styled_func) (info->stream, dis_style_text,
   4155   1.8  christos 				    "%s", detail->error);
   4156   1.8  christos       if (detail->index >= 0)
   4157   1.7  christos 	(*info->fprintf_styled_func) (info->stream, dis_style_text,
   4158   1.7  christos 				      " at operand %d", detail->index + 1);
   4159   1.1  christos       break;
   4160   1.1  christos     }
   4161   1.1  christos }
   4162   1.1  christos 
   4163   1.7  christos /* Print the instruction according to *INST.  */
   4164   1.7  christos 
   4165   1.7  christos static void
   4166   1.1  christos print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
   4167   1.8  christos 		    const aarch64_insn code,
   4168   1.7  christos 		    struct disassemble_info *info,
   4169   1.1  christos 		    aarch64_operand_error *mismatch_details)
   4170   1.7  christos {
   4171   1.6  christos   bool has_notes = false;
   4172   1.7  christos 
   4173   1.7  christos   print_mnemonic_name (inst, info);
   4174   1.7  christos   print_operands (pc, inst->opcode, inst->operands, info, &has_notes);
   4175   1.7  christos   print_comment (inst, info);
   4176   1.7  christos 
   4177   1.7  christos   /* We've already printed a note, not enough space to print more so exit.
   4178   1.7  christos      Usually notes shouldn't overlap so it shouldn't happen that we have a note
   4179   1.7  christos      from a register and instruction at the same time.  */
   4180   1.7  christos   if (has_notes)
   4181   1.7  christos     return;
   4182   1.8  christos 
   4183   1.7  christos   /* Always run constraint verifiers, this is needed because constraints need to
   4184   1.7  christos      maintain a global state regardless of whether the instruction has the flag
   4185   1.7  christos      set or not.  */
   4186   1.8  christos   enum err_type result = verify_constraints (inst, code, pc, false,
   4187   1.8  christos 					     mismatch_details, &insn_sequence);
   4188   1.8  christos   switch (result)
   4189   1.7  christos     {
   4190   1.7  christos     case ERR_VFI:
   4191   1.7  christos       print_verifier_notes (mismatch_details, info);
   4192   1.7  christos       break;
   4193   1.7  christos     case ERR_UND:
   4194   1.7  christos     case ERR_UNP:
   4195   1.1  christos     case ERR_NYI:
   4196   1.1  christos     default:
   4197   1.1  christos       break;
   4198   1.1  christos     }
   4199   1.1  christos }
   4200   1.1  christos 
   4201   1.1  christos /* Entry-point of the instruction disassembler and printer.  */
   4202   1.6  christos 
   4203   1.6  christos static void
   4204   1.1  christos print_insn_aarch64_word (bfd_vma pc,
   4205   1.7  christos 			 uint32_t word,
   4206   1.1  christos 			 struct disassemble_info *info,
   4207   1.7  christos 			 aarch64_operand_error *errors)
   4208   1.7  christos {
   4209   1.7  christos   static const char *err_msg[ERR_NR_ENTRIES+1] =
   4210   1.7  christos     {
   4211   1.1  christos       [ERR_OK]  = "_",
   4212   1.1  christos       [ERR_UND] = "undefined",
   4213   1.7  christos       [ERR_UNP] = "unpredictable",
   4214   1.1  christos       [ERR_NYI] = "NYI"
   4215   1.1  christos     };
   4216   1.1  christos 
   4217   1.1  christos   enum err_type ret;
   4218   1.1  christos   aarch64_inst inst;
   4219   1.1  christos 
   4220   1.1  christos   info->insn_info_valid = 1;
   4221   1.1  christos   info->branch_delay_insns = 0;
   4222   1.1  christos   info->data_size = 0;
   4223   1.1  christos   info->target = 0;
   4224   1.1  christos   info->target2 = 0;
   4225   1.1  christos 
   4226   1.1  christos   if (info->flags & INSN_HAS_RELOC)
   4227   1.1  christos     /* If the instruction has a reloc associated with it, then
   4228   1.1  christos        the offset field in the instruction will actually be the
   4229   1.1  christos        addend for the reloc.  (If we are using REL type relocs).
   4230   1.6  christos        In such cases, we can ignore the pc when computing
   4231   1.1  christos        addresses, since the addend is not currently pc-relative.  */
   4232   1.1  christos     pc = 0;
   4233   1.1  christos 
   4234   1.3  christos   ret = aarch64_decode_insn (word, &inst, no_aliases, errors);
   4235   1.1  christos 
   4236   1.1  christos   if (((word >> 21) & 0x3ff) == 1)
   4237   1.1  christos     {
   4238   1.1  christos       /* RESERVED for ALES.  */
   4239   1.1  christos       assert (ret != ERR_OK);
   4240   1.1  christos       ret = ERR_NYI;
   4241   1.1  christos     }
   4242   1.1  christos 
   4243   1.1  christos   switch (ret)
   4244   1.1  christos     {
   4245   1.1  christos     case ERR_UND:
   4246   1.9  christos     case ERR_UNP:
   4247   1.9  christos     case ERR_NYI:
   4248   1.9  christos       /* Handle undefined instructions.  */
   4249   1.9  christos       info->insn_type = dis_noninsn;
   4250   1.9  christos       (*info->fprintf_styled_func) (info->stream,
   4251   1.9  christos 				    dis_style_assembler_directive,
   4252   1.9  christos 				    ".inst\t");
   4253   1.1  christos       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
   4254   1.1  christos 				    "0x%08x", word);
   4255   1.1  christos       (*info->fprintf_styled_func) (info->stream, dis_style_comment_start,
   4256   1.9  christos 				    " ; %s", err_msg[ret]);
   4257   1.9  christos       break;
   4258   1.9  christos     case ERR_OK:
   4259   1.9  christos       user_friendly_fixup (&inst);
   4260   1.9  christos       if (inst.opcode->iclass == condbranch
   4261   1.9  christos 	  || inst.opcode->iclass == testbranch
   4262   1.7  christos 	  || inst.opcode->iclass == compbranch)
   4263   1.1  christos         info->insn_type = dis_condbranch;
   4264   1.1  christos       else if (inst.opcode->iclass == branch_imm)
   4265   1.1  christos         info->insn_type = dis_jsr;
   4266   1.1  christos       print_aarch64_insn (pc, &inst, word, info, errors);
   4267   1.1  christos       break;
   4268   1.1  christos     default:
   4269   1.1  christos       abort ();
   4270   1.1  christos     }
   4271   1.1  christos }
   4272   1.8  christos 
   4273   1.1  christos /* Disallow mapping symbols ($x, $d etc) from
   4274   1.1  christos    being displayed in symbol relative addresses.  */
   4275   1.1  christos 
   4276   1.1  christos bool
   4277   1.1  christos aarch64_symbol_is_valid (asymbol * sym,
   4278   1.1  christos 			 struct disassemble_info * info ATTRIBUTE_UNUSED)
   4279   1.8  christos {
   4280   1.1  christos   const char * name;
   4281   1.1  christos 
   4282   1.1  christos   if (sym == NULL)
   4283   1.1  christos     return false;
   4284   1.1  christos 
   4285   1.1  christos   name = bfd_asymbol_name (sym);
   4286   1.1  christos 
   4287   1.1  christos   return name
   4288   1.1  christos     && (name[0] != '$'
   4289   1.1  christos 	|| (name[1] != 'x' && name[1] != 'd')
   4290   1.1  christos 	|| (name[2] != '\0' && name[2] != '.'));
   4291   1.1  christos }
   4292   1.1  christos 
   4293   1.1  christos /* Print data bytes on INFO->STREAM.  */
   4294   1.6  christos 
   4295   1.6  christos static void
   4296   1.1  christos print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
   4297   1.1  christos 		 uint32_t word,
   4298   1.1  christos 		 struct disassemble_info *info,
   4299   1.1  christos 		 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
   4300   1.9  christos {
   4301   1.9  christos   switch (info->bytes_per_chunk)
   4302   1.9  christos     {
   4303   1.9  christos     case 1:
   4304   1.1  christos       info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
   4305   1.1  christos 				 ".byte\t");
   4306   1.9  christos       info->fprintf_styled_func (info->stream, dis_style_immediate,
   4307   1.9  christos 				 "0x%02x", word);
   4308   1.9  christos       break;
   4309   1.9  christos     case 2:
   4310   1.1  christos       info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
   4311   1.1  christos 				 ".short\t");
   4312   1.9  christos       info->fprintf_styled_func (info->stream, dis_style_immediate,
   4313   1.9  christos 				 "0x%04x", word);
   4314   1.9  christos       break;
   4315   1.9  christos     case 4:
   4316   1.1  christos       info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
   4317   1.1  christos 				 ".word\t");
   4318   1.1  christos       info->fprintf_styled_func (info->stream, dis_style_immediate,
   4319   1.1  christos 				 "0x%08x", word);
   4320   1.1  christos       break;
   4321   1.1  christos     default:
   4322   1.1  christos       abort ();
   4323   1.1  christos     }
   4324   1.1  christos }
   4325   1.1  christos 
   4326   1.1  christos /* Try to infer the code or data type from a symbol.
   4327   1.1  christos    Returns nonzero if *MAP_TYPE was set.  */
   4328   1.1  christos 
   4329   1.8  christos static int
   4330   1.1  christos get_sym_code_type (struct disassemble_info *info, int n,
   4331   1.1  christos 		   enum map_type *map_type)
   4332   1.1  christos {
   4333   1.1  christos   asymbol * as;
   4334   1.6  christos   elf_symbol_type *es;
   4335   1.6  christos   unsigned int type;
   4336   1.8  christos   const char *name;
   4337   1.8  christos 
   4338   1.8  christos   /* If the symbol is in a different section, ignore it.  */
   4339   1.8  christos   if (info->section != NULL && info->section != info->symtab[n]->section)
   4340   1.8  christos     return false;
   4341   1.8  christos 
   4342   1.8  christos   if (n >= info->symtab_size)
   4343   1.8  christos     return false;
   4344   1.8  christos 
   4345   1.6  christos   as = info->symtab[n];
   4346   1.1  christos   if (bfd_asymbol_flavour (as) != bfd_target_elf_flavour)
   4347   1.1  christos     return false;
   4348   1.1  christos   es = (elf_symbol_type *) as;
   4349   1.1  christos 
   4350   1.1  christos   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
   4351   1.1  christos 
   4352   1.8  christos   /* If the symbol has function type then use that.  */
   4353   1.1  christos   if (type == STT_FUNC)
   4354   1.1  christos     {
   4355   1.1  christos       *map_type = MAP_INSN;
   4356   1.1  christos       return true;
   4357   1.1  christos     }
   4358   1.1  christos 
   4359   1.1  christos   /* Check for mapping symbols.  */
   4360   1.1  christos   name = bfd_asymbol_name(info->symtab[n]);
   4361   1.1  christos   if (name[0] == '$'
   4362   1.8  christos       && (name[1] == 'x' || name[1] == 'd')
   4363   1.1  christos       && (name[2] == '\0' || name[2] == '.'))
   4364   1.1  christos     {
   4365   1.8  christos       *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
   4366   1.8  christos       return true;
   4367   1.8  christos     }
   4368   1.8  christos 
   4369   1.8  christos   return false;
   4370   1.8  christos }
   4371   1.8  christos 
   4372   1.8  christos /* Set the feature bits in arch_variant in order to get the correct disassembly
   4373   1.8  christos    for the chosen architecture variant.
   4374   1.8  christos 
   4375   1.8  christos    Currently we only restrict disassembly for Armv8-R and otherwise enable all
   4376   1.8  christos    non-R-profile features.  */
   4377   1.8  christos static void
   4378   1.8  christos select_aarch64_variant (unsigned mach)
   4379   1.9  christos {
   4380   1.8  christos   switch (mach)
   4381   1.8  christos     {
   4382   1.9  christos     case bfd_mach_aarch64_8R:
   4383   1.9  christos       AARCH64_SET_FEATURE (arch_variant, AARCH64_ARCH_V8R);
   4384   1.8  christos       break;
   4385   1.1  christos     default:
   4386   1.1  christos       arch_variant = (aarch64_feature_set) AARCH64_ALL_FEATURES;
   4387   1.1  christos       AARCH64_CLEAR_FEATURE (arch_variant, arch_variant, V8R);
   4388   1.1  christos     }
   4389   1.1  christos }
   4390   1.1  christos 
   4391   1.1  christos /* Entry-point of the AArch64 disassembler.  */
   4392   1.1  christos 
   4393   1.1  christos int
   4394   1.1  christos print_insn_aarch64 (bfd_vma pc,
   4395   1.6  christos 		    struct disassemble_info *info)
   4396   1.6  christos {
   4397   1.8  christos   bfd_byte	buffer[INSNLEN];
   4398   1.1  christos   int		status;
   4399   1.1  christos   void		(*printer) (bfd_vma, uint32_t, struct disassemble_info *,
   4400   1.6  christos 			    aarch64_operand_error *);
   4401   1.8  christos   bool   found = false;
   4402   1.1  christos   unsigned int	size = 4;
   4403   1.1  christos   unsigned long	data;
   4404   1.1  christos   aarch64_operand_error errors;
   4405   1.1  christos   static bool set_features;
   4406   1.1  christos 
   4407   1.1  christos   if (info->disassembler_options)
   4408   1.1  christos     {
   4409   1.1  christos       set_default_aarch64_dis_options (info);
   4410   1.1  christos 
   4411   1.1  christos       parse_aarch64_dis_options (info->disassembler_options);
   4412   1.1  christos 
   4413   1.8  christos       /* To avoid repeated parsing of these options, we remove them here.  */
   4414   1.8  christos       info->disassembler_options = NULL;
   4415   1.8  christos     }
   4416   1.8  christos 
   4417   1.8  christos   if (!set_features)
   4418   1.8  christos     {
   4419   1.1  christos       select_aarch64_variant (info->mach);
   4420   1.1  christos       set_features = true;
   4421   1.1  christos     }
   4422   1.7  christos 
   4423   1.7  christos   /* Aarch64 instructions are always little-endian */
   4424   1.7  christos   info->endian_code = BFD_ENDIAN_LITTLE;
   4425   1.7  christos 
   4426   1.7  christos   /* Default to DATA.  A text section is required by the ABI to contain an
   4427   1.7  christos      INSN mapping symbol at the start.  A data section has no such
   4428   1.7  christos      requirement, hence if no mapping symbol is found the section must
   4429   1.7  christos      contain only data.  This however isn't very useful if the user has
   4430   1.7  christos      fully stripped the binaries.  If this is the case use the section
   4431   1.7  christos      attributes to determine the default.  If we have no section default to
   4432   1.7  christos      INSN as well, as we may be disassembling some raw bytes on a baremetal
   4433   1.7  christos      HEX file or similar.  */
   4434   1.1  christos   enum map_type type = MAP_DATA;
   4435   1.1  christos   if ((info->section && info->section->flags & SEC_CODE) || !info->section)
   4436   1.1  christos     type = MAP_INSN;
   4437   1.1  christos 
   4438   1.1  christos   /* First check the full symtab for a mapping symbol, even if there
   4439   1.1  christos      are no usable non-mapping symbols for this address.  */
   4440   1.7  christos   if (info->symtab_size != 0
   4441   1.8  christos       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
   4442   1.1  christos     {
   4443   1.1  christos       int last_sym = -1;
   4444   1.1  christos       bfd_vma addr, section_vma = 0;
   4445   1.1  christos       bool can_use_search_opt_p;
   4446   1.1  christos       int n;
   4447   1.1  christos 
   4448   1.1  christos       if (pc <= last_mapping_addr)
   4449   1.1  christos 	last_mapping_sym = -1;
   4450   1.7  christos 
   4451   1.7  christos       /* Start scanning at the start of the function, or wherever
   4452   1.7  christos 	 we finished last time.  */
   4453   1.7  christos       n = info->symtab_pos + 1;
   4454   1.7  christos 
   4455   1.7  christos       /* If the last stop offset is different from the current one it means we
   4456   1.7  christos 	 are disassembling a different glob of bytes.  As such the optimization
   4457   1.7  christos 	 would not be safe and we should start over.  */
   4458   1.1  christos       can_use_search_opt_p = last_mapping_sym >= 0
   4459   1.1  christos 			     && info->stop_offset == last_stop_offset;
   4460   1.7  christos 
   4461   1.7  christos       if (n >= last_mapping_sym && can_use_search_opt_p)
   4462   1.7  christos 	n = last_mapping_sym;
   4463   1.7  christos 
   4464   1.1  christos       /* Look down while we haven't passed the location being disassembled.
   4465   1.1  christos 	 The reason for this is that there's no defined order between a symbol
   4466   1.1  christos 	 and an mapping symbol that may be at the same address.  We may have to
   4467   1.1  christos 	 look at least one position ahead.  */
   4468   1.1  christos       for (; n < info->symtab_size; n++)
   4469   1.6  christos 	{
   4470   1.1  christos 	  addr = bfd_asymbol_value (info->symtab[n]);
   4471   1.1  christos 	  if (addr > pc)
   4472   1.8  christos 	    break;
   4473   1.1  christos 	  if (get_sym_code_type (info, n, &type))
   4474   1.1  christos 	    {
   4475   1.1  christos 	      last_sym = n;
   4476   1.1  christos 	      found = true;
   4477   1.1  christos 	    }
   4478   1.1  christos 	}
   4479   1.7  christos 
   4480   1.1  christos       if (!found)
   4481   1.1  christos 	{
   4482   1.1  christos 	  n = info->symtab_pos;
   4483   1.7  christos 	  if (n >= last_mapping_sym && can_use_search_opt_p)
   4484   1.7  christos 	    n = last_mapping_sym;
   4485   1.7  christos 
   4486   1.7  christos 	  /* No mapping symbol found at this address.  Look backwards
   4487   1.7  christos 	     for a preceeding one, but don't go pass the section start
   4488   1.7  christos 	     otherwise a data section with no mapping symbol can pick up
   4489   1.7  christos 	     a text mapping symbol of a preceeding section.  The documentation
   4490   1.7  christos 	     says section can be NULL, in which case we will seek up all the
   4491   1.1  christos 	     way to the top.  */
   4492   1.1  christos 	  if (info->section)
   4493   1.7  christos 	    section_vma = info->section->vma;
   4494   1.7  christos 
   4495   1.7  christos 	  for (; n >= 0; n--)
   4496   1.7  christos 	    {
   4497   1.1  christos 	      addr = bfd_asymbol_value (info->symtab[n]);
   4498   1.1  christos 	      if (addr < section_vma)
   4499   1.1  christos 		break;
   4500   1.8  christos 
   4501   1.1  christos 	      if (get_sym_code_type (info, n, &type))
   4502   1.1  christos 		{
   4503   1.1  christos 		  last_sym = n;
   4504   1.1  christos 		  found = true;
   4505   1.1  christos 		  break;
   4506   1.1  christos 		}
   4507   1.1  christos 	    }
   4508   1.7  christos 	}
   4509   1.1  christos 
   4510   1.1  christos       last_mapping_sym = last_sym;
   4511   1.1  christos       last_type = type;
   4512   1.1  christos       last_stop_offset = info->stop_offset;
   4513   1.1  christos 
   4514   1.1  christos       /* Look a little bit ahead to see if we should print out
   4515   1.1  christos 	 less than four bytes of data.  If there's a symbol,
   4516   1.1  christos 	 mapping or otherwise, after two bytes then don't
   4517   1.1  christos 	 print more.  */
   4518   1.1  christos       if (last_type == MAP_DATA)
   4519   1.1  christos 	{
   4520   1.1  christos 	  size = 4 - (pc & 3);
   4521   1.1  christos 	  for (n = last_sym + 1; n < info->symtab_size; n++)
   4522   1.1  christos 	    {
   4523   1.1  christos 	      addr = bfd_asymbol_value (info->symtab[n]);
   4524   1.1  christos 	      if (addr > pc)
   4525   1.1  christos 		{
   4526   1.1  christos 		  if (addr - pc < size)
   4527   1.1  christos 		    size = addr - pc;
   4528   1.1  christos 		  break;
   4529   1.1  christos 		}
   4530   1.1  christos 	    }
   4531   1.1  christos 	  /* If the next symbol is after three bytes, we need to
   4532   1.1  christos 	     print only part of the data, so that we can use either
   4533   1.1  christos 	     .byte or .short.  */
   4534   1.7  christos 	  if (size == 3)
   4535   1.7  christos 	    size = (pc & 1) ? 1 : 2;
   4536   1.1  christos 	}
   4537   1.7  christos     }
   4538   1.7  christos   else
   4539   1.1  christos     last_type = type;
   4540   1.1  christos 
   4541   1.1  christos   /* PR 10263: Disassemble data if requested to do so by the user.  */
   4542   1.1  christos   if (last_type == MAP_DATA && ((info->flags & DISASSEMBLE_DATA) == 0))
   4543   1.1  christos     {
   4544   1.1  christos       /* size was set above.  */
   4545   1.1  christos       info->bytes_per_chunk = size;
   4546   1.1  christos       info->display_endian = info->endian;
   4547   1.1  christos       printer = print_insn_data;
   4548   1.1  christos     }
   4549   1.1  christos   else
   4550   1.1  christos     {
   4551   1.1  christos       info->bytes_per_chunk = size = INSNLEN;
   4552   1.1  christos       info->display_endian = info->endian_code;
   4553   1.1  christos       printer = print_insn_aarch64_word;
   4554   1.1  christos     }
   4555   1.1  christos 
   4556   1.1  christos   status = (*info->read_memory_func) (pc, buffer, size, info);
   4557   1.1  christos   if (status != 0)
   4558   1.1  christos     {
   4559   1.1  christos       (*info->memory_error_func) (status, pc, info);
   4560   1.1  christos       return -1;
   4561   1.1  christos     }
   4562   1.6  christos 
   4563   1.1  christos   data = bfd_get_bits (buffer, size * 8,
   4564   1.1  christos 		       info->display_endian == BFD_ENDIAN_BIG);
   4565   1.1  christos 
   4566   1.1  christos   (*printer) (pc, data, info, &errors);
   4567   1.1  christos 
   4568   1.1  christos   return size;
   4569   1.1  christos }
   4570   1.1  christos 
   4571   1.1  christos void
   4573   1.1  christos print_aarch64_disassembler_options (FILE *stream)
   4574   1.1  christos {
   4575   1.1  christos   fprintf (stream, _("\n\
   4576   1.1  christos The following AARCH64 specific disassembler options are supported for use\n\
   4577   1.1  christos with the -M switch (multiple options should be separated by commas):\n"));
   4578   1.1  christos 
   4579   1.1  christos   fprintf (stream, _("\n\
   4580   1.6  christos   no-aliases         Don't print instruction aliases.\n"));
   4581   1.6  christos 
   4582   1.6  christos   fprintf (stream, _("\n\
   4583   1.6  christos   aliases            Do print instruction aliases.\n"));
   4584   1.6  christos 
   4585   1.6  christos   fprintf (stream, _("\n\
   4586   1.1  christos   no-notes         Don't print instruction notes.\n"));
   4587   1.1  christos 
   4588   1.1  christos   fprintf (stream, _("\n\
   4589   1.1  christos   notes            Do print instruction notes.\n"));
   4590   1.1  christos 
   4591   1.1  christos #ifdef DEBUG_AARCH64
   4592   1.1  christos   fprintf (stream, _("\n\
   4593                   debug_dump         Temp switch for debug trace.\n"));
   4594                 #endif /* DEBUG_AARCH64 */
   4595                 
   4596                   fprintf (stream, _("\n"));
   4597                 }
   4598