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