Home | History | Annotate | Line # | Download | only in opcodes
aarch64-opc.c revision 1.3
      1  1.1  christos /* aarch64-opc.c -- AArch64 opcode support.
      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 <assert.h>
     23  1.1  christos #include <stdlib.h>
     24  1.1  christos #include <stdio.h>
     25  1.1  christos #include <stdint.h>
     26  1.1  christos #include <stdarg.h>
     27  1.1  christos #include <inttypes.h>
     28  1.1  christos 
     29  1.1  christos #include "opintl.h"
     30  1.1  christos 
     31  1.1  christos #include "aarch64-opc.h"
     32  1.1  christos 
     33  1.1  christos #ifdef DEBUG_AARCH64
     34  1.1  christos int debug_dump = FALSE;
     35  1.1  christos #endif /* DEBUG_AARCH64 */
     36  1.1  christos 
     37  1.1  christos /* Helper functions to determine which operand to be used to encode/decode
     38  1.1  christos    the size:Q fields for AdvSIMD instructions.  */
     39  1.1  christos 
     40  1.1  christos static inline bfd_boolean
     41  1.1  christos vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
     42  1.1  christos {
     43  1.1  christos   return ((qualifier >= AARCH64_OPND_QLF_V_8B
     44  1.1  christos 	  && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
     45  1.1  christos 	  : FALSE);
     46  1.1  christos }
     47  1.1  christos 
     48  1.1  christos static inline bfd_boolean
     49  1.1  christos fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
     50  1.1  christos {
     51  1.1  christos   return ((qualifier >= AARCH64_OPND_QLF_S_B
     52  1.1  christos 	  && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
     53  1.1  christos 	  : FALSE);
     54  1.1  christos }
     55  1.1  christos 
     56  1.1  christos enum data_pattern
     57  1.1  christos {
     58  1.1  christos   DP_UNKNOWN,
     59  1.1  christos   DP_VECTOR_3SAME,
     60  1.1  christos   DP_VECTOR_LONG,
     61  1.1  christos   DP_VECTOR_WIDE,
     62  1.1  christos   DP_VECTOR_ACROSS_LANES,
     63  1.1  christos };
     64  1.1  christos 
     65  1.1  christos static const char significant_operand_index [] =
     66  1.1  christos {
     67  1.1  christos   0,	/* DP_UNKNOWN, by default using operand 0.  */
     68  1.1  christos   0,	/* DP_VECTOR_3SAME */
     69  1.1  christos   1,	/* DP_VECTOR_LONG */
     70  1.1  christos   2,	/* DP_VECTOR_WIDE */
     71  1.1  christos   1,	/* DP_VECTOR_ACROSS_LANES */
     72  1.1  christos };
     73  1.1  christos 
     74  1.1  christos /* Given a sequence of qualifiers in QUALIFIERS, determine and return
     75  1.1  christos    the data pattern.
     76  1.1  christos    N.B. QUALIFIERS is a possible sequence of qualifiers each of which
     77  1.1  christos    corresponds to one of a sequence of operands.  */
     78  1.1  christos 
     79  1.1  christos static enum data_pattern
     80  1.1  christos get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
     81  1.1  christos {
     82  1.1  christos   if (vector_qualifier_p (qualifiers[0]) == TRUE)
     83  1.1  christos     {
     84  1.1  christos       /* e.g. v.4s, v.4s, v.4s
     85  1.1  christos 	   or v.4h, v.4h, v.h[3].  */
     86  1.1  christos       if (qualifiers[0] == qualifiers[1]
     87  1.1  christos 	  && vector_qualifier_p (qualifiers[2]) == TRUE
     88  1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
     89  1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1]))
     90  1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
     91  1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[2])))
     92  1.1  christos 	return DP_VECTOR_3SAME;
     93  1.1  christos       /* e.g. v.8h, v.8b, v.8b.
     94  1.1  christos            or v.4s, v.4h, v.h[2].
     95  1.1  christos 	   or v.8h, v.16b.  */
     96  1.1  christos       if (vector_qualifier_p (qualifiers[1]) == TRUE
     97  1.1  christos 	  && aarch64_get_qualifier_esize (qualifiers[0]) != 0
     98  1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
     99  1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
    100  1.1  christos 	return DP_VECTOR_LONG;
    101  1.1  christos       /* e.g. v.8h, v.8h, v.8b.  */
    102  1.1  christos       if (qualifiers[0] == qualifiers[1]
    103  1.1  christos 	  && vector_qualifier_p (qualifiers[2]) == TRUE
    104  1.1  christos 	  && aarch64_get_qualifier_esize (qualifiers[0]) != 0
    105  1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    106  1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
    107  1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    108  1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1])))
    109  1.1  christos 	return DP_VECTOR_WIDE;
    110  1.1  christos     }
    111  1.1  christos   else if (fp_qualifier_p (qualifiers[0]) == TRUE)
    112  1.1  christos     {
    113  1.1  christos       /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
    114  1.1  christos       if (vector_qualifier_p (qualifiers[1]) == TRUE
    115  1.1  christos 	  && qualifiers[2] == AARCH64_OPND_QLF_NIL)
    116  1.1  christos 	return DP_VECTOR_ACROSS_LANES;
    117  1.1  christos     }
    118  1.1  christos 
    119  1.1  christos   return DP_UNKNOWN;
    120  1.1  christos }
    121  1.1  christos 
    122  1.1  christos /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
    123  1.1  christos    the AdvSIMD instructions.  */
    124  1.1  christos /* N.B. it is possible to do some optimization that doesn't call
    125  1.1  christos    get_data_pattern each time when we need to select an operand.  We can
    126  1.1  christos    either buffer the caculated the result or statically generate the data,
    127  1.1  christos    however, it is not obvious that the optimization will bring significant
    128  1.1  christos    benefit.  */
    129  1.1  christos 
    130  1.1  christos int
    131  1.1  christos aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
    132  1.1  christos {
    133  1.1  christos   return
    134  1.1  christos     significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
    135  1.1  christos }
    136  1.1  christos 
    137  1.1  christos const aarch64_field fields[] =
    139  1.1  christos {
    140  1.1  christos     {  0,  0 },	/* NIL.  */
    141  1.1  christos     {  0,  4 },	/* cond2: condition in truly conditional-executed inst.  */
    142  1.1  christos     {  0,  4 },	/* nzcv: flag bit specifier, encoded in the "nzcv" field.  */
    143  1.1  christos     {  5,  5 },	/* defgh: d:e:f:g:h bits in AdvSIMD modified immediate.  */
    144  1.1  christos     { 16,  3 },	/* abc: a:b:c bits in AdvSIMD modified immediate.  */
    145  1.1  christos     {  5, 19 },	/* imm19: e.g. in CBZ.  */
    146  1.1  christos     {  5, 19 },	/* immhi: e.g. in ADRP.  */
    147  1.1  christos     { 29,  2 },	/* immlo: e.g. in ADRP.  */
    148  1.1  christos     { 22,  2 },	/* size: in most AdvSIMD and floating-point instructions.  */
    149  1.1  christos     { 10,  2 },	/* vldst_size: size field in the AdvSIMD load/store inst.  */
    150  1.1  christos     { 29,  1 },	/* op: in AdvSIMD modified immediate instructions.  */
    151  1.1  christos     { 30,  1 },	/* Q: in most AdvSIMD instructions.  */
    152  1.1  christos     {  0,  5 },	/* Rt: in load/store instructions.  */
    153  1.1  christos     {  0,  5 },	/* Rd: in many integer instructions.  */
    154  1.1  christos     {  5,  5 },	/* Rn: in many integer instructions.  */
    155  1.1  christos     { 10,  5 },	/* Rt2: in load/store pair instructions.  */
    156  1.1  christos     { 10,  5 },	/* Ra: in fp instructions.  */
    157  1.1  christos     {  5,  3 },	/* op2: in the system instructions.  */
    158  1.1  christos     {  8,  4 },	/* CRm: in the system instructions.  */
    159  1.1  christos     { 12,  4 },	/* CRn: in the system instructions.  */
    160  1.1  christos     { 16,  3 },	/* op1: in the system instructions.  */
    161  1.1  christos     { 19,  2 },	/* op0: in the system instructions.  */
    162  1.1  christos     { 10,  3 },	/* imm3: in add/sub extended reg instructions.  */
    163  1.1  christos     { 12,  4 },	/* cond: condition flags as a source operand.  */
    164  1.1  christos     { 12,  4 },	/* opcode: in advsimd load/store instructions.  */
    165  1.1  christos     { 12,  4 },	/* cmode: in advsimd modified immediate instructions.  */
    166  1.1  christos     { 13,  3 },	/* asisdlso_opcode: opcode in advsimd ld/st single element.  */
    167  1.1  christos     { 13,  2 },	/* len: in advsimd tbl/tbx instructions.  */
    168  1.1  christos     { 16,  5 },	/* Rm: in ld/st reg offset and some integer inst.  */
    169  1.1  christos     { 16,  5 },	/* Rs: in load/store exclusive instructions.  */
    170  1.1  christos     { 13,  3 },	/* option: in ld/st reg offset + add/sub extended reg inst.  */
    171  1.1  christos     { 12,  1 },	/* S: in load/store reg offset instructions.  */
    172  1.1  christos     { 21,  2 },	/* hw: in move wide constant instructions.  */
    173  1.1  christos     { 22,  2 },	/* opc: in load/store reg offset instructions.  */
    174  1.1  christos     { 23,  1 },	/* opc1: in load/store reg offset instructions.  */
    175  1.1  christos     { 22,  2 },	/* shift: in add/sub reg/imm shifted instructions.  */
    176  1.1  christos     { 22,  2 },	/* type: floating point type field in fp data inst.  */
    177  1.1  christos     { 30,  2 },	/* ldst_size: size field in ld/st reg offset inst.  */
    178  1.1  christos     { 10,  6 },	/* imm6: in add/sub reg shifted instructions.  */
    179  1.1  christos     { 11,  4 },	/* imm4: in advsimd ext and advsimd ins instructions.  */
    180  1.1  christos     { 16,  5 },	/* imm5: in conditional compare (immediate) instructions.  */
    181  1.1  christos     { 15,  7 },	/* imm7: in load/store pair pre/post index instructions.  */
    182  1.1  christos     { 13,  8 },	/* imm8: in floating-point scalar move immediate inst.  */
    183  1.1  christos     { 12,  9 },	/* imm9: in load/store pre/post index instructions.  */
    184  1.1  christos     { 10, 12 },	/* imm12: in ld/st unsigned imm or add/sub shifted inst.  */
    185  1.1  christos     {  5, 14 },	/* imm14: in test bit and branch instructions.  */
    186  1.1  christos     {  5, 16 },	/* imm16: in exception instructions.  */
    187  1.1  christos     {  0, 26 },	/* imm26: in unconditional branch instructions.  */
    188  1.1  christos     { 10,  6 },	/* imms: in bitfield and logical immediate instructions.  */
    189  1.1  christos     { 16,  6 },	/* immr: in bitfield and logical immediate instructions.  */
    190  1.1  christos     { 16,  3 },	/* immb: in advsimd shift by immediate instructions.  */
    191  1.1  christos     { 19,  4 },	/* immh: in advsimd shift by immediate instructions.  */
    192  1.1  christos     { 22,  1 },	/* N: in logical (immediate) instructions.  */
    193  1.1  christos     { 11,  1 },	/* index: in ld/st inst deciding the pre/post-index.  */
    194  1.1  christos     { 24,  1 },	/* index2: in ld/st pair inst deciding the pre/post-index.  */
    195  1.3  christos     { 31,  1 },	/* sf: in integer data processing instructions.  */
    196  1.1  christos     { 30,  1 },	/* lse_size: in LSE extension atomic instructions.  */
    197  1.1  christos     { 11,  1 },	/* H: in advsimd scalar x indexed element instructions.  */
    198  1.1  christos     { 21,  1 },	/* L: in advsimd scalar x indexed element instructions.  */
    199  1.1  christos     { 20,  1 },	/* M: in advsimd scalar x indexed element instructions.  */
    200  1.1  christos     { 31,  1 },	/* b5: in the test bit and branch instructions.  */
    201  1.1  christos     { 19,  5 },	/* b40: in the test bit and branch instructions.  */
    202  1.1  christos     { 10,  6 },	/* scale: in the fixed-point scalar to fp converting inst.  */
    203  1.1  christos };
    204  1.1  christos 
    205  1.1  christos enum aarch64_operand_class
    206  1.1  christos aarch64_get_operand_class (enum aarch64_opnd type)
    207  1.1  christos {
    208  1.1  christos   return aarch64_operands[type].op_class;
    209  1.1  christos }
    210  1.1  christos 
    211  1.1  christos const char *
    212  1.1  christos aarch64_get_operand_name (enum aarch64_opnd type)
    213  1.1  christos {
    214  1.1  christos   return aarch64_operands[type].name;
    215  1.1  christos }
    216  1.1  christos 
    217  1.1  christos /* Get operand description string.
    218  1.1  christos    This is usually for the diagnosis purpose.  */
    219  1.1  christos const char *
    220  1.1  christos aarch64_get_operand_desc (enum aarch64_opnd type)
    221  1.1  christos {
    222  1.1  christos   return aarch64_operands[type].desc;
    223  1.1  christos }
    224  1.1  christos 
    225  1.1  christos /* Table of all conditional affixes.  */
    226  1.1  christos const aarch64_cond aarch64_conds[16] =
    227  1.1  christos {
    228  1.1  christos   {{"eq"}, 0x0},
    229  1.1  christos   {{"ne"}, 0x1},
    230  1.1  christos   {{"cs", "hs"}, 0x2},
    231  1.1  christos   {{"cc", "lo", "ul"}, 0x3},
    232  1.1  christos   {{"mi"}, 0x4},
    233  1.1  christos   {{"pl"}, 0x5},
    234  1.1  christos   {{"vs"}, 0x6},
    235  1.1  christos   {{"vc"}, 0x7},
    236  1.1  christos   {{"hi"}, 0x8},
    237  1.1  christos   {{"ls"}, 0x9},
    238  1.1  christos   {{"ge"}, 0xa},
    239  1.1  christos   {{"lt"}, 0xb},
    240  1.1  christos   {{"gt"}, 0xc},
    241  1.1  christos   {{"le"}, 0xd},
    242  1.1  christos   {{"al"}, 0xe},
    243  1.1  christos   {{"nv"}, 0xf},
    244  1.1  christos };
    245  1.1  christos 
    246  1.1  christos const aarch64_cond *
    247  1.1  christos get_cond_from_value (aarch64_insn value)
    248  1.1  christos {
    249  1.1  christos   assert (value < 16);
    250  1.1  christos   return &aarch64_conds[(unsigned int) value];
    251  1.1  christos }
    252  1.1  christos 
    253  1.1  christos const aarch64_cond *
    254  1.1  christos get_inverted_cond (const aarch64_cond *cond)
    255  1.1  christos {
    256  1.1  christos   return &aarch64_conds[cond->value ^ 0x1];
    257  1.1  christos }
    258  1.1  christos 
    259  1.1  christos /* Table describing the operand extension/shifting operators; indexed by
    260  1.1  christos    enum aarch64_modifier_kind.
    261  1.1  christos 
    262  1.1  christos    The value column provides the most common values for encoding modifiers,
    263  1.1  christos    which enables table-driven encoding/decoding for the modifiers.  */
    264  1.1  christos const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
    265  1.1  christos {
    266  1.1  christos     {"none", 0x0},
    267  1.1  christos     {"msl",  0x0},
    268  1.1  christos     {"ror",  0x3},
    269  1.1  christos     {"asr",  0x2},
    270  1.1  christos     {"lsr",  0x1},
    271  1.1  christos     {"lsl",  0x0},
    272  1.1  christos     {"uxtb", 0x0},
    273  1.1  christos     {"uxth", 0x1},
    274  1.1  christos     {"uxtw", 0x2},
    275  1.1  christos     {"uxtx", 0x3},
    276  1.1  christos     {"sxtb", 0x4},
    277  1.1  christos     {"sxth", 0x5},
    278  1.1  christos     {"sxtw", 0x6},
    279  1.1  christos     {"sxtx", 0x7},
    280  1.1  christos     {NULL, 0},
    281  1.1  christos };
    282  1.1  christos 
    283  1.1  christos enum aarch64_modifier_kind
    284  1.1  christos aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
    285  1.1  christos {
    286  1.1  christos   return desc - aarch64_operand_modifiers;
    287  1.1  christos }
    288  1.1  christos 
    289  1.1  christos aarch64_insn
    290  1.1  christos aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
    291  1.1  christos {
    292  1.1  christos   return aarch64_operand_modifiers[kind].value;
    293  1.1  christos }
    294  1.1  christos 
    295  1.1  christos enum aarch64_modifier_kind
    296  1.1  christos aarch64_get_operand_modifier_from_value (aarch64_insn value,
    297  1.1  christos 					 bfd_boolean extend_p)
    298  1.1  christos {
    299  1.1  christos   if (extend_p == TRUE)
    300  1.1  christos     return AARCH64_MOD_UXTB + value;
    301  1.1  christos   else
    302  1.1  christos     return AARCH64_MOD_LSL - value;
    303  1.1  christos }
    304  1.1  christos 
    305  1.1  christos bfd_boolean
    306  1.1  christos aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
    307  1.1  christos {
    308  1.1  christos   return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
    309  1.1  christos     ? TRUE : FALSE;
    310  1.1  christos }
    311  1.1  christos 
    312  1.1  christos static inline bfd_boolean
    313  1.1  christos aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
    314  1.1  christos {
    315  1.1  christos   return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
    316  1.1  christos     ? TRUE : FALSE;
    317  1.1  christos }
    318  1.1  christos 
    319  1.1  christos const struct aarch64_name_value_pair aarch64_barrier_options[16] =
    320  1.1  christos {
    321  1.1  christos     { "#0x00", 0x0 },
    322  1.1  christos     { "oshld", 0x1 },
    323  1.1  christos     { "oshst", 0x2 },
    324  1.1  christos     { "osh",   0x3 },
    325  1.1  christos     { "#0x04", 0x4 },
    326  1.1  christos     { "nshld", 0x5 },
    327  1.1  christos     { "nshst", 0x6 },
    328  1.1  christos     { "nsh",   0x7 },
    329  1.1  christos     { "#0x08", 0x8 },
    330  1.1  christos     { "ishld", 0x9 },
    331  1.1  christos     { "ishst", 0xa },
    332  1.1  christos     { "ish",   0xb },
    333  1.1  christos     { "#0x0c", 0xc },
    334  1.1  christos     { "ld",    0xd },
    335  1.1  christos     { "st",    0xe },
    336  1.1  christos     { "sy",    0xf },
    337  1.1  christos };
    338  1.1  christos 
    339  1.1  christos /* op -> op:       load = 0 instruction = 1 store = 2
    340  1.1  christos    l  -> level:    1-3
    341  1.1  christos    t  -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1   */
    342  1.1  christos #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
    343  1.1  christos const struct aarch64_name_value_pair aarch64_prfops[32] =
    344  1.1  christos {
    345  1.1  christos   { "pldl1keep", B(0, 1, 0) },
    346  1.1  christos   { "pldl1strm", B(0, 1, 1) },
    347  1.1  christos   { "pldl2keep", B(0, 2, 0) },
    348  1.1  christos   { "pldl2strm", B(0, 2, 1) },
    349  1.1  christos   { "pldl3keep", B(0, 3, 0) },
    350  1.1  christos   { "pldl3strm", B(0, 3, 1) },
    351  1.1  christos   { NULL, 0x06 },
    352  1.1  christos   { NULL, 0x07 },
    353  1.1  christos   { "plil1keep", B(1, 1, 0) },
    354  1.1  christos   { "plil1strm", B(1, 1, 1) },
    355  1.1  christos   { "plil2keep", B(1, 2, 0) },
    356  1.1  christos   { "plil2strm", B(1, 2, 1) },
    357  1.1  christos   { "plil3keep", B(1, 3, 0) },
    358  1.1  christos   { "plil3strm", B(1, 3, 1) },
    359  1.1  christos   { NULL, 0x0e },
    360  1.1  christos   { NULL, 0x0f },
    361  1.1  christos   { "pstl1keep", B(2, 1, 0) },
    362  1.1  christos   { "pstl1strm", B(2, 1, 1) },
    363  1.1  christos   { "pstl2keep", B(2, 2, 0) },
    364  1.1  christos   { "pstl2strm", B(2, 2, 1) },
    365  1.1  christos   { "pstl3keep", B(2, 3, 0) },
    366  1.1  christos   { "pstl3strm", B(2, 3, 1) },
    367  1.1  christos   { NULL, 0x16 },
    368  1.1  christos   { NULL, 0x17 },
    369  1.1  christos   { NULL, 0x18 },
    370  1.1  christos   { NULL, 0x19 },
    371  1.1  christos   { NULL, 0x1a },
    372  1.1  christos   { NULL, 0x1b },
    373  1.1  christos   { NULL, 0x1c },
    374  1.1  christos   { NULL, 0x1d },
    375  1.1  christos   { NULL, 0x1e },
    376  1.1  christos   { NULL, 0x1f },
    377  1.1  christos };
    378  1.1  christos #undef B
    379  1.1  christos 
    380  1.1  christos /* Utilities on value constraint.  */
    382  1.1  christos 
    383  1.1  christos static inline int
    384  1.1  christos value_in_range_p (int64_t value, int low, int high)
    385  1.1  christos {
    386  1.1  christos   return (value >= low && value <= high) ? 1 : 0;
    387  1.1  christos }
    388  1.1  christos 
    389  1.1  christos static inline int
    390  1.1  christos value_aligned_p (int64_t value, int align)
    391  1.1  christos {
    392  1.1  christos   return ((value & (align - 1)) == 0) ? 1 : 0;
    393  1.1  christos }
    394  1.1  christos 
    395  1.1  christos /* A signed value fits in a field.  */
    396  1.1  christos static inline int
    397  1.1  christos value_fit_signed_field_p (int64_t value, unsigned width)
    398  1.1  christos {
    399  1.1  christos   assert (width < 32);
    400  1.1  christos   if (width < sizeof (value) * 8)
    401  1.1  christos     {
    402  1.1  christos       int64_t lim = (int64_t)1 << (width - 1);
    403  1.1  christos       if (value >= -lim && value < lim)
    404  1.1  christos 	return 1;
    405  1.1  christos     }
    406  1.1  christos   return 0;
    407  1.1  christos }
    408  1.1  christos 
    409  1.1  christos /* An unsigned value fits in a field.  */
    410  1.1  christos static inline int
    411  1.1  christos value_fit_unsigned_field_p (int64_t value, unsigned width)
    412  1.1  christos {
    413  1.1  christos   assert (width < 32);
    414  1.1  christos   if (width < sizeof (value) * 8)
    415  1.1  christos     {
    416  1.1  christos       int64_t lim = (int64_t)1 << width;
    417  1.1  christos       if (value >= 0 && value < lim)
    418  1.1  christos 	return 1;
    419  1.1  christos     }
    420  1.1  christos   return 0;
    421  1.1  christos }
    422  1.1  christos 
    423  1.1  christos /* Return 1 if OPERAND is SP or WSP.  */
    424  1.1  christos int
    425  1.1  christos aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
    426  1.1  christos {
    427  1.1  christos   return ((aarch64_get_operand_class (operand->type)
    428  1.1  christos 	   == AARCH64_OPND_CLASS_INT_REG)
    429  1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type)
    430  1.1  christos 	  && operand->reg.regno == 31);
    431  1.1  christos }
    432  1.1  christos 
    433  1.1  christos /* Return 1 if OPERAND is XZR or WZP.  */
    434  1.1  christos int
    435  1.1  christos aarch64_zero_register_p (const aarch64_opnd_info *operand)
    436  1.1  christos {
    437  1.1  christos   return ((aarch64_get_operand_class (operand->type)
    438  1.1  christos 	   == AARCH64_OPND_CLASS_INT_REG)
    439  1.1  christos 	  && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
    440  1.1  christos 	  && operand->reg.regno == 31);
    441  1.1  christos }
    442  1.1  christos 
    443  1.1  christos /* Return true if the operand *OPERAND that has the operand code
    444  1.1  christos    OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
    445  1.1  christos    qualified by the qualifier TARGET.  */
    446  1.1  christos 
    447  1.1  christos static inline int
    448  1.1  christos operand_also_qualified_p (const struct aarch64_opnd_info *operand,
    449  1.1  christos 			  aarch64_opnd_qualifier_t target)
    450  1.1  christos {
    451  1.1  christos   switch (operand->qualifier)
    452  1.1  christos     {
    453  1.1  christos     case AARCH64_OPND_QLF_W:
    454  1.1  christos       if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
    455  1.1  christos 	return 1;
    456  1.1  christos       break;
    457  1.1  christos     case AARCH64_OPND_QLF_X:
    458  1.1  christos       if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
    459  1.1  christos 	return 1;
    460  1.1  christos       break;
    461  1.1  christos     case AARCH64_OPND_QLF_WSP:
    462  1.1  christos       if (target == AARCH64_OPND_QLF_W
    463  1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
    464  1.1  christos 	return 1;
    465  1.1  christos       break;
    466  1.1  christos     case AARCH64_OPND_QLF_SP:
    467  1.1  christos       if (target == AARCH64_OPND_QLF_X
    468  1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
    469  1.1  christos 	return 1;
    470  1.1  christos       break;
    471  1.1  christos     default:
    472  1.1  christos       break;
    473  1.1  christos     }
    474  1.1  christos 
    475  1.1  christos   return 0;
    476  1.1  christos }
    477  1.1  christos 
    478  1.1  christos /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
    479  1.1  christos    for operand KNOWN_IDX, return the expected qualifier for operand IDX.
    480  1.1  christos 
    481  1.1  christos    Return NIL if more than one expected qualifiers are found.  */
    482  1.1  christos 
    483  1.1  christos aarch64_opnd_qualifier_t
    484  1.1  christos aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
    485  1.1  christos 				int idx,
    486  1.1  christos 				const aarch64_opnd_qualifier_t known_qlf,
    487  1.1  christos 				int known_idx)
    488  1.1  christos {
    489  1.1  christos   int i, saved_i;
    490  1.1  christos 
    491  1.1  christos   /* Special case.
    492  1.1  christos 
    493  1.1  christos      When the known qualifier is NIL, we have to assume that there is only
    494  1.1  christos      one qualifier sequence in the *QSEQ_LIST and return the corresponding
    495  1.1  christos      qualifier directly.  One scenario is that for instruction
    496  1.1  christos 	PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
    497  1.1  christos      which has only one possible valid qualifier sequence
    498  1.1  christos 	NIL, S_D
    499  1.1  christos      the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
    500  1.1  christos      determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
    501  1.1  christos 
    502  1.1  christos      Because the qualifier NIL has dual roles in the qualifier sequence:
    503  1.1  christos      it can mean no qualifier for the operand, or the qualifer sequence is
    504  1.1  christos      not in use (when all qualifiers in the sequence are NILs), we have to
    505  1.1  christos      handle this special case here.  */
    506  1.1  christos   if (known_qlf == AARCH64_OPND_NIL)
    507  1.1  christos     {
    508  1.1  christos       assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
    509  1.1  christos       return qseq_list[0][idx];
    510  1.1  christos     }
    511  1.1  christos 
    512  1.1  christos   for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
    513  1.1  christos     {
    514  1.1  christos       if (qseq_list[i][known_idx] == known_qlf)
    515  1.1  christos 	{
    516  1.1  christos 	  if (saved_i != -1)
    517  1.1  christos 	    /* More than one sequences are found to have KNOWN_QLF at
    518  1.1  christos 	       KNOWN_IDX.  */
    519  1.1  christos 	    return AARCH64_OPND_NIL;
    520  1.1  christos 	  saved_i = i;
    521  1.1  christos 	}
    522  1.1  christos     }
    523  1.1  christos 
    524  1.1  christos   return qseq_list[saved_i][idx];
    525  1.1  christos }
    526  1.1  christos 
    527  1.1  christos enum operand_qualifier_kind
    528  1.1  christos {
    529  1.1  christos   OQK_NIL,
    530  1.1  christos   OQK_OPD_VARIANT,
    531  1.1  christos   OQK_VALUE_IN_RANGE,
    532  1.1  christos   OQK_MISC,
    533  1.1  christos };
    534  1.1  christos 
    535  1.1  christos /* Operand qualifier description.  */
    536  1.1  christos struct operand_qualifier_data
    537  1.1  christos {
    538  1.1  christos   /* The usage of the three data fields depends on the qualifier kind.  */
    539  1.1  christos   int data0;
    540  1.1  christos   int data1;
    541  1.1  christos   int data2;
    542  1.1  christos   /* Description.  */
    543  1.1  christos   const char *desc;
    544  1.1  christos   /* Kind.  */
    545  1.1  christos   enum operand_qualifier_kind kind;
    546  1.1  christos };
    547  1.1  christos 
    548  1.1  christos /* Indexed by the operand qualifier enumerators.  */
    549  1.1  christos struct operand_qualifier_data aarch64_opnd_qualifiers[] =
    550  1.1  christos {
    551  1.1  christos   {0, 0, 0, "NIL", OQK_NIL},
    552  1.1  christos 
    553  1.1  christos   /* Operand variant qualifiers.
    554  1.1  christos      First 3 fields:
    555  1.1  christos      element size, number of elements and common value for encoding.  */
    556  1.1  christos 
    557  1.1  christos   {4, 1, 0x0, "w", OQK_OPD_VARIANT},
    558  1.1  christos   {8, 1, 0x1, "x", OQK_OPD_VARIANT},
    559  1.1  christos   {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
    560  1.1  christos   {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
    561  1.1  christos 
    562  1.1  christos   {1, 1, 0x0, "b", OQK_OPD_VARIANT},
    563  1.1  christos   {2, 1, 0x1, "h", OQK_OPD_VARIANT},
    564  1.1  christos   {4, 1, 0x2, "s", OQK_OPD_VARIANT},
    565  1.1  christos   {8, 1, 0x3, "d", OQK_OPD_VARIANT},
    566  1.1  christos   {16, 1, 0x4, "q", OQK_OPD_VARIANT},
    567  1.1  christos 
    568  1.1  christos   {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
    569  1.1  christos   {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
    570  1.1  christos   {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
    571  1.1  christos   {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
    572  1.1  christos   {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
    573  1.1  christos   {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
    574  1.1  christos   {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
    575  1.1  christos   {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
    576  1.1  christos   {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
    577  1.1  christos 
    578  1.1  christos   /* Qualifiers constraining the value range.
    579  1.1  christos      First 3 fields:
    580  1.1  christos      Lower bound, higher bound, unused.  */
    581  1.1  christos 
    582  1.1  christos   {0,  7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
    583  1.1  christos   {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
    584  1.1  christos   {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
    585  1.1  christos   {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
    586  1.1  christos   {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
    587  1.1  christos   {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
    588  1.1  christos 
    589  1.1  christos   /* Qualifiers for miscellaneous purpose.
    590  1.1  christos      First 3 fields:
    591  1.1  christos      unused, unused and unused.  */
    592  1.1  christos 
    593  1.1  christos   {0, 0, 0, "lsl", 0},
    594  1.1  christos   {0, 0, 0, "msl", 0},
    595  1.1  christos 
    596  1.1  christos   {0, 0, 0, "retrieving", 0},
    597  1.1  christos };
    598  1.1  christos 
    599  1.1  christos static inline bfd_boolean
    600  1.1  christos operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
    601  1.1  christos {
    602  1.1  christos   return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
    603  1.1  christos     ? TRUE : FALSE;
    604  1.1  christos }
    605  1.1  christos 
    606  1.1  christos static inline bfd_boolean
    607  1.1  christos qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
    608  1.1  christos {
    609  1.1  christos   return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
    610  1.1  christos     ? TRUE : FALSE;
    611  1.1  christos }
    612  1.1  christos 
    613  1.1  christos const char*
    614  1.1  christos aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
    615  1.1  christos {
    616  1.1  christos   return aarch64_opnd_qualifiers[qualifier].desc;
    617  1.1  christos }
    618  1.1  christos 
    619  1.1  christos /* Given an operand qualifier, return the expected data element size
    620  1.1  christos    of a qualified operand.  */
    621  1.1  christos unsigned char
    622  1.1  christos aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
    623  1.1  christos {
    624  1.1  christos   assert (operand_variant_qualifier_p (qualifier) == TRUE);
    625  1.1  christos   return aarch64_opnd_qualifiers[qualifier].data0;
    626  1.1  christos }
    627  1.1  christos 
    628  1.1  christos unsigned char
    629  1.1  christos aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
    630  1.1  christos {
    631  1.1  christos   assert (operand_variant_qualifier_p (qualifier) == TRUE);
    632  1.1  christos   return aarch64_opnd_qualifiers[qualifier].data1;
    633  1.1  christos }
    634  1.1  christos 
    635  1.1  christos aarch64_insn
    636  1.1  christos aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
    637  1.1  christos {
    638  1.1  christos   assert (operand_variant_qualifier_p (qualifier) == TRUE);
    639  1.1  christos   return aarch64_opnd_qualifiers[qualifier].data2;
    640  1.1  christos }
    641  1.1  christos 
    642  1.1  christos static int
    643  1.1  christos get_lower_bound (aarch64_opnd_qualifier_t qualifier)
    644  1.1  christos {
    645  1.1  christos   assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
    646  1.1  christos   return aarch64_opnd_qualifiers[qualifier].data0;
    647  1.1  christos }
    648  1.1  christos 
    649  1.1  christos static int
    650  1.1  christos get_upper_bound (aarch64_opnd_qualifier_t qualifier)
    651  1.1  christos {
    652  1.1  christos   assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
    653  1.1  christos   return aarch64_opnd_qualifiers[qualifier].data1;
    654  1.1  christos }
    655  1.1  christos 
    656  1.1  christos #ifdef DEBUG_AARCH64
    657  1.1  christos void
    658  1.1  christos aarch64_verbose (const char *str, ...)
    659  1.1  christos {
    660  1.1  christos   va_list ap;
    661  1.1  christos   va_start (ap, str);
    662  1.1  christos   printf ("#### ");
    663  1.1  christos   vprintf (str, ap);
    664  1.1  christos   printf ("\n");
    665  1.1  christos   va_end (ap);
    666  1.1  christos }
    667  1.1  christos 
    668  1.1  christos static inline void
    669  1.1  christos dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
    670  1.1  christos {
    671  1.1  christos   int i;
    672  1.1  christos   printf ("#### \t");
    673  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
    674  1.1  christos     printf ("%s,", aarch64_get_qualifier_name (*qualifier));
    675  1.1  christos   printf ("\n");
    676  1.1  christos }
    677  1.1  christos 
    678  1.1  christos static void
    679  1.1  christos dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
    680  1.1  christos 		       const aarch64_opnd_qualifier_t *qualifier)
    681  1.1  christos {
    682  1.1  christos   int i;
    683  1.1  christos   aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
    684  1.1  christos 
    685  1.1  christos   aarch64_verbose ("dump_match_qualifiers:");
    686  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
    687  1.1  christos     curr[i] = opnd[i].qualifier;
    688  1.1  christos   dump_qualifier_sequence (curr);
    689  1.1  christos   aarch64_verbose ("against");
    690  1.1  christos   dump_qualifier_sequence (qualifier);
    691  1.1  christos }
    692  1.1  christos #endif /* DEBUG_AARCH64 */
    693  1.1  christos 
    694  1.1  christos /* TODO improve this, we can have an extra field at the runtime to
    695  1.1  christos    store the number of operands rather than calculating it every time.  */
    696  1.1  christos 
    697  1.1  christos int
    698  1.1  christos aarch64_num_of_operands (const aarch64_opcode *opcode)
    699  1.1  christos {
    700  1.1  christos   int i = 0;
    701  1.1  christos   const enum aarch64_opnd *opnds = opcode->operands;
    702  1.1  christos   while (opnds[i++] != AARCH64_OPND_NIL)
    703  1.1  christos     ;
    704  1.1  christos   --i;
    705  1.1  christos   assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
    706  1.1  christos   return i;
    707  1.1  christos }
    708  1.1  christos 
    709  1.1  christos /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
    710  1.1  christos    If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
    711  1.1  christos 
    712  1.1  christos    N.B. on the entry, it is very likely that only some operands in *INST
    713  1.1  christos    have had their qualifiers been established.
    714  1.1  christos 
    715  1.1  christos    If STOP_AT is not -1, the function will only try to match
    716  1.1  christos    the qualifier sequence for operands before and including the operand
    717  1.1  christos    of index STOP_AT; and on success *RET will only be filled with the first
    718  1.1  christos    (STOP_AT+1) qualifiers.
    719  1.1  christos 
    720  1.1  christos    A couple examples of the matching algorithm:
    721  1.1  christos 
    722  1.1  christos    X,W,NIL should match
    723  1.1  christos    X,W,NIL
    724  1.1  christos 
    725  1.1  christos    NIL,NIL should match
    726  1.1  christos    X  ,NIL
    727  1.1  christos 
    728  1.1  christos    Apart from serving the main encoding routine, this can also be called
    729  1.1  christos    during or after the operand decoding.  */
    730  1.1  christos 
    731  1.1  christos int
    732  1.1  christos aarch64_find_best_match (const aarch64_inst *inst,
    733  1.1  christos 			 const aarch64_opnd_qualifier_seq_t *qualifiers_list,
    734  1.1  christos 			 int stop_at, aarch64_opnd_qualifier_t *ret)
    735  1.1  christos {
    736  1.1  christos   int found = 0;
    737  1.1  christos   int i, num_opnds;
    738  1.1  christos   const aarch64_opnd_qualifier_t *qualifiers;
    739  1.1  christos 
    740  1.1  christos   num_opnds = aarch64_num_of_operands (inst->opcode);
    741  1.1  christos   if (num_opnds == 0)
    742  1.1  christos     {
    743  1.1  christos       DEBUG_TRACE ("SUCCEED: no operand");
    744  1.1  christos       return 1;
    745  1.1  christos     }
    746  1.1  christos 
    747  1.1  christos   if (stop_at < 0 || stop_at >= num_opnds)
    748  1.1  christos     stop_at = num_opnds - 1;
    749  1.1  christos 
    750  1.1  christos   /* For each pattern.  */
    751  1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
    752  1.1  christos     {
    753  1.1  christos       int j;
    754  1.1  christos       qualifiers = *qualifiers_list;
    755  1.1  christos 
    756  1.1  christos       /* Start as positive.  */
    757  1.1  christos       found = 1;
    758  1.1  christos 
    759  1.1  christos       DEBUG_TRACE ("%d", i);
    760  1.1  christos #ifdef DEBUG_AARCH64
    761  1.1  christos       if (debug_dump)
    762  1.1  christos 	dump_match_qualifiers (inst->operands, qualifiers);
    763  1.1  christos #endif
    764  1.1  christos 
    765  1.1  christos       /* Most opcodes has much fewer patterns in the list.
    766  1.1  christos 	 First NIL qualifier indicates the end in the list.   */
    767  1.1  christos       if (empty_qualifier_sequence_p (qualifiers) == TRUE)
    768  1.1  christos 	{
    769  1.1  christos 	  DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
    770  1.1  christos 	  if (i)
    771  1.1  christos 	    found = 0;
    772  1.1  christos 	  break;
    773  1.1  christos 	}
    774  1.1  christos 
    775  1.1  christos       for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
    776  1.1  christos 	{
    777  1.1  christos 	  if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
    778  1.1  christos 	    {
    779  1.1  christos 	      /* Either the operand does not have qualifier, or the qualifier
    780  1.1  christos 		 for the operand needs to be deduced from the qualifier
    781  1.1  christos 		 sequence.
    782  1.1  christos 		 In the latter case, any constraint checking related with
    783  1.1  christos 		 the obtained qualifier should be done later in
    784  1.1  christos 		 operand_general_constraint_met_p.  */
    785  1.1  christos 	      continue;
    786  1.1  christos 	    }
    787  1.1  christos 	  else if (*qualifiers != inst->operands[j].qualifier)
    788  1.1  christos 	    {
    789  1.1  christos 	      /* Unless the target qualifier can also qualify the operand
    790  1.1  christos 		 (which has already had a non-nil qualifier), non-equal
    791  1.1  christos 		 qualifiers are generally un-matched.  */
    792  1.1  christos 	      if (operand_also_qualified_p (inst->operands + j, *qualifiers))
    793  1.1  christos 		continue;
    794  1.1  christos 	      else
    795  1.1  christos 		{
    796  1.1  christos 		  found = 0;
    797  1.1  christos 		  break;
    798  1.1  christos 		}
    799  1.1  christos 	    }
    800  1.1  christos 	  else
    801  1.1  christos 	    continue;	/* Equal qualifiers are certainly matched.  */
    802  1.1  christos 	}
    803  1.1  christos 
    804  1.1  christos       /* Qualifiers established.  */
    805  1.1  christos       if (found == 1)
    806  1.1  christos 	break;
    807  1.1  christos     }
    808  1.1  christos 
    809  1.1  christos   if (found == 1)
    810  1.1  christos     {
    811  1.1  christos       /* Fill the result in *RET.  */
    812  1.1  christos       int j;
    813  1.1  christos       qualifiers = *qualifiers_list;
    814  1.1  christos 
    815  1.1  christos       DEBUG_TRACE ("complete qualifiers using list %d", i);
    816  1.1  christos #ifdef DEBUG_AARCH64
    817  1.1  christos       if (debug_dump)
    818  1.1  christos 	dump_qualifier_sequence (qualifiers);
    819  1.1  christos #endif
    820  1.1  christos 
    821  1.1  christos       for (j = 0; j <= stop_at; ++j, ++qualifiers)
    822  1.1  christos 	ret[j] = *qualifiers;
    823  1.1  christos       for (; j < AARCH64_MAX_OPND_NUM; ++j)
    824  1.1  christos 	ret[j] = AARCH64_OPND_QLF_NIL;
    825  1.1  christos 
    826  1.1  christos       DEBUG_TRACE ("SUCCESS");
    827  1.1  christos       return 1;
    828  1.1  christos     }
    829  1.1  christos 
    830  1.1  christos   DEBUG_TRACE ("FAIL");
    831  1.1  christos   return 0;
    832  1.1  christos }
    833  1.1  christos 
    834  1.1  christos /* Operand qualifier matching and resolving.
    835  1.1  christos 
    836  1.1  christos    Return 1 if the operand qualifier(s) in *INST match one of the qualifier
    837  1.1  christos    sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
    838  1.1  christos 
    839  1.1  christos    if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
    840  1.1  christos    succeeds.  */
    841  1.1  christos 
    842  1.1  christos static int
    843  1.1  christos match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
    844  1.1  christos {
    845  1.1  christos   int i;
    846  1.1  christos   aarch64_opnd_qualifier_seq_t qualifiers;
    847  1.1  christos 
    848  1.1  christos   if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
    849  1.1  christos 			       qualifiers))
    850  1.1  christos     {
    851  1.1  christos       DEBUG_TRACE ("matching FAIL");
    852  1.1  christos       return 0;
    853  1.1  christos     }
    854  1.1  christos 
    855  1.1  christos   /* Update the qualifiers.  */
    856  1.1  christos   if (update_p == TRUE)
    857  1.1  christos     for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
    858  1.1  christos       {
    859  1.1  christos 	if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
    860  1.1  christos 	  break;
    861  1.1  christos 	DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
    862  1.1  christos 			"update %s with %s for operand %d",
    863  1.1  christos 			aarch64_get_qualifier_name (inst->operands[i].qualifier),
    864  1.1  christos 			aarch64_get_qualifier_name (qualifiers[i]), i);
    865  1.1  christos 	inst->operands[i].qualifier = qualifiers[i];
    866  1.1  christos       }
    867  1.1  christos 
    868  1.1  christos   DEBUG_TRACE ("matching SUCCESS");
    869  1.1  christos   return 1;
    870  1.1  christos }
    871  1.1  christos 
    872  1.1  christos /* Return TRUE if VALUE is a wide constant that can be moved into a general
    873  1.1  christos    register by MOVZ.
    874  1.1  christos 
    875  1.1  christos    IS32 indicates whether value is a 32-bit immediate or not.
    876  1.1  christos    If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
    877  1.1  christos    amount will be returned in *SHIFT_AMOUNT.  */
    878  1.1  christos 
    879  1.1  christos bfd_boolean
    880  1.1  christos aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
    881  1.1  christos {
    882  1.1  christos   int amount;
    883  1.1  christos 
    884  1.1  christos   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
    885  1.1  christos 
    886  1.1  christos   if (is32)
    887  1.1  christos     {
    888  1.1  christos       /* Allow all zeros or all ones in top 32-bits, so that
    889  1.1  christos 	 32-bit constant expressions like ~0x80000000 are
    890  1.1  christos 	 permitted.  */
    891  1.1  christos       uint64_t ext = value;
    892  1.1  christos       if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
    893  1.1  christos 	/* Immediate out of range.  */
    894  1.1  christos 	return FALSE;
    895  1.1  christos       value &= (int64_t) 0xffffffff;
    896  1.1  christos     }
    897  1.1  christos 
    898  1.1  christos   /* first, try movz then movn */
    899  1.1  christos   amount = -1;
    900  1.1  christos   if ((value & ((int64_t) 0xffff << 0)) == value)
    901  1.1  christos     amount = 0;
    902  1.1  christos   else if ((value & ((int64_t) 0xffff << 16)) == value)
    903  1.1  christos     amount = 16;
    904  1.1  christos   else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
    905  1.1  christos     amount = 32;
    906  1.1  christos   else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
    907  1.1  christos     amount = 48;
    908  1.1  christos 
    909  1.1  christos   if (amount == -1)
    910  1.1  christos     {
    911  1.1  christos       DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
    912  1.1  christos       return FALSE;
    913  1.1  christos     }
    914  1.1  christos 
    915  1.1  christos   if (shift_amount != NULL)
    916  1.1  christos     *shift_amount = amount;
    917  1.1  christos 
    918  1.1  christos   DEBUG_TRACE ("exit TRUE with amount %d", amount);
    919  1.1  christos 
    920  1.1  christos   return TRUE;
    921  1.1  christos }
    922  1.1  christos 
    923  1.1  christos /* Build the accepted values for immediate logical SIMD instructions.
    924  1.1  christos 
    925  1.1  christos    The standard encodings of the immediate value are:
    926  1.1  christos      N      imms     immr         SIMD size  R             S
    927  1.1  christos      1      ssssss   rrrrrr       64      UInt(rrrrrr)  UInt(ssssss)
    928  1.1  christos      0      0sssss   0rrrrr       32      UInt(rrrrr)   UInt(sssss)
    929  1.1  christos      0      10ssss   00rrrr       16      UInt(rrrr)    UInt(ssss)
    930  1.1  christos      0      110sss   000rrr       8       UInt(rrr)     UInt(sss)
    931  1.1  christos      0      1110ss   0000rr       4       UInt(rr)      UInt(ss)
    932  1.1  christos      0      11110s   00000r       2       UInt(r)       UInt(s)
    933  1.1  christos    where all-ones value of S is reserved.
    934  1.1  christos 
    935  1.1  christos    Let's call E the SIMD size.
    936  1.1  christos 
    937  1.1  christos    The immediate value is: S+1 bits '1' rotated to the right by R.
    938  1.1  christos 
    939  1.1  christos    The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
    940  1.1  christos    (remember S != E - 1).  */
    941  1.1  christos 
    942  1.1  christos #define TOTAL_IMM_NB  5334
    943  1.1  christos 
    944  1.1  christos typedef struct
    945  1.1  christos {
    946  1.1  christos   uint64_t imm;
    947  1.1  christos   aarch64_insn encoding;
    948  1.1  christos } simd_imm_encoding;
    949  1.1  christos 
    950  1.1  christos static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
    951  1.1  christos 
    952  1.1  christos static int
    953  1.1  christos simd_imm_encoding_cmp(const void *i1, const void *i2)
    954  1.1  christos {
    955  1.1  christos   const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
    956  1.1  christos   const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
    957  1.1  christos 
    958  1.1  christos   if (imm1->imm < imm2->imm)
    959  1.1  christos     return -1;
    960  1.1  christos   if (imm1->imm > imm2->imm)
    961  1.1  christos     return +1;
    962  1.1  christos   return 0;
    963  1.1  christos }
    964  1.1  christos 
    965  1.1  christos /* immediate bitfield standard encoding
    966  1.1  christos    imm13<12> imm13<5:0> imm13<11:6> SIMD size R      S
    967  1.1  christos    1         ssssss     rrrrrr      64        rrrrrr ssssss
    968  1.1  christos    0         0sssss     0rrrrr      32        rrrrr  sssss
    969  1.1  christos    0         10ssss     00rrrr      16        rrrr   ssss
    970  1.1  christos    0         110sss     000rrr      8         rrr    sss
    971  1.1  christos    0         1110ss     0000rr      4         rr     ss
    972  1.1  christos    0         11110s     00000r      2         r      s  */
    973  1.1  christos static inline int
    974  1.1  christos encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
    975  1.1  christos {
    976  1.1  christos   return (is64 << 12) | (r << 6) | s;
    977  1.1  christos }
    978  1.1  christos 
    979  1.1  christos static void
    980  1.1  christos build_immediate_table (void)
    981  1.1  christos {
    982  1.1  christos   uint32_t log_e, e, s, r, s_mask;
    983  1.1  christos   uint64_t mask, imm;
    984  1.1  christos   int nb_imms;
    985  1.1  christos   int is64;
    986  1.1  christos 
    987  1.1  christos   nb_imms = 0;
    988  1.1  christos   for (log_e = 1; log_e <= 6; log_e++)
    989  1.1  christos     {
    990  1.1  christos       /* Get element size.  */
    991  1.1  christos       e = 1u << log_e;
    992  1.1  christos       if (log_e == 6)
    993  1.1  christos 	{
    994  1.1  christos 	  is64 = 1;
    995  1.1  christos 	  mask = 0xffffffffffffffffull;
    996  1.1  christos 	  s_mask = 0;
    997  1.1  christos 	}
    998  1.1  christos       else
    999  1.1  christos 	{
   1000  1.1  christos 	  is64 = 0;
   1001  1.1  christos 	  mask = (1ull << e) - 1;
   1002  1.1  christos 	  /* log_e  s_mask
   1003  1.1  christos 	     1     ((1 << 4) - 1) << 2 = 111100
   1004  1.1  christos 	     2     ((1 << 3) - 1) << 3 = 111000
   1005  1.1  christos 	     3     ((1 << 2) - 1) << 4 = 110000
   1006  1.1  christos 	     4     ((1 << 1) - 1) << 5 = 100000
   1007  1.1  christos 	     5     ((1 << 0) - 1) << 6 = 000000  */
   1008  1.1  christos 	  s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
   1009  1.1  christos 	}
   1010  1.1  christos       for (s = 0; s < e - 1; s++)
   1011  1.1  christos 	for (r = 0; r < e; r++)
   1012  1.1  christos 	  {
   1013  1.1  christos 	    /* s+1 consecutive bits to 1 (s < 63) */
   1014  1.1  christos 	    imm = (1ull << (s + 1)) - 1;
   1015  1.1  christos 	    /* rotate right by r */
   1016  1.1  christos 	    if (r != 0)
   1017  1.1  christos 	      imm = (imm >> r) | ((imm << (e - r)) & mask);
   1018  1.1  christos 	    /* replicate the constant depending on SIMD size */
   1019  1.1  christos 	    switch (log_e)
   1020  1.1  christos 	      {
   1021  1.1  christos 	      case 1: imm = (imm <<  2) | imm;
   1022  1.1  christos 	      case 2: imm = (imm <<  4) | imm;
   1023  1.1  christos 	      case 3: imm = (imm <<  8) | imm;
   1024  1.1  christos 	      case 4: imm = (imm << 16) | imm;
   1025  1.1  christos 	      case 5: imm = (imm << 32) | imm;
   1026  1.1  christos 	      case 6: break;
   1027  1.1  christos 	      default: abort ();
   1028  1.1  christos 	      }
   1029  1.1  christos 	    simd_immediates[nb_imms].imm = imm;
   1030  1.1  christos 	    simd_immediates[nb_imms].encoding =
   1031  1.1  christos 	      encode_immediate_bitfield(is64, s | s_mask, r);
   1032  1.1  christos 	    nb_imms++;
   1033  1.1  christos 	  }
   1034  1.1  christos     }
   1035  1.1  christos   assert (nb_imms == TOTAL_IMM_NB);
   1036  1.1  christos   qsort(simd_immediates, nb_imms,
   1037  1.1  christos 	sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
   1038  1.1  christos }
   1039  1.1  christos 
   1040  1.1  christos /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
   1041  1.1  christos    be accepted by logical (immediate) instructions
   1042  1.1  christos    e.g. ORR <Xd|SP>, <Xn>, #<imm>.
   1043  1.1  christos 
   1044  1.1  christos    IS32 indicates whether or not VALUE is a 32-bit immediate.
   1045  1.1  christos    If ENCODING is not NULL, on the return of TRUE, the standard encoding for
   1046  1.1  christos    VALUE will be returned in *ENCODING.  */
   1047  1.1  christos 
   1048  1.1  christos bfd_boolean
   1049  1.1  christos aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
   1050  1.1  christos {
   1051  1.1  christos   simd_imm_encoding imm_enc;
   1052  1.1  christos   const simd_imm_encoding *imm_encoding;
   1053  1.1  christos   static bfd_boolean initialized = FALSE;
   1054  1.1  christos 
   1055  1.1  christos   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
   1056  1.1  christos 	       value, is32);
   1057  1.1  christos 
   1058  1.1  christos   if (initialized == FALSE)
   1059  1.1  christos     {
   1060  1.1  christos       build_immediate_table ();
   1061  1.1  christos       initialized = TRUE;
   1062  1.1  christos     }
   1063  1.1  christos 
   1064  1.1  christos   if (is32)
   1065  1.1  christos     {
   1066  1.1  christos       /* Allow all zeros or all ones in top 32-bits, so that
   1067  1.1  christos 	 constant expressions like ~1 are permitted.  */
   1068  1.1  christos       if (value >> 32 != 0 && value >> 32 != 0xffffffff)
   1069  1.1  christos 	return FALSE;
   1070  1.1  christos 
   1071  1.1  christos       /* Replicate the 32 lower bits to the 32 upper bits.  */
   1072  1.1  christos       value &= 0xffffffff;
   1073  1.1  christos       value |= value << 32;
   1074  1.1  christos     }
   1075  1.1  christos 
   1076  1.1  christos   imm_enc.imm = value;
   1077  1.1  christos   imm_encoding = (const simd_imm_encoding *)
   1078  1.1  christos     bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
   1079  1.1  christos             sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
   1080  1.1  christos   if (imm_encoding == NULL)
   1081  1.1  christos     {
   1082  1.1  christos       DEBUG_TRACE ("exit with FALSE");
   1083  1.1  christos       return FALSE;
   1084  1.1  christos     }
   1085  1.1  christos   if (encoding != NULL)
   1086  1.1  christos     *encoding = imm_encoding->encoding;
   1087  1.1  christos   DEBUG_TRACE ("exit with TRUE");
   1088  1.1  christos   return TRUE;
   1089  1.1  christos }
   1090  1.1  christos 
   1091  1.1  christos /* If 64-bit immediate IMM is in the format of
   1092  1.1  christos    "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
   1093  1.1  christos    where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
   1094  1.1  christos    of value "abcdefgh".  Otherwise return -1.  */
   1095  1.1  christos int
   1096  1.1  christos aarch64_shrink_expanded_imm8 (uint64_t imm)
   1097  1.1  christos {
   1098  1.1  christos   int i, ret;
   1099  1.1  christos   uint32_t byte;
   1100  1.1  christos 
   1101  1.1  christos   ret = 0;
   1102  1.1  christos   for (i = 0; i < 8; i++)
   1103  1.1  christos     {
   1104  1.1  christos       byte = (imm >> (8 * i)) & 0xff;
   1105  1.1  christos       if (byte == 0xff)
   1106  1.1  christos 	ret |= 1 << i;
   1107  1.1  christos       else if (byte != 0x00)
   1108  1.1  christos 	return -1;
   1109  1.1  christos     }
   1110  1.1  christos   return ret;
   1111  1.1  christos }
   1112  1.1  christos 
   1113  1.1  christos /* Utility inline functions for operand_general_constraint_met_p.  */
   1114  1.1  christos 
   1115  1.1  christos static inline void
   1116  1.1  christos set_error (aarch64_operand_error *mismatch_detail,
   1117  1.1  christos 	   enum aarch64_operand_error_kind kind, int idx,
   1118  1.1  christos 	   const char* error)
   1119  1.1  christos {
   1120  1.1  christos   if (mismatch_detail == NULL)
   1121  1.1  christos     return;
   1122  1.1  christos   mismatch_detail->kind = kind;
   1123  1.1  christos   mismatch_detail->index = idx;
   1124  1.1  christos   mismatch_detail->error = error;
   1125  1.1  christos }
   1126  1.1  christos 
   1127  1.1  christos static inline void
   1128  1.1  christos set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
   1129  1.1  christos 		  const char* error)
   1130  1.1  christos {
   1131  1.1  christos   if (mismatch_detail == NULL)
   1132  1.1  christos     return;
   1133  1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
   1134  1.1  christos }
   1135  1.1  christos 
   1136  1.1  christos static inline void
   1137  1.1  christos set_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1138  1.1  christos 			int idx, int lower_bound, int upper_bound,
   1139  1.1  christos 			const char* error)
   1140  1.1  christos {
   1141  1.1  christos   if (mismatch_detail == NULL)
   1142  1.1  christos     return;
   1143  1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
   1144  1.1  christos   mismatch_detail->data[0] = lower_bound;
   1145  1.1  christos   mismatch_detail->data[1] = upper_bound;
   1146  1.1  christos }
   1147  1.1  christos 
   1148  1.1  christos static inline void
   1149  1.1  christos set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1150  1.1  christos 			    int idx, int lower_bound, int upper_bound)
   1151  1.1  christos {
   1152  1.1  christos   if (mismatch_detail == NULL)
   1153  1.1  christos     return;
   1154  1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1155  1.1  christos 			  _("immediate value"));
   1156  1.1  christos }
   1157  1.1  christos 
   1158  1.1  christos static inline void
   1159  1.1  christos set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1160  1.1  christos 			       int idx, int lower_bound, int upper_bound)
   1161  1.1  christos {
   1162  1.1  christos   if (mismatch_detail == NULL)
   1163  1.1  christos     return;
   1164  1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1165  1.1  christos 			  _("immediate offset"));
   1166  1.1  christos }
   1167  1.1  christos 
   1168  1.1  christos static inline void
   1169  1.1  christos set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1170  1.1  christos 			      int idx, int lower_bound, int upper_bound)
   1171  1.1  christos {
   1172  1.1  christos   if (mismatch_detail == NULL)
   1173  1.1  christos     return;
   1174  1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1175  1.1  christos 			  _("register number"));
   1176  1.1  christos }
   1177  1.1  christos 
   1178  1.1  christos static inline void
   1179  1.1  christos set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1180  1.1  christos 				 int idx, int lower_bound, int upper_bound)
   1181  1.1  christos {
   1182  1.1  christos   if (mismatch_detail == NULL)
   1183  1.1  christos     return;
   1184  1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1185  1.1  christos 			  _("register element index"));
   1186  1.1  christos }
   1187  1.1  christos 
   1188  1.1  christos static inline void
   1189  1.1  christos set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1190  1.1  christos 				   int idx, int lower_bound, int upper_bound)
   1191  1.1  christos {
   1192  1.1  christos   if (mismatch_detail == NULL)
   1193  1.1  christos     return;
   1194  1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1195  1.1  christos 			  _("shift amount"));
   1196  1.1  christos }
   1197  1.1  christos 
   1198  1.1  christos static inline void
   1199  1.1  christos set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
   1200  1.1  christos 		     int alignment)
   1201  1.1  christos {
   1202  1.1  christos   if (mismatch_detail == NULL)
   1203  1.1  christos     return;
   1204  1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
   1205  1.1  christos   mismatch_detail->data[0] = alignment;
   1206  1.1  christos }
   1207  1.1  christos 
   1208  1.1  christos static inline void
   1209  1.1  christos set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
   1210  1.1  christos 		    int expected_num)
   1211  1.1  christos {
   1212  1.1  christos   if (mismatch_detail == NULL)
   1213  1.1  christos     return;
   1214  1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
   1215  1.1  christos   mismatch_detail->data[0] = expected_num;
   1216  1.1  christos }
   1217  1.1  christos 
   1218  1.1  christos static inline void
   1219  1.1  christos set_other_error (aarch64_operand_error *mismatch_detail, int idx,
   1220  1.1  christos 		 const char* error)
   1221  1.1  christos {
   1222  1.1  christos   if (mismatch_detail == NULL)
   1223  1.1  christos     return;
   1224  1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
   1225  1.1  christos }
   1226  1.1  christos 
   1227  1.1  christos /* General constraint checking based on operand code.
   1228  1.1  christos 
   1229  1.1  christos    Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
   1230  1.1  christos    as the IDXth operand of opcode OPCODE.  Otherwise return 0.
   1231  1.1  christos 
   1232  1.1  christos    This function has to be called after the qualifiers for all operands
   1233  1.1  christos    have been resolved.
   1234  1.1  christos 
   1235  1.1  christos    Mismatching error message is returned in *MISMATCH_DETAIL upon request,
   1236  1.1  christos    i.e. when MISMATCH_DETAIL is non-NULL.  This avoids the generation
   1237  1.1  christos    of error message during the disassembling where error message is not
   1238  1.1  christos    wanted.  We avoid the dynamic construction of strings of error messages
   1239  1.1  christos    here (i.e. in libopcodes), as it is costly and complicated; instead, we
   1240  1.1  christos    use a combination of error code, static string and some integer data to
   1241  1.1  christos    represent an error.  */
   1242  1.1  christos 
   1243  1.1  christos static int
   1244  1.1  christos operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
   1245  1.1  christos 				  enum aarch64_opnd type,
   1246  1.1  christos 				  const aarch64_opcode *opcode,
   1247  1.1  christos 				  aarch64_operand_error *mismatch_detail)
   1248  1.1  christos {
   1249  1.1  christos   unsigned num;
   1250  1.1  christos   unsigned char size;
   1251  1.1  christos   int64_t imm;
   1252  1.1  christos   const aarch64_opnd_info *opnd = opnds + idx;
   1253  1.1  christos   aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
   1254  1.1  christos 
   1255  1.1  christos   assert (opcode->operands[idx] == opnd->type && opnd->type == type);
   1256  1.1  christos 
   1257  1.1  christos   switch (aarch64_operands[type].op_class)
   1258  1.3  christos     {
   1259  1.3  christos     case AARCH64_OPND_CLASS_INT_REG:
   1260  1.3  christos       /* Check pair reg constraints for cas* instructions.  */
   1261  1.3  christos       if (type == AARCH64_OPND_PAIRREG)
   1262  1.3  christos 	{
   1263  1.3  christos 	  assert (idx == 1 || idx == 3);
   1264  1.3  christos 	  if (opnds[idx - 1].reg.regno % 2 != 0)
   1265  1.3  christos 	    {
   1266  1.3  christos 	      set_syntax_error (mismatch_detail, idx - 1,
   1267  1.3  christos 				_("reg pair must start from even reg"));
   1268  1.3  christos 	      return 0;
   1269  1.3  christos 	    }
   1270  1.3  christos 	  if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
   1271  1.3  christos 	    {
   1272  1.3  christos 	      set_syntax_error (mismatch_detail, idx,
   1273  1.3  christos 				_("reg pair must be contiguous"));
   1274  1.3  christos 	      return 0;
   1275  1.3  christos 	    }
   1276  1.3  christos 	  break;
   1277  1.1  christos 	}
   1278  1.1  christos 
   1279  1.1  christos       /* <Xt> may be optional in some IC and TLBI instructions.  */
   1280  1.1  christos       if (type == AARCH64_OPND_Rt_SYS)
   1281  1.1  christos 	{
   1282  1.1  christos 	  assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
   1283  1.1  christos 			       == AARCH64_OPND_CLASS_SYSTEM));
   1284  1.1  christos 	  if (opnds[1].present && !opnds[0].sysins_op->has_xt)
   1285  1.1  christos 	    {
   1286  1.1  christos 	      set_other_error (mismatch_detail, idx, _("extraneous register"));
   1287  1.1  christos 	      return 0;
   1288  1.1  christos 	    }
   1289  1.1  christos 	  if (!opnds[1].present && opnds[0].sysins_op->has_xt)
   1290  1.1  christos 	    {
   1291  1.1  christos 	      set_other_error (mismatch_detail, idx, _("missing register"));
   1292  1.1  christos 	      return 0;
   1293  1.1  christos 	    }
   1294  1.1  christos 	}
   1295  1.1  christos       switch (qualifier)
   1296  1.1  christos 	{
   1297  1.1  christos 	case AARCH64_OPND_QLF_WSP:
   1298  1.1  christos 	case AARCH64_OPND_QLF_SP:
   1299  1.1  christos 	  if (!aarch64_stack_pointer_p (opnd))
   1300  1.1  christos 	    {
   1301  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1302  1.1  christos 			       _("stack pointer register expected"));
   1303  1.1  christos 	      return 0;
   1304  1.1  christos 	    }
   1305  1.1  christos 	  break;
   1306  1.1  christos 	default:
   1307  1.1  christos 	  break;
   1308  1.1  christos 	}
   1309  1.1  christos       break;
   1310  1.1  christos 
   1311  1.1  christos     case AARCH64_OPND_CLASS_COND:
   1312  1.1  christos       if (type == AARCH64_OPND_COND1
   1313  1.1  christos 	  && (opnds[idx].cond->value & 0xe) == 0xe)
   1314  1.1  christos 	{
   1315  1.1  christos 	  /* Not allow AL or NV.  */
   1316  1.1  christos 	  set_syntax_error (mismatch_detail, idx, NULL);
   1317  1.1  christos 	}
   1318  1.1  christos       break;
   1319  1.1  christos 
   1320  1.1  christos     case AARCH64_OPND_CLASS_ADDRESS:
   1321  1.1  christos       /* Check writeback.  */
   1322  1.1  christos       switch (opcode->iclass)
   1323  1.1  christos 	{
   1324  1.1  christos 	case ldst_pos:
   1325  1.1  christos 	case ldst_unscaled:
   1326  1.1  christos 	case ldstnapair_offs:
   1327  1.1  christos 	case ldstpair_off:
   1328  1.1  christos 	case ldst_unpriv:
   1329  1.1  christos 	  if (opnd->addr.writeback == 1)
   1330  1.1  christos 	    {
   1331  1.1  christos 	      set_syntax_error (mismatch_detail, idx,
   1332  1.1  christos 				_("unexpected address writeback"));
   1333  1.1  christos 	      return 0;
   1334  1.1  christos 	    }
   1335  1.1  christos 	  break;
   1336  1.1  christos 	case ldst_imm9:
   1337  1.1  christos 	case ldstpair_indexed:
   1338  1.1  christos 	case asisdlsep:
   1339  1.1  christos 	case asisdlsop:
   1340  1.1  christos 	  if (opnd->addr.writeback == 0)
   1341  1.1  christos 	    {
   1342  1.1  christos 	      set_syntax_error (mismatch_detail, idx,
   1343  1.1  christos 				_("address writeback expected"));
   1344  1.1  christos 	      return 0;
   1345  1.1  christos 	    }
   1346  1.1  christos 	  break;
   1347  1.1  christos 	default:
   1348  1.1  christos 	  assert (opnd->addr.writeback == 0);
   1349  1.1  christos 	  break;
   1350  1.1  christos 	}
   1351  1.1  christos       switch (type)
   1352  1.1  christos 	{
   1353  1.1  christos 	case AARCH64_OPND_ADDR_SIMM7:
   1354  1.1  christos 	  /* Scaled signed 7 bits immediate offset.  */
   1355  1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   1356  1.1  christos 	     different from that of the source register size,
   1357  1.1  christos 	     e.g. in strb/ldrb.  */
   1358  1.1  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   1359  1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
   1360  1.1  christos 	    {
   1361  1.1  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   1362  1.1  christos 					     -64 * size, 63 * size);
   1363  1.1  christos 	      return 0;
   1364  1.1  christos 	    }
   1365  1.1  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
   1366  1.1  christos 	    {
   1367  1.1  christos 	      set_unaligned_error (mismatch_detail, idx, size);
   1368  1.1  christos 	      return 0;
   1369  1.1  christos 	    }
   1370  1.1  christos 	  break;
   1371  1.1  christos 	case AARCH64_OPND_ADDR_SIMM9:
   1372  1.1  christos 	  /* Unscaled signed 9 bits immediate offset.  */
   1373  1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
   1374  1.1  christos 	    {
   1375  1.1  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
   1376  1.1  christos 	      return 0;
   1377  1.1  christos 	    }
   1378  1.1  christos 	  break;
   1379  1.1  christos 
   1380  1.1  christos 	case AARCH64_OPND_ADDR_SIMM9_2:
   1381  1.1  christos 	  /* Unscaled signed 9 bits immediate offset, which has to be negative
   1382  1.1  christos 	     or unaligned.  */
   1383  1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   1384  1.1  christos 	  if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
   1385  1.1  christos 	       && !value_aligned_p (opnd->addr.offset.imm, size))
   1386  1.1  christos 	      || value_in_range_p (opnd->addr.offset.imm, -256, -1))
   1387  1.1  christos 	    return 1;
   1388  1.1  christos 	  set_other_error (mismatch_detail, idx,
   1389  1.1  christos 			   _("negative or unaligned offset expected"));
   1390  1.1  christos 	  return 0;
   1391  1.1  christos 
   1392  1.1  christos 	case AARCH64_OPND_SIMD_ADDR_POST:
   1393  1.1  christos 	  /* AdvSIMD load/store multiple structures, post-index.  */
   1394  1.1  christos 	  assert (idx == 1);
   1395  1.1  christos 	  if (opnd->addr.offset.is_reg)
   1396  1.1  christos 	    {
   1397  1.1  christos 	      if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
   1398  1.1  christos 		return 1;
   1399  1.1  christos 	      else
   1400  1.1  christos 		{
   1401  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1402  1.1  christos 				   _("invalid register offset"));
   1403  1.1  christos 		  return 0;
   1404  1.1  christos 		}
   1405  1.1  christos 	    }
   1406  1.1  christos 	  else
   1407  1.1  christos 	    {
   1408  1.1  christos 	      const aarch64_opnd_info *prev = &opnds[idx-1];
   1409  1.1  christos 	      unsigned num_bytes; /* total number of bytes transferred.  */
   1410  1.1  christos 	      /* The opcode dependent area stores the number of elements in
   1411  1.1  christos 		 each structure to be loaded/stored.  */
   1412  1.1  christos 	      int is_ld1r = get_opcode_dependent_value (opcode) == 1;
   1413  1.1  christos 	      if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
   1414  1.1  christos 		/* Special handling of loading single structure to all lane.  */
   1415  1.1  christos 		num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
   1416  1.1  christos 		  * aarch64_get_qualifier_esize (prev->qualifier);
   1417  1.1  christos 	      else
   1418  1.1  christos 		num_bytes = prev->reglist.num_regs
   1419  1.1  christos 		  * aarch64_get_qualifier_esize (prev->qualifier)
   1420  1.1  christos 		  * aarch64_get_qualifier_nelem (prev->qualifier);
   1421  1.1  christos 	      if ((int) num_bytes != opnd->addr.offset.imm)
   1422  1.1  christos 		{
   1423  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1424  1.1  christos 				   _("invalid post-increment amount"));
   1425  1.1  christos 		  return 0;
   1426  1.1  christos 		}
   1427  1.1  christos 	    }
   1428  1.1  christos 	  break;
   1429  1.1  christos 
   1430  1.1  christos 	case AARCH64_OPND_ADDR_REGOFF:
   1431  1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   1432  1.1  christos 	     different from that of the source register size,
   1433  1.1  christos 	     e.g. in strb/ldrb.  */
   1434  1.1  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   1435  1.1  christos 	  /* It is either no shift or shift by the binary logarithm of SIZE.  */
   1436  1.1  christos 	  if (opnd->shifter.amount != 0
   1437  1.1  christos 	      && opnd->shifter.amount != (int)get_logsz (size))
   1438  1.1  christos 	    {
   1439  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1440  1.1  christos 			       _("invalid shift amount"));
   1441  1.1  christos 	      return 0;
   1442  1.1  christos 	    }
   1443  1.1  christos 	  /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
   1444  1.1  christos 	     operators.  */
   1445  1.1  christos 	  switch (opnd->shifter.kind)
   1446  1.1  christos 	    {
   1447  1.1  christos 	    case AARCH64_MOD_UXTW:
   1448  1.1  christos 	    case AARCH64_MOD_LSL:
   1449  1.1  christos 	    case AARCH64_MOD_SXTW:
   1450  1.1  christos 	    case AARCH64_MOD_SXTX: break;
   1451  1.1  christos 	    default:
   1452  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1453  1.1  christos 			       _("invalid extend/shift operator"));
   1454  1.1  christos 	      return 0;
   1455  1.1  christos 	    }
   1456  1.1  christos 	  break;
   1457  1.1  christos 
   1458  1.1  christos 	case AARCH64_OPND_ADDR_UIMM12:
   1459  1.1  christos 	  imm = opnd->addr.offset.imm;
   1460  1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   1461  1.1  christos 	     different from that of the source register size,
   1462  1.1  christos 	     e.g. in strb/ldrb.  */
   1463  1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   1464  1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
   1465  1.1  christos 	    {
   1466  1.1  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   1467  1.1  christos 					     0, 4095 * size);
   1468  1.1  christos 	      return 0;
   1469  1.1  christos 	    }
   1470  1.1  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
   1471  1.1  christos 	    {
   1472  1.1  christos 	      set_unaligned_error (mismatch_detail, idx, size);
   1473  1.1  christos 	      return 0;
   1474  1.1  christos 	    }
   1475  1.1  christos 	  break;
   1476  1.1  christos 
   1477  1.1  christos 	case AARCH64_OPND_ADDR_PCREL14:
   1478  1.1  christos 	case AARCH64_OPND_ADDR_PCREL19:
   1479  1.1  christos 	case AARCH64_OPND_ADDR_PCREL21:
   1480  1.1  christos 	case AARCH64_OPND_ADDR_PCREL26:
   1481  1.1  christos 	  imm = opnd->imm.value;
   1482  1.1  christos 	  if (operand_need_shift_by_two (get_operand_from_code (type)))
   1483  1.1  christos 	    {
   1484  1.1  christos 	      /* The offset value in a PC-relative branch instruction is alway
   1485  1.1  christos 		 4-byte aligned and is encoded without the lowest 2 bits.  */
   1486  1.1  christos 	      if (!value_aligned_p (imm, 4))
   1487  1.1  christos 		{
   1488  1.1  christos 		  set_unaligned_error (mismatch_detail, idx, 4);
   1489  1.1  christos 		  return 0;
   1490  1.1  christos 		}
   1491  1.1  christos 	      /* Right shift by 2 so that we can carry out the following check
   1492  1.1  christos 		 canonically.  */
   1493  1.1  christos 	      imm >>= 2;
   1494  1.1  christos 	    }
   1495  1.1  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   1496  1.1  christos 	  if (!value_fit_signed_field_p (imm, size))
   1497  1.1  christos 	    {
   1498  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1499  1.1  christos 			       _("immediate out of range"));
   1500  1.1  christos 	      return 0;
   1501  1.1  christos 	    }
   1502  1.1  christos 	  break;
   1503  1.1  christos 
   1504  1.1  christos 	default:
   1505  1.1  christos 	  break;
   1506  1.1  christos 	}
   1507  1.1  christos       break;
   1508  1.1  christos 
   1509  1.1  christos     case AARCH64_OPND_CLASS_SIMD_REGLIST:
   1510  1.1  christos       /* The opcode dependent area stores the number of elements in
   1511  1.1  christos 	 each structure to be loaded/stored.  */
   1512  1.1  christos       num = get_opcode_dependent_value (opcode);
   1513  1.1  christos       switch (type)
   1514  1.1  christos 	{
   1515  1.1  christos 	case AARCH64_OPND_LVt:
   1516  1.1  christos 	  assert (num >= 1 && num <= 4);
   1517  1.1  christos 	  /* Unless LD1/ST1, the number of registers should be equal to that
   1518  1.1  christos 	     of the structure elements.  */
   1519  1.1  christos 	  if (num != 1 && opnd->reglist.num_regs != num)
   1520  1.1  christos 	    {
   1521  1.1  christos 	      set_reg_list_error (mismatch_detail, idx, num);
   1522  1.1  christos 	      return 0;
   1523  1.1  christos 	    }
   1524  1.1  christos 	  break;
   1525  1.1  christos 	case AARCH64_OPND_LVt_AL:
   1526  1.1  christos 	case AARCH64_OPND_LEt:
   1527  1.1  christos 	  assert (num >= 1 && num <= 4);
   1528  1.1  christos 	  /* The number of registers should be equal to that of the structure
   1529  1.1  christos 	     elements.  */
   1530  1.1  christos 	  if (opnd->reglist.num_regs != num)
   1531  1.1  christos 	    {
   1532  1.1  christos 	      set_reg_list_error (mismatch_detail, idx, num);
   1533  1.1  christos 	      return 0;
   1534  1.1  christos 	    }
   1535  1.1  christos 	  break;
   1536  1.1  christos 	default:
   1537  1.1  christos 	  break;
   1538  1.1  christos 	}
   1539  1.1  christos       break;
   1540  1.1  christos 
   1541  1.1  christos     case AARCH64_OPND_CLASS_IMMEDIATE:
   1542  1.1  christos       /* Constraint check on immediate operand.  */
   1543  1.1  christos       imm = opnd->imm.value;
   1544  1.1  christos       /* E.g. imm_0_31 constrains value to be 0..31.  */
   1545  1.1  christos       if (qualifier_value_in_range_constraint_p (qualifier)
   1546  1.1  christos 	  && !value_in_range_p (imm, get_lower_bound (qualifier),
   1547  1.1  christos 				get_upper_bound (qualifier)))
   1548  1.1  christos 	{
   1549  1.1  christos 	  set_imm_out_of_range_error (mismatch_detail, idx,
   1550  1.1  christos 				      get_lower_bound (qualifier),
   1551  1.1  christos 				      get_upper_bound (qualifier));
   1552  1.1  christos 	  return 0;
   1553  1.1  christos 	}
   1554  1.1  christos 
   1555  1.1  christos       switch (type)
   1556  1.1  christos 	{
   1557  1.1  christos 	case AARCH64_OPND_AIMM:
   1558  1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_LSL)
   1559  1.1  christos 	    {
   1560  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1561  1.1  christos 			       _("invalid shift operator"));
   1562  1.1  christos 	      return 0;
   1563  1.1  christos 	    }
   1564  1.1  christos 	  if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
   1565  1.1  christos 	    {
   1566  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1567  1.1  christos 			       _("shift amount expected to be 0 or 12"));
   1568  1.1  christos 	      return 0;
   1569  1.1  christos 	    }
   1570  1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
   1571  1.1  christos 	    {
   1572  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1573  1.1  christos 			       _("immediate out of range"));
   1574  1.1  christos 	      return 0;
   1575  1.1  christos 	    }
   1576  1.1  christos 	  break;
   1577  1.1  christos 
   1578  1.1  christos 	case AARCH64_OPND_HALF:
   1579  1.1  christos 	  assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
   1580  1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_LSL)
   1581  1.1  christos 	    {
   1582  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1583  1.1  christos 			       _("invalid shift operator"));
   1584  1.1  christos 	      return 0;
   1585  1.1  christos 	    }
   1586  1.1  christos 	  size = aarch64_get_qualifier_esize (opnds[0].qualifier);
   1587  1.1  christos 	  if (!value_aligned_p (opnd->shifter.amount, 16))
   1588  1.1  christos 	    {
   1589  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1590  1.1  christos 			       _("shift amount should be a multiple of 16"));
   1591  1.1  christos 	      return 0;
   1592  1.1  christos 	    }
   1593  1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
   1594  1.1  christos 	    {
   1595  1.1  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx,
   1596  1.1  christos 						 0, size * 8 - 16);
   1597  1.1  christos 	      return 0;
   1598  1.1  christos 	    }
   1599  1.1  christos 	  if (opnd->imm.value < 0)
   1600  1.1  christos 	    {
   1601  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1602  1.1  christos 			       _("negative immediate value not allowed"));
   1603  1.1  christos 	      return 0;
   1604  1.1  christos 	    }
   1605  1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
   1606  1.1  christos 	    {
   1607  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1608  1.1  christos 			       _("immediate out of range"));
   1609  1.1  christos 	      return 0;
   1610  1.1  christos 	    }
   1611  1.1  christos 	  break;
   1612  1.1  christos 
   1613  1.1  christos 	case AARCH64_OPND_IMM_MOV:
   1614  1.1  christos 	    {
   1615  1.1  christos 	      int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
   1616  1.1  christos 	      imm = opnd->imm.value;
   1617  1.1  christos 	      assert (idx == 1);
   1618  1.1  christos 	      switch (opcode->op)
   1619  1.1  christos 		{
   1620  1.1  christos 		case OP_MOV_IMM_WIDEN:
   1621  1.1  christos 		  imm = ~imm;
   1622  1.1  christos 		  /* Fall through...  */
   1623  1.1  christos 		case OP_MOV_IMM_WIDE:
   1624  1.1  christos 		  if (!aarch64_wide_constant_p (imm, is32, NULL))
   1625  1.1  christos 		    {
   1626  1.1  christos 		      set_other_error (mismatch_detail, idx,
   1627  1.1  christos 				       _("immediate out of range"));
   1628  1.1  christos 		      return 0;
   1629  1.1  christos 		    }
   1630  1.1  christos 		  break;
   1631  1.1  christos 		case OP_MOV_IMM_LOG:
   1632  1.1  christos 		  if (!aarch64_logical_immediate_p (imm, is32, NULL))
   1633  1.1  christos 		    {
   1634  1.1  christos 		      set_other_error (mismatch_detail, idx,
   1635  1.1  christos 				       _("immediate out of range"));
   1636  1.1  christos 		      return 0;
   1637  1.1  christos 		    }
   1638  1.1  christos 		  break;
   1639  1.1  christos 		default:
   1640  1.1  christos 		  assert (0);
   1641  1.1  christos 		  return 0;
   1642  1.1  christos 		}
   1643  1.1  christos 	    }
   1644  1.1  christos 	  break;
   1645  1.1  christos 
   1646  1.1  christos 	case AARCH64_OPND_NZCV:
   1647  1.1  christos 	case AARCH64_OPND_CCMP_IMM:
   1648  1.1  christos 	case AARCH64_OPND_EXCEPTION:
   1649  1.1  christos 	case AARCH64_OPND_UIMM4:
   1650  1.1  christos 	case AARCH64_OPND_UIMM7:
   1651  1.1  christos 	case AARCH64_OPND_UIMM3_OP1:
   1652  1.1  christos 	case AARCH64_OPND_UIMM3_OP2:
   1653  1.1  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   1654  1.1  christos 	  assert (size < 32);
   1655  1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, size))
   1656  1.1  christos 	    {
   1657  1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
   1658  1.1  christos 					  (1 << size) - 1);
   1659  1.1  christos 	      return 0;
   1660  1.1  christos 	    }
   1661  1.1  christos 	  break;
   1662  1.1  christos 
   1663  1.1  christos 	case AARCH64_OPND_WIDTH:
   1664  1.1  christos 	  assert (idx == 3 && opnds[idx-1].type == AARCH64_OPND_IMM
   1665  1.1  christos 		  && opnds[0].type == AARCH64_OPND_Rd);
   1666  1.1  christos 	  size = get_upper_bound (qualifier);
   1667  1.1  christos 	  if (opnd->imm.value + opnds[idx-1].imm.value > size)
   1668  1.1  christos 	    /* lsb+width <= reg.size  */
   1669  1.1  christos 	    {
   1670  1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1,
   1671  1.1  christos 					  size - opnds[idx-1].imm.value);
   1672  1.1  christos 	      return 0;
   1673  1.1  christos 	    }
   1674  1.1  christos 	  break;
   1675  1.1  christos 
   1676  1.1  christos 	case AARCH64_OPND_LIMM:
   1677  1.1  christos 	    {
   1678  1.1  christos 	      int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
   1679  1.1  christos 	      uint64_t uimm = opnd->imm.value;
   1680  1.1  christos 	      if (opcode->op == OP_BIC)
   1681  1.1  christos 		uimm = ~uimm;
   1682  1.1  christos 	      if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
   1683  1.1  christos 		{
   1684  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1685  1.1  christos 				   _("immediate out of range"));
   1686  1.1  christos 		  return 0;
   1687  1.1  christos 		}
   1688  1.1  christos 	    }
   1689  1.1  christos 	  break;
   1690  1.1  christos 
   1691  1.1  christos 	case AARCH64_OPND_IMM0:
   1692  1.1  christos 	case AARCH64_OPND_FPIMM0:
   1693  1.1  christos 	  if (opnd->imm.value != 0)
   1694  1.1  christos 	    {
   1695  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1696  1.1  christos 			       _("immediate zero expected"));
   1697  1.1  christos 	      return 0;
   1698  1.1  christos 	    }
   1699  1.1  christos 	  break;
   1700  1.1  christos 
   1701  1.1  christos 	case AARCH64_OPND_SHLL_IMM:
   1702  1.1  christos 	  assert (idx == 2);
   1703  1.1  christos 	  size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
   1704  1.1  christos 	  if (opnd->imm.value != size)
   1705  1.1  christos 	    {
   1706  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1707  1.1  christos 			       _("invalid shift amount"));
   1708  1.1  christos 	      return 0;
   1709  1.1  christos 	    }
   1710  1.1  christos 	  break;
   1711  1.1  christos 
   1712  1.1  christos 	case AARCH64_OPND_IMM_VLSL:
   1713  1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   1714  1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
   1715  1.1  christos 	    {
   1716  1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
   1717  1.1  christos 					  size * 8 - 1);
   1718  1.1  christos 	      return 0;
   1719  1.1  christos 	    }
   1720  1.1  christos 	  break;
   1721  1.1  christos 
   1722  1.1  christos 	case AARCH64_OPND_IMM_VLSR:
   1723  1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   1724  1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 1, size * 8))
   1725  1.1  christos 	    {
   1726  1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
   1727  1.1  christos 	      return 0;
   1728  1.1  christos 	    }
   1729  1.1  christos 	  break;
   1730  1.1  christos 
   1731  1.1  christos 	case AARCH64_OPND_SIMD_IMM:
   1732  1.1  christos 	case AARCH64_OPND_SIMD_IMM_SFT:
   1733  1.1  christos 	  /* Qualifier check.  */
   1734  1.1  christos 	  switch (qualifier)
   1735  1.1  christos 	    {
   1736  1.1  christos 	    case AARCH64_OPND_QLF_LSL:
   1737  1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_LSL)
   1738  1.1  christos 		{
   1739  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1740  1.1  christos 				   _("invalid shift operator"));
   1741  1.1  christos 		  return 0;
   1742  1.1  christos 		}
   1743  1.1  christos 	      break;
   1744  1.1  christos 	    case AARCH64_OPND_QLF_MSL:
   1745  1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_MSL)
   1746  1.1  christos 		{
   1747  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1748  1.1  christos 				   _("invalid shift operator"));
   1749  1.1  christos 		  return 0;
   1750  1.1  christos 		}
   1751  1.1  christos 	      break;
   1752  1.1  christos 	    case AARCH64_OPND_QLF_NIL:
   1753  1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_NONE)
   1754  1.1  christos 		{
   1755  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1756  1.1  christos 				   _("shift is not permitted"));
   1757  1.1  christos 		  return 0;
   1758  1.1  christos 		}
   1759  1.1  christos 	      break;
   1760  1.1  christos 	    default:
   1761  1.1  christos 	      assert (0);
   1762  1.1  christos 	      return 0;
   1763  1.1  christos 	    }
   1764  1.1  christos 	  /* Is the immediate valid?  */
   1765  1.1  christos 	  assert (idx == 1);
   1766  1.1  christos 	  if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
   1767  1.1  christos 	    {
   1768  1.1  christos 	      /* uimm8 or simm8 */
   1769  1.1  christos 	      if (!value_in_range_p (opnd->imm.value, -128, 255))
   1770  1.1  christos 		{
   1771  1.1  christos 		  set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
   1772  1.1  christos 		  return 0;
   1773  1.1  christos 		}
   1774  1.1  christos 	    }
   1775  1.1  christos 	  else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
   1776  1.1  christos 	    {
   1777  1.1  christos 	      /* uimm64 is not
   1778  1.1  christos 		 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
   1779  1.1  christos 		 ffffffffgggggggghhhhhhhh'.  */
   1780  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1781  1.1  christos 			       _("invalid value for immediate"));
   1782  1.1  christos 	      return 0;
   1783  1.1  christos 	    }
   1784  1.1  christos 	  /* Is the shift amount valid?  */
   1785  1.1  christos 	  switch (opnd->shifter.kind)
   1786  1.1  christos 	    {
   1787  1.1  christos 	    case AARCH64_MOD_LSL:
   1788  1.1  christos 	      size = aarch64_get_qualifier_esize (opnds[0].qualifier);
   1789  1.1  christos 	      if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
   1790  1.1  christos 		{
   1791  1.1  christos 		  set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
   1792  1.1  christos 						     (size - 1) * 8);
   1793  1.1  christos 		  return 0;
   1794  1.1  christos 		}
   1795  1.1  christos 	      if (!value_aligned_p (opnd->shifter.amount, 8))
   1796  1.1  christos 		{
   1797  1.1  christos 		  set_unaligned_error (mismatch_detail, idx, 8);
   1798  1.1  christos 		  return 0;
   1799  1.1  christos 		}
   1800  1.1  christos 	      break;
   1801  1.1  christos 	    case AARCH64_MOD_MSL:
   1802  1.1  christos 	      /* Only 8 and 16 are valid shift amount.  */
   1803  1.1  christos 	      if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
   1804  1.1  christos 		{
   1805  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1806  1.1  christos 				   _("shift amount expected to be 0 or 16"));
   1807  1.1  christos 		  return 0;
   1808  1.1  christos 		}
   1809  1.1  christos 	      break;
   1810  1.1  christos 	    default:
   1811  1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_NONE)
   1812  1.1  christos 		{
   1813  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1814  1.1  christos 				   _("invalid shift operator"));
   1815  1.1  christos 		  return 0;
   1816  1.1  christos 		}
   1817  1.1  christos 	      break;
   1818  1.1  christos 	    }
   1819  1.1  christos 	  break;
   1820  1.1  christos 
   1821  1.1  christos 	case AARCH64_OPND_FPIMM:
   1822  1.1  christos 	case AARCH64_OPND_SIMD_FPIMM:
   1823  1.1  christos 	  if (opnd->imm.is_fp == 0)
   1824  1.1  christos 	    {
   1825  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1826  1.1  christos 			       _("floating-point immediate expected"));
   1827  1.1  christos 	      return 0;
   1828  1.1  christos 	    }
   1829  1.1  christos 	  /* The value is expected to be an 8-bit floating-point constant with
   1830  1.1  christos 	     sign, 3-bit exponent and normalized 4 bits of precision, encoded
   1831  1.1  christos 	     in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
   1832  1.1  christos 	     instruction).  */
   1833  1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 255))
   1834  1.1  christos 	    {
   1835  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1836  1.1  christos 			       _("immediate out of range"));
   1837  1.1  christos 	      return 0;
   1838  1.1  christos 	    }
   1839  1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_NONE)
   1840  1.1  christos 	    {
   1841  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1842  1.1  christos 			       _("invalid shift operator"));
   1843  1.1  christos 	      return 0;
   1844  1.1  christos 	    }
   1845  1.1  christos 	  break;
   1846  1.1  christos 
   1847  1.1  christos 	default:
   1848  1.1  christos 	  break;
   1849  1.1  christos 	}
   1850  1.1  christos       break;
   1851  1.1  christos 
   1852  1.1  christos     case AARCH64_OPND_CLASS_CP_REG:
   1853  1.1  christos       /* Cn or Cm: 4-bit opcode field named for historical reasons.
   1854  1.1  christos 	 valid range: C0 - C15.  */
   1855  1.1  christos       if (opnd->reg.regno > 15)
   1856  1.1  christos 	{
   1857  1.1  christos 	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
   1858  1.1  christos 	  return 0;
   1859  1.1  christos 	}
   1860  1.1  christos       break;
   1861  1.1  christos 
   1862  1.1  christos     case AARCH64_OPND_CLASS_SYSTEM:
   1863  1.1  christos       switch (type)
   1864  1.1  christos 	{
   1865  1.1  christos 	case AARCH64_OPND_PSTATEFIELD:
   1866  1.1  christos 	  assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
   1867  1.1  christos 	  /* MSR SPSel, #uimm4
   1868  1.1  christos 	     Uses uimm4 as a control value to select the stack pointer: if
   1869  1.1  christos 	     bit 0 is set it selects the current exception level's stack
   1870  1.1  christos 	     pointer, if bit 0 is clear it selects shared EL0 stack pointer.
   1871  1.1  christos 	     Bits 1 to 3 of uimm4 are reserved and should be zero.  */
   1872  1.1  christos 	  if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
   1873  1.1  christos 	    {
   1874  1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
   1875  1.1  christos 	      return 0;
   1876  1.1  christos 	    }
   1877  1.1  christos 	  break;
   1878  1.1  christos 	default:
   1879  1.1  christos 	  break;
   1880  1.1  christos 	}
   1881  1.1  christos       break;
   1882  1.1  christos 
   1883  1.1  christos     case AARCH64_OPND_CLASS_SIMD_ELEMENT:
   1884  1.1  christos       /* Get the upper bound for the element index.  */
   1885  1.1  christos       num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
   1886  1.1  christos       /* Index out-of-range.  */
   1887  1.1  christos       if (!value_in_range_p (opnd->reglane.index, 0, num))
   1888  1.1  christos 	{
   1889  1.1  christos 	  set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
   1890  1.1  christos 	  return 0;
   1891  1.1  christos 	}
   1892  1.1  christos       /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
   1893  1.1  christos 	 <Vm>	Is the vector register (V0-V31) or (V0-V15), whose
   1894  1.1  christos 	 number is encoded in "size:M:Rm":
   1895  1.1  christos 	 size	<Vm>
   1896  1.1  christos 	 00		RESERVED
   1897  1.1  christos 	 01		0:Rm
   1898  1.1  christos 	 10		M:Rm
   1899  1.1  christos 	 11		RESERVED  */
   1900  1.1  christos       if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
   1901  1.1  christos 	  && !value_in_range_p (opnd->reglane.regno, 0, 15))
   1902  1.1  christos 	{
   1903  1.1  christos 	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
   1904  1.1  christos 	  return 0;
   1905  1.1  christos 	}
   1906  1.1  christos       break;
   1907  1.1  christos 
   1908  1.1  christos     case AARCH64_OPND_CLASS_MODIFIED_REG:
   1909  1.1  christos       assert (idx == 1 || idx == 2);
   1910  1.1  christos       switch (type)
   1911  1.1  christos 	{
   1912  1.1  christos 	case AARCH64_OPND_Rm_EXT:
   1913  1.1  christos 	  if (aarch64_extend_operator_p (opnd->shifter.kind) == FALSE
   1914  1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_LSL)
   1915  1.1  christos 	    {
   1916  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1917  1.1  christos 			       _("extend operator expected"));
   1918  1.1  christos 	      return 0;
   1919  1.1  christos 	    }
   1920  1.1  christos 	  /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
   1921  1.1  christos 	     (i.e. SP), in which case it defaults to LSL. The LSL alias is
   1922  1.1  christos 	     only valid when "Rd" or "Rn" is '11111', and is preferred in that
   1923  1.1  christos 	     case.  */
   1924  1.1  christos 	  if (!aarch64_stack_pointer_p (opnds + 0)
   1925  1.1  christos 	      && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
   1926  1.1  christos 	    {
   1927  1.1  christos 	      if (!opnd->shifter.operator_present)
   1928  1.1  christos 		{
   1929  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1930  1.1  christos 				   _("missing extend operator"));
   1931  1.1  christos 		  return 0;
   1932  1.1  christos 		}
   1933  1.1  christos 	      else if (opnd->shifter.kind == AARCH64_MOD_LSL)
   1934  1.1  christos 		{
   1935  1.1  christos 		  set_other_error (mismatch_detail, idx,
   1936  1.1  christos 				   _("'LSL' operator not allowed"));
   1937  1.1  christos 		  return 0;
   1938  1.1  christos 		}
   1939  1.1  christos 	    }
   1940  1.1  christos 	  assert (opnd->shifter.operator_present	/* Default to LSL.  */
   1941  1.1  christos 		  || opnd->shifter.kind == AARCH64_MOD_LSL);
   1942  1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, 4))
   1943  1.1  christos 	    {
   1944  1.1  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
   1945  1.1  christos 	      return 0;
   1946  1.1  christos 	    }
   1947  1.1  christos 	  /* In the 64-bit form, the final register operand is written as Wm
   1948  1.1  christos 	     for all but the (possibly omitted) UXTX/LSL and SXTX
   1949  1.1  christos 	     operators.
   1950  1.1  christos 	     N.B. GAS allows X register to be used with any operator as a
   1951  1.1  christos 	     programming convenience.  */
   1952  1.1  christos 	  if (qualifier == AARCH64_OPND_QLF_X
   1953  1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_LSL
   1954  1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_UXTX
   1955  1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_SXTX)
   1956  1.1  christos 	    {
   1957  1.1  christos 	      set_other_error (mismatch_detail, idx, _("W register expected"));
   1958  1.1  christos 	      return 0;
   1959  1.1  christos 	    }
   1960  1.1  christos 	  break;
   1961  1.1  christos 
   1962  1.1  christos 	case AARCH64_OPND_Rm_SFT:
   1963  1.1  christos 	  /* ROR is not available to the shifted register operand in
   1964  1.1  christos 	     arithmetic instructions.  */
   1965  1.1  christos 	  if (aarch64_shift_operator_p (opnd->shifter.kind) == FALSE)
   1966  1.1  christos 	    {
   1967  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1968  1.1  christos 			       _("shift operator expected"));
   1969  1.1  christos 	      return 0;
   1970  1.1  christos 	    }
   1971  1.1  christos 	  if (opnd->shifter.kind == AARCH64_MOD_ROR
   1972  1.1  christos 	      && opcode->iclass != log_shift)
   1973  1.1  christos 	    {
   1974  1.1  christos 	      set_other_error (mismatch_detail, idx,
   1975  1.1  christos 			       _("'ROR' operator not allowed"));
   1976  1.1  christos 	      return 0;
   1977  1.1  christos 	    }
   1978  1.1  christos 	  num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
   1979  1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, num))
   1980  1.1  christos 	    {
   1981  1.1  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
   1982  1.1  christos 	      return 0;
   1983  1.1  christos 	    }
   1984  1.1  christos 	  break;
   1985  1.1  christos 
   1986  1.1  christos 	default:
   1987  1.1  christos 	  break;
   1988  1.1  christos 	}
   1989  1.1  christos       break;
   1990  1.1  christos 
   1991  1.1  christos     default:
   1992  1.1  christos       break;
   1993  1.1  christos     }
   1994  1.1  christos 
   1995  1.1  christos   return 1;
   1996  1.1  christos }
   1997  1.1  christos 
   1998  1.1  christos /* Main entrypoint for the operand constraint checking.
   1999  1.1  christos 
   2000  1.1  christos    Return 1 if operands of *INST meet the constraint applied by the operand
   2001  1.1  christos    codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
   2002  1.1  christos    not NULL, return the detail of the error in *MISMATCH_DETAIL.  N.B. when
   2003  1.1  christos    adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
   2004  1.1  christos    with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
   2005  1.1  christos    error kind when it is notified that an instruction does not pass the check).
   2006  1.1  christos 
   2007  1.1  christos    Un-determined operand qualifiers may get established during the process.  */
   2008  1.1  christos 
   2009  1.1  christos int
   2010  1.1  christos aarch64_match_operands_constraint (aarch64_inst *inst,
   2011  1.1  christos 				   aarch64_operand_error *mismatch_detail)
   2012  1.1  christos {
   2013  1.1  christos   int i;
   2014  1.1  christos 
   2015  1.1  christos   DEBUG_TRACE ("enter");
   2016  1.1  christos 
   2017  1.1  christos   /* Match operands' qualifier.
   2018  1.1  christos      *INST has already had qualifier establish for some, if not all, of
   2019  1.1  christos      its operands; we need to find out whether these established
   2020  1.1  christos      qualifiers match one of the qualifier sequence in
   2021  1.1  christos      INST->OPCODE->QUALIFIERS_LIST.  If yes, we will assign each operand
   2022  1.1  christos      with the corresponding qualifier in such a sequence.
   2023  1.1  christos      Only basic operand constraint checking is done here; the more thorough
   2024  1.1  christos      constraint checking will carried out by operand_general_constraint_met_p,
   2025  1.1  christos      which has be to called after this in order to get all of the operands'
   2026  1.1  christos      qualifiers established.  */
   2027  1.1  christos   if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
   2028  1.1  christos     {
   2029  1.1  christos       DEBUG_TRACE ("FAIL on operand qualifier matching");
   2030  1.1  christos       if (mismatch_detail)
   2031  1.1  christos 	{
   2032  1.1  christos 	  /* Return an error type to indicate that it is the qualifier
   2033  1.1  christos 	     matching failure; we don't care about which operand as there
   2034  1.1  christos 	     are enough information in the opcode table to reproduce it.  */
   2035  1.1  christos 	  mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
   2036  1.1  christos 	  mismatch_detail->index = -1;
   2037  1.1  christos 	  mismatch_detail->error = NULL;
   2038  1.1  christos 	}
   2039  1.1  christos       return 0;
   2040  1.1  christos     }
   2041  1.1  christos 
   2042  1.1  christos   /* Match operands' constraint.  */
   2043  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2044  1.1  christos     {
   2045  1.1  christos       enum aarch64_opnd type = inst->opcode->operands[i];
   2046  1.1  christos       if (type == AARCH64_OPND_NIL)
   2047  1.1  christos 	break;
   2048  1.1  christos       if (inst->operands[i].skip)
   2049  1.1  christos 	{
   2050  1.1  christos 	  DEBUG_TRACE ("skip the incomplete operand %d", i);
   2051  1.1  christos 	  continue;
   2052  1.1  christos 	}
   2053  1.1  christos       if (operand_general_constraint_met_p (inst->operands, i, type,
   2054  1.1  christos 					    inst->opcode, mismatch_detail) == 0)
   2055  1.1  christos 	{
   2056  1.1  christos 	  DEBUG_TRACE ("FAIL on operand %d", i);
   2057  1.1  christos 	  return 0;
   2058  1.1  christos 	}
   2059  1.1  christos     }
   2060  1.1  christos 
   2061  1.1  christos   DEBUG_TRACE ("PASS");
   2062  1.1  christos 
   2063  1.1  christos   return 1;
   2064  1.1  christos }
   2065  1.1  christos 
   2066  1.1  christos /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
   2067  1.1  christos    Also updates the TYPE of each INST->OPERANDS with the corresponding
   2068  1.1  christos    value of OPCODE->OPERANDS.
   2069  1.1  christos 
   2070  1.1  christos    Note that some operand qualifiers may need to be manually cleared by
   2071  1.1  christos    the caller before it further calls the aarch64_opcode_encode; by
   2072  1.1  christos    doing this, it helps the qualifier matching facilities work
   2073  1.1  christos    properly.  */
   2074  1.1  christos 
   2075  1.1  christos const aarch64_opcode*
   2076  1.1  christos aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
   2077  1.1  christos {
   2078  1.1  christos   int i;
   2079  1.1  christos   const aarch64_opcode *old = inst->opcode;
   2080  1.1  christos 
   2081  1.1  christos   inst->opcode = opcode;
   2082  1.1  christos 
   2083  1.1  christos   /* Update the operand types.  */
   2084  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2085  1.1  christos     {
   2086  1.1  christos       inst->operands[i].type = opcode->operands[i];
   2087  1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL)
   2088  1.1  christos 	break;
   2089  1.1  christos     }
   2090  1.1  christos 
   2091  1.1  christos   DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
   2092  1.1  christos 
   2093  1.1  christos   return old;
   2094  1.1  christos }
   2095  1.1  christos 
   2096  1.1  christos int
   2097  1.1  christos aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
   2098  1.1  christos {
   2099  1.1  christos   int i;
   2100  1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   2101  1.1  christos     if (operands[i] == operand)
   2102  1.1  christos       return i;
   2103  1.1  christos     else if (operands[i] == AARCH64_OPND_NIL)
   2104  1.1  christos       break;
   2105  1.1  christos   return -1;
   2106  1.1  christos }
   2107  1.1  christos 
   2108  1.1  christos /* [0][0]  32-bit integer regs with sp   Wn
   2110  1.1  christos    [0][1]  64-bit integer regs with sp   Xn  sf=1
   2111  1.1  christos    [1][0]  32-bit integer regs with #0   Wn
   2112  1.1  christos    [1][1]  64-bit integer regs with #0   Xn  sf=1 */
   2113  1.1  christos static const char *int_reg[2][2][32] = {
   2114  1.1  christos #define R32 "w"
   2115  1.1  christos #define R64 "x"
   2116  1.1  christos   { { R32  "0", R32  "1", R32  "2", R32  "3", R32  "4", R32  "5", R32  "6", R32  "7",
   2117  1.1  christos       R32  "8", R32  "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
   2118  1.1  christos       R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
   2119  1.1  christos       R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30",    "wsp" },
   2120  1.1  christos     { R64  "0", R64  "1", R64  "2", R64  "3", R64  "4", R64  "5", R64  "6", R64  "7",
   2121  1.1  christos       R64  "8", R64  "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
   2122  1.1  christos       R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
   2123  1.1  christos       R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30",     "sp" } },
   2124  1.1  christos   { { R32  "0", R32  "1", R32  "2", R32  "3", R32  "4", R32  "5", R32  "6", R32  "7",
   2125  1.1  christos       R32  "8", R32  "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
   2126  1.1  christos       R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
   2127  1.1  christos       R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", R32 "zr" },
   2128  1.1  christos     { R64  "0", R64  "1", R64  "2", R64  "3", R64  "4", R64  "5", R64  "6", R64  "7",
   2129  1.1  christos       R64  "8", R64  "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
   2130  1.1  christos       R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
   2131  1.1  christos       R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", R64 "zr" } }
   2132  1.1  christos #undef R64
   2133  1.1  christos #undef R32
   2134  1.1  christos };
   2135  1.1  christos 
   2136  1.1  christos /* Return the integer register name.
   2137  1.1  christos    if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg.  */
   2138  1.1  christos 
   2139  1.1  christos static inline const char *
   2140  1.1  christos get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
   2141  1.1  christos {
   2142  1.1  christos   const int has_zr = sp_reg_p ? 0 : 1;
   2143  1.1  christos   const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
   2144  1.1  christos   return int_reg[has_zr][is_64][regno];
   2145  1.1  christos }
   2146  1.1  christos 
   2147  1.1  christos /* Like get_int_reg_name, but IS_64 is always 1.  */
   2148  1.1  christos 
   2149  1.1  christos static inline const char *
   2150  1.1  christos get_64bit_int_reg_name (int regno, int sp_reg_p)
   2151  1.1  christos {
   2152  1.1  christos   const int has_zr = sp_reg_p ? 0 : 1;
   2153  1.1  christos   return int_reg[has_zr][1][regno];
   2154  1.1  christos }
   2155  1.1  christos 
   2156  1.1  christos /* Types for expanding an encoded 8-bit value to a floating-point value.  */
   2157  1.1  christos 
   2158  1.1  christos typedef union
   2159  1.1  christos {
   2160  1.1  christos   uint64_t i;
   2161  1.1  christos   double   d;
   2162  1.1  christos } double_conv_t;
   2163  1.1  christos 
   2164  1.1  christos typedef union
   2165  1.1  christos {
   2166  1.1  christos   uint32_t i;
   2167  1.1  christos   float    f;
   2168  1.1  christos } single_conv_t;
   2169  1.1  christos 
   2170  1.1  christos /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
   2171  1.1  christos    normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
   2172  1.1  christos    (depending on the type of the instruction).  IMM8 will be expanded to a
   2173  1.1  christos    single-precision floating-point value (IS_DP == 0) or a double-precision
   2174  1.1  christos    floating-point value (IS_DP == 1).  The expanded value is returned.  */
   2175  1.1  christos 
   2176  1.1  christos static uint64_t
   2177  1.1  christos expand_fp_imm (int is_dp, uint32_t imm8)
   2178  1.1  christos {
   2179  1.1  christos   uint64_t imm;
   2180  1.1  christos   uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
   2181  1.1  christos 
   2182  1.1  christos   imm8_7 = (imm8 >> 7) & 0x01;	/* imm8<7>   */
   2183  1.1  christos   imm8_6_0 = imm8 & 0x7f;	/* imm8<6:0> */
   2184  1.1  christos   imm8_6 = imm8_6_0 >> 6;	/* imm8<6>   */
   2185  1.1  christos   imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
   2186  1.1  christos     | (imm8_6 << 1) | imm8_6;	/* Replicate(imm8<6>,4) */
   2187  1.1  christos   if (is_dp)
   2188  1.1  christos     {
   2189  1.1  christos       imm = (imm8_7 << (63-32))		/* imm8<7>  */
   2190  1.1  christos 	| ((imm8_6 ^ 1) << (62-32))	/* NOT(imm8<6)	*/
   2191  1.1  christos 	| (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
   2192  1.1  christos 	| (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
   2193  1.1  christos 	| (imm8_6_0 << (48-32));	/* imm8<6>:imm8<5:0>    */
   2194  1.1  christos       imm <<= 32;
   2195  1.1  christos     }
   2196  1.1  christos   else
   2197  1.1  christos     {
   2198  1.1  christos       imm = (imm8_7 << 31)	/* imm8<7>              */
   2199  1.1  christos 	| ((imm8_6 ^ 1) << 30)	/* NOT(imm8<6>)         */
   2200  1.1  christos 	| (imm8_6_repl4 << 26)	/* Replicate(imm8<6>,4) */
   2201  1.1  christos 	| (imm8_6_0 << 19);	/* imm8<6>:imm8<5:0>    */
   2202  1.1  christos     }
   2203  1.1  christos 
   2204  1.1  christos   return imm;
   2205  1.1  christos }
   2206  1.1  christos 
   2207  1.1  christos /* Produce the string representation of the register list operand *OPND
   2208  1.1  christos    in the buffer pointed by BUF of size SIZE.  */
   2209  1.1  christos static void
   2210  1.1  christos print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
   2211  1.1  christos {
   2212  1.1  christos   const int num_regs = opnd->reglist.num_regs;
   2213  1.1  christos   const int first_reg = opnd->reglist.first_regno;
   2214  1.1  christos   const int last_reg = (first_reg + num_regs - 1) & 0x1f;
   2215  1.1  christos   const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
   2216  1.1  christos   char tb[8];	/* Temporary buffer.  */
   2217  1.1  christos 
   2218  1.1  christos   assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
   2219  1.1  christos   assert (num_regs >= 1 && num_regs <= 4);
   2220  1.1  christos 
   2221  1.1  christos   /* Prepare the index if any.  */
   2222  1.1  christos   if (opnd->reglist.has_index)
   2223  1.1  christos     snprintf (tb, 8, "[%d]", opnd->reglist.index);
   2224  1.1  christos   else
   2225  1.1  christos     tb[0] = '\0';
   2226  1.1  christos 
   2227  1.1  christos   /* The hyphenated form is preferred for disassembly if there are
   2228  1.1  christos      more than two registers in the list, and the register numbers
   2229  1.1  christos      are monotonically increasing in increments of one.  */
   2230  1.1  christos   if (num_regs > 2 && last_reg > first_reg)
   2231  1.1  christos     snprintf (buf, size, "{v%d.%s-v%d.%s}%s", first_reg, qlf_name,
   2232  1.1  christos 	      last_reg, qlf_name, tb);
   2233  1.1  christos   else
   2234  1.1  christos     {
   2235  1.1  christos       const int reg0 = first_reg;
   2236  1.1  christos       const int reg1 = (first_reg + 1) & 0x1f;
   2237  1.1  christos       const int reg2 = (first_reg + 2) & 0x1f;
   2238  1.1  christos       const int reg3 = (first_reg + 3) & 0x1f;
   2239  1.1  christos 
   2240  1.1  christos       switch (num_regs)
   2241  1.1  christos 	{
   2242  1.1  christos 	case 1:
   2243  1.1  christos 	  snprintf (buf, size, "{v%d.%s}%s", reg0, qlf_name, tb);
   2244  1.1  christos 	  break;
   2245  1.1  christos 	case 2:
   2246  1.1  christos 	  snprintf (buf, size, "{v%d.%s, v%d.%s}%s", reg0, qlf_name,
   2247  1.1  christos 		    reg1, qlf_name, tb);
   2248  1.1  christos 	  break;
   2249  1.1  christos 	case 3:
   2250  1.1  christos 	  snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s}%s", reg0, qlf_name,
   2251  1.1  christos 		    reg1, qlf_name, reg2, qlf_name, tb);
   2252  1.1  christos 	  break;
   2253  1.1  christos 	case 4:
   2254  1.1  christos 	  snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s, v%d.%s}%s",
   2255  1.1  christos 		    reg0, qlf_name, reg1, qlf_name, reg2, qlf_name,
   2256  1.1  christos 		    reg3, qlf_name, tb);
   2257  1.1  christos 	  break;
   2258  1.1  christos 	}
   2259  1.1  christos     }
   2260  1.1  christos }
   2261  1.1  christos 
   2262  1.1  christos /* Produce the string representation of the register offset address operand
   2263  1.1  christos    *OPND in the buffer pointed by BUF of size SIZE.  */
   2264  1.1  christos static void
   2265  1.1  christos print_register_offset_address (char *buf, size_t size,
   2266  1.1  christos 			       const aarch64_opnd_info *opnd)
   2267  1.1  christos {
   2268  1.1  christos   const size_t tblen = 16;
   2269  1.1  christos   char tb[tblen];		/* Temporary buffer.  */
   2270  1.1  christos   bfd_boolean lsl_p = FALSE;	/* Is LSL shift operator?  */
   2271  1.1  christos   bfd_boolean wm_p = FALSE;	/* Should Rm be Wm?  */
   2272  1.1  christos   bfd_boolean print_extend_p = TRUE;
   2273  1.1  christos   bfd_boolean print_amount_p = TRUE;
   2274  1.1  christos   const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
   2275  1.1  christos 
   2276  1.1  christos   switch (opnd->shifter.kind)
   2277  1.1  christos     {
   2278  1.1  christos     case AARCH64_MOD_UXTW: wm_p = TRUE; break;
   2279  1.1  christos     case AARCH64_MOD_LSL : lsl_p = TRUE; break;
   2280  1.1  christos     case AARCH64_MOD_SXTW: wm_p = TRUE; break;
   2281  1.1  christos     case AARCH64_MOD_SXTX: break;
   2282  1.1  christos     default: assert (0);
   2283  1.1  christos     }
   2284  1.1  christos 
   2285  1.1  christos   if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
   2286  1.1  christos 				|| !opnd->shifter.amount_present))
   2287  1.1  christos     {
   2288  1.1  christos       /* Not print the shift/extend amount when the amount is zero and
   2289  1.1  christos          when it is not the special case of 8-bit load/store instruction.  */
   2290  1.1  christos       print_amount_p = FALSE;
   2291  1.1  christos       /* Likewise, no need to print the shift operator LSL in such a
   2292  1.1  christos 	 situation.  */
   2293  1.1  christos       if (lsl_p)
   2294  1.1  christos 	print_extend_p = FALSE;
   2295  1.1  christos     }
   2296  1.1  christos 
   2297  1.1  christos   /* Prepare for the extend/shift.  */
   2298  1.1  christos   if (print_extend_p)
   2299  1.1  christos     {
   2300  1.1  christos       if (print_amount_p)
   2301  1.1  christos 	snprintf (tb, tblen, ",%s #%d", shift_name, opnd->shifter.amount);
   2302  1.1  christos       else
   2303  1.1  christos 	snprintf (tb, tblen, ",%s", shift_name);
   2304  1.1  christos     }
   2305  1.3  christos   else
   2306  1.1  christos     tb[0] = '\0';
   2307  1.3  christos 
   2308  1.3  christos   snprintf (buf, size, "[%s,%s%s]",
   2309  1.3  christos 	    get_64bit_int_reg_name (opnd->addr.base_regno, 1),
   2310  1.3  christos 	    get_int_reg_name (opnd->addr.offset.regno,
   2311  1.1  christos 			      wm_p ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X,
   2312  1.1  christos 			      0 /* sp_reg_p */),
   2313  1.1  christos 	    tb);
   2314  1.1  christos }
   2315  1.1  christos 
   2316  1.1  christos /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
   2317  1.1  christos    in *BUF.  The caller should pass in the maximum size of *BUF in SIZE.
   2318  1.1  christos    PC, PCREL_P and ADDRESS are used to pass in and return information about
   2319  1.1  christos    the PC-relative address calculation, where the PC value is passed in
   2320  1.1  christos    PC.  If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
   2321  1.1  christos    will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
   2322  1.1  christos    calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
   2323  1.1  christos 
   2324  1.1  christos    The function serves both the disassembler and the assembler diagnostics
   2325  1.1  christos    issuer, which is the reason why it lives in this file.  */
   2326  1.1  christos 
   2327  1.1  christos void
   2328  1.1  christos aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
   2329  1.1  christos 		       const aarch64_opcode *opcode,
   2330  1.1  christos 		       const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
   2331  1.1  christos 		       bfd_vma *address)
   2332  1.1  christos {
   2333  1.1  christos   int i;
   2334  1.1  christos   const char *name = NULL;
   2335  1.1  christos   const aarch64_opnd_info *opnd = opnds + idx;
   2336  1.1  christos   enum aarch64_modifier_kind kind;
   2337  1.1  christos   uint64_t addr;
   2338  1.1  christos 
   2339  1.1  christos   buf[0] = '\0';
   2340  1.1  christos   if (pcrel_p)
   2341  1.1  christos     *pcrel_p = 0;
   2342  1.1  christos 
   2343  1.1  christos   switch (opnd->type)
   2344  1.1  christos     {
   2345  1.1  christos     case AARCH64_OPND_Rd:
   2346  1.1  christos     case AARCH64_OPND_Rn:
   2347  1.1  christos     case AARCH64_OPND_Rm:
   2348  1.1  christos     case AARCH64_OPND_Rt:
   2349  1.1  christos     case AARCH64_OPND_Rt2:
   2350  1.3  christos     case AARCH64_OPND_Rs:
   2351  1.1  christos     case AARCH64_OPND_Ra:
   2352  1.1  christos     case AARCH64_OPND_Rt_SYS:
   2353  1.1  christos     case AARCH64_OPND_PAIRREG:
   2354  1.1  christos       /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
   2355  1.1  christos 	 the <ic_op>, therefore we we use opnd->present to override the
   2356  1.1  christos 	 generic optional-ness information.  */
   2357  1.1  christos       if (opnd->type == AARCH64_OPND_Rt_SYS && !opnd->present)
   2358  1.1  christos 	break;
   2359  1.1  christos       /* Omit the operand, e.g. RET.  */
   2360  1.1  christos       if (optional_operand_p (opcode, idx)
   2361  1.1  christos 	  && opnd->reg.regno == get_optional_operand_default_value (opcode))
   2362  1.1  christos 	break;
   2363  1.1  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   2364  1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
   2365  1.1  christos       snprintf (buf, size, "%s",
   2366  1.1  christos 		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
   2367  1.1  christos       break;
   2368  1.1  christos 
   2369  1.1  christos     case AARCH64_OPND_Rd_SP:
   2370  1.1  christos     case AARCH64_OPND_Rn_SP:
   2371  1.1  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   2372  1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_WSP
   2373  1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X
   2374  1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_SP);
   2375  1.1  christos       snprintf (buf, size, "%s",
   2376  1.1  christos 		get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
   2377  1.1  christos       break;
   2378  1.1  christos 
   2379  1.1  christos     case AARCH64_OPND_Rm_EXT:
   2380  1.1  christos       kind = opnd->shifter.kind;
   2381  1.1  christos       assert (idx == 1 || idx == 2);
   2382  1.1  christos       if ((aarch64_stack_pointer_p (opnds)
   2383  1.1  christos 	   || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
   2384  1.1  christos 	  && ((opnd->qualifier == AARCH64_OPND_QLF_W
   2385  1.1  christos 	       && opnds[0].qualifier == AARCH64_OPND_QLF_W
   2386  1.1  christos 	       && kind == AARCH64_MOD_UXTW)
   2387  1.1  christos 	      || (opnd->qualifier == AARCH64_OPND_QLF_X
   2388  1.1  christos 		  && kind == AARCH64_MOD_UXTX)))
   2389  1.1  christos 	{
   2390  1.1  christos 	  /* 'LSL' is the preferred form in this case.  */
   2391  1.1  christos 	  kind = AARCH64_MOD_LSL;
   2392  1.1  christos 	  if (opnd->shifter.amount == 0)
   2393  1.1  christos 	    {
   2394  1.1  christos 	      /* Shifter omitted.  */
   2395  1.1  christos 	      snprintf (buf, size, "%s",
   2396  1.1  christos 			get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
   2397  1.1  christos 	      break;
   2398  1.1  christos 	    }
   2399  1.1  christos 	}
   2400  1.1  christos       if (opnd->shifter.amount)
   2401  1.1  christos 	snprintf (buf, size, "%s, %s #%d",
   2402  1.1  christos 		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
   2403  1.1  christos 		  aarch64_operand_modifiers[kind].name,
   2404  1.1  christos 		  opnd->shifter.amount);
   2405  1.1  christos       else
   2406  1.1  christos 	snprintf (buf, size, "%s, %s",
   2407  1.1  christos 		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
   2408  1.1  christos 		  aarch64_operand_modifiers[kind].name);
   2409  1.1  christos       break;
   2410  1.1  christos 
   2411  1.1  christos     case AARCH64_OPND_Rm_SFT:
   2412  1.1  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   2413  1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
   2414  1.1  christos       if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
   2415  1.1  christos 	snprintf (buf, size, "%s",
   2416  1.1  christos 		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
   2417  1.1  christos       else
   2418  1.1  christos 	snprintf (buf, size, "%s, %s #%d",
   2419  1.1  christos 		  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
   2420  1.1  christos 		  aarch64_operand_modifiers[opnd->shifter.kind].name,
   2421  1.1  christos 		  opnd->shifter.amount);
   2422  1.1  christos       break;
   2423  1.1  christos 
   2424  1.1  christos     case AARCH64_OPND_Fd:
   2425  1.1  christos     case AARCH64_OPND_Fn:
   2426  1.1  christos     case AARCH64_OPND_Fm:
   2427  1.1  christos     case AARCH64_OPND_Fa:
   2428  1.1  christos     case AARCH64_OPND_Ft:
   2429  1.1  christos     case AARCH64_OPND_Ft2:
   2430  1.1  christos     case AARCH64_OPND_Sd:
   2431  1.1  christos     case AARCH64_OPND_Sn:
   2432  1.1  christos     case AARCH64_OPND_Sm:
   2433  1.1  christos       snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
   2434  1.1  christos 		opnd->reg.regno);
   2435  1.1  christos       break;
   2436  1.1  christos 
   2437  1.1  christos     case AARCH64_OPND_Vd:
   2438  1.1  christos     case AARCH64_OPND_Vn:
   2439  1.1  christos     case AARCH64_OPND_Vm:
   2440  1.1  christos       snprintf (buf, size, "v%d.%s", opnd->reg.regno,
   2441  1.1  christos 		aarch64_get_qualifier_name (opnd->qualifier));
   2442  1.1  christos       break;
   2443  1.1  christos 
   2444  1.1  christos     case AARCH64_OPND_Ed:
   2445  1.1  christos     case AARCH64_OPND_En:
   2446  1.1  christos     case AARCH64_OPND_Em:
   2447  1.1  christos       snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
   2448  1.1  christos 		aarch64_get_qualifier_name (opnd->qualifier),
   2449  1.1  christos 		opnd->reglane.index);
   2450  1.1  christos       break;
   2451  1.1  christos 
   2452  1.1  christos     case AARCH64_OPND_VdD1:
   2453  1.1  christos     case AARCH64_OPND_VnD1:
   2454  1.1  christos       snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
   2455  1.1  christos       break;
   2456  1.1  christos 
   2457  1.1  christos     case AARCH64_OPND_LVn:
   2458  1.1  christos     case AARCH64_OPND_LVt:
   2459  1.1  christos     case AARCH64_OPND_LVt_AL:
   2460  1.1  christos     case AARCH64_OPND_LEt:
   2461  1.1  christos       print_register_list (buf, size, opnd);
   2462  1.1  christos       break;
   2463  1.1  christos 
   2464  1.1  christos     case AARCH64_OPND_Cn:
   2465  1.1  christos     case AARCH64_OPND_Cm:
   2466  1.1  christos       snprintf (buf, size, "C%d", opnd->reg.regno);
   2467  1.1  christos       break;
   2468  1.1  christos 
   2469  1.1  christos     case AARCH64_OPND_IDX:
   2470  1.1  christos     case AARCH64_OPND_IMM:
   2471  1.1  christos     case AARCH64_OPND_WIDTH:
   2472  1.1  christos     case AARCH64_OPND_UIMM3_OP1:
   2473  1.1  christos     case AARCH64_OPND_UIMM3_OP2:
   2474  1.1  christos     case AARCH64_OPND_BIT_NUM:
   2475  1.1  christos     case AARCH64_OPND_IMM_VLSL:
   2476  1.1  christos     case AARCH64_OPND_IMM_VLSR:
   2477  1.1  christos     case AARCH64_OPND_SHLL_IMM:
   2478  1.1  christos     case AARCH64_OPND_IMM0:
   2479  1.1  christos     case AARCH64_OPND_IMMR:
   2480  1.1  christos     case AARCH64_OPND_IMMS:
   2481  1.1  christos     case AARCH64_OPND_FBITS:
   2482  1.1  christos       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
   2483  1.1  christos       break;
   2484  1.1  christos 
   2485  1.1  christos     case AARCH64_OPND_IMM_MOV:
   2486  1.1  christos       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
   2487  1.1  christos 	{
   2488  1.1  christos 	case 4:	/* e.g. MOV Wd, #<imm32>.  */
   2489  1.1  christos 	    {
   2490  1.1  christos 	      int imm32 = opnd->imm.value;
   2491  1.1  christos 	      snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
   2492  1.1  christos 	    }
   2493  1.1  christos 	  break;
   2494  1.1  christos 	case 8:	/* e.g. MOV Xd, #<imm64>.  */
   2495  1.1  christos 	  snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
   2496  1.1  christos 		    opnd->imm.value, opnd->imm.value);
   2497  1.1  christos 	  break;
   2498  1.1  christos 	default: assert (0);
   2499  1.1  christos 	}
   2500  1.1  christos       break;
   2501  1.1  christos 
   2502  1.1  christos     case AARCH64_OPND_FPIMM0:
   2503  1.1  christos       snprintf (buf, size, "#0.0");
   2504  1.1  christos       break;
   2505  1.1  christos 
   2506  1.1  christos     case AARCH64_OPND_LIMM:
   2507  1.1  christos     case AARCH64_OPND_AIMM:
   2508  1.1  christos     case AARCH64_OPND_HALF:
   2509  1.1  christos       if (opnd->shifter.amount)
   2510  1.1  christos 	snprintf (buf, size, "#0x%" PRIx64 ", lsl #%d", opnd->imm.value,
   2511  1.1  christos 		  opnd->shifter.amount);
   2512  1.1  christos       else
   2513  1.1  christos 	snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
   2514  1.1  christos       break;
   2515  1.1  christos 
   2516  1.1  christos     case AARCH64_OPND_SIMD_IMM:
   2517  1.1  christos     case AARCH64_OPND_SIMD_IMM_SFT:
   2518  1.1  christos       if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
   2519  1.1  christos 	  || opnd->shifter.kind == AARCH64_MOD_NONE)
   2520  1.1  christos 	snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
   2521  1.1  christos       else
   2522  1.1  christos 	snprintf (buf, size, "#0x%" PRIx64 ", %s #%d", opnd->imm.value,
   2523  1.1  christos 		  aarch64_operand_modifiers[opnd->shifter.kind].name,
   2524  1.1  christos 		  opnd->shifter.amount);
   2525  1.1  christos       break;
   2526  1.1  christos 
   2527  1.1  christos     case AARCH64_OPND_FPIMM:
   2528  1.1  christos     case AARCH64_OPND_SIMD_FPIMM:
   2529  1.1  christos       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
   2530  1.1  christos 	{
   2531  1.1  christos 	case 4:	/* e.g. FMOV <Vd>.4S, #<imm>.  */
   2532  1.1  christos 	    {
   2533  1.1  christos 	      single_conv_t c;
   2534  1.1  christos 	      c.i = expand_fp_imm (0, opnd->imm.value);
   2535  1.1  christos 	      snprintf (buf, size,  "#%.18e", c.f);
   2536  1.1  christos 	    }
   2537  1.1  christos 	  break;
   2538  1.1  christos 	case 8:	/* e.g. FMOV <Sd>, #<imm>.  */
   2539  1.1  christos 	    {
   2540  1.1  christos 	      double_conv_t c;
   2541  1.1  christos 	      c.i = expand_fp_imm (1, opnd->imm.value);
   2542  1.1  christos 	      snprintf (buf, size,  "#%.18e", c.d);
   2543  1.1  christos 	    }
   2544  1.1  christos 	  break;
   2545  1.1  christos 	default: assert (0);
   2546  1.1  christos 	}
   2547  1.1  christos       break;
   2548  1.1  christos 
   2549  1.1  christos     case AARCH64_OPND_CCMP_IMM:
   2550  1.1  christos     case AARCH64_OPND_NZCV:
   2551  1.1  christos     case AARCH64_OPND_EXCEPTION:
   2552  1.1  christos     case AARCH64_OPND_UIMM4:
   2553  1.1  christos     case AARCH64_OPND_UIMM7:
   2554  1.1  christos       if (optional_operand_p (opcode, idx) == TRUE
   2555  1.1  christos 	  && (opnd->imm.value ==
   2556  1.1  christos 	      (int64_t) get_optional_operand_default_value (opcode)))
   2557  1.1  christos 	/* Omit the operand, e.g. DCPS1.  */
   2558  1.1  christos 	break;
   2559  1.1  christos       snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
   2560  1.1  christos       break;
   2561  1.1  christos 
   2562  1.1  christos     case AARCH64_OPND_COND:
   2563  1.1  christos     case AARCH64_OPND_COND1:
   2564  1.1  christos       snprintf (buf, size, "%s", opnd->cond->names[0]);
   2565  1.1  christos       break;
   2566  1.1  christos 
   2567  1.1  christos     case AARCH64_OPND_ADDR_ADRP:
   2568  1.1  christos       addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
   2569  1.1  christos 	+ opnd->imm.value;
   2570  1.1  christos       if (pcrel_p)
   2571  1.1  christos 	*pcrel_p = 1;
   2572  1.1  christos       if (address)
   2573  1.1  christos 	*address = addr;
   2574  1.1  christos       /* This is not necessary during the disassembling, as print_address_func
   2575  1.1  christos 	 in the disassemble_info will take care of the printing.  But some
   2576  1.1  christos 	 other callers may be still interested in getting the string in *STR,
   2577  1.1  christos 	 so here we do snprintf regardless.  */
   2578  1.1  christos       snprintf (buf, size, "#0x%" PRIx64, addr);
   2579  1.1  christos       break;
   2580  1.1  christos 
   2581  1.1  christos     case AARCH64_OPND_ADDR_PCREL14:
   2582  1.1  christos     case AARCH64_OPND_ADDR_PCREL19:
   2583  1.1  christos     case AARCH64_OPND_ADDR_PCREL21:
   2584  1.1  christos     case AARCH64_OPND_ADDR_PCREL26:
   2585  1.1  christos       addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
   2586  1.1  christos       if (pcrel_p)
   2587  1.1  christos 	*pcrel_p = 1;
   2588  1.1  christos       if (address)
   2589  1.1  christos 	*address = addr;
   2590  1.1  christos       /* This is not necessary during the disassembling, as print_address_func
   2591  1.1  christos 	 in the disassemble_info will take care of the printing.  But some
   2592  1.1  christos 	 other callers may be still interested in getting the string in *STR,
   2593  1.1  christos 	 so here we do snprintf regardless.  */
   2594  1.1  christos       snprintf (buf, size, "#0x%" PRIx64, addr);
   2595  1.1  christos       break;
   2596  1.1  christos 
   2597  1.1  christos     case AARCH64_OPND_ADDR_SIMPLE:
   2598  1.1  christos     case AARCH64_OPND_SIMD_ADDR_SIMPLE:
   2599  1.1  christos     case AARCH64_OPND_SIMD_ADDR_POST:
   2600  1.1  christos       name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
   2601  1.1  christos       if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
   2602  1.1  christos 	{
   2603  1.1  christos 	  if (opnd->addr.offset.is_reg)
   2604  1.1  christos 	    snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
   2605  1.1  christos 	  else
   2606  1.1  christos 	    snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
   2607  1.1  christos 	}
   2608  1.1  christos       else
   2609  1.1  christos 	snprintf (buf, size, "[%s]", name);
   2610  1.1  christos       break;
   2611  1.1  christos 
   2612  1.1  christos     case AARCH64_OPND_ADDR_REGOFF:
   2613  1.1  christos       print_register_offset_address (buf, size, opnd);
   2614  1.1  christos       break;
   2615  1.1  christos 
   2616  1.1  christos     case AARCH64_OPND_ADDR_SIMM7:
   2617  1.1  christos     case AARCH64_OPND_ADDR_SIMM9:
   2618  1.1  christos     case AARCH64_OPND_ADDR_SIMM9_2:
   2619  1.1  christos       name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
   2620  1.1  christos       if (opnd->addr.writeback)
   2621  1.1  christos 	{
   2622  1.1  christos 	  if (opnd->addr.preind)
   2623  1.1  christos 	    snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
   2624  1.1  christos 	  else
   2625  1.1  christos 	    snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
   2626  1.1  christos 	}
   2627  1.1  christos       else
   2628  1.1  christos 	{
   2629  1.1  christos 	  if (opnd->addr.offset.imm)
   2630  1.1  christos 	    snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
   2631  1.1  christos 	  else
   2632  1.1  christos 	    snprintf (buf, size, "[%s]", name);
   2633  1.1  christos 	}
   2634  1.1  christos       break;
   2635  1.1  christos 
   2636  1.1  christos     case AARCH64_OPND_ADDR_UIMM12:
   2637  1.1  christos       name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
   2638  1.1  christos       if (opnd->addr.offset.imm)
   2639  1.1  christos 	snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
   2640  1.1  christos       else
   2641  1.1  christos 	snprintf (buf, size, "[%s]", name);
   2642  1.1  christos       break;
   2643  1.1  christos 
   2644  1.1  christos     case AARCH64_OPND_SYSREG:
   2645  1.1  christos       for (i = 0; aarch64_sys_regs[i].name; ++i)
   2646  1.1  christos 	if (aarch64_sys_regs[i].value == opnd->sysreg
   2647  1.1  christos 	    && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
   2648  1.1  christos 	  break;
   2649  1.1  christos       if (aarch64_sys_regs[i].name)
   2650  1.1  christos 	snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
   2651  1.1  christos       else
   2652  1.1  christos 	{
   2653  1.1  christos 	  /* Implementation defined system register.  */
   2654  1.1  christos 	  unsigned int value = opnd->sysreg;
   2655  1.1  christos 	  snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
   2656  1.1  christos 		    (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
   2657  1.1  christos 		    value & 0x7);
   2658  1.1  christos 	}
   2659  1.1  christos       break;
   2660  1.1  christos 
   2661  1.1  christos     case AARCH64_OPND_PSTATEFIELD:
   2662  1.1  christos       for (i = 0; aarch64_pstatefields[i].name; ++i)
   2663  1.1  christos 	if (aarch64_pstatefields[i].value == opnd->pstatefield)
   2664  1.1  christos 	  break;
   2665  1.1  christos       assert (aarch64_pstatefields[i].name);
   2666  1.1  christos       snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
   2667  1.1  christos       break;
   2668  1.1  christos 
   2669  1.1  christos     case AARCH64_OPND_SYSREG_AT:
   2670  1.1  christos     case AARCH64_OPND_SYSREG_DC:
   2671  1.1  christos     case AARCH64_OPND_SYSREG_IC:
   2672  1.1  christos     case AARCH64_OPND_SYSREG_TLBI:
   2673  1.1  christos       snprintf (buf, size, "%s", opnd->sysins_op->template);
   2674  1.1  christos       break;
   2675  1.1  christos 
   2676  1.1  christos     case AARCH64_OPND_BARRIER:
   2677  1.1  christos       snprintf (buf, size, "%s", opnd->barrier->name);
   2678  1.1  christos       break;
   2679  1.1  christos 
   2680  1.1  christos     case AARCH64_OPND_BARRIER_ISB:
   2681  1.1  christos       /* Operand can be omitted, e.g. in DCPS1.  */
   2682  1.1  christos       if (! optional_operand_p (opcode, idx)
   2683  1.1  christos 	  || (opnd->barrier->value
   2684  1.1  christos 	      != get_optional_operand_default_value (opcode)))
   2685  1.1  christos 	snprintf (buf, size, "#0x%x", opnd->barrier->value);
   2686  1.1  christos       break;
   2687  1.1  christos 
   2688  1.1  christos     case AARCH64_OPND_PRFOP:
   2689  1.1  christos       if (opnd->prfop->name != NULL)
   2690  1.1  christos 	snprintf (buf, size, "%s", opnd->prfop->name);
   2691  1.1  christos       else
   2692  1.1  christos 	snprintf (buf, size, "#0x%02x", opnd->prfop->value);
   2693  1.1  christos       break;
   2694  1.1  christos 
   2695  1.1  christos     default:
   2696  1.1  christos       assert (0);
   2697  1.1  christos     }
   2698  1.1  christos }
   2699  1.1  christos 
   2700  1.1  christos #define CPENC(op0,op1,crn,crm,op2) \
   2702  1.1  christos   ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
   2703  1.1  christos   /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
   2704  1.1  christos #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
   2705  1.1  christos   /* for 3.9.10 System Instructions */
   2706  1.1  christos #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
   2707  1.1  christos 
   2708  1.1  christos #define C0  0
   2709  1.1  christos #define C1  1
   2710  1.1  christos #define C2  2
   2711  1.1  christos #define C3  3
   2712  1.1  christos #define C4  4
   2713  1.1  christos #define C5  5
   2714  1.1  christos #define C6  6
   2715  1.1  christos #define C7  7
   2716  1.1  christos #define C8  8
   2717  1.1  christos #define C9  9
   2718  1.1  christos #define C10 10
   2719  1.1  christos #define C11 11
   2720  1.1  christos #define C12 12
   2721  1.1  christos #define C13 13
   2722  1.1  christos #define C14 14
   2723  1.1  christos #define C15 15
   2724  1.1  christos 
   2725  1.1  christos #ifdef F_DEPRECATED
   2726  1.1  christos #undef F_DEPRECATED
   2727  1.1  christos #endif
   2728  1.1  christos #define F_DEPRECATED	0x1	/* Deprecated system register.  */
   2729  1.1  christos 
   2730  1.1  christos /* TODO there are two more issues need to be resolved
   2731  1.1  christos    1. handle read-only and write-only system registers
   2732  1.1  christos    2. handle cpu-implementation-defined system registers.  */
   2733  1.1  christos const aarch64_sys_reg aarch64_sys_regs [] =
   2734  1.1  christos {
   2735  1.1  christos   { "spsr_el1",         CPEN_(0,C0,0),	0 }, /* = spsr_svc */
   2736  1.1  christos   { "elr_el1",          CPEN_(0,C0,1),	0 },
   2737  1.1  christos   { "sp_el0",           CPEN_(0,C1,0),	0 },
   2738  1.1  christos   { "spsel",            CPEN_(0,C2,0),	0 },
   2739  1.1  christos   { "daif",             CPEN_(3,C2,1),	0 },
   2740  1.1  christos   { "currentel",        CPEN_(0,C2,2),	0 }, /* RO */
   2741  1.1  christos   { "nzcv",             CPEN_(3,C2,0),	0 },
   2742  1.1  christos   { "fpcr",             CPEN_(3,C4,0),	0 },
   2743  1.1  christos   { "fpsr",             CPEN_(3,C4,1),	0 },
   2744  1.1  christos   { "dspsr_el0",        CPEN_(3,C5,0),	0 },
   2745  1.1  christos   { "dlr_el0",          CPEN_(3,C5,1),	0 },
   2746  1.1  christos   { "spsr_el2",         CPEN_(4,C0,0),	0 }, /* = spsr_hyp */
   2747  1.1  christos   { "elr_el2",          CPEN_(4,C0,1),	0 },
   2748  1.1  christos   { "sp_el1",           CPEN_(4,C1,0),	0 },
   2749  1.1  christos   { "spsr_irq",         CPEN_(4,C3,0),	0 },
   2750  1.1  christos   { "spsr_abt",         CPEN_(4,C3,1),	0 },
   2751  1.1  christos   { "spsr_und",         CPEN_(4,C3,2),	0 },
   2752  1.1  christos   { "spsr_fiq",         CPEN_(4,C3,3),	0 },
   2753  1.1  christos   { "spsr_el3",         CPEN_(6,C0,0),	0 },
   2754  1.1  christos   { "elr_el3",          CPEN_(6,C0,1),	0 },
   2755  1.1  christos   { "sp_el2",           CPEN_(6,C1,0),	0 },
   2756  1.1  christos   { "spsr_svc",         CPEN_(0,C0,0),	F_DEPRECATED }, /* = spsr_el1 */
   2757  1.1  christos   { "spsr_hyp",         CPEN_(4,C0,0),	F_DEPRECATED }, /* = spsr_el2 */
   2758  1.1  christos   { "midr_el1",         CPENC(3,0,C0,C0,0),	0 }, /* RO */
   2759  1.1  christos   { "ctr_el0",          CPENC(3,3,C0,C0,1),	0 }, /* RO */
   2760  1.1  christos   { "mpidr_el1",        CPENC(3,0,C0,C0,5),	0 }, /* RO */
   2761  1.1  christos   { "revidr_el1",       CPENC(3,0,C0,C0,6),	0 }, /* RO */
   2762  1.1  christos   { "aidr_el1",         CPENC(3,1,C0,C0,7),	0 }, /* RO */
   2763  1.1  christos   { "dczid_el0",        CPENC(3,3,C0,C0,7),	0 }, /* RO */
   2764  1.1  christos   { "id_dfr0_el1",      CPENC(3,0,C0,C1,2),	0 }, /* RO */
   2765  1.1  christos   { "id_pfr0_el1",      CPENC(3,0,C0,C1,0),	0 }, /* RO */
   2766  1.1  christos   { "id_pfr1_el1",      CPENC(3,0,C0,C1,1),	0 }, /* RO */
   2767  1.1  christos   { "id_afr0_el1",      CPENC(3,0,C0,C1,3),	0 }, /* RO */
   2768  1.1  christos   { "id_mmfr0_el1",     CPENC(3,0,C0,C1,4),	0 }, /* RO */
   2769  1.1  christos   { "id_mmfr1_el1",     CPENC(3,0,C0,C1,5),	0 }, /* RO */
   2770  1.1  christos   { "id_mmfr2_el1",     CPENC(3,0,C0,C1,6),	0 }, /* RO */
   2771  1.1  christos   { "id_mmfr3_el1",     CPENC(3,0,C0,C1,7),	0 }, /* RO */
   2772  1.1  christos   { "id_isar0_el1",     CPENC(3,0,C0,C2,0),	0 }, /* RO */
   2773  1.1  christos   { "id_isar1_el1",     CPENC(3,0,C0,C2,1),	0 }, /* RO */
   2774  1.1  christos   { "id_isar2_el1",     CPENC(3,0,C0,C2,2),	0 }, /* RO */
   2775  1.1  christos   { "id_isar3_el1",     CPENC(3,0,C0,C2,3),	0 }, /* RO */
   2776  1.1  christos   { "id_isar4_el1",     CPENC(3,0,C0,C2,4),	0 }, /* RO */
   2777  1.1  christos   { "id_isar5_el1",     CPENC(3,0,C0,C2,5),	0 }, /* RO */
   2778  1.1  christos   { "mvfr0_el1",        CPENC(3,0,C0,C3,0),	0 }, /* RO */
   2779  1.1  christos   { "mvfr1_el1",        CPENC(3,0,C0,C3,1),	0 }, /* RO */
   2780  1.1  christos   { "mvfr2_el1",        CPENC(3,0,C0,C3,2),	0 }, /* RO */
   2781  1.1  christos   { "ccsidr_el1",       CPENC(3,1,C0,C0,0),	0 }, /* RO */
   2782  1.1  christos   { "id_aa64pfr0_el1",  CPENC(3,0,C0,C4,0),	0 }, /* RO */
   2783  1.1  christos   { "id_aa64pfr1_el1",  CPENC(3,0,C0,C4,1),	0 }, /* RO */
   2784  1.1  christos   { "id_aa64dfr0_el1",  CPENC(3,0,C0,C5,0),	0 }, /* RO */
   2785  1.1  christos   { "id_aa64dfr1_el1",  CPENC(3,0,C0,C5,1),	0 }, /* RO */
   2786  1.1  christos   { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0),	0 }, /* RO */
   2787  1.1  christos   { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1),	0 }, /* RO */
   2788  1.1  christos   { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0),	0 }, /* RO */
   2789  1.1  christos   { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1),	0 }, /* RO */
   2790  1.1  christos   { "id_aa64afr0_el1",  CPENC(3,0,C0,C5,4),	0 }, /* RO */
   2791  1.1  christos   { "id_aa64afr1_el1",  CPENC(3,0,C0,C5,5),	0 }, /* RO */
   2792  1.1  christos   { "clidr_el1",        CPENC(3,1,C0,C0,1),	0 }, /* RO */
   2793  1.1  christos   { "csselr_el1",       CPENC(3,2,C0,C0,0),	0 }, /* RO */
   2794  1.1  christos   { "vpidr_el2",        CPENC(3,4,C0,C0,0),	0 },
   2795  1.1  christos   { "vmpidr_el2",       CPENC(3,4,C0,C0,5),	0 },
   2796  1.1  christos   { "sctlr_el1",        CPENC(3,0,C1,C0,0),	0 },
   2797  1.1  christos   { "sctlr_el2",        CPENC(3,4,C1,C0,0),	0 },
   2798  1.1  christos   { "sctlr_el3",        CPENC(3,6,C1,C0,0),	0 },
   2799  1.1  christos   { "actlr_el1",        CPENC(3,0,C1,C0,1),	0 },
   2800  1.1  christos   { "actlr_el2",        CPENC(3,4,C1,C0,1),	0 },
   2801  1.1  christos   { "actlr_el3",        CPENC(3,6,C1,C0,1),	0 },
   2802  1.1  christos   { "cpacr_el1",        CPENC(3,0,C1,C0,2),	0 },
   2803  1.1  christos   { "cptr_el2",         CPENC(3,4,C1,C1,2),	0 },
   2804  1.1  christos   { "cptr_el3",         CPENC(3,6,C1,C1,2),	0 },
   2805  1.1  christos   { "scr_el3",          CPENC(3,6,C1,C1,0),	0 },
   2806  1.1  christos   { "hcr_el2",          CPENC(3,4,C1,C1,0),	0 },
   2807  1.1  christos   { "mdcr_el2",         CPENC(3,4,C1,C1,1),	0 },
   2808  1.1  christos   { "mdcr_el3",         CPENC(3,6,C1,C3,1),	0 },
   2809  1.1  christos   { "hstr_el2",         CPENC(3,4,C1,C1,3),	0 },
   2810  1.1  christos   { "hacr_el2",         CPENC(3,4,C1,C1,7),	0 },
   2811  1.1  christos   { "ttbr0_el1",        CPENC(3,0,C2,C0,0),	0 },
   2812  1.1  christos   { "ttbr1_el1",        CPENC(3,0,C2,C0,1),	0 },
   2813  1.1  christos   { "ttbr0_el2",        CPENC(3,4,C2,C0,0),	0 },
   2814  1.1  christos   { "ttbr0_el3",        CPENC(3,6,C2,C0,0),	0 },
   2815  1.1  christos   { "vttbr_el2",        CPENC(3,4,C2,C1,0),	0 },
   2816  1.1  christos   { "tcr_el1",          CPENC(3,0,C2,C0,2),	0 },
   2817  1.1  christos   { "tcr_el2",          CPENC(3,4,C2,C0,2),	0 },
   2818  1.1  christos   { "tcr_el3",          CPENC(3,6,C2,C0,2),	0 },
   2819  1.1  christos   { "vtcr_el2",         CPENC(3,4,C2,C1,2),	0 },
   2820  1.1  christos   { "afsr0_el1",        CPENC(3,0,C5,C1,0),	0 },
   2821  1.1  christos   { "afsr1_el1",        CPENC(3,0,C5,C1,1),	0 },
   2822  1.1  christos   { "afsr0_el2",        CPENC(3,4,C5,C1,0),	0 },
   2823  1.1  christos   { "afsr1_el2",        CPENC(3,4,C5,C1,1),	0 },
   2824  1.1  christos   { "afsr0_el3",        CPENC(3,6,C5,C1,0),	0 },
   2825  1.1  christos   { "afsr1_el3",        CPENC(3,6,C5,C1,1),	0 },
   2826  1.1  christos   { "esr_el1",          CPENC(3,0,C5,C2,0),	0 },
   2827  1.1  christos   { "esr_el2",          CPENC(3,4,C5,C2,0),	0 },
   2828  1.1  christos   { "esr_el3",          CPENC(3,6,C5,C2,0),	0 },
   2829  1.1  christos   { "fpexc32_el2",      CPENC(3,4,C5,C3,0),	0 },
   2830  1.1  christos   { "far_el1",          CPENC(3,0,C6,C0,0),	0 },
   2831  1.1  christos   { "far_el2",          CPENC(3,4,C6,C0,0),	0 },
   2832  1.1  christos   { "far_el3",          CPENC(3,6,C6,C0,0),	0 },
   2833  1.1  christos   { "hpfar_el2",        CPENC(3,4,C6,C0,4),	0 },
   2834  1.1  christos   { "par_el1",          CPENC(3,0,C7,C4,0),	0 },
   2835  1.1  christos   { "mair_el1",         CPENC(3,0,C10,C2,0),	0 },
   2836  1.1  christos   { "mair_el2",         CPENC(3,4,C10,C2,0),	0 },
   2837  1.1  christos   { "mair_el3",         CPENC(3,6,C10,C2,0),	0 },
   2838  1.1  christos   { "amair_el1",        CPENC(3,0,C10,C3,0),	0 },
   2839  1.1  christos   { "amair_el2",        CPENC(3,4,C10,C3,0),	0 },
   2840  1.1  christos   { "amair_el3",        CPENC(3,6,C10,C3,0),	0 },
   2841  1.1  christos   { "vbar_el1",         CPENC(3,0,C12,C0,0),	0 },
   2842  1.1  christos   { "vbar_el2",         CPENC(3,4,C12,C0,0),	0 },
   2843  1.1  christos   { "vbar_el3",         CPENC(3,6,C12,C0,0),	0 },
   2844  1.1  christos   { "rvbar_el1",        CPENC(3,0,C12,C0,1),	0 }, /* RO */
   2845  1.1  christos   { "rvbar_el2",        CPENC(3,4,C12,C0,1),	0 }, /* RO */
   2846  1.1  christos   { "rvbar_el3",        CPENC(3,6,C12,C0,1),	0 }, /* RO */
   2847  1.1  christos   { "rmr_el1",          CPENC(3,0,C12,C0,2),	0 },
   2848  1.1  christos   { "rmr_el2",          CPENC(3,4,C12,C0,2),	0 },
   2849  1.1  christos   { "rmr_el3",          CPENC(3,6,C12,C0,2),	0 },
   2850  1.1  christos   { "isr_el1",          CPENC(3,0,C12,C1,0),	0 }, /* RO */
   2851  1.1  christos   { "contextidr_el1",   CPENC(3,0,C13,C0,1),	0 },
   2852  1.1  christos   { "tpidr_el0",        CPENC(3,3,C13,C0,2),	0 },
   2853  1.1  christos   { "tpidrro_el0",      CPENC(3,3,C13,C0,3),	0 }, /* RO */
   2854  1.1  christos   { "tpidr_el1",        CPENC(3,0,C13,C0,4),	0 },
   2855  1.1  christos   { "tpidr_el2",        CPENC(3,4,C13,C0,2),	0 },
   2856  1.1  christos   { "tpidr_el3",        CPENC(3,6,C13,C0,2),	0 },
   2857  1.1  christos   { "teecr32_el1",      CPENC(2,2,C0, C0,0),	0 }, /* See section 3.9.7.1 */
   2858  1.1  christos   { "cntfrq_el0",       CPENC(3,3,C14,C0,0),	0 }, /* RO */
   2859  1.1  christos   { "cntpct_el0",       CPENC(3,3,C14,C0,1),	0 }, /* RO */
   2860  1.1  christos   { "cntvct_el0",       CPENC(3,3,C14,C0,2),	0 }, /* RO */
   2861  1.1  christos   { "cntvoff_el2",      CPENC(3,4,C14,C0,3),	0 },
   2862  1.1  christos   { "cntkctl_el1",      CPENC(3,0,C14,C1,0),	0 },
   2863  1.1  christos   { "cnthctl_el2",      CPENC(3,4,C14,C1,0),	0 },
   2864  1.1  christos   { "cntp_tval_el0",    CPENC(3,3,C14,C2,0),	0 },
   2865  1.1  christos   { "cntp_ctl_el0",     CPENC(3,3,C14,C2,1),	0 },
   2866  1.1  christos   { "cntp_cval_el0",    CPENC(3,3,C14,C2,2),	0 },
   2867  1.1  christos   { "cntv_tval_el0",    CPENC(3,3,C14,C3,0),	0 },
   2868  1.1  christos   { "cntv_ctl_el0",     CPENC(3,3,C14,C3,1),	0 },
   2869  1.1  christos   { "cntv_cval_el0",    CPENC(3,3,C14,C3,2),	0 },
   2870  1.1  christos   { "cnthp_tval_el2",   CPENC(3,4,C14,C2,0),	0 },
   2871  1.1  christos   { "cnthp_ctl_el2",    CPENC(3,4,C14,C2,1),	0 },
   2872  1.1  christos   { "cnthp_cval_el2",   CPENC(3,4,C14,C2,2),	0 },
   2873  1.1  christos   { "cntps_tval_el1",   CPENC(3,7,C14,C2,0),	0 },
   2874  1.1  christos   { "cntps_ctl_el1",    CPENC(3,7,C14,C2,1),	0 },
   2875  1.1  christos   { "cntps_cval_el1",   CPENC(3,7,C14,C2,2),	0 },
   2876  1.1  christos   { "dacr32_el2",       CPENC(3,4,C3,C0,0),	0 },
   2877  1.1  christos   { "ifsr32_el2",       CPENC(3,4,C5,C0,1),	0 },
   2878  1.1  christos   { "teehbr32_el1",     CPENC(2,2,C1,C0,0),	0 },
   2879  1.1  christos   { "sder32_el3",       CPENC(3,6,C1,C1,1),	0 },
   2880  1.1  christos   { "mdscr_el1",         CPENC(2,0,C0, C2, 2),	0 },
   2881  1.1  christos   { "mdccsr_el0",        CPENC(2,3,C0, C1, 0),	0 },  /* r */
   2882  1.1  christos   { "mdccint_el1",       CPENC(2,0,C0, C2, 0),	0 },
   2883  1.1  christos   { "dbgdtr_el0",        CPENC(2,3,C0, C4, 0),	0 },
   2884  1.1  christos   { "dbgdtrrx_el0",      CPENC(2,3,C0, C5, 0),	0 },  /* r */
   2885  1.1  christos   { "dbgdtrtx_el0",      CPENC(2,3,C0, C5, 0),	0 },  /* w */
   2886  1.1  christos   { "osdtrrx_el1",       CPENC(2,0,C0, C0, 2),	0 },  /* r */
   2887  1.1  christos   { "osdtrtx_el1",       CPENC(2,0,C0, C3, 2),	0 },  /* w */
   2888  1.1  christos   { "oseccr_el1",        CPENC(2,0,C0, C6, 2),	0 },
   2889  1.1  christos   { "dbgvcr32_el2",      CPENC(2,4,C0, C7, 0),	0 },
   2890  1.1  christos   { "dbgbvr0_el1",       CPENC(2,0,C0, C0, 4),	0 },
   2891  1.1  christos   { "dbgbvr1_el1",       CPENC(2,0,C0, C1, 4),	0 },
   2892  1.1  christos   { "dbgbvr2_el1",       CPENC(2,0,C0, C2, 4),	0 },
   2893  1.1  christos   { "dbgbvr3_el1",       CPENC(2,0,C0, C3, 4),	0 },
   2894  1.1  christos   { "dbgbvr4_el1",       CPENC(2,0,C0, C4, 4),	0 },
   2895  1.1  christos   { "dbgbvr5_el1",       CPENC(2,0,C0, C5, 4),	0 },
   2896  1.1  christos   { "dbgbvr6_el1",       CPENC(2,0,C0, C6, 4),	0 },
   2897  1.1  christos   { "dbgbvr7_el1",       CPENC(2,0,C0, C7, 4),	0 },
   2898  1.1  christos   { "dbgbvr8_el1",       CPENC(2,0,C0, C8, 4),	0 },
   2899  1.1  christos   { "dbgbvr9_el1",       CPENC(2,0,C0, C9, 4),	0 },
   2900  1.1  christos   { "dbgbvr10_el1",      CPENC(2,0,C0, C10,4),	0 },
   2901  1.1  christos   { "dbgbvr11_el1",      CPENC(2,0,C0, C11,4),	0 },
   2902  1.1  christos   { "dbgbvr12_el1",      CPENC(2,0,C0, C12,4),	0 },
   2903  1.1  christos   { "dbgbvr13_el1",      CPENC(2,0,C0, C13,4),	0 },
   2904  1.1  christos   { "dbgbvr14_el1",      CPENC(2,0,C0, C14,4),	0 },
   2905  1.1  christos   { "dbgbvr15_el1",      CPENC(2,0,C0, C15,4),	0 },
   2906  1.1  christos   { "dbgbcr0_el1",       CPENC(2,0,C0, C0, 5),	0 },
   2907  1.1  christos   { "dbgbcr1_el1",       CPENC(2,0,C0, C1, 5),	0 },
   2908  1.1  christos   { "dbgbcr2_el1",       CPENC(2,0,C0, C2, 5),	0 },
   2909  1.1  christos   { "dbgbcr3_el1",       CPENC(2,0,C0, C3, 5),	0 },
   2910  1.1  christos   { "dbgbcr4_el1",       CPENC(2,0,C0, C4, 5),	0 },
   2911  1.1  christos   { "dbgbcr5_el1",       CPENC(2,0,C0, C5, 5),	0 },
   2912  1.1  christos   { "dbgbcr6_el1",       CPENC(2,0,C0, C6, 5),	0 },
   2913  1.1  christos   { "dbgbcr7_el1",       CPENC(2,0,C0, C7, 5),	0 },
   2914  1.1  christos   { "dbgbcr8_el1",       CPENC(2,0,C0, C8, 5),	0 },
   2915  1.1  christos   { "dbgbcr9_el1",       CPENC(2,0,C0, C9, 5),	0 },
   2916  1.1  christos   { "dbgbcr10_el1",      CPENC(2,0,C0, C10,5),	0 },
   2917  1.1  christos   { "dbgbcr11_el1",      CPENC(2,0,C0, C11,5),	0 },
   2918  1.1  christos   { "dbgbcr12_el1",      CPENC(2,0,C0, C12,5),	0 },
   2919  1.1  christos   { "dbgbcr13_el1",      CPENC(2,0,C0, C13,5),	0 },
   2920  1.1  christos   { "dbgbcr14_el1",      CPENC(2,0,C0, C14,5),	0 },
   2921  1.1  christos   { "dbgbcr15_el1",      CPENC(2,0,C0, C15,5),	0 },
   2922  1.1  christos   { "dbgwvr0_el1",       CPENC(2,0,C0, C0, 6),	0 },
   2923  1.1  christos   { "dbgwvr1_el1",       CPENC(2,0,C0, C1, 6),	0 },
   2924  1.1  christos   { "dbgwvr2_el1",       CPENC(2,0,C0, C2, 6),	0 },
   2925  1.1  christos   { "dbgwvr3_el1",       CPENC(2,0,C0, C3, 6),	0 },
   2926  1.1  christos   { "dbgwvr4_el1",       CPENC(2,0,C0, C4, 6),	0 },
   2927  1.1  christos   { "dbgwvr5_el1",       CPENC(2,0,C0, C5, 6),	0 },
   2928  1.1  christos   { "dbgwvr6_el1",       CPENC(2,0,C0, C6, 6),	0 },
   2929  1.1  christos   { "dbgwvr7_el1",       CPENC(2,0,C0, C7, 6),	0 },
   2930  1.1  christos   { "dbgwvr8_el1",       CPENC(2,0,C0, C8, 6),	0 },
   2931  1.1  christos   { "dbgwvr9_el1",       CPENC(2,0,C0, C9, 6),	0 },
   2932  1.1  christos   { "dbgwvr10_el1",      CPENC(2,0,C0, C10,6),	0 },
   2933  1.1  christos   { "dbgwvr11_el1",      CPENC(2,0,C0, C11,6),	0 },
   2934  1.1  christos   { "dbgwvr12_el1",      CPENC(2,0,C0, C12,6),	0 },
   2935  1.1  christos   { "dbgwvr13_el1",      CPENC(2,0,C0, C13,6),	0 },
   2936  1.1  christos   { "dbgwvr14_el1",      CPENC(2,0,C0, C14,6),	0 },
   2937  1.1  christos   { "dbgwvr15_el1",      CPENC(2,0,C0, C15,6),	0 },
   2938  1.1  christos   { "dbgwcr0_el1",       CPENC(2,0,C0, C0, 7),	0 },
   2939  1.1  christos   { "dbgwcr1_el1",       CPENC(2,0,C0, C1, 7),	0 },
   2940  1.1  christos   { "dbgwcr2_el1",       CPENC(2,0,C0, C2, 7),	0 },
   2941  1.1  christos   { "dbgwcr3_el1",       CPENC(2,0,C0, C3, 7),	0 },
   2942  1.1  christos   { "dbgwcr4_el1",       CPENC(2,0,C0, C4, 7),	0 },
   2943  1.1  christos   { "dbgwcr5_el1",       CPENC(2,0,C0, C5, 7),	0 },
   2944  1.1  christos   { "dbgwcr6_el1",       CPENC(2,0,C0, C6, 7),	0 },
   2945  1.1  christos   { "dbgwcr7_el1",       CPENC(2,0,C0, C7, 7),	0 },
   2946  1.1  christos   { "dbgwcr8_el1",       CPENC(2,0,C0, C8, 7),	0 },
   2947  1.1  christos   { "dbgwcr9_el1",       CPENC(2,0,C0, C9, 7),	0 },
   2948  1.1  christos   { "dbgwcr10_el1",      CPENC(2,0,C0, C10,7),	0 },
   2949  1.1  christos   { "dbgwcr11_el1",      CPENC(2,0,C0, C11,7),	0 },
   2950  1.1  christos   { "dbgwcr12_el1",      CPENC(2,0,C0, C12,7),	0 },
   2951  1.1  christos   { "dbgwcr13_el1",      CPENC(2,0,C0, C13,7),	0 },
   2952  1.1  christos   { "dbgwcr14_el1",      CPENC(2,0,C0, C14,7),	0 },
   2953  1.1  christos   { "dbgwcr15_el1",      CPENC(2,0,C0, C15,7),	0 },
   2954  1.1  christos   { "mdrar_el1",         CPENC(2,0,C1, C0, 0),	0 },  /* r */
   2955  1.1  christos   { "oslar_el1",         CPENC(2,0,C1, C0, 4),	0 },  /* w */
   2956  1.1  christos   { "oslsr_el1",         CPENC(2,0,C1, C1, 4),	0 },  /* r */
   2957  1.1  christos   { "osdlr_el1",         CPENC(2,0,C1, C3, 4),	0 },
   2958  1.1  christos   { "dbgprcr_el1",       CPENC(2,0,C1, C4, 4),	0 },
   2959  1.1  christos   { "dbgclaimset_el1",   CPENC(2,0,C7, C8, 6),	0 },
   2960  1.1  christos   { "dbgclaimclr_el1",   CPENC(2,0,C7, C9, 6),	0 },
   2961  1.1  christos   { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6),	0 },  /* r */
   2962  1.1  christos 
   2963  1.1  christos   { "pmcr_el0",          CPENC(3,3,C9,C12, 0),	0 },
   2964  1.1  christos   { "pmcntenset_el0",    CPENC(3,3,C9,C12, 1),	0 },
   2965  1.1  christos   { "pmcntenclr_el0",    CPENC(3,3,C9,C12, 2),	0 },
   2966  1.1  christos   { "pmovsclr_el0",      CPENC(3,3,C9,C12, 3),	0 },
   2967  1.1  christos   { "pmswinc_el0",       CPENC(3,3,C9,C12, 4),	0 },  /* w */
   2968  1.1  christos   { "pmselr_el0",        CPENC(3,3,C9,C12, 5),	0 },
   2969  1.1  christos   { "pmceid0_el0",       CPENC(3,3,C9,C12, 6),	0 },  /* r */
   2970  1.1  christos   { "pmceid1_el0",       CPENC(3,3,C9,C12, 7),	0 },  /* r */
   2971  1.1  christos   { "pmccntr_el0",       CPENC(3,3,C9,C13, 0),	0 },
   2972  1.1  christos   { "pmxevtyper_el0",    CPENC(3,3,C9,C13, 1),	0 },
   2973  1.1  christos   { "pmxevcntr_el0",     CPENC(3,3,C9,C13, 2),	0 },
   2974  1.1  christos   { "pmuserenr_el0",     CPENC(3,3,C9,C14, 0),	0 },
   2975  1.1  christos   { "pmintenset_el1",    CPENC(3,0,C9,C14, 1),	0 },
   2976  1.1  christos   { "pmintenclr_el1",    CPENC(3,0,C9,C14, 2),	0 },
   2977  1.1  christos   { "pmovsset_el0",      CPENC(3,3,C9,C14, 3),	0 },
   2978  1.1  christos   { "pmevcntr0_el0",     CPENC(3,3,C14,C8, 0),	0 },
   2979  1.1  christos   { "pmevcntr1_el0",     CPENC(3,3,C14,C8, 1),	0 },
   2980  1.1  christos   { "pmevcntr2_el0",     CPENC(3,3,C14,C8, 2),	0 },
   2981  1.1  christos   { "pmevcntr3_el0",     CPENC(3,3,C14,C8, 3),	0 },
   2982  1.1  christos   { "pmevcntr4_el0",     CPENC(3,3,C14,C8, 4),	0 },
   2983  1.1  christos   { "pmevcntr5_el0",     CPENC(3,3,C14,C8, 5),	0 },
   2984  1.1  christos   { "pmevcntr6_el0",     CPENC(3,3,C14,C8, 6),	0 },
   2985  1.1  christos   { "pmevcntr7_el0",     CPENC(3,3,C14,C8, 7),	0 },
   2986  1.1  christos   { "pmevcntr8_el0",     CPENC(3,3,C14,C9, 0),	0 },
   2987  1.1  christos   { "pmevcntr9_el0",     CPENC(3,3,C14,C9, 1),	0 },
   2988  1.1  christos   { "pmevcntr10_el0",    CPENC(3,3,C14,C9, 2),	0 },
   2989  1.1  christos   { "pmevcntr11_el0",    CPENC(3,3,C14,C9, 3),	0 },
   2990  1.1  christos   { "pmevcntr12_el0",    CPENC(3,3,C14,C9, 4),	0 },
   2991  1.1  christos   { "pmevcntr13_el0",    CPENC(3,3,C14,C9, 5),	0 },
   2992  1.1  christos   { "pmevcntr14_el0",    CPENC(3,3,C14,C9, 6),	0 },
   2993  1.1  christos   { "pmevcntr15_el0",    CPENC(3,3,C14,C9, 7),	0 },
   2994  1.1  christos   { "pmevcntr16_el0",    CPENC(3,3,C14,C10,0),	0 },
   2995  1.1  christos   { "pmevcntr17_el0",    CPENC(3,3,C14,C10,1),	0 },
   2996  1.1  christos   { "pmevcntr18_el0",    CPENC(3,3,C14,C10,2),	0 },
   2997  1.1  christos   { "pmevcntr19_el0",    CPENC(3,3,C14,C10,3),	0 },
   2998  1.1  christos   { "pmevcntr20_el0",    CPENC(3,3,C14,C10,4),	0 },
   2999  1.1  christos   { "pmevcntr21_el0",    CPENC(3,3,C14,C10,5),	0 },
   3000  1.1  christos   { "pmevcntr22_el0",    CPENC(3,3,C14,C10,6),	0 },
   3001  1.1  christos   { "pmevcntr23_el0",    CPENC(3,3,C14,C10,7),	0 },
   3002  1.1  christos   { "pmevcntr24_el0",    CPENC(3,3,C14,C11,0),	0 },
   3003  1.1  christos   { "pmevcntr25_el0",    CPENC(3,3,C14,C11,1),	0 },
   3004  1.1  christos   { "pmevcntr26_el0",    CPENC(3,3,C14,C11,2),	0 },
   3005  1.1  christos   { "pmevcntr27_el0",    CPENC(3,3,C14,C11,3),	0 },
   3006  1.1  christos   { "pmevcntr28_el0",    CPENC(3,3,C14,C11,4),	0 },
   3007  1.1  christos   { "pmevcntr29_el0",    CPENC(3,3,C14,C11,5),	0 },
   3008  1.1  christos   { "pmevcntr30_el0",    CPENC(3,3,C14,C11,6),	0 },
   3009  1.1  christos   { "pmevtyper0_el0",    CPENC(3,3,C14,C12,0),	0 },
   3010  1.1  christos   { "pmevtyper1_el0",    CPENC(3,3,C14,C12,1),	0 },
   3011  1.1  christos   { "pmevtyper2_el0",    CPENC(3,3,C14,C12,2),	0 },
   3012  1.1  christos   { "pmevtyper3_el0",    CPENC(3,3,C14,C12,3),	0 },
   3013  1.1  christos   { "pmevtyper4_el0",    CPENC(3,3,C14,C12,4),	0 },
   3014  1.1  christos   { "pmevtyper5_el0",    CPENC(3,3,C14,C12,5),	0 },
   3015  1.1  christos   { "pmevtyper6_el0",    CPENC(3,3,C14,C12,6),	0 },
   3016  1.1  christos   { "pmevtyper7_el0",    CPENC(3,3,C14,C12,7),	0 },
   3017  1.1  christos   { "pmevtyper8_el0",    CPENC(3,3,C14,C13,0),	0 },
   3018  1.1  christos   { "pmevtyper9_el0",    CPENC(3,3,C14,C13,1),	0 },
   3019  1.1  christos   { "pmevtyper10_el0",   CPENC(3,3,C14,C13,2),	0 },
   3020  1.1  christos   { "pmevtyper11_el0",   CPENC(3,3,C14,C13,3),	0 },
   3021  1.1  christos   { "pmevtyper12_el0",   CPENC(3,3,C14,C13,4),	0 },
   3022  1.1  christos   { "pmevtyper13_el0",   CPENC(3,3,C14,C13,5),	0 },
   3023  1.1  christos   { "pmevtyper14_el0",   CPENC(3,3,C14,C13,6),	0 },
   3024  1.1  christos   { "pmevtyper15_el0",   CPENC(3,3,C14,C13,7),	0 },
   3025  1.1  christos   { "pmevtyper16_el0",   CPENC(3,3,C14,C14,0),	0 },
   3026  1.1  christos   { "pmevtyper17_el0",   CPENC(3,3,C14,C14,1),	0 },
   3027  1.1  christos   { "pmevtyper18_el0",   CPENC(3,3,C14,C14,2),	0 },
   3028  1.1  christos   { "pmevtyper19_el0",   CPENC(3,3,C14,C14,3),	0 },
   3029  1.1  christos   { "pmevtyper20_el0",   CPENC(3,3,C14,C14,4),	0 },
   3030  1.1  christos   { "pmevtyper21_el0",   CPENC(3,3,C14,C14,5),	0 },
   3031  1.1  christos   { "pmevtyper22_el0",   CPENC(3,3,C14,C14,6),	0 },
   3032  1.1  christos   { "pmevtyper23_el0",   CPENC(3,3,C14,C14,7),	0 },
   3033  1.1  christos   { "pmevtyper24_el0",   CPENC(3,3,C14,C15,0),	0 },
   3034  1.1  christos   { "pmevtyper25_el0",   CPENC(3,3,C14,C15,1),	0 },
   3035  1.1  christos   { "pmevtyper26_el0",   CPENC(3,3,C14,C15,2),	0 },
   3036  1.1  christos   { "pmevtyper27_el0",   CPENC(3,3,C14,C15,3),	0 },
   3037  1.1  christos   { "pmevtyper28_el0",   CPENC(3,3,C14,C15,4),	0 },
   3038  1.1  christos   { "pmevtyper29_el0",   CPENC(3,3,C14,C15,5),	0 },
   3039  1.1  christos   { "pmevtyper30_el0",   CPENC(3,3,C14,C15,6),	0 },
   3040  1.1  christos   { "pmccfiltr_el0",     CPENC(3,3,C14,C15,7),	0 },
   3041  1.1  christos   { 0,          CPENC(0,0,0,0,0),	0 },
   3042  1.1  christos };
   3043  1.1  christos 
   3044  1.1  christos bfd_boolean
   3045  1.1  christos aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
   3046  1.1  christos {
   3047  1.1  christos   return (reg->flags & F_DEPRECATED) != 0;
   3048  1.1  christos }
   3049  1.1  christos 
   3050  1.1  christos const aarch64_sys_reg aarch64_pstatefields [] =
   3051  1.1  christos {
   3052  1.1  christos   { "spsel",            0x05,	0 },
   3053  1.1  christos   { "daifset",          0x1e,	0 },
   3054  1.1  christos   { "daifclr",          0x1f,	0 },
   3055  1.1  christos   { 0,          CPENC(0,0,0,0,0), 0 },
   3056  1.1  christos };
   3057  1.1  christos 
   3058  1.1  christos const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
   3059  1.1  christos {
   3060  1.1  christos     { "ialluis", CPENS(0,C7,C1,0), 0 },
   3061  1.1  christos     { "iallu",   CPENS(0,C7,C5,0), 0 },
   3062  1.1  christos     { "ivau",    CPENS(3,C7,C5,1), 1 },
   3063  1.1  christos     { 0, CPENS(0,0,0,0), 0 }
   3064  1.1  christos };
   3065  1.1  christos 
   3066  1.1  christos const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
   3067  1.1  christos {
   3068  1.1  christos     { "zva",        CPENS(3,C7,C4,1),  1 },
   3069  1.1  christos     { "ivac",       CPENS(0,C7,C6,1),  1 },
   3070  1.1  christos     { "isw",        CPENS(0,C7,C6,2),  1 },
   3071  1.1  christos     { "cvac",       CPENS(3,C7,C10,1), 1 },
   3072  1.1  christos     { "csw",        CPENS(0,C7,C10,2), 1 },
   3073  1.1  christos     { "cvau",       CPENS(3,C7,C11,1), 1 },
   3074  1.1  christos     { "civac",      CPENS(3,C7,C14,1), 1 },
   3075  1.1  christos     { "cisw",       CPENS(0,C7,C14,2), 1 },
   3076  1.1  christos     { 0,       CPENS(0,0,0,0), 0 }
   3077  1.1  christos };
   3078  1.1  christos 
   3079  1.1  christos const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
   3080  1.1  christos {
   3081  1.1  christos     { "s1e1r",      CPENS(0,C7,C8,0), 1 },
   3082  1.1  christos     { "s1e1w",      CPENS(0,C7,C8,1), 1 },
   3083  1.1  christos     { "s1e0r",      CPENS(0,C7,C8,2), 1 },
   3084  1.1  christos     { "s1e0w",      CPENS(0,C7,C8,3), 1 },
   3085  1.1  christos     { "s12e1r",     CPENS(4,C7,C8,4), 1 },
   3086  1.1  christos     { "s12e1w",     CPENS(4,C7,C8,5), 1 },
   3087  1.1  christos     { "s12e0r",     CPENS(4,C7,C8,6), 1 },
   3088  1.1  christos     { "s12e0w",     CPENS(4,C7,C8,7), 1 },
   3089  1.1  christos     { "s1e2r",      CPENS(4,C7,C8,0), 1 },
   3090  1.1  christos     { "s1e2w",      CPENS(4,C7,C8,1), 1 },
   3091  1.1  christos     { "s1e3r",      CPENS(6,C7,C8,0), 1 },
   3092  1.1  christos     { "s1e3w",      CPENS(6,C7,C8,1), 1 },
   3093  1.1  christos     { 0,       CPENS(0,0,0,0), 0 }
   3094  1.1  christos };
   3095  1.1  christos 
   3096  1.1  christos const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
   3097  1.1  christos {
   3098  1.1  christos     { "vmalle1",   CPENS(0,C8,C7,0), 0 },
   3099  1.1  christos     { "vae1",      CPENS(0,C8,C7,1), 1 },
   3100  1.1  christos     { "aside1",    CPENS(0,C8,C7,2), 1 },
   3101  1.1  christos     { "vaae1",     CPENS(0,C8,C7,3), 1 },
   3102  1.1  christos     { "vmalle1is", CPENS(0,C8,C3,0), 0 },
   3103  1.1  christos     { "vae1is",    CPENS(0,C8,C3,1), 1 },
   3104  1.1  christos     { "aside1is",  CPENS(0,C8,C3,2), 1 },
   3105  1.1  christos     { "vaae1is",   CPENS(0,C8,C3,3), 1 },
   3106  1.1  christos     { "ipas2e1is", CPENS(4,C8,C0,1), 1 },
   3107  1.1  christos     { "ipas2le1is",CPENS(4,C8,C0,5), 1 },
   3108  1.1  christos     { "ipas2e1",   CPENS(4,C8,C4,1), 1 },
   3109  1.1  christos     { "ipas2le1",  CPENS(4,C8,C4,5), 1 },
   3110  1.1  christos     { "vae2",      CPENS(4,C8,C7,1), 1 },
   3111  1.1  christos     { "vae2is",    CPENS(4,C8,C3,1), 1 },
   3112  1.1  christos     { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
   3113  1.1  christos     { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
   3114  1.1  christos     { "vae3",      CPENS(6,C8,C7,1), 1 },
   3115  1.1  christos     { "vae3is",    CPENS(6,C8,C3,1), 1 },
   3116  1.1  christos     { "alle2",     CPENS(4,C8,C7,0), 0 },
   3117  1.1  christos     { "alle2is",   CPENS(4,C8,C3,0), 0 },
   3118  1.1  christos     { "alle1",     CPENS(4,C8,C7,4), 0 },
   3119  1.1  christos     { "alle1is",   CPENS(4,C8,C3,4), 0 },
   3120  1.1  christos     { "alle3",     CPENS(6,C8,C7,0), 0 },
   3121  1.1  christos     { "alle3is",   CPENS(6,C8,C3,0), 0 },
   3122  1.1  christos     { "vale1is",   CPENS(0,C8,C3,5), 1 },
   3123  1.1  christos     { "vale2is",   CPENS(4,C8,C3,5), 1 },
   3124  1.1  christos     { "vale3is",   CPENS(6,C8,C3,5), 1 },
   3125  1.1  christos     { "vaale1is",  CPENS(0,C8,C3,7), 1 },
   3126  1.1  christos     { "vale1",     CPENS(0,C8,C7,5), 1 },
   3127  1.1  christos     { "vale2",     CPENS(4,C8,C7,5), 1 },
   3128  1.1  christos     { "vale3",     CPENS(6,C8,C7,5), 1 },
   3129  1.1  christos     { "vaale1",    CPENS(0,C8,C7,7), 1 },
   3130  1.1  christos     { 0,       CPENS(0,0,0,0), 0 }
   3131  1.1  christos };
   3132  1.1  christos 
   3133  1.1  christos #undef C0
   3134  1.1  christos #undef C1
   3135  1.1  christos #undef C2
   3136  1.1  christos #undef C3
   3137  1.1  christos #undef C4
   3138  1.1  christos #undef C5
   3139  1.1  christos #undef C6
   3140  1.1  christos #undef C7
   3141  1.1  christos #undef C8
   3142  1.1  christos #undef C9
   3143  1.1  christos #undef C10
   3144  1.1  christos #undef C11
   3145  1.1  christos #undef C12
   3146  1.1  christos #undef C13
   3147  1.1  christos #undef C14
   3148  1.1  christos #undef C15
   3149                
   3150                /* Include the opcode description table as well as the operand description
   3151                   table.  */
   3152                #include "aarch64-tbl.h"
   3153