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