Home | History | Annotate | Line # | Download | only in opcodes
aarch64-opc.c revision 1.10
      1   1.1  christos /* aarch64-opc.c -- AArch64 opcode support.
      2  1.10  christos    Copyright (C) 2009-2025 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by ARM Ltd.
      4   1.1  christos 
      5   1.1  christos    This file is part of the GNU opcodes library.
      6   1.1  christos 
      7   1.1  christos    This library is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     10   1.1  christos    any later version.
     11   1.1  christos 
     12   1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT
     13   1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14   1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15   1.1  christos    License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with this program; see the file COPYING3. If not,
     19   1.1  christos    see <http://www.gnu.org/licenses/>.  */
     20   1.1  christos 
     21   1.1  christos #include "sysdep.h"
     22   1.1  christos #include <assert.h>
     23   1.1  christos #include <stdlib.h>
     24   1.1  christos #include <stdio.h>
     25   1.8  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.6  christos #include "libiberty.h"
     31   1.1  christos 
     32   1.1  christos #include "aarch64-opc.h"
     33   1.1  christos 
     34   1.1  christos #ifdef DEBUG_AARCH64
     35   1.8  christos int debug_dump = false;
     36   1.1  christos #endif /* DEBUG_AARCH64 */
     37   1.1  christos 
     38   1.6  christos /* The enumeration strings associated with each value of a 5-bit SVE
     39   1.6  christos    pattern operand.  A null entry indicates a reserved meaning.  */
     40   1.6  christos const char *const aarch64_sve_pattern_array[32] = {
     41   1.6  christos   /* 0-7.  */
     42   1.6  christos   "pow2",
     43   1.6  christos   "vl1",
     44   1.6  christos   "vl2",
     45   1.6  christos   "vl3",
     46   1.6  christos   "vl4",
     47   1.6  christos   "vl5",
     48   1.6  christos   "vl6",
     49   1.6  christos   "vl7",
     50   1.6  christos   /* 8-15.  */
     51   1.6  christos   "vl8",
     52   1.6  christos   "vl16",
     53   1.6  christos   "vl32",
     54   1.6  christos   "vl64",
     55   1.6  christos   "vl128",
     56   1.6  christos   "vl256",
     57   1.6  christos   0,
     58   1.6  christos   0,
     59   1.6  christos   /* 16-23.  */
     60   1.6  christos   0,
     61   1.6  christos   0,
     62   1.6  christos   0,
     63   1.6  christos   0,
     64   1.6  christos   0,
     65   1.6  christos   0,
     66   1.6  christos   0,
     67   1.6  christos   0,
     68   1.6  christos   /* 24-31.  */
     69   1.6  christos   0,
     70   1.6  christos   0,
     71   1.6  christos   0,
     72   1.6  christos   0,
     73   1.6  christos   0,
     74   1.6  christos   "mul4",
     75   1.6  christos   "mul3",
     76   1.6  christos   "all"
     77   1.6  christos };
     78   1.6  christos 
     79   1.6  christos /* The enumeration strings associated with each value of a 4-bit SVE
     80   1.6  christos    prefetch operand.  A null entry indicates a reserved meaning.  */
     81   1.6  christos const char *const aarch64_sve_prfop_array[16] = {
     82   1.6  christos   /* 0-7.  */
     83   1.6  christos   "pldl1keep",
     84   1.6  christos   "pldl1strm",
     85   1.6  christos   "pldl2keep",
     86   1.6  christos   "pldl2strm",
     87   1.6  christos   "pldl3keep",
     88   1.6  christos   "pldl3strm",
     89   1.6  christos   0,
     90   1.6  christos   0,
     91   1.6  christos   /* 8-15.  */
     92   1.6  christos   "pstl1keep",
     93   1.6  christos   "pstl1strm",
     94   1.6  christos   "pstl2keep",
     95   1.6  christos   "pstl2strm",
     96   1.6  christos   "pstl3keep",
     97   1.6  christos   "pstl3strm",
     98   1.6  christos   0,
     99   1.6  christos   0
    100   1.6  christos };
    101   1.6  christos 
    102   1.9  christos /* The enumeration strings associated with each value of a 6-bit RPRFM
    103   1.9  christos    operation.  */
    104   1.9  christos const char *const aarch64_rprfmop_array[64] = {
    105   1.9  christos   "pldkeep",
    106   1.9  christos   "pstkeep",
    107   1.9  christos   0,
    108   1.9  christos   0,
    109   1.9  christos   "pldstrm",
    110   1.9  christos   "pststrm"
    111   1.9  christos };
    112   1.9  christos 
    113   1.9  christos /* Vector length multiples for a predicate-as-counter operand.  Used in things
    114   1.9  christos    like AARCH64_OPND_SME_VLxN_10.  */
    115   1.9  christos const char *const aarch64_sme_vlxn_array[2] = {
    116   1.9  christos   "vlx2",
    117   1.9  christos   "vlx4"
    118   1.9  christos };
    119   1.9  christos 
    120  1.10  christos /* Values accepted by the brb alias.  */
    121  1.10  christos const char *const aarch64_brbop_array[] = {
    122  1.10  christos   "iall",
    123  1.10  christos   "inj",
    124  1.10  christos };
    125  1.10  christos 
    126   1.1  christos /* Helper functions to determine which operand to be used to encode/decode
    127   1.1  christos    the size:Q fields for AdvSIMD instructions.  */
    128   1.1  christos 
    129   1.8  christos static inline bool
    130   1.1  christos vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
    131   1.1  christos {
    132   1.8  christos   return (qualifier >= AARCH64_OPND_QLF_V_8B
    133   1.8  christos 	  && qualifier <= AARCH64_OPND_QLF_V_1Q);
    134   1.1  christos }
    135   1.1  christos 
    136   1.8  christos static inline bool
    137   1.1  christos fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
    138   1.1  christos {
    139   1.8  christos   return (qualifier >= AARCH64_OPND_QLF_S_B
    140   1.8  christos 	  && qualifier <= AARCH64_OPND_QLF_S_Q);
    141   1.1  christos }
    142   1.1  christos 
    143   1.1  christos enum data_pattern
    144   1.1  christos {
    145   1.1  christos   DP_UNKNOWN,
    146   1.1  christos   DP_VECTOR_3SAME,
    147   1.1  christos   DP_VECTOR_LONG,
    148   1.1  christos   DP_VECTOR_WIDE,
    149   1.1  christos   DP_VECTOR_ACROSS_LANES,
    150   1.1  christos };
    151   1.1  christos 
    152   1.1  christos static const char significant_operand_index [] =
    153   1.1  christos {
    154   1.1  christos   0,	/* DP_UNKNOWN, by default using operand 0.  */
    155   1.1  christos   0,	/* DP_VECTOR_3SAME */
    156   1.1  christos   1,	/* DP_VECTOR_LONG */
    157   1.1  christos   2,	/* DP_VECTOR_WIDE */
    158   1.1  christos   1,	/* DP_VECTOR_ACROSS_LANES */
    159   1.1  christos };
    160   1.1  christos 
    161   1.1  christos /* Given a sequence of qualifiers in QUALIFIERS, determine and return
    162   1.1  christos    the data pattern.
    163   1.1  christos    N.B. QUALIFIERS is a possible sequence of qualifiers each of which
    164   1.1  christos    corresponds to one of a sequence of operands.  */
    165   1.1  christos 
    166   1.1  christos static enum data_pattern
    167   1.1  christos get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
    168   1.1  christos {
    169   1.8  christos   if (vector_qualifier_p (qualifiers[0]))
    170   1.1  christos     {
    171   1.1  christos       /* e.g. v.4s, v.4s, v.4s
    172   1.1  christos 	   or v.4h, v.4h, v.h[3].  */
    173   1.1  christos       if (qualifiers[0] == qualifiers[1]
    174   1.8  christos 	  && vector_qualifier_p (qualifiers[2])
    175   1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    176   1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1]))
    177   1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    178   1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[2])))
    179   1.1  christos 	return DP_VECTOR_3SAME;
    180   1.1  christos       /* e.g. v.8h, v.8b, v.8b.
    181   1.1  christos            or v.4s, v.4h, v.h[2].
    182   1.1  christos 	   or v.8h, v.16b.  */
    183   1.8  christos       if (vector_qualifier_p (qualifiers[1])
    184   1.1  christos 	  && aarch64_get_qualifier_esize (qualifiers[0]) != 0
    185   1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    186   1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
    187   1.1  christos 	return DP_VECTOR_LONG;
    188   1.1  christos       /* e.g. v.8h, v.8h, v.8b.  */
    189   1.1  christos       if (qualifiers[0] == qualifiers[1]
    190   1.8  christos 	  && vector_qualifier_p (qualifiers[2])
    191   1.1  christos 	  && aarch64_get_qualifier_esize (qualifiers[0]) != 0
    192   1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    193   1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
    194   1.1  christos 	  && (aarch64_get_qualifier_esize (qualifiers[0])
    195   1.1  christos 	      == aarch64_get_qualifier_esize (qualifiers[1])))
    196   1.1  christos 	return DP_VECTOR_WIDE;
    197   1.1  christos     }
    198   1.8  christos   else if (fp_qualifier_p (qualifiers[0]))
    199   1.1  christos     {
    200   1.1  christos       /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
    201   1.8  christos       if (vector_qualifier_p (qualifiers[1])
    202   1.1  christos 	  && qualifiers[2] == AARCH64_OPND_QLF_NIL)
    203   1.1  christos 	return DP_VECTOR_ACROSS_LANES;
    204   1.1  christos     }
    205   1.1  christos 
    206   1.1  christos   return DP_UNKNOWN;
    207   1.1  christos }
    208   1.1  christos 
    209   1.1  christos /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
    210   1.1  christos    the AdvSIMD instructions.  */
    211   1.1  christos /* N.B. it is possible to do some optimization that doesn't call
    212   1.1  christos    get_data_pattern each time when we need to select an operand.  We can
    213   1.1  christos    either buffer the caculated the result or statically generate the data,
    214   1.1  christos    however, it is not obvious that the optimization will bring significant
    215   1.1  christos    benefit.  */
    216   1.1  christos 
    217   1.1  christos int
    218   1.1  christos aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
    219   1.1  christos {
    220   1.1  christos   return
    221   1.1  christos     significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
    222   1.1  christos }
    223   1.1  christos 
    224   1.8  christos /* Instruction bit-fields.
    226   1.1  christos +   Keep synced with 'enum aarch64_field_kind'.  */
    227   1.1  christos const aarch64_field fields[] =
    228   1.1  christos {
    229   1.9  christos     {  0,  0 },	/* NIL.  */
    230   1.9  christos     {  8,  4 },	/* CRm: in the system instructions.  */
    231   1.9  christos     { 10,  2 }, /* CRm_dsb_nxs: 2-bit imm. encoded in CRm<3:2>.  */
    232   1.9  christos     { 12,  4 },	/* CRn: in the system instructions.  */
    233   1.9  christos     { 10,  8 }, /* CSSC_imm8.  */
    234   1.9  christos     { 11,  1 },	/* H: in advsimd scalar x indexed element instructions.  */
    235   1.9  christos     { 21,  1 },	/* L: in advsimd scalar x indexed element instructions.  */
    236   1.9  christos     {  0,  5 },	/* LSE128_Rt: Shared input+output operand register.  */
    237   1.9  christos     { 16,  5 },	/* LSE128_Rt2: Shared input+output operand register 2.  */
    238   1.9  christos     { 20,  1 },	/* M: in advsimd scalar x indexed element instructions.  */
    239   1.1  christos     { 22,  1 },	/* N: in logical (immediate) instructions.  */
    240   1.9  christos     { 30,  1 },	/* Q: in most AdvSIMD instructions.  */
    241   1.1  christos     { 10,  5 },	/* Ra: in fp instructions.  */
    242   1.9  christos     {  0,  5 },	/* Rd: in many integer instructions.  */
    243   1.1  christos     { 16,  5 },	/* Rm: in ld/st reg offset and some integer inst.  */
    244   1.9  christos     {  5,  5 },	/* Rn: in many integer instructions.  */
    245   1.9  christos     { 16,  5 },	/* Rs: in load/store exclusive instructions.  */
    246   1.1  christos     {  0,  5 },	/* Rt: in load/store instructions.  */
    247   1.1  christos     { 10,  5 },	/* Rt2: in load/store pair instructions.  */
    248   1.9  christos     { 12,  1 },	/* S: in load/store reg offset instructions.  */
    249   1.9  christos     { 12,  2 }, /* SM3_imm2: Indexed element SM3 2 bits index immediate.  */
    250   1.9  christos     {  1,  3 }, /* SME_Pdx2: predicate register, multiple of 2, [3:1].  */
    251   1.9  christos     { 13,  3 }, /* SME_Pm: second source scalable predicate register P0-P7.  */
    252   1.9  christos     {  0,  3 }, /* SME_PNd3: PN0-PN7, bits [2:0].  */
    253   1.9  christos     {  5,  3 }, /* SME_PNn3: PN0-PN7, bits [7:5].  */
    254   1.9  christos     { 16,  1 }, /* SME_Q: Q class bit, bit 16.  */
    255   1.9  christos     { 16,  2 }, /* SME_Rm: index base register W12-W15 [17:16].  */
    256   1.9  christos     { 13,  2 }, /* SME_Rv: vector select register W12-W15, bits [14:13].  */
    257   1.9  christos     { 15,  1 }, /* SME_V: (horizontal / vertical tiles), bit 15.  */
    258   1.9  christos     { 10,  1 }, /* SME_VL_10: VLx2 or VLx4, bit [10].  */
    259  1.10  christos     { 13,  1 }, /* SME_VL_13: VLx2 or VLx4, bit [13].  */
    260   1.9  christos     {  0,  1 }, /* SME_ZAda_1b: tile ZA0-ZA1.  */
    261   1.9  christos     {  0,  2 }, /* SME_ZAda_2b: tile ZA0-ZA3.  */
    262   1.9  christos     {  0,  3 }, /* SME_ZAda_3b: tile ZA0-ZA7.  */
    263   1.9  christos     {  1,  4 }, /* SME_Zdn2: Z0-Z31, multiple of 2, bits [4:1].  */
    264   1.9  christos     {  2,  3 }, /* SME_Zdn4: Z0-Z31, multiple of 4, bits [4:2].  */
    265   1.9  christos     { 16,  4 }, /* SME_Zm: Z0-Z15, bits [19:16].  */
    266   1.9  christos     { 17,  4 }, /* SME_Zm2: Z0-Z31, multiple of 2, bits [20:17].  */
    267   1.9  christos     { 18,  3 }, /* SME_Zm4: Z0-Z31, multiple of 4, bits [20:18].  */
    268   1.9  christos     {  6,  4 }, /* SME_Zn2: Z0-Z31, multiple of 2, bits [9:6].  */
    269   1.9  christos     {  7,  3 }, /* SME_Zn4: Z0-Z31, multiple of 4, bits [9:7].  */
    270   1.9  christos     {  4,  1 }, /* SME_ZtT: upper bit of Zt, bit [4].  */
    271   1.9  christos     {  0,  3 }, /* SME_Zt3: lower 3 bits of Zt, bits [2:0].  */
    272   1.9  christos     {  0,  2 }, /* SME_Zt2: lower 2 bits of Zt, bits [1:0].  */
    273   1.9  christos     { 23,  1 }, /* SME_i1: immediate field, bit 23.  */
    274   1.9  christos     { 12,  2 }, /* SME_size_12: bits [13:12].  */
    275   1.9  christos     { 22,  2 }, /* SME_size_22: size<1>, size<0> class field, [23:22].  */
    276   1.9  christos     { 23,  1 }, /* SME_sz_23: bit [23].  */
    277   1.9  christos     { 22,  1 }, /* SME_tszh: immediate and qualifier field, bit 22.  */
    278   1.9  christos     { 18,  3 }, /* SME_tszl: immediate and qualifier field, bits [20:18].  */
    279   1.6  christos     { 0,   8 }, /* SME_zero_mask: list of up to 8 tile names separated by commas [7:0].  */
    280   1.6  christos     {  4,  1 }, /* SVE_M_4: Merge/zero select, bit 4.  */
    281   1.6  christos     { 14,  1 }, /* SVE_M_14: Merge/zero select, bit 14.  */
    282   1.6  christos     { 16,  1 }, /* SVE_M_16: Merge/zero select, bit 16.  */
    283   1.6  christos     { 17,  1 }, /* SVE_N: SVE equivalent of N.  */
    284   1.6  christos     {  0,  4 }, /* SVE_Pd: p0-p15, bits [3,0].  */
    285   1.6  christos     { 10,  3 }, /* SVE_Pg3: p0-p7, bits [12,10].  */
    286   1.6  christos     {  5,  4 }, /* SVE_Pg4_5: p0-p15, bits [8,5].  */
    287   1.6  christos     { 10,  4 }, /* SVE_Pg4_10: p0-p15, bits [13,10].  */
    288   1.6  christos     { 16,  4 }, /* SVE_Pg4_16: p0-p15, bits [19,16].  */
    289   1.6  christos     { 16,  4 }, /* SVE_Pm: p0-p15, bits [19,16].  */
    290   1.6  christos     {  5,  4 }, /* SVE_Pn: p0-p15, bits [8,5].  */
    291   1.6  christos     {  0,  4 }, /* SVE_Pt: p0-p15, bits [3,0].  */
    292   1.6  christos     {  5,  5 }, /* SVE_Rm: SVE alternative position for Rm.  */
    293   1.6  christos     { 16,  5 }, /* SVE_Rn: SVE alternative position for Rn.  */
    294   1.6  christos     {  0,  5 }, /* SVE_Vd: Scalar SIMD&FP register, bits [4,0].  */
    295   1.6  christos     {  5,  5 }, /* SVE_Vm: Scalar SIMD&FP register, bits [9,5].  */
    296   1.6  christos     {  5,  5 }, /* SVE_Vn: Scalar SIMD&FP register, bits [9,5].  */
    297   1.6  christos     {  5,  5 }, /* SVE_Za_5: SVE vector register, bits [9,5].  */
    298   1.6  christos     { 16,  5 }, /* SVE_Za_16: SVE vector register, bits [20,16].  */
    299   1.6  christos     {  0,  5 }, /* SVE_Zd: SVE vector register. bits [4,0].  */
    300   1.6  christos     {  5,  5 }, /* SVE_Zm_5: SVE vector register, bits [9,5].  */
    301   1.6  christos     { 16,  5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
    302   1.6  christos     {  5,  5 }, /* SVE_Zn: SVE vector register, bits [9,5].  */
    303   1.6  christos     {  0,  5 }, /* SVE_Zt: SVE vector register, bits [4,0].  */
    304  1.10  christos     {  5,  1 }, /* SVE_i1: single-bit immediate.  */
    305  1.10  christos     { 23,  1 }, /* SVE_i1_23: single-bit immediate.  */
    306   1.9  christos     { 22,  2 }, /* SVE_i2: 2-bit index, bits [23,22].  */
    307   1.6  christos     { 20,  1 }, /* SVE_i2h: high bit of 2bit immediate, bits.  */
    308   1.9  christos     { 22,  1 }, /* SVE_i3h: high bit of 3-bit immediate.  */
    309  1.10  christos     { 19,  2 }, /* SVE_i3h2: two high bits of 3bit immediate, bits [20,19].  */
    310   1.7  christos     { 22,  2 }, /* SVE_i3h3: two high bits of 3bit immediate, bits [22,23].  */
    311  1.10  christos     { 11,  1 }, /* SVE_i3l: low bit of 3-bit immediate.  */
    312  1.10  christos     { 12,  1 }, /* SVE_i3l2: low bit of 3-bit immediate, bit 12.  */
    313   1.6  christos     { 10,  2 }, /* SVE_i4l2: two low bits of 4bit immediate, bits [11,10].  */
    314   1.6  christos     { 16,  3 }, /* SVE_imm3: 3-bit immediate field.  */
    315   1.6  christos     { 16,  4 }, /* SVE_imm4: 4-bit immediate field.  */
    316   1.6  christos     {  5,  5 }, /* SVE_imm5: 5-bit immediate field.  */
    317   1.6  christos     { 16,  5 }, /* SVE_imm5b: secondary 5-bit immediate field.  */
    318   1.6  christos     { 16,  6 }, /* SVE_imm6: 6-bit immediate field.  */
    319   1.6  christos     { 14,  7 }, /* SVE_imm7: 7-bit immediate field.  */
    320   1.6  christos     {  5,  8 }, /* SVE_imm8: 8-bit immediate field.  */
    321   1.6  christos     {  5,  9 }, /* SVE_imm9: 9-bit immediate field.  */
    322   1.6  christos     { 11,  6 }, /* SVE_immr: SVE equivalent of immr.  */
    323   1.6  christos     {  5,  6 }, /* SVE_imms: SVE equivalent of imms.  */
    324   1.6  christos     { 10,  2 }, /* SVE_msz: 2-bit shift amount for ADR.  */
    325   1.6  christos     {  5,  5 }, /* SVE_pattern: vector pattern enumeration.  */
    326   1.6  christos     {  0,  4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD].  */
    327   1.6  christos     { 16,  1 }, /* SVE_rot1: 1-bit rotation amount.  */
    328   1.7  christos     { 10,  2 }, /* SVE_rot2: 2-bit rotation amount.  */
    329   1.9  christos     { 10,  1 }, /* SVE_rot3: 1-bit rotation amount at bit 10.  */
    330   1.6  christos     { 17,  2 }, /* SVE_size: 2-bit element size, bits [18,17].  */
    331   1.7  christos     { 22,  1 }, /* SVE_sz: 1-bit element size select.  */
    332  1.10  christos     { 30,  1 }, /* SVE_sz2: 1-bit element size select.  */
    333  1.10  christos     { 17,  1 }, /* SVE_sz3: 1-bit element size select.  */
    334   1.6  christos     { 14,  1 }, /* SVE_sz4: 1-bit element size select.  */
    335   1.6  christos     { 16,  4 }, /* SVE_tsz: triangular size select.  */
    336   1.6  christos     { 22,  2 }, /* SVE_tszh: triangular size select high, bits [23,22].  */
    337   1.6  christos     {  8,  2 }, /* SVE_tszl_8: triangular size select low, bits [9,8].  */
    338   1.6  christos     { 19,  2 }, /* SVE_tszl_19: triangular size select low, bits [20,19].  */
    339   1.6  christos     { 14,  1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14).  */
    340   1.9  christos     { 22,  1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22).  */
    341   1.9  christos     { 22,  1 },	/* S_imm10: in LDRAA and LDRAB instructions.  */
    342   1.9  christos     { 16,  3 },	/* abc: a:b:c bits in AdvSIMD modified immediate.  */
    343   1.9  christos     { 13,  3 },	/* asisdlso_opcode: opcode in advsimd ld/st single element.  */
    344   1.9  christos     { 19,  5 },	/* b40: in the test bit and branch instructions.  */
    345   1.9  christos     { 31,  1 },	/* b5: in the test bit and branch instructions.  */
    346   1.9  christos     { 12,  4 },	/* cmode: in advsimd modified immediate instructions.  */
    347   1.9  christos     { 12,  4 },	/* cond: condition flags as a source operand.  */
    348   1.9  christos     {  0,  4 },	/* cond2: condition in truly conditional-executed inst.  */
    349   1.9  christos     {  5,  5 },	/* defgh: d:e:f:g:h bits in AdvSIMD modified immediate.  */
    350   1.9  christos     { 21,  2 },	/* hw: in move wide constant instructions.  */
    351   1.9  christos     {  0,  1 },	/* imm1_0: general immediate in bits [0].  */
    352  1.10  christos     {  2,  1 },	/* imm1_2: general immediate in bits [2].  */
    353   1.9  christos     {  3,  1 },	/* imm1_3: general immediate in bits [3].  */
    354   1.9  christos     {  8,  1 },	/* imm1_8: general immediate in bits [8].  */
    355  1.10  christos     { 10,  1 },	/* imm1_10: general immediate in bits [10].  */
    356   1.9  christos     { 14,  1 },	/* imm1_14: general immediate in bits [14].  */
    357   1.9  christos     { 15,  1 },	/* imm1_15: general immediate in bits [15].  */
    358   1.9  christos     { 16,  1 },	/* imm1_16: general immediate in bits [16].  */
    359   1.9  christos     {  0,  2 },	/* imm2_0: general immediate in bits [1:0].  */
    360  1.10  christos     {  1,  2 },	/* imm2_1: general immediate in bits [2:1].  */
    361   1.9  christos     {  2,  2 },	/* imm2_2: general immediate in bits [3:2].  */
    362   1.9  christos     {  8,  2 },	/* imm2_8: general immediate in bits [9:8].  */
    363   1.9  christos     { 10,  2 }, /* imm2_10: 2-bit immediate, bits [11:10] */
    364  1.10  christos     { 12,  2 }, /* imm2_12: 2-bit immediate, bits [13:12] */
    365   1.9  christos     { 13,  2 }, /* imm2_13: 2-bit immediate, bits [14:13] */
    366   1.9  christos     { 15,  2 }, /* imm2_15: 2-bit immediate, bits [16:15] */
    367   1.9  christos     { 16,  2 }, /* imm2_16: 2-bit immediate, bits [17:16] */
    368   1.9  christos     { 19,  2 }, /* imm2_19: 2-bit immediate, bits [20:19] */
    369   1.9  christos     {  0,  3 },	/* imm3_0: general immediate in bits [2:0].  */
    370   1.9  christos     {  5,  3 },	/* imm3_5: general immediate in bits [7:5].  */
    371   1.9  christos     { 10,  3 },	/* imm3_10: in add/sub extended reg instructions.  */
    372   1.9  christos     { 12,  3 },	/* imm3_12: general immediate in bits [14:12].  */
    373   1.9  christos     { 14,  3 },	/* imm3_14: general immediate in bits [16:14].  */
    374  1.10  christos     { 15,  3 },	/* imm3_15: general immediate in bits [17:15].  */
    375   1.9  christos     { 19,  3 },	/* imm3_19: general immediate in bits [21:19].  */
    376   1.9  christos     {  0,  4 },	/* imm4_0: in rmif instructions.  */
    377   1.9  christos     {  5,  4 }, /* imm4_5: in SME instructions.  */
    378   1.9  christos     { 10,  4 },	/* imm4_10: in adddg/subg instructions.  */
    379   1.9  christos     { 11,  4 },	/* imm4_11: in advsimd ext and advsimd ins instructions.  */
    380   1.9  christos     { 14,  4 },	/* imm4_14: general immediate in bits [17:14].  */
    381   1.9  christos     { 16,  5 },	/* imm5: in conditional compare (immediate) instructions.  */
    382   1.9  christos     { 10,  6 },	/* imm6_10: in add/sub reg shifted instructions.  */
    383   1.9  christos     { 15,  6 },	/* imm6_15: in rmif instructions.  */
    384   1.9  christos     { 15,  7 },	/* imm7: in load/store pair pre/post index instructions.  */
    385   1.9  christos     { 13,  8 },	/* imm8: in floating-point scalar move immediate inst.  */
    386  1.10  christos     { 12,  9 },	/* imm9: in load/store pre/post index instructions.  */
    387   1.9  christos     {  5,  9 },	/* imm9_5: in CB<cc> (immediate).  */
    388   1.9  christos     { 10, 12 },	/* imm12: in ld/st unsigned imm or add/sub shifted inst.  */
    389   1.9  christos     {  5, 14 },	/* imm14: in test bit and branch instructions.  */
    390   1.9  christos     {  0, 16 },	/* imm16_0: in udf instruction. */
    391  1.10  christos     {  5, 16 },	/* imm16_5: in exception instructions.  */
    392  1.10  christos     { 17,  1 }, /* imm17_1: in 1 bit element index.  */
    393   1.9  christos     { 17,  2 }, /* imm17_2: in 2 bits element index.  */
    394   1.9  christos     {  5, 19 },	/* imm19: e.g. in CBZ.  */
    395   1.9  christos     {  0, 26 },	/* imm26: in unconditional branch instructions.  */
    396   1.9  christos     { 16,  3 },	/* immb: in advsimd shift by immediate instructions.  */
    397   1.9  christos     { 19,  4 },	/* immh: in advsimd shift by immediate instructions.  */
    398   1.9  christos     {  5, 19 },	/* immhi: e.g. in ADRP.  */
    399   1.9  christos     { 29,  2 },	/* immlo: e.g. in ADRP.  */
    400   1.9  christos     { 16,  6 },	/* immr: in bitfield and logical immediate instructions.  */
    401   1.9  christos     { 10,  6 },	/* imms: in bitfield and logical immediate instructions.  */
    402   1.9  christos     { 11,  1 },	/* index: in ld/st inst deciding the pre/post-index.  */
    403   1.9  christos     { 24,  1 },	/* index2: in ld/st pair inst deciding the pre/post-index.  */
    404   1.9  christos     { 30,  2 },	/* ldst_size: size field in ld/st reg offset inst.  */
    405   1.9  christos     { 13,  2 },	/* len: in advsimd tbl/tbx instructions.  */
    406   1.9  christos     { 30,  1 },	/* lse_sz: in LSE extension atomic instructions.  */
    407   1.9  christos     {  0,  4 },	/* nzcv: flag bit specifier, encoded in the "nzcv" field.  */
    408   1.9  christos     { 29,  1 },	/* op: in AdvSIMD modified immediate instructions.  */
    409   1.9  christos     { 19,  2 },	/* op0: in the system instructions.  */
    410   1.9  christos     { 16,  3 },	/* op1: in the system instructions.  */
    411   1.9  christos     {  5,  3 },	/* op2: in the system instructions.  */
    412   1.9  christos     { 22,  2 },	/* opc: in load/store reg offset instructions.  */
    413   1.9  christos     { 23,  1 },	/* opc1: in load/store reg offset instructions.  */
    414   1.9  christos     { 12,  4 },	/* opcode: in advsimd load/store instructions.  */
    415   1.6  christos     { 13,  3 },	/* option: in ld/st reg offset + add/sub extended reg inst.  */
    416   1.6  christos     { 11,  2 }, /* rotate1: FCMLA immediate rotate.  */
    417   1.6  christos     { 13,  2 }, /* rotate2: Indexed element FCMLA immediate rotate.  */
    418   1.9  christos     { 12,  1 }, /* rotate3: FCADD immediate rotate.  */
    419   1.9  christos     { 10,  6 },	/* scale: in the fixed-point scalar to fp converting inst.  */
    420   1.9  christos     { 31,  1 },	/* sf: in integer data processing instructions.  */
    421   1.9  christos     { 22,  2 },	/* shift: in add/sub reg/imm shifted instructions.  */
    422   1.7  christos     { 22,  2 },	/* size: in most AdvSIMD and floating-point instructions.  */
    423   1.9  christos     { 22,  1 }, /* sz: 1-bit element size select.  */
    424   1.9  christos     { 22,  2 },	/* type: floating point type field in fp data inst.  */
    425   1.9  christos     { 10,  2 },	/* vldst_size: size field in the AdvSIMD load/store inst.  */
    426   1.9  christos     {  5,  3 }, /* off3: immediate offset used to calculate slice number in a
    427   1.9  christos 		   ZA tile.  */
    428   1.9  christos     {  5,  2 }, /* off2: immediate offset used to calculate slice number in
    429   1.9  christos 		   a ZA tile.  */
    430   1.9  christos     {  7,  1 }, /* ZAn_1: name of the 1bit encoded ZA tile.  */
    431   1.9  christos     {  5,  1 }, /* ol: immediate offset used to calculate slice number in a ZA
    432   1.9  christos 		   tile.  */
    433   1.9  christos     {  6,  2 }, /* ZAn_2: name of the 2bit encoded ZA tile.  */
    434   1.9  christos     {  5,  3 }, /* ZAn_3: name of the 3bit encoded ZA tile.  */
    435   1.9  christos     {  6,  1 }, /* ZAn: name of the bit encoded ZA tile.  */
    436   1.9  christos     { 12,  4 },	/* opc2: in rcpc3 ld/st inst deciding the pre/post-index.  */
    437  1.10  christos     { 30,  2 },	/* rcpc3_size: in rcpc3 ld/st, field controls Rt/Rt2 width.  */
    438  1.10  christos     {  5,  1 },	/* FLD_brbop: used in BRB to mean IALL or INJ.  */
    439  1.10  christos     {  8,  1 }, /* ZA8_1: name of the 1 bit encoded ZA tile ZA0-ZA1.  */
    440  1.10  christos     {  7,  2 }, /* ZA7_2: name of the 2 bits encoded ZA tile ZA0-ZA3.  */
    441  1.10  christos     {  6,  3 }, /* ZA6_3: name of the 3 bits encoded ZA tile ZA0-ZA7.  */
    442   1.1  christos     {  5,  4 }, /* ZA5_4: name of the 4 bits encoded ZA tile ZA0-ZA15.  */
    443   1.1  christos };
    444   1.1  christos 
    445   1.1  christos enum aarch64_operand_class
    446   1.1  christos aarch64_get_operand_class (enum aarch64_opnd type)
    447   1.1  christos {
    448   1.1  christos   return aarch64_operands[type].op_class;
    449   1.1  christos }
    450   1.3  christos 
    451   1.1  christos const char *
    452   1.1  christos aarch64_get_operand_name (enum aarch64_opnd type)
    453   1.1  christos {
    454   1.1  christos   return aarch64_operands[type].name;
    455   1.1  christos }
    456   1.1  christos 
    457   1.1  christos /* Get operand description string.
    458   1.3  christos    This is usually for the diagnosis purpose.  */
    459   1.1  christos const char *
    460   1.1  christos aarch64_get_operand_desc (enum aarch64_opnd type)
    461   1.1  christos {
    462   1.1  christos   return aarch64_operands[type].desc;
    463   1.1  christos }
    464   1.1  christos 
    465   1.1  christos /* Table of all conditional affixes.  */
    466   1.1  christos const aarch64_cond aarch64_conds[16] =
    467   1.6  christos {
    468   1.6  christos   {{"eq", "none"}, 0x0},
    469   1.6  christos   {{"ne", "any"}, 0x1},
    470   1.6  christos   {{"cs", "hs", "nlast"}, 0x2},
    471   1.6  christos   {{"cc", "lo", "ul", "last"}, 0x3},
    472   1.6  christos   {{"mi", "first"}, 0x4},
    473   1.1  christos   {{"pl", "nfrst"}, 0x5},
    474   1.1  christos   {{"vs"}, 0x6},
    475   1.6  christos   {{"vc"}, 0x7},
    476   1.6  christos   {{"hi", "pmore"}, 0x8},
    477   1.6  christos   {{"ls", "plast"}, 0x9},
    478   1.6  christos   {{"ge", "tcont"}, 0xa},
    479   1.1  christos   {{"lt", "tstop"}, 0xb},
    480   1.1  christos   {{"gt"}, 0xc},
    481   1.1  christos   {{"le"}, 0xd},
    482   1.1  christos   {{"al"}, 0xe},
    483   1.1  christos   {{"nv"}, 0xf},
    484   1.1  christos };
    485   1.3  christos 
    486   1.1  christos const aarch64_cond *
    487   1.1  christos get_cond_from_value (aarch64_insn value)
    488   1.1  christos {
    489   1.1  christos   assert (value < 16);
    490   1.1  christos   return &aarch64_conds[(unsigned int) value];
    491   1.1  christos }
    492   1.3  christos 
    493   1.1  christos const aarch64_cond *
    494   1.1  christos get_inverted_cond (const aarch64_cond *cond)
    495   1.1  christos {
    496   1.1  christos   return &aarch64_conds[cond->value ^ 0x1];
    497   1.1  christos }
    498   1.1  christos 
    499   1.1  christos /* Table describing the operand extension/shifting operators; indexed by
    500   1.1  christos    enum aarch64_modifier_kind.
    501   1.1  christos 
    502   1.1  christos    The value column provides the most common values for encoding modifiers,
    503   1.1  christos    which enables table-driven encoding/decoding for the modifiers.  */
    504   1.1  christos const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
    505   1.1  christos {
    506   1.1  christos     {"none", 0x0},
    507   1.1  christos     {"msl",  0x0},
    508   1.1  christos     {"ror",  0x3},
    509   1.1  christos     {"asr",  0x2},
    510   1.1  christos     {"lsr",  0x1},
    511   1.1  christos     {"lsl",  0x0},
    512   1.1  christos     {"uxtb", 0x0},
    513   1.1  christos     {"uxth", 0x1},
    514   1.1  christos     {"uxtw", 0x2},
    515   1.1  christos     {"uxtx", 0x3},
    516   1.1  christos     {"sxtb", 0x4},
    517   1.1  christos     {"sxth", 0x5},
    518   1.1  christos     {"sxtw", 0x6},
    519   1.6  christos     {"sxtx", 0x7},
    520   1.6  christos     {"mul", 0x0},
    521   1.1  christos     {"mul vl", 0x0},
    522   1.1  christos     {NULL, 0},
    523   1.1  christos };
    524   1.1  christos 
    525   1.1  christos enum aarch64_modifier_kind
    526   1.1  christos aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
    527   1.1  christos {
    528   1.1  christos   return desc - aarch64_operand_modifiers;
    529   1.1  christos }
    530   1.1  christos 
    531   1.1  christos aarch64_insn
    532   1.1  christos aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
    533   1.1  christos {
    534   1.1  christos   return aarch64_operand_modifiers[kind].value;
    535   1.1  christos }
    536   1.1  christos 
    537   1.1  christos enum aarch64_modifier_kind
    538   1.8  christos aarch64_get_operand_modifier_from_value (aarch64_insn value,
    539   1.1  christos 					 bool extend_p)
    540   1.8  christos {
    541   1.1  christos   if (extend_p)
    542   1.1  christos     return AARCH64_MOD_UXTB + value;
    543   1.1  christos   else
    544   1.1  christos     return AARCH64_MOD_LSL - value;
    545   1.1  christos }
    546   1.8  christos 
    547   1.1  christos bool
    548   1.1  christos aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
    549   1.8  christos {
    550   1.1  christos   return kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX;
    551   1.1  christos }
    552   1.8  christos 
    553   1.1  christos static inline bool
    554   1.1  christos aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
    555   1.8  christos {
    556   1.1  christos   return kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL;
    557   1.1  christos }
    558   1.1  christos 
    559   1.1  christos const struct aarch64_name_value_pair aarch64_barrier_options[16] =
    560   1.1  christos {
    561   1.1  christos     { "#0x00", 0x0 },
    562   1.1  christos     { "oshld", 0x1 },
    563   1.1  christos     { "oshst", 0x2 },
    564   1.1  christos     { "osh",   0x3 },
    565   1.1  christos     { "#0x04", 0x4 },
    566   1.1  christos     { "nshld", 0x5 },
    567   1.1  christos     { "nshst", 0x6 },
    568   1.1  christos     { "nsh",   0x7 },
    569   1.1  christos     { "#0x08", 0x8 },
    570   1.1  christos     { "ishld", 0x9 },
    571   1.1  christos     { "ishst", 0xa },
    572   1.1  christos     { "ish",   0xb },
    573   1.1  christos     { "#0x0c", 0xc },
    574   1.1  christos     { "ld",    0xd },
    575   1.1  christos     { "st",    0xe },
    576   1.1  christos     { "sy",    0xf },
    577   1.1  christos };
    578   1.8  christos 
    579   1.8  christos const struct aarch64_name_value_pair aarch64_barrier_dsb_nxs_options[4] =
    580   1.8  christos {                       /*  CRm<3:2>  #imm  */
    581   1.8  christos     { "oshnxs", 16 },    /*    00       16   */
    582   1.8  christos     { "nshnxs", 20 },    /*    01       20   */
    583   1.8  christos     { "ishnxs", 24 },    /*    10       24   */
    584   1.8  christos     { "synxs",  28 },    /*    11       28   */
    585   1.8  christos };
    586   1.3  christos 
    587   1.3  christos /* Table describing the operands supported by the aliases of the HINT
    588   1.3  christos    instruction.
    589   1.3  christos 
    590   1.3  christos    The name column is the operand that is accepted for the alias.  The value
    591   1.3  christos    column is the hint number of the alias.  The list of operands is terminated
    592   1.3  christos    by NULL in the name column.  */
    593   1.3  christos 
    594   1.3  christos const struct aarch64_name_value_pair aarch64_hint_options[] =
    595   1.7  christos {
    596   1.7  christos   /* BTI.  This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET.  */
    597   1.7  christos   { " ",	HINT_ENCODE (HINT_OPD_F_NOPRINT, 0x20) },
    598   1.9  christos   { "csync",	HINT_OPD_CSYNC },	/* PSB CSYNC.  */
    599   1.7  christos   { "dsync",	HINT_OPD_DSYNC },	/* GCSB DSYNC.  */
    600   1.7  christos   { "c",	HINT_OPD_C },		/* BTI C.  */
    601   1.7  christos   { "j",	HINT_OPD_J },		/* BTI J.  */
    602  1.10  christos   { "jc",	HINT_OPD_JC },		/* BTI JC.  */
    603  1.10  christos   { "keep",	HINT_OPD_KEEP },	/* STSHH KEEP  */
    604   1.7  christos   { "strm",	HINT_OPD_STRM },	/* STSHH STRM  */
    605   1.3  christos   { NULL,	HINT_OPD_NULL },
    606   1.3  christos };
    607   1.1  christos 
    608   1.1  christos /* op -> op:       load = 0 instruction = 1 store = 2
    609   1.1  christos    l  -> level:    1-3
    610   1.1  christos    t  -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1   */
    611   1.1  christos #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
    612   1.1  christos const struct aarch64_name_value_pair aarch64_prfops[32] =
    613   1.1  christos {
    614   1.1  christos   { "pldl1keep", B(0, 1, 0) },
    615   1.1  christos   { "pldl1strm", B(0, 1, 1) },
    616   1.1  christos   { "pldl2keep", B(0, 2, 0) },
    617   1.1  christos   { "pldl2strm", B(0, 2, 1) },
    618   1.1  christos   { "pldl3keep", B(0, 3, 0) },
    619   1.9  christos   { "pldl3strm", B(0, 3, 1) },
    620   1.9  christos   { "pldslckeep", B(0, 4, 0) },
    621   1.1  christos   { "pldslcstrm", B(0, 4, 1) },
    622   1.1  christos   { "plil1keep", B(1, 1, 0) },
    623   1.1  christos   { "plil1strm", B(1, 1, 1) },
    624   1.1  christos   { "plil2keep", B(1, 2, 0) },
    625   1.1  christos   { "plil2strm", B(1, 2, 1) },
    626   1.1  christos   { "plil3keep", B(1, 3, 0) },
    627   1.9  christos   { "plil3strm", B(1, 3, 1) },
    628   1.9  christos   { "plislckeep", B(1, 4, 0) },
    629   1.1  christos   { "plislcstrm", B(1, 4, 1) },
    630   1.1  christos   { "pstl1keep", B(2, 1, 0) },
    631   1.1  christos   { "pstl1strm", B(2, 1, 1) },
    632   1.1  christos   { "pstl2keep", B(2, 2, 0) },
    633   1.1  christos   { "pstl2strm", B(2, 2, 1) },
    634   1.1  christos   { "pstl3keep", B(2, 3, 0) },
    635   1.9  christos   { "pstl3strm", B(2, 3, 1) },
    636   1.9  christos   { "pstslckeep", B(2, 4, 0) },
    637  1.10  christos   { "pstslcstrm", B(2, 4, 1) },
    638   1.1  christos   { "ir", B(3, 1, 0) },
    639   1.1  christos   { NULL, 0x19 },
    640   1.1  christos   { NULL, 0x1a },
    641   1.1  christos   { NULL, 0x1b },
    642   1.1  christos   { NULL, 0x1c },
    643   1.1  christos   { NULL, 0x1d },
    644   1.1  christos   { NULL, 0x1e },
    645   1.1  christos   { NULL, 0x1f },
    646   1.1  christos };
    647   1.1  christos #undef B
    648   1.1  christos 
    649   1.1  christos /* Utilities on value constraint.  */
    651  1.10  christos 
    652   1.1  christos static inline bool
    653  1.10  christos value_in_range_p (int64_t value, int64_t low, int64_t high)
    654   1.1  christos {
    655   1.1  christos   return (low <= value) && (value <= high);
    656   1.6  christos }
    657  1.10  christos 
    658   1.1  christos /* Return true if VALUE is a multiple of ALIGN.  */
    659   1.1  christos static inline bool
    660   1.6  christos value_aligned_p (int64_t value, int align)
    661   1.1  christos {
    662   1.1  christos   return (value % align) == 0;
    663   1.1  christos }
    664  1.10  christos 
    665   1.1  christos /* A signed value fits in a field.  */
    666   1.1  christos static inline bool
    667   1.1  christos value_fit_signed_field_p (int64_t value, unsigned width)
    668   1.1  christos {
    669   1.1  christos   assert (width < 32);
    670   1.7  christos   if (width < sizeof (value) * 8)
    671   1.1  christos     {
    672  1.10  christos       int64_t lim = (uint64_t) 1 << (width - 1);
    673   1.1  christos       if (value >= -lim && value < lim)
    674  1.10  christos 	return true;
    675   1.1  christos     }
    676   1.1  christos   return false;
    677   1.1  christos }
    678  1.10  christos 
    679   1.1  christos /* An unsigned value fits in a field.  */
    680   1.1  christos static inline bool
    681   1.1  christos value_fit_unsigned_field_p (int64_t value, unsigned width)
    682   1.1  christos {
    683   1.1  christos   assert (width < 32);
    684   1.7  christos   if (width < sizeof (value) * 8)
    685   1.1  christos     {
    686  1.10  christos       int64_t lim = (uint64_t) 1 << width;
    687   1.1  christos       if (value >= 0 && value < lim)
    688  1.10  christos 	return true;
    689   1.1  christos     }
    690   1.1  christos   return false;
    691  1.10  christos }
    692  1.10  christos 
    693   1.1  christos /* Return true if OPERAND is SP or WSP.  */
    694   1.1  christos bool
    695   1.1  christos aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
    696   1.1  christos {
    697   1.1  christos   return ((aarch64_get_operand_class (operand->type)
    698   1.1  christos 	   == AARCH64_OPND_CLASS_INT_REG)
    699   1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type)
    700   1.1  christos 	  && operand->reg.regno == 31);
    701   1.1  christos }
    702   1.1  christos 
    703   1.1  christos /* Return 1 if OPERAND is XZR or WZP.  */
    704   1.1  christos int
    705   1.1  christos aarch64_zero_register_p (const aarch64_opnd_info *operand)
    706   1.1  christos {
    707   1.1  christos   return ((aarch64_get_operand_class (operand->type)
    708   1.1  christos 	   == AARCH64_OPND_CLASS_INT_REG)
    709   1.1  christos 	  && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
    710   1.1  christos 	  && operand->reg.regno == 31);
    711   1.1  christos }
    712   1.1  christos 
    713   1.1  christos /* Return true if the operand *OPERAND that has the operand code
    714   1.1  christos    OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
    715  1.10  christos    qualified by the qualifier TARGET.  */
    716   1.1  christos 
    717   1.1  christos static inline bool
    718   1.1  christos operand_also_qualified_p (const struct aarch64_opnd_info *operand,
    719   1.1  christos 			  aarch64_opnd_qualifier_t target)
    720   1.1  christos {
    721   1.1  christos   switch (operand->qualifier)
    722   1.1  christos     {
    723  1.10  christos     case AARCH64_OPND_QLF_W:
    724   1.1  christos       if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
    725   1.1  christos 	return true;
    726   1.1  christos       break;
    727  1.10  christos     case AARCH64_OPND_QLF_X:
    728   1.1  christos       if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
    729   1.1  christos 	return true;
    730   1.1  christos       break;
    731   1.1  christos     case AARCH64_OPND_QLF_WSP:
    732  1.10  christos       if (target == AARCH64_OPND_QLF_W
    733   1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
    734   1.1  christos 	return true;
    735   1.1  christos       break;
    736   1.1  christos     case AARCH64_OPND_QLF_SP:
    737  1.10  christos       if (target == AARCH64_OPND_QLF_X
    738   1.1  christos 	  && operand_maybe_stack_pointer (aarch64_operands + operand->type))
    739   1.1  christos 	return true;
    740   1.1  christos       break;
    741   1.1  christos     default:
    742   1.1  christos       break;
    743  1.10  christos     }
    744   1.1  christos 
    745   1.1  christos   return false;
    746   1.1  christos }
    747   1.1  christos 
    748   1.1  christos /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
    749   1.1  christos    for operand KNOWN_IDX, return the expected qualifier for operand IDX.
    750   1.1  christos 
    751   1.1  christos    Return NIL if more than one expected qualifiers are found.  */
    752   1.1  christos 
    753   1.1  christos aarch64_opnd_qualifier_t
    754   1.1  christos aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
    755   1.1  christos 				int idx,
    756   1.1  christos 				const aarch64_opnd_qualifier_t known_qlf,
    757   1.1  christos 				int known_idx)
    758   1.1  christos {
    759   1.1  christos   int i, saved_i;
    760   1.1  christos 
    761   1.1  christos   /* Special case.
    762   1.1  christos 
    763   1.1  christos      When the known qualifier is NIL, we have to assume that there is only
    764   1.1  christos      one qualifier sequence in the *QSEQ_LIST and return the corresponding
    765   1.1  christos      qualifier directly.  One scenario is that for instruction
    766   1.1  christos 	PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
    767   1.1  christos      which has only one possible valid qualifier sequence
    768   1.1  christos 	NIL, S_D
    769   1.1  christos      the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
    770   1.1  christos      determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
    771   1.1  christos 
    772   1.1  christos      Because the qualifier NIL has dual roles in the qualifier sequence:
    773   1.1  christos      it can mean no qualifier for the operand, or the qualifer sequence is
    774  1.10  christos      not in use (when all qualifiers in the sequence are NILs), we have to
    775   1.1  christos      handle this special case here.  */
    776  1.10  christos   if (((enum aarch64_opnd) known_qlf) == AARCH64_OPND_NIL)
    777   1.1  christos     {
    778   1.1  christos       assert (((enum aarch64_opnd) qseq_list[0][known_idx]) == AARCH64_OPND_NIL);
    779   1.1  christos       return qseq_list[0][idx];
    780   1.1  christos     }
    781   1.1  christos 
    782   1.1  christos   for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
    783   1.1  christos     {
    784   1.1  christos       if (qseq_list[i][known_idx] == known_qlf)
    785   1.1  christos 	{
    786   1.1  christos 	  if (saved_i != -1)
    787  1.10  christos 	    /* More than one sequences are found to have KNOWN_QLF at
    788   1.1  christos 	       KNOWN_IDX.  */
    789   1.1  christos 	    return AARCH64_OPND_QLF_NIL;
    790   1.1  christos 	  saved_i = i;
    791   1.1  christos 	}
    792   1.1  christos     }
    793   1.1  christos 
    794   1.1  christos   return qseq_list[saved_i][idx];
    795   1.1  christos }
    796   1.1  christos 
    797   1.1  christos enum operand_qualifier_kind
    798   1.1  christos {
    799   1.1  christos   OQK_NIL,
    800   1.1  christos   OQK_OPD_VARIANT,
    801   1.1  christos   OQK_VALUE_IN_RANGE,
    802   1.1  christos   OQK_MISC,
    803   1.1  christos };
    804   1.1  christos 
    805   1.1  christos /* Operand qualifier description.  */
    806   1.1  christos struct operand_qualifier_data
    807   1.1  christos {
    808   1.1  christos   /* The usage of the three data fields depends on the qualifier kind.  */
    809   1.1  christos   int data0;
    810   1.1  christos   int data1;
    811   1.1  christos   int data2;
    812   1.1  christos   /* Description.  */
    813   1.1  christos   const char *desc;
    814   1.1  christos   /* Kind.  */
    815   1.1  christos   enum operand_qualifier_kind kind;
    816   1.1  christos };
    817   1.1  christos 
    818   1.1  christos /* Indexed by the operand qualifier enumerators.  */
    819   1.1  christos struct operand_qualifier_data aarch64_opnd_qualifiers[] =
    820   1.1  christos {
    821   1.1  christos   {0, 0, 0, "NIL", OQK_NIL},
    822   1.1  christos 
    823   1.1  christos   /* Operand variant qualifiers.
    824   1.1  christos      First 3 fields:
    825   1.1  christos      element size, number of elements and common value for encoding.  */
    826   1.1  christos 
    827   1.1  christos   {4, 1, 0x0, "w", OQK_OPD_VARIANT},
    828   1.1  christos   {8, 1, 0x1, "x", OQK_OPD_VARIANT},
    829   1.1  christos   {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
    830   1.1  christos   {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
    831   1.1  christos 
    832   1.1  christos   {1, 1, 0x0, "b", OQK_OPD_VARIANT},
    833   1.1  christos   {2, 1, 0x1, "h", OQK_OPD_VARIANT},
    834   1.1  christos   {4, 1, 0x2, "s", OQK_OPD_VARIANT},
    835  1.10  christos   {8, 1, 0x3, "d", OQK_OPD_VARIANT},
    836   1.7  christos   {16, 1, 0x4, "q", OQK_OPD_VARIANT},
    837   1.7  christos   {2, 1, 0x0, "2b", OQK_OPD_VARIANT},
    838   1.1  christos   {4, 1, 0x0, "4b", OQK_OPD_VARIANT},
    839   1.6  christos   {4, 1, 0x0, "2h", OQK_OPD_VARIANT},
    840   1.1  christos 
    841   1.1  christos   {1, 4, 0x0, "4b", OQK_OPD_VARIANT},
    842   1.3  christos   {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
    843   1.1  christos   {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
    844   1.1  christos   {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
    845   1.1  christos   {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
    846   1.1  christos   {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
    847   1.1  christos   {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
    848   1.1  christos   {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
    849   1.1  christos   {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
    850   1.1  christos   {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
    851   1.6  christos   {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
    852   1.6  christos 
    853   1.6  christos   {0, 0, 0, "z", OQK_OPD_VARIANT},
    854   1.7  christos   {0, 0, 0, "m", OQK_OPD_VARIANT},
    855   1.7  christos 
    856   1.7  christos   /* Qualifier for scaled immediate for Tag granule (stg,st2g,etc).  */
    857   1.1  christos   {16, 0, 0, "tag", OQK_OPD_VARIANT},
    858   1.1  christos 
    859   1.1  christos   /* Qualifiers constraining the value range.
    860   1.1  christos      First 3 fields:
    861   1.6  christos      Lower bound, higher bound, unused.  */
    862   1.1  christos 
    863   1.1  christos   {0, 15, 0, "CR",       OQK_VALUE_IN_RANGE},
    864   1.1  christos   {0,  7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
    865   1.1  christos   {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
    866   1.1  christos   {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
    867   1.1  christos   {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
    868   1.1  christos   {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
    869   1.1  christos   {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
    870   1.1  christos 
    871   1.1  christos   /* Qualifiers for miscellaneous purpose.
    872   1.1  christos      First 3 fields:
    873   1.1  christos      unused, unused and unused.  */
    874   1.1  christos 
    875   1.1  christos   {0, 0, 0, "lsl", 0},
    876   1.1  christos   {0, 0, 0, "msl", 0},
    877   1.1  christos 
    878   1.1  christos   {0, 0, 0, "retrieving", 0},
    879   1.8  christos };
    880   1.1  christos 
    881   1.1  christos static inline bool
    882   1.8  christos operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
    883   1.1  christos {
    884   1.1  christos   return aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT;
    885   1.8  christos }
    886   1.1  christos 
    887   1.1  christos static inline bool
    888   1.8  christos qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
    889   1.1  christos {
    890   1.1  christos   return aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE;
    891   1.1  christos }
    892   1.1  christos 
    893   1.1  christos const char*
    894   1.1  christos aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
    895   1.1  christos {
    896   1.1  christos   return aarch64_opnd_qualifiers[qualifier].desc;
    897   1.1  christos }
    898   1.1  christos 
    899   1.1  christos /* Given an operand qualifier, return the expected data element size
    900   1.1  christos    of a qualified operand.  */
    901   1.1  christos unsigned char
    902   1.8  christos aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
    903   1.1  christos {
    904   1.1  christos   assert (operand_variant_qualifier_p (qualifier));
    905   1.1  christos   return aarch64_opnd_qualifiers[qualifier].data0;
    906   1.1  christos }
    907   1.1  christos 
    908   1.1  christos unsigned char
    909   1.8  christos aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
    910   1.1  christos {
    911   1.1  christos   assert (operand_variant_qualifier_p (qualifier));
    912   1.1  christos   return aarch64_opnd_qualifiers[qualifier].data1;
    913   1.1  christos }
    914   1.1  christos 
    915   1.1  christos aarch64_insn
    916   1.8  christos aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
    917   1.1  christos {
    918   1.1  christos   assert (operand_variant_qualifier_p (qualifier));
    919   1.1  christos   return aarch64_opnd_qualifiers[qualifier].data2;
    920   1.1  christos }
    921   1.1  christos 
    922   1.1  christos static int
    923   1.8  christos get_lower_bound (aarch64_opnd_qualifier_t qualifier)
    924   1.1  christos {
    925   1.1  christos   assert (qualifier_value_in_range_constraint_p (qualifier));
    926   1.1  christos   return aarch64_opnd_qualifiers[qualifier].data0;
    927   1.1  christos }
    928   1.1  christos 
    929   1.1  christos static int
    930   1.8  christos get_upper_bound (aarch64_opnd_qualifier_t qualifier)
    931   1.1  christos {
    932   1.1  christos   assert (qualifier_value_in_range_constraint_p (qualifier));
    933   1.1  christos   return aarch64_opnd_qualifiers[qualifier].data1;
    934   1.1  christos }
    935   1.1  christos 
    936   1.1  christos #ifdef DEBUG_AARCH64
    937   1.1  christos void
    938   1.1  christos aarch64_verbose (const char *str, ...)
    939   1.1  christos {
    940   1.1  christos   va_list ap;
    941   1.1  christos   va_start (ap, str);
    942   1.1  christos   printf ("#### ");
    943   1.1  christos   vprintf (str, ap);
    944   1.1  christos   printf ("\n");
    945   1.1  christos   va_end (ap);
    946   1.1  christos }
    947   1.1  christos 
    948   1.1  christos static inline void
    949   1.1  christos dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
    950   1.1  christos {
    951   1.1  christos   int i;
    952   1.1  christos   printf ("#### \t");
    953   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
    954   1.1  christos     printf ("%s,", aarch64_get_qualifier_name (*qualifier));
    955   1.1  christos   printf ("\n");
    956   1.1  christos }
    957   1.1  christos 
    958   1.1  christos static void
    959   1.1  christos dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
    960   1.1  christos 		       const aarch64_opnd_qualifier_t *qualifier)
    961   1.1  christos {
    962   1.1  christos   int i;
    963   1.1  christos   aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
    964   1.1  christos 
    965   1.1  christos   aarch64_verbose ("dump_match_qualifiers:");
    966   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
    967   1.1  christos     curr[i] = opnd[i].qualifier;
    968   1.1  christos   dump_qualifier_sequence (curr);
    969   1.1  christos   aarch64_verbose ("against");
    970   1.1  christos   dump_qualifier_sequence (qualifier);
    971   1.1  christos }
    972   1.7  christos #endif /* DEBUG_AARCH64 */
    973   1.7  christos 
    974   1.7  christos /* This function checks if the given instruction INSN is a destructive
    975   1.8  christos    instruction based on the usage of the registers.  It does not recognize
    976   1.7  christos    unary destructive instructions.  */
    977   1.7  christos bool
    978   1.7  christos aarch64_is_destructive_by_operands (const aarch64_opcode *opcode)
    979   1.7  christos {
    980   1.7  christos   int i = 0;
    981   1.7  christos   const enum aarch64_opnd *opnds = opcode->operands;
    982   1.8  christos 
    983   1.7  christos   if (opnds[0] == AARCH64_OPND_NIL)
    984   1.7  christos     return false;
    985   1.7  christos 
    986   1.8  christos   while (opnds[++i] != AARCH64_OPND_NIL)
    987   1.7  christos     if (opnds[i] == opnds[0])
    988   1.8  christos       return true;
    989   1.7  christos 
    990   1.7  christos   return false;
    991   1.1  christos }
    992   1.1  christos 
    993   1.1  christos /* TODO improve this, we can have an extra field at the runtime to
    994   1.1  christos    store the number of operands rather than calculating it every time.  */
    995   1.1  christos 
    996   1.1  christos int
    997   1.1  christos aarch64_num_of_operands (const aarch64_opcode *opcode)
    998   1.1  christos {
    999   1.1  christos   int i = 0;
   1000   1.1  christos   const enum aarch64_opnd *opnds = opcode->operands;
   1001   1.1  christos   while (opnds[i++] != AARCH64_OPND_NIL)
   1002   1.1  christos     ;
   1003   1.1  christos   --i;
   1004   1.1  christos   assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
   1005   1.1  christos   return i;
   1006   1.1  christos }
   1007   1.1  christos 
   1008   1.1  christos /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
   1009   1.9  christos    If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
   1010   1.9  christos 
   1011   1.9  christos    Store the smallest number of non-matching qualifiers in *INVALID_COUNT.
   1012   1.1  christos    This is always 0 if the function succeeds.
   1013   1.1  christos 
   1014   1.1  christos    N.B. on the entry, it is very likely that only some operands in *INST
   1015   1.1  christos    have had their qualifiers been established.
   1016   1.1  christos 
   1017   1.1  christos    If STOP_AT is not -1, the function will only try to match
   1018   1.1  christos    the qualifier sequence for operands before and including the operand
   1019   1.1  christos    of index STOP_AT; and on success *RET will only be filled with the first
   1020   1.1  christos    (STOP_AT+1) qualifiers.
   1021   1.1  christos 
   1022   1.1  christos    A couple examples of the matching algorithm:
   1023   1.1  christos 
   1024   1.1  christos    X,W,NIL should match
   1025   1.1  christos    X,W,NIL
   1026   1.1  christos 
   1027   1.1  christos    NIL,NIL should match
   1028   1.1  christos    X  ,NIL
   1029   1.1  christos 
   1030   1.1  christos    Apart from serving the main encoding routine, this can also be called
   1031   1.1  christos    during or after the operand decoding.  */
   1032   1.1  christos 
   1033   1.1  christos int
   1034   1.9  christos aarch64_find_best_match (const aarch64_inst *inst,
   1035   1.9  christos 			 const aarch64_opnd_qualifier_seq_t *qualifiers_list,
   1036   1.1  christos 			 int stop_at, aarch64_opnd_qualifier_t *ret,
   1037   1.9  christos 			 int *invalid_count)
   1038   1.1  christos {
   1039   1.1  christos   int i, num_opnds, invalid, min_invalid;
   1040   1.1  christos   const aarch64_opnd_qualifier_t *qualifiers;
   1041   1.1  christos 
   1042   1.1  christos   num_opnds = aarch64_num_of_operands (inst->opcode);
   1043   1.1  christos   if (num_opnds == 0)
   1044   1.9  christos     {
   1045   1.1  christos       DEBUG_TRACE ("SUCCEED: no operand");
   1046   1.1  christos       *invalid_count = 0;
   1047   1.1  christos       return 1;
   1048   1.1  christos     }
   1049   1.1  christos 
   1050   1.1  christos   if (stop_at < 0 || stop_at >= num_opnds)
   1051   1.1  christos     stop_at = num_opnds - 1;
   1052   1.9  christos 
   1053   1.1  christos   /* For each pattern.  */
   1054   1.1  christos   min_invalid = num_opnds;
   1055   1.1  christos   for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
   1056   1.1  christos     {
   1057   1.1  christos       int j;
   1058   1.1  christos       qualifiers = *qualifiers_list;
   1059   1.9  christos 
   1060   1.1  christos       /* Start as positive.  */
   1061   1.1  christos       invalid = 0;
   1062   1.1  christos 
   1063   1.1  christos       DEBUG_TRACE ("%d", i);
   1064   1.1  christos #ifdef DEBUG_AARCH64
   1065   1.1  christos       if (debug_dump)
   1066   1.1  christos 	dump_match_qualifiers (inst->operands, qualifiers);
   1067   1.9  christos #endif
   1068   1.9  christos 
   1069   1.9  christos       /* The first entry should be taken literally, even if it's an empty
   1070   1.9  christos 	 qualifier sequence.  (This matters for strict testing.)  In other
   1071   1.9  christos 	 positions an empty sequence acts as a terminator.  */
   1072   1.1  christos       if (i > 0 && empty_qualifier_sequence_p (qualifiers))
   1073   1.1  christos 	break;
   1074   1.1  christos 
   1075   1.9  christos       for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
   1076   1.9  christos 	{
   1077   1.1  christos 	  if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL
   1078   1.1  christos 	      && !(inst->opcode->flags & F_STRICT))
   1079   1.1  christos 	    {
   1080   1.1  christos 	      /* Either the operand does not have qualifier, or the qualifier
   1081   1.1  christos 		 for the operand needs to be deduced from the qualifier
   1082   1.1  christos 		 sequence.
   1083   1.1  christos 		 In the latter case, any constraint checking related with
   1084   1.1  christos 		 the obtained qualifier should be done later in
   1085   1.1  christos 		 operand_general_constraint_met_p.  */
   1086   1.1  christos 	      continue;
   1087   1.1  christos 	    }
   1088   1.1  christos 	  else if (*qualifiers != inst->operands[j].qualifier)
   1089   1.1  christos 	    {
   1090   1.1  christos 	      /* Unless the target qualifier can also qualify the operand
   1091   1.1  christos 		 (which has already had a non-nil qualifier), non-equal
   1092   1.1  christos 		 qualifiers are generally un-matched.  */
   1093   1.1  christos 	      if (operand_also_qualified_p (inst->operands + j, *qualifiers))
   1094   1.9  christos 		continue;
   1095   1.1  christos 	      else
   1096   1.1  christos 		invalid += 1;
   1097   1.1  christos 	    }
   1098   1.1  christos 	  else
   1099   1.1  christos 	    continue;	/* Equal qualifiers are certainly matched.  */
   1100   1.9  christos 	}
   1101   1.9  christos 
   1102   1.9  christos       if (min_invalid > invalid)
   1103   1.1  christos 	min_invalid = invalid;
   1104   1.9  christos 
   1105   1.1  christos       /* Qualifiers established.  */
   1106   1.1  christos       if (min_invalid == 0)
   1107   1.1  christos 	break;
   1108   1.9  christos     }
   1109   1.9  christos 
   1110   1.1  christos   *invalid_count = min_invalid;
   1111   1.1  christos   if (min_invalid == 0)
   1112   1.1  christos     {
   1113   1.1  christos       /* Fill the result in *RET.  */
   1114   1.1  christos       int j;
   1115   1.1  christos       qualifiers = *qualifiers_list;
   1116   1.1  christos 
   1117   1.1  christos       DEBUG_TRACE ("complete qualifiers using list %d", i);
   1118   1.1  christos #ifdef DEBUG_AARCH64
   1119   1.1  christos       if (debug_dump)
   1120   1.1  christos 	dump_qualifier_sequence (qualifiers);
   1121   1.1  christos #endif
   1122   1.1  christos 
   1123   1.1  christos       for (j = 0; j <= stop_at; ++j, ++qualifiers)
   1124   1.1  christos 	ret[j] = *qualifiers;
   1125   1.1  christos       for (; j < AARCH64_MAX_OPND_NUM; ++j)
   1126   1.1  christos 	ret[j] = AARCH64_OPND_QLF_NIL;
   1127   1.1  christos 
   1128   1.1  christos       DEBUG_TRACE ("SUCCESS");
   1129   1.1  christos       return 1;
   1130   1.1  christos     }
   1131   1.1  christos 
   1132   1.1  christos   DEBUG_TRACE ("FAIL");
   1133   1.1  christos   return 0;
   1134   1.1  christos }
   1135   1.1  christos 
   1136   1.1  christos /* Operand qualifier matching and resolving.
   1137   1.1  christos 
   1138   1.1  christos    Return 1 if the operand qualifier(s) in *INST match one of the qualifier
   1139   1.9  christos    sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
   1140   1.9  christos 
   1141   1.9  christos    Store the smallest number of non-matching qualifiers in *INVALID_COUNT.
   1142   1.8  christos    This is always 0 if the function succeeds.
   1143   1.1  christos 
   1144   1.1  christos    if UPDATE_P, update the qualifier(s) in *INST after the matching
   1145   1.1  christos    succeeds.  */
   1146   1.9  christos 
   1147   1.9  christos static int
   1148   1.1  christos match_operands_qualifier (aarch64_inst *inst, bool update_p,
   1149   1.9  christos 			  int *invalid_count)
   1150   1.1  christos {
   1151   1.1  christos   int i;
   1152   1.1  christos   aarch64_opnd_qualifier_seq_t qualifiers;
   1153   1.9  christos 
   1154   1.1  christos   if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
   1155   1.1  christos 				qualifiers, invalid_count))
   1156   1.1  christos     {
   1157   1.1  christos       DEBUG_TRACE ("matching FAIL");
   1158   1.1  christos       return 0;
   1159   1.1  christos     }
   1160   1.8  christos 
   1161   1.1  christos   /* Update the qualifiers.  */
   1162   1.1  christos   if (update_p)
   1163   1.1  christos     for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   1164   1.1  christos       {
   1165   1.1  christos 	if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
   1166   1.1  christos 	  break;
   1167   1.1  christos 	DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
   1168   1.1  christos 			"update %s with %s for operand %d",
   1169   1.1  christos 			aarch64_get_qualifier_name (inst->operands[i].qualifier),
   1170   1.1  christos 			aarch64_get_qualifier_name (qualifiers[i]), i);
   1171   1.1  christos 	inst->operands[i].qualifier = qualifiers[i];
   1172   1.1  christos       }
   1173   1.1  christos 
   1174   1.1  christos   DEBUG_TRACE ("matching SUCCESS");
   1175   1.1  christos   return 1;
   1176   1.1  christos }
   1177   1.1  christos 
   1178   1.1  christos /* Return TRUE if VALUE is a wide constant that can be moved into a general
   1179   1.1  christos    register by MOVZ.
   1180   1.1  christos 
   1181   1.1  christos    IS32 indicates whether value is a 32-bit immediate or not.
   1182   1.1  christos    If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
   1183   1.8  christos    amount will be returned in *SHIFT_AMOUNT.  */
   1184   1.7  christos 
   1185   1.1  christos bool
   1186   1.1  christos aarch64_wide_constant_p (uint64_t value, int is32, unsigned int *shift_amount)
   1187   1.1  christos {
   1188   1.1  christos   int amount;
   1189   1.1  christos 
   1190   1.1  christos   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
   1191   1.1  christos 
   1192   1.1  christos   if (is32)
   1193   1.1  christos     {
   1194   1.1  christos       /* Allow all zeros or all ones in top 32-bits, so that
   1195   1.7  christos 	 32-bit constant expressions like ~0x80000000 are
   1196   1.1  christos 	 permitted.  */
   1197   1.8  christos       if (value >> 32 != 0 && value >> 32 != 0xffffffff)
   1198   1.7  christos 	/* Immediate out of range.  */
   1199   1.1  christos 	return false;
   1200   1.1  christos       value &= 0xffffffff;
   1201   1.1  christos     }
   1202   1.1  christos 
   1203   1.7  christos   /* first, try movz then movn */
   1204   1.1  christos   amount = -1;
   1205   1.7  christos   if ((value & ((uint64_t) 0xffff << 0)) == value)
   1206   1.1  christos     amount = 0;
   1207   1.7  christos   else if ((value & ((uint64_t) 0xffff << 16)) == value)
   1208   1.1  christos     amount = 16;
   1209   1.7  christos   else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
   1210   1.1  christos     amount = 32;
   1211   1.1  christos   else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
   1212   1.1  christos     amount = 48;
   1213   1.1  christos 
   1214   1.8  christos   if (amount == -1)
   1215   1.8  christos     {
   1216   1.1  christos       DEBUG_TRACE ("exit false with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
   1217   1.1  christos       return false;
   1218   1.1  christos     }
   1219   1.1  christos 
   1220   1.1  christos   if (shift_amount != NULL)
   1221   1.8  christos     *shift_amount = amount;
   1222   1.1  christos 
   1223   1.8  christos   DEBUG_TRACE ("exit true with amount %d", amount);
   1224   1.1  christos 
   1225   1.1  christos   return true;
   1226   1.1  christos }
   1227   1.1  christos 
   1228   1.1  christos /* Build the accepted values for immediate logical SIMD instructions.
   1229   1.1  christos 
   1230   1.1  christos    The standard encodings of the immediate value are:
   1231   1.1  christos      N      imms     immr         SIMD size  R             S
   1232   1.1  christos      1      ssssss   rrrrrr       64      UInt(rrrrrr)  UInt(ssssss)
   1233   1.1  christos      0      0sssss   0rrrrr       32      UInt(rrrrr)   UInt(sssss)
   1234   1.1  christos      0      10ssss   00rrrr       16      UInt(rrrr)    UInt(ssss)
   1235   1.1  christos      0      110sss   000rrr       8       UInt(rrr)     UInt(sss)
   1236   1.1  christos      0      1110ss   0000rr       4       UInt(rr)      UInt(ss)
   1237   1.1  christos      0      11110s   00000r       2       UInt(r)       UInt(s)
   1238   1.1  christos    where all-ones value of S is reserved.
   1239   1.1  christos 
   1240   1.1  christos    Let's call E the SIMD size.
   1241   1.1  christos 
   1242   1.1  christos    The immediate value is: S+1 bits '1' rotated to the right by R.
   1243   1.1  christos 
   1244   1.1  christos    The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
   1245   1.1  christos    (remember S != E - 1).  */
   1246   1.1  christos 
   1247   1.1  christos #define TOTAL_IMM_NB  5334
   1248   1.1  christos 
   1249   1.1  christos typedef struct
   1250   1.1  christos {
   1251   1.1  christos   uint64_t imm;
   1252   1.1  christos   aarch64_insn encoding;
   1253   1.1  christos } simd_imm_encoding;
   1254   1.1  christos 
   1255   1.1  christos static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
   1256   1.1  christos 
   1257   1.1  christos static int
   1258   1.1  christos simd_imm_encoding_cmp(const void *i1, const void *i2)
   1259   1.1  christos {
   1260   1.1  christos   const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
   1261   1.1  christos   const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
   1262   1.1  christos 
   1263   1.1  christos   if (imm1->imm < imm2->imm)
   1264   1.1  christos     return -1;
   1265   1.1  christos   if (imm1->imm > imm2->imm)
   1266   1.1  christos     return +1;
   1267   1.1  christos   return 0;
   1268   1.1  christos }
   1269   1.1  christos 
   1270   1.1  christos /* immediate bitfield standard encoding
   1271   1.1  christos    imm13<12> imm13<5:0> imm13<11:6> SIMD size R      S
   1272   1.1  christos    1         ssssss     rrrrrr      64        rrrrrr ssssss
   1273   1.1  christos    0         0sssss     0rrrrr      32        rrrrr  sssss
   1274   1.1  christos    0         10ssss     00rrrr      16        rrrr   ssss
   1275   1.1  christos    0         110sss     000rrr      8         rrr    sss
   1276   1.1  christos    0         1110ss     0000rr      4         rr     ss
   1277   1.1  christos    0         11110s     00000r      2         r      s  */
   1278   1.1  christos static inline int
   1279   1.1  christos encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
   1280   1.1  christos {
   1281   1.1  christos   return (is64 << 12) | (r << 6) | s;
   1282   1.1  christos }
   1283   1.1  christos 
   1284   1.1  christos static void
   1285   1.1  christos build_immediate_table (void)
   1286   1.1  christos {
   1287   1.1  christos   uint32_t log_e, e, s, r, s_mask;
   1288   1.1  christos   uint64_t mask, imm;
   1289   1.1  christos   int nb_imms;
   1290   1.1  christos   int is64;
   1291   1.1  christos 
   1292   1.1  christos   nb_imms = 0;
   1293   1.1  christos   for (log_e = 1; log_e <= 6; log_e++)
   1294   1.1  christos     {
   1295   1.1  christos       /* Get element size.  */
   1296   1.1  christos       e = 1u << log_e;
   1297   1.1  christos       if (log_e == 6)
   1298   1.1  christos 	{
   1299   1.1  christos 	  is64 = 1;
   1300   1.1  christos 	  mask = 0xffffffffffffffffull;
   1301   1.1  christos 	  s_mask = 0;
   1302   1.1  christos 	}
   1303   1.1  christos       else
   1304   1.1  christos 	{
   1305   1.1  christos 	  is64 = 0;
   1306   1.1  christos 	  mask = (1ull << e) - 1;
   1307   1.1  christos 	  /* log_e  s_mask
   1308   1.1  christos 	     1     ((1 << 4) - 1) << 2 = 111100
   1309   1.1  christos 	     2     ((1 << 3) - 1) << 3 = 111000
   1310   1.1  christos 	     3     ((1 << 2) - 1) << 4 = 110000
   1311   1.1  christos 	     4     ((1 << 1) - 1) << 5 = 100000
   1312   1.1  christos 	     5     ((1 << 0) - 1) << 6 = 000000  */
   1313   1.1  christos 	  s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
   1314   1.1  christos 	}
   1315   1.1  christos       for (s = 0; s < e - 1; s++)
   1316   1.1  christos 	for (r = 0; r < e; r++)
   1317   1.1  christos 	  {
   1318   1.1  christos 	    /* s+1 consecutive bits to 1 (s < 63) */
   1319   1.1  christos 	    imm = (1ull << (s + 1)) - 1;
   1320   1.1  christos 	    /* rotate right by r */
   1321   1.1  christos 	    if (r != 0)
   1322   1.1  christos 	      imm = (imm >> r) | ((imm << (e - r)) & mask);
   1323   1.1  christos 	    /* replicate the constant depending on SIMD size */
   1324   1.1  christos 	    switch (log_e)
   1325   1.6  christos 	      {
   1326   1.1  christos 	      case 1: imm = (imm <<  2) | imm;
   1327   1.6  christos 		/* Fall through.  */
   1328   1.1  christos 	      case 2: imm = (imm <<  4) | imm;
   1329   1.6  christos 		/* Fall through.  */
   1330   1.1  christos 	      case 3: imm = (imm <<  8) | imm;
   1331   1.6  christos 		/* Fall through.  */
   1332   1.1  christos 	      case 4: imm = (imm << 16) | imm;
   1333   1.6  christos 		/* Fall through.  */
   1334   1.1  christos 	      case 5: imm = (imm << 32) | imm;
   1335   1.1  christos 		/* Fall through.  */
   1336   1.1  christos 	      case 6: break;
   1337   1.1  christos 	      default: abort ();
   1338   1.1  christos 	      }
   1339   1.1  christos 	    simd_immediates[nb_imms].imm = imm;
   1340   1.1  christos 	    simd_immediates[nb_imms].encoding =
   1341   1.1  christos 	      encode_immediate_bitfield(is64, s | s_mask, r);
   1342   1.1  christos 	    nb_imms++;
   1343   1.1  christos 	  }
   1344   1.1  christos     }
   1345   1.1  christos   assert (nb_imms == TOTAL_IMM_NB);
   1346   1.1  christos   qsort(simd_immediates, nb_imms,
   1347   1.1  christos 	sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
   1348   1.1  christos }
   1349   1.1  christos 
   1350   1.1  christos /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
   1351   1.1  christos    be accepted by logical (immediate) instructions
   1352   1.6  christos    e.g. ORR <Xd|SP>, <Xn>, #<imm>.
   1353   1.1  christos 
   1354   1.1  christos    ESIZE is the number of bytes in the decoded immediate value.
   1355   1.1  christos    If ENCODING is not NULL, on the return of TRUE, the standard encoding for
   1356   1.8  christos    VALUE will be returned in *ENCODING.  */
   1357   1.6  christos 
   1358   1.1  christos bool
   1359   1.1  christos aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
   1360   1.1  christos {
   1361   1.8  christos   simd_imm_encoding imm_enc;
   1362   1.6  christos   const simd_imm_encoding *imm_encoding;
   1363   1.6  christos   static bool initialized = false;
   1364   1.1  christos   uint64_t upper;
   1365   1.6  christos   int i;
   1366   1.6  christos 
   1367   1.1  christos   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
   1368   1.6  christos 	       value, esize);
   1369   1.1  christos 
   1370   1.1  christos   if (!initialized)
   1371   1.8  christos     {
   1372   1.1  christos       build_immediate_table ();
   1373   1.1  christos       initialized = true;
   1374   1.6  christos     }
   1375   1.6  christos 
   1376   1.6  christos   /* Allow all zeros or all ones in top bits, so that
   1377   1.6  christos      constant expressions like ~1 are permitted.  */
   1378   1.8  christos   upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
   1379   1.3  christos   if ((value & ~upper) != value && (value | upper) != value)
   1380   1.6  christos     return false;
   1381   1.6  christos 
   1382   1.6  christos   /* Replicate to a full 64-bit value.  */
   1383   1.6  christos   value &= ~upper;
   1384   1.1  christos   for (i = esize * 8; i < 64; i *= 2)
   1385   1.1  christos     value |= (value << i);
   1386   1.1  christos 
   1387   1.1  christos   imm_enc.imm = value;
   1388   1.1  christos   imm_encoding = (const simd_imm_encoding *)
   1389   1.1  christos     bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
   1390   1.1  christos             sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
   1391   1.8  christos   if (imm_encoding == NULL)
   1392   1.8  christos     {
   1393   1.1  christos       DEBUG_TRACE ("exit with false");
   1394   1.1  christos       return false;
   1395   1.1  christos     }
   1396   1.8  christos   if (encoding != NULL)
   1397   1.8  christos     *encoding = imm_encoding->encoding;
   1398   1.1  christos   DEBUG_TRACE ("exit with true");
   1399   1.1  christos   return true;
   1400   1.1  christos }
   1401   1.1  christos 
   1402   1.1  christos /* If 64-bit immediate IMM is in the format of
   1403   1.1  christos    "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
   1404   1.1  christos    where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
   1405   1.1  christos    of value "abcdefgh".  Otherwise return -1.  */
   1406   1.1  christos int
   1407   1.1  christos aarch64_shrink_expanded_imm8 (uint64_t imm)
   1408   1.1  christos {
   1409   1.1  christos   int i, ret;
   1410   1.1  christos   uint32_t byte;
   1411   1.1  christos 
   1412   1.1  christos   ret = 0;
   1413   1.1  christos   for (i = 0; i < 8; i++)
   1414   1.1  christos     {
   1415   1.1  christos       byte = (imm >> (8 * i)) & 0xff;
   1416   1.1  christos       if (byte == 0xff)
   1417   1.1  christos 	ret |= 1 << i;
   1418   1.1  christos       else if (byte != 0x00)
   1419   1.1  christos 	return -1;
   1420   1.1  christos     }
   1421   1.1  christos   return ret;
   1422   1.1  christos }
   1423   1.1  christos 
   1424   1.1  christos /* Utility inline functions for operand_general_constraint_met_p.  */
   1425   1.1  christos 
   1426   1.1  christos static inline void
   1427   1.1  christos set_error (aarch64_operand_error *mismatch_detail,
   1428   1.1  christos 	   enum aarch64_operand_error_kind kind, int idx,
   1429   1.1  christos 	   const char* error)
   1430   1.1  christos {
   1431   1.1  christos   if (mismatch_detail == NULL)
   1432   1.1  christos     return;
   1433   1.1  christos   mismatch_detail->kind = kind;
   1434   1.1  christos   mismatch_detail->index = idx;
   1435   1.1  christos   mismatch_detail->error = error;
   1436   1.1  christos }
   1437   1.3  christos 
   1438   1.3  christos static inline void
   1439   1.3  christos set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
   1440   1.3  christos 		  const char* error)
   1441   1.3  christos {
   1442   1.3  christos   if (mismatch_detail == NULL)
   1443   1.3  christos     return;
   1444   1.3  christos   set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
   1445   1.3  christos }
   1446   1.9  christos 
   1447   1.9  christos static inline void
   1448   1.9  christos set_invalid_regno_error (aarch64_operand_error *mismatch_detail, int idx,
   1449   1.9  christos 			 const char *prefix, int lower_bound, int upper_bound)
   1450   1.9  christos {
   1451   1.9  christos   if (mismatch_detail == NULL)
   1452   1.9  christos     return;
   1453   1.9  christos   set_error (mismatch_detail, AARCH64_OPDE_INVALID_REGNO, idx, NULL);
   1454   1.9  christos   mismatch_detail->data[0].s = prefix;
   1455   1.9  christos   mismatch_detail->data[1].i = lower_bound;
   1456   1.9  christos   mismatch_detail->data[2].i = upper_bound;
   1457   1.9  christos }
   1458   1.1  christos 
   1459   1.1  christos static inline void
   1460   1.1  christos set_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1461   1.1  christos 			int idx, int lower_bound, int upper_bound,
   1462   1.1  christos 			const char* error)
   1463   1.1  christos {
   1464   1.1  christos   if (mismatch_detail == NULL)
   1465   1.8  christos     return;
   1466   1.8  christos   set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
   1467   1.1  christos   mismatch_detail->data[0].i = lower_bound;
   1468   1.1  christos   mismatch_detail->data[1].i = upper_bound;
   1469   1.1  christos }
   1470   1.1  christos 
   1471   1.1  christos static inline void
   1472   1.1  christos set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1473   1.1  christos 			    int idx, int lower_bound, int upper_bound)
   1474   1.1  christos {
   1475   1.1  christos   if (mismatch_detail == NULL)
   1476   1.1  christos     return;
   1477   1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1478   1.1  christos 			  _("immediate value"));
   1479   1.1  christos }
   1480   1.1  christos 
   1481   1.1  christos static inline void
   1482   1.1  christos set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1483   1.1  christos 			       int idx, int lower_bound, int upper_bound)
   1484   1.1  christos {
   1485   1.1  christos   if (mismatch_detail == NULL)
   1486   1.1  christos     return;
   1487   1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1488   1.1  christos 			  _("immediate offset"));
   1489   1.1  christos }
   1490   1.1  christos 
   1491   1.1  christos static inline void
   1492   1.1  christos set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1493   1.1  christos 			      int idx, int lower_bound, int upper_bound)
   1494   1.1  christos {
   1495   1.1  christos   if (mismatch_detail == NULL)
   1496   1.1  christos     return;
   1497   1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1498   1.1  christos 			  _("register number"));
   1499   1.1  christos }
   1500   1.1  christos 
   1501   1.1  christos static inline void
   1502   1.1  christos set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1503   1.1  christos 				 int idx, int lower_bound, int upper_bound)
   1504   1.1  christos {
   1505   1.1  christos   if (mismatch_detail == NULL)
   1506   1.1  christos     return;
   1507   1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1508   1.1  christos 			  _("register element index"));
   1509   1.1  christos }
   1510   1.1  christos 
   1511   1.1  christos static inline void
   1512   1.1  christos set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1513   1.1  christos 				   int idx, int lower_bound, int upper_bound)
   1514   1.1  christos {
   1515   1.1  christos   if (mismatch_detail == NULL)
   1516   1.1  christos     return;
   1517   1.1  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1518   1.1  christos 			  _("shift amount"));
   1519   1.6  christos }
   1520   1.6  christos 
   1521   1.6  christos /* Report that the MUL modifier in operand IDX should be in the range
   1522   1.6  christos    [LOWER_BOUND, UPPER_BOUND].  */
   1523   1.6  christos static inline void
   1524   1.6  christos set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
   1525   1.6  christos 				   int idx, int lower_bound, int upper_bound)
   1526   1.6  christos {
   1527   1.6  christos   if (mismatch_detail == NULL)
   1528   1.6  christos     return;
   1529   1.6  christos   set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
   1530   1.6  christos 			  _("multiplier"));
   1531   1.1  christos }
   1532   1.1  christos 
   1533   1.1  christos static inline void
   1534   1.1  christos set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
   1535   1.1  christos 		     int alignment)
   1536   1.1  christos {
   1537   1.1  christos   if (mismatch_detail == NULL)
   1538   1.8  christos     return;
   1539   1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
   1540   1.1  christos   mismatch_detail->data[0].i = alignment;
   1541   1.1  christos }
   1542   1.9  christos 
   1543   1.9  christos static inline void
   1544   1.1  christos set_reg_list_length_error (aarch64_operand_error *mismatch_detail, int idx,
   1545   1.1  christos 			   int expected_num)
   1546   1.1  christos {
   1547   1.9  christos   if (mismatch_detail == NULL)
   1548   1.9  christos     return;
   1549   1.9  christos   set_error (mismatch_detail, AARCH64_OPDE_REG_LIST_LENGTH, idx, NULL);
   1550   1.9  christos   mismatch_detail->data[0].i = 1 << expected_num;
   1551   1.9  christos }
   1552   1.9  christos 
   1553   1.9  christos static inline void
   1554   1.9  christos set_reg_list_stride_error (aarch64_operand_error *mismatch_detail, int idx,
   1555   1.9  christos 			   int expected_num)
   1556   1.9  christos {
   1557   1.9  christos   if (mismatch_detail == NULL)
   1558   1.9  christos     return;
   1559   1.9  christos   set_error (mismatch_detail, AARCH64_OPDE_REG_LIST_STRIDE, idx, NULL);
   1560   1.9  christos   mismatch_detail->data[0].i = 1 << expected_num;
   1561   1.9  christos }
   1562   1.9  christos 
   1563   1.9  christos static inline void
   1564   1.9  christos set_invalid_vg_size (aarch64_operand_error *mismatch_detail,
   1565   1.9  christos 		     int idx, int expected)
   1566   1.9  christos {
   1567   1.9  christos   if (mismatch_detail == NULL)
   1568   1.9  christos     return;
   1569   1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_INVALID_VG_SIZE, idx, NULL);
   1570   1.1  christos   mismatch_detail->data[0].i = expected;
   1571   1.1  christos }
   1572   1.1  christos 
   1573   1.1  christos static inline void
   1574   1.1  christos set_other_error (aarch64_operand_error *mismatch_detail, int idx,
   1575   1.1  christos 		 const char* error)
   1576   1.1  christos {
   1577   1.1  christos   if (mismatch_detail == NULL)
   1578   1.1  christos     return;
   1579   1.1  christos   set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
   1580   1.9  christos }
   1581   1.9  christos 
   1582   1.9  christos /* Check that indexed register operand OPND has a register in the range
   1583   1.9  christos    [MIN_REGNO, MAX_REGNO] and an index in the range [MIN_INDEX, MAX_INDEX].
   1584   1.9  christos    PREFIX is the register prefix, such as "z" for SVE vector registers.  */
   1585   1.9  christos 
   1586   1.9  christos static bool
   1587   1.9  christos check_reglane (const aarch64_opnd_info *opnd,
   1588   1.9  christos 	       aarch64_operand_error *mismatch_detail, int idx,
   1589   1.9  christos 	       const char *prefix, int min_regno, int max_regno,
   1590   1.9  christos 	       int min_index, int max_index)
   1591   1.9  christos {
   1592   1.9  christos   if (!value_in_range_p (opnd->reglane.regno, min_regno, max_regno))
   1593   1.9  christos     {
   1594   1.9  christos       set_invalid_regno_error (mismatch_detail, idx, prefix, min_regno,
   1595   1.9  christos 			       max_regno);
   1596   1.9  christos       return false;
   1597   1.9  christos     }
   1598   1.9  christos   if (!value_in_range_p (opnd->reglane.index, min_index, max_index))
   1599   1.9  christos     {
   1600   1.9  christos       set_elem_idx_out_of_range_error (mismatch_detail, idx, min_index,
   1601   1.9  christos 				       max_index);
   1602   1.9  christos       return false;
   1603   1.9  christos     }
   1604   1.9  christos   return true;
   1605   1.9  christos }
   1606   1.9  christos 
   1607   1.9  christos /* Check that register list operand OPND has NUM_REGS registers and a
   1608   1.9  christos    register stride of STRIDE.  */
   1609   1.9  christos 
   1610   1.9  christos static bool
   1611   1.9  christos check_reglist (const aarch64_opnd_info *opnd,
   1612   1.9  christos 	       aarch64_operand_error *mismatch_detail, int idx,
   1613   1.9  christos 	       int num_regs, int stride)
   1614   1.9  christos {
   1615   1.9  christos   if (opnd->reglist.num_regs != num_regs)
   1616   1.9  christos     {
   1617   1.9  christos       set_reg_list_length_error (mismatch_detail, idx, num_regs);
   1618   1.9  christos       return false;
   1619   1.9  christos     }
   1620   1.9  christos   if (opnd->reglist.stride != stride)
   1621   1.9  christos     {
   1622   1.9  christos       set_reg_list_stride_error (mismatch_detail, idx, stride);
   1623   1.9  christos       return false;
   1624   1.9  christos     }
   1625   1.9  christos   return true;
   1626  1.10  christos }
   1627  1.10  christos 
   1628  1.10  christos typedef struct
   1629  1.10  christos {
   1630  1.10  christos   int64_t min;
   1631  1.10  christos   int64_t max;
   1632  1.10  christos } imm_range_t;
   1633  1.10  christos 
   1634  1.10  christos static imm_range_t
   1635  1.10  christos imm_range_min_max (unsigned size, bool signed_rng)
   1636  1.10  christos {
   1637  1.10  christos   assert (size < 63);
   1638  1.10  christos   imm_range_t r;
   1639  1.10  christos   if (signed_rng)
   1640  1.10  christos     {
   1641  1.10  christos       r.max = (((int64_t) 0x1) << (size - 1)) - 1;
   1642  1.10  christos       r.min = - r.max - 1;
   1643  1.10  christos     }
   1644  1.10  christos   else
   1645  1.10  christos     {
   1646  1.10  christos       r.max = (((int64_t) 0x1) << size) - 1;
   1647  1.10  christos       r.min = 0;
   1648  1.10  christos     }
   1649  1.10  christos   return r;
   1650  1.10  christos }
   1651  1.10  christos 
   1652  1.10  christos /* Check that an immediate value is in the range provided by the
   1653  1.10  christos    operand type.  */
   1654  1.10  christos static bool
   1655  1.10  christos check_immediate_out_of_range (int64_t imm,
   1656  1.10  christos 			      enum aarch64_opnd type,
   1657  1.10  christos 			      aarch64_operand_error *mismatch_detail,
   1658  1.10  christos 			      int idx)
   1659  1.10  christos {
   1660  1.10  christos   const aarch64_operand *operand = get_operand_from_code (type);
   1661  1.10  christos   uint8_t size = get_operand_fields_width (operand);
   1662  1.10  christos   bool unsigned_imm = operand_need_unsigned_offset (operand);
   1663  1.10  christos   bool (*value_fit_field) (int64_t, unsigned)
   1664  1.10  christos     = (unsigned_imm
   1665  1.10  christos       ? value_fit_unsigned_field_p
   1666  1.10  christos       : value_fit_signed_field_p);
   1667  1.10  christos 
   1668  1.10  christos   if (!value_fit_field (imm, size))
   1669  1.10  christos     {
   1670  1.10  christos       imm_range_t rng = imm_range_min_max (size, !unsigned_imm);
   1671  1.10  christos       set_imm_out_of_range_error (mismatch_detail, idx, rng.min, rng.max);
   1672  1.10  christos       return false;
   1673  1.10  christos     }
   1674  1.10  christos   return true;
   1675   1.9  christos }
   1676   1.9  christos 
   1677   1.9  christos /* Check that indexed ZA operand OPND has:
   1678   1.9  christos 
   1679   1.9  christos    - a selection register in the range [MIN_WREG, MIN_WREG + 3]
   1680   1.9  christos 
   1681   1.9  christos    - RANGE_SIZE consecutive immediate offsets.
   1682   1.9  christos 
   1683   1.9  christos    - an initial immediate offset that is a multiple of RANGE_SIZE
   1684  1.10  christos      in the range [0, MAX_VALUE * RANGE_SIZE]
   1685   1.9  christos 
   1686  1.10  christos    - a vector group size of GROUP_SIZE.
   1687   1.9  christos 
   1688   1.9  christos    - STATUS_VG for cases where VGx2 or VGx4 is mandatory.  */
   1689   1.9  christos static bool
   1690   1.9  christos check_za_access (const aarch64_opnd_info *opnd,
   1691  1.10  christos 		 aarch64_operand_error *mismatch_detail, int idx,
   1692   1.9  christos 		 int min_wreg, int max_value, unsigned int range_size,
   1693   1.9  christos 		 int group_size, bool status_vg)
   1694   1.9  christos {
   1695   1.9  christos   if (!value_in_range_p (opnd->indexed_za.index.regno, min_wreg, min_wreg + 3))
   1696   1.9  christos     {
   1697   1.9  christos       if (min_wreg == 12)
   1698   1.9  christos 	set_other_error (mismatch_detail, idx,
   1699   1.9  christos 			 _("expected a selection register in the"
   1700   1.9  christos 			   " range w12-w15"));
   1701   1.9  christos       else if (min_wreg == 8)
   1702   1.9  christos 	set_other_error (mismatch_detail, idx,
   1703   1.9  christos 			 _("expected a selection register in the"
   1704   1.9  christos 			   " range w8-w11"));
   1705   1.9  christos       else
   1706   1.9  christos 	abort ();
   1707   1.9  christos       return false;
   1708   1.9  christos     }
   1709   1.9  christos 
   1710   1.9  christos   int max_index = max_value * range_size;
   1711   1.9  christos   if (!value_in_range_p (opnd->indexed_za.index.imm, 0, max_index))
   1712   1.9  christos     {
   1713   1.9  christos       set_offset_out_of_range_error (mismatch_detail, idx, 0, max_index);
   1714   1.9  christos       return false;
   1715   1.9  christos     }
   1716   1.9  christos 
   1717   1.9  christos   if ((opnd->indexed_za.index.imm % range_size) != 0)
   1718   1.9  christos     {
   1719   1.9  christos       assert (range_size == 2 || range_size == 4);
   1720   1.9  christos       set_other_error (mismatch_detail, idx,
   1721   1.9  christos 		       range_size == 2
   1722   1.9  christos 		       ? _("starting offset is not a multiple of 2")
   1723   1.9  christos 		       : _("starting offset is not a multiple of 4"));
   1724   1.9  christos       return false;
   1725   1.9  christos     }
   1726   1.9  christos 
   1727   1.9  christos   if (opnd->indexed_za.index.countm1 != range_size - 1)
   1728   1.9  christos     {
   1729   1.9  christos       if (range_size == 1)
   1730   1.9  christos 	set_other_error (mismatch_detail, idx,
   1731   1.9  christos 			 _("expected a single offset rather than"
   1732   1.9  christos 			   " a range"));
   1733   1.9  christos       else if (range_size == 2)
   1734   1.9  christos 	set_other_error (mismatch_detail, idx,
   1735   1.9  christos 			 _("expected a range of two offsets"));
   1736   1.9  christos       else if (range_size == 4)
   1737   1.9  christos 	set_other_error (mismatch_detail, idx,
   1738   1.9  christos 			 _("expected a range of four offsets"));
   1739   1.9  christos       else
   1740   1.9  christos 	abort ();
   1741   1.9  christos       return false;
   1742   1.9  christos     }
   1743  1.10  christos 
   1744  1.10  christos   /* The vector group specifier is optional in assembly code.  */
   1745   1.9  christos   if (opnd->indexed_za.group_size != group_size
   1746   1.9  christos       && (status_vg || opnd->indexed_za.group_size != 0 ))
   1747   1.9  christos     {
   1748   1.9  christos       set_invalid_vg_size (mismatch_detail, idx, group_size);
   1749   1.9  christos       return false;
   1750   1.9  christos     }
   1751   1.9  christos 
   1752   1.9  christos   return true;
   1753   1.9  christos }
   1754   1.9  christos 
   1755   1.9  christos /* Given a load/store operation, calculate the size of transferred data via a
   1756   1.9  christos    cumulative sum of qualifier sizes preceding the address operand in the
   1757   1.9  christos    OPNDS operand list argument.  */
   1758   1.9  christos int
   1759   1.9  christos calc_ldst_datasize (const aarch64_opnd_info *opnds)
   1760   1.9  christos {
   1761   1.9  christos   unsigned num_bytes = 0; /* total number of bytes transferred.  */
   1762   1.9  christos   enum aarch64_operand_class opnd_class;
   1763   1.9  christos   enum aarch64_opnd type;
   1764   1.9  christos 
   1765   1.9  christos   for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
   1766   1.9  christos     {
   1767   1.9  christos       type = opnds[i].type;
   1768   1.9  christos       opnd_class = aarch64_operands[type].op_class;
   1769   1.9  christos       if (opnd_class == AARCH64_OPND_CLASS_ADDRESS)
   1770   1.9  christos 	break;
   1771   1.9  christos       num_bytes += aarch64_get_qualifier_esize (opnds[i].qualifier);
   1772   1.9  christos     }
   1773   1.9  christos   return num_bytes;
   1774   1.9  christos }
   1775   1.1  christos 
   1776   1.1  christos 
   1777   1.1  christos /* General constraint checking based on operand code.
   1778   1.1  christos 
   1779   1.1  christos    Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
   1780   1.1  christos    as the IDXth operand of opcode OPCODE.  Otherwise return 0.
   1781   1.1  christos 
   1782   1.1  christos    This function has to be called after the qualifiers for all operands
   1783   1.1  christos    have been resolved.
   1784   1.1  christos 
   1785   1.1  christos    Mismatching error message is returned in *MISMATCH_DETAIL upon request,
   1786   1.1  christos    i.e. when MISMATCH_DETAIL is non-NULL.  This avoids the generation
   1787   1.1  christos    of error message during the disassembling where error message is not
   1788   1.1  christos    wanted.  We avoid the dynamic construction of strings of error messages
   1789   1.1  christos    here (i.e. in libopcodes), as it is costly and complicated; instead, we
   1790   1.1  christos    use a combination of error code, static string and some integer data to
   1791  1.10  christos    represent an error.  */
   1792   1.1  christos 
   1793   1.1  christos static bool
   1794   1.1  christos operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
   1795   1.1  christos 				  enum aarch64_opnd type,
   1796   1.1  christos 				  const aarch64_opcode *opcode,
   1797   1.6  christos 				  aarch64_operand_error *mismatch_detail)
   1798   1.1  christos {
   1799   1.6  christos   unsigned num, modifiers, shift;
   1800   1.6  christos   unsigned char size;
   1801   1.1  christos   int64_t imm, min_value, max_value;
   1802   1.1  christos   uint64_t uvalue, mask;
   1803   1.8  christos   const aarch64_opnd_info *opnd = opnds + idx;
   1804   1.1  christos   aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
   1805   1.1  christos   int i;
   1806   1.1  christos 
   1807   1.1  christos   assert (opcode->operands[idx] == opnd->type && opnd->type == type);
   1808   1.1  christos 
   1809   1.1  christos   switch (aarch64_operands[type].op_class)
   1810   1.9  christos     {
   1811   1.9  christos     case AARCH64_OPND_CLASS_INT_REG:
   1812   1.9  christos       /* Check for pair of xzr registers.  */
   1813   1.9  christos       if (type == AARCH64_OPND_PAIRREG_OR_XZR
   1814   1.9  christos 	  && opnds[idx - 1].reg.regno == 0x1f)
   1815   1.9  christos 	{
   1816   1.9  christos 	  if (opnds[idx].reg.regno != 0x1f)
   1817   1.9  christos 	    {
   1818   1.9  christos 	      set_syntax_error (mismatch_detail, idx - 1,
   1819  1.10  christos 				_("second reg in pair should be xzr if first is"
   1820   1.9  christos 				  " xzr"));
   1821   1.9  christos 	      return false;
   1822   1.9  christos 	    }
   1823   1.9  christos 	}
   1824   1.9  christos       /* Check pair reg constraints for instructions taking a pair of
   1825   1.9  christos 	 consecutively-numbered general-purpose registers.  */
   1826   1.3  christos       else if (type == AARCH64_OPND_PAIRREG
   1827   1.9  christos 	       || type == AARCH64_OPND_PAIRREG_OR_XZR)
   1828   1.3  christos 	{
   1829   1.3  christos 	  assert (idx == 1 || idx == 2 || idx == 3 || idx == 5);
   1830   1.3  christos 	  if (opnds[idx - 1].reg.regno % 2 != 0)
   1831   1.3  christos 	    {
   1832  1.10  christos 	      set_syntax_error (mismatch_detail, idx - 1,
   1833   1.3  christos 				_("reg pair must start from even reg"));
   1834   1.3  christos 	      return false;
   1835   1.3  christos 	    }
   1836   1.3  christos 	  if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
   1837   1.3  christos 	    {
   1838  1.10  christos 	      set_syntax_error (mismatch_detail, idx,
   1839   1.3  christos 				_("reg pair must be contiguous"));
   1840   1.3  christos 	      return false;
   1841   1.3  christos 	    }
   1842   1.3  christos 	  break;
   1843   1.1  christos 	}
   1844   1.1  christos 
   1845   1.1  christos       /* <Xt> may be optional in some IC and TLBI instructions.  */
   1846   1.1  christos       if (type == AARCH64_OPND_Rt_SYS)
   1847   1.1  christos 	{
   1848   1.3  christos 	  assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
   1849   1.3  christos 			       == AARCH64_OPND_CLASS_SYSTEM));
   1850   1.1  christos 	  if (opnds[1].present
   1851   1.1  christos 	      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
   1852  1.10  christos 	    {
   1853   1.1  christos 	      set_other_error (mismatch_detail, idx, _("extraneous register"));
   1854   1.3  christos 	      return false;
   1855   1.3  christos 	    }
   1856   1.1  christos 	  if (!opnds[1].present
   1857   1.1  christos 	      && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
   1858  1.10  christos 	    {
   1859   1.1  christos 	      set_other_error (mismatch_detail, idx, _("missing register"));
   1860   1.1  christos 	      return false;
   1861   1.1  christos 	    }
   1862   1.1  christos 	}
   1863   1.1  christos       switch (qualifier)
   1864   1.1  christos 	{
   1865   1.1  christos 	case AARCH64_OPND_QLF_WSP:
   1866   1.1  christos 	case AARCH64_OPND_QLF_SP:
   1867   1.1  christos 	  if (!aarch64_stack_pointer_p (opnd))
   1868   1.8  christos 	    {
   1869  1.10  christos 	      set_other_error (mismatch_detail, idx,
   1870   1.1  christos 		       _("stack pointer register expected"));
   1871   1.1  christos 	      return false;
   1872   1.1  christos 	    }
   1873   1.1  christos 	  break;
   1874   1.1  christos 	default:
   1875   1.1  christos 	  break;
   1876   1.1  christos 	}
   1877   1.6  christos       break;
   1878   1.6  christos 
   1879   1.6  christos     case AARCH64_OPND_CLASS_SVE_REG:
   1880   1.6  christos       switch (type)
   1881   1.6  christos 	{
   1882   1.9  christos 	case AARCH64_OPND_SVE_Zm3_INDEX:
   1883   1.7  christos 	case AARCH64_OPND_SVE_Zm3_22_INDEX:
   1884  1.10  christos 	case AARCH64_OPND_SVE_Zm3_19_INDEX:
   1885   1.7  christos 	case AARCH64_OPND_SVE_Zm3_11_INDEX:
   1886   1.6  christos 	case AARCH64_OPND_SVE_Zm3_10_INDEX:
   1887   1.6  christos 	case AARCH64_OPND_SVE_Zm4_11_INDEX:
   1888   1.6  christos 	case AARCH64_OPND_SVE_Zm4_INDEX:
   1889   1.9  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   1890   1.9  christos 	  shift = get_operand_specific_data (&aarch64_operands[type]);
   1891   1.9  christos 	  if (!check_reglane (opnd, mismatch_detail, idx,
   1892  1.10  christos 			      "z", 0, (1 << shift) - 1,
   1893  1.10  christos 			      0, (1u << (size - shift)) - 1))
   1894  1.10  christos 	    return false;
   1895  1.10  christos 	  break;
   1896  1.10  christos 
   1897  1.10  christos 	case AARCH64_OPND_SVE_Zm1_23_INDEX:
   1898  1.10  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   1899  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 1))
   1900  1.10  christos 	    return 0;
   1901  1.10  christos 	  break;
   1902  1.10  christos 
   1903  1.10  christos 	case AARCH64_OPND_SME_Zn_INDEX2_19:
   1904  1.10  christos 	case AARCH64_OPND_SVE_Zm2_22_INDEX:
   1905   1.9  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   1906   1.9  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
   1907   1.9  christos 	    return 0;
   1908   1.9  christos 	  break;
   1909   1.9  christos 
   1910   1.9  christos 	case AARCH64_OPND_SVE_Zn_INDEX:
   1911   1.9  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   1912  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
   1913   1.9  christos 			      0, 64 / size - 1))
   1914   1.9  christos 	    return false;
   1915   1.9  christos 	  break;
   1916   1.9  christos 
   1917   1.9  christos 	case AARCH64_OPND_SVE_Zn_5_INDEX:
   1918   1.9  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   1919  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
   1920   1.9  christos 			      0, 16 / size - 1))
   1921   1.9  christos 	    return false;
   1922   1.9  christos 	  break;
   1923   1.9  christos 
   1924   1.9  christos 	case AARCH64_OPND_SME_PNn3_INDEX1:
   1925   1.9  christos 	case AARCH64_OPND_SME_PNn3_INDEX2:
   1926   1.9  christos 	  size = get_operand_field_width (get_operand_from_code (type), 1);
   1927  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
   1928   1.9  christos 			      0, (1 << size) - 1))
   1929   1.9  christos 	    return false;
   1930  1.10  christos 	  break;
   1931   1.9  christos 
   1932   1.9  christos 	case AARCH64_OPND_SVE_Zm3_12_INDEX:
   1933   1.9  christos 	case AARCH64_OPND_SME_Zn_INDEX1_16:
   1934   1.9  christos 	case AARCH64_OPND_SME_Zn_INDEX2_15:
   1935   1.9  christos 	case AARCH64_OPND_SME_Zn_INDEX2_16:
   1936   1.9  christos 	case AARCH64_OPND_SME_Zn_INDEX3_14:
   1937  1.10  christos 	case AARCH64_OPND_SME_Zn_INDEX3_15:
   1938  1.10  christos 	case AARCH64_OPND_SME_Zn_INDEX4_14:
   1939  1.10  christos 	case AARCH64_OPND_SVE_Zn0_INDEX:
   1940  1.10  christos 	case AARCH64_OPND_SVE_Zn1_17_INDEX:
   1941  1.10  christos 	case AARCH64_OPND_SVE_Zn2_18_INDEX:
   1942  1.10  christos 	case AARCH64_OPND_SVE_Zn3_22_INDEX:
   1943  1.10  christos 	case AARCH64_OPND_SVE_Zd0_INDEX:
   1944  1.10  christos 	case AARCH64_OPND_SVE_Zd1_17_INDEX:
   1945   1.9  christos 	case AARCH64_OPND_SVE_Zd2_18_INDEX:
   1946   1.9  christos 	case AARCH64_OPND_SVE_Zd3_22_INDEX:
   1947   1.9  christos 	  size = get_operand_fields_width (get_operand_from_code (type)) - 5;
   1948  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
   1949   1.9  christos 			      0, (1 << size) - 1))
   1950   1.9  christos 	    return false;
   1951   1.9  christos 	  break;
   1952   1.9  christos 
   1953  1.10  christos 	case AARCH64_OPND_SME_Zm_INDEX1:
   1954   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX2:
   1955   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX2_3:
   1956  1.10  christos 	case AARCH64_OPND_SME_Zm_INDEX3_1:
   1957   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX3_2:
   1958   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX3_3:
   1959  1.10  christos 	case AARCH64_OPND_SME_Zm_INDEX3_10:
   1960  1.10  christos 	case AARCH64_OPND_SME_Zm_INDEX4_1:
   1961   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX4_2:
   1962   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX4_3:
   1963   1.9  christos 	case AARCH64_OPND_SME_Zm_INDEX4_10:
   1964   1.9  christos 	  size = get_operand_fields_width (get_operand_from_code (type)) - 4;
   1965  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
   1966   1.9  christos 			      0, (1 << size) - 1))
   1967   1.9  christos 	    return false;
   1968   1.9  christos 	  break;
   1969  1.10  christos 
   1970   1.9  christos 	case AARCH64_OPND_SME_Zm:
   1971   1.6  christos 	case AARCH64_OPND_SME_Zm_17:
   1972   1.9  christos 	  if (opnd->reg.regno > 15)
   1973  1.10  christos 	    {
   1974   1.6  christos 	      set_invalid_regno_error (mismatch_detail, idx, "z", 0, 15);
   1975   1.9  christos 	      return false;
   1976   1.9  christos 	    }
   1977   1.9  christos 	  break;
   1978   1.9  christos 
   1979   1.9  christos 	case AARCH64_OPND_SME_PnT_Wm_imm:
   1980   1.9  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   1981  1.10  christos 	  max_value = 16 / size - 1;
   1982  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx,
   1983   1.9  christos 				12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
   1984   1.9  christos 	    return false;
   1985   1.9  christos 	  break;
   1986   1.9  christos 
   1987   1.9  christos 	default:
   1988   1.9  christos 	  break;
   1989   1.9  christos 	}
   1990   1.9  christos       break;
   1991   1.9  christos 
   1992   1.9  christos     case AARCH64_OPND_CLASS_SVE_REGLIST:
   1993   1.9  christos       switch (type)
   1994   1.9  christos 	{
   1995   1.9  christos 	case AARCH64_OPND_SME_Pdx2:
   1996   1.9  christos 	case AARCH64_OPND_SME_Zdnx2:
   1997   1.9  christos 	case AARCH64_OPND_SME_Zdnx4:
   1998   1.9  christos 	case AARCH64_OPND_SME_Zmx2:
   1999  1.10  christos 	case AARCH64_OPND_SME_Zmx4:
   2000   1.9  christos 	case AARCH64_OPND_SME_Znx2:
   2001   1.9  christos 	case AARCH64_OPND_SME_Znx2_BIT_INDEX:
   2002   1.9  christos 	case AARCH64_OPND_SME_Znx4:
   2003  1.10  christos 	  num = get_operand_specific_data (&aarch64_operands[type]);
   2004   1.9  christos 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
   2005   1.6  christos 	    return false;
   2006   1.9  christos 	  if ((opnd->reglist.first_regno % num) != 0)
   2007   1.9  christos 	    {
   2008  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2009   1.6  christos 			       _("start register out of range"));
   2010   1.6  christos 	      return false;
   2011   1.6  christos 	    }
   2012   1.9  christos 	  break;
   2013   1.9  christos 
   2014   1.9  christos 	case AARCH64_OPND_SME_Ztx2_STRIDED:
   2015   1.9  christos 	case AARCH64_OPND_SME_Ztx4_STRIDED:
   2016   1.9  christos 	  /* 2-register lists have a stride of 8 and 4-register lists
   2017   1.9  christos 	     have a stride of 4.  */
   2018  1.10  christos 	  num = get_operand_specific_data (&aarch64_operands[type]);
   2019   1.9  christos 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
   2020   1.9  christos 	    return false;
   2021   1.6  christos 	  num = 16 | (opnd->reglist.stride - 1);
   2022   1.9  christos 	  if ((opnd->reglist.first_regno & ~num) != 0)
   2023   1.9  christos 	    {
   2024  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2025   1.6  christos 			       _("start register out of range"));
   2026   1.6  christos 	      return false;
   2027   1.6  christos 	    }
   2028   1.9  christos 	  break;
   2029   1.6  christos 
   2030   1.6  christos 	case AARCH64_OPND_SME_PdxN:
   2031   1.9  christos 	case AARCH64_OPND_SVE_ZnxN:
   2032   1.9  christos 	case AARCH64_OPND_SVE_ZtxN:
   2033  1.10  christos 	  num = get_opcode_dependent_value (opcode);
   2034   1.6  christos 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
   2035   1.6  christos 	    return false;
   2036   1.6  christos 	  break;
   2037   1.9  christos 
   2038   1.9  christos 	default:
   2039   1.9  christos 	  abort ();
   2040   1.9  christos 	}
   2041   1.9  christos       break;
   2042   1.9  christos 
   2043   1.9  christos     case AARCH64_OPND_CLASS_ZA_ACCESS:
   2044   1.9  christos       switch (type)
   2045   1.9  christos 	{
   2046   1.9  christos 	case AARCH64_OPND_SME_ZA_HV_idx_src:
   2047   1.9  christos 	case AARCH64_OPND_SME_ZA_HV_idx_dest:
   2048   1.9  christos 	case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
   2049   1.9  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   2050  1.10  christos 	  max_value = 16 / size - 1;
   2051  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
   2052  1.10  christos 				get_opcode_dependent_value (opcode),
   2053   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2054   1.9  christos 	    return false;
   2055   1.9  christos 	  break;
   2056   1.9  christos 
   2057  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off4:
   2058  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
   2059  1.10  christos 				get_opcode_dependent_value (opcode),
   2060   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2061   1.9  christos 	    return false;
   2062   1.9  christos 	  break;
   2063   1.9  christos 
   2064   1.9  christos 	case AARCH64_OPND_SME_ZA_array_off3_0:
   2065  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off3_5:
   2066  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
   2067  1.10  christos 				get_opcode_dependent_value (opcode),
   2068   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2069   1.9  christos 	    return false;
   2070   1.9  christos 	  break;
   2071   1.9  christos 
   2072  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off1x4:
   2073  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
   2074  1.10  christos 				get_opcode_dependent_value (opcode),
   2075   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2076   1.9  christos 	    return false;
   2077   1.9  christos 	  break;
   2078   1.9  christos 
   2079  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off2x2:
   2080  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
   2081  1.10  christos 				get_opcode_dependent_value (opcode),
   2082   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2083   1.9  christos 	    return false;
   2084   1.9  christos 	  break;
   2085   1.9  christos 
   2086  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off2x4:
   2087  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
   2088  1.10  christos 				get_opcode_dependent_value (opcode),
   2089   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2090   1.9  christos 	    return false;
   2091   1.9  christos 	  break;
   2092   1.9  christos 
   2093  1.10  christos 	case AARCH64_OPND_SME_ZA_array_off3x2:
   2094  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
   2095  1.10  christos 				get_opcode_dependent_value (opcode),
   2096   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2097   1.9  christos 	    return false;
   2098   1.9  christos 	  break;
   2099   1.9  christos 
   2100  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsb_1:
   2101  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
   2102  1.10  christos 				get_opcode_dependent_value (opcode),
   2103   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2104   1.9  christos 	    return false;
   2105   1.9  christos 	  break;
   2106   1.9  christos 
   2107  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsh_1:
   2108  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
   2109  1.10  christos 				get_opcode_dependent_value (opcode),
   2110   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2111   1.9  christos 	    return false;
   2112   1.9  christos 	  break;
   2113   1.9  christos 
   2114  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrss_1:
   2115  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
   2116  1.10  christos 				get_opcode_dependent_value (opcode),
   2117   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2118   1.9  christos 	    return false;
   2119   1.9  christos 	  break;
   2120   1.9  christos 
   2121  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsd_1:
   2122  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
   2123  1.10  christos 				get_opcode_dependent_value (opcode),
   2124   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2125   1.9  christos 	    return false;
   2126   1.9  christos 	  break;
   2127   1.9  christos 
   2128  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsb_2:
   2129  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
   2130  1.10  christos 				get_opcode_dependent_value (opcode),
   2131   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2132   1.9  christos 	    return false;
   2133   1.9  christos 	  break;
   2134   1.9  christos 
   2135  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsh_2:
   2136  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
   2137  1.10  christos 				get_opcode_dependent_value (opcode),
   2138  1.10  christos 				get_opcode_dependent_vg_status (opcode)))
   2139  1.10  christos 	    return false;
   2140  1.10  christos 	  break;
   2141  1.10  christos 
   2142  1.10  christos 	case AARCH64_OPND_SME_ZA_ARRAY4:
   2143  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
   2144  1.10  christos 				get_opcode_dependent_value (opcode),
   2145   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2146   1.9  christos 	    return false;
   2147   1.9  christos 	  break;
   2148   1.9  christos 
   2149   1.9  christos 	case AARCH64_OPND_SME_ZA_array_vrss_2:
   2150  1.10  christos 	case AARCH64_OPND_SME_ZA_array_vrsd_2:
   2151  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
   2152  1.10  christos 				get_opcode_dependent_value (opcode),
   2153   1.9  christos 				get_opcode_dependent_vg_status (opcode)))
   2154   1.9  christos 	    return false;
   2155   1.9  christos 	  break;
   2156   1.9  christos 
   2157   1.9  christos 	case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
   2158   1.9  christos 	case AARCH64_OPND_SME_ZA_HV_idx_destxN:
   2159   1.9  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   2160   1.9  christos 	  num = get_opcode_dependent_value (opcode);
   2161   1.9  christos 	  max_value = 16 / num / size;
   2162  1.10  christos 	  if (max_value > 0)
   2163  1.10  christos 	    max_value -= 1;
   2164  1.10  christos 	  if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
   2165   1.6  christos 				0, get_opcode_dependent_value (opcode)))
   2166   1.9  christos 	    return false;
   2167   1.9  christos 	  break;
   2168   1.9  christos 
   2169   1.6  christos 	default:
   2170   1.6  christos 	  abort ();
   2171   1.6  christos 	}
   2172   1.6  christos       break;
   2173   1.9  christos 
   2174   1.6  christos     case AARCH64_OPND_CLASS_PRED_REG:
   2175   1.9  christos       switch (type)
   2176   1.9  christos 	{
   2177   1.9  christos 	case AARCH64_OPND_SME_PNd3:
   2178   1.9  christos 	case AARCH64_OPND_SME_PNg3:
   2179   1.9  christos 	  if (opnd->reg.regno < 8)
   2180  1.10  christos 	    {
   2181   1.9  christos 	      set_invalid_regno_error (mismatch_detail, idx, "pn", 8, 15);
   2182   1.9  christos 	      return false;
   2183   1.9  christos 	    }
   2184   1.9  christos 	  break;
   2185   1.9  christos 
   2186   1.9  christos 	default:
   2187   1.9  christos 	  if (opnd->reg.regno >= 8
   2188   1.9  christos 	      && get_operand_fields_width (get_operand_from_code (type)) == 3)
   2189  1.10  christos 	    {
   2190   1.9  christos 	      set_invalid_regno_error (mismatch_detail, idx, "p", 0, 7);
   2191   1.9  christos 	      return false;
   2192   1.6  christos 	    }
   2193   1.6  christos 	  break;
   2194   1.6  christos 	}
   2195   1.3  christos       break;
   2196   1.3  christos 
   2197   1.3  christos     case AARCH64_OPND_CLASS_COND:
   2198   1.3  christos       if (type == AARCH64_OPND_COND1
   2199   1.3  christos 	  && (opnds[idx].cond->value & 0xe) == 0xe)
   2200   1.3  christos 	{
   2201   1.3  christos 	  /* Not allow AL or NV.  */
   2202   1.3  christos 	  set_syntax_error (mismatch_detail, idx, NULL);
   2203   1.3  christos 	}
   2204   1.1  christos       break;
   2205   1.1  christos 
   2206   1.1  christos     case AARCH64_OPND_CLASS_ADDRESS:
   2207   1.1  christos       /* Check writeback.  */
   2208   1.1  christos       switch (opcode->iclass)
   2209   1.1  christos 	{
   2210   1.1  christos 	case ldst_pos:
   2211   1.1  christos 	case ldst_unscaled:
   2212   1.1  christos 	case ldstnapair_offs:
   2213   1.1  christos 	case ldstpair_off:
   2214   1.1  christos 	case ldst_unpriv:
   2215   1.3  christos 	  if (opnd->addr.writeback == 1)
   2216   1.3  christos 	    {
   2217  1.10  christos 	      set_syntax_error (mismatch_detail, idx,
   2218   1.1  christos 				_("unexpected address writeback"));
   2219   1.1  christos 	      return false;
   2220   1.6  christos 	    }
   2221   1.6  christos 	  break;
   2222   1.6  christos 	case ldst_imm10:
   2223   1.6  christos 	  if (opnd->addr.writeback == 1 && opnd->addr.preind != 1)
   2224   1.6  christos 	    {
   2225  1.10  christos 	      set_syntax_error (mismatch_detail, idx,
   2226   1.6  christos 				_("unexpected address writeback"));
   2227   1.6  christos 	      return false;
   2228   1.1  christos 	    }
   2229   1.1  christos 	  break;
   2230   1.1  christos 	case ldst_imm9:
   2231   1.1  christos 	case ldstpair_indexed:
   2232   1.1  christos 	case asisdlsep:
   2233   1.1  christos 	case asisdlsop:
   2234   1.3  christos 	  if (opnd->addr.writeback == 0)
   2235   1.3  christos 	    {
   2236  1.10  christos 	      set_syntax_error (mismatch_detail, idx,
   2237   1.1  christos 				_("address writeback expected"));
   2238   1.1  christos 	      return false;
   2239   1.9  christos 	    }
   2240   1.9  christos 	  break;
   2241   1.9  christos 	case rcpc3:
   2242   1.9  christos 	  if (opnd->addr.writeback)
   2243   1.9  christos 	    if ((type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB
   2244   1.9  christos 		 && !opnd->addr.preind)
   2245   1.9  christos 		|| (type == AARCH64_OPND_RCPC3_ADDR_POSTIND
   2246   1.9  christos 		    && !opnd->addr.postind))
   2247   1.9  christos 	      {
   2248  1.10  christos 		set_syntax_error (mismatch_detail, idx,
   2249   1.9  christos 				  _("unexpected address writeback"));
   2250   1.9  christos 		return false;
   2251   1.9  christos 	      }
   2252   1.1  christos 
   2253   1.1  christos 	  break;
   2254   1.1  christos 	default:
   2255   1.1  christos 	  assert (opnd->addr.writeback == 0);
   2256   1.1  christos 	  break;
   2257   1.1  christos 	}
   2258   1.1  christos       switch (type)
   2259   1.1  christos 	{
   2260   1.1  christos 	case AARCH64_OPND_ADDR_SIMM7:
   2261   1.1  christos 	  /* Scaled signed 7 bits immediate offset.  */
   2262   1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   2263   1.1  christos 	     different from that of the source register size,
   2264   1.1  christos 	     e.g. in strb/ldrb.  */
   2265   1.1  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   2266   1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
   2267   1.1  christos 	    {
   2268  1.10  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   2269   1.1  christos 					     -64 * size, 63 * size);
   2270   1.1  christos 	      return false;
   2271   1.1  christos 	    }
   2272   1.1  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
   2273  1.10  christos 	    {
   2274   1.1  christos 	      set_unaligned_error (mismatch_detail, idx, size);
   2275   1.1  christos 	      return false;
   2276   1.6  christos 	    }
   2277   1.1  christos 	  break;
   2278   1.1  christos 	case AARCH64_OPND_ADDR_OFFSET:
   2279   1.1  christos 	case AARCH64_OPND_ADDR_SIMM9:
   2280   1.1  christos 	  /* Unscaled signed 9 bits immediate offset.  */
   2281   1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
   2282  1.10  christos 	    {
   2283   1.1  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
   2284   1.1  christos 	      return false;
   2285   1.1  christos 	    }
   2286   1.1  christos 	  break;
   2287   1.1  christos 
   2288   1.1  christos 	case AARCH64_OPND_ADDR_SIMM9_2:
   2289   1.1  christos 	  /* Unscaled signed 9 bits immediate offset, which has to be negative
   2290   1.1  christos 	     or unaligned.  */
   2291   1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   2292   1.1  christos 	  if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
   2293  1.10  christos 	       && !value_aligned_p (opnd->addr.offset.imm, size))
   2294   1.1  christos 	      || value_in_range_p (opnd->addr.offset.imm, -256, -1))
   2295   1.1  christos 	    return true;
   2296  1.10  christos 	  set_other_error (mismatch_detail, idx,
   2297   1.1  christos 			   _("negative or unaligned offset expected"));
   2298   1.6  christos 	  return false;
   2299   1.6  christos 
   2300   1.6  christos 	case AARCH64_OPND_ADDR_SIMM10:
   2301   1.6  christos 	  /* Scaled signed 10 bits immediate offset.  */
   2302   1.6  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4088))
   2303  1.10  christos 	    {
   2304   1.6  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4088);
   2305   1.6  christos 	      return false;
   2306   1.6  christos 	    }
   2307   1.6  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, 8))
   2308  1.10  christos 	    {
   2309   1.6  christos 	      set_unaligned_error (mismatch_detail, idx, 8);
   2310   1.6  christos 	      return false;
   2311   1.6  christos 	    }
   2312   1.7  christos 	  break;
   2313   1.7  christos 
   2314   1.7  christos 	case AARCH64_OPND_ADDR_SIMM11:
   2315   1.7  christos 	  /* Signed 11 bits immediate offset (multiple of 16).  */
   2316   1.7  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -1024, 1008))
   2317  1.10  christos 	    {
   2318   1.7  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, -1024, 1008);
   2319   1.7  christos 	      return false;
   2320   1.7  christos 	    }
   2321   1.7  christos 
   2322   1.7  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, 16))
   2323  1.10  christos 	    {
   2324   1.7  christos 	      set_unaligned_error (mismatch_detail, idx, 16);
   2325   1.7  christos 	      return false;
   2326   1.7  christos 	    }
   2327   1.7  christos 	  break;
   2328   1.7  christos 
   2329   1.7  christos 	case AARCH64_OPND_ADDR_SIMM13:
   2330   1.7  christos 	  /* Signed 13 bits immediate offset (multiple of 16).  */
   2331   1.7  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4080))
   2332  1.10  christos 	    {
   2333   1.7  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4080);
   2334   1.7  christos 	      return false;
   2335   1.7  christos 	    }
   2336   1.7  christos 
   2337   1.7  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, 16))
   2338  1.10  christos 	    {
   2339   1.7  christos 	      set_unaligned_error (mismatch_detail, idx, 16);
   2340   1.7  christos 	      return false;
   2341   1.7  christos 	    }
   2342   1.1  christos 	  break;
   2343   1.1  christos 
   2344   1.1  christos 	case AARCH64_OPND_SIMD_ADDR_POST:
   2345   1.1  christos 	  /* AdvSIMD load/store multiple structures, post-index.  */
   2346   1.1  christos 	  assert (idx == 1);
   2347   1.1  christos 	  if (opnd->addr.offset.is_reg)
   2348  1.10  christos 	    {
   2349   1.1  christos 	      if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
   2350   1.1  christos 		return true;
   2351   1.1  christos 	      else
   2352   1.1  christos 		{
   2353  1.10  christos 		  set_other_error (mismatch_detail, idx,
   2354   1.1  christos 				   _("invalid register offset"));
   2355   1.1  christos 		  return false;
   2356   1.1  christos 		}
   2357   1.1  christos 	    }
   2358   1.1  christos 	  else
   2359   1.1  christos 	    {
   2360   1.1  christos 	      const aarch64_opnd_info *prev = &opnds[idx-1];
   2361   1.1  christos 	      unsigned num_bytes; /* total number of bytes transferred.  */
   2362   1.1  christos 	      /* The opcode dependent area stores the number of elements in
   2363   1.1  christos 		 each structure to be loaded/stored.  */
   2364   1.1  christos 	      int is_ld1r = get_opcode_dependent_value (opcode) == 1;
   2365   1.1  christos 	      if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
   2366   1.1  christos 		/* Special handling of loading single structure to all lane.  */
   2367   1.1  christos 		num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
   2368   1.1  christos 		  * aarch64_get_qualifier_esize (prev->qualifier);
   2369   1.1  christos 	      else
   2370   1.1  christos 		num_bytes = prev->reglist.num_regs
   2371   1.1  christos 		  * aarch64_get_qualifier_esize (prev->qualifier)
   2372   1.1  christos 		  * aarch64_get_qualifier_nelem (prev->qualifier);
   2373   1.1  christos 	      if ((int) num_bytes != opnd->addr.offset.imm)
   2374   1.1  christos 		{
   2375  1.10  christos 		  set_other_error (mismatch_detail, idx,
   2376   1.1  christos 				   _("invalid post-increment amount"));
   2377   1.1  christos 		  return false;
   2378   1.1  christos 		}
   2379   1.1  christos 	    }
   2380   1.1  christos 	  break;
   2381   1.1  christos 
   2382   1.1  christos 	case AARCH64_OPND_ADDR_REGOFF:
   2383   1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   2384   1.1  christos 	     different from that of the source register size,
   2385   1.1  christos 	     e.g. in strb/ldrb.  */
   2386   1.1  christos 	  size = aarch64_get_qualifier_esize (opnd->qualifier);
   2387   1.1  christos 	  /* It is either no shift or shift by the binary logarithm of SIZE.  */
   2388   1.1  christos 	  if (opnd->shifter.amount != 0
   2389   1.1  christos 	      && opnd->shifter.amount != (int)get_logsz (size))
   2390   1.1  christos 	    {
   2391  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2392   1.1  christos 			       _("invalid shift amount"));
   2393   1.1  christos 	      return false;
   2394   1.1  christos 	    }
   2395   1.1  christos 	  /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
   2396   1.1  christos 	     operators.  */
   2397   1.1  christos 	  switch (opnd->shifter.kind)
   2398   1.1  christos 	    {
   2399   1.1  christos 	    case AARCH64_MOD_UXTW:
   2400   1.1  christos 	    case AARCH64_MOD_LSL:
   2401   1.1  christos 	    case AARCH64_MOD_SXTW:
   2402   1.1  christos 	    case AARCH64_MOD_SXTX: break;
   2403   1.1  christos 	    default:
   2404  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2405   1.1  christos 			       _("invalid extend/shift operator"));
   2406   1.1  christos 	      return false;
   2407   1.1  christos 	    }
   2408   1.1  christos 	  break;
   2409   1.1  christos 
   2410   1.1  christos 	case AARCH64_OPND_ADDR_UIMM12:
   2411   1.1  christos 	  imm = opnd->addr.offset.imm;
   2412   1.1  christos 	  /* Get the size of the data element that is accessed, which may be
   2413   1.1  christos 	     different from that of the source register size,
   2414   1.1  christos 	     e.g. in strb/ldrb.  */
   2415   1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   2416   1.1  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
   2417   1.1  christos 	    {
   2418  1.10  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   2419   1.1  christos 					     0, 4095 * size);
   2420   1.1  christos 	      return false;
   2421   1.1  christos 	    }
   2422   1.1  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, size))
   2423  1.10  christos 	    {
   2424   1.1  christos 	      set_unaligned_error (mismatch_detail, idx, size);
   2425   1.1  christos 	      return false;
   2426   1.1  christos 	    }
   2427  1.10  christos 	  break;
   2428   1.1  christos 
   2429   1.1  christos 	case AARCH64_OPND_ADDR_PCREL9:
   2430   1.1  christos 	case AARCH64_OPND_ADDR_PCREL14:
   2431   1.1  christos 	case AARCH64_OPND_ADDR_PCREL19:
   2432  1.10  christos 	case AARCH64_OPND_ADDR_PCREL21:
   2433  1.10  christos 	case AARCH64_OPND_ADDR_PCREL26:
   2434  1.10  christos 	  {
   2435  1.10  christos 	    imm = opnd->imm.value;
   2436  1.10  christos 	    if (operand_need_shift_by_two (get_operand_from_code (type)))
   2437  1.10  christos 	      {
   2438  1.10  christos 		/* The offset value in a PC-relative branch instruction is alway
   2439  1.10  christos 		   4-byte aligned and is encoded without the lowest 2 bits.  */
   2440  1.10  christos 		if (!value_aligned_p (imm, 4))
   2441  1.10  christos 		  {
   2442  1.10  christos 		    set_unaligned_error (mismatch_detail, idx, 4);
   2443  1.10  christos 		    return false;
   2444  1.10  christos 		  }
   2445  1.10  christos 		/* Right shift by 2 so that we can carry out the following check
   2446  1.10  christos 		   canonically.  */
   2447  1.10  christos 		imm >>= 2;
   2448  1.10  christos 	      }
   2449  1.10  christos 
   2450  1.10  christos 	    if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
   2451   1.1  christos 	      return false;
   2452   1.1  christos 	  }
   2453   1.8  christos 	  break;
   2454   1.8  christos 
   2455   1.8  christos 	case AARCH64_OPND_SME_ADDR_RI_U4xVL:
   2456   1.8  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, 0, 15))
   2457  1.10  christos 	    {
   2458   1.8  christos 	      set_offset_out_of_range_error (mismatch_detail, idx, 0, 15);
   2459   1.8  christos 	      return false;
   2460   1.8  christos 	    }
   2461   1.6  christos 	  break;
   2462   1.6  christos 
   2463   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
   2464   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
   2465   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
   2466   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
   2467   1.6  christos 	  min_value = -8;
   2468   1.6  christos 	  max_value = 7;
   2469   1.6  christos 	sve_imm_offset_vl:
   2470   1.6  christos 	  assert (!opnd->addr.offset.is_reg);
   2471   1.6  christos 	  assert (opnd->addr.preind);
   2472   1.6  christos 	  num = 1 + get_operand_specific_data (&aarch64_operands[type]);
   2473   1.6  christos 	  min_value *= num;
   2474   1.6  christos 	  max_value *= num;
   2475   1.6  christos 	  if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
   2476   1.6  christos 	      || (opnd->shifter.operator_present
   2477   1.6  christos 		  && opnd->shifter.kind != AARCH64_MOD_MUL_VL))
   2478   1.6  christos 	    {
   2479  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2480   1.6  christos 			       _("invalid addressing mode"));
   2481   1.6  christos 	      return false;
   2482   1.6  christos 	    }
   2483   1.6  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
   2484   1.6  christos 	    {
   2485  1.10  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   2486   1.6  christos 					     min_value, max_value);
   2487   1.6  christos 	      return false;
   2488   1.6  christos 	    }
   2489   1.6  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, num))
   2490  1.10  christos 	    {
   2491   1.6  christos 	      set_unaligned_error (mismatch_detail, idx, num);
   2492   1.6  christos 	      return false;
   2493   1.6  christos 	    }
   2494   1.6  christos 	  break;
   2495   1.6  christos 
   2496   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
   2497   1.6  christos 	  min_value = -32;
   2498   1.6  christos 	  max_value = 31;
   2499   1.6  christos 	  goto sve_imm_offset_vl;
   2500   1.6  christos 
   2501   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
   2502   1.6  christos 	  min_value = -256;
   2503   1.6  christos 	  max_value = 255;
   2504   1.6  christos 	  goto sve_imm_offset_vl;
   2505   1.6  christos 
   2506   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_U6:
   2507   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_U6x2:
   2508   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_U6x4:
   2509   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_U6x8:
   2510   1.6  christos 	  min_value = 0;
   2511   1.6  christos 	  max_value = 63;
   2512   1.6  christos 	sve_imm_offset:
   2513   1.6  christos 	  assert (!opnd->addr.offset.is_reg);
   2514   1.6  christos 	  assert (opnd->addr.preind);
   2515   1.6  christos 	  num = 1 << get_operand_specific_data (&aarch64_operands[type]);
   2516   1.6  christos 	  min_value *= num;
   2517   1.6  christos 	  max_value *= num;
   2518   1.6  christos 	  if (opnd->shifter.operator_present
   2519   1.6  christos 	      || opnd->shifter.amount_present)
   2520   1.6  christos 	    {
   2521  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2522   1.6  christos 			       _("invalid addressing mode"));
   2523   1.6  christos 	      return false;
   2524   1.6  christos 	    }
   2525   1.6  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
   2526   1.6  christos 	    {
   2527  1.10  christos 	      set_offset_out_of_range_error (mismatch_detail, idx,
   2528   1.6  christos 					     min_value, max_value);
   2529   1.6  christos 	      return false;
   2530   1.6  christos 	    }
   2531   1.6  christos 	  if (!value_aligned_p (opnd->addr.offset.imm, num))
   2532  1.10  christos 	    {
   2533   1.6  christos 	      set_unaligned_error (mismatch_detail, idx, num);
   2534   1.6  christos 	      return false;
   2535   1.6  christos 	    }
   2536   1.6  christos 	  break;
   2537   1.7  christos 
   2538   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4x16:
   2539   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RI_S4x32:
   2540   1.6  christos 	  min_value = -8;
   2541   1.6  christos 	  max_value = 7;
   2542   1.7  christos 	  goto sve_imm_offset;
   2543   1.7  christos 
   2544   1.7  christos 	case AARCH64_OPND_SVE_ADDR_ZX:
   2545   1.7  christos 	  /* Everything is already ensured by parse_operands or
   2546   1.7  christos 	     aarch64_ext_sve_addr_rr_lsl (because this is a very specific
   2547   1.7  christos 	     argument type).  */
   2548   1.7  christos 	  assert (opnd->addr.offset.is_reg);
   2549   1.7  christos 	  assert (opnd->addr.preind);
   2550   1.7  christos 	  assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
   2551   1.7  christos 	  assert (opnd->shifter.kind == AARCH64_MOD_LSL);
   2552   1.7  christos 	  assert (opnd->shifter.operator_present == 0);
   2553   1.6  christos 	  break;
   2554   1.6  christos 
   2555   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RR:
   2556   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RR_LSL1:
   2557   1.8  christos 	case AARCH64_OPND_SVE_ADDR_RR_LSL2:
   2558  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RR_LSL3:
   2559  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RR_LSL4:
   2560  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RM:
   2561  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RM_LSL1:
   2562  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RM_LSL2:
   2563   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RM_LSL3:
   2564   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RM_LSL4:
   2565   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RX:
   2566   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RX_LSL1:
   2567  1.10  christos 	case AARCH64_OPND_SVE_ADDR_RX_LSL2:
   2568   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RX_LSL3:
   2569   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RX_LSL4:
   2570   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ:
   2571   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
   2572   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
   2573   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
   2574   1.6  christos 	  modifiers = 1 << AARCH64_MOD_LSL;
   2575   1.6  christos 	sve_rr_operand:
   2576   1.6  christos 	  assert (opnd->addr.offset.is_reg);
   2577   1.6  christos 	  assert (opnd->addr.preind);
   2578   1.6  christos 	  if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
   2579   1.6  christos 	      && opnd->addr.offset.regno == 31)
   2580   1.6  christos 	    {
   2581  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2582   1.6  christos 			       _("index register xzr is not allowed"));
   2583   1.6  christos 	      return false;
   2584   1.6  christos 	    }
   2585   1.6  christos 	  if (((1 << opnd->shifter.kind) & modifiers) == 0
   2586   1.6  christos 	      || (opnd->shifter.amount
   2587   1.6  christos 		  != get_operand_specific_data (&aarch64_operands[type])))
   2588   1.6  christos 	    {
   2589  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2590   1.6  christos 			       _("invalid addressing mode"));
   2591   1.6  christos 	      return false;
   2592   1.6  christos 	    }
   2593   1.6  christos 	  break;
   2594   1.6  christos 
   2595   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
   2596   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
   2597   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
   2598   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
   2599   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
   2600   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
   2601   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
   2602   1.6  christos 	case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
   2603   1.6  christos 	  modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
   2604   1.6  christos 	  goto sve_rr_operand;
   2605   1.6  christos 
   2606   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZI_U5:
   2607   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
   2608   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
   2609   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
   2610   1.6  christos 	  min_value = 0;
   2611   1.6  christos 	  max_value = 31;
   2612   1.6  christos 	  goto sve_imm_offset;
   2613   1.6  christos 
   2614   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
   2615   1.6  christos 	  modifiers = 1 << AARCH64_MOD_LSL;
   2616   1.6  christos 	sve_zz_operand:
   2617   1.6  christos 	  assert (opnd->addr.offset.is_reg);
   2618   1.6  christos 	  assert (opnd->addr.preind);
   2619   1.6  christos 	  if (((1 << opnd->shifter.kind) & modifiers) == 0
   2620   1.6  christos 	      || opnd->shifter.amount < 0
   2621   1.6  christos 	      || opnd->shifter.amount > 3)
   2622   1.6  christos 	    {
   2623  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2624   1.6  christos 			       _("invalid addressing mode"));
   2625   1.6  christos 	      return false;
   2626   1.6  christos 	    }
   2627   1.6  christos 	  break;
   2628   1.6  christos 
   2629   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
   2630   1.6  christos 	  modifiers = (1 << AARCH64_MOD_SXTW);
   2631   1.6  christos 	  goto sve_zz_operand;
   2632   1.6  christos 
   2633   1.6  christos 	case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
   2634   1.6  christos 	  modifiers = 1 << AARCH64_MOD_UXTW;
   2635   1.9  christos 	  goto sve_zz_operand;
   2636   1.9  christos 
   2637   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
   2638   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
   2639   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
   2640   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_POSTIND:
   2641   1.9  christos 	  {
   2642   1.9  christos 	    int num_bytes = calc_ldst_datasize (opnds);
   2643   1.9  christos 	    int abs_offset = (type == AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB
   2644   1.9  christos 			      || type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB)
   2645   1.9  christos 	      ? opnd->addr.offset.imm * -1
   2646   1.9  christos 	      : opnd->addr.offset.imm;
   2647   1.9  christos 	    if ((int) num_bytes != abs_offset
   2648   1.9  christos 		&& opnd->addr.offset.imm != 0)
   2649   1.9  christos 	      {
   2650  1.10  christos 		set_other_error (mismatch_detail, idx,
   2651   1.9  christos 				 _("invalid increment amount"));
   2652   1.9  christos 		return false;
   2653   1.9  christos 	      }
   2654   1.9  christos 	  }
   2655   1.9  christos 	  break;
   2656   1.9  christos 
   2657   1.9  christos 	case AARCH64_OPND_RCPC3_ADDR_OFFSET:
   2658   1.9  christos 	  if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
   2659  1.10  christos 	    {
   2660   1.9  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, -256, 255);
   2661   1.9  christos 	      return false;
   2662   1.1  christos 	    }
   2663   1.1  christos 
   2664   1.1  christos 	default:
   2665   1.1  christos 	  break;
   2666   1.1  christos 	}
   2667   1.1  christos       break;
   2668   1.5  christos 
   2669   1.5  christos     case AARCH64_OPND_CLASS_SIMD_REGLIST:
   2670   1.5  christos       if (type == AARCH64_OPND_LEt)
   2671   1.5  christos 	{
   2672   1.5  christos 	  /* Get the upper bound for the element index.  */
   2673   1.5  christos 	  num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
   2674   1.5  christos 	  if (!value_in_range_p (opnd->reglist.index, 0, num))
   2675  1.10  christos 	    {
   2676   1.5  christos 	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
   2677   1.5  christos 	      return false;
   2678   1.1  christos 	    }
   2679   1.1  christos 	}
   2680   1.1  christos       /* The opcode dependent area stores the number of elements in
   2681   1.1  christos 	 each structure to be loaded/stored.  */
   2682   1.1  christos       num = get_opcode_dependent_value (opcode);
   2683  1.10  christos       switch (type)
   2684  1.10  christos 	{
   2685  1.10  christos 	case AARCH64_OPND_LVn_LUT:
   2686  1.10  christos 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
   2687   1.1  christos 	    return 0;
   2688   1.1  christos 	  break;
   2689   1.1  christos 	case AARCH64_OPND_LVt:
   2690   1.1  christos 	  assert (num >= 1 && num <= 4);
   2691   1.9  christos 	  /* Unless LD1/ST1, the number of registers should be equal to that
   2692  1.10  christos 	     of the structure elements.  */
   2693   1.1  christos 	  if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
   2694   1.1  christos 	    return false;
   2695   1.1  christos 	  break;
   2696   1.1  christos 	case AARCH64_OPND_LVt_AL:
   2697   1.1  christos 	case AARCH64_OPND_LEt:
   2698   1.1  christos 	  assert (num >= 1 && num <= 4);
   2699   1.9  christos 	  /* The number of registers should be equal to that of the structure
   2700  1.10  christos 	     elements.  */
   2701   1.1  christos 	  if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
   2702   1.1  christos 	    return false;
   2703   1.1  christos 	  break;
   2704   1.1  christos 	default:
   2705   1.9  christos 	  break;
   2706   1.9  christos 	}
   2707   1.9  christos       if (opnd->reglist.stride != 1)
   2708  1.10  christos 	{
   2709   1.9  christos 	  set_reg_list_stride_error (mismatch_detail, idx, 1);
   2710   1.1  christos 	  return false;
   2711   1.1  christos 	}
   2712   1.1  christos       break;
   2713   1.1  christos 
   2714   1.1  christos     case AARCH64_OPND_CLASS_IMMEDIATE:
   2715   1.1  christos       /* Constraint check on immediate operand.  */
   2716   1.1  christos       imm = opnd->imm.value;
   2717   1.1  christos       /* E.g. imm_0_31 constrains value to be 0..31.  */
   2718   1.1  christos       if (qualifier_value_in_range_constraint_p (qualifier)
   2719   1.1  christos 	  && !value_in_range_p (imm, get_lower_bound (qualifier),
   2720   1.1  christos 				get_upper_bound (qualifier)))
   2721   1.1  christos 	{
   2722   1.1  christos 	  set_imm_out_of_range_error (mismatch_detail, idx,
   2723  1.10  christos 				      get_lower_bound (qualifier),
   2724   1.1  christos 				      get_upper_bound (qualifier));
   2725   1.1  christos 	  return false;
   2726   1.1  christos 	}
   2727   1.1  christos 
   2728   1.1  christos       switch (type)
   2729   1.1  christos 	{
   2730   1.1  christos 	case AARCH64_OPND_AIMM:
   2731   1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_LSL)
   2732   1.1  christos 	    {
   2733  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2734   1.1  christos 			       _("invalid shift operator"));
   2735   1.1  christos 	      return false;
   2736   1.1  christos 	    }
   2737   1.1  christos 	  if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
   2738   1.6  christos 	    {
   2739  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2740   1.1  christos 			       _("shift amount must be 0 or 12"));
   2741   1.1  christos 	      return false;
   2742   1.1  christos 	    }
   2743   1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
   2744   1.1  christos 	    {
   2745  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2746   1.1  christos 			       _("immediate out of range"));
   2747   1.1  christos 	      return false;
   2748   1.1  christos 	    }
   2749   1.1  christos 	  break;
   2750   1.1  christos 
   2751   1.1  christos 	case AARCH64_OPND_HALF:
   2752   1.1  christos 	  assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
   2753   1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_LSL)
   2754   1.1  christos 	    {
   2755  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2756   1.1  christos 			       _("invalid shift operator"));
   2757   1.1  christos 	      return false;
   2758   1.1  christos 	    }
   2759   1.1  christos 	  size = aarch64_get_qualifier_esize (opnds[0].qualifier);
   2760   1.1  christos 	  if (!value_aligned_p (opnd->shifter.amount, 16))
   2761   1.6  christos 	    {
   2762  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2763   1.1  christos 			       _("shift amount must be a multiple of 16"));
   2764   1.1  christos 	      return false;
   2765   1.1  christos 	    }
   2766   1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
   2767   1.1  christos 	    {
   2768  1.10  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx,
   2769   1.1  christos 						 0, size * 8 - 16);
   2770   1.1  christos 	      return false;
   2771   1.1  christos 	    }
   2772   1.1  christos 	  if (opnd->imm.value < 0)
   2773   1.1  christos 	    {
   2774  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2775   1.1  christos 			       _("negative immediate value not allowed"));
   2776   1.1  christos 	      return false;
   2777   1.1  christos 	    }
   2778   1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
   2779   1.1  christos 	    {
   2780  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2781   1.1  christos 			       _("immediate out of range"));
   2782   1.1  christos 	      return false;
   2783   1.1  christos 	    }
   2784   1.1  christos 	  break;
   2785   1.1  christos 
   2786   1.6  christos 	case AARCH64_OPND_IMM_MOV:
   2787   1.1  christos 	    {
   2788   1.1  christos 	      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
   2789   1.1  christos 	      imm = opnd->imm.value;
   2790   1.1  christos 	      assert (idx == 1);
   2791   1.1  christos 	      switch (opcode->op)
   2792   1.1  christos 		{
   2793   1.6  christos 		case OP_MOV_IMM_WIDEN:
   2794   1.1  christos 		  imm = ~imm;
   2795   1.6  christos 		  /* Fall through.  */
   2796   1.1  christos 		case OP_MOV_IMM_WIDE:
   2797   1.1  christos 		  if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
   2798   1.1  christos 		    {
   2799  1.10  christos 		      set_other_error (mismatch_detail, idx,
   2800   1.1  christos 				       _("immediate out of range"));
   2801   1.1  christos 		      return false;
   2802   1.1  christos 		    }
   2803   1.6  christos 		  break;
   2804   1.1  christos 		case OP_MOV_IMM_LOG:
   2805   1.1  christos 		  if (!aarch64_logical_immediate_p (imm, esize, NULL))
   2806   1.1  christos 		    {
   2807  1.10  christos 		      set_other_error (mismatch_detail, idx,
   2808   1.1  christos 				       _("immediate out of range"));
   2809   1.1  christos 		      return false;
   2810   1.1  christos 		    }
   2811   1.1  christos 		  break;
   2812  1.10  christos 		default:
   2813   1.1  christos 		  assert (0);
   2814   1.1  christos 		  return false;
   2815   1.1  christos 		}
   2816   1.1  christos 	    }
   2817   1.1  christos 	  break;
   2818   1.1  christos 
   2819   1.1  christos 	case AARCH64_OPND_NZCV:
   2820   1.8  christos 	case AARCH64_OPND_CCMP_IMM:
   2821   1.7  christos 	case AARCH64_OPND_EXCEPTION:
   2822   1.1  christos 	case AARCH64_OPND_UNDEFINED:
   2823   1.7  christos 	case AARCH64_OPND_TME_UIMM16:
   2824   1.1  christos 	case AARCH64_OPND_UIMM4:
   2825   1.1  christos 	case AARCH64_OPND_UIMM4_ADDG:
   2826   1.1  christos 	case AARCH64_OPND_UIMM7:
   2827   1.6  christos 	case AARCH64_OPND_UIMM3_OP1:
   2828   1.6  christos 	case AARCH64_OPND_UIMM3_OP2:
   2829   1.6  christos 	case AARCH64_OPND_SVE_UIMM3:
   2830  1.10  christos 	case AARCH64_OPND_SVE_UIMM7:
   2831   1.6  christos 	case AARCH64_OPND_SVE_UIMM8:
   2832   1.9  christos 	case AARCH64_OPND_SVE_UIMM4:
   2833   1.1  christos 	case AARCH64_OPND_SVE_UIMM8_53:
   2834   1.1  christos 	case AARCH64_OPND_CSSC_UIMM8:
   2835   1.1  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   2836   1.1  christos 	  assert (size < 32);
   2837   1.1  christos 	  if (!value_fit_unsigned_field_p (opnd->imm.value, size))
   2838   1.7  christos 	    {
   2839  1.10  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
   2840   1.7  christos 					  (1u << size) - 1);
   2841   1.7  christos 	      return false;
   2842   1.7  christos 	    }
   2843   1.7  christos 	  break;
   2844   1.7  christos 
   2845   1.7  christos 	case AARCH64_OPND_UIMM10:
   2846   1.7  christos 	  /* Scaled unsigned 10 bits immediate offset.  */
   2847   1.7  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 1008))
   2848  1.10  christos 	    {
   2849   1.7  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0, 1008);
   2850   1.7  christos 	      return false;
   2851   1.7  christos 	    }
   2852   1.7  christos 
   2853   1.7  christos 	  if (!value_aligned_p (opnd->imm.value, 16))
   2854  1.10  christos 	    {
   2855   1.1  christos 	      set_unaligned_error (mismatch_detail, idx, 16);
   2856   1.1  christos 	      return false;
   2857   1.1  christos 	    }
   2858   1.6  christos 	  break;
   2859   1.6  christos 
   2860   1.6  christos 	case AARCH64_OPND_SIMM5:
   2861   1.6  christos 	case AARCH64_OPND_SVE_SIMM5:
   2862   1.6  christos 	case AARCH64_OPND_SVE_SIMM5B:
   2863   1.9  christos 	case AARCH64_OPND_SVE_SIMM6:
   2864   1.6  christos 	case AARCH64_OPND_SVE_SIMM8:
   2865   1.6  christos 	case AARCH64_OPND_CSSC_SIMM8:
   2866   1.6  christos 	  size = get_operand_fields_width (get_operand_from_code (type));
   2867   1.6  christos 	  assert (size < 32);
   2868  1.10  christos 	  if (!value_fit_signed_field_p (opnd->imm.value, size))
   2869  1.10  christos 	    {
   2870  1.10  christos 	      imm_range_t rng = imm_range_min_max (size, true);
   2871  1.10  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, rng.min,
   2872   1.6  christos 					  rng.max);
   2873   1.6  christos 	      return false;
   2874   1.6  christos 	    }
   2875   1.1  christos 	  break;
   2876   1.3  christos 
   2877   1.1  christos 	case AARCH64_OPND_WIDTH:
   2878   1.1  christos 	  assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
   2879   1.1  christos 		  && opnds[0].type == AARCH64_OPND_Rd);
   2880   1.1  christos 	  size = get_upper_bound (qualifier);
   2881   1.1  christos 	  if (opnd->imm.value + opnds[idx-1].imm.value > size)
   2882   1.1  christos 	    /* lsb+width <= reg.size  */
   2883   1.1  christos 	    {
   2884  1.10  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1,
   2885   1.1  christos 					  size - opnds[idx-1].imm.value);
   2886   1.1  christos 	      return false;
   2887   1.1  christos 	    }
   2888   1.1  christos 	  break;
   2889   1.6  christos 
   2890   1.6  christos 	case AARCH64_OPND_LIMM:
   2891   1.6  christos 	case AARCH64_OPND_SVE_LIMM:
   2892   1.6  christos 	  {
   2893   1.6  christos 	    int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
   2894   1.6  christos 	    uint64_t uimm = opnd->imm.value;
   2895   1.6  christos 	    if (opcode->op == OP_BIC)
   2896   1.6  christos 	      uimm = ~uimm;
   2897   1.6  christos 	    if (!aarch64_logical_immediate_p (uimm, esize, NULL))
   2898   1.6  christos 	      {
   2899  1.10  christos 		set_other_error (mismatch_detail, idx,
   2900   1.6  christos 				 _("immediate out of range"));
   2901   1.6  christos 		return false;
   2902   1.1  christos 	      }
   2903   1.1  christos 	  }
   2904   1.1  christos 	  break;
   2905   1.1  christos 
   2906   1.1  christos 	case AARCH64_OPND_IMM0:
   2907   1.1  christos 	case AARCH64_OPND_FPIMM0:
   2908   1.1  christos 	  if (opnd->imm.value != 0)
   2909   1.1  christos 	    {
   2910  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2911   1.1  christos 			       _("immediate zero expected"));
   2912   1.1  christos 	      return false;
   2913   1.1  christos 	    }
   2914   1.6  christos 	  break;
   2915   1.6  christos 
   2916   1.6  christos 	case AARCH64_OPND_IMM_ROT1:
   2917   1.6  christos 	case AARCH64_OPND_IMM_ROT2:
   2918   1.6  christos 	case AARCH64_OPND_SVE_IMM_ROT2:
   2919   1.6  christos 	  if (opnd->imm.value != 0
   2920   1.6  christos 	      && opnd->imm.value != 90
   2921   1.6  christos 	      && opnd->imm.value != 180
   2922   1.6  christos 	      && opnd->imm.value != 270)
   2923   1.6  christos 	    {
   2924  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2925   1.6  christos 			       _("rotate expected to be 0, 90, 180 or 270"));
   2926   1.6  christos 	      return false;
   2927   1.6  christos 	    }
   2928   1.6  christos 	  break;
   2929   1.6  christos 
   2930   1.7  christos 	case AARCH64_OPND_IMM_ROT3:
   2931   1.6  christos 	case AARCH64_OPND_SVE_IMM_ROT1:
   2932   1.6  christos 	case AARCH64_OPND_SVE_IMM_ROT3:
   2933   1.6  christos 	  if (opnd->imm.value != 90 && opnd->imm.value != 270)
   2934   1.6  christos 	    {
   2935  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2936   1.6  christos 			       _("rotate expected to be 90 or 270"));
   2937   1.6  christos 	      return false;
   2938   1.6  christos 	    }
   2939   1.1  christos 	  break;
   2940   1.1  christos 
   2941   1.1  christos 	case AARCH64_OPND_SHLL_IMM:
   2942   1.1  christos 	  assert (idx == 2);
   2943   1.1  christos 	  size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
   2944   1.1  christos 	  if (opnd->imm.value != size)
   2945   1.1  christos 	    {
   2946  1.10  christos 	      set_other_error (mismatch_detail, idx,
   2947   1.1  christos 			       _("invalid shift amount"));
   2948   1.1  christos 	      return false;
   2949   1.1  christos 	    }
   2950   1.1  christos 	  break;
   2951   1.1  christos 
   2952   1.1  christos 	case AARCH64_OPND_IMM_VLSL:
   2953   1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   2954   1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
   2955   1.1  christos 	    {
   2956  1.10  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 0,
   2957   1.1  christos 					  size * 8 - 1);
   2958   1.1  christos 	      return false;
   2959   1.1  christos 	    }
   2960   1.1  christos 	  break;
   2961   1.1  christos 
   2962   1.1  christos 	case AARCH64_OPND_IMM_VLSR:
   2963   1.1  christos 	  size = aarch64_get_qualifier_esize (qualifier);
   2964   1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 1, size * 8))
   2965  1.10  christos 	    {
   2966   1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
   2967   1.1  christos 	      return false;
   2968   1.1  christos 	    }
   2969   1.1  christos 	  break;
   2970   1.1  christos 
   2971   1.1  christos 	case AARCH64_OPND_SIMD_IMM:
   2972   1.1  christos 	case AARCH64_OPND_SIMD_IMM_SFT:
   2973   1.1  christos 	  /* Qualifier check.  */
   2974   1.1  christos 	  switch (qualifier)
   2975   1.1  christos 	    {
   2976   1.1  christos 	    case AARCH64_OPND_QLF_LSL:
   2977   1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_LSL)
   2978   1.1  christos 		{
   2979  1.10  christos 		  set_other_error (mismatch_detail, idx,
   2980   1.1  christos 				   _("invalid shift operator"));
   2981   1.1  christos 		  return false;
   2982   1.1  christos 		}
   2983   1.1  christos 	      break;
   2984   1.1  christos 	    case AARCH64_OPND_QLF_MSL:
   2985   1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_MSL)
   2986   1.1  christos 		{
   2987  1.10  christos 		  set_other_error (mismatch_detail, idx,
   2988   1.1  christos 				   _("invalid shift operator"));
   2989   1.1  christos 		  return false;
   2990   1.1  christos 		}
   2991   1.1  christos 	      break;
   2992   1.1  christos 	    case AARCH64_OPND_QLF_NIL:
   2993   1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_NONE)
   2994   1.1  christos 		{
   2995  1.10  christos 		  set_other_error (mismatch_detail, idx,
   2996   1.1  christos 				   _("shift is not permitted"));
   2997   1.1  christos 		  return false;
   2998   1.1  christos 		}
   2999   1.1  christos 	      break;
   3000  1.10  christos 	    default:
   3001   1.1  christos 	      assert (0);
   3002   1.1  christos 	      return false;
   3003   1.1  christos 	    }
   3004   1.1  christos 	  /* Is the immediate valid?  */
   3005   1.1  christos 	  assert (idx == 1);
   3006   1.3  christos 	  if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
   3007   1.3  christos 	    {
   3008   1.1  christos 	      /* uimm8 or simm8 */
   3009   1.3  christos 	      if (!value_in_range_p (opnd->imm.value, -128, 255))
   3010  1.10  christos 		{
   3011   1.1  christos 		  set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
   3012   1.1  christos 		  return false;
   3013   1.1  christos 		}
   3014   1.1  christos 	    }
   3015   1.1  christos 	  else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
   3016   1.1  christos 	    {
   3017   1.1  christos 	      /* uimm64 is not
   3018   1.1  christos 		 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
   3019   1.1  christos 		 ffffffffgggggggghhhhhhhh'.  */
   3020  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3021   1.1  christos 			       _("invalid value for immediate"));
   3022   1.1  christos 	      return false;
   3023   1.1  christos 	    }
   3024   1.1  christos 	  /* Is the shift amount valid?  */
   3025   1.1  christos 	  switch (opnd->shifter.kind)
   3026   1.1  christos 	    {
   3027   1.3  christos 	    case AARCH64_MOD_LSL:
   3028   1.1  christos 	      size = aarch64_get_qualifier_esize (opnds[0].qualifier);
   3029   1.3  christos 	      if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
   3030   1.3  christos 		{
   3031  1.10  christos 		  set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
   3032   1.1  christos 						     (size - 1) * 8);
   3033   1.3  christos 		  return false;
   3034   1.1  christos 		}
   3035   1.3  christos 	      if (!value_aligned_p (opnd->shifter.amount, 8))
   3036  1.10  christos 		{
   3037   1.1  christos 		  set_unaligned_error (mismatch_detail, idx, 8);
   3038   1.1  christos 		  return false;
   3039   1.1  christos 		}
   3040   1.1  christos 	      break;
   3041   1.1  christos 	    case AARCH64_MOD_MSL:
   3042   1.1  christos 	      /* Only 8 and 16 are valid shift amount.  */
   3043   1.1  christos 	      if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
   3044   1.6  christos 		{
   3045  1.10  christos 		  set_other_error (mismatch_detail, idx,
   3046   1.1  christos 				   _("shift amount must be 0 or 16"));
   3047   1.1  christos 		  return false;
   3048   1.1  christos 		}
   3049   1.1  christos 	      break;
   3050   1.1  christos 	    default:
   3051   1.1  christos 	      if (opnd->shifter.kind != AARCH64_MOD_NONE)
   3052   1.1  christos 		{
   3053  1.10  christos 		  set_other_error (mismatch_detail, idx,
   3054   1.1  christos 				   _("invalid shift operator"));
   3055   1.1  christos 		  return false;
   3056   1.1  christos 		}
   3057   1.1  christos 	      break;
   3058   1.1  christos 	    }
   3059   1.1  christos 	  break;
   3060   1.1  christos 
   3061   1.6  christos 	case AARCH64_OPND_FPIMM:
   3062   1.1  christos 	case AARCH64_OPND_SIMD_FPIMM:
   3063   1.1  christos 	case AARCH64_OPND_SVE_FPIMM8:
   3064   1.1  christos 	  if (opnd->imm.is_fp == 0)
   3065   1.1  christos 	    {
   3066  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3067   1.1  christos 			       _("floating-point immediate expected"));
   3068   1.1  christos 	      return false;
   3069   1.1  christos 	    }
   3070   1.1  christos 	  /* The value is expected to be an 8-bit floating-point constant with
   3071   1.1  christos 	     sign, 3-bit exponent and normalized 4 bits of precision, encoded
   3072   1.1  christos 	     in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
   3073   1.1  christos 	     instruction).  */
   3074   1.1  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 255))
   3075   1.1  christos 	    {
   3076  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3077   1.1  christos 			       _("immediate out of range"));
   3078   1.1  christos 	      return false;
   3079   1.1  christos 	    }
   3080   1.1  christos 	  if (opnd->shifter.kind != AARCH64_MOD_NONE)
   3081   1.1  christos 	    {
   3082  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3083   1.1  christos 			       _("invalid shift operator"));
   3084   1.1  christos 	      return false;
   3085   1.1  christos 	    }
   3086   1.6  christos 	  break;
   3087   1.6  christos 
   3088   1.6  christos 	case AARCH64_OPND_SVE_AIMM:
   3089   1.6  christos 	  min_value = 0;
   3090   1.6  christos 	sve_aimm:
   3091   1.6  christos 	  assert (opnd->shifter.kind == AARCH64_MOD_LSL);
   3092   1.6  christos 	  size = aarch64_get_qualifier_esize (opnds[0].qualifier);
   3093   1.6  christos 	  mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
   3094   1.6  christos 	  uvalue = opnd->imm.value;
   3095   1.6  christos 	  shift = opnd->shifter.amount;
   3096   1.6  christos 	  if (size == 1)
   3097   1.6  christos 	    {
   3098   1.6  christos 	      if (shift != 0)
   3099   1.6  christos 		{
   3100   1.6  christos 		  set_other_error (mismatch_detail, idx,
   3101  1.10  christos 				   _("no shift amount allowed for"
   3102   1.6  christos 				     " 8-bit constants"));
   3103   1.6  christos 		  return false;
   3104   1.6  christos 		}
   3105   1.6  christos 	    }
   3106   1.6  christos 	  else
   3107   1.6  christos 	    {
   3108   1.6  christos 	      if (shift != 0 && shift != 8)
   3109   1.6  christos 		{
   3110  1.10  christos 		  set_other_error (mismatch_detail, idx,
   3111   1.6  christos 				   _("shift amount must be 0 or 8"));
   3112   1.6  christos 		  return false;
   3113   1.6  christos 		}
   3114   1.6  christos 	      if (shift == 0 && (uvalue & 0xff) == 0)
   3115   1.6  christos 		{
   3116   1.6  christos 		  shift = 8;
   3117   1.6  christos 		  uvalue = (int64_t) uvalue / 256;
   3118   1.6  christos 		}
   3119   1.6  christos 	    }
   3120   1.6  christos 	  mask >>= shift;
   3121   1.6  christos 	  if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
   3122   1.6  christos 	    {
   3123  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3124   1.6  christos 			       _("immediate too big for element size"));
   3125   1.6  christos 	      return false;
   3126   1.6  christos 	    }
   3127   1.6  christos 	  uvalue = (uvalue - min_value) & mask;
   3128   1.6  christos 	  if (uvalue > 0xff)
   3129   1.6  christos 	    {
   3130  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3131   1.6  christos 			       _("invalid arithmetic immediate"));
   3132   1.6  christos 	      return false;
   3133   1.6  christos 	    }
   3134   1.6  christos 	  break;
   3135   1.6  christos 
   3136   1.6  christos 	case AARCH64_OPND_SVE_ASIMM:
   3137   1.6  christos 	  min_value = -128;
   3138   1.6  christos 	  goto sve_aimm;
   3139   1.6  christos 
   3140   1.6  christos 	case AARCH64_OPND_SVE_I1_HALF_ONE:
   3141   1.6  christos 	  assert (opnd->imm.is_fp);
   3142   1.6  christos 	  if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
   3143   1.6  christos 	    {
   3144  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3145   1.6  christos 			       _("floating-point value must be 0.5 or 1.0"));
   3146   1.6  christos 	      return false;
   3147   1.6  christos 	    }
   3148   1.6  christos 	  break;
   3149   1.6  christos 
   3150   1.6  christos 	case AARCH64_OPND_SVE_I1_HALF_TWO:
   3151   1.6  christos 	  assert (opnd->imm.is_fp);
   3152   1.6  christos 	  if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
   3153   1.6  christos 	    {
   3154  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3155   1.6  christos 			       _("floating-point value must be 0.5 or 2.0"));
   3156   1.6  christos 	      return false;
   3157   1.6  christos 	    }
   3158   1.6  christos 	  break;
   3159   1.6  christos 
   3160   1.6  christos 	case AARCH64_OPND_SVE_I1_ZERO_ONE:
   3161   1.6  christos 	  assert (opnd->imm.is_fp);
   3162   1.6  christos 	  if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
   3163   1.6  christos 	    {
   3164  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3165   1.6  christos 			       _("floating-point value must be 0.0 or 1.0"));
   3166   1.6  christos 	      return false;
   3167   1.6  christos 	    }
   3168   1.6  christos 	  break;
   3169   1.6  christos 
   3170   1.6  christos 	case AARCH64_OPND_SVE_INV_LIMM:
   3171   1.6  christos 	  {
   3172   1.6  christos 	    int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
   3173   1.6  christos 	    uint64_t uimm = ~opnd->imm.value;
   3174   1.6  christos 	    if (!aarch64_logical_immediate_p (uimm, esize, NULL))
   3175   1.6  christos 	      {
   3176  1.10  christos 		set_other_error (mismatch_detail, idx,
   3177   1.6  christos 				 _("immediate out of range"));
   3178   1.6  christos 		return false;
   3179   1.6  christos 	      }
   3180   1.6  christos 	  }
   3181   1.6  christos 	  break;
   3182   1.6  christos 
   3183   1.6  christos 	case AARCH64_OPND_SVE_LIMM_MOV:
   3184   1.6  christos 	  {
   3185   1.6  christos 	    int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
   3186   1.6  christos 	    uint64_t uimm = opnd->imm.value;
   3187   1.6  christos 	    if (!aarch64_logical_immediate_p (uimm, esize, NULL))
   3188   1.6  christos 	      {
   3189  1.10  christos 		set_other_error (mismatch_detail, idx,
   3190   1.6  christos 				 _("immediate out of range"));
   3191   1.6  christos 		return false;
   3192   1.6  christos 	      }
   3193   1.6  christos 	    if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
   3194   1.6  christos 	      {
   3195  1.10  christos 		set_other_error (mismatch_detail, idx,
   3196   1.6  christos 				 _("invalid replicated MOV immediate"));
   3197   1.6  christos 		return false;
   3198   1.6  christos 	      }
   3199   1.6  christos 	  }
   3200   1.6  christos 	  break;
   3201   1.6  christos 
   3202   1.6  christos 	case AARCH64_OPND_SVE_PATTERN_SCALED:
   3203   1.6  christos 	  assert (opnd->shifter.kind == AARCH64_MOD_MUL);
   3204   1.6  christos 	  if (!value_in_range_p (opnd->shifter.amount, 1, 16))
   3205  1.10  christos 	    {
   3206   1.6  christos 	      set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
   3207   1.6  christos 	      return false;
   3208   1.6  christos 	    }
   3209   1.6  christos 	  break;
   3210   1.6  christos 
   3211   1.7  christos 	case AARCH64_OPND_SVE_SHLIMM_PRED:
   3212   1.6  christos 	case AARCH64_OPND_SVE_SHLIMM_UNPRED:
   3213   1.6  christos 	case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
   3214   1.6  christos 	  size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
   3215   1.6  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
   3216   1.6  christos 	    {
   3217  1.10  christos 	      set_imm_out_of_range_error (mismatch_detail, idx,
   3218   1.6  christos 					  0, 8 * size - 1);
   3219   1.6  christos 	      return false;
   3220   1.6  christos 	    }
   3221   1.9  christos 	  break;
   3222   1.9  christos 
   3223   1.9  christos 	case AARCH64_OPND_SME_SHRIMM4:
   3224   1.9  christos 	  size = 1 << get_operand_fields_width (get_operand_from_code (type));
   3225   1.9  christos 	  if (!value_in_range_p (opnd->imm.value, 1, size))
   3226  1.10  christos 	    {
   3227   1.9  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, size);
   3228   1.9  christos 	      return false;
   3229   1.9  christos 	    }
   3230   1.9  christos 	  break;
   3231   1.6  christos 
   3232   1.6  christos 	case AARCH64_OPND_SME_SHRIMM5:
   3233   1.7  christos 	case AARCH64_OPND_SVE_SHRIMM_PRED:
   3234   1.7  christos 	case AARCH64_OPND_SVE_SHRIMM_UNPRED:
   3235   1.7  christos 	case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
   3236   1.6  christos 	  num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
   3237   1.6  christos 	  size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
   3238   1.7  christos 	  if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
   3239  1.10  christos 	    {
   3240   1.6  christos 	      set_imm_out_of_range_error (mismatch_detail, idx, 1, 8*size);
   3241   1.6  christos 	      return false;
   3242   1.6  christos 	    }
   3243   1.9  christos 	  break;
   3244   1.9  christos 
   3245   1.9  christos 	case AARCH64_OPND_SME_ZT0_INDEX:
   3246   1.9  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 56))
   3247  1.10  christos 	    {
   3248   1.9  christos 	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, 56);
   3249   1.9  christos 	      return false;
   3250   1.9  christos 	    }
   3251   1.9  christos 	  if (opnd->imm.value % 8 != 0)
   3252   1.9  christos 	    {
   3253  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3254  1.10  christos 			       _("byte index must be a multiple of 8"));
   3255  1.10  christos 	      return false;
   3256  1.10  christos 	    }
   3257  1.10  christos 	  break;
   3258  1.10  christos 
   3259  1.10  christos 	case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
   3260  1.10  christos 	  if (!value_in_range_p (opnd->imm.value, 0, 3))
   3261   1.9  christos 	    {
   3262   1.9  christos 	      set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, 3);
   3263   1.9  christos 	      return 0;
   3264   1.9  christos 	    }
   3265   1.1  christos 	  break;
   3266   1.1  christos 
   3267   1.1  christos 	default:
   3268   1.1  christos 	  break;
   3269   1.1  christos 	}
   3270   1.1  christos       break;
   3271   1.1  christos 
   3272   1.1  christos     case AARCH64_OPND_CLASS_SYSTEM:
   3273   1.1  christos       switch (type)
   3274   1.8  christos 	{
   3275   1.8  christos 	case AARCH64_OPND_PSTATEFIELD:
   3276   1.8  christos 	  for (i = 0; aarch64_pstatefields[i].name; ++i)
   3277   1.8  christos 	    if (aarch64_pstatefields[i].value == opnd->pstatefield)
   3278   1.1  christos 	      break;
   3279   1.8  christos 	  assert (aarch64_pstatefields[i].name);
   3280   1.8  christos 	  assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
   3281   1.1  christos 	  max_value = F_GET_REG_MAX_VALUE (aarch64_pstatefields[i].flags);
   3282   1.8  christos 	  if (opnds[1].imm.value < 0 || opnds[1].imm.value > max_value)
   3283  1.10  christos 	    {
   3284   1.1  christos 	      set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
   3285   1.1  christos 	      return false;
   3286   1.9  christos 	    }
   3287   1.9  christos 	  break;
   3288   1.9  christos 	case AARCH64_OPND_PRFOP:
   3289   1.9  christos 	  if (opcode->iclass == ldst_regoff && opnd->prfop->value >= 24)
   3290   1.9  christos 	    {
   3291   1.9  christos 	      set_other_error (mismatch_detail, idx,
   3292  1.10  christos 			       _("the register-index form of PRFM does"
   3293   1.9  christos 				 " not accept opcodes in the range 24-31"));
   3294   1.9  christos 	      return false;
   3295   1.1  christos 	    }
   3296   1.1  christos 	  break;
   3297   1.1  christos 	default:
   3298   1.1  christos 	  break;
   3299   1.1  christos 	}
   3300   1.1  christos       break;
   3301   1.1  christos 
   3302   1.6  christos     case AARCH64_OPND_CLASS_SIMD_ELEMENT:
   3303   1.6  christos       /* Get the upper bound for the element index.  */
   3304   1.6  christos       if (opcode->op == OP_FCMLA_ELEM)
   3305   1.6  christos 	/* FCMLA index range depends on the vector size of other operands
   3306   1.6  christos 	   and is halfed because complex numbers take two elements.  */
   3307  1.10  christos 	num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
   3308  1.10  christos 	      * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
   3309  1.10  christos       else if (opcode->iclass == lut)
   3310  1.10  christos 	{
   3311  1.10  christos 	  size = get_operand_fields_width (get_operand_from_code (type)) - 5;
   3312  1.10  christos 	  if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
   3313  1.10  christos 			      0, (1 << size) - 1))
   3314  1.10  christos 	    return 0;
   3315   1.6  christos 	  break;
   3316   1.6  christos 	}
   3317   1.6  christos       else
   3318   1.7  christos 	num = 16;
   3319   1.6  christos       num = num / aarch64_get_qualifier_esize (qualifier) - 1;
   3320   1.1  christos       assert (aarch64_get_qualifier_nelem (qualifier) == 1);
   3321   1.1  christos 
   3322   1.1  christos       /* Index out-of-range.  */
   3323   1.1  christos       if (!value_in_range_p (opnd->reglane.index, 0, num))
   3324  1.10  christos 	{
   3325   1.1  christos 	  set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
   3326   1.1  christos 	  return false;
   3327   1.1  christos 	}
   3328   1.1  christos       /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
   3329   1.1  christos 	 <Vm>	Is the vector register (V0-V31) or (V0-V15), whose
   3330   1.1  christos 	 number is encoded in "size:M:Rm":
   3331   1.1  christos 	 size	<Vm>
   3332   1.1  christos 	 00		RESERVED
   3333   1.1  christos 	 01		0:Rm
   3334  1.10  christos 	 10		M:Rm
   3335  1.10  christos 	 11		RESERVED  */
   3336  1.10  christos       if (type == AARCH64_OPND_Em16
   3337   1.1  christos 	  && (qualifier == AARCH64_OPND_QLF_S_H
   3338   1.1  christos 	      || qualifier == AARCH64_OPND_QLF_S_2B)
   3339   1.1  christos 	  && !value_in_range_p (opnd->reglane.regno, 0, 15))
   3340  1.10  christos 	{
   3341  1.10  christos 	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
   3342  1.10  christos 	  return false;
   3343  1.10  christos 	}
   3344  1.10  christos       if (type == AARCH64_OPND_Em8
   3345  1.10  christos 	  && !value_in_range_p (opnd->reglane.regno, 0, 7))
   3346   1.1  christos 	{
   3347   1.1  christos 	  set_regno_out_of_range_error (mismatch_detail, idx, 0, 7);
   3348   1.1  christos 	  return 0;
   3349   1.1  christos 	}
   3350   1.1  christos       break;
   3351   1.1  christos 
   3352   1.1  christos     case AARCH64_OPND_CLASS_MODIFIED_REG:
   3353   1.1  christos       assert (idx == 1 || idx == 2);
   3354   1.1  christos       switch (type)
   3355   1.6  christos 	{
   3356   1.1  christos 	case AARCH64_OPND_Rm_EXT:
   3357   1.1  christos 	  if (!aarch64_extend_operator_p (opnd->shifter.kind)
   3358   1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_LSL)
   3359   1.1  christos 	    {
   3360  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3361   1.1  christos 			       _("extend operator expected"));
   3362   1.1  christos 	      return false;
   3363   1.1  christos 	    }
   3364   1.1  christos 	  /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
   3365   1.1  christos 	     (i.e. SP), in which case it defaults to LSL. The LSL alias is
   3366   1.1  christos 	     only valid when "Rd" or "Rn" is '11111', and is preferred in that
   3367   1.1  christos 	     case.  */
   3368   1.1  christos 	  if (!aarch64_stack_pointer_p (opnds + 0)
   3369   1.1  christos 	      && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
   3370   1.1  christos 	    {
   3371   1.1  christos 	      if (!opnd->shifter.operator_present)
   3372   1.1  christos 		{
   3373  1.10  christos 		  set_other_error (mismatch_detail, idx,
   3374   1.1  christos 				   _("missing extend operator"));
   3375   1.1  christos 		  return false;
   3376   1.1  christos 		}
   3377   1.1  christos 	      else if (opnd->shifter.kind == AARCH64_MOD_LSL)
   3378   1.1  christos 		{
   3379  1.10  christos 		  set_other_error (mismatch_detail, idx,
   3380   1.1  christos 				   _("'LSL' operator not allowed"));
   3381   1.1  christos 		  return false;
   3382   1.1  christos 		}
   3383   1.1  christos 	    }
   3384   1.1  christos 	  assert (opnd->shifter.operator_present	/* Default to LSL.  */
   3385   1.1  christos 		  || opnd->shifter.kind == AARCH64_MOD_LSL);
   3386   1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, 4))
   3387  1.10  christos 	    {
   3388   1.1  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
   3389   1.1  christos 	      return false;
   3390   1.1  christos 	    }
   3391   1.1  christos 	  /* In the 64-bit form, the final register operand is written as Wm
   3392   1.1  christos 	     for all but the (possibly omitted) UXTX/LSL and SXTX
   3393   1.1  christos 	     operators.
   3394   1.1  christos 	     N.B. GAS allows X register to be used with any operator as a
   3395   1.1  christos 	     programming convenience.  */
   3396   1.1  christos 	  if (qualifier == AARCH64_OPND_QLF_X
   3397   1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_LSL
   3398   1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_UXTX
   3399   1.1  christos 	      && opnd->shifter.kind != AARCH64_MOD_SXTX)
   3400  1.10  christos 	    {
   3401   1.1  christos 	      set_other_error (mismatch_detail, idx, _("W register expected"));
   3402   1.1  christos 	      return false;
   3403   1.1  christos 	    }
   3404   1.1  christos 	  break;
   3405   1.1  christos 
   3406   1.1  christos 	case AARCH64_OPND_Rm_SFT:
   3407   1.6  christos 	  /* ROR is not available to the shifted register operand in
   3408   1.1  christos 	     arithmetic instructions.  */
   3409   1.1  christos 	  if (!aarch64_shift_operator_p (opnd->shifter.kind))
   3410   1.1  christos 	    {
   3411  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3412   1.1  christos 			       _("shift operator expected"));
   3413   1.1  christos 	      return false;
   3414   1.1  christos 	    }
   3415   1.1  christos 	  if (opnd->shifter.kind == AARCH64_MOD_ROR
   3416   1.1  christos 	      && opcode->iclass != log_shift)
   3417   1.1  christos 	    {
   3418  1.10  christos 	      set_other_error (mismatch_detail, idx,
   3419   1.1  christos 			       _("'ROR' operator not allowed"));
   3420   1.1  christos 	      return false;
   3421   1.1  christos 	    }
   3422   1.1  christos 	  num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
   3423   1.1  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, num))
   3424  1.10  christos 	    {
   3425  1.10  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
   3426  1.10  christos 	      return false;
   3427  1.10  christos 	    }
   3428  1.10  christos 	  break;
   3429  1.10  christos 
   3430  1.10  christos 	case AARCH64_OPND_Rm_LSL:
   3431  1.10  christos 	  /* We expect here that opnd->shifter.kind != AARCH64_MOD_LSL
   3432  1.10  christos 	     because the parser already restricts the type of shift to LSL only,
   3433  1.10  christos 	     so another check of shift kind would be redundant.  */
   3434  1.10  christos 	  if (!value_in_range_p (opnd->shifter.amount, 0, 7))
   3435  1.10  christos 	    {
   3436   1.1  christos 	      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 7);
   3437   1.1  christos 	      return false;
   3438   1.1  christos 	    }
   3439   1.1  christos 	  break;
   3440   1.1  christos 
   3441   1.1  christos 	default:
   3442   1.1  christos 	  break;
   3443   1.1  christos 	}
   3444   1.1  christos       break;
   3445   1.1  christos 
   3446   1.1  christos     default:
   3447   1.1  christos       break;
   3448  1.10  christos     }
   3449   1.1  christos 
   3450   1.1  christos   return true;
   3451   1.1  christos }
   3452   1.1  christos 
   3453   1.1  christos /* Main entrypoint for the operand constraint checking.
   3454   1.1  christos 
   3455   1.1  christos    Return 1 if operands of *INST meet the constraint applied by the operand
   3456   1.1  christos    codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
   3457   1.1  christos    not NULL, return the detail of the error in *MISMATCH_DETAIL.  N.B. when
   3458   1.1  christos    adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
   3459   1.1  christos    with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
   3460   1.1  christos    error kind when it is notified that an instruction does not pass the check).
   3461   1.1  christos 
   3462  1.10  christos    Un-determined operand qualifiers may get established during the process.  */
   3463   1.1  christos 
   3464   1.1  christos bool
   3465   1.1  christos aarch64_match_operands_constraint (aarch64_inst *inst,
   3466   1.1  christos 				   aarch64_operand_error *mismatch_detail)
   3467   1.1  christos {
   3468   1.1  christos   int i;
   3469   1.1  christos 
   3470   1.6  christos   DEBUG_TRACE ("enter");
   3471   1.8  christos 
   3472   1.8  christos   i = inst->opcode->tied_operand;
   3473   1.6  christos 
   3474   1.8  christos   if (i > 0)
   3475   1.8  christos     {
   3476   1.8  christos       /* Check for tied_operands with specific opcode iclass.  */
   3477   1.8  christos       switch (inst->opcode->iclass)
   3478   1.8  christos         {
   3479   1.8  christos         /* For SME LDR and STR instructions #imm must have the same numerical
   3480   1.8  christos            value for both operands.
   3481   1.8  christos         */
   3482   1.9  christos         case sme_ldr:
   3483   1.8  christos         case sme_str:
   3484   1.9  christos           assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array_off4);
   3485   1.8  christos           assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
   3486   1.8  christos           if (inst->operands[0].indexed_za.index.imm
   3487   1.8  christos               != inst->operands[1].addr.offset.imm)
   3488   1.8  christos             {
   3489   1.8  christos               if (mismatch_detail)
   3490   1.8  christos                 {
   3491   1.8  christos                   mismatch_detail->kind = AARCH64_OPDE_UNTIED_IMMS;
   3492  1.10  christos                   mismatch_detail->index = i;
   3493   1.8  christos                 }
   3494   1.8  christos               return false;
   3495   1.8  christos             }
   3496   1.8  christos           break;
   3497   1.9  christos 
   3498   1.9  christos         default:
   3499   1.9  christos 	  {
   3500   1.9  christos 	    /* Check for cases where a source register needs to be the
   3501   1.9  christos 	       same as the destination register.  Do this before
   3502   1.9  christos 	       matching qualifiers since if an instruction has both
   3503   1.9  christos 	       invalid tying and invalid qualifiers, the error about
   3504   1.9  christos 	       qualifiers would suggest several alternative instructions
   3505   1.9  christos 	       that also have invalid tying.  */
   3506   1.9  christos 	    enum aarch64_operand_class op_class
   3507   1.9  christos 	       = aarch64_get_operand_class (inst->operands[0].type);
   3508   1.9  christos 	    assert (aarch64_get_operand_class (inst->operands[i].type)
   3509   1.9  christos 		    == op_class);
   3510   1.9  christos 	    if (op_class == AARCH64_OPND_CLASS_SVE_REGLIST
   3511   1.9  christos 		? ((inst->operands[0].reglist.first_regno
   3512   1.9  christos 		    != inst->operands[i].reglist.first_regno)
   3513   1.9  christos 		   || (inst->operands[0].reglist.num_regs
   3514   1.9  christos 		       != inst->operands[i].reglist.num_regs)
   3515   1.9  christos 		   || (inst->operands[0].reglist.stride
   3516   1.9  christos 		       != inst->operands[i].reglist.stride))
   3517   1.9  christos 		: (inst->operands[0].reg.regno
   3518   1.9  christos 		   != inst->operands[i].reg.regno))
   3519   1.9  christos 	      {
   3520   1.9  christos 		if (mismatch_detail)
   3521   1.9  christos 		  {
   3522   1.9  christos 		    mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
   3523   1.9  christos 		    mismatch_detail->index = i;
   3524  1.10  christos 		    mismatch_detail->error = NULL;
   3525   1.9  christos 		  }
   3526   1.9  christos 		return false;
   3527   1.9  christos 	      }
   3528   1.8  christos 	    break;
   3529   1.6  christos 	  }
   3530   1.6  christos         }
   3531   1.1  christos     }
   3532   1.1  christos 
   3533   1.1  christos   /* Match operands' qualifier.
   3534   1.1  christos      *INST has already had qualifier establish for some, if not all, of
   3535   1.1  christos      its operands; we need to find out whether these established
   3536   1.1  christos      qualifiers match one of the qualifier sequence in
   3537   1.1  christos      INST->OPCODE->QUALIFIERS_LIST.  If yes, we will assign each operand
   3538   1.1  christos      with the corresponding qualifier in such a sequence.
   3539   1.1  christos      Only basic operand constraint checking is done here; the more thorough
   3540   1.1  christos      constraint checking will carried out by operand_general_constraint_met_p,
   3541   1.9  christos      which has be to called after this in order to get all of the operands'
   3542   1.9  christos      qualifiers established.  */
   3543   1.9  christos   int invalid_count;
   3544   1.1  christos   if (match_operands_qualifier (inst, true /* update_p */,
   3545   1.1  christos 				&invalid_count) == 0)
   3546   1.1  christos     {
   3547   1.1  christos       DEBUG_TRACE ("FAIL on operand qualifier matching");
   3548   1.1  christos       if (mismatch_detail)
   3549   1.1  christos 	{
   3550   1.1  christos 	  /* Return an error type to indicate that it is the qualifier
   3551   1.1  christos 	     matching failure; we don't care about which operand as there
   3552   1.1  christos 	     are enough information in the opcode table to reproduce it.  */
   3553   1.1  christos 	  mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
   3554   1.9  christos 	  mismatch_detail->index = -1;
   3555   1.1  christos 	  mismatch_detail->error = NULL;
   3556  1.10  christos 	  mismatch_detail->data[0].i = invalid_count;
   3557   1.1  christos 	}
   3558   1.1  christos       return false;
   3559   1.1  christos     }
   3560   1.1  christos 
   3561   1.1  christos   /* Match operands' constraint.  */
   3562   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3563   1.1  christos     {
   3564   1.1  christos       enum aarch64_opnd type = inst->opcode->operands[i];
   3565   1.1  christos       if (type == AARCH64_OPND_NIL)
   3566   1.1  christos 	break;
   3567   1.1  christos       if (inst->operands[i].skip)
   3568   1.1  christos 	{
   3569   1.1  christos 	  DEBUG_TRACE ("skip the incomplete operand %d", i);
   3570  1.10  christos 	  continue;
   3571  1.10  christos 	}
   3572   1.1  christos       if (!operand_general_constraint_met_p (inst->operands, i, type,
   3573   1.1  christos 					     inst->opcode, mismatch_detail))
   3574  1.10  christos 	{
   3575   1.1  christos 	  DEBUG_TRACE ("FAIL on operand %d", i);
   3576   1.1  christos 	  return false;
   3577   1.1  christos 	}
   3578   1.1  christos     }
   3579   1.1  christos 
   3580  1.10  christos   DEBUG_TRACE ("PASS");
   3581   1.1  christos 
   3582   1.1  christos   return true;
   3583   1.1  christos }
   3584   1.1  christos 
   3585   1.1  christos /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
   3586   1.1  christos    Also updates the TYPE of each INST->OPERANDS with the corresponding
   3587   1.1  christos    value of OPCODE->OPERANDS.
   3588   1.1  christos 
   3589   1.1  christos    Note that some operand qualifiers may need to be manually cleared by
   3590   1.1  christos    the caller before it further calls the aarch64_opcode_encode; by
   3591   1.1  christos    doing this, it helps the qualifier matching facilities work
   3592   1.1  christos    properly.  */
   3593   1.1  christos 
   3594   1.1  christos const aarch64_opcode*
   3595   1.1  christos aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
   3596   1.1  christos {
   3597   1.1  christos   int i;
   3598   1.1  christos   const aarch64_opcode *old = inst->opcode;
   3599   1.1  christos 
   3600   1.1  christos   inst->opcode = opcode;
   3601   1.1  christos 
   3602   1.1  christos   /* Update the operand types.  */
   3603   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3604   1.1  christos     {
   3605   1.1  christos       inst->operands[i].type = opcode->operands[i];
   3606   1.1  christos       if (opcode->operands[i] == AARCH64_OPND_NIL)
   3607   1.1  christos 	break;
   3608   1.1  christos     }
   3609   1.1  christos 
   3610   1.1  christos   DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
   3611   1.1  christos 
   3612   1.1  christos   return old;
   3613   1.1  christos }
   3614   1.1  christos 
   3615   1.1  christos int
   3616   1.1  christos aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
   3617   1.1  christos {
   3618   1.1  christos   int i;
   3619   1.1  christos   for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   3620   1.1  christos     if (operands[i] == operand)
   3621   1.1  christos       return i;
   3622   1.1  christos     else if (operands[i] == AARCH64_OPND_NIL)
   3623   1.1  christos       break;
   3624   1.1  christos   return -1;
   3625   1.6  christos }
   3626   1.6  christos 
   3627   1.6  christos /* R0...R30, followed by FOR31.  */
   3629   1.6  christos #define BANK(R, FOR31) \
   3630   1.6  christos   { R  (0), R  (1), R  (2), R  (3), R  (4), R  (5), R  (6), R  (7), \
   3631   1.1  christos     R  (8), R  (9), R (10), R (11), R (12), R (13), R (14), R (15), \
   3632   1.1  christos     R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
   3633   1.1  christos     R (24), R (25), R (26), R (27), R (28), R (29), R (30),  FOR31 }
   3634   1.1  christos /* [0][0]  32-bit integer regs with sp   Wn
   3635   1.1  christos    [0][1]  64-bit integer regs with sp   Xn  sf=1
   3636   1.6  christos    [1][0]  32-bit integer regs with #0   Wn
   3637   1.6  christos    [1][1]  64-bit integer regs with #0   Xn  sf=1 */
   3638   1.6  christos static const char *int_reg[2][2][32] = {
   3639   1.6  christos #define R32(X) "w" #X
   3640   1.1  christos #define R64(X) "x" #X
   3641   1.1  christos   { BANK (R32, "wsp"), BANK (R64, "sp") },
   3642   1.1  christos   { BANK (R32, "wzr"), BANK (R64, "xzr") }
   3643   1.1  christos #undef R64
   3644   1.6  christos #undef R32
   3645   1.6  christos };
   3646   1.6  christos 
   3647   1.6  christos /* Names of the SVE vector registers, first with .S suffixes,
   3648   1.6  christos    then with .D suffixes.  */
   3649   1.6  christos 
   3650   1.6  christos static const char *sve_reg[2][32] = {
   3651   1.6  christos #define ZS(X) "z" #X ".s"
   3652   1.6  christos #define ZD(X) "z" #X ".d"
   3653   1.6  christos   BANK (ZS, ZS (31)), BANK (ZD, ZD (31))
   3654   1.6  christos #undef ZD
   3655   1.6  christos #undef ZS
   3656   1.1  christos };
   3657   1.1  christos #undef BANK
   3658   1.1  christos 
   3659   1.1  christos /* Return the integer register name.
   3660   1.1  christos    if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg.  */
   3661   1.1  christos 
   3662   1.1  christos static inline const char *
   3663   1.1  christos get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
   3664   1.1  christos {
   3665   1.1  christos   const int has_zr = sp_reg_p ? 0 : 1;
   3666   1.1  christos   const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
   3667   1.1  christos   return int_reg[has_zr][is_64][regno];
   3668   1.1  christos }
   3669   1.1  christos 
   3670   1.1  christos /* Like get_int_reg_name, but IS_64 is always 1.  */
   3671   1.1  christos 
   3672   1.1  christos static inline const char *
   3673   1.1  christos get_64bit_int_reg_name (int regno, int sp_reg_p)
   3674   1.1  christos {
   3675   1.1  christos   const int has_zr = sp_reg_p ? 0 : 1;
   3676   1.6  christos   return int_reg[has_zr][1][regno];
   3677   1.6  christos }
   3678   1.6  christos 
   3679   1.6  christos /* Get the name of the integer offset register in OPND, using the shift type
   3680   1.6  christos    to decide whether it's a word or doubleword.  */
   3681   1.6  christos 
   3682   1.6  christos static inline const char *
   3683   1.6  christos get_offset_int_reg_name (const aarch64_opnd_info *opnd)
   3684   1.6  christos {
   3685   1.6  christos   switch (opnd->shifter.kind)
   3686   1.6  christos     {
   3687   1.6  christos     case AARCH64_MOD_UXTW:
   3688   1.6  christos     case AARCH64_MOD_SXTW:
   3689   1.6  christos       return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
   3690   1.6  christos 
   3691   1.6  christos     case AARCH64_MOD_LSL:
   3692   1.6  christos     case AARCH64_MOD_SXTX:
   3693   1.6  christos       return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
   3694   1.6  christos 
   3695   1.6  christos     default:
   3696   1.6  christos       abort ();
   3697   1.6  christos     }
   3698   1.6  christos }
   3699   1.6  christos 
   3700   1.6  christos /* Get the name of the SVE vector offset register in OPND, using the operand
   3701   1.6  christos    qualifier to decide whether the suffix should be .S or .D.  */
   3702   1.6  christos 
   3703   1.6  christos static inline const char *
   3704   1.6  christos get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
   3705   1.6  christos {
   3706   1.6  christos   assert (qualifier == AARCH64_OPND_QLF_S_S
   3707   1.6  christos 	  || qualifier == AARCH64_OPND_QLF_S_D);
   3708   1.1  christos   return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
   3709   1.1  christos }
   3710   1.1  christos 
   3711   1.1  christos /* Types for expanding an encoded 8-bit value to a floating-point value.  */
   3712   1.1  christos 
   3713   1.1  christos typedef union
   3714   1.1  christos {
   3715   1.1  christos   uint64_t i;
   3716   1.1  christos   double   d;
   3717   1.1  christos } double_conv_t;
   3718   1.1  christos 
   3719   1.1  christos typedef union
   3720   1.1  christos {
   3721   1.1  christos   uint32_t i;
   3722   1.3  christos   float    f;
   3723   1.3  christos } single_conv_t;
   3724   1.3  christos 
   3725   1.3  christos typedef union
   3726   1.3  christos {
   3727   1.3  christos   uint32_t i;
   3728   1.1  christos   float    f;
   3729   1.1  christos } half_conv_t;
   3730   1.1  christos 
   3731   1.3  christos /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
   3732   1.3  christos    normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
   3733   1.3  christos    (depending on the type of the instruction).  IMM8 will be expanded to a
   3734   1.3  christos    single-precision floating-point value (SIZE == 4) or a double-precision
   3735   1.1  christos    floating-point value (SIZE == 8).  A half-precision floating-point value
   3736   1.1  christos    (SIZE == 2) is expanded to a single-precision floating-point value.  The
   3737   1.3  christos    expanded value is returned.  */
   3738   1.1  christos 
   3739   1.6  christos static uint64_t
   3740   1.1  christos expand_fp_imm (int size, uint32_t imm8)
   3741   1.1  christos {
   3742   1.1  christos   uint64_t imm = 0;
   3743   1.1  christos   uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
   3744   1.1  christos 
   3745   1.1  christos   imm8_7 = (imm8 >> 7) & 0x01;	/* imm8<7>   */
   3746   1.1  christos   imm8_6_0 = imm8 & 0x7f;	/* imm8<6:0> */
   3747   1.3  christos   imm8_6 = imm8_6_0 >> 6;	/* imm8<6>   */
   3748   1.1  christos   imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
   3749   1.1  christos     | (imm8_6 << 1) | imm8_6;	/* Replicate(imm8<6>,4) */
   3750   1.1  christos   if (size == 8)
   3751   1.1  christos     {
   3752   1.1  christos       imm = (imm8_7 << (63-32))		/* imm8<7>  */
   3753   1.1  christos 	| ((imm8_6 ^ 1) << (62-32))	/* NOT(imm8<6)	*/
   3754   1.1  christos 	| (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
   3755   1.1  christos 	| (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
   3756   1.3  christos 	| (imm8_6_0 << (48-32));	/* imm8<6>:imm8<5:0>    */
   3757   1.1  christos       imm <<= 32;
   3758   1.1  christos     }
   3759   1.1  christos   else if (size == 4 || size == 2)
   3760   1.1  christos     {
   3761   1.1  christos       imm = (imm8_7 << 31)	/* imm8<7>              */
   3762   1.1  christos 	| ((imm8_6 ^ 1) << 30)	/* NOT(imm8<6>)         */
   3763   1.3  christos 	| (imm8_6_repl4 << 26)	/* Replicate(imm8<6>,4) */
   3764   1.3  christos 	| (imm8_6_0 << 19);	/* imm8<6>:imm8<5:0>    */
   3765   1.3  christos     }
   3766   1.3  christos   else
   3767   1.3  christos     {
   3768   1.1  christos       /* An unsupported size.  */
   3769   1.1  christos       assert (0);
   3770   1.1  christos     }
   3771   1.1  christos 
   3772   1.9  christos   return imm;
   3773   1.9  christos }
   3774   1.9  christos 
   3775   1.9  christos /* Return a string based on FMT with the register style applied.  */
   3776   1.9  christos 
   3777   1.9  christos static const char *
   3778   1.9  christos style_reg (struct aarch64_styler *styler, const char *fmt, ...)
   3779   1.9  christos {
   3780   1.9  christos   const char *txt;
   3781   1.9  christos   va_list ap;
   3782   1.9  christos 
   3783   1.9  christos   va_start (ap, fmt);
   3784   1.9  christos   txt = styler->apply_style (styler, dis_style_register, fmt, ap);
   3785   1.9  christos   va_end (ap);
   3786   1.9  christos 
   3787   1.9  christos   return txt;
   3788   1.9  christos }
   3789   1.9  christos 
   3790   1.9  christos /* Return a string based on FMT with the immediate style applied.  */
   3791   1.9  christos 
   3792   1.9  christos static const char *
   3793   1.9  christos style_imm (struct aarch64_styler *styler, const char *fmt, ...)
   3794   1.9  christos {
   3795   1.9  christos   const char *txt;
   3796   1.9  christos   va_list ap;
   3797   1.9  christos 
   3798   1.9  christos   va_start (ap, fmt);
   3799   1.9  christos   txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
   3800   1.9  christos   va_end (ap);
   3801   1.9  christos 
   3802   1.9  christos   return txt;
   3803   1.9  christos }
   3804   1.9  christos 
   3805   1.9  christos /* Return a string based on FMT with the sub-mnemonic style applied.  */
   3806   1.9  christos 
   3807   1.9  christos static const char *
   3808   1.9  christos style_sub_mnem (struct aarch64_styler *styler, const char *fmt, ...)
   3809   1.9  christos {
   3810   1.9  christos   const char *txt;
   3811   1.9  christos   va_list ap;
   3812   1.9  christos 
   3813   1.9  christos   va_start (ap, fmt);
   3814   1.9  christos   txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
   3815   1.9  christos   va_end (ap);
   3816   1.9  christos 
   3817   1.9  christos   return txt;
   3818   1.9  christos }
   3819   1.9  christos 
   3820   1.9  christos /* Return a string based on FMT with the address style applied.  */
   3821   1.9  christos 
   3822   1.9  christos static const char *
   3823   1.9  christos style_addr (struct aarch64_styler *styler, const char *fmt, ...)
   3824   1.9  christos {
   3825   1.9  christos   const char *txt;
   3826   1.9  christos   va_list ap;
   3827   1.9  christos 
   3828   1.9  christos   va_start (ap, fmt);
   3829   1.9  christos   txt = styler->apply_style (styler, dis_style_address, fmt, ap);
   3830   1.9  christos   va_end (ap);
   3831   1.9  christos 
   3832   1.1  christos   return txt;
   3833   1.6  christos }
   3834   1.6  christos 
   3835   1.1  christos /* Produce the string representation of the register list operand *OPND
   3836   1.6  christos    in the buffer pointed by BUF of size SIZE.  PREFIX is the part of
   3837   1.9  christos    the register name that comes before the register number, such as "v".  */
   3838   1.1  christos static void
   3839   1.9  christos print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
   3840   1.1  christos 		     const char *prefix, struct aarch64_styler *styler)
   3841   1.9  christos {
   3842   1.1  christos   const int mask = (prefix[0] == 'p' ? 15 : 31);
   3843   1.9  christos   const int num_regs = opnd->reglist.num_regs;
   3844   1.1  christos   const int stride = opnd->reglist.stride;
   3845   1.9  christos   const int first_reg = opnd->reglist.first_regno;
   3846   1.1  christos   const int last_reg = (first_reg + (num_regs - 1) * stride) & mask;
   3847   1.1  christos   const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
   3848   1.1  christos   char tb[16];	/* Temporary buffer.  */
   3849   1.1  christos 
   3850   1.1  christos   assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
   3851   1.1  christos   assert (num_regs >= 1 && num_regs <= 4);
   3852   1.6  christos 
   3853   1.9  christos   /* Prepare the index if any.  */
   3854   1.9  christos   if (opnd->reglist.has_index)
   3855   1.1  christos     /* PR 21096: The %100 is to silence a warning about possible truncation.  */
   3856   1.1  christos     snprintf (tb, sizeof (tb), "[%s]",
   3857   1.1  christos 	      style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
   3858  1.10  christos   else
   3859  1.10  christos     tb[0] = '\0';
   3860   1.1  christos 
   3861  1.10  christos   /* The hyphenated form is preferred for disassembly if there is
   3862  1.10  christos      more than one register in the list, and the register numbers
   3863  1.10  christos      are monotonically increasing in increments of one.  */
   3864  1.10  christos   if (stride == 1 && num_regs > 1)
   3865  1.10  christos     if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
   3866  1.10  christos       snprintf (buf, size, "{%s-%s}%s",
   3867  1.10  christos 		style_reg (styler, "%s%d", prefix, first_reg),
   3868  1.10  christos 		style_reg (styler, "%s%d", prefix, last_reg), tb);
   3869  1.10  christos     else
   3870   1.1  christos       snprintf (buf, size, "{%s-%s}%s",
   3871   1.1  christos 		style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
   3872   1.1  christos 		style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
   3873   1.9  christos   else
   3874   1.9  christos     {
   3875   1.9  christos       const int reg0 = first_reg;
   3876   1.1  christos       const int reg1 = (first_reg + stride) & mask;
   3877   1.1  christos       const int reg2 = (first_reg + stride * 2) & mask;
   3878   1.1  christos       const int reg3 = (first_reg + stride * 3) & mask;
   3879   1.1  christos 
   3880   1.9  christos       switch (num_regs)
   3881   1.9  christos 	{
   3882   1.9  christos 	case 1:
   3883   1.1  christos 	  snprintf (buf, size, "{%s}%s",
   3884   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
   3885   1.9  christos 		    tb);
   3886   1.9  christos 	  break;
   3887   1.9  christos 	case 2:
   3888   1.9  christos 	  snprintf (buf, size, "{%s, %s}%s",
   3889   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
   3890   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
   3891   1.9  christos 		    tb);
   3892   1.9  christos 	  break;
   3893   1.9  christos 	case 3:
   3894   1.9  christos 	  snprintf (buf, size, "{%s, %s, %s}%s",
   3895   1.9  christos 		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
   3896   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
   3897   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
   3898   1.9  christos 		    tb);
   3899   1.9  christos 	  break;
   3900   1.9  christos 	case 4:
   3901   1.9  christos 	  snprintf (buf, size, "{%s, %s, %s, %s}%s",
   3902   1.9  christos 		    style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
   3903   1.9  christos 		    style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
   3904   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
   3905   1.1  christos 		    style_reg (styler, "%s%d.%s", prefix, reg3, qlf_name),
   3906   1.1  christos 		    tb);
   3907   1.1  christos 	  break;
   3908   1.1  christos 	}
   3909   1.6  christos     }
   3910   1.6  christos }
   3911   1.6  christos 
   3912   1.6  christos /* Print the register+immediate address in OPND to BUF, which has SIZE
   3913   1.6  christos    characters.  BASE is the name of the base register.  */
   3914   1.6  christos 
   3915   1.9  christos static void
   3916   1.9  christos print_immediate_offset_address (char *buf, size_t size,
   3917   1.6  christos 				const aarch64_opnd_info *opnd,
   3918   1.6  christos 				const char *base,
   3919   1.6  christos 				struct aarch64_styler *styler)
   3920   1.6  christos {
   3921   1.7  christos   if (opnd->addr.writeback)
   3922   1.7  christos     {
   3923   1.9  christos       if (opnd->addr.preind)
   3924   1.7  christos         {
   3925   1.9  christos 	  if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
   3926   1.9  christos 	    snprintf (buf, size, "[%s]!", style_reg (styler, base));
   3927   1.9  christos           else
   3928   1.7  christos 	    snprintf (buf, size, "[%s, %s]!",
   3929   1.6  christos 		      style_reg (styler, base),
   3930   1.9  christos 		      style_imm (styler, "#%d", opnd->addr.offset.imm));
   3931   1.9  christos         }
   3932   1.9  christos       else
   3933   1.6  christos 	snprintf (buf, size, "[%s], %s",
   3934   1.6  christos 		  style_reg (styler, base),
   3935   1.6  christos 		  style_imm (styler, "#%d", opnd->addr.offset.imm));
   3936   1.6  christos     }
   3937   1.6  christos   else
   3938   1.6  christos     {
   3939   1.9  christos       if (opnd->shifter.operator_present)
   3940   1.9  christos 	{
   3941   1.9  christos 	  assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
   3942   1.9  christos 	  snprintf (buf, size, "[%s, %s, %s]",
   3943   1.6  christos 		    style_reg (styler, base),
   3944   1.6  christos 		    style_imm (styler, "#%d", opnd->addr.offset.imm),
   3945   1.9  christos 		    style_sub_mnem (styler, "mul vl"));
   3946   1.9  christos 	}
   3947   1.9  christos       else if (opnd->addr.offset.imm)
   3948   1.6  christos 	snprintf (buf, size, "[%s, %s]",
   3949   1.9  christos 		  style_reg (styler, base),
   3950   1.6  christos 		  style_imm (styler, "#%d", opnd->addr.offset.imm));
   3951   1.6  christos       else
   3952   1.6  christos 	snprintf (buf, size, "[%s]", style_reg (styler, base));
   3953   1.1  christos     }
   3954   1.6  christos }
   3955   1.6  christos 
   3956   1.1  christos /* Produce the string representation of the register offset address operand
   3957   1.1  christos    *OPND in the buffer pointed by BUF of size SIZE.  BASE and OFFSET are
   3958   1.6  christos    the names of the base and offset registers.  */
   3959   1.9  christos static void
   3960   1.9  christos print_register_offset_address (char *buf, size_t size,
   3961   1.1  christos 			       const aarch64_opnd_info *opnd,
   3962   1.9  christos 			       const char *base, const char *offset,
   3963   1.8  christos 			       struct aarch64_styler *styler)
   3964   1.8  christos {
   3965   1.1  christos   char tb[32];			/* Temporary buffer.  */
   3966   1.1  christos   bool print_extend_p = true;
   3967  1.10  christos   bool print_amount_p = true;
   3968  1.10  christos   const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
   3969  1.10  christos 
   3970  1.10  christos   /* This is the case where offset is the optional argument and the optional
   3971  1.10  christos      argument is ignored in the disassembly.  */
   3972  1.10  christos   if (opnd->type == AARCH64_OPND_SVE_ADDR_ZX && offset != NULL
   3973  1.10  christos       && strcmp (offset,"xzr") == 0)
   3974  1.10  christos     {
   3975  1.10  christos       /* Example: [<Zn>.S{, <Xm>}].
   3976  1.10  christos 	 When the assembly is [Z0.S, XZR] or [Z0.S], Xm is XZR in both the cases
   3977  1.10  christos 	 and the preferred disassembly is [Z0.S], ignoring the optional	Xm.  */
   3978   1.1  christos       snprintf (buf, size, "[%s]", style_reg (styler, base));
   3979  1.10  christos     }
   3980  1.10  christos   else
   3981  1.10  christos     {
   3982  1.10  christos       if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
   3983  1.10  christos 				    || !opnd->shifter.amount_present))
   3984  1.10  christos 	{
   3985  1.10  christos 	  /* Not print the shift/extend amount when the amount is zero and
   3986  1.10  christos 	     when it is not the special case of 8-bit load/store
   3987  1.10  christos 	     instruction.  */
   3988  1.10  christos 	 print_amount_p = false;
   3989  1.10  christos 	 /* Likewise, no need to print the shift operator LSL in such a
   3990  1.10  christos 	    situation.  */
   3991  1.10  christos 	 if (opnd->shifter.kind == AARCH64_MOD_LSL)
   3992  1.10  christos 	   print_extend_p = false;
   3993  1.10  christos 	}
   3994  1.10  christos 
   3995  1.10  christos       /* Prepare for the extend/shift.  */
   3996  1.10  christos       if (print_extend_p)
   3997  1.10  christos 	{
   3998  1.10  christos 	  if (print_amount_p)
   3999  1.10  christos 	    snprintf (tb, sizeof (tb), ", %s %s",
   4000  1.10  christos 		      style_sub_mnem (styler, shift_name),
   4001  1.10  christos 		      style_imm (styler, "#%" PRIi64,
   4002  1.10  christos 	  /* PR 21096: The %100 is to silence a warning about possible
   4003  1.10  christos 	     truncation.  */
   4004  1.10  christos 				 (opnd->shifter.amount % 100)));
   4005  1.10  christos 	  else
   4006   1.1  christos 	    snprintf (tb, sizeof (tb), ", %s",
   4007  1.10  christos 		      style_sub_mnem (styler, shift_name));
   4008  1.10  christos 	}
   4009  1.10  christos       else
   4010  1.10  christos 	tb[0] = '\0';
   4011   1.1  christos 
   4012   1.1  christos       snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
   4013   1.1  christos 		style_reg (styler, offset), tb);
   4014   1.8  christos     }
   4015   1.8  christos }
   4016   1.8  christos 
   4017   1.8  christos /* Print ZA tiles from imm8 in ZERO instruction.
   4018   1.8  christos 
   4019   1.8  christos    The preferred disassembly of this instruction uses the shortest list of tile
   4020   1.8  christos    names that represent the encoded immediate mask.
   4021   1.8  christos 
   4022   1.8  christos    For example:
   4023   1.8  christos     * An all-ones immediate is disassembled as {ZA}.
   4024   1.9  christos     * An all-zeros immediate is disassembled as an empty list { }.
   4025   1.9  christos */
   4026   1.8  christos static void
   4027   1.8  christos print_sme_za_list (char *buf, size_t size, int mask,
   4028   1.8  christos 		   struct aarch64_styler *styler)
   4029   1.8  christos {
   4030   1.8  christos   const char* zan[] = { "za",    "za0.h", "za1.h", "za0.s",
   4031   1.8  christos                         "za1.s", "za2.s", "za3.s", "za0.d",
   4032   1.8  christos                         "za1.d", "za2.d", "za3.d", "za4.d",
   4033   1.8  christos                         "za5.d", "za6.d", "za7.d", " " };
   4034   1.8  christos   const int zan_v[] = { 0xff, 0x55, 0xaa, 0x11,
   4035   1.8  christos                         0x22, 0x44, 0x88, 0x01,
   4036   1.8  christos                         0x02, 0x04, 0x08, 0x10,
   4037   1.8  christos                         0x20, 0x40, 0x80, 0x00 };
   4038   1.8  christos   int i, k;
   4039   1.8  christos   const int ZAN_SIZE = sizeof(zan) / sizeof(zan[0]);
   4040   1.8  christos 
   4041   1.8  christos   k = snprintf (buf, size, "{");
   4042   1.8  christos   for (i = 0; i < ZAN_SIZE; i++)
   4043   1.8  christos     {
   4044   1.8  christos       if ((mask & zan_v[i]) == zan_v[i])
   4045   1.9  christos         {
   4046   1.9  christos           mask &= ~zan_v[i];
   4047   1.9  christos           if (k > 1)
   4048   1.8  christos 	    k += snprintf (buf + k, size - k, ", ");
   4049   1.8  christos 
   4050   1.8  christos 	  k += snprintf (buf + k, size - k, "%s", style_reg (styler, zan[i]));
   4051   1.8  christos         }
   4052   1.8  christos       if (mask == 0)
   4053   1.8  christos         break;
   4054   1.8  christos     }
   4055   1.1  christos   snprintf (buf + k, size - k, "}");
   4056   1.1  christos }
   4057   1.1  christos 
   4058   1.1  christos /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
   4059   1.1  christos    in *BUF.  The caller should pass in the maximum size of *BUF in SIZE.
   4060   1.1  christos    PC, PCREL_P and ADDRESS are used to pass in and return information about
   4061   1.1  christos    the PC-relative address calculation, where the PC value is passed in
   4062   1.1  christos    PC.  If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
   4063   1.1  christos    will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
   4064   1.1  christos    calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
   4065   1.1  christos 
   4066   1.1  christos    The function serves both the disassembler and the assembler diagnostics
   4067   1.1  christos    issuer, which is the reason why it lives in this file.  */
   4068   1.1  christos 
   4069   1.1  christos void
   4070   1.8  christos aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
   4071   1.8  christos 		       const aarch64_opcode *opcode,
   4072   1.9  christos 		       const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
   4073   1.9  christos 		       bfd_vma *address, char** notes,
   4074   1.1  christos 		       char *comment, size_t comment_size,
   4075   1.6  christos 		       aarch64_feature_set features,
   4076   1.1  christos 		       struct aarch64_styler *styler)
   4077   1.1  christos {
   4078   1.1  christos   unsigned int i, num_conds;
   4079   1.6  christos   const char *name = NULL;
   4080   1.1  christos   const aarch64_opnd_info *opnd = opnds + idx;
   4081   1.8  christos   enum aarch64_modifier_kind kind;
   4082   1.8  christos   uint64_t addr, enum_value;
   4083   1.8  christos 
   4084   1.8  christos   if (comment != NULL)
   4085   1.8  christos     {
   4086   1.8  christos       assert (comment_size > 0);
   4087   1.8  christos       comment[0] = '\0';
   4088   1.8  christos     }
   4089   1.1  christos   else
   4090   1.1  christos     assert (comment_size == 0);
   4091   1.1  christos 
   4092   1.1  christos   buf[0] = '\0';
   4093   1.1  christos   if (pcrel_p)
   4094   1.1  christos     *pcrel_p = 0;
   4095   1.1  christos 
   4096   1.1  christos   switch (opnd->type)
   4097   1.1  christos     {
   4098   1.1  christos     case AARCH64_OPND_Rd:
   4099   1.1  christos     case AARCH64_OPND_Rn:
   4100   1.1  christos     case AARCH64_OPND_Rm:
   4101   1.1  christos     case AARCH64_OPND_Rt:
   4102  1.10  christos     case AARCH64_OPND_Rt2:
   4103   1.8  christos     case AARCH64_OPND_Rs:
   4104   1.1  christos     case AARCH64_OPND_Ra:
   4105   1.3  christos     case AARCH64_OPND_Rt_IN_SYS_ALIASES:
   4106   1.9  christos     case AARCH64_OPND_Rt_LS64:
   4107   1.6  christos     case AARCH64_OPND_Rt_SYS:
   4108   1.9  christos     case AARCH64_OPND_PAIRREG:
   4109   1.9  christos     case AARCH64_OPND_PAIRREG_OR_XZR:
   4110   1.1  christos     case AARCH64_OPND_SVE_Rm:
   4111   1.6  christos     case AARCH64_OPND_LSE128_Rt:
   4112   1.1  christos     case AARCH64_OPND_LSE128_Rt2:
   4113   1.6  christos       /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
   4114   1.6  christos 	 the <ic_op>, therefore we use opnd->present to override the
   4115   1.6  christos 	 generic optional-ness information.  */
   4116   1.6  christos       if (opnd->type == AARCH64_OPND_Rt_SYS)
   4117   1.6  christos 	{
   4118  1.10  christos 	  if (!opnd->present)
   4119  1.10  christos 	    break;
   4120  1.10  christos 	}
   4121  1.10  christos       else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
   4122  1.10  christos 	       && (opnd->reg.regno
   4123  1.10  christos 		   != get_optional_operand_default_value (opcode)))
   4124  1.10  christos 	{
   4125  1.10  christos 	  /* Avoid printing an invalid additional value for Rt in SYS aliases such as
   4126  1.10  christos 	     BRB, provide a helpful comment instead */
   4127   1.1  christos 	  snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%u", opnd->reg.regno);
   4128   1.6  christos 	  break;
   4129   1.6  christos 	}
   4130   1.6  christos       /* Omit the operand, e.g. RET.  */
   4131   1.1  christos       else if (optional_operand_p (opcode, idx)
   4132   1.1  christos 	       && (opnd->reg.regno
   4133   1.1  christos 		   == get_optional_operand_default_value (opcode)))
   4134   1.1  christos 	break;
   4135   1.9  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   4136   1.9  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
   4137   1.1  christos       snprintf (buf, size, "%s",
   4138   1.1  christos 		style_reg (styler, get_int_reg_name (opnd->reg.regno,
   4139   1.1  christos 						     opnd->qualifier, 0)));
   4140   1.1  christos       break;
   4141   1.7  christos 
   4142   1.6  christos     case AARCH64_OPND_Rd_SP:
   4143   1.6  christos     case AARCH64_OPND_Rn_SP:
   4144   1.1  christos     case AARCH64_OPND_Rt_SP:
   4145   1.1  christos     case AARCH64_OPND_SVE_Rn_SP:
   4146   1.1  christos     case AARCH64_OPND_Rm_SP:
   4147   1.1  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   4148   1.1  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_WSP
   4149   1.9  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X
   4150   1.9  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_SP);
   4151   1.1  christos       snprintf (buf, size, "%s",
   4152   1.1  christos 		style_reg (styler, get_int_reg_name (opnd->reg.regno,
   4153   1.1  christos 						     opnd->qualifier, 1)));
   4154   1.1  christos       break;
   4155   1.1  christos 
   4156   1.1  christos     case AARCH64_OPND_Rm_EXT:
   4157   1.1  christos       kind = opnd->shifter.kind;
   4158   1.1  christos       assert (idx == 1 || idx == 2);
   4159   1.1  christos       if ((aarch64_stack_pointer_p (opnds)
   4160   1.1  christos 	   || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
   4161   1.1  christos 	  && ((opnd->qualifier == AARCH64_OPND_QLF_W
   4162   1.1  christos 	       && opnds[0].qualifier == AARCH64_OPND_QLF_W
   4163   1.1  christos 	       && kind == AARCH64_MOD_UXTW)
   4164   1.1  christos 	      || (opnd->qualifier == AARCH64_OPND_QLF_X
   4165   1.1  christos 		  && kind == AARCH64_MOD_UXTX)))
   4166   1.1  christos 	{
   4167   1.1  christos 	  /* 'LSL' is the preferred form in this case.  */
   4168   1.1  christos 	  kind = AARCH64_MOD_LSL;
   4169   1.1  christos 	  if (opnd->shifter.amount == 0)
   4170   1.9  christos 	    {
   4171   1.9  christos 	      /* Shifter omitted.  */
   4172   1.9  christos 	      snprintf (buf, size, "%s",
   4173   1.1  christos 			style_reg (styler,
   4174   1.1  christos 				   get_int_reg_name (opnd->reg.regno,
   4175   1.1  christos 						     opnd->qualifier, 0)));
   4176   1.1  christos 	      break;
   4177   1.9  christos 	    }
   4178   1.9  christos 	}
   4179   1.9  christos       if (opnd->shifter.amount)
   4180   1.9  christos 	snprintf (buf, size, "%s, %s %s",
   4181   1.1  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
   4182   1.1  christos 		  style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
   4183   1.9  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4184   1.9  christos       else
   4185   1.1  christos 	snprintf (buf, size, "%s, %s",
   4186   1.1  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
   4187   1.1  christos 		  style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
   4188   1.1  christos       break;
   4189   1.1  christos 
   4190   1.1  christos     case AARCH64_OPND_Rm_SFT:
   4191   1.1  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_W
   4192   1.9  christos 	      || opnd->qualifier == AARCH64_OPND_QLF_X);
   4193   1.9  christos       if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
   4194   1.1  christos 	snprintf (buf, size, "%s",
   4195   1.9  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno,
   4196   1.9  christos 						       opnd->qualifier, 0)));
   4197   1.9  christos       else
   4198   1.9  christos 	snprintf (buf, size, "%s, %s %s",
   4199   1.1  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
   4200   1.1  christos 		  style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
   4201  1.10  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4202  1.10  christos       break;
   4203  1.10  christos 
   4204  1.10  christos     case AARCH64_OPND_Rm_LSL:
   4205  1.10  christos       assert (opnd->qualifier == AARCH64_OPND_QLF_X);
   4206  1.10  christos       assert (opnd->shifter.kind == AARCH64_MOD_LSL);
   4207  1.10  christos       if (opnd->shifter.amount == 0)
   4208  1.10  christos 	snprintf (buf, size, "%s",
   4209  1.10  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno,
   4210  1.10  christos 						       opnd->qualifier, 0)));
   4211  1.10  christos       else
   4212  1.10  christos 	snprintf (buf, size, "%s, %s %s",
   4213  1.10  christos 		  style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
   4214  1.10  christos 		  style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
   4215   1.1  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4216   1.1  christos       break;
   4217   1.1  christos 
   4218   1.1  christos     case AARCH64_OPND_Fd:
   4219   1.1  christos     case AARCH64_OPND_Fn:
   4220   1.1  christos     case AARCH64_OPND_Fm:
   4221   1.1  christos     case AARCH64_OPND_Fa:
   4222   1.1  christos     case AARCH64_OPND_Ft:
   4223   1.1  christos     case AARCH64_OPND_Ft2:
   4224   1.6  christos     case AARCH64_OPND_Sd:
   4225   1.6  christos     case AARCH64_OPND_Sn:
   4226   1.6  christos     case AARCH64_OPND_Sm:
   4227   1.6  christos     case AARCH64_OPND_SVE_VZn:
   4228   1.9  christos     case AARCH64_OPND_SVE_Vd:
   4229   1.9  christos     case AARCH64_OPND_SVE_Vm:
   4230   1.9  christos     case AARCH64_OPND_SVE_Vn:
   4231   1.9  christos       snprintf (buf, size, "%s",
   4232   1.1  christos 		style_reg (styler, "%s%d",
   4233   1.1  christos 			   aarch64_get_qualifier_name (opnd->qualifier),
   4234   1.6  christos 			   opnd->reg.regno));
   4235   1.1  christos       break;
   4236   1.1  christos 
   4237   1.1  christos     case AARCH64_OPND_Va:
   4238   1.9  christos     case AARCH64_OPND_Vd:
   4239   1.9  christos     case AARCH64_OPND_Vn:
   4240   1.9  christos     case AARCH64_OPND_Vm:
   4241   1.1  christos       snprintf (buf, size, "%s",
   4242   1.1  christos 		style_reg (styler, "v%d.%s", opnd->reg.regno,
   4243   1.1  christos 			   aarch64_get_qualifier_name (opnd->qualifier)));
   4244   1.1  christos       break;
   4245   1.1  christos 
   4246   1.6  christos     case AARCH64_OPND_Ed:
   4247  1.10  christos     case AARCH64_OPND_En:
   4248   1.6  christos     case AARCH64_OPND_Em:
   4249   1.9  christos     case AARCH64_OPND_Em16:
   4250   1.9  christos     case AARCH64_OPND_Em8:
   4251   1.9  christos     case AARCH64_OPND_SM3_IMM2:
   4252   1.9  christos       snprintf (buf, size, "%s[%s]",
   4253   1.1  christos 		style_reg (styler, "v%d.%s", opnd->reglane.regno,
   4254   1.1  christos 			   aarch64_get_qualifier_name (opnd->qualifier)),
   4255  1.10  christos 		style_imm (styler, "%" PRIi64, opnd->reglane.index));
   4256  1.10  christos       break;
   4257  1.10  christos 
   4258  1.10  christos     case AARCH64_OPND_Em_INDEX1_14:
   4259  1.10  christos     case AARCH64_OPND_Em_INDEX2_13:
   4260  1.10  christos     case AARCH64_OPND_Em_INDEX3_12:
   4261  1.10  christos       snprintf (buf, size, "%s[%s]",
   4262  1.10  christos 		style_reg (styler, "v%d", opnd->reglane.regno),
   4263   1.1  christos 		style_imm (styler, "%" PRIi64, opnd->reglane.index));
   4264   1.1  christos       break;
   4265   1.9  christos 
   4266   1.9  christos     case AARCH64_OPND_VdD1:
   4267   1.9  christos     case AARCH64_OPND_VnD1:
   4268   1.1  christos       snprintf (buf, size, "%s[%s]",
   4269   1.1  christos 		style_reg (styler, "v%d.d", opnd->reg.regno),
   4270   1.1  christos 		style_imm (styler, "1"));
   4271  1.10  christos       break;
   4272   1.1  christos 
   4273   1.1  christos     case AARCH64_OPND_LVn:
   4274   1.1  christos     case AARCH64_OPND_LVn_LUT:
   4275   1.9  christos     case AARCH64_OPND_LVt:
   4276   1.6  christos     case AARCH64_OPND_LVt_AL:
   4277   1.6  christos     case AARCH64_OPND_LEt:
   4278   1.6  christos       print_register_list (buf, size, opnd, "v", styler);
   4279   1.6  christos       break;
   4280   1.6  christos 
   4281   1.6  christos     case AARCH64_OPND_SVE_Pd:
   4282   1.6  christos     case AARCH64_OPND_SVE_Pg3:
   4283   1.6  christos     case AARCH64_OPND_SVE_Pg4_5:
   4284   1.6  christos     case AARCH64_OPND_SVE_Pg4_10:
   4285   1.6  christos     case AARCH64_OPND_SVE_Pg4_16:
   4286   1.8  christos     case AARCH64_OPND_SVE_Pm:
   4287   1.6  christos     case AARCH64_OPND_SVE_Pn:
   4288   1.9  christos     case AARCH64_OPND_SVE_Pt:
   4289   1.9  christos     case AARCH64_OPND_SME_Pm:
   4290   1.9  christos       if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
   4291   1.9  christos 	snprintf (buf, size, "%s",
   4292   1.9  christos 		  style_reg (styler, "p%d", opnd->reg.regno));
   4293   1.9  christos       else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
   4294   1.9  christos 	       || opnd->qualifier == AARCH64_OPND_QLF_P_M)
   4295   1.9  christos 	snprintf (buf, size, "%s",
   4296   1.9  christos 		  style_reg (styler, "p%d/%s", opnd->reg.regno,
   4297   1.9  christos 			     aarch64_get_qualifier_name (opnd->qualifier)));
   4298   1.9  christos       else
   4299   1.9  christos 	snprintf (buf, size, "%s",
   4300   1.9  christos 		  style_reg (styler, "p%d.%s", opnd->reg.regno,
   4301   1.9  christos 			     aarch64_get_qualifier_name (opnd->qualifier)));
   4302   1.9  christos       break;
   4303   1.9  christos 
   4304   1.9  christos     case AARCH64_OPND_SVE_PNd:
   4305   1.9  christos     case AARCH64_OPND_SVE_PNg4_10:
   4306   1.9  christos     case AARCH64_OPND_SVE_PNn:
   4307   1.9  christos     case AARCH64_OPND_SVE_PNt:
   4308   1.9  christos     case AARCH64_OPND_SME_PNd3:
   4309   1.9  christos     case AARCH64_OPND_SME_PNg3:
   4310   1.9  christos     case AARCH64_OPND_SME_PNn:
   4311   1.6  christos       if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
   4312   1.6  christos 	snprintf (buf, size, "%s",
   4313   1.9  christos 		  style_reg (styler, "pn%d", opnd->reg.regno));
   4314   1.9  christos       else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
   4315   1.9  christos 	       || opnd->qualifier == AARCH64_OPND_QLF_P_M)
   4316   1.6  christos 	snprintf (buf, size, "%s",
   4317   1.9  christos 		  style_reg (styler, "pn%d/%s", opnd->reg.regno,
   4318   1.9  christos 			     aarch64_get_qualifier_name (opnd->qualifier)));
   4319   1.9  christos       else
   4320   1.9  christos 	snprintf (buf, size, "%s",
   4321   1.9  christos 		  style_reg (styler, "pn%d.%s", opnd->reg.regno,
   4322   1.9  christos 			     aarch64_get_qualifier_name (opnd->qualifier)));
   4323   1.9  christos       break;
   4324   1.9  christos 
   4325   1.9  christos     case AARCH64_OPND_SME_Pdx2:
   4326   1.9  christos     case AARCH64_OPND_SME_PdxN:
   4327   1.9  christos       print_register_list (buf, size, opnd, "p", styler);
   4328   1.9  christos       break;
   4329   1.9  christos 
   4330   1.9  christos     case AARCH64_OPND_SME_PNn3_INDEX1:
   4331   1.9  christos     case AARCH64_OPND_SME_PNn3_INDEX2:
   4332   1.6  christos       snprintf (buf, size, "%s[%s]",
   4333   1.6  christos 		style_reg (styler, "pn%d", opnd->reglane.regno),
   4334   1.6  christos 		style_imm (styler, "%" PRIi64, opnd->reglane.index));
   4335   1.6  christos       break;
   4336   1.6  christos 
   4337   1.6  christos     case AARCH64_OPND_SVE_Za_5:
   4338   1.6  christos     case AARCH64_OPND_SVE_Za_16:
   4339   1.6  christos     case AARCH64_OPND_SVE_Zd:
   4340   1.6  christos     case AARCH64_OPND_SVE_Zm_5:
   4341   1.9  christos     case AARCH64_OPND_SVE_Zm_16:
   4342  1.10  christos     case AARCH64_OPND_SVE_Zn:
   4343   1.6  christos     case AARCH64_OPND_SVE_Zt:
   4344  1.10  christos     case AARCH64_OPND_SME_Zm:
   4345   1.6  christos     case AARCH64_OPND_SME_Zm_17:
   4346  1.10  christos       if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
   4347  1.10  christos        snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
   4348  1.10  christos       else
   4349   1.6  christos        snprintf (buf, size, "%s",
   4350   1.6  christos 		 style_reg (styler, "z%d.%s", opnd->reg.regno,
   4351   1.6  christos 			    aarch64_get_qualifier_name (opnd->qualifier)));
   4352   1.6  christos       break;
   4353   1.9  christos 
   4354   1.9  christos     case AARCH64_OPND_SVE_ZnxN:
   4355   1.9  christos     case AARCH64_OPND_SVE_ZtxN:
   4356   1.9  christos     case AARCH64_OPND_SME_Zdnx2:
   4357   1.9  christos     case AARCH64_OPND_SME_Zdnx4:
   4358  1.10  christos     case AARCH64_OPND_SME_Zmx2:
   4359   1.9  christos     case AARCH64_OPND_SME_Zmx4:
   4360   1.9  christos     case AARCH64_OPND_SME_Znx2:
   4361   1.9  christos     case AARCH64_OPND_SME_Znx2_BIT_INDEX:
   4362   1.9  christos     case AARCH64_OPND_SME_Znx4:
   4363   1.1  christos     case AARCH64_OPND_SME_Ztx2_STRIDED:
   4364   1.1  christos     case AARCH64_OPND_SME_Ztx4_STRIDED:
   4365  1.10  christos       print_register_list (buf, size, opnd, "z", styler);
   4366  1.10  christos       break;
   4367   1.6  christos 
   4368   1.6  christos     case AARCH64_OPND_SVE_Zm1_23_INDEX:
   4369   1.9  christos     case AARCH64_OPND_SVE_Zm2_22_INDEX:
   4370  1.10  christos     case AARCH64_OPND_SVE_Zm3_INDEX:
   4371   1.7  christos     case AARCH64_OPND_SVE_Zm3_22_INDEX:
   4372  1.10  christos     case AARCH64_OPND_SVE_Zm3_19_INDEX:
   4373   1.7  christos     case AARCH64_OPND_SVE_Zm3_12_INDEX:
   4374   1.6  christos     case AARCH64_OPND_SVE_Zm3_11_INDEX:
   4375   1.6  christos     case AARCH64_OPND_SVE_Zm3_10_INDEX:
   4376   1.9  christos     case AARCH64_OPND_SVE_Zm4_11_INDEX:
   4377   1.9  christos     case AARCH64_OPND_SVE_Zm4_INDEX:
   4378  1.10  christos     case AARCH64_OPND_SVE_Zn_INDEX:
   4379   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX1:
   4380   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX2:
   4381  1.10  christos     case AARCH64_OPND_SME_Zm_INDEX2_3:
   4382   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX3_1:
   4383   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX3_2:
   4384   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX3_3:
   4385  1.10  christos     case AARCH64_OPND_SME_Zm_INDEX3_10:
   4386  1.10  christos     case AARCH64_OPND_SVE_Zn_5_INDEX:
   4387   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX4_1:
   4388   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX4_2:
   4389   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX4_3:
   4390   1.9  christos     case AARCH64_OPND_SME_Zm_INDEX4_10:
   4391  1.10  christos     case AARCH64_OPND_SME_Zn_INDEX1_16:
   4392   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX2_15:
   4393   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX2_16:
   4394   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX2_19:
   4395   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX3_14:
   4396   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX3_15:
   4397   1.9  christos     case AARCH64_OPND_SME_Zn_INDEX4_14:
   4398   1.9  christos       snprintf (buf, size, "%s[%s]",
   4399   1.9  christos 		(opnd->qualifier == AARCH64_OPND_QLF_NIL
   4400   1.9  christos 		 ? style_reg (styler, "z%d", opnd->reglane.regno)
   4401   1.6  christos 		 : style_reg (styler, "z%d.%s", opnd->reglane.regno,
   4402   1.6  christos 			      aarch64_get_qualifier_name (opnd->qualifier))),
   4403  1.10  christos 		style_imm (styler, "%" PRIi64, opnd->reglane.index));
   4404  1.10  christos       break;
   4405  1.10  christos 
   4406  1.10  christos     case AARCH64_OPND_SVE_Zn0_INDEX:
   4407  1.10  christos     case AARCH64_OPND_SVE_Zn1_17_INDEX:
   4408  1.10  christos     case AARCH64_OPND_SVE_Zn2_18_INDEX:
   4409  1.10  christos     case AARCH64_OPND_SVE_Zn3_22_INDEX:
   4410  1.10  christos     case AARCH64_OPND_SVE_Zd0_INDEX:
   4411  1.10  christos     case AARCH64_OPND_SVE_Zd1_17_INDEX:
   4412  1.10  christos     case AARCH64_OPND_SVE_Zd2_18_INDEX:
   4413  1.10  christos     case AARCH64_OPND_SVE_Zd3_22_INDEX:
   4414  1.10  christos       if (opnd->reglane.index == 0)
   4415  1.10  christos 	snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
   4416  1.10  christos       else
   4417  1.10  christos 	snprintf (buf, size, "%s[%s]",
   4418  1.10  christos 		  style_reg (styler, "z%d", opnd->reglane.regno),
   4419  1.10  christos 		  style_imm (styler, "%" PRIi64, opnd->reglane.index));
   4420   1.8  christos       break;
   4421   1.8  christos 
   4422   1.9  christos     case AARCH64_OPND_SME_ZAda_1b:
   4423   1.9  christos     case AARCH64_OPND_SME_ZAda_2b:
   4424   1.9  christos     case AARCH64_OPND_SME_ZAda_3b:
   4425   1.8  christos       snprintf (buf, size, "%s",
   4426   1.8  christos 		style_reg (styler, "za%d.%s", opnd->reg.regno,
   4427   1.8  christos 			   aarch64_get_qualifier_name (opnd->qualifier)));
   4428   1.9  christos       break;
   4429   1.8  christos 
   4430   1.9  christos     case AARCH64_OPND_SME_ZA_HV_idx_src:
   4431   1.8  christos     case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
   4432   1.9  christos     case AARCH64_OPND_SME_ZA_HV_idx_dest:
   4433   1.9  christos     case AARCH64_OPND_SME_ZA_HV_idx_destxN:
   4434   1.9  christos     case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
   4435   1.9  christos       snprintf (buf, size, "%s%s[%s, %s%s%s%s%s]%s",
   4436   1.9  christos 		opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
   4437   1.9  christos 		style_reg (styler, "za%d%c.%s",
   4438   1.9  christos 			   opnd->indexed_za.regno,
   4439   1.9  christos 			   opnd->indexed_za.v == 1 ? 'v' : 'h',
   4440   1.9  christos 			   aarch64_get_qualifier_name (opnd->qualifier)),
   4441   1.9  christos 		style_reg (styler, "w%d", opnd->indexed_za.index.regno),
   4442   1.9  christos 		style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
   4443   1.9  christos 		opnd->indexed_za.index.countm1 ? ":" : "",
   4444   1.9  christos 		(opnd->indexed_za.index.countm1
   4445   1.9  christos 		 ? style_imm (styler, "%d",
   4446   1.9  christos 			      opnd->indexed_za.index.imm
   4447   1.9  christos 			      + opnd->indexed_za.index.countm1)
   4448   1.9  christos 		 : ""),
   4449   1.9  christos 		opnd->indexed_za.group_size ? ", " : "",
   4450   1.9  christos 		opnd->indexed_za.group_size == 2
   4451   1.9  christos 		? style_sub_mnem (styler, "vgx2")
   4452   1.8  christos 		: opnd->indexed_za.group_size == 4
   4453   1.8  christos 		? style_sub_mnem (styler, "vgx4") : "",
   4454   1.8  christos 		opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
   4455  1.10  christos       break;
   4456   1.8  christos 
   4457   1.8  christos     case AARCH64_OPND_SME_list_of_64bit_tiles:
   4458   1.9  christos       print_sme_za_list (buf, size, opnd->imm.value, styler);
   4459   1.9  christos       break;
   4460   1.9  christos 
   4461   1.9  christos     case AARCH64_OPND_SME_ZA_array_off1x4:
   4462   1.9  christos     case AARCH64_OPND_SME_ZA_array_off2x2:
   4463   1.9  christos     case AARCH64_OPND_SME_ZA_array_off2x4:
   4464   1.9  christos     case AARCH64_OPND_SME_ZA_array_off3_0:
   4465   1.9  christos     case AARCH64_OPND_SME_ZA_array_off3_5:
   4466   1.9  christos     case AARCH64_OPND_SME_ZA_array_off3x2:
   4467   1.9  christos     case AARCH64_OPND_SME_ZA_array_off4:
   4468   1.9  christos       snprintf (buf, size, "%s[%s, %s%s%s%s%s]",
   4469   1.9  christos 		style_reg (styler, "za%s%s",
   4470   1.9  christos 			   opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
   4471   1.9  christos 			   (opnd->qualifier == AARCH64_OPND_QLF_NIL
   4472   1.9  christos 			    ? ""
   4473   1.9  christos 			    : aarch64_get_qualifier_name (opnd->qualifier))),
   4474   1.9  christos 		style_reg (styler, "w%d", opnd->indexed_za.index.regno),
   4475   1.9  christos 		style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
   4476   1.9  christos 		opnd->indexed_za.index.countm1 ? ":" : "",
   4477   1.9  christos 		(opnd->indexed_za.index.countm1
   4478   1.9  christos 		 ? style_imm (styler, "%d",
   4479   1.9  christos 			      opnd->indexed_za.index.imm
   4480   1.9  christos 			      + opnd->indexed_za.index.countm1)
   4481   1.9  christos 		 : ""),
   4482   1.9  christos 		opnd->indexed_za.group_size ? ", " : "",
   4483   1.9  christos 		opnd->indexed_za.group_size == 2
   4484   1.9  christos 		? style_sub_mnem (styler, "vgx2")
   4485   1.9  christos 		: opnd->indexed_za.group_size == 4
   4486   1.9  christos 		? style_sub_mnem (styler, "vgx4") : "");
   4487   1.9  christos       break;
   4488   1.9  christos 
   4489   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrsb_1:
   4490   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrsh_1:
   4491   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrss_1:
   4492   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrsd_1:
   4493   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrsb_2:
   4494  1.10  christos     case AARCH64_OPND_SME_ZA_array_vrsh_2:
   4495   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrss_2:
   4496   1.9  christos     case AARCH64_OPND_SME_ZA_array_vrsd_2:
   4497   1.9  christos     case AARCH64_OPND_SME_ZA_ARRAY4:
   4498   1.9  christos       snprintf (buf, size, "%s [%s, %s%s%s]",
   4499   1.9  christos 		style_reg (styler, "za%d%c%s%s",
   4500   1.9  christos 			   opnd->indexed_za.regno,
   4501   1.9  christos 			   opnd->indexed_za.v ? 'v': 'h',
   4502   1.9  christos 			   opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
   4503   1.9  christos 			   (opnd->qualifier == AARCH64_OPND_QLF_NIL
   4504   1.9  christos 			    ? ""
   4505   1.9  christos 			    : aarch64_get_qualifier_name (opnd->qualifier))),
   4506   1.9  christos 		style_reg (styler, "w%d", opnd->indexed_za.index.regno),
   4507   1.9  christos 		style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
   4508   1.9  christos 		opnd->indexed_za.index.countm1 ? ":" : "",
   4509   1.8  christos 		opnd->indexed_za.index.countm1  ? style_imm (styler, "%d",
   4510   1.8  christos 		opnd->indexed_za.index.imm
   4511   1.8  christos 		+ opnd->indexed_za.index.countm1):"");
   4512   1.9  christos       break;
   4513   1.9  christos 
   4514   1.8  christos     case AARCH64_OPND_SME_SM_ZA:
   4515   1.8  christos       snprintf (buf, size, "%s",
   4516   1.8  christos 		style_reg (styler, opnd->reg.regno == 's' ? "sm" : "za"));
   4517   1.9  christos       break;
   4518   1.9  christos 
   4519   1.9  christos     case AARCH64_OPND_SME_PnT_Wm_imm:
   4520   1.9  christos       snprintf (buf, size, "%s[%s, %s]",
   4521   1.9  christos 		style_reg (styler, "p%d.%s", opnd->indexed_za.regno,
   4522   1.9  christos 			   aarch64_get_qualifier_name (opnd->qualifier)),
   4523   1.9  christos 		style_reg (styler, "w%d", opnd->indexed_za.index.regno),
   4524   1.9  christos 		style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
   4525   1.9  christos       break;
   4526   1.9  christos 
   4527   1.9  christos     case AARCH64_OPND_SME_VLxN_10:
   4528   1.9  christos     case AARCH64_OPND_SME_VLxN_13:
   4529   1.9  christos       enum_value = opnd->imm.value;
   4530   1.8  christos       assert (enum_value < ARRAY_SIZE (aarch64_sme_vlxn_array));
   4531   1.8  christos       snprintf (buf, size, "%s",
   4532  1.10  christos 		style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
   4533  1.10  christos       break;
   4534  1.10  christos 
   4535  1.10  christos     case AARCH64_OPND_BRBOP:
   4536  1.10  christos       enum_value = opnd->imm.value;
   4537  1.10  christos       assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
   4538  1.10  christos       snprintf (buf, size, "%s",
   4539   1.6  christos 		style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
   4540   1.6  christos       break;
   4541   1.9  christos 
   4542   1.9  christos     case AARCH64_OPND_CRn:
   4543   1.1  christos     case AARCH64_OPND_CRm:
   4544   1.1  christos       snprintf (buf, size, "%s",
   4545   1.1  christos 		style_reg (styler, "C%" PRIi64, opnd->imm.value));
   4546   1.6  christos       break;
   4547   1.1  christos 
   4548   1.6  christos     case AARCH64_OPND_IDX:
   4549   1.1  christos     case AARCH64_OPND_MASK:
   4550   1.1  christos     case AARCH64_OPND_IMM:
   4551   1.1  christos     case AARCH64_OPND_IMM_2:
   4552   1.1  christos     case AARCH64_OPND_WIDTH:
   4553   1.1  christos     case AARCH64_OPND_UIMM3_OP1:
   4554   1.1  christos     case AARCH64_OPND_UIMM3_OP2:
   4555   1.1  christos     case AARCH64_OPND_BIT_NUM:
   4556   1.1  christos     case AARCH64_OPND_IMM_VLSL:
   4557   1.1  christos     case AARCH64_OPND_IMM_VLSR:
   4558   1.1  christos     case AARCH64_OPND_SHLL_IMM:
   4559   1.8  christos     case AARCH64_OPND_IMM0:
   4560   1.1  christos     case AARCH64_OPND_IMMR:
   4561   1.7  christos     case AARCH64_OPND_IMMS:
   4562   1.6  christos     case AARCH64_OPND_UNDEFINED:
   4563   1.9  christos     case AARCH64_OPND_FBITS:
   4564   1.9  christos     case AARCH64_OPND_TME_UIMM16:
   4565   1.6  christos     case AARCH64_OPND_SIMM5:
   4566   1.6  christos     case AARCH64_OPND_SME_SHRIMM4:
   4567   1.7  christos     case AARCH64_OPND_SME_SHRIMM5:
   4568   1.6  christos     case AARCH64_OPND_SVE_SHLIMM_PRED:
   4569   1.6  christos     case AARCH64_OPND_SVE_SHLIMM_UNPRED:
   4570   1.7  christos     case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
   4571   1.6  christos     case AARCH64_OPND_SVE_SHRIMM_PRED:
   4572   1.6  christos     case AARCH64_OPND_SVE_SHRIMM_UNPRED:
   4573   1.6  christos     case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
   4574   1.6  christos     case AARCH64_OPND_SVE_SIMM5:
   4575   1.6  christos     case AARCH64_OPND_SVE_SIMM5B:
   4576   1.6  christos     case AARCH64_OPND_SVE_SIMM6:
   4577   1.6  christos     case AARCH64_OPND_SVE_SIMM8:
   4578  1.10  christos     case AARCH64_OPND_SVE_UIMM3:
   4579   1.6  christos     case AARCH64_OPND_SVE_UIMM7:
   4580   1.6  christos     case AARCH64_OPND_SVE_UIMM8:
   4581   1.6  christos     case AARCH64_OPND_SVE_UIMM4:
   4582   1.6  christos     case AARCH64_OPND_SVE_UIMM8_53:
   4583   1.6  christos     case AARCH64_OPND_IMM_ROT1:
   4584   1.6  christos     case AARCH64_OPND_IMM_ROT2:
   4585   1.7  christos     case AARCH64_OPND_IMM_ROT3:
   4586   1.9  christos     case AARCH64_OPND_SVE_IMM_ROT1:
   4587   1.9  christos     case AARCH64_OPND_SVE_IMM_ROT2:
   4588   1.9  christos     case AARCH64_OPND_SVE_IMM_ROT3:
   4589   1.9  christos     case AARCH64_OPND_CSSC_SIMM8:
   4590   1.1  christos     case AARCH64_OPND_CSSC_UIMM8:
   4591   1.1  christos       snprintf (buf, size, "%s",
   4592   1.6  christos 		style_imm (styler, "#%" PRIi64, opnd->imm.value));
   4593   1.6  christos       break;
   4594   1.6  christos 
   4595   1.6  christos     case AARCH64_OPND_SVE_I1_HALF_ONE:
   4596   1.6  christos     case AARCH64_OPND_SVE_I1_HALF_TWO:
   4597   1.6  christos     case AARCH64_OPND_SVE_I1_ZERO_ONE:
   4598   1.9  christos       {
   4599   1.6  christos 	single_conv_t c;
   4600   1.6  christos 	c.i = opnd->imm.value;
   4601   1.6  christos 	snprintf (buf, size, "%s", style_imm (styler, "#%.1f", c.f));
   4602   1.6  christos 	break;
   4603   1.6  christos       }
   4604   1.6  christos 
   4605   1.6  christos     case AARCH64_OPND_SVE_PATTERN:
   4606   1.6  christos       if (optional_operand_p (opcode, idx)
   4607   1.6  christos 	  && opnd->imm.value == get_optional_operand_default_value (opcode))
   4608   1.6  christos 	break;
   4609   1.9  christos       enum_value = opnd->imm.value;
   4610   1.9  christos       assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
   4611   1.6  christos       if (aarch64_sve_pattern_array[enum_value])
   4612   1.9  christos 	snprintf (buf, size, "%s",
   4613   1.9  christos 		  style_reg (styler, aarch64_sve_pattern_array[enum_value]));
   4614   1.6  christos       else
   4615   1.6  christos 	snprintf (buf, size, "%s",
   4616   1.6  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
   4617   1.6  christos       break;
   4618   1.6  christos 
   4619   1.6  christos     case AARCH64_OPND_SVE_PATTERN_SCALED:
   4620   1.6  christos       if (optional_operand_p (opcode, idx)
   4621   1.6  christos 	  && !opnd->shifter.operator_present
   4622   1.6  christos 	  && opnd->imm.value == get_optional_operand_default_value (opcode))
   4623   1.6  christos 	break;
   4624   1.9  christos       enum_value = opnd->imm.value;
   4625   1.9  christos       assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
   4626   1.9  christos       if (aarch64_sve_pattern_array[opnd->imm.value])
   4627   1.6  christos 	snprintf (buf, size, "%s",
   4628   1.9  christos 		  style_reg (styler,
   4629   1.9  christos 			     aarch64_sve_pattern_array[opnd->imm.value]));
   4630   1.6  christos       else
   4631   1.6  christos 	snprintf (buf, size, "%s",
   4632   1.6  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
   4633   1.9  christos       if (opnd->shifter.operator_present)
   4634   1.9  christos 	{
   4635   1.9  christos 	  size_t len = strlen (buf);
   4636   1.9  christos 	  const char *shift_name
   4637   1.9  christos 	    = aarch64_operand_modifiers[opnd->shifter.kind].name;
   4638   1.6  christos 	  snprintf (buf + len, size - len, ", %s %s",
   4639   1.6  christos 		    style_sub_mnem (styler, shift_name),
   4640   1.6  christos 		    style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4641   1.6  christos 	}
   4642   1.6  christos       break;
   4643   1.6  christos 
   4644   1.6  christos     case AARCH64_OPND_SVE_PRFOP:
   4645   1.9  christos       enum_value = opnd->imm.value;
   4646   1.9  christos       assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
   4647   1.6  christos       if (aarch64_sve_prfop_array[enum_value])
   4648   1.9  christos 	snprintf (buf, size, "%s",
   4649   1.9  christos 		  style_reg (styler, aarch64_sve_prfop_array[enum_value]));
   4650   1.6  christos       else
   4651   1.6  christos 	snprintf (buf, size, "%s",
   4652   1.1  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
   4653   1.1  christos       break;
   4654   1.1  christos 
   4655   1.1  christos     case AARCH64_OPND_IMM_MOV:
   4656   1.1  christos       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
   4657   1.1  christos 	{
   4658   1.9  christos 	case 4:	/* e.g. MOV Wd, #<imm32>.  */
   4659   1.9  christos 	    {
   4660   1.8  christos 	      int imm32 = opnd->imm.value;
   4661   1.1  christos 	      snprintf (buf, size, "%s",
   4662   1.1  christos 			style_imm (styler, "#0x%-20x", imm32));
   4663   1.1  christos 	      snprintf (comment, comment_size, "#%d", imm32);
   4664   1.9  christos 	    }
   4665   1.9  christos 	  break;
   4666   1.8  christos 	case 8:	/* e.g. MOV Xd, #<imm64>.  */
   4667   1.8  christos 	  snprintf (buf, size, "%s", style_imm (styler, "#0x%-20" PRIx64,
   4668   1.8  christos 						opnd->imm.value));
   4669   1.8  christos 	  snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
   4670   1.1  christos 	  break;
   4671   1.1  christos 	default:
   4672   1.1  christos 	  snprintf (buf, size, "<invalid>");
   4673   1.1  christos 	  break;
   4674   1.1  christos 	}
   4675   1.9  christos       break;
   4676   1.1  christos 
   4677   1.1  christos     case AARCH64_OPND_FPIMM0:
   4678   1.1  christos       snprintf (buf, size, "%s", style_imm (styler, "#0.0"));
   4679   1.1  christos       break;
   4680   1.1  christos 
   4681   1.6  christos     case AARCH64_OPND_LIMM:
   4682   1.6  christos     case AARCH64_OPND_AIMM:
   4683   1.6  christos     case AARCH64_OPND_HALF:
   4684   1.1  christos     case AARCH64_OPND_SVE_INV_LIMM:
   4685   1.9  christos     case AARCH64_OPND_SVE_LIMM:
   4686   1.9  christos     case AARCH64_OPND_SVE_LIMM_MOV:
   4687   1.9  christos       if (opnd->shifter.amount)
   4688   1.9  christos 	snprintf (buf, size, "%s, %s %s",
   4689   1.1  christos 		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
   4690   1.9  christos 		  style_sub_mnem (styler, "lsl"),
   4691   1.9  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4692   1.1  christos       else
   4693   1.1  christos 	snprintf (buf, size, "%s",
   4694   1.1  christos 		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
   4695   1.1  christos       break;
   4696   1.1  christos 
   4697   1.1  christos     case AARCH64_OPND_SIMD_IMM:
   4698   1.9  christos     case AARCH64_OPND_SIMD_IMM_SFT:
   4699   1.9  christos       if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
   4700   1.1  christos 	  || opnd->shifter.kind == AARCH64_MOD_NONE)
   4701   1.9  christos 	snprintf (buf, size, "%s",
   4702   1.9  christos 		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
   4703   1.9  christos       else
   4704   1.9  christos 	snprintf (buf, size, "%s, %s %s",
   4705   1.1  christos 		  style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
   4706   1.1  christos 		  style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
   4707   1.6  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4708   1.6  christos       break;
   4709   1.6  christos 
   4710   1.9  christos     case AARCH64_OPND_SVE_AIMM:
   4711   1.9  christos     case AARCH64_OPND_SVE_ASIMM:
   4712   1.9  christos       if (opnd->shifter.amount)
   4713   1.9  christos 	snprintf (buf, size, "%s, %s %s",
   4714   1.6  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value),
   4715   1.9  christos 		  style_sub_mnem (styler, "lsl"),
   4716   1.9  christos 		  style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
   4717   1.6  christos       else
   4718   1.6  christos 	snprintf (buf, size, "%s",
   4719   1.1  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
   4720   1.1  christos       break;
   4721   1.6  christos 
   4722   1.1  christos     case AARCH64_OPND_FPIMM:
   4723   1.1  christos     case AARCH64_OPND_SIMD_FPIMM:
   4724   1.3  christos     case AARCH64_OPND_SVE_FPIMM8:
   4725   1.3  christos       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
   4726   1.3  christos 	{
   4727   1.3  christos 	case 2:	/* e.g. FMOV <Hd>, #<imm>.  */
   4728   1.9  christos 	    {
   4729   1.3  christos 	      half_conv_t c;
   4730   1.3  christos 	      c.i = expand_fp_imm (2, opnd->imm.value);
   4731   1.1  christos 	      snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
   4732   1.1  christos 	    }
   4733   1.1  christos 	  break;
   4734   1.3  christos 	case 4:	/* e.g. FMOV <Vd>.4S, #<imm>.  */
   4735   1.9  christos 	    {
   4736   1.1  christos 	      single_conv_t c;
   4737   1.1  christos 	      c.i = expand_fp_imm (4, opnd->imm.value);
   4738   1.1  christos 	      snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
   4739   1.1  christos 	    }
   4740   1.1  christos 	  break;
   4741   1.3  christos 	case 8:	/* e.g. FMOV <Sd>, #<imm>.  */
   4742   1.9  christos 	    {
   4743   1.1  christos 	      double_conv_t c;
   4744   1.1  christos 	      c.i = expand_fp_imm (8, opnd->imm.value);
   4745   1.8  christos 	      snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.d));
   4746   1.8  christos 	    }
   4747   1.8  christos 	  break;
   4748   1.1  christos 	default:
   4749   1.1  christos 	  snprintf (buf, size, "<invalid>");
   4750   1.1  christos 	  break;
   4751   1.1  christos 	}
   4752   1.1  christos       break;
   4753   1.1  christos 
   4754   1.1  christos     case AARCH64_OPND_CCMP_IMM:
   4755   1.7  christos     case AARCH64_OPND_NZCV:
   4756   1.1  christos     case AARCH64_OPND_EXCEPTION:
   4757   1.7  christos     case AARCH64_OPND_UIMM4:
   4758   1.8  christos     case AARCH64_OPND_UIMM4_ADDG:
   4759   1.1  christos     case AARCH64_OPND_UIMM7:
   4760   1.1  christos     case AARCH64_OPND_UIMM10:
   4761   1.1  christos       if (optional_operand_p (opcode, idx)
   4762   1.1  christos 	  && (opnd->imm.value ==
   4763   1.9  christos 	      (int64_t) get_optional_operand_default_value (opcode)))
   4764   1.9  christos 	/* Omit the operand, e.g. DCPS1.  */
   4765   1.1  christos 	break;
   4766   1.1  christos       snprintf (buf, size, "%s",
   4767   1.1  christos 		style_imm (styler, "#0x%x", (unsigned int) opnd->imm.value));
   4768   1.3  christos       break;
   4769   1.9  christos 
   4770   1.9  christos     case AARCH64_OPND_COND:
   4771   1.6  christos     case AARCH64_OPND_COND1:
   4772   1.6  christos       snprintf (buf, size, "%s",
   4773   1.6  christos 		style_sub_mnem (styler, opnd->cond->names[0]));
   4774   1.8  christos       num_conds = ARRAY_SIZE (opnd->cond->names);
   4775   1.6  christos       for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
   4776   1.8  christos 	{
   4777   1.6  christos 	  size_t len = comment != NULL ? strlen (comment) : 0;
   4778   1.6  christos 	  if (i == 1)
   4779   1.8  christos 	    snprintf (comment + len, comment_size - len, "%s = %s",
   4780   1.6  christos 		      opnd->cond->names[0], opnd->cond->names[i]);
   4781   1.6  christos 	  else
   4782   1.1  christos 	    snprintf (comment + len, comment_size - len, ", %s",
   4783   1.1  christos 		      opnd->cond->names[i]);
   4784   1.1  christos 	}
   4785   1.1  christos       break;
   4786   1.1  christos 
   4787   1.1  christos     case AARCH64_OPND_ADDR_ADRP:
   4788   1.1  christos       addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
   4789   1.1  christos 	+ opnd->imm.value;
   4790   1.1  christos       if (pcrel_p)
   4791   1.1  christos 	*pcrel_p = 1;
   4792   1.1  christos       if (address)
   4793   1.1  christos 	*address = addr;
   4794   1.1  christos       /* This is not necessary during the disassembling, as print_address_func
   4795   1.9  christos 	 in the disassemble_info will take care of the printing.  But some
   4796   1.1  christos 	 other callers may be still interested in getting the string in *STR,
   4797   1.1  christos 	 so here we do snprintf regardless.  */
   4798  1.10  christos       snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
   4799   1.1  christos       break;
   4800   1.1  christos 
   4801   1.1  christos     case AARCH64_OPND_ADDR_PCREL9:
   4802   1.1  christos     case AARCH64_OPND_ADDR_PCREL14:
   4803   1.1  christos     case AARCH64_OPND_ADDR_PCREL19:
   4804   1.1  christos     case AARCH64_OPND_ADDR_PCREL21:
   4805   1.1  christos     case AARCH64_OPND_ADDR_PCREL26:
   4806   1.1  christos       addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
   4807   1.1  christos       if (pcrel_p)
   4808   1.1  christos 	*pcrel_p = 1;
   4809   1.1  christos       if (address)
   4810   1.1  christos 	*address = addr;
   4811   1.1  christos       /* This is not necessary during the disassembling, as print_address_func
   4812   1.9  christos 	 in the disassemble_info will take care of the printing.  But some
   4813   1.1  christos 	 other callers may be still interested in getting the string in *STR,
   4814   1.1  christos 	 so here we do snprintf regardless.  */
   4815   1.1  christos       snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
   4816   1.1  christos       break;
   4817   1.1  christos 
   4818   1.1  christos     case AARCH64_OPND_ADDR_SIMPLE:
   4819   1.1  christos     case AARCH64_OPND_SIMD_ADDR_SIMPLE:
   4820   1.1  christos     case AARCH64_OPND_SIMD_ADDR_POST:
   4821   1.1  christos       name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
   4822   1.9  christos       if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
   4823   1.9  christos 	{
   4824   1.9  christos 	  if (opnd->addr.offset.is_reg)
   4825   1.1  christos 	    snprintf (buf, size, "[%s], %s",
   4826   1.9  christos 		      style_reg (styler, name),
   4827   1.9  christos 		      style_reg (styler, "x%d", opnd->addr.offset.regno));
   4828   1.9  christos 	  else
   4829   1.1  christos 	    snprintf (buf, size, "[%s], %s",
   4830   1.1  christos 		      style_reg (styler, name),
   4831   1.9  christos 		      style_imm (styler, "#%d", opnd->addr.offset.imm));
   4832   1.1  christos 	}
   4833   1.1  christos       else
   4834   1.1  christos 	snprintf (buf, size, "[%s]", style_reg (styler, name));
   4835   1.6  christos       break;
   4836   1.6  christos 
   4837   1.6  christos     case AARCH64_OPND_ADDR_REGOFF:
   4838   1.6  christos     case AARCH64_OPND_SVE_ADDR_RR:
   4839   1.8  christos     case AARCH64_OPND_SVE_ADDR_RR_LSL1:
   4840  1.10  christos     case AARCH64_OPND_SVE_ADDR_RR_LSL2:
   4841  1.10  christos     case AARCH64_OPND_SVE_ADDR_RR_LSL3:
   4842  1.10  christos     case AARCH64_OPND_SVE_ADDR_RR_LSL4:
   4843  1.10  christos     case AARCH64_OPND_SVE_ADDR_RM:
   4844  1.10  christos     case AARCH64_OPND_SVE_ADDR_RM_LSL1:
   4845   1.6  christos     case AARCH64_OPND_SVE_ADDR_RM_LSL2:
   4846   1.6  christos     case AARCH64_OPND_SVE_ADDR_RM_LSL3:
   4847   1.6  christos     case AARCH64_OPND_SVE_ADDR_RM_LSL4:
   4848   1.6  christos     case AARCH64_OPND_SVE_ADDR_RX:
   4849  1.10  christos     case AARCH64_OPND_SVE_ADDR_RX_LSL1:
   4850   1.6  christos     case AARCH64_OPND_SVE_ADDR_RX_LSL2:
   4851   1.6  christos     case AARCH64_OPND_SVE_ADDR_RX_LSL3:
   4852   1.9  christos     case AARCH64_OPND_SVE_ADDR_RX_LSL4:
   4853   1.6  christos       print_register_offset_address
   4854   1.6  christos 	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
   4855   1.7  christos 	 get_offset_int_reg_name (opnd), styler);
   4856   1.7  christos       break;
   4857   1.7  christos 
   4858   1.7  christos     case AARCH64_OPND_SVE_ADDR_ZX:
   4859   1.9  christos       print_register_offset_address
   4860   1.7  christos 	(buf, size, opnd,
   4861   1.7  christos 	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
   4862   1.6  christos 	 get_64bit_int_reg_name (opnd->addr.offset.regno, 0), styler);
   4863   1.6  christos       break;
   4864   1.6  christos 
   4865   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ:
   4866   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
   4867   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
   4868   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
   4869   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
   4870   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
   4871   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
   4872   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
   4873   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
   4874   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
   4875   1.6  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
   4876   1.9  christos     case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
   4877   1.9  christos       print_register_offset_address
   4878   1.1  christos 	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
   4879   1.1  christos 	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
   4880   1.1  christos 	 styler);
   4881   1.1  christos       break;
   4882   1.1  christos 
   4883   1.6  christos     case AARCH64_OPND_ADDR_SIMM7:
   4884   1.7  christos     case AARCH64_OPND_ADDR_SIMM9:
   4885   1.7  christos     case AARCH64_OPND_ADDR_SIMM9_2:
   4886   1.9  christos     case AARCH64_OPND_ADDR_SIMM10:
   4887   1.6  christos     case AARCH64_OPND_ADDR_SIMM11:
   4888   1.9  christos     case AARCH64_OPND_ADDR_SIMM13:
   4889   1.9  christos     case AARCH64_OPND_RCPC3_ADDR_OFFSET:
   4890   1.9  christos     case AARCH64_OPND_ADDR_OFFSET:
   4891   1.9  christos     case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
   4892   1.8  christos     case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
   4893   1.6  christos     case AARCH64_OPND_RCPC3_ADDR_POSTIND:
   4894   1.7  christos     case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
   4895   1.6  christos     case AARCH64_OPND_SME_ADDR_RI_U4xVL:
   4896   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4x16:
   4897   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4x32:
   4898   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
   4899   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
   4900   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
   4901   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
   4902   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
   4903   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
   4904   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_U6:
   4905   1.6  christos     case AARCH64_OPND_SVE_ADDR_RI_U6x2:
   4906   1.9  christos     case AARCH64_OPND_SVE_ADDR_RI_U6x4:
   4907   1.9  christos     case AARCH64_OPND_SVE_ADDR_RI_U6x8:
   4908   1.6  christos       print_immediate_offset_address
   4909   1.6  christos 	(buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
   4910   1.6  christos 	 styler);
   4911   1.6  christos       break;
   4912   1.6  christos 
   4913   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZI_U5:
   4914   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
   4915   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
   4916   1.9  christos     case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
   4917   1.9  christos       print_immediate_offset_address
   4918   1.6  christos 	(buf, size, opnd,
   4919   1.6  christos 	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
   4920   1.6  christos 	 styler);
   4921   1.6  christos       break;
   4922   1.6  christos 
   4923   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
   4924   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
   4925   1.6  christos     case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
   4926   1.9  christos       print_register_offset_address
   4927   1.9  christos 	(buf, size, opnd,
   4928   1.1  christos 	 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
   4929   1.1  christos 	 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
   4930   1.1  christos 	 styler);
   4931   1.1  christos       break;
   4932   1.1  christos 
   4933   1.9  christos     case AARCH64_OPND_ADDR_UIMM12:
   4934   1.9  christos       name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
   4935   1.9  christos       if (opnd->addr.offset.imm)
   4936   1.1  christos 	snprintf (buf, size, "[%s, %s]",
   4937   1.9  christos 		  style_reg (styler, name),
   4938   1.1  christos 		  style_imm (styler, "#%d", opnd->addr.offset.imm));
   4939   1.1  christos       else
   4940   1.1  christos 	snprintf (buf, size, "[%s]", style_reg (styler, name));
   4941   1.9  christos       break;
   4942   1.1  christos 
   4943   1.6  christos     case AARCH64_OPND_SYSREG:
   4944   1.8  christos     case AARCH64_OPND_SYSREG128:
   4945   1.8  christos       for (i = 0; aarch64_sys_regs[i].name; ++i)
   4946   1.8  christos 	{
   4947   1.8  christos 	  const aarch64_sys_reg *sr = aarch64_sys_regs + i;
   4948   1.8  christos 
   4949   1.9  christos 	  bool exact_match
   4950   1.6  christos 	    = (!(sr->flags & (F_REG_READ | F_REG_WRITE))
   4951   1.6  christos 	    || (sr->flags & opnd->sysreg.flags) == opnd->sysreg.flags)
   4952   1.6  christos 	    && AARCH64_CPU_HAS_ALL_FEATURES (features, sr->features);
   4953   1.6  christos 
   4954   1.8  christos 	  /* Try and find an exact match, But if that fails, return the first
   4955   1.9  christos 	     partial match that was found.  */
   4956   1.6  christos 	  if (aarch64_sys_regs[i].value == opnd->sysreg.value
   4957   1.6  christos 	      && ! aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
   4958   1.6  christos 	      && ! aarch64_sys_reg_alias_p (aarch64_sys_regs[i].flags)
   4959   1.6  christos 	      && (name == NULL || exact_match))
   4960   1.6  christos 	    {
   4961   1.6  christos 	      name = aarch64_sys_regs[i].name;
   4962   1.6  christos 	      if (exact_match)
   4963   1.6  christos 		{
   4964   1.6  christos 		  if (notes)
   4965   1.6  christos 		    *notes = NULL;
   4966   1.6  christos 		  break;
   4967   1.6  christos 		}
   4968   1.6  christos 
   4969   1.6  christos 	      /* If we didn't match exactly, that means the presense of a flag
   4970   1.6  christos 		 indicates what we didn't want for this instruction.  e.g. If
   4971   1.7  christos 		 F_REG_READ is there, that means we were looking for a write
   4972   1.6  christos 		 register.  See aarch64_ext_sysreg.  */
   4973   1.7  christos 	      if (aarch64_sys_regs[i].flags & F_REG_WRITE)
   4974   1.6  christos 		*notes = _("reading from a write-only register");
   4975   1.6  christos 	      else if (aarch64_sys_regs[i].flags & F_REG_READ)
   4976   1.6  christos 		*notes = _("writing to a read-only register");
   4977   1.6  christos 	    }
   4978   1.9  christos 	}
   4979   1.1  christos 
   4980   1.1  christos       if (name)
   4981   1.1  christos 	snprintf (buf, size, "%s", style_reg (styler, name));
   4982   1.6  christos       else
   4983   1.9  christos 	{
   4984   1.9  christos 	  /* Implementation defined system register.  */
   4985   1.9  christos 	  unsigned int value = opnd->sysreg.value;
   4986   1.9  christos 	  snprintf (buf, size, "%s",
   4987   1.9  christos 		    style_reg (styler, "s%u_%u_c%u_c%u_%u",
   4988   1.1  christos 			       (value >> 14) & 0x3, (value >> 11) & 0x7,
   4989   1.1  christos 			       (value >> 7) & 0xf, (value >> 3) & 0xf,
   4990   1.1  christos 			       value & 0x7));
   4991   1.1  christos 	}
   4992   1.1  christos       break;
   4993   1.8  christos 
   4994   1.8  christos     case AARCH64_OPND_PSTATEFIELD:
   4995   1.8  christos       for (i = 0; aarch64_pstatefields[i].name; ++i)
   4996   1.8  christos         if (aarch64_pstatefields[i].value == opnd->pstatefield)
   4997   1.8  christos           {
   4998   1.8  christos             /* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
   4999   1.8  christos                SVCRZA and SVCRSMZA.  */
   5000   1.8  christos             uint32_t flags = aarch64_pstatefields[i].flags;
   5001   1.8  christos             if (flags & F_REG_IN_CRM
   5002   1.8  christos                 && (PSTATE_DECODE_CRM (opnd->sysreg.flags)
   5003   1.8  christos                     != PSTATE_DECODE_CRM (flags)))
   5004   1.1  christos               continue;
   5005   1.9  christos             break;
   5006   1.9  christos           }
   5007   1.1  christos       assert (aarch64_pstatefields[i].name);
   5008   1.1  christos       snprintf (buf, size, "%s",
   5009   1.1  christos 		style_reg (styler, aarch64_pstatefields[i].name));
   5010   1.1  christos       break;
   5011   1.1  christos 
   5012   1.1  christos     case AARCH64_OPND_SYSREG_AT:
   5013   1.9  christos     case AARCH64_OPND_SYSREG_DC:
   5014   1.7  christos     case AARCH64_OPND_SYSREG_IC:
   5015   1.9  christos     case AARCH64_OPND_SYSREG_TLBI:
   5016   1.1  christos     case AARCH64_OPND_SYSREG_TLBIP:
   5017   1.1  christos     case AARCH64_OPND_SYSREG_SR:
   5018   1.1  christos       snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name));
   5019   1.8  christos       break;
   5020   1.9  christos 
   5021   1.9  christos     case AARCH64_OPND_BARRIER:
   5022   1.9  christos     case AARCH64_OPND_BARRIER_DSB_NXS:
   5023   1.9  christos       {
   5024   1.9  christos 	if (opnd->barrier->name[0] == '#')
   5025   1.9  christos 	  snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
   5026   1.9  christos 	else
   5027   1.1  christos 	  snprintf (buf, size, "%s",
   5028   1.1  christos 		    style_sub_mnem (styler, opnd->barrier->name));
   5029   1.1  christos       }
   5030   1.1  christos       break;
   5031   1.1  christos 
   5032   1.1  christos     case AARCH64_OPND_BARRIER_ISB:
   5033   1.1  christos       /* Operand can be omitted, e.g. in DCPS1.  */
   5034   1.9  christos       if (! optional_operand_p (opcode, idx)
   5035   1.9  christos 	  || (opnd->barrier->value
   5036   1.1  christos 	      != get_optional_operand_default_value (opcode)))
   5037   1.1  christos 	snprintf (buf, size, "%s",
   5038   1.1  christos 		  style_imm (styler, "#0x%x", opnd->barrier->value));
   5039  1.10  christos       break;
   5040  1.10  christos 
   5041  1.10  christos     case AARCH64_OPND_PRFOP:
   5042  1.10  christos       if ((opnd->prfop->name == NULL)
   5043   1.9  christos           || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18))
   5044  1.10  christos         snprintf (buf, size, "%s",
   5045   1.9  christos                   style_imm (styler, "#0x%02x", opnd->prfop->value));
   5046   1.9  christos       else
   5047   1.9  christos         snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
   5048   1.9  christos       break;
   5049   1.9  christos 
   5050   1.9  christos     case AARCH64_OPND_RPRFMOP:
   5051   1.9  christos       enum_value = opnd->imm.value;
   5052   1.9  christos       if (enum_value < ARRAY_SIZE (aarch64_rprfmop_array)
   5053   1.1  christos 	  && aarch64_rprfmop_array[enum_value])
   5054   1.9  christos 	snprintf (buf, size, "%s",
   5055   1.9  christos 		  style_reg (styler, aarch64_rprfmop_array[enum_value]));
   5056   1.1  christos       else
   5057   1.1  christos 	snprintf (buf, size, "%s",
   5058   1.3  christos 		  style_imm (styler, "#%" PRIi64, opnd->imm.value));
   5059   1.9  christos       break;
   5060   1.9  christos 
   5061   1.9  christos     case AARCH64_OPND_BARRIER_PSB:
   5062   1.9  christos       snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
   5063   1.9  christos       break;
   5064   1.9  christos 
   5065   1.9  christos     case AARCH64_OPND_X16:
   5066   1.9  christos       snprintf (buf, size, "%s", style_reg (styler, "x16"));
   5067   1.9  christos       break;
   5068   1.9  christos 
   5069   1.9  christos     case AARCH64_OPND_SME_ZT0:
   5070   1.9  christos       snprintf (buf, size, "%s", style_reg (styler, "zt0"));
   5071   1.9  christos       break;
   5072   1.9  christos 
   5073   1.9  christos     case AARCH64_OPND_SME_ZT0_INDEX:
   5074  1.10  christos       snprintf (buf, size, "%s[%s]", style_reg (styler, "zt0"),
   5075  1.10  christos 		style_imm (styler, "%d", (int) opnd->imm.value));
   5076  1.10  christos       break;
   5077  1.10  christos     case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
   5078  1.10  christos       snprintf (buf, size, "%s[%s, %s]", style_reg (styler, "zt0"),
   5079   1.9  christos 		style_imm (styler, "%d", (int) opnd->imm.value),
   5080   1.9  christos 		style_sub_mnem (styler, "mul vl"));
   5081   1.9  christos       break;
   5082   1.9  christos 
   5083   1.9  christos     case AARCH64_OPND_SME_ZT0_LIST:
   5084   1.9  christos       snprintf (buf, size, "{%s}", style_reg (styler, "zt0"));
   5085   1.9  christos       break;
   5086   1.8  christos 
   5087   1.8  christos     case AARCH64_OPND_BARRIER_GCSB:
   5088   1.7  christos       snprintf (buf, size, "%s", style_sub_mnem (styler, "dsync"));
   5089   1.7  christos       break;
   5090   1.9  christos 
   5091   1.9  christos     case AARCH64_OPND_BTI_TARGET:
   5092   1.3  christos       if ((HINT_FLAG (opnd->hint_option->value) & HINT_OPD_F_NOPRINT) == 0)
   5093   1.3  christos 	snprintf (buf, size, "%s",
   5094  1.10  christos 		  style_sub_mnem (styler, opnd->hint_option->name));
   5095  1.10  christos       break;
   5096  1.10  christos 
   5097  1.10  christos     case AARCH64_OPND_STSHH_POLICY:
   5098   1.8  christos       snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name));
   5099   1.8  christos       break;
   5100   1.8  christos 
   5101   1.9  christos     case AARCH64_OPND_MOPS_ADDR_Rd:
   5102   1.9  christos     case AARCH64_OPND_MOPS_ADDR_Rs:
   5103   1.9  christos       snprintf (buf, size, "[%s]!",
   5104   1.8  christos 		style_reg (styler,
   5105   1.8  christos 			   get_int_reg_name (opnd->reg.regno,
   5106   1.8  christos 					     AARCH64_OPND_QLF_X, 0)));
   5107   1.8  christos       break;
   5108   1.9  christos 
   5109   1.9  christos     case AARCH64_OPND_MOPS_WB_Rn:
   5110   1.8  christos       snprintf (buf, size, "%s!",
   5111   1.8  christos 		style_reg (styler, get_int_reg_name (opnd->reg.regno,
   5112   1.1  christos 						     AARCH64_OPND_QLF_X, 0)));
   5113   1.8  christos       break;
   5114   1.8  christos 
   5115   1.1  christos     default:
   5116   1.1  christos       snprintf (buf, size, "<invalid>");
   5117   1.1  christos       break;
   5118   1.1  christos     }
   5119   1.1  christos }
   5120   1.1  christos 
   5121   1.1  christos #define CPENC(op0,op1,crn,crm,op2) \
   5123   1.1  christos   ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
   5124   1.1  christos   /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
   5125   1.1  christos #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
   5126   1.1  christos   /* for 3.9.10 System Instructions */
   5127   1.1  christos #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
   5128   1.1  christos 
   5129   1.1  christos #define C0  0
   5130   1.1  christos #define C1  1
   5131   1.1  christos #define C2  2
   5132   1.1  christos #define C3  3
   5133   1.1  christos #define C4  4
   5134   1.1  christos #define C5  5
   5135   1.1  christos #define C6  6
   5136   1.1  christos #define C7  7
   5137   1.1  christos #define C8  8
   5138   1.1  christos #define C9  9
   5139   1.1  christos #define C10 10
   5140   1.1  christos #define C11 11
   5141   1.1  christos #define C12 12
   5142   1.6  christos #define C13 13
   5143   1.8  christos #define C14 14
   5144   1.8  christos #define C15 15
   5145   1.8  christos 
   5146   1.8  christos /* TODO there is one more issues need to be resolved
   5147   1.3  christos    1. handle cpu-implementation-defined system registers.
   5148   1.1  christos 
   5149   1.9  christos    Note that the F_REG_{READ,WRITE} flags mean read-only and write-only
   5150   1.9  christos    respectively.  If neither of these are set then the register is read-write.  */
   5151   1.9  christos const aarch64_sys_reg aarch64_sys_regs [] =
   5152   1.9  christos {
   5153   1.9  christos   #define SYSREG(name, encoding, flags, features) \
   5154   1.8  christos     { name, encoding, flags, features },
   5155   1.6  christos   #include "aarch64-sys-regs.def"
   5156   1.8  christos   { 0, CPENC (0,0,0,0,0), 0, AARCH64_NO_FEATURES }
   5157   1.8  christos   #undef SYSREG
   5158   1.8  christos };
   5159   1.8  christos 
   5160   1.3  christos bool
   5161   1.3  christos aarch64_sys_reg_deprecated_p (const uint32_t reg_flags)
   5162   1.9  christos {
   5163   1.9  christos   return (reg_flags & F_DEPRECATED) != 0;
   5164   1.9  christos }
   5165   1.9  christos 
   5166   1.9  christos bool
   5167   1.9  christos aarch64_sys_reg_128bit_p (const uint32_t reg_flags)
   5168   1.9  christos {
   5169   1.9  christos   return (reg_flags & F_REG_128) != 0;
   5170   1.9  christos }
   5171   1.9  christos 
   5172   1.9  christos bool
   5173   1.9  christos aarch64_sys_reg_alias_p (const uint32_t reg_flags)
   5174   1.6  christos {
   5175   1.6  christos   return (reg_flags & F_REG_ALIAS) != 0;
   5176   1.6  christos }
   5177   1.6  christos 
   5178   1.6  christos /* The CPENC below is fairly misleading, the fields
   5179   1.6  christos    here are not in CPENC form. They are in op2op1 form. The fields are encoded
   5180   1.6  christos    by ins_pstatefield, which just shifts the value by the width of the fields
   5181   1.3  christos    in a loop. So if you CPENC them only the first value will be set, the rest
   5182   1.3  christos    are masked out to 0. As an example. op2 = 3, op1=2. CPENC would produce a
   5183   1.9  christos    value of 0b110000000001000000 (0x30040) while what you want is
   5184   1.9  christos    0b011010 (0x1a).  */
   5185   1.9  christos const aarch64_sys_reg aarch64_pstatefields [] =
   5186   1.9  christos {
   5187   1.9  christos   { "spsel",	0x05, F_REG_MAX_VALUE (1), AARCH64_NO_FEATURES },
   5188   1.9  christos   { "daifset",	0x1e, F_REG_MAX_VALUE (15), AARCH64_NO_FEATURES },
   5189   1.9  christos   { "daifclr",	0x1f, F_REG_MAX_VALUE (15), AARCH64_NO_FEATURES },
   5190   1.9  christos   { "pan",	0x04, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (PAN) },
   5191   1.9  christos   { "uao",	0x03, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (V8_2A) },
   5192   1.9  christos   { "ssbs",	0x19, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (SSBS) },
   5193   1.9  christos   { "dit",	0x1a, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (V8_4A) },
   5194   1.9  christos   { "tco",	0x1c, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5195   1.9  christos   { "svcrsm",	0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x2,0x1) | F_REG_MAX_VALUE (1)
   5196   1.9  christos 		      | F_ARCHEXT, AARCH64_FEATURE (SME) },
   5197   1.9  christos   { "svcrza",	0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x4,0x1) | F_REG_MAX_VALUE (1)
   5198   1.9  christos 		      | F_ARCHEXT, AARCH64_FEATURE (SME) },
   5199   1.1  christos   { "svcrsmza",	0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x6,0x1) | F_REG_MAX_VALUE (1)
   5200   1.1  christos 		      | F_ARCHEXT, AARCH64_FEATURE (SME) },
   5201   1.8  christos   { "allint",	0x08, F_REG_MAX_VALUE (1) | F_ARCHEXT, AARCH64_FEATURE (V8_8A) },
   5202   1.3  christos   { 0,	CPENC (0,0,0,0,0), 0, AARCH64_NO_FEATURES },
   5203   1.3  christos };
   5204   1.3  christos 
   5205   1.3  christos bool
   5206   1.8  christos aarch64_pstatefield_supported_p (const aarch64_feature_set features,
   5207   1.7  christos 				 const aarch64_sys_reg *reg)
   5208   1.8  christos {
   5209   1.3  christos   if (!(reg->flags & F_ARCHEXT))
   5210   1.3  christos     return true;
   5211   1.1  christos 
   5212   1.1  christos   return AARCH64_CPU_HAS_ALL_FEATURES (features, reg->features);
   5213   1.9  christos }
   5214   1.9  christos 
   5215   1.9  christos const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
   5216   1.9  christos {
   5217   1.1  christos     { "ialluis", CPENS(0,C7,C1,0), 0, AARCH64_NO_FEATURES },
   5218   1.1  christos     { "iallu",   CPENS(0,C7,C5,0), 0, AARCH64_NO_FEATURES },
   5219   1.1  christos     { "ivau",    CPENS (3, C7, C5, 1), F_HASXT, AARCH64_NO_FEATURES },
   5220   1.1  christos     { 0, CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
   5221   1.9  christos };
   5222   1.9  christos 
   5223   1.9  christos const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
   5224   1.9  christos {
   5225   1.9  christos     { "zva",	    CPENS (3, C7, C4, 1),  F_HASXT, AARCH64_NO_FEATURES },
   5226   1.9  christos     { "gva",	    CPENS (3, C7, C4, 3),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5227   1.9  christos     { "gzva",	    CPENS (3, C7, C4, 4),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5228   1.9  christos     { "ivac",       CPENS (0, C7, C6, 1),  F_HASXT, AARCH64_NO_FEATURES },
   5229   1.9  christos     { "igvac",      CPENS (0, C7, C6, 3),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5230  1.10  christos     { "igsw",       CPENS (0, C7, C6, 4),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5231  1.10  christos     { "isw",	    CPENS (0, C7, C6, 2),  F_HASXT, AARCH64_NO_FEATURES },
   5232   1.9  christos     { "igdvac",	    CPENS (0, C7, C6, 5),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5233   1.9  christos     { "igdsw",	    CPENS (0, C7, C6, 6),  F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5234   1.9  christos     { "cigdvaps",   CPENS (0, C7, C15, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, MEMTAG, PoPS) },
   5235  1.10  christos     { "civaps",     CPENS (0, C7, C15, 1), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (PoPS) },
   5236  1.10  christos     { "cvac",       CPENS (3, C7, C10, 1), F_HASXT, AARCH64_NO_FEATURES },
   5237   1.9  christos     { "cgvac",      CPENS (3, C7, C10, 3), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5238   1.9  christos     { "cgdvac",     CPENS (3, C7, C10, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5239   1.9  christos     { "cvaoc",      CPENS (3, C7, C11, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (OCCMO) },
   5240   1.9  christos     { "cgdvaoc",    CPENS (3, C7, C11, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) },
   5241   1.9  christos     { "csw",	    CPENS (0, C7, C10, 2), F_HASXT, AARCH64_NO_FEATURES },
   5242   1.9  christos     { "cgsw",       CPENS (0, C7, C10, 4), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5243   1.9  christos     { "cgdsw",	    CPENS (0, C7, C10, 6), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5244   1.9  christos     { "cvau",       CPENS (3, C7, C11, 1), F_HASXT, AARCH64_NO_FEATURES },
   5245   1.9  christos     { "cvap",       CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_2A) },
   5246   1.9  christos     { "cgvap",      CPENS (3, C7, C12, 3), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5247   1.9  christos     { "cgdvap",     CPENS (3, C7, C12, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5248   1.9  christos     { "cvadp",      CPENS (3, C7, C13, 1), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (CVADP) },
   5249   1.9  christos     { "cgvadp",     CPENS (3, C7, C13, 3), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5250   1.9  christos     { "cgdvadp",    CPENS (3, C7, C13, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5251   1.9  christos     { "civac",      CPENS (3, C7, C14, 1), F_HASXT, AARCH64_NO_FEATURES },
   5252   1.9  christos     { "cigvac",     CPENS (3, C7, C14, 3), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5253  1.10  christos     { "cigdvac",    CPENS (3, C7, C14, 5), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5254  1.10  christos     { "cisw",       CPENS (0, C7, C14, 2), F_HASXT, AARCH64_NO_FEATURES },
   5255  1.10  christos     { "cigsw",      CPENS (0, C7, C14, 4), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5256  1.10  christos     { "cigdsw",     CPENS (0, C7, C14, 6), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (MEMTAG) },
   5257   1.9  christos     { "civaoc",     CPENS (3, C7, C15, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (OCCMO) },
   5258   1.9  christos     { "cigdvaoc",   CPENS (3, C7, C15, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) },
   5259   1.9  christos     { "cipae",      CPENS (4, C7, C14, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_7A) },
   5260   1.1  christos     { "cigdpae",    CPENS (4, C7, C14, 7), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_7A) },
   5261   1.1  christos     { "cipapa",     CPENS (6, C7, C14, 1), F_HASXT, AARCH64_NO_FEATURES },
   5262   1.1  christos     { "cigdpapa",   CPENS (6, C7, C14, 5), F_HASXT, AARCH64_NO_FEATURES },
   5263   1.1  christos     { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
   5264   1.9  christos };
   5265   1.9  christos 
   5266   1.9  christos const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
   5267   1.9  christos {
   5268   1.9  christos     { "s1e1r",      CPENS (0, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
   5269   1.9  christos     { "s1e1w",      CPENS (0, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
   5270   1.9  christos     { "s1e0r",      CPENS (0, C7, C8, 2), F_HASXT, AARCH64_NO_FEATURES },
   5271   1.9  christos     { "s1e0w",      CPENS (0, C7, C8, 3), F_HASXT, AARCH64_NO_FEATURES },
   5272   1.9  christos     { "s12e1r",     CPENS (4, C7, C8, 4), F_HASXT, AARCH64_NO_FEATURES },
   5273   1.9  christos     { "s12e1w",     CPENS (4, C7, C8, 5), F_HASXT, AARCH64_NO_FEATURES },
   5274   1.9  christos     { "s12e0r",     CPENS (4, C7, C8, 6), F_HASXT, AARCH64_NO_FEATURES },
   5275   1.9  christos     { "s12e0w",     CPENS (4, C7, C8, 7), F_HASXT, AARCH64_NO_FEATURES },
   5276   1.9  christos     { "s1e2r",      CPENS (4, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
   5277   1.9  christos     { "s1e2w",      CPENS (4, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
   5278   1.9  christos     { "s1e3r",      CPENS (6, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
   5279   1.9  christos     { "s1e3w",      CPENS (6, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
   5280   1.9  christos     { "s1e1rp",     CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_2A) },
   5281   1.9  christos     { "s1e1wp",     CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (V8_2A) },
   5282   1.1  christos     { "s1e1a",      CPENS (0, C7, C9, 2), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (ATS1A) },
   5283   1.1  christos     { "s1e2a",      CPENS (4, C7, C9, 2), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (ATS1A) },
   5284   1.1  christos     { "s1e3a",      CPENS (6, C7, C9, 2), F_HASXT | F_ARCHEXT, AARCH64_FEATURE (ATS1A) },
   5285   1.1  christos     { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
   5286   1.9  christos };
   5287   1.9  christos 
   5288   1.9  christos const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
   5289   1.9  christos {
   5290   1.9  christos     { "rpaos",      CPENS (6, C8, C4, 3), F_HASXT, AARCH64_NO_FEATURES },
   5291   1.9  christos     { "rpalos",     CPENS (6, C8, C4, 7), F_HASXT, AARCH64_NO_FEATURES },
   5292   1.9  christos     { "paallos",    CPENS (6, C8, C1, 4), 0, AARCH64_NO_FEATURES },
   5293   1.9  christos     { "paall",      CPENS (6, C8, C7, 4), 0, AARCH64_NO_FEATURES },
   5294   1.9  christos 
   5295   1.9  christos #define TLBI_XS_OP(OP, CODE, FLAGS) \
   5296   1.9  christos     { OP, CODE, FLAGS, AARCH64_NO_FEATURES }, \
   5297   1.9  christos     { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS | F_ARCHEXT, AARCH64_FEATURE (XS) },
   5298   1.9  christos 
   5299   1.9  christos     TLBI_XS_OP ( "vmalle1",   CPENS (0, C8, C7, 0), 0)
   5300   1.9  christos     TLBI_XS_OP ( "vae1",      CPENS (0, C8, C7, 1), F_HASXT | F_REG_128)
   5301   1.9  christos     TLBI_XS_OP ( "aside1",    CPENS (0, C8, C7, 2), F_HASXT )
   5302   1.9  christos     TLBI_XS_OP ( "vaae1",     CPENS (0, C8, C7, 3), F_HASXT | F_REG_128)
   5303   1.9  christos     TLBI_XS_OP ( "vmalle1is", CPENS (0, C8, C3, 0), 0)
   5304   1.9  christos     TLBI_XS_OP ( "vae1is",    CPENS (0, C8, C3, 1), F_HASXT | F_REG_128)
   5305   1.9  christos     TLBI_XS_OP ( "aside1is",  CPENS (0, C8, C3, 2), F_HASXT )
   5306   1.9  christos     TLBI_XS_OP ( "vaae1is",   CPENS (0, C8, C3, 3), F_HASXT | F_REG_128)
   5307   1.9  christos     TLBI_XS_OP ( "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT | F_REG_128)
   5308   1.9  christos     TLBI_XS_OP ( "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT | F_REG_128)
   5309   1.9  christos     TLBI_XS_OP ( "ipas2e1",   CPENS (4, C8, C4, 1), F_HASXT | F_REG_128)
   5310   1.9  christos     TLBI_XS_OP ( "ipas2le1",  CPENS (4, C8, C4, 5), F_HASXT | F_REG_128)
   5311   1.9  christos     TLBI_XS_OP ( "vae2",      CPENS (4, C8, C7, 1), F_HASXT | F_REG_128)
   5312   1.9  christos     TLBI_XS_OP ( "vae2is",    CPENS (4, C8, C3, 1), F_HASXT | F_REG_128)
   5313   1.9  christos     TLBI_XS_OP ( "vmalls12e1",CPENS (4, C8, C7, 6), 0)
   5314   1.9  christos     TLBI_XS_OP ( "vmalls12e1is",CPENS(4,C8, C3, 6), 0)
   5315   1.9  christos     TLBI_XS_OP ( "vae3",      CPENS (6, C8, C7, 1), F_HASXT | F_REG_128)
   5316   1.9  christos     TLBI_XS_OP ( "vae3is",    CPENS (6, C8, C3, 1), F_HASXT | F_REG_128)
   5317   1.9  christos     TLBI_XS_OP ( "alle2",     CPENS (4, C8, C7, 0), 0)
   5318   1.9  christos     TLBI_XS_OP ( "alle2is",   CPENS (4, C8, C3, 0), 0)
   5319   1.9  christos     TLBI_XS_OP ( "alle1",     CPENS (4, C8, C7, 4), 0)
   5320   1.9  christos     TLBI_XS_OP ( "alle1is",   CPENS (4, C8, C3, 4), 0)
   5321   1.9  christos     TLBI_XS_OP ( "alle3",     CPENS (6, C8, C7, 0), 0)
   5322   1.9  christos     TLBI_XS_OP ( "alle3is",   CPENS (6, C8, C3, 0), 0)
   5323   1.9  christos     TLBI_XS_OP ( "vale1is",   CPENS (0, C8, C3, 5), F_HASXT | F_REG_128)
   5324   1.9  christos     TLBI_XS_OP ( "vale2is",   CPENS (4, C8, C3, 5), F_HASXT | F_REG_128)
   5325   1.9  christos     TLBI_XS_OP ( "vale3is",   CPENS (6, C8, C3, 5), F_HASXT | F_REG_128)
   5326   1.9  christos     TLBI_XS_OP ( "vaale1is",  CPENS (0, C8, C3, 7), F_HASXT | F_REG_128)
   5327   1.9  christos     TLBI_XS_OP ( "vale1",     CPENS (0, C8, C7, 5), F_HASXT | F_REG_128)
   5328   1.9  christos     TLBI_XS_OP ( "vale2",     CPENS (4, C8, C7, 5), F_HASXT | F_REG_128)
   5329   1.9  christos     TLBI_XS_OP ( "vale3",     CPENS (6, C8, C7, 5), F_HASXT | F_REG_128)
   5330   1.9  christos     TLBI_XS_OP ( "vaale1",    CPENS (0, C8, C7, 7), F_HASXT | F_REG_128)
   5331   1.9  christos 
   5332   1.9  christos #undef TLBI_XS_OP
   5333   1.9  christos #define TLBI_XS_OP(OP, CODE, FLAGS) \
   5334   1.9  christos     { OP, CODE, FLAGS | F_ARCHEXT, AARCH64_FEATURE (V8_4A) }, \
   5335   1.9  christos     { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS | F_ARCHEXT, AARCH64_FEATURE (XS) },
   5336   1.9  christos 
   5337   1.9  christos     TLBI_XS_OP ( "vmalle1os",    CPENS (0, C8, C1, 0), 0 )
   5338   1.9  christos     TLBI_XS_OP ( "vae1os",       CPENS (0, C8, C1, 1), F_HASXT | F_REG_128 )
   5339   1.9  christos     TLBI_XS_OP ( "aside1os",     CPENS (0, C8, C1, 2), F_HASXT )
   5340   1.9  christos     TLBI_XS_OP ( "vaae1os",      CPENS (0, C8, C1, 3), F_HASXT | F_REG_128 )
   5341   1.9  christos     TLBI_XS_OP ( "vale1os",      CPENS (0, C8, C1, 5), F_HASXT | F_REG_128 )
   5342   1.9  christos     TLBI_XS_OP ( "vaale1os",     CPENS (0, C8, C1, 7), F_HASXT | F_REG_128 )
   5343   1.9  christos     TLBI_XS_OP ( "ipas2e1os",    CPENS (4, C8, C4, 0), F_HASXT | F_REG_128 )
   5344   1.9  christos     TLBI_XS_OP ( "ipas2le1os",   CPENS (4, C8, C4, 4), F_HASXT | F_REG_128 )
   5345   1.9  christos     TLBI_XS_OP ( "vae2os",       CPENS (4, C8, C1, 1), F_HASXT | F_REG_128 )
   5346   1.9  christos     TLBI_XS_OP ( "vale2os",      CPENS (4, C8, C1, 5), F_HASXT | F_REG_128 )
   5347   1.9  christos     TLBI_XS_OP ( "vmalls12e1os", CPENS (4, C8, C1, 6), 0 )
   5348   1.9  christos     TLBI_XS_OP ( "vae3os",       CPENS (6, C8, C1, 1), F_HASXT | F_REG_128 )
   5349   1.9  christos     TLBI_XS_OP ( "vale3os",      CPENS (6, C8, C1, 5), F_HASXT | F_REG_128 )
   5350   1.9  christos     TLBI_XS_OP ( "alle2os",      CPENS (4, C8, C1, 0), 0 )
   5351   1.9  christos     TLBI_XS_OP ( "alle1os",      CPENS (4, C8, C1, 4), 0 )
   5352   1.9  christos     TLBI_XS_OP ( "alle3os",      CPENS (6, C8, C1, 0), 0 )
   5353   1.9  christos 
   5354   1.9  christos     TLBI_XS_OP ( "rvae1",      CPENS (0, C8, C6, 1), F_HASXT | F_REG_128 )
   5355   1.9  christos     TLBI_XS_OP ( "rvaae1",     CPENS (0, C8, C6, 3), F_HASXT | F_REG_128 )
   5356   1.9  christos     TLBI_XS_OP ( "rvale1",     CPENS (0, C8, C6, 5), F_HASXT | F_REG_128 )
   5357   1.9  christos     TLBI_XS_OP ( "rvaale1",    CPENS (0, C8, C6, 7), F_HASXT | F_REG_128 )
   5358   1.9  christos     TLBI_XS_OP ( "rvae1is",    CPENS (0, C8, C2, 1), F_HASXT | F_REG_128 )
   5359   1.9  christos     TLBI_XS_OP ( "rvaae1is",   CPENS (0, C8, C2, 3), F_HASXT | F_REG_128 )
   5360   1.9  christos     TLBI_XS_OP ( "rvale1is",   CPENS (0, C8, C2, 5), F_HASXT | F_REG_128 )
   5361   1.9  christos     TLBI_XS_OP ( "rvaale1is",  CPENS (0, C8, C2, 7), F_HASXT | F_REG_128 )
   5362   1.9  christos     TLBI_XS_OP ( "rvae1os",    CPENS (0, C8, C5, 1), F_HASXT | F_REG_128 )
   5363   1.9  christos     TLBI_XS_OP ( "rvaae1os",   CPENS (0, C8, C5, 3), F_HASXT | F_REG_128 )
   5364   1.9  christos     TLBI_XS_OP ( "rvale1os",   CPENS (0, C8, C5, 5), F_HASXT | F_REG_128 )
   5365   1.9  christos     TLBI_XS_OP ( "rvaale1os",  CPENS (0, C8, C5, 7), F_HASXT | F_REG_128 )
   5366   1.9  christos     TLBI_XS_OP ( "ripas2e1is", CPENS (4, C8, C0, 2), F_HASXT | F_REG_128 )
   5367   1.9  christos     TLBI_XS_OP ( "ripas2le1is",CPENS (4, C8, C0, 6), F_HASXT | F_REG_128 )
   5368   1.9  christos     TLBI_XS_OP ( "ripas2e1",   CPENS (4, C8, C4, 2), F_HASXT | F_REG_128 )
   5369   1.9  christos     TLBI_XS_OP ( "ripas2le1",  CPENS (4, C8, C4, 6), F_HASXT | F_REG_128 )
   5370   1.9  christos     TLBI_XS_OP ( "ripas2e1os", CPENS (4, C8, C4, 3), F_HASXT | F_REG_128 )
   5371   1.9  christos     TLBI_XS_OP ( "ripas2le1os",CPENS (4, C8, C4, 7), F_HASXT | F_REG_128 )
   5372   1.9  christos     TLBI_XS_OP ( "rvae2",      CPENS (4, C8, C6, 1), F_HASXT | F_REG_128 )
   5373   1.9  christos     TLBI_XS_OP ( "rvale2",     CPENS (4, C8, C6, 5), F_HASXT | F_REG_128 )
   5374   1.9  christos     TLBI_XS_OP ( "rvae2is",    CPENS (4, C8, C2, 1), F_HASXT | F_REG_128 )
   5375   1.9  christos     TLBI_XS_OP ( "rvale2is",   CPENS (4, C8, C2, 5), F_HASXT | F_REG_128 )
   5376   1.9  christos     TLBI_XS_OP ( "rvae2os",    CPENS (4, C8, C5, 1), F_HASXT | F_REG_128 )
   5377   1.9  christos     TLBI_XS_OP ( "rvale2os",   CPENS (4, C8, C5, 5), F_HASXT | F_REG_128 )
   5378   1.9  christos     TLBI_XS_OP ( "rvae3",      CPENS (6, C8, C6, 1), F_HASXT | F_REG_128 )
   5379   1.9  christos     TLBI_XS_OP ( "rvale3",     CPENS (6, C8, C6, 5), F_HASXT | F_REG_128 )
   5380   1.9  christos     TLBI_XS_OP ( "rvae3is",    CPENS (6, C8, C2, 1), F_HASXT | F_REG_128 )
   5381   1.9  christos     TLBI_XS_OP ( "rvale3is",   CPENS (6, C8, C2, 5), F_HASXT | F_REG_128 )
   5382   1.8  christos     TLBI_XS_OP ( "rvae3os",    CPENS (6, C8, C5, 1), F_HASXT | F_REG_128 )
   5383   1.9  christos     TLBI_XS_OP ( "rvale3os",   CPENS (6, C8, C5, 5), F_HASXT | F_REG_128 )
   5384   1.1  christos 
   5385   1.1  christos #undef TLBI_XS_OP
   5386   1.7  christos 
   5387   1.7  christos     { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
   5388   1.7  christos };
   5389   1.7  christos 
   5390   1.7  christos const aarch64_sys_ins_reg aarch64_sys_regs_sr[] =
   5391   1.7  christos {
   5392   1.9  christos     /* RCTX is somewhat unique in a way that it has different values
   5393   1.9  christos        (op2) based on the instruction in which it is used (cfp/dvp/cpp).
   5394   1.7  christos        Thus op2 is masked out and instead encoded directly in the
   5395   1.7  christos        aarch64_opcode_table entries for the respective instructions.  */
   5396   1.8  christos     { "rctx",   CPENS(3,C7,C3,0), F_HASXT | F_ARCHEXT | F_REG_WRITE, AARCH64_FEATURE (PREDRES) }, /* WO */
   5397   1.3  christos     { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
   5398   1.3  christos };
   5399   1.3  christos 
   5400   1.3  christos bool
   5401   1.3  christos aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
   5402   1.8  christos {
   5403   1.3  christos   return (sys_ins_reg->flags & F_HASXT) != 0;
   5404   1.9  christos }
   5405   1.9  christos 
   5406   1.9  christos extern bool
   5407   1.3  christos aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
   5408   1.8  christos 				 const char *reg_name,
   5409   1.9  christos 				 uint32_t reg_flags,
   5410   1.8  christos 				 const aarch64_feature_set *reg_features)
   5411   1.8  christos {
   5412   1.8  christos   /* Armv8-R has no EL3.  */
   5413   1.8  christos   if (AARCH64_CPU_HAS_FEATURE (features, V8R))
   5414   1.8  christos     {
   5415   1.8  christos       const char *suffix = strrchr (reg_name, '_');
   5416   1.8  christos       if (suffix && !strcmp (suffix, "_el3"))
   5417   1.8  christos 	return false;
   5418   1.8  christos     }
   5419   1.9  christos 
   5420   1.3  christos   if (!(reg_flags & F_ARCHEXT))
   5421   1.3  christos     return true;
   5422   1.1  christos 
   5423   1.1  christos   return AARCH64_CPU_HAS_ALL_FEATURES (features, *reg_features);
   5424   1.1  christos }
   5425   1.1  christos 
   5426   1.1  christos #undef C0
   5427   1.1  christos #undef C1
   5428   1.1  christos #undef C2
   5429   1.1  christos #undef C3
   5430   1.1  christos #undef C4
   5431   1.1  christos #undef C5
   5432   1.1  christos #undef C6
   5433   1.1  christos #undef C7
   5434   1.1  christos #undef C8
   5435   1.1  christos #undef C9
   5436   1.1  christos #undef C10
   5437   1.1  christos #undef C11
   5438   1.1  christos #undef C12
   5439   1.5  christos #undef C13
   5440   1.5  christos #undef C14
   5441   1.5  christos #undef C15
   5442   1.7  christos 
   5443   1.7  christos #define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
   5444   1.7  christos #define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
   5445   1.8  christos 
   5446   1.7  christos static enum err_type
   5447   1.7  christos verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED,
   5448   1.5  christos 	      const aarch64_insn insn, bfd_vma pc ATTRIBUTE_UNUSED,
   5449   1.5  christos 	      bool encoding ATTRIBUTE_UNUSED,
   5450   1.5  christos 	      aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
   5451   1.5  christos 	      aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
   5452   1.5  christos {
   5453   1.5  christos   int t  = BITS (insn, 4, 0);
   5454   1.5  christos   int n  = BITS (insn, 9, 5);
   5455   1.5  christos   int t2 = BITS (insn, 14, 10);
   5456   1.5  christos 
   5457   1.7  christos   if (BIT (insn, 23))
   5458   1.5  christos     {
   5459   1.5  christos       /* Write back enabled.  */
   5460   1.5  christos       if ((t == n || t2 == n) && n != 31)
   5461   1.5  christos 	return ERR_UND;
   5462   1.5  christos     }
   5463   1.5  christos 
   5464   1.7  christos   if (BIT (insn, 22))
   5465   1.7  christos     {
   5466   1.7  christos       /* Load */
   5467   1.7  christos       if (t == t2)
   5468   1.7  christos 	return ERR_UND;
   5469   1.7  christos     }
   5470   1.7  christos 
   5471   1.7  christos   return ERR_OK;
   5472   1.7  christos }
   5473   1.7  christos 
   5474   1.7  christos /* Verifier for vector by element 3 operands functions where the
   5475   1.8  christos    conditions `if sz:L == 11 then UNDEFINED` holds.  */
   5476   1.7  christos 
   5477   1.7  christos static enum err_type
   5478   1.7  christos verify_elem_sd (const struct aarch64_inst *inst, const aarch64_insn insn,
   5479   1.7  christos 		bfd_vma pc ATTRIBUTE_UNUSED, bool encoding,
   5480   1.7  christos 		aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
   5481   1.7  christos 		aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
   5482   1.7  christos {
   5483   1.7  christos   const aarch64_insn undef_pattern = 0x3;
   5484   1.7  christos   aarch64_insn value;
   5485   1.7  christos 
   5486   1.7  christos   assert (inst->opcode);
   5487   1.7  christos   assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
   5488   1.7  christos   value = encoding ? inst->value : insn;
   5489   1.7  christos   assert (value);
   5490   1.7  christos 
   5491   1.7  christos   if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
   5492   1.7  christos     return ERR_UND;
   5493   1.8  christos 
   5494   1.8  christos   return ERR_OK;
   5495   1.8  christos }
   5496   1.8  christos 
   5497   1.8  christos /* Check an instruction that takes three register operands and that
   5498   1.8  christos    requires the register numbers to be distinct from one another.  */
   5499   1.8  christos 
   5500   1.8  christos static enum err_type
   5501   1.8  christos verify_three_different_regs (const struct aarch64_inst *inst,
   5502   1.8  christos 			     const aarch64_insn insn ATTRIBUTE_UNUSED,
   5503   1.8  christos 			     bfd_vma pc ATTRIBUTE_UNUSED,
   5504   1.8  christos 			     bool encoding ATTRIBUTE_UNUSED,
   5505   1.8  christos 			     aarch64_operand_error *mismatch_detail
   5506   1.8  christos 			       ATTRIBUTE_UNUSED,
   5507   1.8  christos 			     aarch64_instr_sequence *insn_sequence
   5508   1.8  christos 			       ATTRIBUTE_UNUSED)
   5509   1.8  christos {
   5510   1.8  christos   int rd, rs, rn;
   5511   1.8  christos 
   5512   1.8  christos   rd = inst->operands[0].reg.regno;
   5513   1.8  christos   rs = inst->operands[1].reg.regno;
   5514   1.8  christos   rn = inst->operands[2].reg.regno;
   5515   1.8  christos   if (rd == rs || rd == rn || rs == rn)
   5516   1.8  christos     {
   5517   1.8  christos       mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5518   1.8  christos       mismatch_detail->error
   5519   1.8  christos 	= _("the three register operands must be distinct from one another");
   5520   1.8  christos       mismatch_detail->index = -1;
   5521   1.8  christos       return ERR_UND;
   5522   1.8  christos     }
   5523   1.8  christos 
   5524   1.8  christos   return ERR_OK;
   5525   1.8  christos }
   5526   1.8  christos 
   5527   1.8  christos /* Add INST to the end of INSN_SEQUENCE.  */
   5528   1.8  christos 
   5529   1.8  christos static void
   5530   1.8  christos add_insn_to_sequence (const struct aarch64_inst *inst,
   5531   1.8  christos 		      aarch64_instr_sequence *insn_sequence)
   5532   1.7  christos {
   5533   1.7  christos   insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
   5534   1.7  christos }
   5535   1.7  christos 
   5536   1.7  christos /* Initialize an instruction sequence insn_sequence with the instruction INST.
   5537   1.7  christos    If INST is NULL the given insn_sequence is cleared and the sequence is left
   5538   1.7  christos    uninitialized.  */
   5539   1.7  christos 
   5540   1.7  christos void
   5541   1.8  christos init_insn_sequence (const struct aarch64_inst *inst,
   5542   1.7  christos 		    aarch64_instr_sequence *insn_sequence)
   5543   1.7  christos {
   5544   1.8  christos   int num_req_entries = 0;
   5545   1.8  christos 
   5546   1.7  christos   if (insn_sequence->instr)
   5547   1.7  christos     {
   5548   1.7  christos       XDELETE (insn_sequence->instr);
   5549   1.7  christos       insn_sequence->instr = NULL;
   5550   1.7  christos     }
   5551   1.7  christos 
   5552   1.7  christos   /* Handle all the cases here.  May need to think of something smarter than
   5553   1.8  christos      a giant if/else chain if this grows.  At that time, a lookup table may be
   5554   1.8  christos      best.  */
   5555   1.7  christos   if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
   5556   1.8  christos     num_req_entries = 1;
   5557   1.8  christos   if (inst && (inst->opcode->constraints & C_SCAN_MOPS_PME) == C_SCAN_MOPS_P)
   5558   1.7  christos     num_req_entries = 2;
   5559   1.7  christos 
   5560   1.7  christos   insn_sequence->num_added_insns = 0;
   5561   1.8  christos   insn_sequence->num_allocated_insns = num_req_entries;
   5562   1.8  christos 
   5563   1.7  christos   if (num_req_entries != 0)
   5564   1.7  christos     {
   5565   1.7  christos       insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
   5566   1.8  christos       add_insn_to_sequence (inst, insn_sequence);
   5567   1.8  christos     }
   5568   1.8  christos }
   5569   1.8  christos 
   5570   1.8  christos /* Subroutine of verify_constraints.  Check whether the instruction
   5571   1.8  christos    is part of a MOPS P/M/E sequence and, if so, whether sequencing
   5572   1.8  christos    expectations are met.  Return true if the check passes, otherwise
   5573   1.8  christos    describe the problem in MISMATCH_DETAIL.
   5574   1.8  christos 
   5575   1.8  christos    IS_NEW_SECTION is true if INST is assumed to start a new section.
   5576   1.8  christos    The other arguments are as for verify_constraints.  */
   5577   1.8  christos 
   5578   1.8  christos static bool
   5579   1.8  christos verify_mops_pme_sequence (const struct aarch64_inst *inst,
   5580   1.8  christos 			  bool is_new_section,
   5581   1.8  christos 			  aarch64_operand_error *mismatch_detail,
   5582   1.8  christos 			  aarch64_instr_sequence *insn_sequence)
   5583   1.8  christos {
   5584   1.8  christos   const struct aarch64_opcode *opcode;
   5585   1.8  christos   const struct aarch64_inst *prev_insn;
   5586   1.8  christos   int i;
   5587   1.8  christos 
   5588   1.8  christos   opcode = inst->opcode;
   5589   1.8  christos   if (insn_sequence->instr)
   5590   1.8  christos     prev_insn = insn_sequence->instr + (insn_sequence->num_added_insns - 1);
   5591   1.8  christos   else
   5592   1.8  christos     prev_insn = NULL;
   5593   1.8  christos 
   5594   1.8  christos   if (prev_insn
   5595   1.8  christos       && (prev_insn->opcode->constraints & C_SCAN_MOPS_PME)
   5596   1.8  christos       && prev_insn->opcode != opcode - 1)
   5597   1.8  christos     {
   5598   1.8  christos       mismatch_detail->kind = AARCH64_OPDE_EXPECTED_A_AFTER_B;
   5599   1.8  christos       mismatch_detail->error = NULL;
   5600   1.8  christos       mismatch_detail->index = -1;
   5601   1.8  christos       mismatch_detail->data[0].s = prev_insn->opcode[1].name;
   5602   1.8  christos       mismatch_detail->data[1].s = prev_insn->opcode->name;
   5603   1.8  christos       mismatch_detail->non_fatal = true;
   5604   1.8  christos       return false;
   5605   1.8  christos     }
   5606   1.8  christos 
   5607   1.8  christos   if (opcode->constraints & C_SCAN_MOPS_PME)
   5608   1.8  christos     {
   5609   1.8  christos       if (is_new_section || !prev_insn || prev_insn->opcode != opcode - 1)
   5610   1.8  christos 	{
   5611   1.8  christos 	  mismatch_detail->kind = AARCH64_OPDE_A_SHOULD_FOLLOW_B;
   5612   1.8  christos 	  mismatch_detail->error = NULL;
   5613   1.8  christos 	  mismatch_detail->index = -1;
   5614   1.8  christos 	  mismatch_detail->data[0].s = opcode->name;
   5615   1.8  christos 	  mismatch_detail->data[1].s = opcode[-1].name;
   5616   1.8  christos 	  mismatch_detail->non_fatal = true;
   5617   1.8  christos 	  return false;
   5618   1.8  christos 	}
   5619   1.8  christos 
   5620   1.8  christos       for (i = 0; i < 3; ++i)
   5621   1.8  christos 	/* There's no specific requirement for the data register to be
   5622   1.8  christos 	   the same between consecutive SET* instructions.  */
   5623   1.8  christos 	if ((opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd
   5624   1.8  christos 	     || opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs
   5625   1.8  christos 	     || opcode->operands[i] == AARCH64_OPND_MOPS_WB_Rn)
   5626   1.8  christos 	    && prev_insn->operands[i].reg.regno != inst->operands[i].reg.regno)
   5627   1.8  christos 	  {
   5628   1.8  christos 	    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5629   1.8  christos 	    if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd)
   5630   1.8  christos 	      mismatch_detail->error = _("destination register differs from "
   5631   1.8  christos 					 "preceding instruction");
   5632   1.8  christos 	    else if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs)
   5633   1.8  christos 	      mismatch_detail->error = _("source register differs from "
   5634   1.8  christos 					 "preceding instruction");
   5635   1.8  christos 	    else
   5636   1.8  christos 	      mismatch_detail->error = _("size register differs from "
   5637   1.8  christos 					 "preceding instruction");
   5638   1.8  christos 	    mismatch_detail->index = i;
   5639   1.8  christos 	    mismatch_detail->non_fatal = true;
   5640   1.8  christos 	    return false;
   5641   1.8  christos 	  }
   5642   1.7  christos     }
   5643   1.7  christos 
   5644   1.7  christos   return true;
   5645   1.7  christos }
   5646   1.7  christos 
   5647   1.7  christos /*  This function verifies that the instruction INST adheres to its specified
   5648   1.7  christos     constraints.  If it does then ERR_OK is returned, if not then ERR_VFI is
   5649   1.7  christos     returned and MISMATCH_DETAIL contains the reason why verification failed.
   5650   1.7  christos 
   5651   1.7  christos     The function is called both during assembly and disassembly.  If assembling
   5652   1.7  christos     then ENCODING will be TRUE, else FALSE.  If dissassembling PC will be set
   5653   1.7  christos     and will contain the PC of the current instruction w.r.t to the section.
   5654   1.7  christos 
   5655   1.7  christos     If ENCODING and PC=0 then you are at a start of a section.  The constraints
   5656   1.7  christos     are verified against the given state insn_sequence which is updated as it
   5657   1.7  christos     transitions through the verification.  */
   5658   1.7  christos 
   5659   1.8  christos enum err_type
   5660   1.7  christos verify_constraints (const struct aarch64_inst *inst,
   5661   1.7  christos 		    const aarch64_insn insn ATTRIBUTE_UNUSED,
   5662   1.7  christos 		    bfd_vma pc,
   5663   1.7  christos 		    bool encoding,
   5664   1.7  christos 		    aarch64_operand_error *mismatch_detail,
   5665   1.7  christos 		    aarch64_instr_sequence *insn_sequence)
   5666   1.7  christos {
   5667   1.7  christos   assert (inst);
   5668   1.7  christos   assert (inst->opcode);
   5669   1.7  christos 
   5670   1.7  christos   const struct aarch64_opcode *opcode = inst->opcode;
   5671   1.7  christos   if (!opcode->constraints && !insn_sequence->instr)
   5672   1.7  christos     return ERR_OK;
   5673   1.7  christos 
   5674   1.7  christos   assert (insn_sequence);
   5675   1.7  christos 
   5676   1.7  christos   enum err_type res = ERR_OK;
   5677   1.7  christos 
   5678   1.7  christos   /* This instruction puts a constraint on the insn_sequence.  */
   5679   1.7  christos   if (opcode->flags & F_SCAN)
   5680   1.7  christos     {
   5681   1.7  christos       if (insn_sequence->instr)
   5682   1.7  christos 	{
   5683   1.8  christos 	  mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5684   1.7  christos 	  mismatch_detail->error = _("instruction opens new dependency "
   5685   1.7  christos 				     "sequence without ending previous one");
   5686   1.7  christos 	  mismatch_detail->index = -1;
   5687   1.7  christos 	  mismatch_detail->non_fatal = true;
   5688   1.7  christos 	  res = ERR_VFI;
   5689   1.7  christos 	}
   5690   1.7  christos 
   5691   1.8  christos       init_insn_sequence (inst, insn_sequence);
   5692   1.8  christos       return res;
   5693   1.8  christos     }
   5694   1.8  christos 
   5695   1.8  christos   bool is_new_section = (!encoding && pc == 0);
   5696   1.8  christos   if (!verify_mops_pme_sequence (inst, is_new_section, mismatch_detail,
   5697   1.8  christos 				 insn_sequence))
   5698   1.8  christos     {
   5699   1.8  christos       res = ERR_VFI;
   5700   1.7  christos       if ((opcode->constraints & C_SCAN_MOPS_PME) != C_SCAN_MOPS_M)
   5701   1.7  christos 	init_insn_sequence (NULL, insn_sequence);
   5702   1.7  christos     }
   5703   1.7  christos 
   5704   1.7  christos   /* Verify constraints on an existing sequence.  */
   5705   1.7  christos   if (insn_sequence->instr)
   5706   1.8  christos     {
   5707   1.7  christos       const struct aarch64_opcode* inst_opcode = insn_sequence->instr->opcode;
   5708   1.7  christos       /* If we're decoding and we hit PC=0 with an open sequence then we haven't
   5709   1.7  christos 	 closed a previous one that we should have.  */
   5710   1.7  christos       if (is_new_section && res == ERR_OK)
   5711   1.8  christos 	{
   5712   1.7  christos 	  mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5713   1.7  christos 	  mismatch_detail->error = _("previous `movprfx' sequence not closed");
   5714   1.7  christos 	  mismatch_detail->index = -1;
   5715   1.7  christos 	  mismatch_detail->non_fatal = true;
   5716   1.7  christos 	  res = ERR_VFI;
   5717   1.7  christos 	  /* Reset the sequence.  */
   5718   1.7  christos 	  init_insn_sequence (NULL, insn_sequence);
   5719   1.7  christos 	  return res;
   5720   1.7  christos 	}
   5721   1.7  christos 
   5722   1.7  christos       /* Validate C_SCAN_MOVPRFX constraints.  Move this to a lookup table.  */
   5723  1.10  christos       if (inst_opcode->constraints & C_SCAN_MOVPRFX)
   5724  1.10  christos 	{
   5725  1.10  christos 	  /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
   5726  1.10  christos 	     instruction for better error messages.  */
   5727  1.10  christos 	  bool sve_operand_p = false;
   5728  1.10  christos 	  for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   5729  1.10  christos 	    {
   5730  1.10  christos 	      enum aarch64_operand_class op_class
   5731  1.10  christos 		= aarch64_get_operand_class (opcode->operands[i]);
   5732  1.10  christos 	      if (op_class == AARCH64_OPND_CLASS_SVE_REG
   5733  1.10  christos 		  || op_class == AARCH64_OPND_CLASS_SVE_REGLIST
   5734  1.10  christos 		  || op_class == AARCH64_OPND_CLASS_PRED_REG)
   5735  1.10  christos 		{
   5736  1.10  christos 		  sve_operand_p = true;
   5737  1.10  christos 		  break;
   5738   1.7  christos 		}
   5739   1.7  christos 	    }
   5740   1.7  christos 
   5741   1.7  christos 	  if (!sve_operand_p)
   5742   1.7  christos 	    {
   5743   1.8  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5744   1.7  christos 	      mismatch_detail->error = _("SVE instruction expected after "
   5745   1.7  christos 					 "`movprfx'");
   5746   1.7  christos 	      mismatch_detail->index = -1;
   5747   1.7  christos 	      mismatch_detail->non_fatal = true;
   5748   1.7  christos 	      res = ERR_VFI;
   5749   1.7  christos 	      goto done;
   5750   1.7  christos 	    }
   5751   1.7  christos 
   5752   1.7  christos 	  /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
   5753   1.7  christos 	     instruction that is allowed to be used with a MOVPRFX.  */
   5754   1.7  christos 	  if (!(opcode->constraints & C_SCAN_MOVPRFX))
   5755   1.7  christos 	    {
   5756   1.8  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5757   1.7  christos 	      mismatch_detail->error = _("SVE `movprfx' compatible instruction "
   5758   1.7  christos 					 "expected");
   5759   1.7  christos 	      mismatch_detail->index = -1;
   5760   1.7  christos 	      mismatch_detail->non_fatal = true;
   5761   1.7  christos 	      res = ERR_VFI;
   5762   1.7  christos 	      goto done;
   5763   1.7  christos 	    }
   5764   1.7  christos 
   5765   1.7  christos 	  /* Next check for usage of the predicate register.  */
   5766   1.8  christos 	  aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
   5767   1.7  christos 	  aarch64_opnd_info blk_pred, inst_pred;
   5768   1.7  christos 	  memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
   5769   1.7  christos 	  memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
   5770   1.7  christos 	  bool predicated = false;
   5771   1.7  christos 	  assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
   5772   1.8  christos 
   5773   1.7  christos 	  /* Determine if the movprfx instruction used is predicated or not.  */
   5774   1.7  christos 	  if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
   5775   1.7  christos 	    {
   5776   1.7  christos 	      predicated = true;
   5777   1.7  christos 	      blk_pred = insn_sequence->instr->operands[1];
   5778   1.7  christos 	    }
   5779   1.7  christos 
   5780   1.7  christos 	  unsigned char max_elem_size = 0;
   5781   1.7  christos 	  unsigned char current_elem_size;
   5782   1.7  christos 	  int num_op_used = 0, last_op_usage = 0;
   5783   1.7  christos 	  int i, inst_pred_idx = -1;
   5784   1.7  christos 	  int num_ops = aarch64_num_of_operands (opcode);
   5785   1.7  christos 	  for (i = 0; i < num_ops; i++)
   5786   1.7  christos 	    {
   5787   1.7  christos 	      aarch64_opnd_info inst_op = inst->operands[i];
   5788   1.7  christos 	      switch (inst_op.type)
   5789   1.7  christos 		{
   5790   1.7  christos 		  case AARCH64_OPND_SVE_Zd:
   5791   1.7  christos 		  case AARCH64_OPND_SVE_Zm_5:
   5792   1.7  christos 		  case AARCH64_OPND_SVE_Zm_16:
   5793   1.7  christos 		  case AARCH64_OPND_SVE_Zn:
   5794   1.7  christos 		  case AARCH64_OPND_SVE_Zt:
   5795   1.7  christos 		  case AARCH64_OPND_SVE_Vm:
   5796   1.7  christos 		  case AARCH64_OPND_SVE_Vn:
   5797   1.7  christos 		  case AARCH64_OPND_Va:
   5798   1.7  christos 		  case AARCH64_OPND_Vn:
   5799   1.7  christos 		  case AARCH64_OPND_Vm:
   5800   1.7  christos 		  case AARCH64_OPND_Sn:
   5801   1.7  christos 		  case AARCH64_OPND_Sm:
   5802   1.7  christos 		    if (inst_op.reg.regno == blk_dest.reg.regno)
   5803   1.7  christos 		      {
   5804   1.7  christos 			num_op_used++;
   5805   1.7  christos 			last_op_usage = i;
   5806   1.7  christos 		      }
   5807   1.7  christos 		    current_elem_size
   5808   1.7  christos 		      = aarch64_get_qualifier_esize (inst_op.qualifier);
   5809   1.7  christos 		    if (current_elem_size > max_elem_size)
   5810   1.7  christos 		      max_elem_size = current_elem_size;
   5811   1.7  christos 		    break;
   5812   1.7  christos 		  case AARCH64_OPND_SVE_Pd:
   5813   1.7  christos 		  case AARCH64_OPND_SVE_Pg3:
   5814   1.7  christos 		  case AARCH64_OPND_SVE_Pg4_5:
   5815   1.7  christos 		  case AARCH64_OPND_SVE_Pg4_10:
   5816   1.8  christos 		  case AARCH64_OPND_SVE_Pg4_16:
   5817   1.7  christos 		  case AARCH64_OPND_SVE_Pm:
   5818   1.7  christos 		  case AARCH64_OPND_SVE_Pn:
   5819   1.7  christos 		  case AARCH64_OPND_SVE_Pt:
   5820   1.7  christos 		  case AARCH64_OPND_SME_Pm:
   5821   1.7  christos 		    inst_pred = inst_op;
   5822   1.7  christos 		    inst_pred_idx = i;
   5823   1.7  christos 		    break;
   5824   1.7  christos 		  default:
   5825   1.7  christos 		    break;
   5826   1.7  christos 		}
   5827   1.7  christos 	    }
   5828   1.7  christos 
   5829   1.7  christos 	   assert (max_elem_size != 0);
   5830   1.7  christos 	   aarch64_opnd_info inst_dest = inst->operands[0];
   5831   1.7  christos 	   /* Determine the size that should be used to compare against the
   5832   1.7  christos 	      movprfx size.  */
   5833   1.7  christos 	   current_elem_size
   5834   1.7  christos 	     = opcode->constraints & C_MAX_ELEM
   5835   1.7  christos 	       ? max_elem_size
   5836   1.7  christos 	       : aarch64_get_qualifier_esize (inst_dest.qualifier);
   5837   1.7  christos 
   5838   1.7  christos 	  /* If movprfx is predicated do some extra checks.  */
   5839   1.7  christos 	  if (predicated)
   5840   1.7  christos 	    {
   5841   1.7  christos 	      /* The instruction must be predicated.  */
   5842   1.7  christos 	      if (inst_pred_idx < 0)
   5843   1.7  christos 		{
   5844   1.8  christos 		  mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5845   1.7  christos 		  mismatch_detail->error = _("predicated instruction expected "
   5846   1.7  christos 					     "after `movprfx'");
   5847   1.7  christos 		  mismatch_detail->index = -1;
   5848   1.7  christos 		  mismatch_detail->non_fatal = true;
   5849   1.7  christos 		  res = ERR_VFI;
   5850   1.7  christos 		  goto done;
   5851   1.7  christos 		}
   5852   1.7  christos 
   5853   1.7  christos 	      /* The instruction must have a merging predicate.  */
   5854   1.7  christos 	      if (inst_pred.qualifier != AARCH64_OPND_QLF_P_M)
   5855   1.7  christos 		{
   5856   1.8  christos 		  mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5857   1.7  christos 		  mismatch_detail->error = _("merging predicate expected due "
   5858   1.7  christos 					     "to preceding `movprfx'");
   5859   1.7  christos 		  mismatch_detail->index = inst_pred_idx;
   5860   1.7  christos 		  mismatch_detail->non_fatal = true;
   5861   1.7  christos 		  res = ERR_VFI;
   5862   1.7  christos 		  goto done;
   5863   1.7  christos 		}
   5864   1.7  christos 
   5865   1.7  christos 	      /* The same register must be used in instruction.  */
   5866   1.7  christos 	      if (blk_pred.reg.regno != inst_pred.reg.regno)
   5867   1.7  christos 		{
   5868   1.7  christos 		  mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5869   1.8  christos 		  mismatch_detail->error = _("predicate register differs "
   5870   1.7  christos 					     "from that in preceding "
   5871   1.7  christos 					     "`movprfx'");
   5872   1.7  christos 		  mismatch_detail->index = inst_pred_idx;
   5873   1.7  christos 		  mismatch_detail->non_fatal = true;
   5874   1.7  christos 		  res = ERR_VFI;
   5875   1.7  christos 		  goto done;
   5876   1.7  christos 		}
   5877   1.7  christos 	    }
   5878   1.7  christos 
   5879   1.7  christos 	  /* Destructive operations by definition must allow one usage of the
   5880   1.7  christos 	     same register.  */
   5881   1.7  christos 	  int allowed_usage
   5882   1.7  christos 	    = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
   5883   1.7  christos 
   5884   1.7  christos 	  /* Operand is not used at all.  */
   5885   1.7  christos 	  if (num_op_used == 0)
   5886   1.7  christos 	    {
   5887   1.7  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5888   1.8  christos 	      mismatch_detail->error = _("output register of preceding "
   5889   1.7  christos 					 "`movprfx' not used in current "
   5890   1.7  christos 					 "instruction");
   5891   1.7  christos 	      mismatch_detail->index = 0;
   5892   1.7  christos 	      mismatch_detail->non_fatal = true;
   5893   1.7  christos 	      res = ERR_VFI;
   5894   1.7  christos 	      goto done;
   5895   1.7  christos 	    }
   5896   1.7  christos 
   5897   1.7  christos 	  /* We now know it's used, now determine exactly where it's used.  */
   5898   1.7  christos 	  if (blk_dest.reg.regno != inst_dest.reg.regno)
   5899   1.7  christos 	    {
   5900   1.8  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5901   1.7  christos 	      mismatch_detail->error = _("output register of preceding "
   5902   1.7  christos 					 "`movprfx' expected as output");
   5903   1.7  christos 	      mismatch_detail->index = 0;
   5904   1.7  christos 	      mismatch_detail->non_fatal = true;
   5905   1.7  christos 	      res = ERR_VFI;
   5906   1.7  christos 	      goto done;
   5907   1.7  christos 	    }
   5908   1.7  christos 
   5909   1.7  christos 	  /* Operand used more than allowed for the specific opcode type.  */
   5910   1.7  christos 	  if (num_op_used > allowed_usage)
   5911   1.7  christos 	    {
   5912   1.8  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5913   1.7  christos 	      mismatch_detail->error = _("output register of preceding "
   5914   1.7  christos 					 "`movprfx' used as input");
   5915   1.7  christos 	      mismatch_detail->index = last_op_usage;
   5916   1.7  christos 	      mismatch_detail->non_fatal = true;
   5917   1.7  christos 	      res = ERR_VFI;
   5918   1.7  christos 	      goto done;
   5919   1.7  christos 	    }
   5920   1.7  christos 
   5921   1.7  christos 	  /* Now the only thing left is the qualifiers checks.  The register
   5922   1.7  christos 	     must have the same maximum element size.  */
   5923   1.7  christos 	  if (inst_dest.qualifier
   5924   1.7  christos 	      && blk_dest.qualifier
   5925   1.7  christos 	      && current_elem_size
   5926   1.7  christos 		 != aarch64_get_qualifier_esize (blk_dest.qualifier))
   5927   1.7  christos 	    {
   5928   1.8  christos 	      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
   5929   1.7  christos 	      mismatch_detail->error = _("register size not compatible with "
   5930   1.7  christos 					 "previous `movprfx'");
   5931   1.7  christos 	      mismatch_detail->index = 0;
   5932   1.7  christos 	      mismatch_detail->non_fatal = true;
   5933   1.7  christos 	      res = ERR_VFI;
   5934   1.8  christos 	      goto done;
   5935   1.8  christos 	    }
   5936   1.8  christos 	}
   5937   1.8  christos 
   5938   1.8  christos     done:
   5939   1.8  christos       if (insn_sequence->num_added_insns == insn_sequence->num_allocated_insns)
   5940   1.8  christos 	/* We've checked the last instruction in the sequence and so
   5941   1.5  christos 	   don't need the sequence any more.  */
   5942   1.5  christos 	init_insn_sequence (NULL, insn_sequence);
   5943   1.7  christos       else
   5944   1.5  christos 	add_insn_to_sequence (inst, insn_sequence);
   5945   1.5  christos     }
   5946   1.7  christos 
   5947   1.6  christos   return res;
   5948   1.6  christos }
   5949   1.6  christos 
   5950   1.6  christos 
   5951   1.8  christos /* Return true if VALUE cannot be moved into an SVE register using DUP
   5952   1.6  christos    (with any element size, not just ESIZE) and if using DUPM would
   5953   1.6  christos    therefore be OK.  ESIZE is the number of bytes in the immediate.  */
   5954   1.6  christos 
   5955   1.6  christos bool
   5956   1.6  christos aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
   5957   1.6  christos {
   5958   1.8  christos   int64_t svalue = uvalue;
   5959   1.6  christos   uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
   5960   1.6  christos 
   5961   1.6  christos   if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
   5962   1.6  christos     return false;
   5963   1.6  christos   if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
   5964   1.6  christos     {
   5965   1.6  christos       svalue = (int32_t) uvalue;
   5966   1.8  christos       if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
   5967   1.6  christos 	{
   5968   1.6  christos 	  svalue = (int16_t) uvalue;
   5969   1.6  christos 	  if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
   5970   1.6  christos 	    return false;
   5971   1.6  christos 	}
   5972   1.6  christos     }
   5973   1.6  christos   if ((svalue & 0xff) == 0)
   5974   1.9  christos     svalue /= 256;
   5975   1.9  christos   return svalue < -128 || svalue >= 128;
   5976   1.9  christos }
   5977   1.9  christos 
   5978   1.9  christos /* Return true if a CPU with the AARCH64_FEATURE_* bits in CPU_VARIANT
   5979   1.9  christos    supports the instruction described by INST.  */
   5980   1.9  christos 
   5981   1.9  christos bool
   5982   1.9  christos aarch64_cpu_supports_inst_p (aarch64_feature_set cpu_variant,
   5983   1.9  christos 			     aarch64_inst *inst)
   5984   1.9  christos {
   5985   1.9  christos   if (!inst->opcode->avariant
   5986   1.9  christos       || !AARCH64_CPU_HAS_ALL_FEATURES (cpu_variant, *inst->opcode->avariant))
   5987   1.9  christos     return false;
   5988   1.9  christos 
   5989   1.9  christos   if (inst->opcode->iclass == sme_fp_sd
   5990   1.9  christos       && inst->operands[0].qualifier == AARCH64_OPND_QLF_S_D
   5991   1.9  christos       && !AARCH64_CPU_HAS_FEATURE (cpu_variant, SME_F64F64))
   5992   1.9  christos     return false;
   5993   1.9  christos 
   5994   1.9  christos   if (inst->opcode->iclass == sme_int_sd
   5995   1.9  christos       && inst->operands[0].qualifier == AARCH64_OPND_QLF_S_D
   5996   1.9  christos       && !AARCH64_CPU_HAS_FEATURE (cpu_variant, SME_I16I64))
   5997   1.9  christos     return false;
   5998   1.1  christos 
   5999   1.1  christos   return true;
   6000   1.5  christos }
   6001   1.1  christos 
   6002                 /* Include the opcode description table as well as the operand description
   6003                    table.  */
   6004                 #define VERIFIER(x) verify_##x
   6005                 #include "aarch64-tbl.h"
   6006