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