Home | History | Annotate | Line # | Download | only in opcodes
aarch64-dis.c revision 1.3
      1  1.1  christos /* aarch64-dis.c -- AArch64 disassembler.
      2  1.3  christos    Copyright (C) 2009-2015 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.1  christos #include "dis-asm.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.1  christos 
     50  1.1  christos 
     52  1.1  christos static void
     53  1.1  christos set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
     54  1.1  christos {
     55  1.1  christos }
     56  1.1  christos 
     57  1.1  christos static void
     58  1.1  christos parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
     59  1.1  christos {
     60  1.1  christos   /* Try to match options that are simple flags */
     61  1.1  christos   if (CONST_STRNEQ (option, "no-aliases"))
     62  1.1  christos     {
     63  1.1  christos       no_aliases = 1;
     64  1.1  christos       return;
     65  1.1  christos     }
     66  1.1  christos 
     67  1.1  christos   if (CONST_STRNEQ (option, "aliases"))
     68  1.1  christos     {
     69  1.1  christos       no_aliases = 0;
     70  1.1  christos       return;
     71  1.1  christos     }
     72  1.1  christos 
     73  1.1  christos #ifdef DEBUG_AARCH64
     74  1.1  christos   if (CONST_STRNEQ (option, "debug_dump"))
     75  1.1  christos     {
     76  1.1  christos       debug_dump = 1;
     77  1.1  christos       return;
     78  1.1  christos     }
     79  1.1  christos #endif /* DEBUG_AARCH64 */
     80  1.1  christos 
     81  1.1  christos   /* Invalid option.  */
     82  1.1  christos   fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
     83  1.1  christos }
     84  1.1  christos 
     85  1.1  christos static void
     86  1.1  christos parse_aarch64_dis_options (const char *options)
     87  1.1  christos {
     88  1.1  christos   const char *option_end;
     89  1.1  christos 
     90  1.1  christos   if (options == NULL)
     91  1.1  christos     return;
     92  1.1  christos 
     93  1.1  christos   while (*options != '\0')
     94  1.1  christos     {
     95  1.1  christos       /* Skip empty options.  */
     96  1.1  christos       if (*options == ',')
     97  1.1  christos 	{
     98  1.1  christos 	  options++;
     99  1.1  christos 	  continue;
    100  1.1  christos 	}
    101  1.1  christos 
    102  1.1  christos       /* We know that *options is neither NUL or a comma.  */
    103  1.1  christos       option_end = options + 1;
    104  1.1  christos       while (*option_end != ',' && *option_end != '\0')
    105  1.1  christos 	option_end++;
    106  1.1  christos 
    107  1.1  christos       parse_aarch64_dis_option (options, option_end - options);
    108  1.1  christos 
    109  1.1  christos       /* Go on to the next one.  If option_end points to a comma, it
    110  1.1  christos 	 will be skipped above.  */
    111  1.1  christos       options = option_end;
    112  1.1  christos     }
    113  1.1  christos }
    114  1.1  christos 
    115  1.1  christos /* Functions doing the instruction disassembling.  */
    117  1.1  christos 
    118  1.1  christos /* The unnamed arguments consist of the number of fields and information about
    119  1.1  christos    these fields where the VALUE will be extracted from CODE and returned.
    120  1.1  christos    MASK can be zero or the base mask of the opcode.
    121  1.1  christos 
    122  1.1  christos    N.B. the fields are required to be in such an order than the most signficant
    123  1.3  christos    field for VALUE comes the first, e.g. the <index> in
    124  1.1  christos     SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    125  1.1  christos    is encoded in H:L:M in some cases, the fields H:L:M should be passed in
    126  1.1  christos    the order of H, L, M.  */
    127  1.1  christos 
    128  1.1  christos static inline aarch64_insn
    129  1.1  christos extract_fields (aarch64_insn code, aarch64_insn mask, ...)
    130  1.1  christos {
    131  1.1  christos   uint32_t num;
    132  1.1  christos   const aarch64_field *field;
    133  1.3  christos   enum aarch64_field_kind kind;
    134  1.1  christos   va_list va;
    135  1.1  christos 
    136  1.1  christos   va_start (va, mask);
    137  1.1  christos   num = va_arg (va, uint32_t);
    138  1.1  christos   assert (num <= 5);
    139  1.1  christos   aarch64_insn value = 0x0;
    140  1.1  christos   while (num--)
    141  1.1  christos     {
    142  1.1  christos       kind = va_arg (va, enum aarch64_field_kind);
    143  1.1  christos       field = &fields[kind];
    144  1.1  christos       value <<= field->width;
    145  1.1  christos       value |= extract_field (kind, code, mask);
    146  1.1  christos     }
    147  1.1  christos   return value;
    148  1.1  christos }
    149  1.1  christos 
    150  1.1  christos /* Sign-extend bit I of VALUE.  */
    151  1.1  christos static inline int32_t
    152  1.1  christos sign_extend (aarch64_insn value, unsigned i)
    153  1.3  christos {
    154  1.1  christos   uint32_t ret = value;
    155  1.1  christos 
    156  1.1  christos   assert (i < 32);
    157  1.1  christos   if ((value >> i) & 0x1)
    158  1.1  christos     {
    159  1.1  christos       uint32_t val = (uint32_t)(-1) << i;
    160  1.1  christos       ret = ret | val;
    161  1.1  christos     }
    162  1.1  christos   return (int32_t) ret;
    163  1.1  christos }
    164  1.1  christos 
    165  1.1  christos /* N.B. the following inline helpfer functions create a dependency on the
    166  1.1  christos    order of operand qualifier enumerators.  */
    167  1.1  christos 
    168  1.1  christos /* Given VALUE, return qualifier for a general purpose register.  */
    169  1.1  christos static inline enum aarch64_opnd_qualifier
    170  1.1  christos get_greg_qualifier_from_value (aarch64_insn value)
    171  1.1  christos {
    172  1.1  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
    173  1.1  christos   assert (value <= 0x1
    174  1.1  christos 	  && aarch64_get_qualifier_standard_value (qualifier) == value);
    175  1.1  christos   return qualifier;
    176  1.3  christos }
    177  1.3  christos 
    178  1.3  christos /* Given VALUE, return qualifier for a vector register.  This does not support
    179  1.1  christos    decoding instructions that accept the 2H vector type.  */
    180  1.1  christos 
    181  1.1  christos static inline enum aarch64_opnd_qualifier
    182  1.1  christos get_vreg_qualifier_from_value (aarch64_insn value)
    183  1.3  christos {
    184  1.3  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
    185  1.3  christos 
    186  1.3  christos   /* Instructions using vector type 2H should not call this function.  Skip over
    187  1.3  christos      the 2H qualifier.  */
    188  1.3  christos   if (qualifier >= AARCH64_OPND_QLF_V_2H)
    189  1.1  christos     qualifier += 1;
    190  1.1  christos 
    191  1.1  christos   assert (value <= 0x8
    192  1.1  christos 	  && aarch64_get_qualifier_standard_value (qualifier) == value);
    193  1.1  christos   return qualifier;
    194  1.1  christos }
    195  1.1  christos 
    196  1.1  christos /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register.  */
    197  1.1  christos static inline enum aarch64_opnd_qualifier
    198  1.1  christos get_sreg_qualifier_from_value (aarch64_insn value)
    199  1.3  christos {
    200  1.1  christos   enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
    201  1.1  christos 
    202  1.1  christos   assert (value <= 0x4
    203  1.1  christos 	  && aarch64_get_qualifier_standard_value (qualifier) == value);
    204  1.1  christos   return qualifier;
    205  1.1  christos }
    206  1.1  christos 
    207  1.1  christos /* Given the instruction in *INST which is probably half way through the
    208  1.1  christos    decoding and our caller wants to know the expected qualifier for operand
    209  1.1  christos    I.  Return such a qualifier if we can establish it; otherwise return
    210  1.1  christos    AARCH64_OPND_QLF_NIL.  */
    211  1.1  christos 
    212  1.1  christos static aarch64_opnd_qualifier_t
    213  1.1  christos get_expected_qualifier (const aarch64_inst *inst, int i)
    214  1.1  christos {
    215  1.1  christos   aarch64_opnd_qualifier_seq_t qualifiers;
    216  1.1  christos   /* Should not be called if the qualifier is known.  */
    217  1.1  christos   assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
    218  1.1  christos   if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
    219  1.1  christos 			       i, qualifiers))
    220  1.1  christos     return qualifiers[i];
    221  1.1  christos   else
    222  1.1  christos     return AARCH64_OPND_QLF_NIL;
    223  1.1  christos }
    224  1.1  christos 
    225  1.1  christos /* Operand extractors.  */
    226  1.1  christos 
    227  1.1  christos int
    228  1.1  christos aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
    229  1.1  christos 		   const aarch64_insn code,
    230  1.1  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED)
    231  1.1  christos {
    232  1.1  christos   info->reg.regno = extract_field (self->fields[0], code, 0);
    233  1.1  christos   return 1;
    234  1.3  christos }
    235  1.3  christos 
    236  1.3  christos int
    237  1.3  christos aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
    238  1.3  christos 		   const aarch64_insn code ATTRIBUTE_UNUSED,
    239  1.3  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED)
    240  1.3  christos {
    241  1.3  christos   assert (info->idx == 1
    242  1.3  christos 	  || info->idx ==3);
    243  1.3  christos   info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
    244  1.3  christos   return 1;
    245  1.1  christos }
    246  1.1  christos 
    247  1.1  christos /* e.g. IC <ic_op>{, <Xt>}.  */
    248  1.1  christos int
    249  1.1  christos aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
    250  1.1  christos 			  const aarch64_insn code,
    251  1.1  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED)
    252  1.1  christos {
    253  1.1  christos   info->reg.regno = extract_field (self->fields[0], code, 0);
    254  1.1  christos   assert (info->idx == 1
    255  1.1  christos 	  && (aarch64_get_operand_class (inst->operands[0].type)
    256  1.1  christos 	      == AARCH64_OPND_CLASS_SYSTEM));
    257  1.1  christos   /* This will make the constraint checking happy and more importantly will
    258  1.3  christos      help the disassembler determine whether this operand is optional or
    259  1.1  christos      not.  */
    260  1.1  christos   info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
    261  1.1  christos 
    262  1.1  christos   return 1;
    263  1.1  christos }
    264  1.1  christos 
    265  1.1  christos /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
    266  1.1  christos int
    267  1.1  christos aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
    268  1.1  christos 		     const aarch64_insn code,
    269  1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED)
    270  1.1  christos {
    271  1.1  christos   /* regno */
    272  1.1  christos   info->reglane.regno = extract_field (self->fields[0], code,
    273  1.3  christos 				       inst->opcode->mask);
    274  1.1  christos 
    275  1.1  christos   /* Index and/or type.  */
    276  1.1  christos   if (inst->opcode->iclass == asisdone
    277  1.1  christos     || inst->opcode->iclass == asimdins)
    278  1.1  christos     {
    279  1.1  christos       if (info->type == AARCH64_OPND_En
    280  1.1  christos 	  && inst->opcode->operands[0] == AARCH64_OPND_Ed)
    281  1.1  christos 	{
    282  1.1  christos 	  unsigned shift;
    283  1.1  christos 	  /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>].  */
    284  1.1  christos 	  assert (info->idx == 1);	/* Vn */
    285  1.1  christos 	  aarch64_insn value = extract_field (FLD_imm4, code, 0);
    286  1.1  christos 	  /* Depend on AARCH64_OPND_Ed to determine the qualifier.  */
    287  1.1  christos 	  info->qualifier = get_expected_qualifier (inst, info->idx);
    288  1.1  christos 	  shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
    289  1.1  christos 	  info->reglane.index = value >> shift;
    290  1.1  christos 	}
    291  1.1  christos       else
    292  1.1  christos 	{
    293  1.1  christos 	  /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
    294  1.1  christos 	     imm5<3:0>	<V>
    295  1.1  christos 	     0000	RESERVED
    296  1.1  christos 	     xxx1	B
    297  1.1  christos 	     xx10	H
    298  1.1  christos 	     x100	S
    299  1.1  christos 	     1000	D  */
    300  1.1  christos 	  int pos = -1;
    301  1.1  christos 	  aarch64_insn value = extract_field (FLD_imm5, code, 0);
    302  1.1  christos 	  while (++pos <= 3 && (value & 0x1) == 0)
    303  1.1  christos 	    value >>= 1;
    304  1.1  christos 	  if (pos > 3)
    305  1.1  christos 	    return 0;
    306  1.1  christos 	  info->qualifier = get_sreg_qualifier_from_value (pos);
    307  1.1  christos 	  info->reglane.index = (unsigned) (value >> 1);
    308  1.1  christos 	}
    309  1.1  christos     }
    310  1.3  christos   else
    311  1.1  christos     {
    312  1.1  christos       /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
    313  1.1  christos          or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>].  */
    314  1.1  christos 
    315  1.1  christos       /* Need information in other operand(s) to help decoding.  */
    316  1.1  christos       info->qualifier = get_expected_qualifier (inst, info->idx);
    317  1.1  christos       switch (info->qualifier)
    318  1.1  christos 	{
    319  1.1  christos 	case AARCH64_OPND_QLF_S_H:
    320  1.1  christos 	  /* h:l:m */
    321  1.1  christos 	  info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
    322  1.1  christos 						FLD_M);
    323  1.1  christos 	  info->reglane.regno &= 0xf;
    324  1.1  christos 	  break;
    325  1.1  christos 	case AARCH64_OPND_QLF_S_S:
    326  1.1  christos 	  /* h:l */
    327  1.1  christos 	  info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
    328  1.1  christos 	  break;
    329  1.1  christos 	case AARCH64_OPND_QLF_S_D:
    330  1.1  christos 	  /* H */
    331  1.1  christos 	  info->reglane.index = extract_field (FLD_H, code, 0);
    332  1.1  christos 	  break;
    333  1.1  christos 	default:
    334  1.1  christos 	  return 0;
    335  1.1  christos 	}
    336  1.1  christos     }
    337  1.1  christos 
    338  1.1  christos   return 1;
    339  1.1  christos }
    340  1.1  christos 
    341  1.1  christos int
    342  1.1  christos aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
    343  1.1  christos 		     const aarch64_insn code,
    344  1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED)
    345  1.1  christos {
    346  1.1  christos   /* R */
    347  1.1  christos   info->reglist.first_regno = extract_field (self->fields[0], code, 0);
    348  1.1  christos   /* len */
    349  1.1  christos   info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
    350  1.1  christos   return 1;
    351  1.1  christos }
    352  1.1  christos 
    353  1.1  christos /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions.  */
    354  1.1  christos int
    355  1.1  christos aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
    356  1.1  christos 			  aarch64_opnd_info *info, const aarch64_insn code,
    357  1.1  christos 			  const aarch64_inst *inst)
    358  1.1  christos {
    359  1.1  christos   aarch64_insn value;
    360  1.1  christos   /* Number of elements in each structure to be loaded/stored.  */
    361  1.1  christos   unsigned expected_num = get_opcode_dependent_value (inst->opcode);
    362  1.1  christos 
    363  1.1  christos   struct
    364  1.1  christos     {
    365  1.1  christos       unsigned is_reserved;
    366  1.1  christos       unsigned num_regs;
    367  1.1  christos       unsigned num_elements;
    368  1.1  christos     } data [] =
    369  1.1  christos   {   {0, 4, 4},
    370  1.1  christos       {1, 4, 4},
    371  1.1  christos       {0, 4, 1},
    372  1.1  christos       {0, 4, 2},
    373  1.1  christos       {0, 3, 3},
    374  1.1  christos       {1, 3, 3},
    375  1.1  christos       {0, 3, 1},
    376  1.1  christos       {0, 1, 1},
    377  1.1  christos       {0, 2, 2},
    378  1.1  christos       {1, 2, 2},
    379  1.1  christos       {0, 2, 1},
    380  1.1  christos   };
    381  1.1  christos 
    382  1.1  christos   /* Rt */
    383  1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    384  1.1  christos   /* opcode */
    385  1.1  christos   value = extract_field (FLD_opcode, code, 0);
    386  1.1  christos   if (expected_num != data[value].num_elements || data[value].is_reserved)
    387  1.1  christos     return 0;
    388  1.1  christos   info->reglist.num_regs = data[value].num_regs;
    389  1.1  christos 
    390  1.1  christos   return 1;
    391  1.1  christos }
    392  1.1  christos 
    393  1.1  christos /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
    394  1.1  christos    lanes instructions.  */
    395  1.1  christos int
    396  1.1  christos aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
    397  1.1  christos 			    aarch64_opnd_info *info, const aarch64_insn code,
    398  1.1  christos 			    const aarch64_inst *inst)
    399  1.1  christos {
    400  1.1  christos   aarch64_insn value;
    401  1.1  christos 
    402  1.1  christos   /* Rt */
    403  1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    404  1.1  christos   /* S */
    405  1.1  christos   value = extract_field (FLD_S, code, 0);
    406  1.1  christos 
    407  1.1  christos   /* Number of registers is equal to the number of elements in
    408  1.1  christos      each structure to be loaded/stored.  */
    409  1.1  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
    410  1.1  christos   assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
    411  1.1  christos 
    412  1.1  christos   /* Except when it is LD1R.  */
    413  1.1  christos   if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
    414  1.1  christos     info->reglist.num_regs = 2;
    415  1.1  christos 
    416  1.1  christos   return 1;
    417  1.1  christos }
    418  1.1  christos 
    419  1.1  christos /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
    420  1.1  christos    load/store single element instructions.  */
    421  1.1  christos int
    422  1.1  christos aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
    423  1.1  christos 			   aarch64_opnd_info *info, const aarch64_insn code,
    424  1.1  christos 			   const aarch64_inst *inst ATTRIBUTE_UNUSED)
    425  1.1  christos {
    426  1.1  christos   aarch64_field field = {0, 0};
    427  1.1  christos   aarch64_insn QSsize;		/* fields Q:S:size.  */
    428  1.1  christos   aarch64_insn opcodeh2;	/* opcode<2:1> */
    429  1.1  christos 
    430  1.1  christos   /* Rt */
    431  1.1  christos   info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
    432  1.1  christos 
    433  1.1  christos   /* Decode the index, opcode<2:1> and size.  */
    434  1.1  christos   gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
    435  1.1  christos   opcodeh2 = extract_field_2 (&field, code, 0);
    436  1.1  christos   QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
    437  1.1  christos   switch (opcodeh2)
    438  1.1  christos     {
    439  1.1  christos     case 0x0:
    440  1.1  christos       info->qualifier = AARCH64_OPND_QLF_S_B;
    441  1.1  christos       /* Index encoded in "Q:S:size".  */
    442  1.1  christos       info->reglist.index = QSsize;
    443  1.3  christos       break;
    444  1.3  christos     case 0x1:
    445  1.3  christos       if (QSsize & 0x1)
    446  1.1  christos 	/* UND.  */
    447  1.1  christos 	return 0;
    448  1.1  christos       info->qualifier = AARCH64_OPND_QLF_S_H;
    449  1.1  christos       /* Index encoded in "Q:S:size<1>".  */
    450  1.1  christos       info->reglist.index = QSsize >> 1;
    451  1.3  christos       break;
    452  1.3  christos     case 0x2:
    453  1.3  christos       if ((QSsize >> 1) & 0x1)
    454  1.1  christos 	/* UND.  */
    455  1.1  christos 	return 0;
    456  1.1  christos       if ((QSsize & 0x1) == 0)
    457  1.1  christos 	{
    458  1.1  christos 	  info->qualifier = AARCH64_OPND_QLF_S_S;
    459  1.1  christos 	  /* Index encoded in "Q:S".  */
    460  1.1  christos 	  info->reglist.index = QSsize >> 2;
    461  1.1  christos 	}
    462  1.3  christos       else
    463  1.3  christos 	{
    464  1.3  christos 	  if (extract_field (FLD_S, code, 0))
    465  1.1  christos 	    /* UND */
    466  1.1  christos 	    return 0;
    467  1.1  christos 	  info->qualifier = AARCH64_OPND_QLF_S_D;
    468  1.1  christos 	  /* Index encoded in "Q".  */
    469  1.1  christos 	  info->reglist.index = QSsize >> 3;
    470  1.1  christos 	}
    471  1.1  christos       break;
    472  1.1  christos     default:
    473  1.1  christos       return 0;
    474  1.1  christos     }
    475  1.1  christos 
    476  1.1  christos   info->reglist.has_index = 1;
    477  1.1  christos   info->reglist.num_regs = 0;
    478  1.1  christos   /* Number of registers is equal to the number of elements in
    479  1.1  christos      each structure to be loaded/stored.  */
    480  1.1  christos   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
    481  1.1  christos   assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
    482  1.1  christos 
    483  1.1  christos   return 1;
    484  1.1  christos }
    485  1.1  christos 
    486  1.1  christos /* Decode fields immh:immb and/or Q for e.g.
    487  1.1  christos    SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
    488  1.1  christos    or SSHR <V><d>, <V><n>, #<shift>.  */
    489  1.1  christos 
    490  1.1  christos int
    491  1.1  christos aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
    492  1.1  christos 			       aarch64_opnd_info *info, const aarch64_insn code,
    493  1.1  christos 			       const aarch64_inst *inst)
    494  1.1  christos {
    495  1.1  christos   int pos;
    496  1.1  christos   aarch64_insn Q, imm, immh;
    497  1.1  christos   enum aarch64_insn_class iclass = inst->opcode->iclass;
    498  1.1  christos 
    499  1.1  christos   immh = extract_field (FLD_immh, code, 0);
    500  1.1  christos   if (immh == 0)
    501  1.1  christos     return 0;
    502  1.1  christos   imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
    503  1.1  christos   pos = 4;
    504  1.1  christos   /* Get highest set bit in immh.  */
    505  1.1  christos   while (--pos >= 0 && (immh & 0x8) == 0)
    506  1.1  christos     immh <<= 1;
    507  1.1  christos 
    508  1.1  christos   assert ((iclass == asimdshf || iclass == asisdshf)
    509  1.1  christos 	  && (info->type == AARCH64_OPND_IMM_VLSR
    510  1.1  christos 	      || info->type == AARCH64_OPND_IMM_VLSL));
    511  1.1  christos 
    512  1.1  christos   if (iclass == asimdshf)
    513  1.1  christos     {
    514  1.1  christos       Q = extract_field (FLD_Q, code, 0);
    515  1.1  christos       /* immh	Q	<T>
    516  1.1  christos 	 0000	x	SEE AdvSIMD modified immediate
    517  1.1  christos 	 0001	0	8B
    518  1.1  christos 	 0001	1	16B
    519  1.1  christos 	 001x	0	4H
    520  1.1  christos 	 001x	1	8H
    521  1.1  christos 	 01xx	0	2S
    522  1.1  christos 	 01xx	1	4S
    523  1.1  christos 	 1xxx	0	RESERVED
    524  1.1  christos 	 1xxx	1	2D  */
    525  1.1  christos       info->qualifier =
    526  1.1  christos 	get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
    527  1.1  christos     }
    528  1.1  christos   else
    529  1.1  christos     info->qualifier = get_sreg_qualifier_from_value (pos);
    530  1.1  christos 
    531  1.1  christos   if (info->type == AARCH64_OPND_IMM_VLSR)
    532  1.1  christos     /* immh	<shift>
    533  1.1  christos        0000	SEE AdvSIMD modified immediate
    534  1.1  christos        0001	(16-UInt(immh:immb))
    535  1.1  christos        001x	(32-UInt(immh:immb))
    536  1.1  christos        01xx	(64-UInt(immh:immb))
    537  1.1  christos        1xxx	(128-UInt(immh:immb))  */
    538  1.1  christos     info->imm.value = (16 << pos) - imm;
    539  1.1  christos   else
    540  1.1  christos     /* immh:immb
    541  1.1  christos        immh	<shift>
    542  1.1  christos        0000	SEE AdvSIMD modified immediate
    543  1.1  christos        0001	(UInt(immh:immb)-8)
    544  1.1  christos        001x	(UInt(immh:immb)-16)
    545  1.1  christos        01xx	(UInt(immh:immb)-32)
    546  1.1  christos        1xxx	(UInt(immh:immb)-64)  */
    547  1.1  christos     info->imm.value = imm - (8 << pos);
    548  1.1  christos 
    549  1.1  christos   return 1;
    550  1.1  christos }
    551  1.1  christos 
    552  1.1  christos /* Decode shift immediate for e.g. sshr (imm).  */
    553  1.1  christos int
    554  1.1  christos aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
    555  1.1  christos 		      aarch64_opnd_info *info, const aarch64_insn code,
    556  1.1  christos 		      const aarch64_inst *inst ATTRIBUTE_UNUSED)
    557  1.1  christos {
    558  1.1  christos   int64_t imm;
    559  1.1  christos   aarch64_insn val;
    560  1.1  christos   val = extract_field (FLD_size, code, 0);
    561  1.1  christos   switch (val)
    562  1.1  christos     {
    563  1.1  christos     case 0: imm = 8; break;
    564  1.1  christos     case 1: imm = 16; break;
    565  1.1  christos     case 2: imm = 32; break;
    566  1.1  christos     default: return 0;
    567  1.1  christos     }
    568  1.1  christos   info->imm.value = imm;
    569  1.1  christos   return 1;
    570  1.1  christos }
    571  1.1  christos 
    572  1.1  christos /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
    573  1.1  christos    value in the field(s) will be extracted as unsigned immediate value.  */
    574  1.1  christos int
    575  1.1  christos aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
    576  1.1  christos 		 const aarch64_insn code,
    577  1.1  christos 		 const aarch64_inst *inst ATTRIBUTE_UNUSED)
    578  1.1  christos {
    579  1.1  christos   int64_t imm;
    580  1.1  christos   /* Maximum of two fields to extract.  */
    581  1.1  christos   assert (self->fields[2] == FLD_NIL);
    582  1.1  christos 
    583  1.1  christos   if (self->fields[1] == FLD_NIL)
    584  1.1  christos     imm = extract_field (self->fields[0], code, 0);
    585  1.1  christos   else
    586  1.1  christos     /* e.g. TBZ b5:b40.  */
    587  1.1  christos     imm = extract_fields (code, 0, 2, self->fields[0], self->fields[1]);
    588  1.1  christos 
    589  1.1  christos   if (info->type == AARCH64_OPND_FPIMM)
    590  1.1  christos     info->imm.is_fp = 1;
    591  1.1  christos 
    592  1.1  christos   if (operand_need_sign_extension (self))
    593  1.1  christos     imm = sign_extend (imm, get_operand_fields_width (self) - 1);
    594  1.1  christos 
    595  1.1  christos   if (operand_need_shift_by_two (self))
    596  1.1  christos     imm <<= 2;
    597  1.1  christos 
    598  1.1  christos   if (info->type == AARCH64_OPND_ADDR_ADRP)
    599  1.1  christos     imm <<= 12;
    600  1.1  christos 
    601  1.1  christos   info->imm.value = imm;
    602  1.1  christos   return 1;
    603  1.1  christos }
    604  1.1  christos 
    605  1.1  christos /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}.  */
    606  1.1  christos int
    607  1.1  christos aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
    608  1.1  christos 		      const aarch64_insn code,
    609  1.1  christos 		      const aarch64_inst *inst ATTRIBUTE_UNUSED)
    610  1.1  christos {
    611  1.1  christos   aarch64_ext_imm (self, info, code, inst);
    612  1.1  christos   info->shifter.kind = AARCH64_MOD_LSL;
    613  1.1  christos   info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
    614  1.1  christos   return 1;
    615  1.1  christos }
    616  1.1  christos 
    617  1.1  christos /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
    618  1.1  christos      MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}.  */
    619  1.1  christos int
    620  1.1  christos aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
    621  1.1  christos 				  aarch64_opnd_info *info,
    622  1.1  christos 				  const aarch64_insn code,
    623  1.1  christos 				  const aarch64_inst *inst ATTRIBUTE_UNUSED)
    624  1.1  christos {
    625  1.1  christos   uint64_t imm;
    626  1.1  christos   enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
    627  1.1  christos   aarch64_field field = {0, 0};
    628  1.1  christos 
    629  1.1  christos   assert (info->idx == 1);
    630  1.1  christos 
    631  1.1  christos   if (info->type == AARCH64_OPND_SIMD_FPIMM)
    632  1.1  christos     info->imm.is_fp = 1;
    633  1.1  christos 
    634  1.1  christos   /* a:b:c:d:e:f:g:h */
    635  1.1  christos   imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
    636  1.1  christos   if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
    637  1.1  christos     {
    638  1.1  christos       /* Either MOVI <Dd>, #<imm>
    639  1.1  christos 	 or     MOVI <Vd>.2D, #<imm>.
    640  1.1  christos 	 <imm> is a 64-bit immediate
    641  1.1  christos 	 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
    642  1.1  christos 	 encoded in "a:b:c:d:e:f:g:h".	*/
    643  1.1  christos       int i;
    644  1.1  christos       unsigned abcdefgh = imm;
    645  1.1  christos       for (imm = 0ull, i = 0; i < 8; i++)
    646  1.1  christos 	if (((abcdefgh >> i) & 0x1) != 0)
    647  1.1  christos 	  imm |= 0xffull << (8 * i);
    648  1.1  christos     }
    649  1.1  christos   info->imm.value = imm;
    650  1.1  christos 
    651  1.1  christos   /* cmode */
    652  1.1  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
    653  1.1  christos   switch (info->qualifier)
    654  1.1  christos     {
    655  1.1  christos     case AARCH64_OPND_QLF_NIL:
    656  1.1  christos       /* no shift */
    657  1.1  christos       info->shifter.kind = AARCH64_MOD_NONE;
    658  1.1  christos       return 1;
    659  1.1  christos     case AARCH64_OPND_QLF_LSL:
    660  1.1  christos       /* shift zeros */
    661  1.1  christos       info->shifter.kind = AARCH64_MOD_LSL;
    662  1.1  christos       switch (aarch64_get_qualifier_esize (opnd0_qualifier))
    663  1.1  christos 	{
    664  1.3  christos 	case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break;	/* per word */
    665  1.1  christos 	case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break;	/* per half */
    666  1.1  christos 	case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break;	/* per byte */
    667  1.1  christos 	default: assert (0); return 0;
    668  1.1  christos 	}
    669  1.1  christos       /* 00: 0; 01: 8; 10:16; 11:24.  */
    670  1.1  christos       info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
    671  1.1  christos       break;
    672  1.1  christos     case AARCH64_OPND_QLF_MSL:
    673  1.1  christos       /* shift ones */
    674  1.1  christos       info->shifter.kind = AARCH64_MOD_MSL;
    675  1.1  christos       gen_sub_field (FLD_cmode, 0, 1, &field);		/* per word */
    676  1.1  christos       info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
    677  1.1  christos       break;
    678  1.1  christos     default:
    679  1.1  christos       assert (0);
    680  1.1  christos       return 0;
    681  1.1  christos     }
    682  1.1  christos 
    683  1.1  christos   return 1;
    684  1.1  christos }
    685  1.1  christos 
    686  1.1  christos /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>.  */
    687  1.1  christos int
    688  1.1  christos aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
    689  1.1  christos 		   aarch64_opnd_info *info, const aarch64_insn code,
    690  1.1  christos 		   const aarch64_inst *inst ATTRIBUTE_UNUSED)
    691  1.1  christos {
    692  1.1  christos   info->imm.value = 64- extract_field (FLD_scale, code, 0);
    693  1.1  christos   return 1;
    694  1.1  christos }
    695  1.1  christos 
    696  1.1  christos /* Decode arithmetic immediate for e.g.
    697  1.1  christos      SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}.  */
    698  1.1  christos int
    699  1.1  christos aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
    700  1.1  christos 		  aarch64_opnd_info *info, const aarch64_insn code,
    701  1.1  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED)
    702  1.1  christos {
    703  1.1  christos   aarch64_insn value;
    704  1.1  christos 
    705  1.1  christos   info->shifter.kind = AARCH64_MOD_LSL;
    706  1.1  christos   /* shift */
    707  1.1  christos   value = extract_field (FLD_shift, code, 0);
    708  1.1  christos   if (value >= 2)
    709  1.1  christos     return 0;
    710  1.1  christos   info->shifter.amount = value ? 12 : 0;
    711  1.1  christos   /* imm12 (unsigned) */
    712  1.1  christos   info->imm.value = extract_field (FLD_imm12, code, 0);
    713  1.1  christos 
    714  1.1  christos   return 1;
    715  1.1  christos }
    716  1.1  christos 
    717  1.1  christos /* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */
    718  1.1  christos 
    719  1.1  christos int
    720  1.1  christos aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
    721  1.1  christos 		  aarch64_opnd_info *info, const aarch64_insn code,
    722  1.1  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED)
    723  1.1  christos {
    724  1.1  christos   uint64_t imm, mask;
    725  1.1  christos   uint32_t sf;
    726  1.1  christos   uint32_t N, R, S;
    727  1.1  christos   unsigned simd_size;
    728  1.1  christos   aarch64_insn value;
    729  1.1  christos 
    730  1.1  christos   value = extract_fields (code, 0, 3, FLD_N, FLD_immr, FLD_imms);
    731  1.1  christos   assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_W
    732  1.1  christos 	  || inst->operands[0].qualifier == AARCH64_OPND_QLF_X);
    733  1.1  christos   sf = aarch64_get_qualifier_esize (inst->operands[0].qualifier) != 4;
    734  1.1  christos 
    735  1.1  christos   /* value is N:immr:imms.  */
    736  1.1  christos   S = value & 0x3f;
    737  1.1  christos   R = (value >> 6) & 0x3f;
    738  1.1  christos   N = (value >> 12) & 0x1;
    739  1.1  christos 
    740  1.1  christos   if (sf == 0 && N == 1)
    741  1.1  christos     return 0;
    742  1.3  christos 
    743  1.1  christos   /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
    744  1.1  christos      (in other words, right rotated by R), then replicated.  */
    745  1.1  christos   if (N != 0)
    746  1.1  christos     {
    747  1.1  christos       simd_size = 64;
    748  1.1  christos       mask = 0xffffffffffffffffull;
    749  1.1  christos     }
    750  1.1  christos   else
    751  1.1  christos     {
    752  1.1  christos       switch (S)
    753  1.1  christos 	{
    754  1.1  christos 	case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32;           break;
    755  1.1  christos 	case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
    756  1.1  christos 	case 0x30 ... 0x37: /* 110xxx */ simd_size =  8; S &= 0x7; break;
    757  1.1  christos 	case 0x38 ... 0x3b: /* 1110xx */ simd_size =  4; S &= 0x3; break;
    758  1.1  christos 	case 0x3c ... 0x3d: /* 11110x */ simd_size =  2; S &= 0x1; break;
    759  1.1  christos 	default: return 0;
    760  1.1  christos 	}
    761  1.1  christos       mask = (1ull << simd_size) - 1;
    762  1.1  christos       /* Top bits are IGNORED.  */
    763  1.1  christos       R &= simd_size - 1;
    764  1.1  christos     }
    765  1.1  christos   /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
    766  1.1  christos   if (S == simd_size - 1)
    767  1.1  christos     return 0;
    768  1.1  christos   /* S+1 consecutive bits to 1.  */
    769  1.1  christos   /* NOTE: S can't be 63 due to detection above.  */
    770  1.1  christos   imm = (1ull << (S + 1)) - 1;
    771  1.1  christos   /* Rotate to the left by simd_size - R.  */
    772  1.1  christos   if (R != 0)
    773  1.1  christos     imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
    774  1.1  christos   /* Replicate the value according to SIMD size.  */
    775  1.1  christos   switch (simd_size)
    776  1.1  christos     {
    777  1.1  christos     case  2: imm = (imm <<  2) | imm;
    778  1.1  christos     case  4: imm = (imm <<  4) | imm;
    779  1.1  christos     case  8: imm = (imm <<  8) | imm;
    780  1.1  christos     case 16: imm = (imm << 16) | imm;
    781  1.1  christos     case 32: imm = (imm << 32) | imm;
    782  1.1  christos     case 64: break;
    783  1.1  christos     default: assert (0); return 0;
    784  1.1  christos     }
    785  1.1  christos 
    786  1.1  christos   info->imm.value = sf ? imm : imm & 0xffffffff;
    787  1.1  christos 
    788  1.1  christos   return 1;
    789  1.1  christos }
    790  1.1  christos 
    791  1.1  christos /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
    792  1.1  christos    or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>.  */
    793  1.1  christos int
    794  1.1  christos aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
    795  1.1  christos 		aarch64_opnd_info *info,
    796  1.1  christos 		const aarch64_insn code, const aarch64_inst *inst)
    797  1.1  christos {
    798  1.1  christos   aarch64_insn value;
    799  1.1  christos 
    800  1.1  christos   /* Rt */
    801  1.1  christos   info->reg.regno = extract_field (FLD_Rt, code, 0);
    802  1.1  christos 
    803  1.1  christos   /* size */
    804  1.1  christos   value = extract_field (FLD_ldst_size, code, 0);
    805  1.1  christos   if (inst->opcode->iclass == ldstpair_indexed
    806  1.1  christos       || inst->opcode->iclass == ldstnapair_offs
    807  1.1  christos       || inst->opcode->iclass == ldstpair_off
    808  1.1  christos       || inst->opcode->iclass == loadlit)
    809  1.1  christos     {
    810  1.1  christos       enum aarch64_opnd_qualifier qualifier;
    811  1.1  christos       switch (value)
    812  1.1  christos 	{
    813  1.1  christos 	case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
    814  1.1  christos 	case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
    815  1.1  christos 	case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
    816  1.1  christos 	default: return 0;
    817  1.1  christos 	}
    818  1.1  christos       info->qualifier = qualifier;
    819  1.1  christos     }
    820  1.1  christos   else
    821  1.1  christos     {
    822  1.1  christos       /* opc1:size */
    823  1.1  christos       value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
    824  1.1  christos       if (value > 0x4)
    825  1.1  christos 	return 0;
    826  1.1  christos       info->qualifier = get_sreg_qualifier_from_value (value);
    827  1.1  christos     }
    828  1.1  christos 
    829  1.1  christos   return 1;
    830  1.1  christos }
    831  1.1  christos 
    832  1.1  christos /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}].  */
    833  1.1  christos int
    834  1.1  christos aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
    835  1.1  christos 			 aarch64_opnd_info *info,
    836  1.1  christos 			 aarch64_insn code,
    837  1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED)
    838  1.1  christos {
    839  1.1  christos   /* Rn */
    840  1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
    841  1.1  christos   return 1;
    842  1.1  christos }
    843  1.1  christos 
    844  1.1  christos /* Decode the address operand for e.g.
    845  1.1  christos      STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
    846  1.1  christos int
    847  1.1  christos aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
    848  1.1  christos 			 aarch64_opnd_info *info,
    849  1.1  christos 			 aarch64_insn code, const aarch64_inst *inst)
    850  1.1  christos {
    851  1.1  christos   aarch64_insn S, value;
    852  1.1  christos 
    853  1.1  christos   /* Rn */
    854  1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
    855  1.1  christos   /* Rm */
    856  1.1  christos   info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
    857  1.1  christos   /* option */
    858  1.1  christos   value = extract_field (FLD_option, code, 0);
    859  1.1  christos   info->shifter.kind =
    860  1.1  christos     aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
    861  1.1  christos   /* Fix-up the shifter kind; although the table-driven approach is
    862  1.1  christos      efficient, it is slightly inflexible, thus needing this fix-up.  */
    863  1.1  christos   if (info->shifter.kind == AARCH64_MOD_UXTX)
    864  1.1  christos     info->shifter.kind = AARCH64_MOD_LSL;
    865  1.1  christos   /* S */
    866  1.1  christos   S = extract_field (FLD_S, code, 0);
    867  1.1  christos   if (S == 0)
    868  1.1  christos     {
    869  1.1  christos       info->shifter.amount = 0;
    870  1.1  christos       info->shifter.amount_present = 0;
    871  1.1  christos     }
    872  1.1  christos   else
    873  1.1  christos     {
    874  1.1  christos       int size;
    875  1.1  christos       /* Need information in other operand(s) to help achieve the decoding
    876  1.1  christos 	 from 'S' field.  */
    877  1.1  christos       info->qualifier = get_expected_qualifier (inst, info->idx);
    878  1.1  christos       /* Get the size of the data element that is accessed, which may be
    879  1.1  christos 	 different from that of the source register size, e.g. in strb/ldrb.  */
    880  1.1  christos       size = aarch64_get_qualifier_esize (info->qualifier);
    881  1.1  christos       info->shifter.amount = get_logsz (size);
    882  1.1  christos       info->shifter.amount_present = 1;
    883  1.1  christos     }
    884  1.1  christos 
    885  1.1  christos   return 1;
    886  1.1  christos }
    887  1.1  christos 
    888  1.1  christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>.  */
    889  1.1  christos int
    890  1.1  christos aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
    891  1.1  christos 		       aarch64_insn code, const aarch64_inst *inst)
    892  1.1  christos {
    893  1.1  christos   aarch64_insn imm;
    894  1.1  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
    895  1.1  christos 
    896  1.1  christos   /* Rn */
    897  1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
    898  1.1  christos   /* simm (imm9 or imm7)  */
    899  1.1  christos   imm = extract_field (self->fields[0], code, 0);
    900  1.1  christos   info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
    901  1.1  christos   if (self->fields[0] == FLD_imm7)
    902  1.1  christos     /* scaled immediate in ld/st pair instructions.  */
    903  1.1  christos     info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
    904  1.1  christos   /* qualifier */
    905  1.1  christos   if (inst->opcode->iclass == ldst_unscaled
    906  1.1  christos       || inst->opcode->iclass == ldstnapair_offs
    907  1.1  christos       || inst->opcode->iclass == ldstpair_off
    908  1.1  christos       || inst->opcode->iclass == ldst_unpriv)
    909  1.1  christos     info->addr.writeback = 0;
    910  1.1  christos   else
    911  1.1  christos     {
    912  1.1  christos       /* pre/post- index */
    913  1.1  christos       info->addr.writeback = 1;
    914  1.1  christos       if (extract_field (self->fields[1], code, 0) == 1)
    915  1.1  christos 	info->addr.preind = 1;
    916  1.1  christos       else
    917  1.1  christos 	info->addr.postind = 1;
    918  1.1  christos     }
    919  1.1  christos 
    920  1.1  christos   return 1;
    921  1.1  christos }
    922  1.1  christos 
    923  1.1  christos /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}].  */
    924  1.1  christos int
    925  1.1  christos aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
    926  1.1  christos 			 aarch64_insn code,
    927  1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED)
    928  1.1  christos {
    929  1.1  christos   int shift;
    930  1.1  christos   info->qualifier = get_expected_qualifier (inst, info->idx);
    931  1.1  christos   shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
    932  1.1  christos   /* Rn */
    933  1.1  christos   info->addr.base_regno = extract_field (self->fields[0], code, 0);
    934  1.1  christos   /* uimm12 */
    935  1.1  christos   info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
    936  1.1  christos   return 1;
    937  1.1  christos }
    938  1.1  christos 
    939  1.1  christos /* Decode the address operand for e.g.
    940  1.1  christos      LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>.  */
    941  1.1  christos int
    942  1.1  christos aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
    943  1.1  christos 			    aarch64_opnd_info *info,
    944  1.1  christos 			    aarch64_insn code, const aarch64_inst *inst)
    945  1.1  christos {
    946  1.1  christos   /* The opcode dependent area stores the number of elements in
    947  1.1  christos      each structure to be loaded/stored.  */
    948  1.1  christos   int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
    949  1.1  christos 
    950  1.1  christos   /* Rn */
    951  1.1  christos   info->addr.base_regno = extract_field (FLD_Rn, code, 0);
    952  1.1  christos   /* Rm | #<amount>  */
    953  1.1  christos   info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
    954  1.1  christos   if (info->addr.offset.regno == 31)
    955  1.1  christos     {
    956  1.1  christos       if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
    957  1.1  christos 	/* Special handling of loading single structure to all lane.  */
    958  1.1  christos 	info->addr.offset.imm = (is_ld1r ? 1
    959  1.1  christos 				 : inst->operands[0].reglist.num_regs)
    960  1.1  christos 	  * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
    961  1.1  christos       else
    962  1.1  christos 	info->addr.offset.imm = inst->operands[0].reglist.num_regs
    963  1.1  christos 	  * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
    964  1.1  christos 	  * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
    965  1.1  christos     }
    966  1.1  christos   else
    967  1.1  christos     info->addr.offset.is_reg = 1;
    968  1.1  christos   info->addr.writeback = 1;
    969  1.1  christos 
    970  1.1  christos   return 1;
    971  1.1  christos }
    972  1.1  christos 
    973  1.1  christos /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>.  */
    974  1.1  christos int
    975  1.1  christos aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
    976  1.1  christos 		  aarch64_opnd_info *info,
    977  1.1  christos 		  aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
    978  1.1  christos {
    979  1.1  christos   aarch64_insn value;
    980  1.1  christos   /* cond */
    981  1.1  christos   value = extract_field (FLD_cond, code, 0);
    982  1.1  christos   info->cond = get_cond_from_value (value);
    983  1.1  christos   return 1;
    984  1.1  christos }
    985  1.1  christos 
    986  1.1  christos /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>.  */
    987  1.1  christos int
    988  1.1  christos aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
    989  1.1  christos 		    aarch64_opnd_info *info,
    990  1.1  christos 		    aarch64_insn code,
    991  1.1  christos 		    const aarch64_inst *inst ATTRIBUTE_UNUSED)
    992  1.1  christos {
    993  1.1  christos   /* op0:op1:CRn:CRm:op2 */
    994  1.1  christos   info->sysreg = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
    995  1.1  christos 				 FLD_CRm, FLD_op2);
    996  1.1  christos   return 1;
    997  1.1  christos }
    998  1.1  christos 
    999  1.1  christos /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>.  */
   1000  1.1  christos int
   1001  1.1  christos aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1002  1.1  christos 			 aarch64_opnd_info *info, aarch64_insn code,
   1003  1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1004  1.1  christos {
   1005  1.1  christos   int i;
   1006  1.1  christos   /* op1:op2 */
   1007  1.1  christos   info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
   1008  1.1  christos   for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
   1009  1.1  christos     if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
   1010  1.1  christos       return 1;
   1011  1.1  christos   /* Reserved value in <pstatefield>.  */
   1012  1.1  christos   return 0;
   1013  1.1  christos }
   1014  1.1  christos 
   1015  1.1  christos /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>.  */
   1016  1.1  christos int
   1017  1.1  christos aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1018  1.1  christos 		       aarch64_opnd_info *info,
   1019  1.1  christos 		       aarch64_insn code,
   1020  1.1  christos 		       const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1021  1.1  christos {
   1022  1.1  christos   int i;
   1023  1.1  christos   aarch64_insn value;
   1024  1.1  christos   const aarch64_sys_ins_reg *sysins_ops;
   1025  1.1  christos   /* op0:op1:CRn:CRm:op2 */
   1026  1.1  christos   value = extract_fields (code, 0, 5,
   1027  1.1  christos 			  FLD_op0, FLD_op1, FLD_CRn,
   1028  1.1  christos 			  FLD_CRm, FLD_op2);
   1029  1.1  christos 
   1030  1.1  christos   switch (info->type)
   1031  1.1  christos     {
   1032  1.1  christos     case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
   1033  1.1  christos     case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
   1034  1.1  christos     case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
   1035  1.1  christos     case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
   1036  1.1  christos     default: assert (0); return 0;
   1037  1.3  christos     }
   1038  1.1  christos 
   1039  1.1  christos   for (i = 0; sysins_ops[i].name != NULL; ++i)
   1040  1.1  christos     if (sysins_ops[i].value == value)
   1041  1.1  christos       {
   1042  1.3  christos 	info->sysins_op = sysins_ops + i;
   1043  1.1  christos 	DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
   1044  1.3  christos 		     info->sysins_op->name,
   1045  1.1  christos 		     (unsigned)info->sysins_op->value,
   1046  1.1  christos 		     aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
   1047  1.1  christos 	return 1;
   1048  1.1  christos       }
   1049  1.1  christos 
   1050  1.1  christos   return 0;
   1051  1.1  christos }
   1052  1.1  christos 
   1053  1.1  christos /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>.  */
   1054  1.1  christos 
   1055  1.1  christos int
   1056  1.1  christos aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1057  1.1  christos 		     aarch64_opnd_info *info,
   1058  1.1  christos 		     aarch64_insn code,
   1059  1.1  christos 		     const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1060  1.1  christos {
   1061  1.1  christos   /* CRm */
   1062  1.1  christos   info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
   1063  1.1  christos   return 1;
   1064  1.1  christos }
   1065  1.1  christos 
   1066  1.1  christos /* Decode the prefetch operation option operand for e.g.
   1067  1.1  christos      PRFM <prfop>, [<Xn|SP>{, #<pimm>}].  */
   1068  1.1  christos 
   1069  1.1  christos int
   1070  1.1  christos aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1071  1.1  christos 		   aarch64_opnd_info *info,
   1072  1.1  christos 		   aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1073  1.1  christos {
   1074  1.1  christos   /* prfop in Rt */
   1075  1.1  christos   info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
   1076  1.1  christos   return 1;
   1077  1.3  christos }
   1078  1.3  christos 
   1079  1.3  christos /* Decode the hint number for an alias taking an operand.  Set info->hint_option
   1080  1.3  christos    to the matching name/value pair in aarch64_hint_options.  */
   1081  1.3  christos 
   1082  1.3  christos int
   1083  1.3  christos aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1084  1.3  christos 		  aarch64_opnd_info *info,
   1085  1.3  christos 		  aarch64_insn code,
   1086  1.3  christos 		  const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1087  1.3  christos {
   1088  1.3  christos   /* CRm:op2.  */
   1089  1.3  christos   unsigned hint_number;
   1090  1.3  christos   int i;
   1091  1.3  christos 
   1092  1.3  christos   hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
   1093  1.3  christos 
   1094  1.3  christos   for (i = 0; aarch64_hint_options[i].name != NULL; i++)
   1095  1.3  christos     {
   1096  1.3  christos       if (hint_number == aarch64_hint_options[i].value)
   1097  1.3  christos 	{
   1098  1.3  christos 	  info->hint_option = &(aarch64_hint_options[i]);
   1099  1.3  christos 	  return 1;
   1100  1.3  christos 	}
   1101  1.3  christos     }
   1102  1.3  christos 
   1103  1.3  christos   return 0;
   1104  1.1  christos }
   1105  1.1  christos 
   1106  1.1  christos /* Decode the extended register operand for e.g.
   1107  1.1  christos      STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}].  */
   1108  1.1  christos int
   1109  1.1  christos aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1110  1.1  christos 			  aarch64_opnd_info *info,
   1111  1.1  christos 			  aarch64_insn code,
   1112  1.1  christos 			  const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1113  1.1  christos {
   1114  1.1  christos   aarch64_insn value;
   1115  1.1  christos 
   1116  1.1  christos   /* Rm */
   1117  1.1  christos   info->reg.regno = extract_field (FLD_Rm, code, 0);
   1118  1.1  christos   /* option */
   1119  1.1  christos   value = extract_field (FLD_option, code, 0);
   1120  1.1  christos   info->shifter.kind =
   1121  1.1  christos     aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
   1122  1.1  christos   /* imm3 */
   1123  1.1  christos   info->shifter.amount = extract_field (FLD_imm3, code,  0);
   1124  1.1  christos 
   1125  1.1  christos   /* This makes the constraint checking happy.  */
   1126  1.1  christos   info->shifter.operator_present = 1;
   1127  1.1  christos 
   1128  1.1  christos   /* Assume inst->operands[0].qualifier has been resolved.  */
   1129  1.1  christos   assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
   1130  1.1  christos   info->qualifier = AARCH64_OPND_QLF_W;
   1131  1.1  christos   if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
   1132  1.1  christos       && (info->shifter.kind == AARCH64_MOD_UXTX
   1133  1.1  christos 	  || info->shifter.kind == AARCH64_MOD_SXTX))
   1134  1.1  christos     info->qualifier = AARCH64_OPND_QLF_X;
   1135  1.1  christos 
   1136  1.1  christos   return 1;
   1137  1.1  christos }
   1138  1.1  christos 
   1139  1.1  christos /* Decode the shifted register operand for e.g.
   1140  1.1  christos      SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}.  */
   1141  1.1  christos int
   1142  1.1  christos aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
   1143  1.1  christos 			 aarch64_opnd_info *info,
   1144  1.1  christos 			 aarch64_insn code,
   1145  1.1  christos 			 const aarch64_inst *inst ATTRIBUTE_UNUSED)
   1146  1.1  christos {
   1147  1.1  christos   aarch64_insn value;
   1148  1.1  christos 
   1149  1.1  christos   /* Rm */
   1150  1.1  christos   info->reg.regno = extract_field (FLD_Rm, code, 0);
   1151  1.1  christos   /* shift */
   1152  1.1  christos   value = extract_field (FLD_shift, code, 0);
   1153  1.1  christos   info->shifter.kind =
   1154  1.1  christos     aarch64_get_operand_modifier_from_value (value, FALSE /* extend_p */);
   1155  1.1  christos   if (info->shifter.kind == AARCH64_MOD_ROR
   1156  1.1  christos       && inst->opcode->iclass != log_shift)
   1157  1.1  christos     /* ROR is not available for the shifted register operand in arithmetic
   1158  1.1  christos        instructions.  */
   1159  1.1  christos     return 0;
   1160  1.1  christos   /* imm6 */
   1161  1.1  christos   info->shifter.amount = extract_field (FLD_imm6, code,  0);
   1162  1.1  christos 
   1163  1.1  christos   /* This makes the constraint checking happy.  */
   1164  1.1  christos   info->shifter.operator_present = 1;
   1165  1.1  christos 
   1166  1.1  christos   return 1;
   1167  1.1  christos }
   1168  1.1  christos 
   1169  1.1  christos /* Bitfields that are commonly used to encode certain operands' information
   1171  1.1  christos    may be partially used as part of the base opcode in some instructions.
   1172  1.1  christos    For example, the bit 1 of the field 'size' in
   1173  1.1  christos      FCVTXN <Vb><d>, <Va><n>
   1174  1.1  christos    is actually part of the base opcode, while only size<0> is available
   1175  1.1  christos    for encoding the register type.  Another example is the AdvSIMD
   1176  1.1  christos    instruction ORR (register), in which the field 'size' is also used for
   1177  1.1  christos    the base opcode, leaving only the field 'Q' available to encode the
   1178  1.1  christos    vector register arrangement specifier '8B' or '16B'.
   1179  1.1  christos 
   1180  1.1  christos    This function tries to deduce the qualifier from the value of partially
   1181  1.1  christos    constrained field(s).  Given the VALUE of such a field or fields, the
   1182  1.1  christos    qualifiers CANDIDATES and the MASK (indicating which bits are valid for
   1183  1.1  christos    operand encoding), the function returns the matching qualifier or
   1184  1.1  christos    AARCH64_OPND_QLF_NIL if nothing matches.
   1185  1.1  christos 
   1186  1.1  christos    N.B. CANDIDATES is a group of possible qualifiers that are valid for
   1187  1.1  christos    one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
   1188  1.1  christos    may end with AARCH64_OPND_QLF_NIL.  */
   1189  1.1  christos 
   1190  1.1  christos static enum aarch64_opnd_qualifier
   1191  1.1  christos get_qualifier_from_partial_encoding (aarch64_insn value,
   1192  1.1  christos 				     const enum aarch64_opnd_qualifier* \
   1193  1.1  christos 				     candidates,
   1194  1.1  christos 				     aarch64_insn mask)
   1195  1.1  christos {
   1196  1.1  christos   int i;
   1197  1.1  christos   DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
   1198  1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   1199  1.1  christos     {
   1200  1.1  christos       aarch64_insn standard_value;
   1201  1.1  christos       if (candidates[i] == AARCH64_OPND_QLF_NIL)
   1202  1.1  christos 	break;
   1203  1.1  christos       standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
   1204  1.1  christos       if ((standard_value & mask) == (value & mask))
   1205  1.1  christos 	return candidates[i];
   1206  1.1  christos     }
   1207  1.1  christos   return AARCH64_OPND_QLF_NIL;
   1208  1.1  christos }
   1209  1.1  christos 
   1210  1.1  christos /* Given a list of qualifier sequences, return all possible valid qualifiers
   1211  1.1  christos    for operand IDX in QUALIFIERS.
   1212  1.1  christos    Assume QUALIFIERS is an array whose length is large enough.  */
   1213  1.1  christos 
   1214  1.1  christos static void
   1215  1.1  christos get_operand_possible_qualifiers (int idx,
   1216  1.1  christos 				 const aarch64_opnd_qualifier_seq_t *list,
   1217  1.1  christos 				 enum aarch64_opnd_qualifier *qualifiers)
   1218  1.1  christos {
   1219  1.1  christos   int i;
   1220  1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   1221  1.1  christos     if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
   1222  1.1  christos       break;
   1223  1.1  christos }
   1224  1.1  christos 
   1225  1.1  christos /* Decode the size Q field for e.g. SHADD.
   1226  1.1  christos    We tag one operand with the qualifer according to the code;
   1227  1.1  christos    whether the qualifier is valid for this opcode or not, it is the
   1228  1.1  christos    duty of the semantic checking.  */
   1229  1.1  christos 
   1230  1.1  christos static int
   1231  1.1  christos decode_sizeq (aarch64_inst *inst)
   1232  1.1  christos {
   1233  1.1  christos   int idx;
   1234  1.1  christos   enum aarch64_opnd_qualifier qualifier;
   1235  1.1  christos   aarch64_insn code;
   1236  1.1  christos   aarch64_insn value, mask;
   1237  1.1  christos   enum aarch64_field_kind fld_sz;
   1238  1.1  christos   enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
   1239  1.1  christos 
   1240  1.1  christos   if (inst->opcode->iclass == asisdlse
   1241  1.1  christos      || inst->opcode->iclass == asisdlsep
   1242  1.1  christos      || inst->opcode->iclass == asisdlso
   1243  1.1  christos      || inst->opcode->iclass == asisdlsop)
   1244  1.1  christos     fld_sz = FLD_vldst_size;
   1245  1.1  christos   else
   1246  1.1  christos     fld_sz = FLD_size;
   1247  1.1  christos 
   1248  1.1  christos   code = inst->value;
   1249  1.1  christos   value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
   1250  1.1  christos   /* Obtain the info that which bits of fields Q and size are actually
   1251  1.1  christos      available for operand encoding.  Opcodes like FMAXNM and FMLA have
   1252  1.1  christos      size[1] unavailable.  */
   1253  1.1  christos   mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
   1254  1.1  christos 
   1255  1.1  christos   /* The index of the operand we are going to tag a qualifier and the qualifer
   1256  1.1  christos      itself are reasoned from the value of the size and Q fields and the
   1257  1.1  christos      possible valid qualifier lists.  */
   1258  1.1  christos   idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
   1259  1.1  christos   DEBUG_TRACE ("key idx: %d", idx);
   1260  1.1  christos 
   1261  1.1  christos   /* For most related instruciton, size:Q are fully available for operand
   1262  1.1  christos      encoding.  */
   1263  1.1  christos   if (mask == 0x7)
   1264  1.1  christos     {
   1265  1.1  christos       inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
   1266  1.1  christos       return 1;
   1267  1.1  christos     }
   1268  1.1  christos 
   1269  1.1  christos   get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
   1270  1.1  christos 				   candidates);
   1271  1.1  christos #ifdef DEBUG_AARCH64
   1272  1.1  christos   if (debug_dump)
   1273  1.1  christos     {
   1274  1.1  christos       int i;
   1275  1.1  christos       for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
   1276  1.1  christos 	   && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
   1277  1.1  christos 	DEBUG_TRACE ("qualifier %d: %s", i,
   1278  1.1  christos 		     aarch64_get_qualifier_name(candidates[i]));
   1279  1.1  christos       DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
   1280  1.1  christos     }
   1281  1.1  christos #endif /* DEBUG_AARCH64 */
   1282  1.1  christos 
   1283  1.1  christos   qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
   1284  1.1  christos 
   1285  1.1  christos   if (qualifier == AARCH64_OPND_QLF_NIL)
   1286  1.1  christos     return 0;
   1287  1.1  christos 
   1288  1.1  christos   inst->operands[idx].qualifier = qualifier;
   1289  1.1  christos   return 1;
   1290  1.1  christos }
   1291  1.1  christos 
   1292  1.1  christos /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
   1293  1.1  christos      e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
   1294  1.1  christos 
   1295  1.1  christos static int
   1296  1.1  christos decode_asimd_fcvt (aarch64_inst *inst)
   1297  1.1  christos {
   1298  1.1  christos   aarch64_field field = {0, 0};
   1299  1.1  christos   aarch64_insn value;
   1300  1.1  christos   enum aarch64_opnd_qualifier qualifier;
   1301  1.1  christos 
   1302  1.1  christos   gen_sub_field (FLD_size, 0, 1, &field);
   1303  1.1  christos   value = extract_field_2 (&field, inst->value, 0);
   1304  1.1  christos   qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
   1305  1.1  christos     : AARCH64_OPND_QLF_V_2D;
   1306  1.1  christos   switch (inst->opcode->op)
   1307  1.1  christos     {
   1308  1.1  christos     case OP_FCVTN:
   1309  1.1  christos     case OP_FCVTN2:
   1310  1.1  christos       /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>.  */
   1311  1.1  christos       inst->operands[1].qualifier = qualifier;
   1312  1.1  christos       break;
   1313  1.1  christos     case OP_FCVTL:
   1314  1.1  christos     case OP_FCVTL2:
   1315  1.1  christos       /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>.  */
   1316  1.1  christos       inst->operands[0].qualifier = qualifier;
   1317  1.1  christos       break;
   1318  1.1  christos     default:
   1319  1.1  christos       assert (0);
   1320  1.1  christos       return 0;
   1321  1.1  christos     }
   1322  1.1  christos 
   1323  1.1  christos   return 1;
   1324  1.1  christos }
   1325  1.1  christos 
   1326  1.1  christos /* Decode size[0], i.e. bit 22, for
   1327  1.1  christos      e.g. FCVTXN <Vb><d>, <Va><n>.  */
   1328  1.1  christos 
   1329  1.1  christos static int
   1330  1.1  christos decode_asisd_fcvtxn (aarch64_inst *inst)
   1331  1.1  christos {
   1332  1.1  christos   aarch64_field field = {0, 0};
   1333  1.1  christos   gen_sub_field (FLD_size, 0, 1, &field);
   1334  1.1  christos   if (!extract_field_2 (&field, inst->value, 0))
   1335  1.1  christos     return 0;
   1336  1.1  christos   inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
   1337  1.1  christos   return 1;
   1338  1.1  christos }
   1339  1.1  christos 
   1340  1.1  christos /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>.  */
   1341  1.1  christos static int
   1342  1.1  christos decode_fcvt (aarch64_inst *inst)
   1343  1.1  christos {
   1344  1.1  christos   enum aarch64_opnd_qualifier qualifier;
   1345  1.1  christos   aarch64_insn value;
   1346  1.1  christos   const aarch64_field field = {15, 2};
   1347  1.1  christos 
   1348  1.1  christos   /* opc dstsize */
   1349  1.1  christos   value = extract_field_2 (&field, inst->value, 0);
   1350  1.1  christos   switch (value)
   1351  1.1  christos     {
   1352  1.1  christos     case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
   1353  1.1  christos     case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
   1354  1.1  christos     case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
   1355  1.1  christos     default: return 0;
   1356  1.1  christos     }
   1357  1.1  christos   inst->operands[0].qualifier = qualifier;
   1358  1.1  christos 
   1359  1.1  christos   return 1;
   1360  1.1  christos }
   1361  1.1  christos 
   1362  1.1  christos /* Do miscellaneous decodings that are not common enough to be driven by
   1363  1.1  christos    flags.  */
   1364  1.1  christos 
   1365  1.1  christos static int
   1366  1.1  christos do_misc_decoding (aarch64_inst *inst)
   1367  1.1  christos {
   1368  1.1  christos   switch (inst->opcode->op)
   1369  1.1  christos     {
   1370  1.1  christos     case OP_FCVT:
   1371  1.1  christos       return decode_fcvt (inst);
   1372  1.1  christos     case OP_FCVTN:
   1373  1.1  christos     case OP_FCVTN2:
   1374  1.1  christos     case OP_FCVTL:
   1375  1.1  christos     case OP_FCVTL2:
   1376  1.1  christos       return decode_asimd_fcvt (inst);
   1377  1.1  christos     case OP_FCVTXN_S:
   1378  1.1  christos       return decode_asisd_fcvtxn (inst);
   1379  1.1  christos     default:
   1380  1.1  christos       return 0;
   1381  1.1  christos     }
   1382  1.1  christos }
   1383  1.1  christos 
   1384  1.1  christos /* Opcodes that have fields shared by multiple operands are usually flagged
   1385  1.1  christos    with flags.  In this function, we detect such flags, decode the related
   1386  1.1  christos    field(s) and store the information in one of the related operands.  The
   1387  1.1  christos    'one' operand is not any operand but one of the operands that can
   1388  1.1  christos    accommadate all the information that has been decoded.  */
   1389  1.1  christos 
   1390  1.1  christos static int
   1391  1.1  christos do_special_decoding (aarch64_inst *inst)
   1392  1.1  christos {
   1393  1.1  christos   int idx;
   1394  1.1  christos   aarch64_insn value;
   1395  1.1  christos   /* Condition for truly conditional executed instructions, e.g. b.cond.  */
   1396  1.1  christos   if (inst->opcode->flags & F_COND)
   1397  1.1  christos     {
   1398  1.1  christos       value = extract_field (FLD_cond2, inst->value, 0);
   1399  1.1  christos       inst->cond = get_cond_from_value (value);
   1400  1.1  christos     }
   1401  1.1  christos   /* 'sf' field.  */
   1402  1.1  christos   if (inst->opcode->flags & F_SF)
   1403  1.1  christos     {
   1404  1.1  christos       idx = select_operand_for_sf_field_coding (inst->opcode);
   1405  1.1  christos       value = extract_field (FLD_sf, inst->value, 0);
   1406  1.1  christos       inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   1407  1.1  christos       if ((inst->opcode->flags & F_N)
   1408  1.3  christos 	  && extract_field (FLD_N, inst->value, 0) != value)
   1409  1.3  christos 	return 0;
   1410  1.3  christos     }
   1411  1.3  christos   /* 'sf' field.  */
   1412  1.3  christos   if (inst->opcode->flags & F_LSE_SZ)
   1413  1.3  christos     {
   1414  1.3  christos       idx = select_operand_for_sf_field_coding (inst->opcode);
   1415  1.1  christos       value = extract_field (FLD_lse_sz, inst->value, 0);
   1416  1.1  christos       inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   1417  1.1  christos     }
   1418  1.1  christos   /* size:Q fields.  */
   1419  1.1  christos   if (inst->opcode->flags & F_SIZEQ)
   1420  1.1  christos     return decode_sizeq (inst);
   1421  1.1  christos 
   1422  1.1  christos   if (inst->opcode->flags & F_FPTYPE)
   1423  1.1  christos     {
   1424  1.1  christos       idx = select_operand_for_fptype_field_coding (inst->opcode);
   1425  1.1  christos       value = extract_field (FLD_type, inst->value, 0);
   1426  1.1  christos       switch (value)
   1427  1.1  christos 	{
   1428  1.1  christos 	case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
   1429  1.1  christos 	case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
   1430  1.1  christos 	case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
   1431  1.1  christos 	default: return 0;
   1432  1.1  christos 	}
   1433  1.1  christos     }
   1434  1.1  christos 
   1435  1.1  christos   if (inst->opcode->flags & F_SSIZE)
   1436  1.1  christos     {
   1437  1.1  christos       /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
   1438  1.1  christos 	 of the base opcode.  */
   1439  1.1  christos       aarch64_insn mask;
   1440  1.1  christos       enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
   1441  1.1  christos       idx = select_operand_for_scalar_size_field_coding (inst->opcode);
   1442  1.1  christos       value = extract_field (FLD_size, inst->value, inst->opcode->mask);
   1443  1.1  christos       mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
   1444  1.1  christos       /* For most related instruciton, the 'size' field is fully available for
   1445  1.1  christos 	 operand encoding.  */
   1446  1.1  christos       if (mask == 0x3)
   1447  1.1  christos 	inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
   1448  1.1  christos       else
   1449  1.1  christos 	{
   1450  1.1  christos 	  get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
   1451  1.1  christos 					   candidates);
   1452  1.1  christos 	  inst->operands[idx].qualifier
   1453  1.1  christos 	    = get_qualifier_from_partial_encoding (value, candidates, mask);
   1454  1.1  christos 	}
   1455  1.1  christos     }
   1456  1.1  christos 
   1457  1.1  christos   if (inst->opcode->flags & F_T)
   1458  1.1  christos     {
   1459  1.1  christos       /* Num of consecutive '0's on the right side of imm5<3:0>.  */
   1460  1.1  christos       int num = 0;
   1461  1.1  christos       unsigned val, Q;
   1462  1.1  christos       assert (aarch64_get_operand_class (inst->opcode->operands[0])
   1463  1.1  christos 	      == AARCH64_OPND_CLASS_SIMD_REG);
   1464  1.1  christos       /* imm5<3:0>	q	<t>
   1465  1.1  christos 	 0000		x	reserved
   1466  1.1  christos 	 xxx1		0	8b
   1467  1.1  christos 	 xxx1		1	16b
   1468  1.1  christos 	 xx10		0	4h
   1469  1.1  christos 	 xx10		1	8h
   1470  1.1  christos 	 x100		0	2s
   1471  1.1  christos 	 x100		1	4s
   1472  1.1  christos 	 1000		0	reserved
   1473  1.1  christos 	 1000		1	2d  */
   1474  1.1  christos       val = extract_field (FLD_imm5, inst->value, 0);
   1475  1.1  christos       while ((val & 0x1) == 0 && ++num <= 3)
   1476  1.1  christos 	val >>= 1;
   1477  1.1  christos       if (num > 3)
   1478  1.1  christos 	return 0;
   1479  1.1  christos       Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
   1480  1.1  christos       inst->operands[0].qualifier =
   1481  1.1  christos 	get_vreg_qualifier_from_value ((num << 1) | Q);
   1482  1.1  christos     }
   1483  1.1  christos 
   1484  1.1  christos   if (inst->opcode->flags & F_GPRSIZE_IN_Q)
   1485  1.1  christos     {
   1486  1.1  christos       /* Use Rt to encode in the case of e.g.
   1487  1.1  christos 	 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}].  */
   1488  1.1  christos       idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
   1489  1.1  christos       if (idx == -1)
   1490  1.1  christos 	{
   1491  1.1  christos 	  /* Otherwise use the result operand, which has to be a integer
   1492  1.1  christos 	     register.  */
   1493  1.1  christos 	  assert (aarch64_get_operand_class (inst->opcode->operands[0])
   1494  1.1  christos 		  == AARCH64_OPND_CLASS_INT_REG);
   1495  1.1  christos 	  idx = 0;
   1496  1.1  christos 	}
   1497  1.1  christos       assert (idx == 0 || idx == 1);
   1498  1.1  christos       value = extract_field (FLD_Q, inst->value, 0);
   1499  1.1  christos       inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
   1500  1.1  christos     }
   1501  1.1  christos 
   1502  1.1  christos   if (inst->opcode->flags & F_LDS_SIZE)
   1503  1.1  christos     {
   1504  1.1  christos       aarch64_field field = {0, 0};
   1505  1.1  christos       assert (aarch64_get_operand_class (inst->opcode->operands[0])
   1506  1.1  christos 	      == AARCH64_OPND_CLASS_INT_REG);
   1507  1.1  christos       gen_sub_field (FLD_opc, 0, 1, &field);
   1508  1.1  christos       value = extract_field_2 (&field, inst->value, 0);
   1509  1.1  christos       inst->operands[0].qualifier
   1510  1.1  christos 	= value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
   1511  1.1  christos     }
   1512  1.1  christos 
   1513  1.1  christos   /* Miscellaneous decoding; done as the last step.  */
   1514  1.1  christos   if (inst->opcode->flags & F_MISC)
   1515  1.1  christos     return do_misc_decoding (inst);
   1516  1.1  christos 
   1517  1.1  christos   return 1;
   1518  1.1  christos }
   1519  1.1  christos 
   1520  1.1  christos /* Converters converting a real opcode instruction to its alias form.  */
   1521  1.1  christos 
   1522  1.1  christos /* ROR <Wd>, <Ws>, #<shift>
   1523  1.1  christos      is equivalent to:
   1524  1.1  christos    EXTR <Wd>, <Ws>, <Ws>, #<shift>.  */
   1525  1.1  christos static int
   1526  1.1  christos convert_extr_to_ror (aarch64_inst *inst)
   1527  1.1  christos {
   1528  1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
   1529  1.1  christos     {
   1530  1.1  christos       copy_operand_info (inst, 2, 3);
   1531  1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1532  1.1  christos       return 1;
   1533  1.1  christos     }
   1534  1.1  christos   return 0;
   1535  1.1  christos }
   1536  1.1  christos 
   1537  1.1  christos /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
   1538  1.1  christos      is equivalent to:
   1539  1.1  christos    USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0.  */
   1540  1.1  christos static int
   1541  1.1  christos convert_shll_to_xtl (aarch64_inst *inst)
   1542  1.1  christos {
   1543  1.1  christos   if (inst->operands[2].imm.value == 0)
   1544  1.1  christos     {
   1545  1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   1546  1.1  christos       return 1;
   1547  1.1  christos     }
   1548  1.1  christos   return 0;
   1549  1.1  christos }
   1550  1.1  christos 
   1551  1.1  christos /* Convert
   1552  1.1  christos      UBFM <Xd>, <Xn>, #<shift>, #63.
   1553  1.1  christos    to
   1554  1.1  christos      LSR <Xd>, <Xn>, #<shift>.  */
   1555  1.1  christos static int
   1556  1.1  christos convert_bfm_to_sr (aarch64_inst *inst)
   1557  1.1  christos {
   1558  1.1  christos   int64_t imms, val;
   1559  1.1  christos 
   1560  1.1  christos   imms = inst->operands[3].imm.value;
   1561  1.1  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
   1562  1.1  christos   if (imms == val)
   1563  1.1  christos     {
   1564  1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1565  1.1  christos       return 1;
   1566  1.1  christos     }
   1567  1.1  christos 
   1568  1.1  christos   return 0;
   1569  1.1  christos }
   1570  1.1  christos 
   1571  1.1  christos /* Convert MOV to ORR.  */
   1572  1.1  christos static int
   1573  1.1  christos convert_orr_to_mov (aarch64_inst *inst)
   1574  1.1  christos {
   1575  1.1  christos   /* MOV <Vd>.<T>, <Vn>.<T>
   1576  1.1  christos      is equivalent to:
   1577  1.1  christos      ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>.  */
   1578  1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
   1579  1.1  christos     {
   1580  1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   1581  1.1  christos       return 1;
   1582  1.1  christos     }
   1583  1.1  christos   return 0;
   1584  1.1  christos }
   1585  1.1  christos 
   1586  1.1  christos /* When <imms> >= <immr>, the instruction written:
   1587  1.1  christos      SBFX <Xd>, <Xn>, #<lsb>, #<width>
   1588  1.1  christos    is equivalent to:
   1589  1.1  christos      SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1).  */
   1590  1.1  christos 
   1591  1.1  christos static int
   1592  1.1  christos convert_bfm_to_bfx (aarch64_inst *inst)
   1593  1.1  christos {
   1594  1.1  christos   int64_t immr, imms;
   1595  1.1  christos 
   1596  1.1  christos   immr = inst->operands[2].imm.value;
   1597  1.1  christos   imms = inst->operands[3].imm.value;
   1598  1.1  christos   if (imms >= immr)
   1599  1.1  christos     {
   1600  1.1  christos       int64_t lsb = immr;
   1601  1.1  christos       inst->operands[2].imm.value = lsb;
   1602  1.1  christos       inst->operands[3].imm.value = imms + 1 - lsb;
   1603  1.1  christos       /* The two opcodes have different qualifiers for
   1604  1.1  christos 	 the immediate operands; reset to help the checking.  */
   1605  1.1  christos       reset_operand_qualifier (inst, 2);
   1606  1.1  christos       reset_operand_qualifier (inst, 3);
   1607  1.1  christos       return 1;
   1608  1.1  christos     }
   1609  1.1  christos 
   1610  1.1  christos   return 0;
   1611  1.1  christos }
   1612  1.1  christos 
   1613  1.1  christos /* When <imms> < <immr>, the instruction written:
   1614  1.1  christos      SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
   1615  1.1  christos    is equivalent to:
   1616  1.1  christos      SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1).  */
   1617  1.1  christos 
   1618  1.1  christos static int
   1619  1.1  christos convert_bfm_to_bfi (aarch64_inst *inst)
   1620  1.1  christos {
   1621  1.1  christos   int64_t immr, imms, val;
   1622  1.1  christos 
   1623  1.1  christos   immr = inst->operands[2].imm.value;
   1624  1.1  christos   imms = inst->operands[3].imm.value;
   1625  1.1  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
   1626  1.1  christos   if (imms < immr)
   1627  1.1  christos     {
   1628  1.1  christos       inst->operands[2].imm.value = (val - immr) & (val - 1);
   1629  1.1  christos       inst->operands[3].imm.value = imms + 1;
   1630  1.1  christos       /* The two opcodes have different qualifiers for
   1631  1.1  christos 	 the immediate operands; reset to help the checking.  */
   1632  1.1  christos       reset_operand_qualifier (inst, 2);
   1633  1.1  christos       reset_operand_qualifier (inst, 3);
   1634  1.1  christos       return 1;
   1635  1.1  christos     }
   1636  1.1  christos 
   1637  1.1  christos   return 0;
   1638  1.3  christos }
   1639  1.3  christos 
   1640  1.3  christos /* The instruction written:
   1641  1.3  christos      BFC <Xd>, #<lsb>, #<width>
   1642  1.3  christos    is equivalent to:
   1643  1.3  christos      BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1).  */
   1644  1.3  christos 
   1645  1.3  christos static int
   1646  1.3  christos convert_bfm_to_bfc (aarch64_inst *inst)
   1647  1.3  christos {
   1648  1.3  christos   int64_t immr, imms, val;
   1649  1.3  christos 
   1650  1.3  christos   /* Should have been assured by the base opcode value.  */
   1651  1.3  christos   assert (inst->operands[1].reg.regno == 0x1f);
   1652  1.3  christos 
   1653  1.3  christos   immr = inst->operands[2].imm.value;
   1654  1.3  christos   imms = inst->operands[3].imm.value;
   1655  1.3  christos   val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
   1656  1.3  christos   if (imms < immr)
   1657  1.3  christos     {
   1658  1.3  christos       /* Drop XZR from the second operand.  */
   1659  1.3  christos       copy_operand_info (inst, 1, 2);
   1660  1.3  christos       copy_operand_info (inst, 2, 3);
   1661  1.3  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1662  1.3  christos 
   1663  1.3  christos       /* Recalculate the immediates.  */
   1664  1.3  christos       inst->operands[1].imm.value = (val - immr) & (val - 1);
   1665  1.3  christos       inst->operands[2].imm.value = imms + 1;
   1666  1.3  christos 
   1667  1.3  christos       /* The two opcodes have different qualifiers for the operands; reset to
   1668  1.3  christos 	 help the checking.  */
   1669  1.3  christos       reset_operand_qualifier (inst, 1);
   1670  1.3  christos       reset_operand_qualifier (inst, 2);
   1671  1.3  christos       reset_operand_qualifier (inst, 3);
   1672  1.3  christos 
   1673  1.3  christos       return 1;
   1674  1.3  christos     }
   1675  1.3  christos 
   1676  1.3  christos   return 0;
   1677  1.1  christos }
   1678  1.1  christos 
   1679  1.1  christos /* The instruction written:
   1680  1.1  christos      LSL <Xd>, <Xn>, #<shift>
   1681  1.1  christos    is equivalent to:
   1682  1.1  christos      UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>).  */
   1683  1.1  christos 
   1684  1.1  christos static int
   1685  1.1  christos convert_ubfm_to_lsl (aarch64_inst *inst)
   1686  1.1  christos {
   1687  1.1  christos   int64_t immr = inst->operands[2].imm.value;
   1688  1.1  christos   int64_t imms = inst->operands[3].imm.value;
   1689  1.1  christos   int64_t val
   1690  1.1  christos     = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
   1691  1.1  christos 
   1692  1.1  christos   if ((immr == 0 && imms == val) || immr == imms + 1)
   1693  1.1  christos     {
   1694  1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1695  1.1  christos       inst->operands[2].imm.value = val - imms;
   1696  1.1  christos       return 1;
   1697  1.1  christos     }
   1698  1.1  christos 
   1699  1.1  christos   return 0;
   1700  1.1  christos }
   1701  1.3  christos 
   1702  1.3  christos /* CINC <Wd>, <Wn>, <cond>
   1703  1.1  christos      is equivalent to:
   1704  1.1  christos    CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
   1705  1.1  christos      where <cond> is not AL or NV.  */
   1706  1.1  christos 
   1707  1.3  christos static int
   1708  1.3  christos convert_from_csel (aarch64_inst *inst)
   1709  1.1  christos {
   1710  1.1  christos   if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
   1711  1.1  christos       && (inst->operands[3].cond->value & 0xe) != 0xe)
   1712  1.1  christos     {
   1713  1.1  christos       copy_operand_info (inst, 2, 3);
   1714  1.1  christos       inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
   1715  1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1716  1.1  christos       return 1;
   1717  1.1  christos     }
   1718  1.1  christos   return 0;
   1719  1.1  christos }
   1720  1.3  christos 
   1721  1.3  christos /* CSET <Wd>, <cond>
   1722  1.1  christos      is equivalent to:
   1723  1.1  christos    CSINC <Wd>, WZR, WZR, invert(<cond>)
   1724  1.1  christos      where <cond> is not AL or NV.  */
   1725  1.1  christos 
   1726  1.1  christos static int
   1727  1.3  christos convert_csinc_to_cset (aarch64_inst *inst)
   1728  1.3  christos {
   1729  1.1  christos   if (inst->operands[1].reg.regno == 0x1f
   1730  1.1  christos       && inst->operands[2].reg.regno == 0x1f
   1731  1.1  christos       && (inst->operands[3].cond->value & 0xe) != 0xe)
   1732  1.1  christos     {
   1733  1.1  christos       copy_operand_info (inst, 1, 3);
   1734  1.1  christos       inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
   1735  1.1  christos       inst->operands[3].type = AARCH64_OPND_NIL;
   1736  1.1  christos       inst->operands[2].type = AARCH64_OPND_NIL;
   1737  1.1  christos       return 1;
   1738  1.1  christos     }
   1739  1.1  christos   return 0;
   1740  1.1  christos }
   1741  1.1  christos 
   1742  1.1  christos /* MOV <Wd>, #<imm>
   1743  1.1  christos      is equivalent to:
   1744  1.1  christos    MOVZ <Wd>, #<imm16>, LSL #<shift>.
   1745  1.1  christos 
   1746  1.1  christos    A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
   1747  1.1  christos    ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
   1748  1.1  christos    or where a MOVN has an immediate that could be encoded by MOVZ, or where
   1749  1.1  christos    MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
   1750  1.1  christos    machine-instruction mnemonic must be used.  */
   1751  1.1  christos 
   1752  1.1  christos static int
   1753  1.1  christos convert_movewide_to_mov (aarch64_inst *inst)
   1754  1.1  christos {
   1755  1.1  christos   uint64_t value = inst->operands[1].imm.value;
   1756  1.1  christos   /* MOVZ/MOVN #0 have a shift amount other than LSL #0.  */
   1757  1.1  christos   if (value == 0 && inst->operands[1].shifter.amount != 0)
   1758  1.1  christos     return 0;
   1759  1.1  christos   inst->operands[1].type = AARCH64_OPND_IMM_MOV;
   1760  1.1  christos   inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
   1761  1.1  christos   value <<= inst->operands[1].shifter.amount;
   1762  1.1  christos   /* As an alias convertor, it has to be clear that the INST->OPCODE
   1763  1.1  christos      is the opcode of the real instruction.  */
   1764  1.1  christos   if (inst->opcode->op == OP_MOVN)
   1765  1.1  christos     {
   1766  1.1  christos       int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
   1767  1.1  christos       value = ~value;
   1768  1.1  christos       /* A MOVN has an immediate that could be encoded by MOVZ.  */
   1769  1.1  christos       if (aarch64_wide_constant_p (value, is32, NULL) == TRUE)
   1770  1.1  christos 	return 0;
   1771  1.1  christos     }
   1772  1.1  christos   inst->operands[1].imm.value = value;
   1773  1.1  christos   inst->operands[1].shifter.amount = 0;
   1774  1.1  christos   return 1;
   1775  1.1  christos }
   1776  1.1  christos 
   1777  1.1  christos /* MOV <Wd>, #<imm>
   1778  1.1  christos      is equivalent to:
   1779  1.1  christos    ORR <Wd>, WZR, #<imm>.
   1780  1.1  christos 
   1781  1.1  christos    A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
   1782  1.1  christos    ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
   1783  1.1  christos    or where a MOVN has an immediate that could be encoded by MOVZ, or where
   1784  1.1  christos    MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
   1785  1.1  christos    machine-instruction mnemonic must be used.  */
   1786  1.1  christos 
   1787  1.1  christos static int
   1788  1.1  christos convert_movebitmask_to_mov (aarch64_inst *inst)
   1789  1.1  christos {
   1790  1.1  christos   int is32;
   1791  1.1  christos   uint64_t value;
   1792  1.1  christos 
   1793  1.1  christos   /* Should have been assured by the base opcode value.  */
   1794  1.1  christos   assert (inst->operands[1].reg.regno == 0x1f);
   1795  1.1  christos   copy_operand_info (inst, 1, 2);
   1796  1.1  christos   is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
   1797  1.1  christos   inst->operands[1].type = AARCH64_OPND_IMM_MOV;
   1798  1.1  christos   value = inst->operands[1].imm.value;
   1799  1.1  christos   /* ORR has an immediate that could be generated by a MOVZ or MOVN
   1800  1.1  christos      instruction.  */
   1801  1.1  christos   if (inst->operands[0].reg.regno != 0x1f
   1802  1.1  christos       && (aarch64_wide_constant_p (value, is32, NULL) == TRUE
   1803  1.1  christos 	  || aarch64_wide_constant_p (~value, is32, NULL) == TRUE))
   1804  1.1  christos     return 0;
   1805  1.1  christos 
   1806  1.1  christos   inst->operands[2].type = AARCH64_OPND_NIL;
   1807  1.1  christos   return 1;
   1808  1.1  christos }
   1809  1.1  christos 
   1810  1.1  christos /* Some alias opcodes are disassembled by being converted from their real-form.
   1811  1.1  christos    N.B. INST->OPCODE is the real opcode rather than the alias.  */
   1812  1.1  christos 
   1813  1.1  christos static int
   1814  1.1  christos convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
   1815  1.1  christos {
   1816  1.1  christos   switch (alias->op)
   1817  1.1  christos     {
   1818  1.1  christos     case OP_ASR_IMM:
   1819  1.1  christos     case OP_LSR_IMM:
   1820  1.1  christos       return convert_bfm_to_sr (inst);
   1821  1.1  christos     case OP_LSL_IMM:
   1822  1.1  christos       return convert_ubfm_to_lsl (inst);
   1823  1.1  christos     case OP_CINC:
   1824  1.1  christos     case OP_CINV:
   1825  1.1  christos     case OP_CNEG:
   1826  1.1  christos       return convert_from_csel (inst);
   1827  1.1  christos     case OP_CSET:
   1828  1.1  christos     case OP_CSETM:
   1829  1.1  christos       return convert_csinc_to_cset (inst);
   1830  1.1  christos     case OP_UBFX:
   1831  1.1  christos     case OP_BFXIL:
   1832  1.1  christos     case OP_SBFX:
   1833  1.1  christos       return convert_bfm_to_bfx (inst);
   1834  1.1  christos     case OP_SBFIZ:
   1835  1.3  christos     case OP_BFI:
   1836  1.3  christos     case OP_UBFIZ:
   1837  1.1  christos       return convert_bfm_to_bfi (inst);
   1838  1.1  christos     case OP_BFC:
   1839  1.1  christos       return convert_bfm_to_bfc (inst);
   1840  1.1  christos     case OP_MOV_V:
   1841  1.1  christos       return convert_orr_to_mov (inst);
   1842  1.1  christos     case OP_MOV_IMM_WIDE:
   1843  1.1  christos     case OP_MOV_IMM_WIDEN:
   1844  1.1  christos       return convert_movewide_to_mov (inst);
   1845  1.1  christos     case OP_MOV_IMM_LOG:
   1846  1.1  christos       return convert_movebitmask_to_mov (inst);
   1847  1.1  christos     case OP_ROR_IMM:
   1848  1.1  christos       return convert_extr_to_ror (inst);
   1849  1.1  christos     case OP_SXTL:
   1850  1.1  christos     case OP_SXTL2:
   1851  1.1  christos     case OP_UXTL:
   1852  1.1  christos     case OP_UXTL2:
   1853  1.1  christos       return convert_shll_to_xtl (inst);
   1854  1.1  christos     default:
   1855  1.1  christos       return 0;
   1856  1.1  christos     }
   1857  1.1  christos }
   1858  1.1  christos 
   1859  1.1  christos static int aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
   1860  1.1  christos 				  aarch64_inst *, int);
   1861  1.1  christos 
   1862  1.1  christos /* Given the instruction information in *INST, check if the instruction has
   1863  1.1  christos    any alias form that can be used to represent *INST.  If the answer is yes,
   1864  1.1  christos    update *INST to be in the form of the determined alias.  */
   1865  1.1  christos 
   1866  1.1  christos /* In the opcode description table, the following flags are used in opcode
   1867  1.1  christos    entries to help establish the relations between the real and alias opcodes:
   1868  1.1  christos 
   1869  1.1  christos 	F_ALIAS:	opcode is an alias
   1870  1.1  christos 	F_HAS_ALIAS:	opcode has alias(es)
   1871  1.1  christos 	F_P1
   1872  1.1  christos 	F_P2
   1873  1.1  christos 	F_P3:		Disassembly preference priority 1-3 (the larger the
   1874  1.1  christos 			higher).  If nothing is specified, it is the priority
   1875  1.1  christos 			0 by default, i.e. the lowest priority.
   1876  1.1  christos 
   1877  1.1  christos    Although the relation between the machine and the alias instructions are not
   1878  1.1  christos    explicitly described, it can be easily determined from the base opcode
   1879  1.1  christos    values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
   1880  1.1  christos    description entries:
   1881  1.1  christos 
   1882  1.1  christos    The mask of an alias opcode must be equal to or a super-set (i.e. more
   1883  1.1  christos    constrained) of that of the aliased opcode; so is the base opcode value.
   1884  1.1  christos 
   1885  1.1  christos    if (opcode_has_alias (real) && alias_opcode_p (opcode)
   1886  1.1  christos        && (opcode->mask & real->mask) == real->mask
   1887  1.1  christos        && (real->mask & opcode->opcode) == (real->mask & real->opcode))
   1888  1.1  christos    then OPCODE is an alias of, and only of, the REAL instruction
   1889  1.1  christos 
   1890  1.1  christos    The alias relationship is forced flat-structured to keep related algorithm
   1891  1.1  christos    simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
   1892  1.1  christos 
   1893  1.1  christos    During the disassembling, the decoding decision tree (in
   1894  1.1  christos    opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
   1895  1.1  christos    if the decoding of such a machine instruction succeeds (and -Mno-aliases is
   1896  1.1  christos    not specified), the disassembler will check whether there is any alias
   1897  1.1  christos    instruction exists for this real instruction.  If there is, the disassembler
   1898  1.1  christos    will try to disassemble the 32-bit binary again using the alias's rule, or
   1899  1.1  christos    try to convert the IR to the form of the alias.  In the case of the multiple
   1900  1.1  christos    aliases, the aliases are tried one by one from the highest priority
   1901  1.1  christos    (currently the flag F_P3) to the lowest priority (no priority flag), and the
   1902  1.1  christos    first succeeds first adopted.
   1903  1.1  christos 
   1904  1.1  christos    You may ask why there is a need for the conversion of IR from one form to
   1905  1.1  christos    another in handling certain aliases.  This is because on one hand it avoids
   1906  1.1  christos    adding more operand code to handle unusual encoding/decoding; on other
   1907  1.1  christos    hand, during the disassembling, the conversion is an effective approach to
   1908  1.1  christos    check the condition of an alias (as an alias may be adopted only if certain
   1909  1.1  christos    conditions are met).
   1910  1.1  christos 
   1911  1.1  christos    In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
   1912  1.1  christos    aarch64_opcode_table and generated aarch64_find_alias_opcode and
   1913  1.1  christos    aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help.  */
   1914  1.1  christos 
   1915  1.1  christos static void
   1916  1.1  christos determine_disassembling_preference (struct aarch64_inst *inst)
   1917  1.1  christos {
   1918  1.1  christos   const aarch64_opcode *opcode;
   1919  1.1  christos   const aarch64_opcode *alias;
   1920  1.1  christos 
   1921  1.1  christos   opcode = inst->opcode;
   1922  1.1  christos 
   1923  1.1  christos   /* This opcode does not have an alias, so use itself.  */
   1924  1.1  christos   if (opcode_has_alias (opcode) == FALSE)
   1925  1.1  christos     return;
   1926  1.1  christos 
   1927  1.1  christos   alias = aarch64_find_alias_opcode (opcode);
   1928  1.1  christos   assert (alias);
   1929  1.1  christos 
   1930  1.1  christos #ifdef DEBUG_AARCH64
   1931  1.1  christos   if (debug_dump)
   1932  1.1  christos     {
   1933  1.1  christos       const aarch64_opcode *tmp = alias;
   1934  1.1  christos       printf ("####   LIST    orderd: ");
   1935  1.1  christos       while (tmp)
   1936  1.1  christos 	{
   1937  1.1  christos 	  printf ("%s, ", tmp->name);
   1938  1.1  christos 	  tmp = aarch64_find_next_alias_opcode (tmp);
   1939  1.1  christos 	}
   1940  1.1  christos       printf ("\n");
   1941  1.1  christos     }
   1942  1.1  christos #endif /* DEBUG_AARCH64 */
   1943  1.1  christos 
   1944  1.3  christos   for (; alias; alias = aarch64_find_next_alias_opcode (alias))
   1945  1.1  christos     {
   1946  1.1  christos       DEBUG_TRACE ("try %s", alias->name);
   1947  1.1  christos       assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
   1948  1.1  christos 
   1949  1.1  christos       /* An alias can be a pseudo opcode which will never be used in the
   1950  1.1  christos 	 disassembly, e.g. BIC logical immediate is such a pseudo opcode
   1951  1.1  christos 	 aliasing AND.  */
   1952  1.1  christos       if (pseudo_opcode_p (alias))
   1953  1.1  christos 	{
   1954  1.1  christos 	  DEBUG_TRACE ("skip pseudo %s", alias->name);
   1955  1.1  christos 	  continue;
   1956  1.1  christos 	}
   1957  1.1  christos 
   1958  1.1  christos       if ((inst->value & alias->mask) != alias->opcode)
   1959  1.1  christos 	{
   1960  1.1  christos 	  DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
   1961  1.1  christos 	  continue;
   1962  1.1  christos 	}
   1963  1.1  christos       /* No need to do any complicated transformation on operands, if the alias
   1964  1.1  christos 	 opcode does not have any operand.  */
   1965  1.1  christos       if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
   1966  1.1  christos 	{
   1967  1.1  christos 	  DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
   1968  1.1  christos 	  aarch64_replace_opcode (inst, alias);
   1969  1.1  christos 	  return;
   1970  1.1  christos 	}
   1971  1.1  christos       if (alias->flags & F_CONV)
   1972  1.1  christos 	{
   1973  1.1  christos 	  aarch64_inst copy;
   1974  1.1  christos 	  memcpy (&copy, inst, sizeof (aarch64_inst));
   1975  1.1  christos 	  /* ALIAS is the preference as long as the instruction can be
   1976  1.1  christos 	     successfully converted to the form of ALIAS.  */
   1977  1.1  christos 	  if (convert_to_alias (&copy, alias) == 1)
   1978  1.1  christos 	    {
   1979  1.1  christos 	      aarch64_replace_opcode (&copy, alias);
   1980  1.1  christos 	      assert (aarch64_match_operands_constraint (&copy, NULL));
   1981  1.1  christos 	      DEBUG_TRACE ("succeed with %s via conversion", alias->name);
   1982  1.1  christos 	      memcpy (inst, &copy, sizeof (aarch64_inst));
   1983  1.1  christos 	      return;
   1984  1.1  christos 	    }
   1985  1.1  christos 	}
   1986  1.1  christos       else
   1987  1.1  christos 	{
   1988  1.1  christos 	  /* Directly decode the alias opcode.  */
   1989  1.1  christos 	  aarch64_inst temp;
   1990  1.1  christos 	  memset (&temp, '\0', sizeof (aarch64_inst));
   1991  1.1  christos 	  if (aarch64_opcode_decode (alias, inst->value, &temp, 1) == 1)
   1992  1.1  christos 	    {
   1993  1.1  christos 	      DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
   1994  1.1  christos 	      memcpy (inst, &temp, sizeof (aarch64_inst));
   1995  1.1  christos 	      return;
   1996  1.1  christos 	    }
   1997  1.1  christos 	}
   1998  1.1  christos     }
   1999  1.1  christos }
   2000  1.1  christos 
   2001  1.1  christos /* Decode the CODE according to OPCODE; fill INST.  Return 0 if the decoding
   2002  1.1  christos    fails, which meanes that CODE is not an instruction of OPCODE; otherwise
   2003  1.1  christos    return 1.
   2004  1.1  christos 
   2005  1.1  christos    If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
   2006  1.1  christos    determined and used to disassemble CODE; this is done just before the
   2007  1.1  christos    return.  */
   2008  1.1  christos 
   2009  1.1  christos static int
   2010  1.1  christos aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
   2011  1.1  christos 		       aarch64_inst *inst, int noaliases_p)
   2012  1.1  christos {
   2013  1.1  christos   int i;
   2014  1.1  christos 
   2015  1.1  christos   DEBUG_TRACE ("enter with %s", opcode->name);
   2016  1.1  christos 
   2017  1.1  christos   assert (opcode && inst);
   2018  1.1  christos 
   2019  1.1  christos   /* Check the base opcode.  */
   2020  1.1  christos   if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
   2021  1.1  christos     {
   2022  1.1  christos       DEBUG_TRACE ("base opcode match FAIL");
   2023  1.1  christos       goto decode_fail;
   2024  1.1  christos     }
   2025  1.1  christos 
   2026  1.1  christos   /* Clear inst.  */
   2027  1.1  christos   memset (inst, '\0', sizeof (aarch64_inst));
   2028  1.1  christos 
   2029  1.1  christos   inst->opcode = opcode;
   2030  1.1  christos   inst->value = code;
   2031  1.1  christos 
   2032  1.1  christos   /* Assign operand codes and indexes.  */
   2033  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2034  1.1  christos     {
   2035  1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL)
   2036  1.1  christos 	break;
   2037  1.1  christos       inst->operands[i].type = opcode->operands[i];
   2038  1.1  christos       inst->operands[i].idx = i;
   2039  1.1  christos     }
   2040  1.1  christos 
   2041  1.1  christos   /* Call the opcode decoder indicated by flags.  */
   2042  1.1  christos   if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
   2043  1.1  christos     {
   2044  1.1  christos       DEBUG_TRACE ("opcode flag-based decoder FAIL");
   2045  1.1  christos       goto decode_fail;
   2046  1.1  christos     }
   2047  1.1  christos 
   2048  1.1  christos   /* Call operand decoders.  */
   2049  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2050  1.1  christos     {
   2051  1.1  christos       const aarch64_operand *opnd;
   2052  1.1  christos       enum aarch64_opnd type;
   2053  1.1  christos       type = opcode->operands[i];
   2054  1.1  christos       if (type == AARCH64_OPND_NIL)
   2055  1.1  christos 	break;
   2056  1.1  christos       opnd = &aarch64_operands[type];
   2057  1.1  christos       if (operand_has_extractor (opnd)
   2058  1.1  christos 	  && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst)))
   2059  1.1  christos 	{
   2060  1.1  christos 	  DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
   2061  1.1  christos 	  goto decode_fail;
   2062  1.1  christos 	}
   2063  1.1  christos     }
   2064  1.1  christos 
   2065  1.1  christos   /* Match the qualifiers.  */
   2066  1.1  christos   if (aarch64_match_operands_constraint (inst, NULL) == 1)
   2067  1.1  christos     {
   2068  1.1  christos       /* Arriving here, the CODE has been determined as a valid instruction
   2069  1.1  christos 	 of OPCODE and *INST has been filled with information of this OPCODE
   2070  1.1  christos 	 instruction.  Before the return, check if the instruction has any
   2071  1.1  christos 	 alias and should be disassembled in the form of its alias instead.
   2072  1.1  christos 	 If the answer is yes, *INST will be updated.  */
   2073  1.1  christos       if (!noaliases_p)
   2074  1.1  christos 	determine_disassembling_preference (inst);
   2075  1.1  christos       DEBUG_TRACE ("SUCCESS");
   2076  1.1  christos       return 1;
   2077  1.1  christos     }
   2078  1.1  christos   else
   2079  1.1  christos     {
   2080  1.1  christos       DEBUG_TRACE ("constraint matching FAIL");
   2081  1.1  christos     }
   2082  1.1  christos 
   2083  1.1  christos decode_fail:
   2084  1.1  christos   return 0;
   2085  1.1  christos }
   2086  1.1  christos 
   2087  1.1  christos /* This does some user-friendly fix-up to *INST.  It is currently focus on
   2089  1.1  christos    the adjustment of qualifiers to help the printed instruction
   2090  1.1  christos    recognized/understood more easily.  */
   2091  1.1  christos 
   2092  1.1  christos static void
   2093  1.1  christos user_friendly_fixup (aarch64_inst *inst)
   2094  1.1  christos {
   2095  1.1  christos   switch (inst->opcode->iclass)
   2096  1.1  christos     {
   2097  1.1  christos     case testbranch:
   2098  1.1  christos       /* TBNZ Xn|Wn, #uimm6, label
   2099  1.1  christos 	 Test and Branch Not Zero: conditionally jumps to label if bit number
   2100  1.1  christos 	 uimm6 in register Xn is not zero.  The bit number implies the width of
   2101  1.1  christos 	 the register, which may be written and should be disassembled as Wn if
   2102  1.1  christos 	 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
   2103  1.1  christos 	 */
   2104  1.1  christos       if (inst->operands[1].imm.value < 32)
   2105  1.1  christos 	inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
   2106  1.1  christos       break;
   2107  1.3  christos     default: break;
   2108  1.3  christos     }
   2109  1.3  christos }
   2110  1.1  christos 
   2111  1.3  christos /* Decode INSN and fill in *INST the instruction information.  An alias
   2112  1.3  christos    opcode may be filled in *INSN if NOALIASES_P is FALSE.  Return zero on
   2113  1.3  christos    success.  */
   2114  1.1  christos 
   2115  1.1  christos int
   2116  1.1  christos aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
   2117  1.1  christos 		     bfd_boolean noaliases_p)
   2118  1.1  christos {
   2119  1.1  christos   const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
   2120  1.1  christos 
   2121  1.1  christos #ifdef DEBUG_AARCH64
   2122  1.1  christos   if (debug_dump)
   2123  1.1  christos     {
   2124  1.1  christos       const aarch64_opcode *tmp = opcode;
   2125  1.1  christos       printf ("\n");
   2126  1.1  christos       DEBUG_TRACE ("opcode lookup:");
   2127  1.1  christos       while (tmp != NULL)
   2128  1.1  christos 	{
   2129  1.1  christos 	  aarch64_verbose ("  %s", tmp->name);
   2130  1.1  christos 	  tmp = aarch64_find_next_opcode (tmp);
   2131  1.1  christos 	}
   2132  1.1  christos     }
   2133  1.1  christos #endif /* DEBUG_AARCH64 */
   2134  1.1  christos 
   2135  1.1  christos   /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
   2136  1.1  christos      distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
   2137  1.1  christos      opcode field and value, apart from the difference that one of them has an
   2138  1.1  christos      extra field as part of the opcode, but such a field is used for operand
   2139  1.1  christos      encoding in other opcode(s) ('immh' in the case of the example).  */
   2140  1.3  christos   while (opcode != NULL)
   2141  1.1  christos     {
   2142  1.1  christos       /* But only one opcode can be decoded successfully for, as the
   2143  1.1  christos 	 decoding routine will check the constraint carefully.  */
   2144  1.1  christos       if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p) == 1)
   2145  1.1  christos 	return ERR_OK;
   2146  1.1  christos       opcode = aarch64_find_next_opcode (opcode);
   2147  1.1  christos     }
   2148  1.1  christos 
   2149  1.1  christos   return ERR_UND;
   2150  1.1  christos }
   2151  1.1  christos 
   2152  1.1  christos /* Print operands.  */
   2153  1.1  christos 
   2154  1.1  christos static void
   2155  1.1  christos print_operands (bfd_vma pc, const aarch64_opcode *opcode,
   2156  1.1  christos 		const aarch64_opnd_info *opnds, struct disassemble_info *info)
   2157  1.1  christos {
   2158  1.1  christos   int i, pcrel_p, num_printed;
   2159  1.1  christos   for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2160  1.1  christos     {
   2161  1.1  christos       const size_t size = 128;
   2162  1.1  christos       char str[size];
   2163  1.1  christos       /* We regard the opcode operand info more, however we also look into
   2164  1.1  christos 	 the inst->operands to support the disassembling of the optional
   2165  1.1  christos 	 operand.
   2166  1.1  christos 	 The two operand code should be the same in all cases, apart from
   2167  1.1  christos 	 when the operand can be optional.  */
   2168  1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL
   2169  1.1  christos 	  || opnds[i].type == AARCH64_OPND_NIL)
   2170  1.1  christos 	break;
   2171  1.1  christos 
   2172  1.1  christos       /* Generate the operand string in STR.  */
   2173  1.1  christos       aarch64_print_operand (str, size, pc, opcode, opnds, i, &pcrel_p,
   2174  1.1  christos 			     &info->target);
   2175  1.1  christos 
   2176  1.1  christos       /* Print the delimiter (taking account of omitted operand(s)).  */
   2177  1.1  christos       if (str[0] != '\0')
   2178  1.1  christos 	(*info->fprintf_func) (info->stream, "%s",
   2179  1.1  christos 			       num_printed++ == 0 ? "\t" : ", ");
   2180  1.1  christos 
   2181  1.1  christos       /* Print the operand.  */
   2182  1.1  christos       if (pcrel_p)
   2183  1.1  christos 	(*info->print_address_func) (info->target, info);
   2184  1.1  christos       else
   2185  1.1  christos 	(*info->fprintf_func) (info->stream, "%s", str);
   2186  1.1  christos     }
   2187  1.1  christos }
   2188  1.1  christos 
   2189  1.1  christos /* Print the instruction mnemonic name.  */
   2190  1.1  christos 
   2191  1.1  christos static void
   2192  1.1  christos print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
   2193  1.1  christos {
   2194  1.1  christos   if (inst->opcode->flags & F_COND)
   2195  1.1  christos     {
   2196  1.1  christos       /* For instructions that are truly conditionally executed, e.g. b.cond,
   2197  1.3  christos 	 prepare the full mnemonic name with the corresponding condition
   2198  1.1  christos 	 suffix.  */
   2199  1.1  christos       char name[8], *ptr;
   2200  1.1  christos       size_t len;
   2201  1.1  christos 
   2202  1.1  christos       ptr = strchr (inst->opcode->name, '.');
   2203  1.1  christos       assert (ptr && inst->cond);
   2204  1.1  christos       len = ptr - inst->opcode->name;
   2205  1.1  christos       assert (len < 8);
   2206  1.1  christos       strncpy (name, inst->opcode->name, len);
   2207  1.1  christos       name [len] = '\0';
   2208  1.1  christos       (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
   2209  1.1  christos     }
   2210  1.1  christos   else
   2211  1.1  christos     (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
   2212  1.1  christos }
   2213  1.1  christos 
   2214  1.1  christos /* Print the instruction according to *INST.  */
   2215  1.1  christos 
   2216  1.1  christos static void
   2217  1.1  christos print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
   2218  1.1  christos 		    struct disassemble_info *info)
   2219  1.1  christos {
   2220  1.1  christos   print_mnemonic_name (inst, info);
   2221  1.1  christos   print_operands (pc, inst->opcode, inst->operands, info);
   2222  1.1  christos }
   2223  1.1  christos 
   2224  1.1  christos /* Entry-point of the instruction disassembler and printer.  */
   2225  1.1  christos 
   2226  1.1  christos static void
   2227  1.1  christos print_insn_aarch64_word (bfd_vma pc,
   2228  1.1  christos 			 uint32_t word,
   2229  1.1  christos 			 struct disassemble_info *info)
   2230  1.1  christos {
   2231  1.1  christos   static const char *err_msg[6] =
   2232  1.1  christos     {
   2233  1.1  christos       [ERR_OK]   = "_",
   2234  1.1  christos       [-ERR_UND] = "undefined",
   2235  1.1  christos       [-ERR_UNP] = "unpredictable",
   2236  1.1  christos       [-ERR_NYI] = "NYI"
   2237  1.1  christos     };
   2238  1.1  christos 
   2239  1.1  christos   int ret;
   2240  1.1  christos   aarch64_inst inst;
   2241  1.1  christos 
   2242  1.1  christos   info->insn_info_valid = 1;
   2243  1.1  christos   info->branch_delay_insns = 0;
   2244  1.1  christos   info->data_size = 0;
   2245  1.1  christos   info->target = 0;
   2246  1.1  christos   info->target2 = 0;
   2247  1.1  christos 
   2248  1.1  christos   if (info->flags & INSN_HAS_RELOC)
   2249  1.1  christos     /* If the instruction has a reloc associated with it, then
   2250  1.1  christos        the offset field in the instruction will actually be the
   2251  1.1  christos        addend for the reloc.  (If we are using REL type relocs).
   2252  1.3  christos        In such cases, we can ignore the pc when computing
   2253  1.1  christos        addresses, since the addend is not currently pc-relative.  */
   2254  1.1  christos     pc = 0;
   2255  1.1  christos 
   2256  1.3  christos   ret = aarch64_decode_insn (word, &inst, no_aliases);
   2257  1.1  christos 
   2258  1.1  christos   if (((word >> 21) & 0x3ff) == 1)
   2259  1.1  christos     {
   2260  1.1  christos       /* RESERVED for ALES.  */
   2261  1.1  christos       assert (ret != ERR_OK);
   2262  1.1  christos       ret = ERR_NYI;
   2263  1.1  christos     }
   2264  1.1  christos 
   2265  1.1  christos   switch (ret)
   2266  1.1  christos     {
   2267  1.1  christos     case ERR_UND:
   2268  1.1  christos     case ERR_UNP:
   2269  1.1  christos     case ERR_NYI:
   2270  1.1  christos       /* Handle undefined instructions.  */
   2271  1.1  christos       info->insn_type = dis_noninsn;
   2272  1.1  christos       (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
   2273  1.1  christos 			     word, err_msg[-ret]);
   2274  1.1  christos       break;
   2275  1.1  christos     case ERR_OK:
   2276  1.1  christos       user_friendly_fixup (&inst);
   2277  1.1  christos       print_aarch64_insn (pc, &inst, info);
   2278  1.1  christos       break;
   2279  1.1  christos     default:
   2280  1.1  christos       abort ();
   2281  1.1  christos     }
   2282  1.1  christos }
   2283  1.1  christos 
   2284  1.1  christos /* Disallow mapping symbols ($x, $d etc) from
   2285  1.1  christos    being displayed in symbol relative addresses.  */
   2286  1.1  christos 
   2287  1.1  christos bfd_boolean
   2288  1.1  christos aarch64_symbol_is_valid (asymbol * sym,
   2289  1.1  christos 			 struct disassemble_info * info ATTRIBUTE_UNUSED)
   2290  1.1  christos {
   2291  1.1  christos   const char * name;
   2292  1.1  christos 
   2293  1.1  christos   if (sym == NULL)
   2294  1.1  christos     return FALSE;
   2295  1.1  christos 
   2296  1.1  christos   name = bfd_asymbol_name (sym);
   2297  1.1  christos 
   2298  1.1  christos   return name
   2299  1.1  christos     && (name[0] != '$'
   2300  1.1  christos 	|| (name[1] != 'x' && name[1] != 'd')
   2301  1.1  christos 	|| (name[2] != '\0' && name[2] != '.'));
   2302  1.1  christos }
   2303  1.1  christos 
   2304  1.1  christos /* Print data bytes on INFO->STREAM.  */
   2305  1.1  christos 
   2306  1.1  christos static void
   2307  1.1  christos print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
   2308  1.1  christos 		 uint32_t word,
   2309  1.1  christos 		 struct disassemble_info *info)
   2310  1.1  christos {
   2311  1.1  christos   switch (info->bytes_per_chunk)
   2312  1.1  christos     {
   2313  1.1  christos     case 1:
   2314  1.1  christos       info->fprintf_func (info->stream, ".byte\t0x%02x", word);
   2315  1.1  christos       break;
   2316  1.1  christos     case 2:
   2317  1.1  christos       info->fprintf_func (info->stream, ".short\t0x%04x", word);
   2318  1.1  christos       break;
   2319  1.1  christos     case 4:
   2320  1.1  christos       info->fprintf_func (info->stream, ".word\t0x%08x", word);
   2321  1.1  christos       break;
   2322  1.1  christos     default:
   2323  1.1  christos       abort ();
   2324  1.1  christos     }
   2325  1.1  christos }
   2326  1.1  christos 
   2327  1.1  christos /* Try to infer the code or data type from a symbol.
   2328  1.1  christos    Returns nonzero if *MAP_TYPE was set.  */
   2329  1.1  christos 
   2330  1.1  christos static int
   2331  1.1  christos get_sym_code_type (struct disassemble_info *info, int n,
   2332  1.1  christos 		   enum map_type *map_type)
   2333  1.1  christos {
   2334  1.1  christos   elf_symbol_type *es;
   2335  1.1  christos   unsigned int type;
   2336  1.1  christos   const char *name;
   2337  1.1  christos 
   2338  1.1  christos   es = *(elf_symbol_type **)(info->symtab + n);
   2339  1.1  christos   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
   2340  1.1  christos 
   2341  1.1  christos   /* If the symbol has function type then use that.  */
   2342  1.1  christos   if (type == STT_FUNC)
   2343  1.1  christos     {
   2344  1.1  christos       *map_type = MAP_INSN;
   2345  1.1  christos       return TRUE;
   2346  1.1  christos     }
   2347  1.1  christos 
   2348  1.1  christos   /* Check for mapping symbols.  */
   2349  1.1  christos   name = bfd_asymbol_name(info->symtab[n]);
   2350  1.1  christos   if (name[0] == '$'
   2351  1.1  christos       && (name[1] == 'x' || name[1] == 'd')
   2352  1.1  christos       && (name[2] == '\0' || name[2] == '.'))
   2353  1.1  christos     {
   2354  1.1  christos       *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
   2355  1.1  christos       return TRUE;
   2356  1.1  christos     }
   2357  1.1  christos 
   2358  1.1  christos   return FALSE;
   2359  1.1  christos }
   2360  1.1  christos 
   2361  1.1  christos /* Entry-point of the AArch64 disassembler.  */
   2362  1.1  christos 
   2363  1.1  christos int
   2364  1.1  christos print_insn_aarch64 (bfd_vma pc,
   2365  1.1  christos 		    struct disassemble_info *info)
   2366  1.1  christos {
   2367  1.1  christos   bfd_byte	buffer[INSNLEN];
   2368  1.1  christos   int		status;
   2369  1.1  christos   void		(*printer) (bfd_vma, uint32_t, struct disassemble_info *);
   2370  1.1  christos   bfd_boolean   found = FALSE;
   2371  1.1  christos   unsigned int	size = 4;
   2372  1.1  christos   unsigned long	data;
   2373  1.1  christos 
   2374  1.1  christos   if (info->disassembler_options)
   2375  1.1  christos     {
   2376  1.1  christos       set_default_aarch64_dis_options (info);
   2377  1.1  christos 
   2378  1.1  christos       parse_aarch64_dis_options (info->disassembler_options);
   2379  1.1  christos 
   2380  1.1  christos       /* To avoid repeated parsing of these options, we remove them here.  */
   2381  1.1  christos       info->disassembler_options = NULL;
   2382  1.1  christos     }
   2383  1.1  christos 
   2384  1.1  christos   /* Aarch64 instructions are always little-endian */
   2385  1.1  christos   info->endian_code = BFD_ENDIAN_LITTLE;
   2386  1.1  christos 
   2387  1.1  christos   /* First check the full symtab for a mapping symbol, even if there
   2388  1.1  christos      are no usable non-mapping symbols for this address.  */
   2389  1.1  christos   if (info->symtab_size != 0
   2390  1.1  christos       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
   2391  1.1  christos     {
   2392  1.1  christos       enum map_type type = MAP_INSN;
   2393  1.1  christos       int last_sym = -1;
   2394  1.1  christos       bfd_vma addr;
   2395  1.1  christos       int n;
   2396  1.1  christos 
   2397  1.1  christos       if (pc <= last_mapping_addr)
   2398  1.1  christos 	last_mapping_sym = -1;
   2399  1.1  christos 
   2400  1.1  christos       /* Start scanning at the start of the function, or wherever
   2401  1.1  christos 	 we finished last time.  */
   2402  1.1  christos       n = info->symtab_pos + 1;
   2403  1.1  christos       if (n < last_mapping_sym)
   2404  1.1  christos 	n = last_mapping_sym;
   2405  1.1  christos 
   2406  1.1  christos       /* Scan up to the location being disassembled.  */
   2407  1.1  christos       for (; n < info->symtab_size; n++)
   2408  1.1  christos 	{
   2409  1.1  christos 	  addr = bfd_asymbol_value (info->symtab[n]);
   2410  1.1  christos 	  if (addr > pc)
   2411  1.1  christos 	    break;
   2412  1.1  christos 	  if ((info->section == NULL
   2413  1.1  christos 	       || info->section == info->symtab[n]->section)
   2414  1.1  christos 	      && get_sym_code_type (info, n, &type))
   2415  1.1  christos 	    {
   2416  1.1  christos 	      last_sym = n;
   2417  1.1  christos 	      found = TRUE;
   2418  1.1  christos 	    }
   2419  1.1  christos 	}
   2420  1.1  christos 
   2421  1.1  christos       if (!found)
   2422  1.1  christos 	{
   2423  1.1  christos 	  n = info->symtab_pos;
   2424  1.1  christos 	  if (n < last_mapping_sym)
   2425  1.1  christos 	    n = last_mapping_sym;
   2426  1.1  christos 
   2427  1.1  christos 	  /* No mapping symbol found at this address.  Look backwards
   2428  1.1  christos 	     for a preceeding one.  */
   2429  1.1  christos 	  for (; n >= 0; n--)
   2430  1.1  christos 	    {
   2431  1.1  christos 	      if (get_sym_code_type (info, n, &type))
   2432  1.1  christos 		{
   2433  1.1  christos 		  last_sym = n;
   2434  1.1  christos 		  found = TRUE;
   2435  1.1  christos 		  break;
   2436  1.1  christos 		}
   2437  1.1  christos 	    }
   2438  1.1  christos 	}
   2439  1.1  christos 
   2440  1.1  christos       last_mapping_sym = last_sym;
   2441  1.1  christos       last_type = type;
   2442  1.1  christos 
   2443  1.1  christos       /* Look a little bit ahead to see if we should print out
   2444  1.1  christos 	 less than four bytes of data.  If there's a symbol,
   2445  1.1  christos 	 mapping or otherwise, after two bytes then don't
   2446  1.1  christos 	 print more.  */
   2447  1.1  christos       if (last_type == MAP_DATA)
   2448  1.1  christos 	{
   2449  1.1  christos 	  size = 4 - (pc & 3);
   2450  1.1  christos 	  for (n = last_sym + 1; n < info->symtab_size; n++)
   2451  1.1  christos 	    {
   2452  1.1  christos 	      addr = bfd_asymbol_value (info->symtab[n]);
   2453  1.1  christos 	      if (addr > pc)
   2454  1.1  christos 		{
   2455  1.1  christos 		  if (addr - pc < size)
   2456  1.1  christos 		    size = addr - pc;
   2457  1.1  christos 		  break;
   2458  1.1  christos 		}
   2459  1.1  christos 	    }
   2460  1.1  christos 	  /* If the next symbol is after three bytes, we need to
   2461  1.1  christos 	     print only part of the data, so that we can use either
   2462  1.1  christos 	     .byte or .short.  */
   2463  1.1  christos 	  if (size == 3)
   2464  1.1  christos 	    size = (pc & 1) ? 1 : 2;
   2465  1.1  christos 	}
   2466  1.1  christos     }
   2467  1.1  christos 
   2468  1.1  christos   if (last_type == MAP_DATA)
   2469  1.1  christos     {
   2470  1.1  christos       /* size was set above.  */
   2471  1.1  christos       info->bytes_per_chunk = size;
   2472  1.1  christos       info->display_endian = info->endian;
   2473  1.1  christos       printer = print_insn_data;
   2474  1.1  christos     }
   2475  1.1  christos   else
   2476  1.1  christos     {
   2477  1.1  christos       info->bytes_per_chunk = size = INSNLEN;
   2478  1.1  christos       info->display_endian = info->endian_code;
   2479  1.1  christos       printer = print_insn_aarch64_word;
   2480  1.1  christos     }
   2481  1.1  christos 
   2482  1.1  christos   status = (*info->read_memory_func) (pc, buffer, size, info);
   2483  1.1  christos   if (status != 0)
   2484  1.1  christos     {
   2485  1.1  christos       (*info->memory_error_func) (status, pc, info);
   2486  1.1  christos       return -1;
   2487  1.1  christos     }
   2488  1.1  christos 
   2489  1.1  christos   data = bfd_get_bits (buffer, size * 8,
   2490  1.1  christos 		       info->display_endian == BFD_ENDIAN_BIG);
   2491  1.1  christos 
   2492  1.1  christos   (*printer) (pc, data, info);
   2493  1.1  christos 
   2494  1.1  christos   return size;
   2495  1.1  christos }
   2496  1.1  christos 
   2497  1.1  christos void
   2499  1.1  christos print_aarch64_disassembler_options (FILE *stream)
   2500  1.1  christos {
   2501  1.1  christos   fprintf (stream, _("\n\
   2502  1.1  christos The following AARCH64 specific disassembler options are supported for use\n\
   2503  1.1  christos with the -M switch (multiple options should be separated by commas):\n"));
   2504  1.1  christos 
   2505  1.1  christos   fprintf (stream, _("\n\
   2506  1.1  christos   no-aliases         Don't print instruction aliases.\n"));
   2507  1.1  christos 
   2508  1.1  christos   fprintf (stream, _("\n\
   2509  1.1  christos   aliases            Do print instruction aliases.\n"));
   2510  1.1  christos 
   2511  1.1  christos #ifdef DEBUG_AARCH64
   2512  1.1  christos   fprintf (stream, _("\n\
   2513                  debug_dump         Temp switch for debug trace.\n"));
   2514                #endif /* DEBUG_AARCH64 */
   2515                
   2516                  fprintf (stream, _("\n"));
   2517                }
   2518