]> 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)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:01:41 +0000 (15:01 -0300)
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 7fb6181410601bb7e52b852ab37bd05b9455107f..7b83a2892048951b4f548c913da85172e705683c 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.
+
 2020-10-16  Nelson Chu  <nelson.chu@sifive.com>
 
        * elfnn-riscv.c (riscv_elf_link_hash_table): Add last_iplt_index.
index 8d9b420a425c3806ee3b50bd47d20650397fbf1c..74491ac4a0a4e6fe9ec6388dfe60b8a4f7793803 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 a9924e7ec5664c8f791bc317e40932f09f507ba8..a38da7297386220711d97551319031b53b8ccbaf 100644 (file)
@@ -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
index 311549975e3a49af3803b18e9d7c473ec223f8da..bf0b6dcc593e7147a1c82fa338e70501de1470d1 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 da0cf11e26ecf2417e6dbe08e7955b06fc1bc9a2..e768c041b1209216801fbae956b2f58d88fb483f 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
@@ -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);
index fad4da1ded21a2921efefb416ddacd2f5bba5d60..edaed03eea7923e99125729d5417801a564ec72d 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 453e08cdcd30a0851288920b1e044148bc718b59..e5e3593c5fe8bda06dbf756ecb33a6e7a8d31e4b 100644 (file)
@@ -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.
index 5b93fc08916864a656301ebe8d60ce3a3c10320a..331e08d1fca8595a5912854b52b528d63612e62a 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 7e450b2a770e4a55154c6b4a4af7e71e83427f32..10e30d1d15e235fcc4488568b0e2ba716d812114 100644 (file)
@@ -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 *,
index 2db94dec5b7716561d67533b678eec30e827f72e..c33d91e68ef689f461a12b8a61c1bd6be30b261b 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 b4846bf986ee9bbc0c3b0e3b73c1cc31e861ce18..52ed5bdf7d9a2e8c9079cb6e3c92f74d940fa65b 100644 (file)
@@ -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;
index b6bc7e6235aa578b47361c353e94e00554d6bceb..10840e642b7a6608d897ec7d8b6b29bd494ebbf4 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
@@ -2715,7 +2718,8 @@ determine_disassembling_preference (struct aarch64_inst *inst,
          if (convert_to_alias (&copy, alias) == 1)
            {
              aarch64_replace_opcode (&copy, alias);
-             assert (aarch64_match_operands_constraint (&copy, NULL));
+             assert (aarch64_match_operands_constraint (MAYBE_C64, &copy,
+                                                        NULL));
              DEBUG_TRACE ("succeed with %s via conversion", alias->name);
              memcpy (inst, &copy, 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, &notes, arch_variant);
+                            &info->target, &notes, 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.  */
index f4dc3ffcf3387de742a329ace09ed3551ef98bb2..05a974cee0304bcbd8492fadfb4b9a0706ff4115 100644 (file)
@@ -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
index ce642cc20db0f54e4ce8893d60b2955b242d42e8..b7e7381a299afe0cc03e009252a7dd11149cfaa8 100644 (file)
@@ -325,7 +325,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.  */