]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Add mapping symbol to identify C64 code sections
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>
Fri, 11 Sep 2020 03:48:04 +0000 (09:18 +0530)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 22:50:13 +0000 (15:50 -0700)
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  <siddesh.poyarekar@arm.com>

* 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  <siddesh.poyarekar@arm.com>

* 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  <siddesh.poyarekar@arm.com>

* opcode/aarch64.h (aarch64_opcode_encode): Add cpu variant
argument.

opcodes/ChangeLog:

2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>

* 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.

14 files changed:
bfd/ChangeLog
bfd/cpu-aarch64.c
bfd/elfnn-aarch64.c
gas/ChangeLog
gas/config/tc-aarch64.c
gas/config/tc-aarch64.h
gas/doc/c-aarch64.texi
include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-asm.c
opcodes/aarch64-dis.c
opcodes/aarch64-opc.c
opcodes/aarch64-opc.h

index 197bfd425a7363d2c2866454fcadf0834258bbf2..1e5ab5b38a534dc15b5910d1551bebad988dfbe6 100644 (file)
@@ -1,3 +1,10 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * 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.
+
 2022-04-27  John Baldwin  <jhb@FreeBSD.org>
 
        * elf.c (elfcore_grok_freebsd_note): Handle NT_ARM_TLS notes.
index e1bd8fc478951332cd7b6878f326bf1e34ee117c..96ac08708ac38698195b44e8088c1e4ed08c7f61 100644 (file)
@@ -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;
index 3eee97b7adae6694480d090186c9c3baee2b4314..2757812b400be0619f80d7853bbbb5958e0ae601 100644 (file)
@@ -8353,7 +8353,7 @@ static bool
 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
@@ -9934,7 +9934,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
index 98d2586cffaa91d0a0de880af3f7dc050b16b9a5..ddeee976e8c8761c78310df53fe2275c3f62682d 100644 (file)
@@ -1,3 +1,16 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * 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  <siddesh.poyarekar@arm.com>
 
        * config/tc-aarch64.c (AARCH64_REG_TYPES,
index 9811a50027624d2ef63d0559d5ad0cc502d5aa9a..0c191eb959fe3cfb8b4fccc0f26fc4087522919a 100644 (file)
 
 #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
@@ -1524,6 +1528,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 ();
     }
@@ -1599,7 +1607,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.  */
@@ -1615,7 +1623,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;
@@ -2019,14 +2027,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
@@ -5530,8 +5538,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.  */
@@ -7926,7 +7935,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;
 
@@ -8020,7 +8030,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)
@@ -8041,7 +8051,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;
@@ -8369,7 +8379,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;
@@ -8417,10 +8427,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;
@@ -8612,8 +8622,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;
@@ -8646,7 +8656,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);
@@ -8655,7 +8665,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);
@@ -8668,7 +8678,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);
@@ -8780,7 +8790,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
@@ -8836,7 +8846,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);
index f5c1752379603ebf808275caab0efae1540c78bb..b463840b444cd2d92d95bf2eaa3e9b3802dacd12 100644 (file)
@@ -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);
index 7f4599d453007b498093663283e9aa92940cb57b..11abc842e61656578b42c82f314ab105234cbfce 100644 (file)
@@ -559,6 +559,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.
index 472741f9b92e2b68226c6e022790e6cd611d49e0..1a9cfd3399289a83e2687f6e1ed7a7881699d862 100644 (file)
@@ -1,3 +1,8 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * opcode/aarch64.h (aarch64_opcode_encode): Add cpu variant
+       argument.
+
 2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
 
        * opcode/aarch64.h (AARCH64_FEATURE_A64C,
index 53681a7abc5b90fb10fe662ebc3023c1ba744256..8881706821fb6e3a2e448969c7bf2c0c648b684d 100644 (file)
@@ -1380,9 +1380,10 @@ struct aarch64_instr_sequence
 /* Encoding entrypoint.  */
 
 extern bool
-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 *,
index b4121c46c061ebd1e063707c55b1d4a4eb52f903..fce7b298278065bbaf2d0efa7c37bb291509f74f 100644 (file)
@@ -1,3 +1,22 @@
+2020-10-20  Siddhesh Poyarekar  <siddesh.poyarekar@arm.com>
+
+       * 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  <siddesh.poyarekar@arm.com>
 
        * aarch64-opc.c (fields): New capability register fields.
index de4c452ff0434e0bd830c9b87b16ecf1aa5f9e82..91054cce5a9975fde9f06f557c33ae0008c17187 100644 (file)
@@ -2210,7 +2210,8 @@ convert_to_real (aarch64_inst *inst, const aarch64_opcode *real)
    matched operand qualifier sequence in *QLF_SEQ.  */
 
 bool
-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,
@@ -2232,7 +2233,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;
index bd2068b0f32f343f5bb48ee4c30dc996a4232d6c..48d818d02682f528b6b7859d056abea1f9cd628a 100644 (file)
@@ -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.  */
 \fstatic int no_notes = 1;      /* If set do not print disassemble notes in the
@@ -2925,7 +2928,8 @@ determine_disassembling_preference (struct aarch64_inst *inst,
          if (convert_to_alias (&copy, alias) == 1)
            {
              aarch64_replace_opcode (&copy, alias);
-             if (aarch64_match_operands_constraint (&copy, NULL) != 1)
+             if (aarch64_match_operands_constraint (MAYBE_C64, &copy,
+                                                    NULL) != 1)
                {
                  DEBUG_TRACE ("FAILED with alias %s ", alias->name);
                }
@@ -3189,7 +3193,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
@@ -3298,7 +3302,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, &notes, arch_variant);
+                            &info->target, &notes, arch_variant | MAYBE_C64);
 
       /* Print the delimiter (taking account of omitted operand(s)).  */
       if (str[0] != '\0')
@@ -3528,7 +3532,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] != '.'));
 }
 
@@ -3582,20 +3586,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;
     }
 
@@ -3606,7 +3625,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)
 {
@@ -3616,7 +3636,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);
     }
 }
 
@@ -3665,7 +3686,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.  */
index 7a8c0c03099844f76c4a4a2341a5333ef265c197..797334c186a113d6d03c098b26ebd849617d5169 100644 (file)
@@ -2757,7 +2757,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;
@@ -2848,7 +2849,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;
@@ -2965,6 +2967,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.  */
 
@@ -3741,7 +3752,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)
@@ -3765,7 +3776,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;
 
@@ -3814,7 +3826,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:
@@ -3836,7 +3849,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
index 6e4f5187c46eadf0f9026675958cdd4bfa9008a0..0acbdfd7e9e568a4f7658f1ecc56a39d41fa5547 100644 (file)
@@ -369,7 +369,7 @@ get_operand_from_code (enum aarch64_opnd code)
 \f
 /* 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.  */