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