From: Siddhesh Poyarekar Date: Fri, 11 Sep 2020 03:48:04 +0000 (+0530) Subject: [Morello] Add mapping symbol to identify C64 code sections X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3979cf5096566fb4f7f6234827abbd087d6598d0;p=thirdparty%2Fbinutils-gdb.git [Morello] Add mapping symbol to identify C64 code sections Add a mapping symbol $c at the beginning of every C64 code section to allow the disassembler to identify C64 code sections. This will allow the disassembler to print the correct base address registers and also choose the correct disassembly in cases where the opcodes for A64 and C64 instructions are aliased. To aid correct disassembly of instructions, pass CPU variant to various helpers in libopcodes so that they can use that information to choose between A64 and C64 disassembly. bfd/ChangeLog: 2020-10-20 Siddhesh Poyarekar * cpu-aarch64.c (bfd_is_aarch64_special_symbol_name): Add capability mapping symbol. * elfnn-aarch64.c (elfNN_aarch64_output_map_sym, is_aarch64_mapping_symbol): Likewise. gas/ChangeLog: 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.h (mstate): Add MAP_C64. * config/tc-aarch64.c (make_mapping_symbol): Add capability mapping symbol. (MAP_CUR_INSN): New macro. (mapping_state, s_aarch64_inst, md_assemble, aarch64_handle_align, aarch64_init_frag): Use it. (output_operand_error_record, do_encode, try_to_encode_as_unscaled_ldst, fix_mov_imm_insn, fix_insn): Pass CPU_VARIANT to AARCH64_OPCODE_ENCODE. * doc/c-aarch64.texi: Document $c. include/ChangeLog: 2020-10-20 Siddhesh Poyarekar * opcode/aarch64.h (aarch64_opcode_encode): Add cpu variant argument. opcodes/ChangeLog: 2020-10-20 Siddhesh Poyarekar * aarch64-asm.c (aarch64_opcode_encode): Add CPU variant argument. * aarch64-dis.c (map_type): Add MAP_C64. (MAYBE_C64): New macro. (determine_disassembling_preference, print_operands): Use it. (aarch64_symbol_is_valid): Test for $c. (get_sym_code_type): Recognise MAP_C64. (select_aarch64_variant): Clear AARCH64_FEATURE_C64. (determine_disassembling_preference, aarch64_opcode_decode): Adjust calls to aarch64_match_operands_constraint. * aarch64-opc.c (get_altbase_reg_name, get_base_reg_name): New functions. (aarch64_print_operand): Use them. (aarch64_match_operands_constraint): Likewise. * aarch64-opc.h (aarch64_match_operands_constraint): Add CPU variant argument. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7fb61814106..7b83a289204 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2020-10-20 Siddhesh Poyarekar + + * cpu-aarch64.c (bfd_is_aarch64_special_symbol_name): Add + capability mapping symbol. + * elfnn-aarch64.c (elfNN_aarch64_output_map_sym, + is_aarch64_mapping_symbol): Likewise. + 2020-10-16 Nelson Chu * elfnn-riscv.c (riscv_elf_link_hash_table): Add last_iplt_index. diff --git a/bfd/cpu-aarch64.c b/bfd/cpu-aarch64.c index 8d9b420a425..74491ac4a0a 100644 --- a/bfd/cpu-aarch64.c +++ b/bfd/cpu-aarch64.c @@ -122,7 +122,7 @@ bfd_is_aarch64_special_symbol_name (const char *name, int type) { if (!name || name[0] != '$') return FALSE; - if (name[1] == 'x' || name[1] == 'd') + if (name[1] == 'x' || name[1] == 'd' || name[1] == 'c') type &= BFD_AARCH64_SPECIAL_SYM_TYPE_MAP; else if (name[1] == 'm' || name[1] == 'f' || name[1] == 'p') type &= BFD_AARCH64_SPECIAL_SYM_TYPE_TAG; diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index a9924e7ec56..a38da729738 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8259,7 +8259,7 @@ static bfd_boolean elfNN_aarch64_output_map_sym (output_arch_syminfo *osi, enum map_symbol_type type, bfd_vma offset) { - static const char *names[2] = { "$x", "$d" }; + static const char *names[3] = { "$x", "$d", "$c" }; Elf_Internal_Sym sym; sym.st_value = (osi->sec->output_section->vma @@ -9838,7 +9838,7 @@ is_aarch64_mapping_symbol (const char * name) the mapping symbols could have acquired a prefix. We do not support this here, since such symbols no longer conform to the ARM ELF ABI. */ - && (name[1] == 'd' || name[1] == 'x') + && (name[1] == 'd' || name[1] == 'x' || name[1] == 'c') && (name[2] == 0 || name[2] == '.'); /* FIXME: Strictly speaking the symbol is only a valid mapping symbol if any characters that follow the period are legal characters for the body diff --git a/gas/ChangeLog b/gas/ChangeLog index 311549975e3..bf0b6dcc593 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2020-10-20 Siddhesh Poyarekar + + * config/tc-aarch64.h (mstate): Add MAP_C64. + * config/tc-aarch64.c (make_mapping_symbol): Add capability + mapping symbol. + (MAP_CUR_INSN): New macro. + (mapping_state, s_aarch64_inst, md_assemble, + aarch64_handle_align, aarch64_init_frag): Use it. + (output_operand_error_record, do_encode, + try_to_encode_as_unscaled_ldst, fix_mov_imm_insn, fix_insn): + Pass CPU_VARIANT to AARCH64_OPCODE_ENCODE. + * doc/c-aarch64.texi: Document $c. + 2020-10-20 Siddhesh Poyarekar * config/tc-aarch64.c (AARCH64_REG_TYPES, diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index da0cf11e26e..e768c041b12 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -44,6 +44,10 @@ #define END_OF_INSN '\0' +#define MAP_CUR_INSN (AARCH64_CPU_HAS_FEATURE (cpu_variant, \ + AARCH64_FEATURE_C64) \ + ? MAP_C64 : MAP_INSN) + static aarch64_feature_set cpu_variant; /* Variables that we set while parsing command-line options. Once all @@ -1549,6 +1553,10 @@ make_mapping_symbol (enum mstate state, valueT value, fragS * frag) symname = "$x"; type = BSF_NO_FLAGS; break; + case MAP_C64: + symname = "$c"; + type = BSF_NO_FLAGS; + break; default: abort (); } @@ -1624,7 +1632,7 @@ mapping_state (enum mstate state) { enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; - if (state == MAP_INSN) + if (state == MAP_CUR_INSN) /* AArch64 instructions require 4-byte alignment. When emitting instructions into any section, record the appropriate section alignment. */ @@ -1640,7 +1648,7 @@ mapping_state (enum mstate state) /* Emit MAP_DATA within executable section in order. Otherwise, it will be evaluated later in the next else. */ return; - else if (TRANSITION (MAP_UNDEFINED, MAP_INSN)) + else if (TRANSITION (MAP_UNDEFINED, MAP_CUR_INSN)) { /* Only add the symbol if the offset is > 0: if we're at the first frag, check it's size > 0; @@ -2044,14 +2052,14 @@ s_aarch64_inst (int ignored ATTRIBUTE_UNUSED) /* Sections are assumed to start aligned. In executable section, there is no MAP_DATA symbol pending. So we only align the address during - MAP_DATA --> MAP_INSN transition. + MAP_DATA --> MAP_CUR_INSN transition. For other sections, this is not guaranteed. */ enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; if (!need_pass_2 && subseg_text_p (now_seg) && mapstate == MAP_DATA) frag_align_code (2, 0); #ifdef OBJ_ELF - mapping_state (MAP_INSN); + mapping_state (MAP_CUR_INSN); #endif do @@ -4866,8 +4874,9 @@ output_operand_error_record (const operand_error_record *record, char *str) result = parse_operands (str + len, opcode) && programmer_friendly_fixup (&inst); gas_assert (result); - result = aarch64_opcode_encode (opcode, inst_base, &inst_base->value, - NULL, NULL, insn_sequence); + result = aarch64_opcode_encode (cpu_variant, opcode, inst_base, + &inst_base->value, NULL, NULL, + insn_sequence); gas_assert (!result); /* Find the most matched qualifier sequence. */ @@ -7063,7 +7072,8 @@ do_encode (const aarch64_opcode *opcode, aarch64_inst *instr, aarch64_operand_error error_info; memset (&error_info, '\0', sizeof (error_info)); error_info.kind = AARCH64_OPDE_NIL; - if (aarch64_opcode_encode (opcode, instr, code, NULL, &error_info, insn_sequence) + if (aarch64_opcode_encode (cpu_variant, opcode, instr, code, NULL, + &error_info, insn_sequence) && !error_info.non_fatal) return TRUE; @@ -7141,7 +7151,7 @@ md_assemble (char *str) /* Sections are assumed to start aligned. In executable section, there is no MAP_DATA symbol pending. So we only align the address during - MAP_DATA --> MAP_INSN transition. + MAP_DATA --> MAP_CUR_INSN transition. For other sections, this is not guaranteed. */ enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate; if (!need_pass_2 && subseg_text_p (now_seg) && mapstate == MAP_DATA) @@ -7162,7 +7172,7 @@ md_assemble (char *str) dump_opcode_operands (opcode); #endif /* DEBUG_AARCH64 */ - mapping_state (MAP_INSN); + mapping_state (MAP_CUR_INSN); inst_base = &inst.base; inst_base->opcode = opcode; @@ -7475,7 +7485,7 @@ aarch64_handle_align (fragS * fragP) if (fix) { #ifdef OBJ_ELF - insert_data_mapping_symbol (MAP_INSN, fragP->fr_fix, fragP, fix); + insert_data_mapping_symbol (MAP_CUR_INSN, fragP->fr_fix, fragP, fix); #endif memset (p, 0, fix); p += fix; @@ -7523,10 +7533,10 @@ aarch64_init_frag (fragS * fragP, int max_chars) case rs_align: /* PR 20364: We can get alignment frags in code sections, so do not just assume that we should use the MAP_DATA state. */ - mapping_state_2 (subseg_text_p (now_seg) ? MAP_INSN : MAP_DATA, max_chars); + mapping_state_2 (subseg_text_p (now_seg) ? MAP_CUR_INSN : MAP_DATA, max_chars); break; case rs_align_code: - mapping_state_2 (MAP_INSN, max_chars); + mapping_state_2 (MAP_CUR_INSN, max_chars); break; default: break; @@ -7718,8 +7728,8 @@ try_to_encode_as_unscaled_ldst (aarch64_inst *instr) DEBUG_TRACE ("Found LDURB entry to encode programmer-friendly LDRB"); - if (!aarch64_opcode_encode (instr->opcode, instr, &instr->value, NULL, NULL, - insn_sequence)) + if (!aarch64_opcode_encode (cpu_variant, instr->opcode, instr, &instr->value, + NULL, NULL, insn_sequence)) return FALSE; return TRUE; @@ -7752,7 +7762,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value) /* Try the MOVZ alias. */ opcode = aarch64_get_opcode (OP_MOV_IMM_WIDE); aarch64_replace_opcode (instr, opcode); - if (aarch64_opcode_encode (instr->opcode, instr, + if (aarch64_opcode_encode (cpu_variant, instr->opcode, instr, &instr->value, NULL, NULL, insn_sequence)) { put_aarch64_insn (buf, instr->value); @@ -7761,7 +7771,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value) /* Try the MOVK alias. */ opcode = aarch64_get_opcode (OP_MOV_IMM_WIDEN); aarch64_replace_opcode (instr, opcode); - if (aarch64_opcode_encode (instr->opcode, instr, + if (aarch64_opcode_encode (cpu_variant, instr->opcode, instr, &instr->value, NULL, NULL, insn_sequence)) { put_aarch64_insn (buf, instr->value); @@ -7774,7 +7784,7 @@ fix_mov_imm_insn (fixS *fixP, char *buf, aarch64_inst *instr, offsetT value) /* Try the ORR alias. */ opcode = aarch64_get_opcode (OP_MOV_IMM_LOG); aarch64_replace_opcode (instr, opcode); - if (aarch64_opcode_encode (instr->opcode, instr, + if (aarch64_opcode_encode (cpu_variant, instr->opcode, instr, &instr->value, NULL, NULL, insn_sequence)) { put_aarch64_insn (buf, instr->value); @@ -7886,7 +7896,7 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value) gas_assert (new_inst != NULL); idx = aarch64_operand_index (new_inst->opcode->operands, opnd); new_inst->operands[idx].imm.value = value; - if (aarch64_opcode_encode (new_inst->opcode, new_inst, + if (aarch64_opcode_encode (cpu_variant, new_inst->opcode, new_inst, &new_inst->value, NULL, NULL, insn_sequence)) put_aarch64_insn (buf, new_inst->value); else @@ -7942,7 +7952,7 @@ fix_insn (fixS *fixP, uint32_t flags, offsetT value) new_inst->operands[idx].addr.offset.imm = value; /* Encode/fix-up. */ - if (aarch64_opcode_encode (new_inst->opcode, new_inst, + if (aarch64_opcode_encode (cpu_variant, new_inst->opcode, new_inst, &new_inst->value, NULL, NULL, insn_sequence)) { put_aarch64_insn (buf, new_inst->value); diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index fad4da1ded2..edaed03eea7 100644 --- a/gas/config/tc-aarch64.h +++ b/gas/config/tc-aarch64.h @@ -219,6 +219,7 @@ enum mstate MAP_UNDEFINED = 0, /* Must be zero, for seginfo in new sections. */ MAP_DATA, MAP_INSN, + MAP_C64, }; void mapping_state (enum mstate); diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi index 453e08cdcd3..e5e3593c5fe 100644 --- a/gas/doc/c-aarch64.texi +++ b/gas/doc/c-aarch64.texi @@ -534,6 +534,11 @@ into object files to mark certain features: @item $x At the start of a region of code containing AArch64 instructions. +@cindex @code{$c} +@item $c +At the start of a region of code containing C64 instructions (as oppposed to +standard A64 or A64C instructions). + @cindex @code{$d} @item $d At the start of a region of data. diff --git a/include/ChangeLog b/include/ChangeLog index 5b93fc08916..331e08d1fca 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2020-10-20 Siddhesh Poyarekar + + * opcode/aarch64.h (aarch64_opcode_encode): Add cpu variant + argument. + 2020-10-20 Siddhesh Poyarekar * opcode/aarch64.h (AARCH64_FEATURE_A64C, diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h index 7e450b2a770..10e30d1d15e 100644 --- a/include/opcode/aarch64.h +++ b/include/opcode/aarch64.h @@ -1281,9 +1281,10 @@ struct aarch64_instr_sequence /* Encoding entrypoint. */ extern int -aarch64_opcode_encode (const aarch64_opcode *, const aarch64_inst *, - aarch64_insn *, aarch64_opnd_qualifier_t *, - aarch64_operand_error *, aarch64_instr_sequence *); +aarch64_opcode_encode (aarch64_feature_set, const aarch64_opcode *, + const aarch64_inst *, aarch64_insn *, + aarch64_opnd_qualifier_t *, aarch64_operand_error *, + aarch64_instr_sequence *); extern const aarch64_opcode * aarch64_replace_opcode (struct aarch64_inst *, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 2db94dec5b7..c33d91e68ef 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,22 @@ +2020-10-20 Siddhesh Poyarekar + + * aarch64-asm.c (aarch64_opcode_encode): Add CPU variant + argument. + * aarch64-dis.c (map_type): Add MAP_C64. + (MAYBE_C64): New macro. + (determine_disassembling_preference, print_operands): Use it. + (aarch64_symbol_is_valid): Test for $c. + (get_sym_code_type): Recognise MAP_C64. + (select_aarch64_variant): Clear AARCH64_FEATURE_C64. + (determine_disassembling_preference, aarch64_opcode_decode): + Adjust calls to aarch64_match_operands_constraint. + * aarch64-opc.c (get_altbase_reg_name, get_base_reg_name): New + functions. + (aarch64_print_operand): Use them. + (aarch64_match_operands_constraint): Likewise. + * aarch64-opc.h (aarch64_match_operands_constraint): Add CPU + variant argument. + 2020-10-20 Siddhesh Poyarekar * aarch64-opc.c (fields): New capability register fields. diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c index b4846bf986e..52ed5bdf7d9 100644 --- a/opcodes/aarch64-asm.c +++ b/opcodes/aarch64-asm.c @@ -1987,7 +1987,8 @@ convert_to_real (aarch64_inst *inst, const aarch64_opcode *real) matched operand qualifier sequence in *QLF_SEQ. */ bfd_boolean -aarch64_opcode_encode (const aarch64_opcode *opcode, +aarch64_opcode_encode (aarch64_feature_set features, + const aarch64_opcode *opcode, const aarch64_inst *inst_ori, aarch64_insn *code, aarch64_opnd_qualifier_t *qlf_seq, aarch64_operand_error *mismatch_detail, @@ -2009,7 +2010,7 @@ aarch64_opcode_encode (const aarch64_opcode *opcode, /* Constrain the operands. After passing this, the encoding is guaranteed to succeed. */ - if (aarch64_match_operands_constraint (inst, mismatch_detail) == 0) + if (aarch64_match_operands_constraint (features, inst, mismatch_detail) == 0) { DEBUG_TRACE ("FAIL since operand constraint not met"); return 0; diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index b6bc7e6235a..10840e642b7 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -32,7 +32,8 @@ enum map_type { MAP_INSN, - MAP_DATA + MAP_DATA, + MAP_C64 }; static aarch64_feature_set arch_variant; /* See select_aarch64_variant. */ @@ -41,6 +42,8 @@ static int last_mapping_sym = -1; static bfd_vma last_stop_offset = 0; static bfd_vma last_mapping_addr = 0; +#define MAYBE_C64 (last_type == MAP_C64 ? AARCH64_FEATURE_C64 : 0) + /* Other options */ static int no_aliases = 0; /* If set disassemble as most general inst. */ static int no_notes = 1; /* If set do not print disassemble notes in the @@ -2715,7 +2718,8 @@ determine_disassembling_preference (struct aarch64_inst *inst, if (convert_to_alias (©, alias) == 1) { aarch64_replace_opcode (©, alias); - assert (aarch64_match_operands_constraint (©, NULL)); + assert (aarch64_match_operands_constraint (MAYBE_C64, ©, + NULL)); DEBUG_TRACE ("succeed with %s via conversion", alias->name); memcpy (inst, ©, sizeof (aarch64_inst)); return; @@ -2973,7 +2977,7 @@ aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code, } /* Match the qualifiers. */ - if (aarch64_match_operands_constraint (inst, NULL) == 1) + if (aarch64_match_operands_constraint (MAYBE_C64, inst, NULL) == 1) { /* Arriving here, the CODE has been determined as a valid instruction of OPCODE and *INST has been filled with information of this OPCODE @@ -3082,7 +3086,7 @@ print_operands (bfd_vma pc, const aarch64_opcode *opcode, /* Generate the operand string in STR. */ aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p, - &info->target, ¬es, arch_variant); + &info->target, ¬es, arch_variant | MAYBE_C64); /* Print the delimiter (taking account of omitted operand(s)). */ if (str[0] != '\0') @@ -3294,7 +3298,7 @@ aarch64_symbol_is_valid (asymbol * sym, return name && (name[0] != '$' - || (name[1] != 'x' && name[1] != 'd') + || (name[1] != 'x' && name[1] != 'd' && name[1] != 'c') || (name[2] != '\0' && name[2] != '.')); } @@ -3348,20 +3352,35 @@ get_sym_code_type (struct disassemble_info *info, int n, type = ELF_ST_TYPE (es->internal_elf_sym.st_info); - /* If the symbol has function type then use that. */ + /* If the symbol has function type then use that. Set mapping symbol as + MAP_INSN only if transitioning from MAP_DATA. We do this to conserve any + previous MAP_C64 type. */ if (type == STT_FUNC) { - *map_type = MAP_INSN; + *map_type = *map_type == MAP_DATA ? MAP_INSN : *map_type; return TRUE; } /* Check for mapping symbols. */ name = bfd_asymbol_name(info->symtab[n]); if (name[0] == '$' - && (name[1] == 'x' || name[1] == 'd') + && (name[1] == 'x' || name[1] == 'd' || name[1] == 'c') && (name[2] == '\0' || name[2] == '.')) { - *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA); + switch (name[1]) + { + case 'd': + *map_type = MAP_DATA; + break; + case 'x': + *map_type = MAP_INSN; + break; + case 'c': + *map_type = MAP_C64; + break; + default: + abort (); + } return TRUE; } @@ -3372,7 +3391,8 @@ get_sym_code_type (struct disassemble_info *info, int n, for the chosen architecture variant. Currently we only restrict disassembly for Armv8-R and otherwise enable all - non-R-profile features. */ + non-R-profile features with the exception of C64, which is set based on + mapping symbols. */ static void select_aarch64_variant (unsigned mach) { @@ -3382,7 +3402,8 @@ select_aarch64_variant (unsigned mach) arch_variant = AARCH64_ARCH_V8_R; break; default: - arch_variant = AARCH64_ANY & ~(AARCH64_FEATURE_V8_R); + arch_variant = AARCH64_ANY & ~(AARCH64_FEATURE_V8_R + | AARCH64_FEATURE_C64); } } @@ -3431,7 +3452,7 @@ print_insn_aarch64 (bfd_vma pc, HEX file or similar. */ enum map_type type = MAP_DATA; if ((info->section && info->section->flags & SEC_CODE) || !info->section) - type = MAP_INSN; + type = last_type == MAP_C64 ? MAP_C64 : MAP_INSN; /* First check the full symtab for a mapping symbol, even if there are no usable non-mapping symbols for this address. */ diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c index f4dc3ffcf33..05a974cee03 100644 --- a/opcodes/aarch64-opc.c +++ b/opcodes/aarch64-opc.c @@ -2742,7 +2742,8 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx, Un-determined operand qualifiers may get established during the process. */ int -aarch64_match_operands_constraint (aarch64_inst *inst, +aarch64_match_operands_constraint (aarch64_feature_set features + ATTRIBUTE_UNUSED, aarch64_inst *inst, aarch64_operand_error *mismatch_detail) { int i; @@ -2803,7 +2804,8 @@ aarch64_match_operands_constraint (aarch64_inst *inst, continue; } if (operand_general_constraint_met_p (inst->operands, i, type, - inst->opcode, mismatch_detail) == 0) + inst->opcode, + mismatch_detail) == 0) { DEBUG_TRACE ("FAIL on operand %d", i); return 0; @@ -2920,6 +2922,15 @@ get_cap_reg_name (int regno, int sp_reg_p) return int_reg[has_zr][2][regno]; } +static inline const char * +get_base_reg_name (aarch64_feature_set features, int regno, int sp_reg_p) +{ + if (AARCH64_CPU_HAS_FEATURE(features, AARCH64_FEATURE_C64)) + return get_cap_reg_name (regno, sp_reg_p); + else + return get_64bit_int_reg_name (regno, sp_reg_p); +} + /* Get the name of the integer offset register in OPND, using the shift type to decide whether it's a word or doubleword. */ @@ -3609,7 +3620,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_ADDR_SIMPLE: case AARCH64_OPND_SIMD_ADDR_SIMPLE: case AARCH64_OPND_SIMD_ADDR_POST: - name = get_64bit_int_reg_name (opnd->addr.base_regno, 1); + name = get_base_reg_name (features, opnd->addr.base_regno, 1); if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST) { if (opnd->addr.offset.is_reg) @@ -3632,7 +3643,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SVE_ADDR_RX_LSL2: case AARCH64_OPND_SVE_ADDR_RX_LSL3: print_register_offset_address - (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1), + (buf, size, opnd, + get_base_reg_name (features, opnd->addr.base_regno, 1), get_offset_int_reg_name (opnd)); break; @@ -3680,7 +3692,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, case AARCH64_OPND_SVE_ADDR_RI_U6x4: case AARCH64_OPND_SVE_ADDR_RI_U6x8: print_immediate_offset_address - (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1)); + (buf, size, opnd, + get_base_reg_name (features, opnd->addr.base_regno, 1)); break; case AARCH64_OPND_SVE_ADDR_ZI_U5: @@ -3702,7 +3715,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc, break; case AARCH64_OPND_ADDR_UIMM12: - name = get_64bit_int_reg_name (opnd->addr.base_regno, 1); + name = get_base_reg_name (features, opnd->addr.base_regno, 1); if (opnd->addr.offset.imm) snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm); else diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h index ce642cc20db..b7e7381a299 100644 --- a/opcodes/aarch64-opc.h +++ b/opcodes/aarch64-opc.h @@ -325,7 +325,7 @@ get_operand_from_code (enum aarch64_opnd code) /* Operand qualifier and operand constraint checking. */ -int aarch64_match_operands_constraint (aarch64_inst *, +int aarch64_match_operands_constraint (aarch64_feature_set, aarch64_inst *, aarch64_operand_error *); /* Operand qualifier related functions. */