public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
@ 2022-09-30  9:20 Nelson Chu
  2022-09-30  9:20 ` [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations Nelson Chu
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Nelson Chu @ 2022-09-30  9:20 UTC (permalink / raw)
  To: binutils, nelson

RISC-V Psabi pr196,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196

bfd/
    * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
    (riscv_copy_subset_list): Copy arch_str as well.
    * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
gas/
    * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
    architecture string in the subset_list.
    (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
    architecture string.
    (s_riscv_option): Likewise.
    (need_arch_map_symbol): New boolean, used to indicate if .option
    directives do affect instructions.
    (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
    generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
    if reset_seg_arch_str is true.
    (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
    now, only add $x+arch if the architecture strings in subset list and segment
    are different.  Besides, always add $x+arch at the start of section, and do
    not add $x+arch for code alignment, since rvc for alignment can be judged
    from addend of R_RISCV_ALIGN.
    (riscv_remove_mapping_symbol): If current and previous mapping symbol have
    same value, then remove the current $x only if the previous is $x+arch;
    Otherwise, always remove previous.
    (riscv_add_odd_padding_symbol): Updated.
    (riscv_check_mapping_symbols): Don't need to add any $x+arch if
    need_arch_map_symbol is false, so changed them to $x.
    (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
    (riscv_init_frag): Likewise.
    (s_riscv_insn): Likewise.
    (riscv_elf_final_processing): Call riscv_release_subset_list to release
    riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
    (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
    from riscv_subsets.
    * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
    symbol of each segment.

    * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
    * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
    one file.
    * testsuite/gas/riscv/mapping-symbols.d: Likewise.
    * testsuite/gas/riscv/mapping-dis.d: Likewise.
    * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
    does need any $x+arch.
    * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
    * testsuite/gas/riscv/option-arch-01a.d: Updated.
opcodes/
    * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
    riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
    for some specfic code region.
    (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
    the architecture string once the ISA is different.
---
 bfd/elfxx-riscv.c                             |   7 +
 bfd/elfxx-riscv.h                             |   1 +
 gas/config/tc-riscv.c                         | 161 ++++++++++++++----
 gas/config/tc-riscv.h                         |   6 +-
 gas/testsuite/gas/riscv/mapping-01.s          |  17 --
 gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
 gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
 gas/testsuite/gas/riscv/mapping-02.s          |  12 --
 gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
 gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
 gas/testsuite/gas/riscv/mapping-03.s          |  11 --
 gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
 gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
 gas/testsuite/gas/riscv/mapping-04.s          |  13 --
 gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
 gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
 gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
 gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
 gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
 gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
 gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
 gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
 gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
 gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
 gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
 gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
 opcodes/riscv-dis.c                           |   9 +
 27 files changed, 420 insertions(+), 328 deletions(-)
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
 create mode 100644 gas/testsuite/gas/riscv/mapping.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c67d4167232..9247350c2c2 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
     }
 
   subset_list->tail = NULL;
+
+  if (subset_list->arch_str != NULL)
+    {
+      free ((void*) subset_list->arch_str);
+      subset_list->arch_str = NULL;
+    }
 }
 
 /* Parsing extension version.
@@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
 {
   riscv_subset_list_t *new = xmalloc (sizeof *new);
   new->head = riscv_copy_subset (new, subset_list->head);
+  new->arch_str = strdup (subset_list->arch_str);
   return new;
 }
 
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index ea7126bdb4d..e2c1e3c1618 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -51,6 +51,7 @@ typedef struct
 {
   riscv_subset_t *head;
   riscv_subset_t *tail;
+  const char *arch_str;
 } riscv_subset_list_t;
 
 extern void
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d9f63b11398..99bd0a06d97 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
   true,			/* check_unknown_prefixed_ext.  */
 };
 
+/* Update the architecture string in the subset_list.  */
+
+static void
+riscv_reset_subsets_list_arch_str (void)
+{
+  if (riscv_subsets->arch_str != NULL)
+    free ((void *) riscv_subsets->arch_str);
+  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
+}
+
 /* This structure is used to hold a stack of .option values.  */
 struct riscv_option_stack
 {
@@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
       riscv_subsets = XNEW (riscv_subset_list_t);
       riscv_subsets->head = NULL;
       riscv_subsets->tail = NULL;
+      riscv_subsets->arch_str = NULL;
       riscv_rps_as.subset_list = riscv_subsets;
     }
   riscv_release_subset_list (riscv_subsets);
   riscv_parse_subset (&riscv_rps_as, s);
+  riscv_reset_subsets_list_arch_str ();
 
   riscv_set_rvc (false);
   if (riscv_subset_supports (&riscv_rps_as, "c"))
@@ -459,21 +471,37 @@ static char *expr_end;
 #define OPCODE_MATCHES(OPCODE, OP) \
   (((OPCODE) & MASK_##OP) == MATCH_##OP)
 
+/* Indicate if .option directives do affect instructions.  Set to true means
+   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
+   should be enough.  */
+static bool need_arch_map_symbol = false;
+
 /* Create a new mapping symbol for the transition to STATE.  */
 
 static void
 make_mapping_symbol (enum riscv_seg_mstate state,
 		     valueT value,
-		     fragS *frag)
+		     fragS *frag,
+		     bool reset_seg_arch_str)
 {
   const char *name;
+  char *buff;
   switch (state)
     {
     case MAP_DATA:
       name = "$d";
       break;
     case MAP_INSN:
-      name = "$x";
+      if (reset_seg_arch_str)
+	{
+	  const char *isa = riscv_subsets->arch_str;
+	  size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
+	  buff = xmalloc (size);
+	  snprintf (buff, size, "$x%s", isa);
+	  name = buff;
+	}
+      else
+	name = "$x";
       break;
     default:
       abort ();
@@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
 
   symbolS *symbol = symbol_new (name, now_seg, frag, value);
   symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
+  if (reset_seg_arch_str)
+    {
+      /* Store current $x+arch into tc_segment_info.  */
+      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
+      xfree ((void *) buff);
+    }
 
   /* If .fill or other data filling directive generates zero sized data,
-     or we are adding odd alignemnts, then the mapping symbol for the
-     following code will have the same value.  */
+     then mapping symbol for the following code will have the same value.
+
+     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
+     and .text.zero.fill.last.  */
+  symbolS *first = frag->tc_frag_data.first_map_symbol;
+  symbolS *last = frag->tc_frag_data.last_map_symbol;
   if (value == 0)
     {
-       if (frag->tc_frag_data.first_map_symbol != NULL)
+      if (first != NULL)
 	{
-	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
-		== S_GET_VALUE (symbol));
+	  know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
+		&& first == last);
 	  /* Remove the old one.  */
-	  symbol_remove (frag->tc_frag_data.first_map_symbol,
-			 &symbol_rootP, &symbol_lastP);
+	  symbol_remove (first, &symbol_rootP, &symbol_lastP);
 	}
       frag->tc_frag_data.first_map_symbol = symbol;
     }
-  if (frag->tc_frag_data.last_map_symbol != NULL)
+  else if (last != NULL)
     {
       /* The mapping symbols should be added in offset order.  */
-      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
-			 <= S_GET_VALUE (symbol));
+      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
       /* Remove the old one.  */
-      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
-	  == S_GET_VALUE (symbol))
-	symbol_remove (frag->tc_frag_data.last_map_symbol,
-		       &symbol_rootP, &symbol_lastP);
+      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
+	symbol_remove (last, &symbol_rootP, &symbol_lastP);
     }
   frag->tc_frag_data.last_map_symbol = symbol;
 }
@@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
 
 void
 riscv_mapping_state (enum riscv_seg_mstate to_state,
-		     int max_chars)
+		     int max_chars,
+		     bool frag_align_code)
 {
   enum riscv_seg_mstate from_state =
 	seg_info (now_seg)->tc_segment_info_data.map_state;
+  bool reset_seg_arch_str = false;
 
   if (!SEG_NORMAL (now_seg)
-      /* For now I only add the mapping symbols to text sections.
+      /* For now we only add the mapping symbols to text sections.
 	 Therefore, the dis-assembler only show the actual contents
 	 distribution for text.  Other sections will be shown as
 	 data without the details.  */
@@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
     return;
 
   /* The mapping symbol should be emitted if not in the right
-     mapping state  */
-  if (from_state == to_state)
+     mapping state.  */
+  symbolS *seg_arch_symbol =
+	seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
+  if (to_state == MAP_INSN && seg_arch_symbol == 0)
+    {
+      /* Always add $x+arch at the first instruction of section.  */
+      reset_seg_arch_str = true;
+    }
+  else if (seg_arch_symbol != 0
+	   && to_state == MAP_INSN
+	   && !frag_align_code
+	   && strcmp (riscv_subsets->arch_str,
+		      S_GET_NAME (seg_arch_symbol) + 2) != 0)
+    {
+      reset_seg_arch_str = true;
+      need_arch_map_symbol = true;
+    }
+  else if (from_state == to_state)
     return;
 
   valueT value = (valueT) (frag_now_fix () - max_chars);
   seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
-  make_mapping_symbol (to_state, value, frag_now);
+  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
 }
 
 /* Add the odd bytes of paddings for riscv_handle_align.  */
@@ -544,9 +596,27 @@ static void
 riscv_add_odd_padding_symbol (fragS *frag)
 {
   /* If there was already a mapping symbol, it should be
-     removed in the make_mapping_symbol.  */
-  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
-  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
+     removed in the make_mapping_symbol.
+
+     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
+  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
+  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
+}
+
+/* If previous and current mapping symbol have same value, then remove the
+   current $x only if the previous is $x+arch; Otherwise, always remove the
+   previous.  */
+
+static void
+riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
+{
+  know (pre != NULL && cur != NULL
+	&& S_GET_VALUE (pre) == S_GET_VALUE (cur));
+  symbolS *removed = pre;
+  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
+      && strcmp (S_GET_NAME (cur), "$x") == 0)
+    removed = cur;
+  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
 }
 
 /* Remove any excess mapping symbols generated for alignment frags in
@@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
   if (seginfo == NULL || seginfo->frchainP == NULL)
     return;
 
+  /* If we don't set any .option arch directive, then the arch_map_symbol
+     in each segment must be the first instruction, and we don't need to
+     add $x+arch for them.  */
+  if (!need_arch_map_symbol
+      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
+    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
+
   for (fragp = seginfo->frchainP->frch_root;
        fragp != NULL;
        fragp = fragp->fr_next)
@@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
 
       do
 	{
-	  if (next->tc_frag_data.first_map_symbol != NULL)
+	  symbolS *next_first = next->tc_frag_data.first_map_symbol;
+	  if (next_first != NULL)
 	    {
 	      /* The last mapping symbol overlaps with another one
-		 which at the start of the next frag.  */
-	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
+		 which at the start of the next frag.
+
+		 Please see the gas/testsuite/gas/riscv/mapping.s:
+		 .text.zero.fill.align.A and .text.zero.fill.align.B.  */
+	      riscv_remove_mapping_symbol (last, next_first);
 	      break;
 	    }
 
 	  if (next->fr_next == NULL)
 	    {
-	      /* The last mapping symbol is at the end of the section.  */
+	      /* The last mapping symbol is at the end of the section.
+
+		 Please see the gas/testsuite/gas/riscv/mapping.s:
+		 .text.last.section.  */
 	      know (next->fr_fix == 0 && next->fr_var == 0);
 	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
 	      break;
@@ -3438,7 +3522,7 @@ md_assemble (char *str)
        return;
     }
 
-  riscv_mapping_state (MAP_INSN, 0);
+  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
 
   const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
 						&imm_reloc, op_hash);
@@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
   if (strcmp (name, "rvc") == 0)
     {
       riscv_update_subset (&riscv_rps_as, "+c");
+      riscv_reset_subsets_list_arch_str ();
       riscv_set_rvc (true);
     }
   else if (strcmp (name, "norvc") == 0)
     {
       riscv_update_subset (&riscv_rps_as, "-c");
+      riscv_reset_subsets_list_arch_str ();
       riscv_set_rvc (false);
     }
   else if (strcmp (name, "pic") == 0)
@@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
       if (ISSPACE (*name) && *name != '\0')
 	name++;
       riscv_update_subset (&riscv_rps_as, name);
+      riscv_reset_subsets_list_arch_str ();
 
       riscv_set_rvc (false);
       if (riscv_subset_supports (&riscv_rps_as, "c"))
@@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
   if (!riscv_opts.relax)
     return false;
 
+  /* Maybe we should use frag_var to create a new rs_align_code fragment,
+     rather than just use frag_more to handle an alignment here?  So that we
+     don't need to call riscv_mapping_state again later, and then only need
+     to check frag->fr_type to see if it is frag_align_code.  */
   nops = frag_more (worst_case_bytes);
 
   ex.X_op = O_constant;
@@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
   fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 	       &ex, false, BFD_RELOC_RISCV_ALIGN);
 
-  riscv_mapping_state (MAP_INSN, worst_case_bytes);
+  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
 
   /* We need to start a new frag after the alignment which may be removed by
      the linker, to prevent the assembler from computing static offsets.
@@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
     case rs_fill:
     case rs_align:
     case rs_align_test:
-      riscv_mapping_state (MAP_DATA, max_chars);
+      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
       break;
     case rs_align_code:
-      riscv_mapping_state (MAP_INSN, max_chars);
+      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
       break;
     default:
       break;
@@ -4418,6 +4509,7 @@ void
 riscv_elf_final_processing (void)
 {
   riscv_set_abi_by_arch ();
+  riscv_release_subset_list (riscv_subsets);
   elf_elfheader (stdoutput)->e_flags |= elf_flags;
 }
 
@@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
   save_c = *input_line_pointer;
   *input_line_pointer = '\0';
 
-  riscv_mapping_state (MAP_INSN, 0);
+  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
 
   struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
 				&imm_reloc, insn_type_hash);
@@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
   unsigned int i;
 
   /* Re-write architecture elf attribute.  */
-  arch_str = riscv_arch_str (xlen, riscv_subsets);
+  arch_str = riscv_subsets->arch_str;
   bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
-  xfree ((void *) arch_str);
 
   /* For the file without any instruction, we don't set the default_priv_spec
      according to the privileged elf attributes since the md_assemble isn't
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 802e7afe670..19c45ba2d12 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
 extern int riscv_convert_symbolic_attribute (const char *);
 
 /* Set mapping symbol states.  */
-#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
-void riscv_mapping_state (enum riscv_seg_mstate, int);
+#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
+void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
 
 /* Define target segment type.  */
 #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
 struct riscv_segment_info_type
 {
   enum riscv_seg_mstate map_state;
+  /* The current mapping symbol with architecture string.  */
+  symbolS *arch_map_symbol;
 };
 
 /* Define target fragment type.  */
diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
deleted file mode 100644
index 989463f91ee..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01.s
+++ /dev/null
@@ -1,17 +0,0 @@
-	.option arch, -c
-	.text
-	.global	funcA
-funcA:
-	add	a0, a0, a0
-	j	funcB
-	.global	funcB
-funcB:
-	add	a1, a1, a1
-	bne	a0, a1, funcB
-
-	.data
-	.word 0x123456
-
-	.section	.foo, "ax"
-foo:
-	add	a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
deleted file mode 100644
index 32e0027a13d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01a.d
+++ /dev/null
@@ -1,17 +0,0 @@
-#as:
-#source: mapping-01.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+00 l    d  .foo	0+00 .foo
-0+00 l       .foo	0+00 foo
-0+00 l       .foo	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
-0+00 g       .text	0+00 funcA
-0+08 g       .text	0+00 funcB
diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
deleted file mode 100644
index e84b3d608f5..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01b.d
+++ /dev/null
@@ -1,21 +0,0 @@
-#as:
-#source: mapping-01.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <funcA>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
-
-0+008 <funcB>:
-[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
-
-Disassembly of section .foo:
-
-0+000 <foo>:
-[ 	]+0:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
deleted file mode 100644
index 79468c0d14f..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02.s
+++ /dev/null
@@ -1,12 +0,0 @@
-	.option arch, -c
-	.text
-	.word	1
-	add	a0, a0, a0
-
-	.data
-	.word	2
-
-	.text
-	add	a1, a1, a1
-	.short	3
-	add	a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
deleted file mode 100644
index 333f12cd343..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02a.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#as:
-#source: mapping-02.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+04 l       .text	0+00 \$x
-0+0c l       .text	0+00 \$d
-0+0e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
deleted file mode 100644
index 1ed6c081cf7..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02b.d
+++ /dev/null
@@ -1,16 +0,0 @@
-#as:
-#source: mapping-02.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+4:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+c:[ 	]+0003[ 	]+.short[ 	]+0x0003
-[ 	]+e:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
deleted file mode 100644
index 88f2601568d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03.s
+++ /dev/null
@@ -1,11 +0,0 @@
-	.option arch, -c
-	.text
-	add	a0, a0, a0
-	.long	0
-	.balign	16
-	.word	1
-	add	a1, a1, a1
-	.byte	2
-	.long	3
-	.balign	16
-	.word	5
diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
deleted file mode 100644
index d3663b663aa..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03a.d
+++ /dev/null
@@ -1,20 +0,0 @@
-#as:
-#source: mapping-03.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+04 l       .text	0+00 \$d
-0+08 l       .text	0+00 \$x
-0+14 l       .text	0+00 \$d
-0+18 l       .text	0+00 \$x
-0+1c l       .text	0+00 \$d
-0+21 l       .text	0+00 \$x
-0+2d l       .text	0+00 \$d
-0+31 l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
deleted file mode 100644
index f4f67269981..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03b.d
+++ /dev/null
@@ -1,24 +0,0 @@
-#as:
-#source: mapping-03.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
-[ 	]+10:[ 	]+00000013[ 	]+nop
-[ 	]+14:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+18:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+1c:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
-[ 	]+20:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+21:[ 	]+00000013[ 	]+nop
-[ 	]+25:[ 	]+00000013[ 	]+nop
-[ 	]+29:[ 	]+00000013[ 	]+nop
-[ 	]+2d:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
deleted file mode 100644
index 804b0397737..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04.s
+++ /dev/null
@@ -1,13 +0,0 @@
-	.text
-	.option	arch, -c
-	.fill	2, 4, 0x1001
-	.byte	1
-	.word	0
-	.balign	8
-	add	a0, a0, a0
-	.fill	5, 2, 0x2002
-	add	a1, a1, a1
-
-	.data
-	.word	0x1
-	.word	0x2
diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
deleted file mode 100644
index 1ae9653212b..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04a.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#as:
-#source: mapping-04.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+0d l       .text	0+00 \$x
-0+15 l       .text	0+00 \$d
-0+1f l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
deleted file mode 100644
index 54bd0afb6c4..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04b.d
+++ /dev/null
@@ -1,23 +0,0 @@
-#as:
-#source: mapping-04.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+d:[ 	]+00000013[ 	]+nop
-[ 	]+11:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+15:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+19:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+1d:[ 	]+2002[ 	]+.short[ 	]+0x2002
-[ 	]+1f:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+23:[ 	]+0000[ 	]+.2byte[ 	]+0x0
-[ 	]+25:[ 	]+0000[ 	]+.2byte[ 	]+0x0
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
new file mode 100644
index 00000000000..246f3672ade
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-dis.d
@@ -0,0 +1,84 @@
+#as:
+#source: mapping.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text.cross.section.A:
+
+0+000 <funcA>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+bffd[ 	]+j[ 	]+0 <funcA>
+
+Disassembly of section .text.corss.section.B:
+
+0+000 <funcB>:
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+fffff06f[ 	]+j[ 	]+0 <funcB>
+
+Disassembly of section .text.data:
+
+0+000 <.text.data>:
+[ 	]+[0-9a-f]+:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+05000302[ 	]+.word[ 	]+0x05000302
+
+Disassembly of section .text.odd.align:
+
+0+000 <.text.odd.align>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+01[ 	]+.byte[ 	]+0x01
+[ 	]+[0-9a-f]+:[ 	]+00[ 	]+.byte[ 	]+0x00
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+
+Disassembly of section .text.zero.fill.first:
+
+0+000 <.text.zero.fill.first>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+
+Disassembly of section .text.zero.fill.last:
+
+0+000 <.text.zero.fill.last>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.zero.fill.align.A:
+
+0+000 <.text.zero.fill.align.A>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.zero.fill.align.B:
+
+0+000 <.text.zero.fill.align.B>:
+[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.last.section:
+
+0+000 <.text.last.section>:
+[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+
+Disassembly of section .text.section.padding:
+
+0+000 <.text.section.padding>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+
+Disassembly of section .text.relax.align:
+
+0+000 <.text.relax.align>:
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
new file mode 100644
index 00000000000..f69e719ff30
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
@@ -0,0 +1,17 @@
+#as:
+#source: mapping-non-arch.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+00+00 l    d  .text	00+00 .text
+00+00 l    d  .data	00+00 .data
+00+00 l    d  .bss	00+00 .bss
+00+00 l       .text	00+00 \$x
+00+08 l       .text	00+00 \$d
+00+0c l       .text	00+00 \$x
+00+00 l    d  text.A	00+00 text.A
+00+00 l       text.A	00+00 \$x
+00+02 l       text.A	00+00 \$d
+00+00 l    d  .riscv.attributes	00+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
new file mode 100644
index 00000000000..03b2d75a5dd
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
@@ -0,0 +1,11 @@
+.attribute arch, "rv32i"
+.option arch, +c
+.text
+addi	a0, zero, 1
+.align 3
+.word 0x1
+addi	a0, zero, 2
+
+.section text.A, "ax"
+addi	a0, zero, 3
+.word 0x2
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
deleted file mode 100644
index 916f732b7f7..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
+++ /dev/null
@@ -1,21 +0,0 @@
-#as: -mno-relax
-#source: mapping-03.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+04 l       .text	0+00 \$d
-0+08 l       .text	0+00 \$x
-0+10 l       .text	0+00 \$d
-0+14 l       .text	0+00 \$x
-0+18 l       .text	0+00 \$d
-0+20 l       .text	0+00 \$d
-0+24 l       .text	0+00 \$x
-0+1d l       .text	0+00 \$d
-0+1e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
deleted file mode 100644
index 9e777351d1d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
+++ /dev/null
@@ -1,25 +0,0 @@
-#as: -mno-relax
-#source: mapping-03.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
-[ 	]+10:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+14:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+18:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
-[ 	]+1c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+1d:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+1e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+20:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
-[ 	]+24:[ 	]+00000013[ 	]+nop
-[ 	]+28:[ 	]+00000013[ 	]+nop
-[ 	]+2c:[ 	]+00000013[ 	]+nop
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
deleted file mode 100644
index d552a7f632a..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
+++ /dev/null
@@ -1,16 +0,0 @@
-#as: -mno-relax
-#source: mapping-04.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+14 l       .text	0+00 \$d
-0+1e l       .text	0+00 \$x
-0+0d l       .text	0+00 \$d
-0+0e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
deleted file mode 100644
index be668f29220..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
+++ /dev/null
@@ -1,24 +0,0 @@
-#as: -mno-relax
-#source: mapping-04.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+d:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+10:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+14:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+18:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+1c:[ 	]+2002[ 	]+.short[ 	]+0x2002
-[ 	]+1e:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+22:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+24:[ 	]+00000013[ 	]+nop
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
new file mode 100644
index 00000000000..83ee6528b79
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-symbols.d
@@ -0,0 +1,48 @@
+#as:
+#source: mapping.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l    d  .text	0+00 .text
+0+00 l    d  .data	0+00 .data
+0+00 l    d  .bss	0+00 .bss
+0+00 l    d  .text.cross.section.A	0+00 .text.cross.section.A
+0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.corss.section.B	0+00 .text.corss.section.B
+0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.corss.section.B	0+00 \$xrv32i2p1
+0+00 l    d  .text.data	0+00 .text.data
+0+00 l       .text.data	0+00 \$d
+0+08 l       .text.data	0+00 \$xrv32i2p1_c2p0
+0+0c l       .text.data	0+00 \$d
+0+00 l    d  .text.odd.align	0+00 .text.odd.align
+0+00 l       .text.odd.align	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.odd.align	0+00 \$d
+0+08 l       .text.odd.align	0+00 \$xrv32i2p1
+0+00 l    d  .text.zero.fill.first	0+00 .text.zero.fill.first
+0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.zero.fill.last	0+00 .text.zero.fill.last
+0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.zero.fill.last	0+00 \$x
+0+00 l    d  .text.zero.fill.align.A	0+00 .text.zero.fill.align.A
+0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.zero.fill.align.B	0+00 .text.zero.fill.align.B
+0+00 l       .text.zero.fill.align.B	0+00 \$xrv32i2p1
+0+00 l    d  .text.last.section	0+00 .text.last.section
+0+00 l       .text.last.section	0+00 \$xrv32i2p1
+0+04 l       .text.last.section	0+00 \$d
+0+00 l    d  .text.section.padding	0+00 .text.section.padding
+0+00 l       .text.section.padding	0+00 \$xrv32i2p1_c2p0
+0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_c2p0
+0+06 l       .text.section.padding	0+00 \$d
+0+00 l    d  .text.relax.align	0+00 .text.relax.align
+0+00 l       .text.relax.align	0+00 \$xrv32i2p1_c2p0
+0+08 l       .text.relax.align	0+00 \$xrv32i2p1
+0+0a l       .text.section.padding	0+00 \$x
+0+03 l       .text.odd.align	0+00 \$d
+0+04 l       .text.odd.align	0+00 \$x
+0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
+0+00 g       .text.cross.section.A	0+00 funcA
+0+00 g       .text.corss.section.B	0+00 funcB
diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
new file mode 100644
index 00000000000..a0e6c744107
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping.s
@@ -0,0 +1,112 @@
+.attribute arch, "rv32ic"
+.option norelax			# FIXME: assembler fill the paddings after parsing everything,
+				# so we probably won't fill anything for the norelax region when
+				# the riscv_opts.relax is enabled at somewhere.
+
+.section .text.cross.section.A, "ax"
+.option push
+.global funcA
+funcA:
+addi	a0, zero, 1		# rv32i
+.option arch, +c
+j	funcA			# rv32ic
+.section .text.corss.section.B, "ax"
+.globl funcB
+funcB:
+addi	a0, zero, 2		# rv32ic, need to be added since start of section
+.option arch, -c
+j	funcB			# rv32i
+.option pop
+
+.section .text.data, "ax"
+.option push
+.word	0			# $d
+.long	1
+addi	a0, zero, 1		# rv32ic
+.data
+.word	2			# don't add mapping symbols for non-text section
+.section .text.data
+addi	a0, zero, 2		# $x, but same as previous addi, so removed
+.byte	2			# $d, dumped as .word
+.short	3
+.byte	5
+.option pop
+
+.section .text.odd.align, "ax"
+.option push
+.option norelax
+.option arch, +c
+addi	a0, zero, 1		# $xrv32ic
+.byte	1			# $d
+.option arch, -c
+.align	3			# odd alignment, $x replaced by $d + $x
+addi	a0, zero, 2		# $xrv32i
+.option pop
+
+.section .text.zero.fill.first, "ax"
+.option push
+.option norelax
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
+addi	a0, zero, 1		# $xrv32ic
+.option pop
+
+.section .text.zero.fill.last, "ax"
+.option push
+.option norelax
+addi	a0, zero, 1		# $xrv32ic
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
+addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
+.option pop
+
+# last overlap next first
+.section .text.zero.fill.align.A, "ax"
+.option push
+.option norelax
+.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
+addi	a0, zero, 1		# $x, should be removed in riscv_check_mapping_symbols
+addi	a0, zero, 2
+.option pop
+
+# last overlap next first
+.section .text.zero.fill.align.B, "ax"
+.option push
+.option norelax
+.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed,
+				# but will be removed in riscv_check_mapping_symbols
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
+.option arch, -c
+addi	a0, zero, 1		# $xrv32i
+addi	a0, zero, 2
+.option pop
+
+.section .text.last.section, "ax"
+.option push
+.option norelax
+.option arch, -c
+addi	a0, zero, 1		# $xrv32i
+.word	1			# $d
+.align	2			# zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
+.option pop
+
+.section .text.section.padding, "ax"
+.option push
+.option norelax
+.align	2
+addi	a0, zero, 1		# $rv32ic
+.option arch, +a
+.align	2			# 2-byte padding, $x, removed
+addi	a0, zero, 2		# $xrv32iac
+.word	1			# $d
+.option pop			# 2-byte padding, $x
+
+.section .text.relax.align, "ax"
+.option push
+.option relax
+.option arch, rv32ic
+.balign	4			# $xrv32ic, add at the start of section
+addi	a0, zero, 1		# $x, won't added
+.option arch, -c
+.align	3			# $x, won't added
+addi	a0, zero, 2		# $xrv32i
+.option pop
diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
index aed4ca8e4d9..1d14c604dec 100644
--- a/gas/testsuite/gas/riscv/option-arch-01a.d
+++ b/gas/testsuite/gas/riscv/option-arch-01a.d
@@ -10,5 +10,5 @@ Disassembly of section .text:
 0+000 <.text>:
 [ 	]+[0-9a-f]+:[  	]+952e[    	]+add[        	]+a0,a0,a1
 [ 	]+[0-9a-f]+:[  	]+00b50533[    	]+add[        	]+a0,a0,a1
-[ 	]+[0-9a-f]+:[  	]+00302573[    	]+csrr[        	]+a0,fcsr
+[ 	]+[0-9a-f]+:[  	]+00302573[    	]+frcsr[        	]+a0
 #...
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index f2d399260c1..eb88c81c0f1 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       /* If arch has ZFINX flags, use gpr for disassemble.  */
       if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
 	riscv_fpr_names = riscv_gpr_names;
+      else
+	riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
+			  riscv_fpr_names_abi : riscv_fpr_names_numeric;
 
       for (; op->name; op++)
 	{
@@ -810,6 +813,12 @@ riscv_get_map_state (int n,
     *state = MAP_INSN;
   else if (strcmp (name, "$d") == 0)
     *state = MAP_DATA;
+  else if (strncmp (name, "$xrv", 4) == 0)
+    {
+      *state = MAP_INSN;
+      riscv_release_subset_list (&riscv_subsets);
+      riscv_parse_subset (&riscv_rps_dis, name + 2);
+    }
   else
     return false;
 
-- 
2.37.0 (Apple Git-136)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations.
  2022-09-30  9:20 [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Nelson Chu
@ 2022-09-30  9:20 ` Nelson Chu
  2022-10-03 11:17 ` [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Tsukasa OI
  2022-10-28  3:16 ` Nelson Chu
  2 siblings, 0 replies; 9+ messages in thread
From: Nelson Chu @ 2022-09-30  9:20 UTC (permalink / raw)
  To: binutils, nelson

RISC-V Psabi pr116,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/116

bfd/
    * elfnn-riscv.c (_bfd_riscv_enable_rvc): New function to check the
    mapping symbol with architecture string in the R_RISCV_RELAX, to see
    if rvc is enabled or not.  If we don't find any mapping symbols, then
    just check the elf header flag as usual.
    (_bfd_riscv_relax_call): Updated since above change.
    (_bfd_riscv_relax_lui): Likewise.
gas/
    * config/tc-riscv.c (append_insn): Store $x+arch in tc_fix_data if exsit.
    (md_apply_fix): Refer the $x+arch from tc_fix_data into R_RISCV_RELAX,
    these only for the relocations used to do rvc relaxation.  Besides, set
    addend of R_RISCV_RELAX (fx_offset) to zero.
    * config/tc-riscv.h (TC_FIX_TYPE): Defined to store $x+arch in each fixup
    only for risc-v target.
    (struct riscv_fixup_type): Likewise.
    (TC_INIT_FIX_DATA): Likewise.
    * testsuite/gas/riscv/mapping-relax.d: New testcase.
    * testsuite/gas/riscv/mapping-relax.s: Likewise.
ld/
    * testsuite/ld-riscv-elf/c-relax.d: New testcase for specific rvc relaxation.
    * testsuite/ld-riscv-elf/c-relax.s: Likewise.
    * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
---
 bfd/elfnn-riscv.c                          | 31 +++++++++++++++++++---
 gas/config/tc-riscv.c                      | 15 +++++++++--
 gas/config/tc-riscv.h                      |  7 +++++
 gas/testsuite/gas/riscv/mapping-relax.d    | 23 ++++++++++++++++
 gas/testsuite/gas/riscv/mapping-relax.s    | 21 +++++++++++++++
 ld/testsuite/ld-riscv-elf/c-relax.d        | 16 +++++++++++
 ld/testsuite/ld-riscv-elf/c-relax.s        | 12 +++++++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  1 +
 8 files changed, 121 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/mapping-relax.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-relax.s
 create mode 100644 ld/testsuite/ld-riscv-elf/c-relax.d
 create mode 100644 ld/testsuite/ld-riscv-elf/c-relax.s

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 3d2ddf4e651..e5c41707437 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4168,6 +4168,31 @@ typedef bool (*relax_func_t) (bfd *, asection *, asection *,
 			      riscv_pcgp_relocs *,
 			      bool undefined_weak);
 
+/* Check the mapping symbol with architecture string in the R_RISCV_RELAX,
+   to see if rvc is enabled or not.  If we don't find any mapping symbols,
+   then just check the elf header flag as usual.  */
+
+static int
+_bfd_riscv_enable_rvc (bfd *abfd, Elf_Internal_Rela *rel)
+{
+  Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
+  int rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
+  if (ELFNN_R_SYM (rel->r_info) < symtab_hdr->sh_info)
+    {
+      Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
+				+ ELFNN_R_SYM (rel->r_info));
+
+      if (isym->st_shndx == SHN_UNDEF
+	  || isym->st_shndx >= elf_numsections (abfd))
+	return rvc;
+
+      const char *name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
+      rvc = (name && strncmp (name, "$xrv", 4) == 0
+	     && strstr (name, "_c") != NULL) ? 1 : 0;
+    }
+  return rvc;
+}
+
 /* Relax AUIPC + JALR into JAL.  */
 
 static bool
@@ -4185,7 +4210,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec,
   bfd_vma foff = symval - (sec_addr (sec) + rel->r_offset);
   bool near_zero = (symval + RISCV_IMM_REACH / 2) < RISCV_IMM_REACH;
   bfd_vma auipc, jalr;
-  int rd, r_type, len = 4, rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
+  int rd, r_type, len = 4;
+  int rvc = _bfd_riscv_enable_rvc (abfd, rel + 1);
 
   /* If the call crosses section boundaries, an alignment directive could
      cause the PC-relative offset to later increase, so we need to add in the
@@ -4279,7 +4305,6 @@ _bfd_riscv_relax_lui (bfd *abfd,
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   bfd_vma gp = riscv_global_pointer_value (link_info);
-  int use_rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
 
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
 
@@ -4347,7 +4372,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
      account for this assuming page alignment at worst. In the presence of 
      RELRO segment the linker aligns it by one page size, therefore sections
      after the segment can be moved more than one page. */
-
+  int use_rvc = _bfd_riscv_enable_rvc (abfd, rel + 1);
   if (use_rvc
       && ELFNN_R_TYPE (rel->r_info) == R_RISCV_HI20
       && VALID_CITYPE_LUI_IMM (RISCV_CONST_HIGH_PART (symval))
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 99bd0a06d97..77a5e45392d 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -511,7 +511,8 @@ make_mapping_symbol (enum riscv_seg_mstate state,
   symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
   if (reset_seg_arch_str)
     {
-      /* Store current $x+arch into tc_segment_info.  */
+      /* Store current $x+arch into tc_segment_info, so that we can
+	 refer to the correct $x+arch for each R_RISCV_RELAX.  */
       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
       xfree ((void *) buff);
     }
@@ -1558,6 +1559,8 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 				  address_expr, false, reloc_type);
 
 	  ip->fixp->fx_tcbit = riscv_opts.relax;
+	  ip->fixp->tc_fix_data.arch_map_symbol =
+		seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
 	}
     }
 
@@ -3731,6 +3734,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   unsigned int subtype;
   bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
   bool relaxable = false;
+  bool rvc_relaxable = false;
   offsetT loc;
   segT sub_segment;
 
@@ -3747,6 +3751,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       if (fixP->fx_addsy == NULL)
 	fixP->fx_done = true;
       relaxable = true;
+      rvc_relaxable = true;
       break;
 
     case BFD_RELOC_RISCV_GOT_HI20:
@@ -3940,6 +3945,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RISCV_CALL:
     case BFD_RELOC_RISCV_CALL_PLT:
       relaxable = true;
+      rvc_relaxable = true;
       break;
 
     case BFD_RELOC_RISCV_PCREL_HI20:
@@ -3964,9 +3970,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
     {
       fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
-      fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
+      /* Currently only rvc relaxations need $x+arch.  */
+      fixP->fx_next->fx_addsy = (need_arch_map_symbol && rvc_relaxable)
+				? fixP->tc_fix_data.arch_map_symbol : NULL;
+      fixP->fx_next->fx_subsy = NULL;
       fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
       fixP->fx_next->fx_size = 0;
+      /* Set addend to zero.  */
+      fixP->fx_next->fx_offset = 0;
     }
 }
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 19c45ba2d12..333731c6120 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -152,6 +152,13 @@ struct riscv_frag_type
 #define TC_FRAG_INIT(fragp, max_bytes) riscv_init_frag (fragp, max_bytes)
 extern void riscv_init_frag (struct frag *, int);
 
+#define TC_FIX_TYPE struct riscv_fixup_type
+struct riscv_fixup_type
+{
+  symbolS *arch_map_symbol;
+};
+#define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data.arch_map_symbol = NULL)
+
 #define obj_adjust_symtab() riscv_adjust_symtab ()
 extern void riscv_adjust_symtab (void);
 
diff --git a/gas/testsuite/gas/riscv/mapping-relax.d b/gas/testsuite/gas/riscv/mapping-relax.d
new file mode 100644
index 00000000000..a12edba7ebf
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-relax.d
@@ -0,0 +1,23 @@
+#name:
+#source: mapping-relax.s
+#as:
+#readelf: -rW
+
+Relocation section '.rela.text' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_HI20[ 	]+[0-9a-f]+[ 	]+foo \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+[0-9a-f]+[ 	]+\$xrv32i2p1 \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_LO12_I[ 	]+[0-9a-f]+[ 	]+foo \+ 4
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+[0-9a-f]+[ 	]+\$xrv32i2p1 \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_TPREL_HI20[ 	]+[0-9a-f]+[ 	]+i \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_TPREL_ADD[ 	]+[0-9a-f]+[ 	]+i \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_TPREL_LO12_I[ 	]+[0-9a-f]+[ 	]+i \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_PCREL_HI20[ 	]+[0-9a-f]+[ 	]+foo \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_PCREL_LO12_I[ 	]+[0-9a-f]+[ 	]+L1 \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_CALL_PLT[ 	]+[0-9a-f]+[ 	]+foo \+ 0
+[0-9a-f]+[ 	]+[0-9a-f]+[ 	]+R_RISCV_RELAX[ 	]+[0-9a-f]+[ 	]+\$xrv32i2p1_c2p0 \+ 0
diff --git a/gas/testsuite/gas/riscv/mapping-relax.s b/gas/testsuite/gas/riscv/mapping-relax.s
new file mode 100644
index 00000000000..0fa7693a6bb
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-relax.s
@@ -0,0 +1,21 @@
+.attribute arch, "rv32i"
+.option relax
+foo:
+.align	2
+lui	a0, %hi (foo)
+addi	a0, a0, %lo (foo + 4)
+.option arch, +a
+lui	a0, %tprel_hi (i)
+add	a0, a0, tp, %tprel_add (i)
+lw	a1, %tprel_lo (i) (a0)
+.option arch, -a, +c
+L1: auipc	a0, %pcrel_hi (foo)
+addi	a0, a0, %pcrel_lo (L1)
+call	foo
+
+.globl	i
+.section .tbss, "awT", @nobits
+.type	i, @object
+.size	i, 4
+i:
+.zero	4
diff --git a/ld/testsuite/ld-riscv-elf/c-relax.d b/ld/testsuite/ld-riscv-elf/c-relax.d
new file mode 100644
index 00000000000..c0a5e611a8f
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/c-relax.d
@@ -0,0 +1,16 @@
+#source: c-relax.s
+#ld: --relax
+#objdump: -d -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+[0-9a-f]+ <_start>:
+.*:[ 	]+[0-9a-f]+[ 	]+lui[ 	]+.*
+.*:[ 	]+[0-9a-f]+[ 	]+addi[ 	]+.*
+.*:[ 	]+[0-9a-f]+[ 	]+c\.lui[ 	]+.*
+.*:[ 	]+[0-9a-f]+[ 	]+addi[ 	]+.*
+.*:[ 	]+[0-9a-f]+[ 	]+c\.j[ 	]+.*
+.*:[ 	]+[0-9a-f]+[ 	]+jal[ 	]+.*
diff --git a/ld/testsuite/ld-riscv-elf/c-relax.s b/ld/testsuite/ld-riscv-elf/c-relax.s
new file mode 100644
index 00000000000..80e52dea1c8
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/c-relax.s
@@ -0,0 +1,12 @@
+.option relax
+.option arch, -c
+.globl _start
+_start:
+lui	a0, %hi (_start)
+addi	a0, a0, %lo (_start)
+.option arch, +c
+lui	a0, %hi (_start)
+addi	a0, a0, %lo (_start)
+call	zero, _start
+.option arch, -c
+call	zero, _start
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index df89e0ee68b..684275508a5 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -125,6 +125,7 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "pcgp-relax-02"
     run_dump_test "c-lui"
     run_dump_test "c-lui-2"
+    run_dump_test "c-relax"
     run_dump_test "disas-jalr"
     run_dump_test "pcrel-lo-addend"
     run_dump_test "pcrel-lo-addend-2a"
-- 
2.37.0 (Apple Git-136)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-09-30  9:20 [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Nelson Chu
  2022-09-30  9:20 ` [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations Nelson Chu
@ 2022-10-03 11:17 ` Tsukasa OI
  2022-10-28  3:16 ` Nelson Chu
  2 siblings, 0 replies; 9+ messages in thread
From: Tsukasa OI @ 2022-10-03 11:17 UTC (permalink / raw)
  To: Nelson Chu, binutils

Hi Nelson,

Some minor behaviors were different than I assumed but they make sense.

This time, I could not find any easy examples to "break" or "confuse"
the assembler.  So, LGTM.

...except one line I describe below (I don't think this is your fault
but needs to be fixed).

Thanks,
Tsukasa

On 2022/09/30 18:20, Nelson Chu wrote:
> RISC-V Psabi pr196,
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
> 
> bfd/
>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
>     (riscv_copy_subset_list): Copy arch_str as well.
>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
> gas/
>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
>     architecture string in the subset_list.
>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
>     architecture string.
>     (s_riscv_option): Likewise.
>     (need_arch_map_symbol): New boolean, used to indicate if .option
>     directives do affect instructions.
>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
>     if reset_seg_arch_str is true.
>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
>     now, only add $x+arch if the architecture strings in subset list and segment
>     are different.  Besides, always add $x+arch at the start of section, and do
>     not add $x+arch for code alignment, since rvc for alignment can be judged
>     from addend of R_RISCV_ALIGN.
>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
>     same value, then remove the current $x only if the previous is $x+arch;
>     Otherwise, always remove previous.
>     (riscv_add_odd_padding_symbol): Updated.
>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
>     need_arch_map_symbol is false, so changed them to $x.
>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
>     (riscv_init_frag): Likewise.
>     (s_riscv_insn): Likewise.
>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
>     from riscv_subsets.
>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
>     symbol of each segment.
> 
>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
>     one file.
>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
>     does need any $x+arch.
>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
> opcodes/
>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
>     for some specfic code region.
>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
>     the architecture string once the ISA is different.
> ---
>  bfd/elfxx-riscv.c                             |   7 +
>  bfd/elfxx-riscv.h                             |   1 +
>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
>  gas/config/tc-riscv.h                         |   6 +-
>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
>  opcodes/riscv-dis.c                           |   9 +
>  27 files changed, 420 insertions(+), 328 deletions(-)
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c67d4167232..9247350c2c2 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
>      }
>  
>    subset_list->tail = NULL;
> +
> +  if (subset_list->arch_str != NULL)
> +    {
> +      free ((void*) subset_list->arch_str);
> +      subset_list->arch_str = NULL;
> +    }
>  }
>  
>  /* Parsing extension version.
> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
>  {
>    riscv_subset_list_t *new = xmalloc (sizeof *new);
>    new->head = riscv_copy_subset (new, subset_list->head);
> +  new->arch_str = strdup (subset_list->arch_str);
>    return new;
>  }
>  
> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> index ea7126bdb4d..e2c1e3c1618 100644
> --- a/bfd/elfxx-riscv.h
> +++ b/bfd/elfxx-riscv.h
> @@ -51,6 +51,7 @@ typedef struct
>  {
>    riscv_subset_t *head;
>    riscv_subset_t *tail;
> +  const char *arch_str;
>  } riscv_subset_list_t;
>  
>  extern void
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index d9f63b11398..99bd0a06d97 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
>    true,			/* check_unknown_prefixed_ext.  */
>  };
>  
> +/* Update the architecture string in the subset_list.  */
> +
> +static void
> +riscv_reset_subsets_list_arch_str (void)
> +{
> +  if (riscv_subsets->arch_str != NULL)
> +    free ((void *) riscv_subsets->arch_str);
> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
> +}
> +
>  /* This structure is used to hold a stack of .option values.  */
>  struct riscv_option_stack
>  {
> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
>        riscv_subsets = XNEW (riscv_subset_list_t);
>        riscv_subsets->head = NULL;
>        riscv_subsets->tail = NULL;
> +      riscv_subsets->arch_str = NULL;
>        riscv_rps_as.subset_list = riscv_subsets;
>      }
>    riscv_release_subset_list (riscv_subsets);
>    riscv_parse_subset (&riscv_rps_as, s);
> +  riscv_reset_subsets_list_arch_str ();
>  
>    riscv_set_rvc (false);
>    if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -459,21 +471,37 @@ static char *expr_end;
>  #define OPCODE_MATCHES(OPCODE, OP) \
>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
>  
> +/* Indicate if .option directives do affect instructions.  Set to true means
> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
> +   should be enough.  */
> +static bool need_arch_map_symbol = false;
> +
>  /* Create a new mapping symbol for the transition to STATE.  */
>  
>  static void
>  make_mapping_symbol (enum riscv_seg_mstate state,
>  		     valueT value,
> -		     fragS *frag)
> +		     fragS *frag,
> +		     bool reset_seg_arch_str)
>  {
>    const char *name;
> +  char *buff;

Change here to:
char *buff = NULL;

Yes, I know that.  But GCC 12 (on my Ubuntu 22.04 LTS) complains about
"maybe uninitialized" variable.  This is definitely a false positive but
"fails to build by default" is what I don't want to see.

>    switch (state)
>      {
>      case MAP_DATA:
>        name = "$d";
>        break;
>      case MAP_INSN:
> -      name = "$x";
> +      if (reset_seg_arch_str)
> +	{
> +	  const char *isa = riscv_subsets->arch_str;
> +	  size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
> +	  buff = xmalloc (size);
> +	  snprintf (buff, size, "$x%s", isa);
> +	  name = buff;
> +	}
> +      else
> +	name = "$x";
>        break;
>      default:
>        abort ();
> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>  
>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> +  if (reset_seg_arch_str)
> +    {
> +      /* Store current $x+arch into tc_segment_info.  */
> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
> +      xfree ((void *) buff);
> +    }
>  
>    /* If .fill or other data filling directive generates zero sized data,
> -     or we are adding odd alignemnts, then the mapping symbol for the
> -     following code will have the same value.  */
> +     then mapping symbol for the following code will have the same value.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
> +     and .text.zero.fill.last.  */
> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
>    if (value == 0)
>      {
> -       if (frag->tc_frag_data.first_map_symbol != NULL)
> +      if (first != NULL)
>  	{
> -	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> -		== S_GET_VALUE (symbol));
> +	  know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
> +		&& first == last);
>  	  /* Remove the old one.  */
> -	  symbol_remove (frag->tc_frag_data.first_map_symbol,
> -			 &symbol_rootP, &symbol_lastP);
> +	  symbol_remove (first, &symbol_rootP, &symbol_lastP);
>  	}
>        frag->tc_frag_data.first_map_symbol = symbol;
>      }
> -  if (frag->tc_frag_data.last_map_symbol != NULL)
> +  else if (last != NULL)
>      {
>        /* The mapping symbols should be added in offset order.  */
> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -			 <= S_GET_VALUE (symbol));
> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
>        /* Remove the old one.  */
> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -	  == S_GET_VALUE (symbol))
> -	symbol_remove (frag->tc_frag_data.last_map_symbol,
> -		       &symbol_rootP, &symbol_lastP);
> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
> +	symbol_remove (last, &symbol_rootP, &symbol_lastP);
>      }
>    frag->tc_frag_data.last_map_symbol = symbol;
>  }
> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>  
>  void
>  riscv_mapping_state (enum riscv_seg_mstate to_state,
> -		     int max_chars)
> +		     int max_chars,
> +		     bool frag_align_code)
>  {
>    enum riscv_seg_mstate from_state =
>  	seg_info (now_seg)->tc_segment_info_data.map_state;
> +  bool reset_seg_arch_str = false;
>  
>    if (!SEG_NORMAL (now_seg)
> -      /* For now I only add the mapping symbols to text sections.
> +      /* For now we only add the mapping symbols to text sections.
>  	 Therefore, the dis-assembler only show the actual contents
>  	 distribution for text.  Other sections will be shown as
>  	 data without the details.  */
> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
>      return;
>  
>    /* The mapping symbol should be emitted if not in the right
> -     mapping state  */
> -  if (from_state == to_state)
> +     mapping state.  */
> +  symbolS *seg_arch_symbol =
> +	seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
> +    {
> +      /* Always add $x+arch at the first instruction of section.  */
> +      reset_seg_arch_str = true;
> +    }
> +  else if (seg_arch_symbol != 0
> +	   && to_state == MAP_INSN
> +	   && !frag_align_code
> +	   && strcmp (riscv_subsets->arch_str,
> +		      S_GET_NAME (seg_arch_symbol) + 2) != 0)
> +    {
> +      reset_seg_arch_str = true;
> +      need_arch_map_symbol = true;
> +    }
> +  else if (from_state == to_state)
>      return;
>  
>    valueT value = (valueT) (frag_now_fix () - max_chars);
>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
> -  make_mapping_symbol (to_state, value, frag_now);
> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
>  }
>  
>  /* Add the odd bytes of paddings for riscv_handle_align.  */
> @@ -544,9 +596,27 @@ static void
>  riscv_add_odd_padding_symbol (fragS *frag)
>  {
>    /* If there was already a mapping symbol, it should be
> -     removed in the make_mapping_symbol.  */
> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
> +     removed in the make_mapping_symbol.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
> +}
> +
> +/* If previous and current mapping symbol have same value, then remove the
> +   current $x only if the previous is $x+arch; Otherwise, always remove the
> +   previous.  */
> +
> +static void
> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
> +{
> +  know (pre != NULL && cur != NULL
> +	&& S_GET_VALUE (pre) == S_GET_VALUE (cur));
> +  symbolS *removed = pre;
> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
> +    removed = cur;
> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
>  }
>  
>  /* Remove any excess mapping symbols generated for alignment frags in
> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>    if (seginfo == NULL || seginfo->frchainP == NULL)
>      return;
>  
> +  /* If we don't set any .option arch directive, then the arch_map_symbol
> +     in each segment must be the first instruction, and we don't need to
> +     add $x+arch for them.  */
> +  if (!need_arch_map_symbol
> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
> +
>    for (fragp = seginfo->frchainP->frch_root;
>         fragp != NULL;
>         fragp = fragp->fr_next)
> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>  
>        do
>  	{
> -	  if (next->tc_frag_data.first_map_symbol != NULL)
> +	  symbolS *next_first = next->tc_frag_data.first_map_symbol;
> +	  if (next_first != NULL)
>  	    {
>  	      /* The last mapping symbol overlaps with another one
> -		 which at the start of the next frag.  */
> -	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
> +		 which at the start of the next frag.
> +
> +		 Please see the gas/testsuite/gas/riscv/mapping.s:
> +		 .text.zero.fill.align.A and .text.zero.fill.align.B.  */
> +	      riscv_remove_mapping_symbol (last, next_first);
>  	      break;
>  	    }
>  
>  	  if (next->fr_next == NULL)
>  	    {
> -	      /* The last mapping symbol is at the end of the section.  */
> +	      /* The last mapping symbol is at the end of the section.
> +
> +		 Please see the gas/testsuite/gas/riscv/mapping.s:
> +		 .text.last.section.  */
>  	      know (next->fr_fix == 0 && next->fr_var == 0);
>  	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
>  	      break;
> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
>         return;
>      }
>  
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>  
>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>  						&imm_reloc, op_hash);
> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>    if (strcmp (name, "rvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "+c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (true);
>      }
>    else if (strcmp (name, "norvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "-c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (false);
>      }
>    else if (strcmp (name, "pic") == 0)
> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>        if (ISSPACE (*name) && *name != '\0')
>  	name++;
>        riscv_update_subset (&riscv_rps_as, name);
> +      riscv_reset_subsets_list_arch_str ();
>  
>        riscv_set_rvc (false);
>        if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
>    if (!riscv_opts.relax)
>      return false;
>  
> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
> +     rather than just use frag_more to handle an alignment here?  So that we
> +     don't need to call riscv_mapping_state again later, and then only need
> +     to check frag->fr_type to see if it is frag_align_code.  */
>    nops = frag_more (worst_case_bytes);
>  
>    ex.X_op = O_constant;
> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
>  	       &ex, false, BFD_RELOC_RISCV_ALIGN);
>  
> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
>  
>    /* We need to start a new frag after the alignment which may be removed by
>       the linker, to prevent the assembler from computing static offsets.
> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
>      case rs_fill:
>      case rs_align:
>      case rs_align_test:
> -      riscv_mapping_state (MAP_DATA, max_chars);
> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
>        break;
>      case rs_align_code:
> -      riscv_mapping_state (MAP_INSN, max_chars);
> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
>        break;
>      default:
>        break;
> @@ -4418,6 +4509,7 @@ void
>  riscv_elf_final_processing (void)
>  {
>    riscv_set_abi_by_arch ();
> +  riscv_release_subset_list (riscv_subsets);
>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
>  }
>  
> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>    save_c = *input_line_pointer;
>    *input_line_pointer = '\0';
>  
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>  
>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>  				&imm_reloc, insn_type_hash);
> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
>    unsigned int i;
>  
>    /* Re-write architecture elf attribute.  */
> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
> +  arch_str = riscv_subsets->arch_str;
>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
> -  xfree ((void *) arch_str);
>  
>    /* For the file without any instruction, we don't set the default_priv_spec
>       according to the privileged elf attributes since the md_assemble isn't
> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> index 802e7afe670..19c45ba2d12 100644
> --- a/gas/config/tc-riscv.h
> +++ b/gas/config/tc-riscv.h
> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
>  extern int riscv_convert_symbolic_attribute (const char *);
>  
>  /* Set mapping symbol states.  */
> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
> -void riscv_mapping_state (enum riscv_seg_mstate, int);
> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
>  
>  /* Define target segment type.  */
>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
>  struct riscv_segment_info_type
>  {
>    enum riscv_seg_mstate map_state;
> +  /* The current mapping symbol with architecture string.  */
> +  symbolS *arch_map_symbol;
>  };
>  
>  /* Define target fragment type.  */
> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> deleted file mode 100644
> index 989463f91ee..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01.s
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -	.option arch, -c
> -	.text
> -	.global	funcA
> -funcA:
> -	add	a0, a0, a0
> -	j	funcB
> -	.global	funcB
> -funcB:
> -	add	a1, a1, a1
> -	bne	a0, a1, funcB
> -
> -	.data
> -	.word 0x123456
> -
> -	.section	.foo, "ax"
> -foo:
> -	add	a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> deleted file mode 100644
> index 32e0027a13d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01a.d
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -#as:
> -#source: mapping-01.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$x
> -0+00 l    d  .foo	0+00 .foo
> -0+00 l       .foo	0+00 foo
> -0+00 l       .foo	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> -0+00 g       .text	0+00 funcA
> -0+08 g       .text	0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
> deleted file mode 100644
> index e84b3d608f5..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01b.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as:
> -#source: mapping-01.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <funcA>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
> -
> -0+008 <funcB>:
> -[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
> -
> -Disassembly of section .foo:
> -
> -0+000 <foo>:
> -[ 	]+0:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> deleted file mode 100644
> index 79468c0d14f..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02.s
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -	.option arch, -c
> -	.text
> -	.word	1
> -	add	a0, a0, a0
> -
> -	.data
> -	.word	2
> -
> -	.text
> -	add	a1, a1, a1
> -	.short	3
> -	add	a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> deleted file mode 100644
> index 333f12cd343..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-02.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$d
> -0+04 l       .text	0+00 \$x
> -0+0c l       .text	0+00 \$d
> -0+0e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> deleted file mode 100644
> index 1ed6c081cf7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02b.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as:
> -#source: mapping-02.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+4:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+c:[ 	]+0003[ 	]+.short[ 	]+0x0003
> -[ 	]+e:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> deleted file mode 100644
> index 88f2601568d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03.s
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -	.option arch, -c
> -	.text
> -	add	a0, a0, a0
> -	.long	0
> -	.balign	16
> -	.word	1
> -	add	a1, a1, a1
> -	.byte	2
> -	.long	3
> -	.balign	16
> -	.word	5
> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> deleted file mode 100644
> index d3663b663aa..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03a.d
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -#as:
> -#source: mapping-03.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$x
> -0+04 l       .text	0+00 \$d
> -0+08 l       .text	0+00 \$x
> -0+14 l       .text	0+00 \$d
> -0+18 l       .text	0+00 \$x
> -0+1c l       .text	0+00 \$d
> -0+21 l       .text	0+00 \$x
> -0+2d l       .text	0+00 \$d
> -0+31 l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
> deleted file mode 100644
> index f4f67269981..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as:
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> -[ 	]+10:[ 	]+00000013[ 	]+nop
> -[ 	]+14:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+18:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+1c:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
> -[ 	]+20:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+21:[ 	]+00000013[ 	]+nop
> -[ 	]+25:[ 	]+00000013[ 	]+nop
> -[ 	]+29:[ 	]+00000013[ 	]+nop
> -[ 	]+2d:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> deleted file mode 100644
> index 804b0397737..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04.s
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -	.text
> -	.option	arch, -c
> -	.fill	2, 4, 0x1001
> -	.byte	1
> -	.word	0
> -	.balign	8
> -	add	a0, a0, a0
> -	.fill	5, 2, 0x2002
> -	add	a1, a1, a1
> -
> -	.data
> -	.word	0x1
> -	.word	0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> deleted file mode 100644
> index 1ae9653212b..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-04.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$d
> -0+0d l       .text	0+00 \$x
> -0+15 l       .text	0+00 \$d
> -0+1f l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> deleted file mode 100644
> index 54bd0afb6c4..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -#as:
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+d:[ 	]+00000013[ 	]+nop
> -[ 	]+11:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+15:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+19:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+1d:[ 	]+2002[ 	]+.short[ 	]+0x2002
> -[ 	]+1f:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+23:[ 	]+0000[ 	]+.2byte[ 	]+0x0
> -[ 	]+25:[ 	]+0000[ 	]+.2byte[ 	]+0x0
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
> new file mode 100644
> index 00000000000..246f3672ade
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
> @@ -0,0 +1,84 @@
> +#as:
> +#source: mapping.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text.cross.section.A:
> +
> +0+000 <funcA>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+bffd[ 	]+j[ 	]+0 <funcA>
> +
> +Disassembly of section .text.corss.section.B:
> +
> +0+000 <funcB>:
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+fffff06f[ 	]+j[ 	]+0 <funcB>
> +
> +Disassembly of section .text.data:
> +
> +0+000 <.text.data>:
> +[ 	]+[0-9a-f]+:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+05000302[ 	]+.word[ 	]+0x05000302
> +
> +Disassembly of section .text.odd.align:
> +
> +0+000 <.text.odd.align>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+01[ 	]+.byte[ 	]+0x01
> +[ 	]+[0-9a-f]+:[ 	]+00[ 	]+.byte[ 	]+0x00
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +
> +Disassembly of section .text.zero.fill.first:
> +
> +0+000 <.text.zero.fill.first>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +
> +Disassembly of section .text.zero.fill.last:
> +
> +0+000 <.text.zero.fill.last>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.A:
> +
> +0+000 <.text.zero.fill.align.A>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.B:
> +
> +0+000 <.text.zero.fill.align.B>:
> +[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.last.section:
> +
> +0+000 <.text.last.section>:
> +[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +
> +Disassembly of section .text.section.padding:
> +
> +0+000 <.text.section.padding>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +
> +Disassembly of section .text.relax.align:
> +
> +0+000 <.text.relax.align>:
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
> new file mode 100644
> index 00000000000..f69e719ff30
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
> @@ -0,0 +1,17 @@
> +#as:
> +#source: mapping-non-arch.s
> +#objdump: --syms --special-syms
> +
> +.*file format.*riscv.*
> +
> +SYMBOL TABLE:
> +00+00 l    d  .text	00+00 .text
> +00+00 l    d  .data	00+00 .data
> +00+00 l    d  .bss	00+00 .bss
> +00+00 l       .text	00+00 \$x
> +00+08 l       .text	00+00 \$d
> +00+0c l       .text	00+00 \$x
> +00+00 l    d  text.A	00+00 text.A
> +00+00 l       text.A	00+00 \$x
> +00+02 l       text.A	00+00 \$d
> +00+00 l    d  .riscv.attributes	00+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
> new file mode 100644
> index 00000000000..03b2d75a5dd
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
> @@ -0,0 +1,11 @@
> +.attribute arch, "rv32i"
> +.option arch, +c
> +.text
> +addi	a0, zero, 1
> +.align 3
> +.word 0x1
> +addi	a0, zero, 2
> +
> +.section text.A, "ax"
> +addi	a0, zero, 3
> +.word 0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> deleted file mode 100644
> index 916f732b7f7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$x
> -0+04 l       .text	0+00 \$d
> -0+08 l       .text	0+00 \$x
> -0+10 l       .text	0+00 \$d
> -0+14 l       .text	0+00 \$x
> -0+18 l       .text	0+00 \$d
> -0+20 l       .text	0+00 \$d
> -0+24 l       .text	0+00 \$x
> -0+1d l       .text	0+00 \$d
> -0+1e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> deleted file mode 100644
> index 9e777351d1d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> -[ 	]+10:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+14:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+18:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
> -[ 	]+1c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+1d:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+1e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
> -[ 	]+20:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
> -[ 	]+24:[ 	]+00000013[ 	]+nop
> -[ 	]+28:[ 	]+00000013[ 	]+nop
> -[ 	]+2c:[ 	]+00000013[ 	]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> deleted file mode 100644
> index d552a7f632a..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text	0+00 .text
> -0+00 l    d  .data	0+00 .data
> -0+00 l    d  .bss	0+00 .bss
> -0+00 l       .text	0+00 \$d
> -0+14 l       .text	0+00 \$d
> -0+1e l       .text	0+00 \$x
> -0+0d l       .text	0+00 \$d
> -0+0e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> deleted file mode 100644
> index be668f29220..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+d:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
> -[ 	]+10:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+14:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+18:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+1c:[ 	]+2002[ 	]+.short[ 	]+0x2002
> -[ 	]+1e:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+22:[ 	]+0001[ 	]+.2byte[ 	]+0x1
> -[ 	]+24:[ 	]+00000013[ 	]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
> new file mode 100644
> index 00000000000..83ee6528b79
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
> @@ -0,0 +1,48 @@
> +#as:
> +#source: mapping.s
> +#objdump: --syms --special-syms
> +
> +.*file format.*riscv.*
> +
> +SYMBOL TABLE:
> +0+00 l    d  .text	0+00 .text
> +0+00 l    d  .data	0+00 .data
> +0+00 l    d  .bss	0+00 .bss
> +0+00 l    d  .text.cross.section.A	0+00 .text.cross.section.A
> +0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.corss.section.B	0+00 .text.corss.section.B
> +0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.corss.section.B	0+00 \$xrv32i2p1
> +0+00 l    d  .text.data	0+00 .text.data
> +0+00 l       .text.data	0+00 \$d
> +0+08 l       .text.data	0+00 \$xrv32i2p1_c2p0
> +0+0c l       .text.data	0+00 \$d
> +0+00 l    d  .text.odd.align	0+00 .text.odd.align
> +0+00 l       .text.odd.align	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.odd.align	0+00 \$d
> +0+08 l       .text.odd.align	0+00 \$xrv32i2p1
> +0+00 l    d  .text.zero.fill.first	0+00 .text.zero.fill.first
> +0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.last	0+00 .text.zero.fill.last
> +0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.zero.fill.last	0+00 \$x
> +0+00 l    d  .text.zero.fill.align.A	0+00 .text.zero.fill.align.A
> +0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.align.B	0+00 .text.zero.fill.align.B
> +0+00 l       .text.zero.fill.align.B	0+00 \$xrv32i2p1
> +0+00 l    d  .text.last.section	0+00 .text.last.section
> +0+00 l       .text.last.section	0+00 \$xrv32i2p1
> +0+04 l       .text.last.section	0+00 \$d
> +0+00 l    d  .text.section.padding	0+00 .text.section.padding
> +0+00 l       .text.section.padding	0+00 \$xrv32i2p1_c2p0
> +0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_c2p0
> +0+06 l       .text.section.padding	0+00 \$d
> +0+00 l    d  .text.relax.align	0+00 .text.relax.align
> +0+00 l       .text.relax.align	0+00 \$xrv32i2p1_c2p0
> +0+08 l       .text.relax.align	0+00 \$xrv32i2p1
> +0+0a l       .text.section.padding	0+00 \$x
> +0+03 l       .text.odd.align	0+00 \$d
> +0+04 l       .text.odd.align	0+00 \$x
> +0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> +0+00 g       .text.cross.section.A	0+00 funcA
> +0+00 g       .text.corss.section.B	0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
> new file mode 100644
> index 00000000000..a0e6c744107
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping.s
> @@ -0,0 +1,112 @@
> +.attribute arch, "rv32ic"
> +.option norelax			# FIXME: assembler fill the paddings after parsing everything,
> +				# so we probably won't fill anything for the norelax region when
> +				# the riscv_opts.relax is enabled at somewhere.
> +
> +.section .text.cross.section.A, "ax"
> +.option push
> +.global funcA
> +funcA:
> +addi	a0, zero, 1		# rv32i
> +.option arch, +c
> +j	funcA			# rv32ic
> +.section .text.corss.section.B, "ax"
> +.globl funcB
> +funcB:
> +addi	a0, zero, 2		# rv32ic, need to be added since start of section
> +.option arch, -c
> +j	funcB			# rv32i
> +.option pop
> +
> +.section .text.data, "ax"
> +.option push
> +.word	0			# $d
> +.long	1
> +addi	a0, zero, 1		# rv32ic
> +.data
> +.word	2			# don't add mapping symbols for non-text section
> +.section .text.data
> +addi	a0, zero, 2		# $x, but same as previous addi, so removed
> +.byte	2			# $d, dumped as .word
> +.short	3
> +.byte	5
> +.option pop
> +
> +.section .text.odd.align, "ax"
> +.option push
> +.option norelax
> +.option arch, +c
> +addi	a0, zero, 1		# $xrv32ic
> +.byte	1			# $d
> +.option arch, -c
> +.align	3			# odd alignment, $x replaced by $d + $x
> +addi	a0, zero, 2		# $xrv32i
> +.option pop
> +
> +.section .text.zero.fill.first, "ax"
> +.option push
> +.option norelax
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
> +addi	a0, zero, 1		# $xrv32ic
> +.option pop
> +
> +.section .text.zero.fill.last, "ax"
> +.option push
> +.option norelax
> +addi	a0, zero, 1		# $xrv32ic
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
> +addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.A, "ax"
> +.option push
> +.option norelax
> +.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +addi	a0, zero, 1		# $x, should be removed in riscv_check_mapping_symbols
> +addi	a0, zero, 2
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.B, "ax"
> +.option push
> +.option norelax
> +.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed,
> +				# but will be removed in riscv_check_mapping_symbols
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +.option arch, -c
> +addi	a0, zero, 1		# $xrv32i
> +addi	a0, zero, 2
> +.option pop
> +
> +.section .text.last.section, "ax"
> +.option push
> +.option norelax
> +.option arch, -c
> +addi	a0, zero, 1		# $xrv32i
> +.word	1			# $d
> +.align	2			# zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
> +.option pop
> +
> +.section .text.section.padding, "ax"
> +.option push
> +.option norelax
> +.align	2
> +addi	a0, zero, 1		# $rv32ic
> +.option arch, +a
> +.align	2			# 2-byte padding, $x, removed
> +addi	a0, zero, 2		# $xrv32iac
> +.word	1			# $d
> +.option pop			# 2-byte padding, $x
> +
> +.section .text.relax.align, "ax"
> +.option push
> +.option relax
> +.option arch, rv32ic
> +.balign	4			# $xrv32ic, add at the start of section
> +addi	a0, zero, 1		# $x, won't added
> +.option arch, -c
> +.align	3			# $x, won't added
> +addi	a0, zero, 2		# $xrv32i
> +.option pop
> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
> index aed4ca8e4d9..1d14c604dec 100644
> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
> @@ -10,5 +10,5 @@ Disassembly of section .text:
>  0+000 <.text>:
>  [ 	]+[0-9a-f]+:[  	]+952e[    	]+add[        	]+a0,a0,a1
>  [ 	]+[0-9a-f]+:[  	]+00b50533[    	]+add[        	]+a0,a0,a1
> -[ 	]+[0-9a-f]+:[  	]+00302573[    	]+csrr[        	]+a0,fcsr
> +[ 	]+[0-9a-f]+:[  	]+00302573[    	]+frcsr[        	]+a0
>  #...
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index f2d399260c1..eb88c81c0f1 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>        /* If arch has ZFINX flags, use gpr for disassemble.  */
>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
>  	riscv_fpr_names = riscv_gpr_names;
> +      else
> +	riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
> +			  riscv_fpr_names_abi : riscv_fpr_names_numeric;
>  
>        for (; op->name; op++)
>  	{
> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
>      *state = MAP_INSN;
>    else if (strcmp (name, "$d") == 0)
>      *state = MAP_DATA;
> +  else if (strncmp (name, "$xrv", 4) == 0)
> +    {
> +      *state = MAP_INSN;
> +      riscv_release_subset_list (&riscv_subsets);
> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
> +    }
>    else
>      return false;
>  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-09-30  9:20 [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Nelson Chu
  2022-09-30  9:20 ` [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations Nelson Chu
  2022-10-03 11:17 ` [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Tsukasa OI
@ 2022-10-28  3:16 ` Nelson Chu
  2022-10-28  7:01   ` Tsukasa OI
  2 siblings, 1 reply; 9+ messages in thread
From: Nelson Chu @ 2022-10-28  3:16 UTC (permalink / raw)
  To: binutils

Committed after passing the regression of riscv-gnu-toolchain.

Thanks
Nelson

On Fri, Sep 30, 2022 at 5:21 PM Nelson Chu <nelson@rivosinc.com> wrote:
>
> RISC-V Psabi pr196,
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
>
> bfd/
>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
>     (riscv_copy_subset_list): Copy arch_str as well.
>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
> gas/
>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
>     architecture string in the subset_list.
>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
>     architecture string.
>     (s_riscv_option): Likewise.
>     (need_arch_map_symbol): New boolean, used to indicate if .option
>     directives do affect instructions.
>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
>     if reset_seg_arch_str is true.
>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
>     now, only add $x+arch if the architecture strings in subset list and segment
>     are different.  Besides, always add $x+arch at the start of section, and do
>     not add $x+arch for code alignment, since rvc for alignment can be judged
>     from addend of R_RISCV_ALIGN.
>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
>     same value, then remove the current $x only if the previous is $x+arch;
>     Otherwise, always remove previous.
>     (riscv_add_odd_padding_symbol): Updated.
>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
>     need_arch_map_symbol is false, so changed them to $x.
>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
>     (riscv_init_frag): Likewise.
>     (s_riscv_insn): Likewise.
>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
>     from riscv_subsets.
>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
>     symbol of each segment.
>
>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
>     one file.
>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
>     does need any $x+arch.
>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
> opcodes/
>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
>     for some specfic code region.
>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
>     the architecture string once the ISA is different.
> ---
>  bfd/elfxx-riscv.c                             |   7 +
>  bfd/elfxx-riscv.h                             |   1 +
>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
>  gas/config/tc-riscv.h                         |   6 +-
>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
>  opcodes/riscv-dis.c                           |   9 +
>  27 files changed, 420 insertions(+), 328 deletions(-)
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c67d4167232..9247350c2c2 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
>      }
>
>    subset_list->tail = NULL;
> +
> +  if (subset_list->arch_str != NULL)
> +    {
> +      free ((void*) subset_list->arch_str);
> +      subset_list->arch_str = NULL;
> +    }
>  }
>
>  /* Parsing extension version.
> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
>  {
>    riscv_subset_list_t *new = xmalloc (sizeof *new);
>    new->head = riscv_copy_subset (new, subset_list->head);
> +  new->arch_str = strdup (subset_list->arch_str);
>    return new;
>  }
>
> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> index ea7126bdb4d..e2c1e3c1618 100644
> --- a/bfd/elfxx-riscv.h
> +++ b/bfd/elfxx-riscv.h
> @@ -51,6 +51,7 @@ typedef struct
>  {
>    riscv_subset_t *head;
>    riscv_subset_t *tail;
> +  const char *arch_str;
>  } riscv_subset_list_t;
>
>  extern void
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index d9f63b11398..99bd0a06d97 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
>    true,                        /* check_unknown_prefixed_ext.  */
>  };
>
> +/* Update the architecture string in the subset_list.  */
> +
> +static void
> +riscv_reset_subsets_list_arch_str (void)
> +{
> +  if (riscv_subsets->arch_str != NULL)
> +    free ((void *) riscv_subsets->arch_str);
> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
> +}
> +
>  /* This structure is used to hold a stack of .option values.  */
>  struct riscv_option_stack
>  {
> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
>        riscv_subsets = XNEW (riscv_subset_list_t);
>        riscv_subsets->head = NULL;
>        riscv_subsets->tail = NULL;
> +      riscv_subsets->arch_str = NULL;
>        riscv_rps_as.subset_list = riscv_subsets;
>      }
>    riscv_release_subset_list (riscv_subsets);
>    riscv_parse_subset (&riscv_rps_as, s);
> +  riscv_reset_subsets_list_arch_str ();
>
>    riscv_set_rvc (false);
>    if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -459,21 +471,37 @@ static char *expr_end;
>  #define OPCODE_MATCHES(OPCODE, OP) \
>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
>
> +/* Indicate if .option directives do affect instructions.  Set to true means
> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
> +   should be enough.  */
> +static bool need_arch_map_symbol = false;
> +
>  /* Create a new mapping symbol for the transition to STATE.  */
>
>  static void
>  make_mapping_symbol (enum riscv_seg_mstate state,
>                      valueT value,
> -                    fragS *frag)
> +                    fragS *frag,
> +                    bool reset_seg_arch_str)
>  {
>    const char *name;
> +  char *buff;
>    switch (state)
>      {
>      case MAP_DATA:
>        name = "$d";
>        break;
>      case MAP_INSN:
> -      name = "$x";
> +      if (reset_seg_arch_str)
> +       {
> +         const char *isa = riscv_subsets->arch_str;
> +         size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
> +         buff = xmalloc (size);
> +         snprintf (buff, size, "$x%s", isa);
> +         name = buff;
> +       }
> +      else
> +       name = "$x";
>        break;
>      default:
>        abort ();
> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>
>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> +  if (reset_seg_arch_str)
> +    {
> +      /* Store current $x+arch into tc_segment_info.  */
> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
> +      xfree ((void *) buff);
> +    }
>
>    /* If .fill or other data filling directive generates zero sized data,
> -     or we are adding odd alignemnts, then the mapping symbol for the
> -     following code will have the same value.  */
> +     then mapping symbol for the following code will have the same value.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
> +     and .text.zero.fill.last.  */
> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
>    if (value == 0)
>      {
> -       if (frag->tc_frag_data.first_map_symbol != NULL)
> +      if (first != NULL)
>         {
> -         know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> -               == S_GET_VALUE (symbol));
> +         know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
> +               && first == last);
>           /* Remove the old one.  */
> -         symbol_remove (frag->tc_frag_data.first_map_symbol,
> -                        &symbol_rootP, &symbol_lastP);
> +         symbol_remove (first, &symbol_rootP, &symbol_lastP);
>         }
>        frag->tc_frag_data.first_map_symbol = symbol;
>      }
> -  if (frag->tc_frag_data.last_map_symbol != NULL)
> +  else if (last != NULL)
>      {
>        /* The mapping symbols should be added in offset order.  */
> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -                        <= S_GET_VALUE (symbol));
> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
>        /* Remove the old one.  */
> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -         == S_GET_VALUE (symbol))
> -       symbol_remove (frag->tc_frag_data.last_map_symbol,
> -                      &symbol_rootP, &symbol_lastP);
> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
> +       symbol_remove (last, &symbol_rootP, &symbol_lastP);
>      }
>    frag->tc_frag_data.last_map_symbol = symbol;
>  }
> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>
>  void
>  riscv_mapping_state (enum riscv_seg_mstate to_state,
> -                    int max_chars)
> +                    int max_chars,
> +                    bool frag_align_code)
>  {
>    enum riscv_seg_mstate from_state =
>         seg_info (now_seg)->tc_segment_info_data.map_state;
> +  bool reset_seg_arch_str = false;
>
>    if (!SEG_NORMAL (now_seg)
> -      /* For now I only add the mapping symbols to text sections.
> +      /* For now we only add the mapping symbols to text sections.
>          Therefore, the dis-assembler only show the actual contents
>          distribution for text.  Other sections will be shown as
>          data without the details.  */
> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
>      return;
>
>    /* The mapping symbol should be emitted if not in the right
> -     mapping state  */
> -  if (from_state == to_state)
> +     mapping state.  */
> +  symbolS *seg_arch_symbol =
> +       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
> +    {
> +      /* Always add $x+arch at the first instruction of section.  */
> +      reset_seg_arch_str = true;
> +    }
> +  else if (seg_arch_symbol != 0
> +          && to_state == MAP_INSN
> +          && !frag_align_code
> +          && strcmp (riscv_subsets->arch_str,
> +                     S_GET_NAME (seg_arch_symbol) + 2) != 0)
> +    {
> +      reset_seg_arch_str = true;
> +      need_arch_map_symbol = true;
> +    }
> +  else if (from_state == to_state)
>      return;
>
>    valueT value = (valueT) (frag_now_fix () - max_chars);
>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
> -  make_mapping_symbol (to_state, value, frag_now);
> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
>  }
>
>  /* Add the odd bytes of paddings for riscv_handle_align.  */
> @@ -544,9 +596,27 @@ static void
>  riscv_add_odd_padding_symbol (fragS *frag)
>  {
>    /* If there was already a mapping symbol, it should be
> -     removed in the make_mapping_symbol.  */
> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
> +     removed in the make_mapping_symbol.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
> +}
> +
> +/* If previous and current mapping symbol have same value, then remove the
> +   current $x only if the previous is $x+arch; Otherwise, always remove the
> +   previous.  */
> +
> +static void
> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
> +{
> +  know (pre != NULL && cur != NULL
> +       && S_GET_VALUE (pre) == S_GET_VALUE (cur));
> +  symbolS *removed = pre;
> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
> +    removed = cur;
> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
>  }
>
>  /* Remove any excess mapping symbols generated for alignment frags in
> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>    if (seginfo == NULL || seginfo->frchainP == NULL)
>      return;
>
> +  /* If we don't set any .option arch directive, then the arch_map_symbol
> +     in each segment must be the first instruction, and we don't need to
> +     add $x+arch for them.  */
> +  if (!need_arch_map_symbol
> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
> +
>    for (fragp = seginfo->frchainP->frch_root;
>         fragp != NULL;
>         fragp = fragp->fr_next)
> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>
>        do
>         {
> -         if (next->tc_frag_data.first_map_symbol != NULL)
> +         symbolS *next_first = next->tc_frag_data.first_map_symbol;
> +         if (next_first != NULL)
>             {
>               /* The last mapping symbol overlaps with another one
> -                which at the start of the next frag.  */
> -             symbol_remove (last, &symbol_rootP, &symbol_lastP);
> +                which at the start of the next frag.
> +
> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> +                .text.zero.fill.align.A and .text.zero.fill.align.B.  */
> +             riscv_remove_mapping_symbol (last, next_first);
>               break;
>             }
>
>           if (next->fr_next == NULL)
>             {
> -             /* The last mapping symbol is at the end of the section.  */
> +             /* The last mapping symbol is at the end of the section.
> +
> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> +                .text.last.section.  */
>               know (next->fr_fix == 0 && next->fr_var == 0);
>               symbol_remove (last, &symbol_rootP, &symbol_lastP);
>               break;
> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
>         return;
>      }
>
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>
>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>                                                 &imm_reloc, op_hash);
> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>    if (strcmp (name, "rvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "+c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (true);
>      }
>    else if (strcmp (name, "norvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "-c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (false);
>      }
>    else if (strcmp (name, "pic") == 0)
> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>        if (ISSPACE (*name) && *name != '\0')
>         name++;
>        riscv_update_subset (&riscv_rps_as, name);
> +      riscv_reset_subsets_list_arch_str ();
>
>        riscv_set_rvc (false);
>        if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
>    if (!riscv_opts.relax)
>      return false;
>
> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
> +     rather than just use frag_more to handle an alignment here?  So that we
> +     don't need to call riscv_mapping_state again later, and then only need
> +     to check frag->fr_type to see if it is frag_align_code.  */
>    nops = frag_more (worst_case_bytes);
>
>    ex.X_op = O_constant;
> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
>                &ex, false, BFD_RELOC_RISCV_ALIGN);
>
> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
>
>    /* We need to start a new frag after the alignment which may be removed by
>       the linker, to prevent the assembler from computing static offsets.
> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
>      case rs_fill:
>      case rs_align:
>      case rs_align_test:
> -      riscv_mapping_state (MAP_DATA, max_chars);
> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
>        break;
>      case rs_align_code:
> -      riscv_mapping_state (MAP_INSN, max_chars);
> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
>        break;
>      default:
>        break;
> @@ -4418,6 +4509,7 @@ void
>  riscv_elf_final_processing (void)
>  {
>    riscv_set_abi_by_arch ();
> +  riscv_release_subset_list (riscv_subsets);
>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
>  }
>
> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>    save_c = *input_line_pointer;
>    *input_line_pointer = '\0';
>
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>
>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>                                 &imm_reloc, insn_type_hash);
> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
>    unsigned int i;
>
>    /* Re-write architecture elf attribute.  */
> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
> +  arch_str = riscv_subsets->arch_str;
>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
> -  xfree ((void *) arch_str);
>
>    /* For the file without any instruction, we don't set the default_priv_spec
>       according to the privileged elf attributes since the md_assemble isn't
> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> index 802e7afe670..19c45ba2d12 100644
> --- a/gas/config/tc-riscv.h
> +++ b/gas/config/tc-riscv.h
> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
>  extern int riscv_convert_symbolic_attribute (const char *);
>
>  /* Set mapping symbol states.  */
> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
> -void riscv_mapping_state (enum riscv_seg_mstate, int);
> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
>
>  /* Define target segment type.  */
>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
>  struct riscv_segment_info_type
>  {
>    enum riscv_seg_mstate map_state;
> +  /* The current mapping symbol with architecture string.  */
> +  symbolS *arch_map_symbol;
>  };
>
>  /* Define target fragment type.  */
> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> deleted file mode 100644
> index 989463f91ee..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01.s
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -       .option arch, -c
> -       .text
> -       .global funcA
> -funcA:
> -       add     a0, a0, a0
> -       j       funcB
> -       .global funcB
> -funcB:
> -       add     a1, a1, a1
> -       bne     a0, a1, funcB
> -
> -       .data
> -       .word 0x123456
> -
> -       .section        .foo, "ax"
> -foo:
> -       add     a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> deleted file mode 100644
> index 32e0027a13d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01a.d
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -#as:
> -#source: mapping-01.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$x
> -0+00 l    d  .foo      0+00 .foo
> -0+00 l       .foo      0+00 foo
> -0+00 l       .foo      0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> -0+00 g       .text     0+00 funcA
> -0+08 g       .text     0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
> deleted file mode 100644
> index e84b3d608f5..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01b.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as:
> -#source: mapping-01.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <funcA>:
> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+4:[   ]+0040006f[     ]+j[    ]+8 <funcB>
> -
> -0+008 <funcB>:
> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+c:[   ]+feb51ee3[     ]+bne[  ]+a0,a1,8 <funcB>
> -
> -Disassembly of section .foo:
> -
> -0+000 <foo>:
> -[      ]+0:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> deleted file mode 100644
> index 79468c0d14f..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02.s
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -       .option arch, -c
> -       .text
> -       .word   1
> -       add     a0, a0, a0
> -
> -       .data
> -       .word   2
> -
> -       .text
> -       add     a1, a1, a1
> -       .short  3
> -       add     a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> deleted file mode 100644
> index 333f12cd343..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-02.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$d
> -0+04 l       .text     0+00 \$x
> -0+0c l       .text     0+00 \$d
> -0+0e l       .text     0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> deleted file mode 100644
> index 1ed6c081cf7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02b.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as:
> -#source: mapping-02.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[      ]+0:[   ]+00000001[     ]+.word[        ]+0x00000001
> -[      ]+4:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+c:[   ]+0003[         ]+.short[       ]+0x0003
> -[      ]+e:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> deleted file mode 100644
> index 88f2601568d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03.s
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -       .option arch, -c
> -       .text
> -       add     a0, a0, a0
> -       .long   0
> -       .balign 16
> -       .word   1
> -       add     a1, a1, a1
> -       .byte   2
> -       .long   3
> -       .balign 16
> -       .word   5
> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> deleted file mode 100644
> index d3663b663aa..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03a.d
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -#as:
> -#source: mapping-03.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$x
> -0+04 l       .text     0+00 \$d
> -0+08 l       .text     0+00 \$x
> -0+14 l       .text     0+00 \$d
> -0+18 l       .text     0+00 \$x
> -0+1c l       .text     0+00 \$d
> -0+21 l       .text     0+00 \$x
> -0+2d l       .text     0+00 \$d
> -0+31 l       .text     0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
> deleted file mode 100644
> index f4f67269981..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as:
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> -[      ]+8:[   ]+00000013[     ]+nop
> -[      ]+c:[   ]+00000013[     ]+nop
> -[      ]+10:[  ]+00000013[     ]+nop
> -[      ]+14:[  ]+00000001[     ]+.word[        ]+0x00000001
> -[      ]+18:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+1c:[  ]+00000302[     ]+.word[        ]+0x00000302
> -[      ]+20:[  ]+00[   ]+.byte[        ]+0x00
> -[      ]+21:[  ]+00000013[     ]+nop
> -[      ]+25:[  ]+00000013[     ]+nop
> -[      ]+29:[  ]+00000013[     ]+nop
> -[      ]+2d:[  ]+00000005[     ]+.word[        ]+0x00000005
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> deleted file mode 100644
> index 804b0397737..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04.s
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -       .text
> -       .option arch, -c
> -       .fill   2, 4, 0x1001
> -       .byte   1
> -       .word   0
> -       .balign 8
> -       add     a0, a0, a0
> -       .fill   5, 2, 0x2002
> -       add     a1, a1, a1
> -
> -       .data
> -       .word   0x1
> -       .word   0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> deleted file mode 100644
> index 1ae9653212b..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-04.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$d
> -0+0d l       .text     0+00 \$x
> -0+15 l       .text     0+00 \$d
> -0+1f l       .text     0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> deleted file mode 100644
> index 54bd0afb6c4..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -#as:
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> -[      ]+d:[   ]+00000013[     ]+nop
> -[      ]+11:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+15:[  ]+20022002[     ]+.word[        ]+0x20022002
> -[      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
> -[      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
> -[      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
> -[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
> new file mode 100644
> index 00000000000..246f3672ade
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
> @@ -0,0 +1,84 @@
> +#as:
> +#source: mapping.s
> +#objdump: -d
> +
> +.*:[   ]+file format .*
> +
> +
> +Disassembly of section .text.cross.section.A:
> +
> +0+000 <funcA>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+bffd[         ]+j[    ]+0 <funcA>
> +
> +Disassembly of section .text.corss.section.B:
> +
> +0+000 <funcB>:
> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> +[      ]+[0-9a-f]+:[   ]+fffff06f[     ]+j[    ]+0 <funcB>
> +
> +Disassembly of section .text.data:
> +
> +0+000 <.text.data>:
> +[      ]+[0-9a-f]+:[   ]+00000000[     ]+.word[        ]+0x00000000
> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> +[      ]+[0-9a-f]+:[   ]+05000302[     ]+.word[        ]+0x05000302
> +
> +Disassembly of section .text.odd.align:
> +
> +0+000 <.text.odd.align>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+01[   ]+.byte[        ]+0x01
> +[      ]+[0-9a-f]+:[   ]+00[   ]+.byte[        ]+0x00
> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> +
> +Disassembly of section .text.zero.fill.first:
> +
> +0+000 <.text.zero.fill.first>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +
> +Disassembly of section .text.zero.fill.last:
> +
> +0+000 <.text.zero.fill.last>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.A:
> +
> +0+000 <.text.zero.fill.align.A>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.B:
> +
> +0+000 <.text.zero.fill.align.B>:
> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> +
> +Disassembly of section .text.last.section:
> +
> +0+000 <.text.last.section>:
> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> +
> +Disassembly of section .text.section.padding:
> +
> +0+000 <.text.section.padding>:
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> +
> +Disassembly of section .text.relax.align:
> +
> +0+000 <.text.relax.align>:
> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
> new file mode 100644
> index 00000000000..f69e719ff30
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
> @@ -0,0 +1,17 @@
> +#as:
> +#source: mapping-non-arch.s
> +#objdump: --syms --special-syms
> +
> +.*file format.*riscv.*
> +
> +SYMBOL TABLE:
> +00+00 l    d  .text    00+00 .text
> +00+00 l    d  .data    00+00 .data
> +00+00 l    d  .bss     00+00 .bss
> +00+00 l       .text    00+00 \$x
> +00+08 l       .text    00+00 \$d
> +00+0c l       .text    00+00 \$x
> +00+00 l    d  text.A   00+00 text.A
> +00+00 l       text.A   00+00 \$x
> +00+02 l       text.A   00+00 \$d
> +00+00 l    d  .riscv.attributes        00+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
> new file mode 100644
> index 00000000000..03b2d75a5dd
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
> @@ -0,0 +1,11 @@
> +.attribute arch, "rv32i"
> +.option arch, +c
> +.text
> +addi   a0, zero, 1
> +.align 3
> +.word 0x1
> +addi   a0, zero, 2
> +
> +.section text.A, "ax"
> +addi   a0, zero, 3
> +.word 0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> deleted file mode 100644
> index 916f732b7f7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$x
> -0+04 l       .text     0+00 \$d
> -0+08 l       .text     0+00 \$x
> -0+10 l       .text     0+00 \$d
> -0+14 l       .text     0+00 \$x
> -0+18 l       .text     0+00 \$d
> -0+20 l       .text     0+00 \$d
> -0+24 l       .text     0+00 \$x
> -0+1d l       .text     0+00 \$d
> -0+1e l       .text     0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> deleted file mode 100644
> index 9e777351d1d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> -[      ]+8:[   ]+00000013[     ]+nop
> -[      ]+c:[   ]+00000013[     ]+nop
> -[      ]+10:[  ]+00000001[     ]+.word[        ]+0x00000001
> -[      ]+14:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
> -[      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
> -[      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
> -[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
> -[      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
> -[      ]+24:[  ]+00000013[     ]+nop
> -[      ]+28:[  ]+00000013[     ]+nop
> -[      ]+2c:[  ]+00000013[     ]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> deleted file mode 100644
> index d552a7f632a..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.s
> -#objdump: --syms --special-syms
> -
> -.*file format.*riscv.*
> -
> -SYMBOL TABLE:
> -0+00 l    d  .text     0+00 .text
> -0+00 l    d  .data     0+00 .data
> -0+00 l    d  .bss      0+00 .bss
> -0+00 l       .text     0+00 \$d
> -0+14 l       .text     0+00 \$d
> -0+1e l       .text     0+00 \$x
> -0+0d l       .text     0+00 \$d
> -0+0e l       .text     0+00 \$x
> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> deleted file mode 100644
> index be668f29220..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[   ]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> -[      ]+d:[   ]+00[   ]+.byte[        ]+0x00
> -[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
> -[      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> -[      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
> -[      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
> -[      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
> -[      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
> -[      ]+24:[  ]+00000013[     ]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
> new file mode 100644
> index 00000000000..83ee6528b79
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
> @@ -0,0 +1,48 @@
> +#as:
> +#source: mapping.s
> +#objdump: --syms --special-syms
> +
> +.*file format.*riscv.*
> +
> +SYMBOL TABLE:
> +0+00 l    d  .text     0+00 .text
> +0+00 l    d  .data     0+00 .data
> +0+00 l    d  .bss      0+00 .bss
> +0+00 l    d  .text.cross.section.A     0+00 .text.cross.section.A
> +0+00 l       .text.cross.section.A     0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.corss.section.B     0+00 .text.corss.section.B
> +0+00 l       .text.corss.section.B     0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.corss.section.B     0+00 \$xrv32i2p1
> +0+00 l    d  .text.data        0+00 .text.data
> +0+00 l       .text.data        0+00 \$d
> +0+08 l       .text.data        0+00 \$xrv32i2p1_c2p0
> +0+0c l       .text.data        0+00 \$d
> +0+00 l    d  .text.odd.align   0+00 .text.odd.align
> +0+00 l       .text.odd.align   0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.odd.align   0+00 \$d
> +0+08 l       .text.odd.align   0+00 \$xrv32i2p1
> +0+00 l    d  .text.zero.fill.first     0+00 .text.zero.fill.first
> +0+00 l       .text.zero.fill.first     0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.last      0+00 .text.zero.fill.last
> +0+00 l       .text.zero.fill.last      0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.zero.fill.last      0+00 \$x
> +0+00 l    d  .text.zero.fill.align.A   0+00 .text.zero.fill.align.A
> +0+00 l       .text.zero.fill.align.A   0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.align.B   0+00 .text.zero.fill.align.B
> +0+00 l       .text.zero.fill.align.B   0+00 \$xrv32i2p1
> +0+00 l    d  .text.last.section        0+00 .text.last.section
> +0+00 l       .text.last.section        0+00 \$xrv32i2p1
> +0+04 l       .text.last.section        0+00 \$d
> +0+00 l    d  .text.section.padding     0+00 .text.section.padding
> +0+00 l       .text.section.padding     0+00 \$xrv32i2p1_c2p0
> +0+04 l       .text.section.padding     0+00 \$xrv32i2p1_a2p1_c2p0
> +0+06 l       .text.section.padding     0+00 \$d
> +0+00 l    d  .text.relax.align 0+00 .text.relax.align
> +0+00 l       .text.relax.align 0+00 \$xrv32i2p1_c2p0
> +0+08 l       .text.relax.align 0+00 \$xrv32i2p1
> +0+0a l       .text.section.padding     0+00 \$x
> +0+03 l       .text.odd.align   0+00 \$d
> +0+04 l       .text.odd.align   0+00 \$x
> +0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> +0+00 g       .text.cross.section.A     0+00 funcA
> +0+00 g       .text.corss.section.B     0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
> new file mode 100644
> index 00000000000..a0e6c744107
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping.s
> @@ -0,0 +1,112 @@
> +.attribute arch, "rv32ic"
> +.option norelax                        # FIXME: assembler fill the paddings after parsing everything,
> +                               # so we probably won't fill anything for the norelax region when
> +                               # the riscv_opts.relax is enabled at somewhere.
> +
> +.section .text.cross.section.A, "ax"
> +.option push
> +.global funcA
> +funcA:
> +addi   a0, zero, 1             # rv32i
> +.option arch, +c
> +j      funcA                   # rv32ic
> +.section .text.corss.section.B, "ax"
> +.globl funcB
> +funcB:
> +addi   a0, zero, 2             # rv32ic, need to be added since start of section
> +.option arch, -c
> +j      funcB                   # rv32i
> +.option pop
> +
> +.section .text.data, "ax"
> +.option push
> +.word  0                       # $d
> +.long  1
> +addi   a0, zero, 1             # rv32ic
> +.data
> +.word  2                       # don't add mapping symbols for non-text section
> +.section .text.data
> +addi   a0, zero, 2             # $x, but same as previous addi, so removed
> +.byte  2                       # $d, dumped as .word
> +.short 3
> +.byte  5
> +.option pop
> +
> +.section .text.odd.align, "ax"
> +.option push
> +.option norelax
> +.option arch, +c
> +addi   a0, zero, 1             # $xrv32ic
> +.byte  1                       # $d
> +.option arch, -c
> +.align 3                       # odd alignment, $x replaced by $d + $x
> +addi   a0, zero, 2             # $xrv32i
> +.option pop
> +
> +.section .text.zero.fill.first, "ax"
> +.option push
> +.option norelax
> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> +addi   a0, zero, 1             # $xrv32ic
> +.option pop
> +
> +.section .text.zero.fill.last, "ax"
> +.option push
> +.option norelax
> +addi   a0, zero, 1             # $xrv32ic
> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> +addi   a0, zero, 2             # $x, FIXME: need find a way to remove?
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.A, "ax"
> +.option push
> +.option norelax
> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed
> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +addi   a0, zero, 1             # $x, should be removed in riscv_check_mapping_symbols
> +addi   a0, zero, 2
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.B, "ax"
> +.option push
> +.option norelax
> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
> +                               # but will be removed in riscv_check_mapping_symbols
> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +.option arch, -c
> +addi   a0, zero, 1             # $xrv32i
> +addi   a0, zero, 2
> +.option pop
> +
> +.section .text.last.section, "ax"
> +.option push
> +.option norelax
> +.option arch, -c
> +addi   a0, zero, 1             # $xrv32i
> +.word  1                       # $d
> +.align 2                       # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
> +.option pop
> +
> +.section .text.section.padding, "ax"
> +.option push
> +.option norelax
> +.align 2
> +addi   a0, zero, 1             # $rv32ic
> +.option arch, +a
> +.align 2                       # 2-byte padding, $x, removed
> +addi   a0, zero, 2             # $xrv32iac
> +.word  1                       # $d
> +.option pop                    # 2-byte padding, $x
> +
> +.section .text.relax.align, "ax"
> +.option push
> +.option relax
> +.option arch, rv32ic
> +.balign        4                       # $xrv32ic, add at the start of section
> +addi   a0, zero, 1             # $x, won't added
> +.option arch, -c
> +.align 3                       # $x, won't added
> +addi   a0, zero, 2             # $xrv32i
> +.option pop
> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
> index aed4ca8e4d9..1d14c604dec 100644
> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
> @@ -10,5 +10,5 @@ Disassembly of section .text:
>  0+000 <.text>:
>  [      ]+[0-9a-f]+:[   ]+952e[         ]+add[          ]+a0,a0,a1
>  [      ]+[0-9a-f]+:[   ]+00b50533[     ]+add[          ]+a0,a0,a1
> -[      ]+[0-9a-f]+:[   ]+00302573[     ]+csrr[         ]+a0,fcsr
> +[      ]+[0-9a-f]+:[   ]+00302573[     ]+frcsr[                ]+a0
>  #...
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index f2d399260c1..eb88c81c0f1 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>        /* If arch has ZFINX flags, use gpr for disassemble.  */
>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
>         riscv_fpr_names = riscv_gpr_names;
> +      else
> +       riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
> +                         riscv_fpr_names_abi : riscv_fpr_names_numeric;
>
>        for (; op->name; op++)
>         {
> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
>      *state = MAP_INSN;
>    else if (strcmp (name, "$d") == 0)
>      *state = MAP_DATA;
> +  else if (strncmp (name, "$xrv", 4) == 0)
> +    {
> +      *state = MAP_INSN;
> +      riscv_release_subset_list (&riscv_subsets);
> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
> +    }
>    else
>      return false;
>
> --
> 2.37.0 (Apple Git-136)
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-10-28  3:16 ` Nelson Chu
@ 2022-10-28  7:01   ` Tsukasa OI
  2022-10-28  7:10     ` Kito Cheng
  0 siblings, 1 reply; 9+ messages in thread
From: Tsukasa OI @ 2022-10-28  7:01 UTC (permalink / raw)
  To: Nelson Chu, Binutils, Tsukasa OI

On 2022/10/28 12:16, Nelson Chu wrote:
> Committed after passing the regression of riscv-gnu-toolchain.
> 
> Thanks
> Nelson

That's great!  My upcoming disassembler optimization heavily depended on
whether this proposal is merged or not.  So, I'm finally ready to submit
next part (small optimizations + core RISC-V disassembler reorganization
for 2 larger optimizations).

One thing I have to point out (again) is, it fails to build on my
environment (caused by a false positive of GCC's "maybe uninitialized"
variable detection).  I have submitted separate patch for it:

<https://sourceware.org/pipermail/binutils/2022-October/123952.html>

Thanks,
Tsukasa

> 
> On Fri, Sep 30, 2022 at 5:21 PM Nelson Chu <nelson@rivosinc.com> wrote:
>>
>> RISC-V Psabi pr196,
>> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
>>
>> bfd/
>>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
>>     (riscv_copy_subset_list): Copy arch_str as well.
>>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
>> gas/
>>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
>>     architecture string in the subset_list.
>>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
>>     architecture string.
>>     (s_riscv_option): Likewise.
>>     (need_arch_map_symbol): New boolean, used to indicate if .option
>>     directives do affect instructions.
>>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
>>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
>>     if reset_seg_arch_str is true.
>>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
>>     now, only add $x+arch if the architecture strings in subset list and segment
>>     are different.  Besides, always add $x+arch at the start of section, and do
>>     not add $x+arch for code alignment, since rvc for alignment can be judged
>>     from addend of R_RISCV_ALIGN.
>>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
>>     same value, then remove the current $x only if the previous is $x+arch;
>>     Otherwise, always remove previous.
>>     (riscv_add_odd_padding_symbol): Updated.
>>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
>>     need_arch_map_symbol is false, so changed them to $x.
>>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
>>     (riscv_init_frag): Likewise.
>>     (s_riscv_insn): Likewise.
>>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
>>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
>>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
>>     from riscv_subsets.
>>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
>>     symbol of each segment.
>>
>>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
>>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
>>     one file.
>>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
>>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
>>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
>>     does need any $x+arch.
>>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
>>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
>> opcodes/
>>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
>>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
>>     for some specfic code region.
>>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
>>     the architecture string once the ISA is different.
>> ---
>>  bfd/elfxx-riscv.c                             |   7 +
>>  bfd/elfxx-riscv.h                             |   1 +
>>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
>>  gas/config/tc-riscv.h                         |   6 +-
>>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
>>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
>>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
>>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
>>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
>>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
>>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
>>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
>>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
>>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
>>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
>>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
>>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
>>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
>>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
>>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
>>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
>>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
>>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
>>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
>>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
>>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
>>  opcodes/riscv-dis.c                           |   9 +
>>  27 files changed, 420 insertions(+), 328 deletions(-)
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
>>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
>>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
>>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
>>
>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>> index c67d4167232..9247350c2c2 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
>>      }
>>
>>    subset_list->tail = NULL;
>> +
>> +  if (subset_list->arch_str != NULL)
>> +    {
>> +      free ((void*) subset_list->arch_str);
>> +      subset_list->arch_str = NULL;
>> +    }
>>  }
>>
>>  /* Parsing extension version.
>> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
>>  {
>>    riscv_subset_list_t *new = xmalloc (sizeof *new);
>>    new->head = riscv_copy_subset (new, subset_list->head);
>> +  new->arch_str = strdup (subset_list->arch_str);
>>    return new;
>>  }
>>
>> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
>> index ea7126bdb4d..e2c1e3c1618 100644
>> --- a/bfd/elfxx-riscv.h
>> +++ b/bfd/elfxx-riscv.h
>> @@ -51,6 +51,7 @@ typedef struct
>>  {
>>    riscv_subset_t *head;
>>    riscv_subset_t *tail;
>> +  const char *arch_str;
>>  } riscv_subset_list_t;
>>
>>  extern void
>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>> index d9f63b11398..99bd0a06d97 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
>>    true,                        /* check_unknown_prefixed_ext.  */
>>  };
>>
>> +/* Update the architecture string in the subset_list.  */
>> +
>> +static void
>> +riscv_reset_subsets_list_arch_str (void)
>> +{
>> +  if (riscv_subsets->arch_str != NULL)
>> +    free ((void *) riscv_subsets->arch_str);
>> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
>> +}
>> +
>>  /* This structure is used to hold a stack of .option values.  */
>>  struct riscv_option_stack
>>  {
>> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
>>        riscv_subsets = XNEW (riscv_subset_list_t);
>>        riscv_subsets->head = NULL;
>>        riscv_subsets->tail = NULL;
>> +      riscv_subsets->arch_str = NULL;
>>        riscv_rps_as.subset_list = riscv_subsets;
>>      }
>>    riscv_release_subset_list (riscv_subsets);
>>    riscv_parse_subset (&riscv_rps_as, s);
>> +  riscv_reset_subsets_list_arch_str ();
>>
>>    riscv_set_rvc (false);
>>    if (riscv_subset_supports (&riscv_rps_as, "c"))
>> @@ -459,21 +471,37 @@ static char *expr_end;
>>  #define OPCODE_MATCHES(OPCODE, OP) \
>>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
>>
>> +/* Indicate if .option directives do affect instructions.  Set to true means
>> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
>> +   should be enough.  */
>> +static bool need_arch_map_symbol = false;
>> +
>>  /* Create a new mapping symbol for the transition to STATE.  */
>>
>>  static void
>>  make_mapping_symbol (enum riscv_seg_mstate state,
>>                      valueT value,
>> -                    fragS *frag)
>> +                    fragS *frag,
>> +                    bool reset_seg_arch_str)
>>  {
>>    const char *name;
>> +  char *buff;
>>    switch (state)
>>      {
>>      case MAP_DATA:
>>        name = "$d";
>>        break;
>>      case MAP_INSN:
>> -      name = "$x";
>> +      if (reset_seg_arch_str)
>> +       {
>> +         const char *isa = riscv_subsets->arch_str;
>> +         size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
>> +         buff = xmalloc (size);
>> +         snprintf (buff, size, "$x%s", isa);
>> +         name = buff;
>> +       }
>> +      else
>> +       name = "$x";
>>        break;
>>      default:
>>        abort ();
>> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>>
>>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
>>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
>> +  if (reset_seg_arch_str)
>> +    {
>> +      /* Store current $x+arch into tc_segment_info.  */
>> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
>> +      xfree ((void *) buff);
>> +    }
>>
>>    /* If .fill or other data filling directive generates zero sized data,
>> -     or we are adding odd alignemnts, then the mapping symbol for the
>> -     following code will have the same value.  */
>> +     then mapping symbol for the following code will have the same value.
>> +
>> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
>> +     and .text.zero.fill.last.  */
>> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
>> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
>>    if (value == 0)
>>      {
>> -       if (frag->tc_frag_data.first_map_symbol != NULL)
>> +      if (first != NULL)
>>         {
>> -         know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
>> -               == S_GET_VALUE (symbol));
>> +         know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
>> +               && first == last);
>>           /* Remove the old one.  */
>> -         symbol_remove (frag->tc_frag_data.first_map_symbol,
>> -                        &symbol_rootP, &symbol_lastP);
>> +         symbol_remove (first, &symbol_rootP, &symbol_lastP);
>>         }
>>        frag->tc_frag_data.first_map_symbol = symbol;
>>      }
>> -  if (frag->tc_frag_data.last_map_symbol != NULL)
>> +  else if (last != NULL)
>>      {
>>        /* The mapping symbols should be added in offset order.  */
>> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
>> -                        <= S_GET_VALUE (symbol));
>> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
>>        /* Remove the old one.  */
>> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
>> -         == S_GET_VALUE (symbol))
>> -       symbol_remove (frag->tc_frag_data.last_map_symbol,
>> -                      &symbol_rootP, &symbol_lastP);
>> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
>> +       symbol_remove (last, &symbol_rootP, &symbol_lastP);
>>      }
>>    frag->tc_frag_data.last_map_symbol = symbol;
>>  }
>> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>>
>>  void
>>  riscv_mapping_state (enum riscv_seg_mstate to_state,
>> -                    int max_chars)
>> +                    int max_chars,
>> +                    bool frag_align_code)
>>  {
>>    enum riscv_seg_mstate from_state =
>>         seg_info (now_seg)->tc_segment_info_data.map_state;
>> +  bool reset_seg_arch_str = false;
>>
>>    if (!SEG_NORMAL (now_seg)
>> -      /* For now I only add the mapping symbols to text sections.
>> +      /* For now we only add the mapping symbols to text sections.
>>          Therefore, the dis-assembler only show the actual contents
>>          distribution for text.  Other sections will be shown as
>>          data without the details.  */
>> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
>>      return;
>>
>>    /* The mapping symbol should be emitted if not in the right
>> -     mapping state  */
>> -  if (from_state == to_state)
>> +     mapping state.  */
>> +  symbolS *seg_arch_symbol =
>> +       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
>> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
>> +    {
>> +      /* Always add $x+arch at the first instruction of section.  */
>> +      reset_seg_arch_str = true;
>> +    }
>> +  else if (seg_arch_symbol != 0
>> +          && to_state == MAP_INSN
>> +          && !frag_align_code
>> +          && strcmp (riscv_subsets->arch_str,
>> +                     S_GET_NAME (seg_arch_symbol) + 2) != 0)
>> +    {
>> +      reset_seg_arch_str = true;
>> +      need_arch_map_symbol = true;
>> +    }
>> +  else if (from_state == to_state)
>>      return;
>>
>>    valueT value = (valueT) (frag_now_fix () - max_chars);
>>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
>> -  make_mapping_symbol (to_state, value, frag_now);
>> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
>>  }
>>
>>  /* Add the odd bytes of paddings for riscv_handle_align.  */
>> @@ -544,9 +596,27 @@ static void
>>  riscv_add_odd_padding_symbol (fragS *frag)
>>  {
>>    /* If there was already a mapping symbol, it should be
>> -     removed in the make_mapping_symbol.  */
>> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
>> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
>> +     removed in the make_mapping_symbol.
>> +
>> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
>> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
>> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
>> +}
>> +
>> +/* If previous and current mapping symbol have same value, then remove the
>> +   current $x only if the previous is $x+arch; Otherwise, always remove the
>> +   previous.  */
>> +
>> +static void
>> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
>> +{
>> +  know (pre != NULL && cur != NULL
>> +       && S_GET_VALUE (pre) == S_GET_VALUE (cur));
>> +  symbolS *removed = pre;
>> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
>> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
>> +    removed = cur;
>> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
>>  }
>>
>>  /* Remove any excess mapping symbols generated for alignment frags in
>> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>>    if (seginfo == NULL || seginfo->frchainP == NULL)
>>      return;
>>
>> +  /* If we don't set any .option arch directive, then the arch_map_symbol
>> +     in each segment must be the first instruction, and we don't need to
>> +     add $x+arch for them.  */
>> +  if (!need_arch_map_symbol
>> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
>> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
>> +
>>    for (fragp = seginfo->frchainP->frch_root;
>>         fragp != NULL;
>>         fragp = fragp->fr_next)
>> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>>
>>        do
>>         {
>> -         if (next->tc_frag_data.first_map_symbol != NULL)
>> +         symbolS *next_first = next->tc_frag_data.first_map_symbol;
>> +         if (next_first != NULL)
>>             {
>>               /* The last mapping symbol overlaps with another one
>> -                which at the start of the next frag.  */
>> -             symbol_remove (last, &symbol_rootP, &symbol_lastP);
>> +                which at the start of the next frag.
>> +
>> +                Please see the gas/testsuite/gas/riscv/mapping.s:
>> +                .text.zero.fill.align.A and .text.zero.fill.align.B.  */
>> +             riscv_remove_mapping_symbol (last, next_first);
>>               break;
>>             }
>>
>>           if (next->fr_next == NULL)
>>             {
>> -             /* The last mapping symbol is at the end of the section.  */
>> +             /* The last mapping symbol is at the end of the section.
>> +
>> +                Please see the gas/testsuite/gas/riscv/mapping.s:
>> +                .text.last.section.  */
>>               know (next->fr_fix == 0 && next->fr_var == 0);
>>               symbol_remove (last, &symbol_rootP, &symbol_lastP);
>>               break;
>> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
>>         return;
>>      }
>>
>> -  riscv_mapping_state (MAP_INSN, 0);
>> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>>
>>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>>                                                 &imm_reloc, op_hash);
>> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>>    if (strcmp (name, "rvc") == 0)
>>      {
>>        riscv_update_subset (&riscv_rps_as, "+c");
>> +      riscv_reset_subsets_list_arch_str ();
>>        riscv_set_rvc (true);
>>      }
>>    else if (strcmp (name, "norvc") == 0)
>>      {
>>        riscv_update_subset (&riscv_rps_as, "-c");
>> +      riscv_reset_subsets_list_arch_str ();
>>        riscv_set_rvc (false);
>>      }
>>    else if (strcmp (name, "pic") == 0)
>> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>>        if (ISSPACE (*name) && *name != '\0')
>>         name++;
>>        riscv_update_subset (&riscv_rps_as, name);
>> +      riscv_reset_subsets_list_arch_str ();
>>
>>        riscv_set_rvc (false);
>>        if (riscv_subset_supports (&riscv_rps_as, "c"))
>> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
>>    if (!riscv_opts.relax)
>>      return false;
>>
>> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
>> +     rather than just use frag_more to handle an alignment here?  So that we
>> +     don't need to call riscv_mapping_state again later, and then only need
>> +     to check frag->fr_type to see if it is frag_align_code.  */
>>    nops = frag_more (worst_case_bytes);
>>
>>    ex.X_op = O_constant;
>> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
>>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
>>                &ex, false, BFD_RELOC_RISCV_ALIGN);
>>
>> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
>> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
>>
>>    /* We need to start a new frag after the alignment which may be removed by
>>       the linker, to prevent the assembler from computing static offsets.
>> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
>>      case rs_fill:
>>      case rs_align:
>>      case rs_align_test:
>> -      riscv_mapping_state (MAP_DATA, max_chars);
>> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
>>        break;
>>      case rs_align_code:
>> -      riscv_mapping_state (MAP_INSN, max_chars);
>> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
>>        break;
>>      default:
>>        break;
>> @@ -4418,6 +4509,7 @@ void
>>  riscv_elf_final_processing (void)
>>  {
>>    riscv_set_abi_by_arch ();
>> +  riscv_release_subset_list (riscv_subsets);
>>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
>>  }
>>
>> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>>    save_c = *input_line_pointer;
>>    *input_line_pointer = '\0';
>>
>> -  riscv_mapping_state (MAP_INSN, 0);
>> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>>
>>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>>                                 &imm_reloc, insn_type_hash);
>> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
>>    unsigned int i;
>>
>>    /* Re-write architecture elf attribute.  */
>> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
>> +  arch_str = riscv_subsets->arch_str;
>>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
>> -  xfree ((void *) arch_str);
>>
>>    /* For the file without any instruction, we don't set the default_priv_spec
>>       according to the privileged elf attributes since the md_assemble isn't
>> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
>> index 802e7afe670..19c45ba2d12 100644
>> --- a/gas/config/tc-riscv.h
>> +++ b/gas/config/tc-riscv.h
>> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
>>  extern int riscv_convert_symbolic_attribute (const char *);
>>
>>  /* Set mapping symbol states.  */
>> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
>> -void riscv_mapping_state (enum riscv_seg_mstate, int);
>> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
>> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
>>
>>  /* Define target segment type.  */
>>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
>>  struct riscv_segment_info_type
>>  {
>>    enum riscv_seg_mstate map_state;
>> +  /* The current mapping symbol with architecture string.  */
>> +  symbolS *arch_map_symbol;
>>  };
>>
>>  /* Define target fragment type.  */
>> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
>> deleted file mode 100644
>> index 989463f91ee..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-01.s
>> +++ /dev/null
>> @@ -1,17 +0,0 @@
>> -       .option arch, -c
>> -       .text
>> -       .global funcA
>> -funcA:
>> -       add     a0, a0, a0
>> -       j       funcB
>> -       .global funcB
>> -funcB:
>> -       add     a1, a1, a1
>> -       bne     a0, a1, funcB
>> -
>> -       .data
>> -       .word 0x123456
>> -
>> -       .section        .foo, "ax"
>> -foo:
>> -       add     a2, a2, a2
>> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
>> deleted file mode 100644
>> index 32e0027a13d..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-01a.d
>> +++ /dev/null
>> @@ -1,17 +0,0 @@
>> -#as:
>> -#source: mapping-01.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$x
>> -0+00 l    d  .foo      0+00 .foo
>> -0+00 l       .foo      0+00 foo
>> -0+00 l       .foo      0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> -0+00 g       .text     0+00 funcA
>> -0+08 g       .text     0+00 funcB
>> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
>> deleted file mode 100644
>> index e84b3d608f5..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-01b.d
>> +++ /dev/null
>> @@ -1,21 +0,0 @@
>> -#as:
>> -#source: mapping-01.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <funcA>:
>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+4:[   ]+0040006f[     ]+j[    ]+8 <funcB>
>> -
>> -0+008 <funcB>:
>> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+c:[   ]+feb51ee3[     ]+bne[  ]+a0,a1,8 <funcB>
>> -
>> -Disassembly of section .foo:
>> -
>> -0+000 <foo>:
>> -[      ]+0:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
>> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
>> deleted file mode 100644
>> index 79468c0d14f..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-02.s
>> +++ /dev/null
>> @@ -1,12 +0,0 @@
>> -       .option arch, -c
>> -       .text
>> -       .word   1
>> -       add     a0, a0, a0
>> -
>> -       .data
>> -       .word   2
>> -
>> -       .text
>> -       add     a1, a1, a1
>> -       .short  3
>> -       add     a2, a2, a2
>> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
>> deleted file mode 100644
>> index 333f12cd343..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-02a.d
>> +++ /dev/null
>> @@ -1,15 +0,0 @@
>> -#as:
>> -#source: mapping-02.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$d
>> -0+04 l       .text     0+00 \$x
>> -0+0c l       .text     0+00 \$d
>> -0+0e l       .text     0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
>> deleted file mode 100644
>> index 1ed6c081cf7..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-02b.d
>> +++ /dev/null
>> @@ -1,16 +0,0 @@
>> -#as:
>> -#source: mapping-02.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <.text>:
>> -[      ]+0:[   ]+00000001[     ]+.word[        ]+0x00000001
>> -[      ]+4:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+c:[   ]+0003[         ]+.short[       ]+0x0003
>> -[      ]+e:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
>> -#...
>> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
>> deleted file mode 100644
>> index 88f2601568d..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-03.s
>> +++ /dev/null
>> @@ -1,11 +0,0 @@
>> -       .option arch, -c
>> -       .text
>> -       add     a0, a0, a0
>> -       .long   0
>> -       .balign 16
>> -       .word   1
>> -       add     a1, a1, a1
>> -       .byte   2
>> -       .long   3
>> -       .balign 16
>> -       .word   5
>> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
>> deleted file mode 100644
>> index d3663b663aa..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-03a.d
>> +++ /dev/null
>> @@ -1,20 +0,0 @@
>> -#as:
>> -#source: mapping-03.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$x
>> -0+04 l       .text     0+00 \$d
>> -0+08 l       .text     0+00 \$x
>> -0+14 l       .text     0+00 \$d
>> -0+18 l       .text     0+00 \$x
>> -0+1c l       .text     0+00 \$d
>> -0+21 l       .text     0+00 \$x
>> -0+2d l       .text     0+00 \$d
>> -0+31 l       .text     0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
>> deleted file mode 100644
>> index f4f67269981..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-03b.d
>> +++ /dev/null
>> @@ -1,24 +0,0 @@
>> -#as:
>> -#source: mapping-03.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <.text>:
>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
>> -[      ]+8:[   ]+00000013[     ]+nop
>> -[      ]+c:[   ]+00000013[     ]+nop
>> -[      ]+10:[  ]+00000013[     ]+nop
>> -[      ]+14:[  ]+00000001[     ]+.word[        ]+0x00000001
>> -[      ]+18:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+1c:[  ]+00000302[     ]+.word[        ]+0x00000302
>> -[      ]+20:[  ]+00[   ]+.byte[        ]+0x00
>> -[      ]+21:[  ]+00000013[     ]+nop
>> -[      ]+25:[  ]+00000013[     ]+nop
>> -[      ]+29:[  ]+00000013[     ]+nop
>> -[      ]+2d:[  ]+00000005[     ]+.word[        ]+0x00000005
>> -#...
>> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
>> deleted file mode 100644
>> index 804b0397737..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-04.s
>> +++ /dev/null
>> @@ -1,13 +0,0 @@
>> -       .text
>> -       .option arch, -c
>> -       .fill   2, 4, 0x1001
>> -       .byte   1
>> -       .word   0
>> -       .balign 8
>> -       add     a0, a0, a0
>> -       .fill   5, 2, 0x2002
>> -       add     a1, a1, a1
>> -
>> -       .data
>> -       .word   0x1
>> -       .word   0x2
>> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
>> deleted file mode 100644
>> index 1ae9653212b..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-04a.d
>> +++ /dev/null
>> @@ -1,15 +0,0 @@
>> -#as:
>> -#source: mapping-04.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$d
>> -0+0d l       .text     0+00 \$x
>> -0+15 l       .text     0+00 \$d
>> -0+1f l       .text     0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
>> deleted file mode 100644
>> index 54bd0afb6c4..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-04b.d
>> +++ /dev/null
>> @@ -1,23 +0,0 @@
>> -#as:
>> -#source: mapping-04.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <.text>:
>> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
>> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
>> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
>> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
>> -[      ]+d:[   ]+00000013[     ]+nop
>> -[      ]+11:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+15:[  ]+20022002[     ]+.word[        ]+0x20022002
>> -[      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
>> -[      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
>> -[      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
>> -[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
>> -#...
>> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
>> new file mode 100644
>> index 00000000000..246f3672ade
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
>> @@ -0,0 +1,84 @@
>> +#as:
>> +#source: mapping.s
>> +#objdump: -d
>> +
>> +.*:[   ]+file format .*
>> +
>> +
>> +Disassembly of section .text.cross.section.A:
>> +
>> +0+000 <funcA>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+bffd[         ]+j[    ]+0 <funcA>
>> +
>> +Disassembly of section .text.corss.section.B:
>> +
>> +0+000 <funcB>:
>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>> +[      ]+[0-9a-f]+:[   ]+fffff06f[     ]+j[    ]+0 <funcB>
>> +
>> +Disassembly of section .text.data:
>> +
>> +0+000 <.text.data>:
>> +[      ]+[0-9a-f]+:[   ]+00000000[     ]+.word[        ]+0x00000000
>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>> +[      ]+[0-9a-f]+:[   ]+05000302[     ]+.word[        ]+0x05000302
>> +
>> +Disassembly of section .text.odd.align:
>> +
>> +0+000 <.text.odd.align>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+01[   ]+.byte[        ]+0x01
>> +[      ]+[0-9a-f]+:[   ]+00[   ]+.byte[        ]+0x00
>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>> +
>> +Disassembly of section .text.zero.fill.first:
>> +
>> +0+000 <.text.zero.fill.first>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +
>> +Disassembly of section .text.zero.fill.last:
>> +
>> +0+000 <.text.zero.fill.last>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>> +
>> +Disassembly of section .text.zero.fill.align.A:
>> +
>> +0+000 <.text.zero.fill.align.A>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>> +
>> +Disassembly of section .text.zero.fill.align.B:
>> +
>> +0+000 <.text.zero.fill.align.B>:
>> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>> +
>> +Disassembly of section .text.last.section:
>> +
>> +0+000 <.text.last.section>:
>> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>> +
>> +Disassembly of section .text.section.padding:
>> +
>> +0+000 <.text.section.padding>:
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>> +
>> +Disassembly of section .text.relax.align:
>> +
>> +0+000 <.text.relax.align>:
>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
>> new file mode 100644
>> index 00000000000..f69e719ff30
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
>> @@ -0,0 +1,17 @@
>> +#as:
>> +#source: mapping-non-arch.s
>> +#objdump: --syms --special-syms
>> +
>> +.*file format.*riscv.*
>> +
>> +SYMBOL TABLE:
>> +00+00 l    d  .text    00+00 .text
>> +00+00 l    d  .data    00+00 .data
>> +00+00 l    d  .bss     00+00 .bss
>> +00+00 l       .text    00+00 \$x
>> +00+08 l       .text    00+00 \$d
>> +00+0c l       .text    00+00 \$x
>> +00+00 l    d  text.A   00+00 text.A
>> +00+00 l       text.A   00+00 \$x
>> +00+02 l       text.A   00+00 \$d
>> +00+00 l    d  .riscv.attributes        00+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
>> new file mode 100644
>> index 00000000000..03b2d75a5dd
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
>> @@ -0,0 +1,11 @@
>> +.attribute arch, "rv32i"
>> +.option arch, +c
>> +.text
>> +addi   a0, zero, 1
>> +.align 3
>> +.word 0x1
>> +addi   a0, zero, 2
>> +
>> +.section text.A, "ax"
>> +addi   a0, zero, 3
>> +.word 0x2
>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
>> deleted file mode 100644
>> index 916f732b7f7..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
>> +++ /dev/null
>> @@ -1,21 +0,0 @@
>> -#as: -mno-relax
>> -#source: mapping-03.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$x
>> -0+04 l       .text     0+00 \$d
>> -0+08 l       .text     0+00 \$x
>> -0+10 l       .text     0+00 \$d
>> -0+14 l       .text     0+00 \$x
>> -0+18 l       .text     0+00 \$d
>> -0+20 l       .text     0+00 \$d
>> -0+24 l       .text     0+00 \$x
>> -0+1d l       .text     0+00 \$d
>> -0+1e l       .text     0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
>> deleted file mode 100644
>> index 9e777351d1d..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
>> +++ /dev/null
>> @@ -1,25 +0,0 @@
>> -#as: -mno-relax
>> -#source: mapping-03.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <.text>:
>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
>> -[      ]+8:[   ]+00000013[     ]+nop
>> -[      ]+c:[   ]+00000013[     ]+nop
>> -[      ]+10:[  ]+00000001[     ]+.word[        ]+0x00000001
>> -[      ]+14:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
>> -[      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
>> -[      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
>> -[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
>> -[      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
>> -[      ]+24:[  ]+00000013[     ]+nop
>> -[      ]+28:[  ]+00000013[     ]+nop
>> -[      ]+2c:[  ]+00000013[     ]+nop
>> -#...
>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
>> deleted file mode 100644
>> index d552a7f632a..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
>> +++ /dev/null
>> @@ -1,16 +0,0 @@
>> -#as: -mno-relax
>> -#source: mapping-04.s
>> -#objdump: --syms --special-syms
>> -
>> -.*file format.*riscv.*
>> -
>> -SYMBOL TABLE:
>> -0+00 l    d  .text     0+00 .text
>> -0+00 l    d  .data     0+00 .data
>> -0+00 l    d  .bss      0+00 .bss
>> -0+00 l       .text     0+00 \$d
>> -0+14 l       .text     0+00 \$d
>> -0+1e l       .text     0+00 \$x
>> -0+0d l       .text     0+00 \$d
>> -0+0e l       .text     0+00 \$x
>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
>> deleted file mode 100644
>> index be668f29220..00000000000
>> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
>> +++ /dev/null
>> @@ -1,24 +0,0 @@
>> -#as: -mno-relax
>> -#source: mapping-04.s
>> -#objdump: -d
>> -
>> -.*:[   ]+file format .*
>> -
>> -
>> -Disassembly of section .text:
>> -
>> -0+000 <.text>:
>> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
>> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
>> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
>> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
>> -[      ]+d:[   ]+00[   ]+.byte[        ]+0x00
>> -[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
>> -[      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
>> -[      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
>> -[      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
>> -[      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
>> -[      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>> -[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
>> -[      ]+24:[  ]+00000013[     ]+nop
>> -#...
>> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
>> new file mode 100644
>> index 00000000000..83ee6528b79
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
>> @@ -0,0 +1,48 @@
>> +#as:
>> +#source: mapping.s
>> +#objdump: --syms --special-syms
>> +
>> +.*file format.*riscv.*
>> +
>> +SYMBOL TABLE:
>> +0+00 l    d  .text     0+00 .text
>> +0+00 l    d  .data     0+00 .data
>> +0+00 l    d  .bss      0+00 .bss
>> +0+00 l    d  .text.cross.section.A     0+00 .text.cross.section.A
>> +0+00 l       .text.cross.section.A     0+00 \$xrv32i2p1_c2p0
>> +0+00 l    d  .text.corss.section.B     0+00 .text.corss.section.B
>> +0+00 l       .text.corss.section.B     0+00 \$xrv32i2p1_c2p0
>> +0+02 l       .text.corss.section.B     0+00 \$xrv32i2p1
>> +0+00 l    d  .text.data        0+00 .text.data
>> +0+00 l       .text.data        0+00 \$d
>> +0+08 l       .text.data        0+00 \$xrv32i2p1_c2p0
>> +0+0c l       .text.data        0+00 \$d
>> +0+00 l    d  .text.odd.align   0+00 .text.odd.align
>> +0+00 l       .text.odd.align   0+00 \$xrv32i2p1_c2p0
>> +0+02 l       .text.odd.align   0+00 \$d
>> +0+08 l       .text.odd.align   0+00 \$xrv32i2p1
>> +0+00 l    d  .text.zero.fill.first     0+00 .text.zero.fill.first
>> +0+00 l       .text.zero.fill.first     0+00 \$xrv32i2p1_c2p0
>> +0+00 l    d  .text.zero.fill.last      0+00 .text.zero.fill.last
>> +0+00 l       .text.zero.fill.last      0+00 \$xrv32i2p1_c2p0
>> +0+02 l       .text.zero.fill.last      0+00 \$x
>> +0+00 l    d  .text.zero.fill.align.A   0+00 .text.zero.fill.align.A
>> +0+00 l       .text.zero.fill.align.A   0+00 \$xrv32i2p1_c2p0
>> +0+00 l    d  .text.zero.fill.align.B   0+00 .text.zero.fill.align.B
>> +0+00 l       .text.zero.fill.align.B   0+00 \$xrv32i2p1
>> +0+00 l    d  .text.last.section        0+00 .text.last.section
>> +0+00 l       .text.last.section        0+00 \$xrv32i2p1
>> +0+04 l       .text.last.section        0+00 \$d
>> +0+00 l    d  .text.section.padding     0+00 .text.section.padding
>> +0+00 l       .text.section.padding     0+00 \$xrv32i2p1_c2p0
>> +0+04 l       .text.section.padding     0+00 \$xrv32i2p1_a2p1_c2p0
>> +0+06 l       .text.section.padding     0+00 \$d
>> +0+00 l    d  .text.relax.align 0+00 .text.relax.align
>> +0+00 l       .text.relax.align 0+00 \$xrv32i2p1_c2p0
>> +0+08 l       .text.relax.align 0+00 \$xrv32i2p1
>> +0+0a l       .text.section.padding     0+00 \$x
>> +0+03 l       .text.odd.align   0+00 \$d
>> +0+04 l       .text.odd.align   0+00 \$x
>> +0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>> +0+00 g       .text.cross.section.A     0+00 funcA
>> +0+00 g       .text.corss.section.B     0+00 funcB
>> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
>> new file mode 100644
>> index 00000000000..a0e6c744107
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/mapping.s
>> @@ -0,0 +1,112 @@
>> +.attribute arch, "rv32ic"
>> +.option norelax                        # FIXME: assembler fill the paddings after parsing everything,
>> +                               # so we probably won't fill anything for the norelax region when
>> +                               # the riscv_opts.relax is enabled at somewhere.
>> +
>> +.section .text.cross.section.A, "ax"
>> +.option push
>> +.global funcA
>> +funcA:
>> +addi   a0, zero, 1             # rv32i
>> +.option arch, +c
>> +j      funcA                   # rv32ic
>> +.section .text.corss.section.B, "ax"
>> +.globl funcB
>> +funcB:
>> +addi   a0, zero, 2             # rv32ic, need to be added since start of section
>> +.option arch, -c
>> +j      funcB                   # rv32i
>> +.option pop
>> +
>> +.section .text.data, "ax"
>> +.option push
>> +.word  0                       # $d
>> +.long  1
>> +addi   a0, zero, 1             # rv32ic
>> +.data
>> +.word  2                       # don't add mapping symbols for non-text section
>> +.section .text.data
>> +addi   a0, zero, 2             # $x, but same as previous addi, so removed
>> +.byte  2                       # $d, dumped as .word
>> +.short 3
>> +.byte  5
>> +.option pop
>> +
>> +.section .text.odd.align, "ax"
>> +.option push
>> +.option norelax
>> +.option arch, +c
>> +addi   a0, zero, 1             # $xrv32ic
>> +.byte  1                       # $d
>> +.option arch, -c
>> +.align 3                       # odd alignment, $x replaced by $d + $x
>> +addi   a0, zero, 2             # $xrv32i
>> +.option pop
>> +
>> +.section .text.zero.fill.first, "ax"
>> +.option push
>> +.option norelax
>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
>> +addi   a0, zero, 1             # $xrv32ic
>> +.option pop
>> +
>> +.section .text.zero.fill.last, "ax"
>> +.option push
>> +.option norelax
>> +addi   a0, zero, 1             # $xrv32ic
>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
>> +addi   a0, zero, 2             # $x, FIXME: need find a way to remove?
>> +.option pop
>> +
>> +# last overlap next first
>> +.section .text.zero.fill.align.A, "ax"
>> +.option push
>> +.option norelax
>> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed
>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
>> +addi   a0, zero, 1             # $x, should be removed in riscv_check_mapping_symbols
>> +addi   a0, zero, 2
>> +.option pop
>> +
>> +# last overlap next first
>> +.section .text.zero.fill.align.B, "ax"
>> +.option push
>> +.option norelax
>> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
>> +                               # but will be removed in riscv_check_mapping_symbols
>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
>> +.option arch, -c
>> +addi   a0, zero, 1             # $xrv32i
>> +addi   a0, zero, 2
>> +.option pop
>> +
>> +.section .text.last.section, "ax"
>> +.option push
>> +.option norelax
>> +.option arch, -c
>> +addi   a0, zero, 1             # $xrv32i
>> +.word  1                       # $d
>> +.align 2                       # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
>> +.option pop
>> +
>> +.section .text.section.padding, "ax"
>> +.option push
>> +.option norelax
>> +.align 2
>> +addi   a0, zero, 1             # $rv32ic
>> +.option arch, +a
>> +.align 2                       # 2-byte padding, $x, removed
>> +addi   a0, zero, 2             # $xrv32iac
>> +.word  1                       # $d
>> +.option pop                    # 2-byte padding, $x
>> +
>> +.section .text.relax.align, "ax"
>> +.option push
>> +.option relax
>> +.option arch, rv32ic
>> +.balign        4                       # $xrv32ic, add at the start of section
>> +addi   a0, zero, 1             # $x, won't added
>> +.option arch, -c
>> +.align 3                       # $x, won't added
>> +addi   a0, zero, 2             # $xrv32i
>> +.option pop
>> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
>> index aed4ca8e4d9..1d14c604dec 100644
>> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
>> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
>> @@ -10,5 +10,5 @@ Disassembly of section .text:
>>  0+000 <.text>:
>>  [      ]+[0-9a-f]+:[   ]+952e[         ]+add[          ]+a0,a0,a1
>>  [      ]+[0-9a-f]+:[   ]+00b50533[     ]+add[          ]+a0,a0,a1
>> -[      ]+[0-9a-f]+:[   ]+00302573[     ]+csrr[         ]+a0,fcsr
>> +[      ]+[0-9a-f]+:[   ]+00302573[     ]+frcsr[                ]+a0
>>  #...
>> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>> index f2d399260c1..eb88c81c0f1 100644
>> --- a/opcodes/riscv-dis.c
>> +++ b/opcodes/riscv-dis.c
>> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>>        /* If arch has ZFINX flags, use gpr for disassemble.  */
>>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
>>         riscv_fpr_names = riscv_gpr_names;
>> +      else
>> +       riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
>> +                         riscv_fpr_names_abi : riscv_fpr_names_numeric;
>>
>>        for (; op->name; op++)
>>         {
>> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
>>      *state = MAP_INSN;
>>    else if (strcmp (name, "$d") == 0)
>>      *state = MAP_DATA;
>> +  else if (strncmp (name, "$xrv", 4) == 0)
>> +    {
>> +      *state = MAP_INSN;
>> +      riscv_release_subset_list (&riscv_subsets);
>> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
>> +    }
>>    else
>>      return false;
>>
>> --
>> 2.37.0 (Apple Git-136)
>>
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-10-28  7:01   ` Tsukasa OI
@ 2022-10-28  7:10     ` Kito Cheng
  2022-10-28  9:23       ` Nelson Chu
  0 siblings, 1 reply; 9+ messages in thread
From: Kito Cheng @ 2022-10-28  7:10 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: Nelson Chu, Binutils

Hi Nelson:

Awesome, Nelson thanks for pushing this forward!

Hi Tsukasa:

It's really exciting that we could finally use that to improve disassembler!

On Fri, Oct 28, 2022 at 3:02 PM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
> On 2022/10/28 12:16, Nelson Chu wrote:
> > Committed after passing the regression of riscv-gnu-toolchain.
> >
> > Thanks
> > Nelson
>
> That's great!  My upcoming disassembler optimization heavily depended on
> whether this proposal is merged or not.  So, I'm finally ready to submit
> next part (small optimizations + core RISC-V disassembler reorganization
> for 2 larger optimizations).
>
> One thing I have to point out (again) is, it fails to build on my
> environment (caused by a false positive of GCC's "maybe uninitialized"
> variable detection).  I have submitted separate patch for it:
>
> <https://sourceware.org/pipermail/binutils/2022-October/123952.html>
>
> Thanks,
> Tsukasa
>
> >
> > On Fri, Sep 30, 2022 at 5:21 PM Nelson Chu <nelson@rivosinc.com> wrote:
> >>
> >> RISC-V Psabi pr196,
> >> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
> >>
> >> bfd/
> >>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
> >>     (riscv_copy_subset_list): Copy arch_str as well.
> >>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
> >> gas/
> >>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
> >>     architecture string in the subset_list.
> >>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
> >>     architecture string.
> >>     (s_riscv_option): Likewise.
> >>     (need_arch_map_symbol): New boolean, used to indicate if .option
> >>     directives do affect instructions.
> >>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
> >>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
> >>     if reset_seg_arch_str is true.
> >>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
> >>     now, only add $x+arch if the architecture strings in subset list and segment
> >>     are different.  Besides, always add $x+arch at the start of section, and do
> >>     not add $x+arch for code alignment, since rvc for alignment can be judged
> >>     from addend of R_RISCV_ALIGN.
> >>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
> >>     same value, then remove the current $x only if the previous is $x+arch;
> >>     Otherwise, always remove previous.
> >>     (riscv_add_odd_padding_symbol): Updated.
> >>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
> >>     need_arch_map_symbol is false, so changed them to $x.
> >>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
> >>     (riscv_init_frag): Likewise.
> >>     (s_riscv_insn): Likewise.
> >>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
> >>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
> >>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
> >>     from riscv_subsets.
> >>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
> >>     symbol of each segment.
> >>
> >>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
> >>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
> >>     one file.
> >>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
> >>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
> >>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
> >>     does need any $x+arch.
> >>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
> >>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
> >> opcodes/
> >>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
> >>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
> >>     for some specfic code region.
> >>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
> >>     the architecture string once the ISA is different.
> >> ---
> >>  bfd/elfxx-riscv.c                             |   7 +
> >>  bfd/elfxx-riscv.h                             |   1 +
> >>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
> >>  gas/config/tc-riscv.h                         |   6 +-
> >>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
> >>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
> >>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
> >>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
> >>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
> >>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
> >>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
> >>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
> >>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
> >>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
> >>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
> >>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
> >>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
> >>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
> >>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
> >>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
> >>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
> >>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
> >>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
> >>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
> >>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
> >>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
> >>  opcodes/riscv-dis.c                           |   9 +
> >>  27 files changed, 420 insertions(+), 328 deletions(-)
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
> >>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
> >>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
> >>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
> >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
> >>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
> >>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
> >>
> >> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> >> index c67d4167232..9247350c2c2 100644
> >> --- a/bfd/elfxx-riscv.c
> >> +++ b/bfd/elfxx-riscv.c
> >> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
> >>      }
> >>
> >>    subset_list->tail = NULL;
> >> +
> >> +  if (subset_list->arch_str != NULL)
> >> +    {
> >> +      free ((void*) subset_list->arch_str);
> >> +      subset_list->arch_str = NULL;
> >> +    }
> >>  }
> >>
> >>  /* Parsing extension version.
> >> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
> >>  {
> >>    riscv_subset_list_t *new = xmalloc (sizeof *new);
> >>    new->head = riscv_copy_subset (new, subset_list->head);
> >> +  new->arch_str = strdup (subset_list->arch_str);
> >>    return new;
> >>  }
> >>
> >> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> >> index ea7126bdb4d..e2c1e3c1618 100644
> >> --- a/bfd/elfxx-riscv.h
> >> +++ b/bfd/elfxx-riscv.h
> >> @@ -51,6 +51,7 @@ typedef struct
> >>  {
> >>    riscv_subset_t *head;
> >>    riscv_subset_t *tail;
> >> +  const char *arch_str;
> >>  } riscv_subset_list_t;
> >>
> >>  extern void
> >> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> >> index d9f63b11398..99bd0a06d97 100644
> >> --- a/gas/config/tc-riscv.c
> >> +++ b/gas/config/tc-riscv.c
> >> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
> >>    true,                        /* check_unknown_prefixed_ext.  */
> >>  };
> >>
> >> +/* Update the architecture string in the subset_list.  */
> >> +
> >> +static void
> >> +riscv_reset_subsets_list_arch_str (void)
> >> +{
> >> +  if (riscv_subsets->arch_str != NULL)
> >> +    free ((void *) riscv_subsets->arch_str);
> >> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
> >> +}
> >> +
> >>  /* This structure is used to hold a stack of .option values.  */
> >>  struct riscv_option_stack
> >>  {
> >> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
> >>        riscv_subsets = XNEW (riscv_subset_list_t);
> >>        riscv_subsets->head = NULL;
> >>        riscv_subsets->tail = NULL;
> >> +      riscv_subsets->arch_str = NULL;
> >>        riscv_rps_as.subset_list = riscv_subsets;
> >>      }
> >>    riscv_release_subset_list (riscv_subsets);
> >>    riscv_parse_subset (&riscv_rps_as, s);
> >> +  riscv_reset_subsets_list_arch_str ();
> >>
> >>    riscv_set_rvc (false);
> >>    if (riscv_subset_supports (&riscv_rps_as, "c"))
> >> @@ -459,21 +471,37 @@ static char *expr_end;
> >>  #define OPCODE_MATCHES(OPCODE, OP) \
> >>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
> >>
> >> +/* Indicate if .option directives do affect instructions.  Set to true means
> >> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
> >> +   should be enough.  */
> >> +static bool need_arch_map_symbol = false;
> >> +
> >>  /* Create a new mapping symbol for the transition to STATE.  */
> >>
> >>  static void
> >>  make_mapping_symbol (enum riscv_seg_mstate state,
> >>                      valueT value,
> >> -                    fragS *frag)
> >> +                    fragS *frag,
> >> +                    bool reset_seg_arch_str)
> >>  {
> >>    const char *name;
> >> +  char *buff;
> >>    switch (state)
> >>      {
> >>      case MAP_DATA:
> >>        name = "$d";
> >>        break;
> >>      case MAP_INSN:
> >> -      name = "$x";
> >> +      if (reset_seg_arch_str)
> >> +       {
> >> +         const char *isa = riscv_subsets->arch_str;
> >> +         size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
> >> +         buff = xmalloc (size);
> >> +         snprintf (buff, size, "$x%s", isa);
> >> +         name = buff;
> >> +       }
> >> +      else
> >> +       name = "$x";
> >>        break;
> >>      default:
> >>        abort ();
> >> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
> >>
> >>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
> >>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> >> +  if (reset_seg_arch_str)
> >> +    {
> >> +      /* Store current $x+arch into tc_segment_info.  */
> >> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
> >> +      xfree ((void *) buff);
> >> +    }
> >>
> >>    /* If .fill or other data filling directive generates zero sized data,
> >> -     or we are adding odd alignemnts, then the mapping symbol for the
> >> -     following code will have the same value.  */
> >> +     then mapping symbol for the following code will have the same value.
> >> +
> >> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
> >> +     and .text.zero.fill.last.  */
> >> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
> >> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
> >>    if (value == 0)
> >>      {
> >> -       if (frag->tc_frag_data.first_map_symbol != NULL)
> >> +      if (first != NULL)
> >>         {
> >> -         know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> >> -               == S_GET_VALUE (symbol));
> >> +         know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
> >> +               && first == last);
> >>           /* Remove the old one.  */
> >> -         symbol_remove (frag->tc_frag_data.first_map_symbol,
> >> -                        &symbol_rootP, &symbol_lastP);
> >> +         symbol_remove (first, &symbol_rootP, &symbol_lastP);
> >>         }
> >>        frag->tc_frag_data.first_map_symbol = symbol;
> >>      }
> >> -  if (frag->tc_frag_data.last_map_symbol != NULL)
> >> +  else if (last != NULL)
> >>      {
> >>        /* The mapping symbols should be added in offset order.  */
> >> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> >> -                        <= S_GET_VALUE (symbol));
> >> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
> >>        /* Remove the old one.  */
> >> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> >> -         == S_GET_VALUE (symbol))
> >> -       symbol_remove (frag->tc_frag_data.last_map_symbol,
> >> -                      &symbol_rootP, &symbol_lastP);
> >> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
> >> +       symbol_remove (last, &symbol_rootP, &symbol_lastP);
> >>      }
> >>    frag->tc_frag_data.last_map_symbol = symbol;
> >>  }
> >> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
> >>
> >>  void
> >>  riscv_mapping_state (enum riscv_seg_mstate to_state,
> >> -                    int max_chars)
> >> +                    int max_chars,
> >> +                    bool frag_align_code)
> >>  {
> >>    enum riscv_seg_mstate from_state =
> >>         seg_info (now_seg)->tc_segment_info_data.map_state;
> >> +  bool reset_seg_arch_str = false;
> >>
> >>    if (!SEG_NORMAL (now_seg)
> >> -      /* For now I only add the mapping symbols to text sections.
> >> +      /* For now we only add the mapping symbols to text sections.
> >>          Therefore, the dis-assembler only show the actual contents
> >>          distribution for text.  Other sections will be shown as
> >>          data without the details.  */
> >> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
> >>      return;
> >>
> >>    /* The mapping symbol should be emitted if not in the right
> >> -     mapping state  */
> >> -  if (from_state == to_state)
> >> +     mapping state.  */
> >> +  symbolS *seg_arch_symbol =
> >> +       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
> >> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
> >> +    {
> >> +      /* Always add $x+arch at the first instruction of section.  */
> >> +      reset_seg_arch_str = true;
> >> +    }
> >> +  else if (seg_arch_symbol != 0
> >> +          && to_state == MAP_INSN
> >> +          && !frag_align_code
> >> +          && strcmp (riscv_subsets->arch_str,
> >> +                     S_GET_NAME (seg_arch_symbol) + 2) != 0)
> >> +    {
> >> +      reset_seg_arch_str = true;
> >> +      need_arch_map_symbol = true;
> >> +    }
> >> +  else if (from_state == to_state)
> >>      return;
> >>
> >>    valueT value = (valueT) (frag_now_fix () - max_chars);
> >>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
> >> -  make_mapping_symbol (to_state, value, frag_now);
> >> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
> >>  }
> >>
> >>  /* Add the odd bytes of paddings for riscv_handle_align.  */
> >> @@ -544,9 +596,27 @@ static void
> >>  riscv_add_odd_padding_symbol (fragS *frag)
> >>  {
> >>    /* If there was already a mapping symbol, it should be
> >> -     removed in the make_mapping_symbol.  */
> >> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
> >> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
> >> +     removed in the make_mapping_symbol.
> >> +
> >> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
> >> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
> >> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
> >> +}
> >> +
> >> +/* If previous and current mapping symbol have same value, then remove the
> >> +   current $x only if the previous is $x+arch; Otherwise, always remove the
> >> +   previous.  */
> >> +
> >> +static void
> >> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
> >> +{
> >> +  know (pre != NULL && cur != NULL
> >> +       && S_GET_VALUE (pre) == S_GET_VALUE (cur));
> >> +  symbolS *removed = pre;
> >> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
> >> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
> >> +    removed = cur;
> >> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
> >>  }
> >>
> >>  /* Remove any excess mapping symbols generated for alignment frags in
> >> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
> >>    if (seginfo == NULL || seginfo->frchainP == NULL)
> >>      return;
> >>
> >> +  /* If we don't set any .option arch directive, then the arch_map_symbol
> >> +     in each segment must be the first instruction, and we don't need to
> >> +     add $x+arch for them.  */
> >> +  if (!need_arch_map_symbol
> >> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
> >> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
> >> +
> >>    for (fragp = seginfo->frchainP->frch_root;
> >>         fragp != NULL;
> >>         fragp = fragp->fr_next)
> >> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
> >>
> >>        do
> >>         {
> >> -         if (next->tc_frag_data.first_map_symbol != NULL)
> >> +         symbolS *next_first = next->tc_frag_data.first_map_symbol;
> >> +         if (next_first != NULL)
> >>             {
> >>               /* The last mapping symbol overlaps with another one
> >> -                which at the start of the next frag.  */
> >> -             symbol_remove (last, &symbol_rootP, &symbol_lastP);
> >> +                which at the start of the next frag.
> >> +
> >> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> >> +                .text.zero.fill.align.A and .text.zero.fill.align.B.  */
> >> +             riscv_remove_mapping_symbol (last, next_first);
> >>               break;
> >>             }
> >>
> >>           if (next->fr_next == NULL)
> >>             {
> >> -             /* The last mapping symbol is at the end of the section.  */
> >> +             /* The last mapping symbol is at the end of the section.
> >> +
> >> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> >> +                .text.last.section.  */
> >>               know (next->fr_fix == 0 && next->fr_var == 0);
> >>               symbol_remove (last, &symbol_rootP, &symbol_lastP);
> >>               break;
> >> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
> >>         return;
> >>      }
> >>
> >> -  riscv_mapping_state (MAP_INSN, 0);
> >> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
> >>
> >>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
> >>                                                 &imm_reloc, op_hash);
> >> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
> >>    if (strcmp (name, "rvc") == 0)
> >>      {
> >>        riscv_update_subset (&riscv_rps_as, "+c");
> >> +      riscv_reset_subsets_list_arch_str ();
> >>        riscv_set_rvc (true);
> >>      }
> >>    else if (strcmp (name, "norvc") == 0)
> >>      {
> >>        riscv_update_subset (&riscv_rps_as, "-c");
> >> +      riscv_reset_subsets_list_arch_str ();
> >>        riscv_set_rvc (false);
> >>      }
> >>    else if (strcmp (name, "pic") == 0)
> >> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
> >>        if (ISSPACE (*name) && *name != '\0')
> >>         name++;
> >>        riscv_update_subset (&riscv_rps_as, name);
> >> +      riscv_reset_subsets_list_arch_str ();
> >>
> >>        riscv_set_rvc (false);
> >>        if (riscv_subset_supports (&riscv_rps_as, "c"))
> >> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
> >>    if (!riscv_opts.relax)
> >>      return false;
> >>
> >> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
> >> +     rather than just use frag_more to handle an alignment here?  So that we
> >> +     don't need to call riscv_mapping_state again later, and then only need
> >> +     to check frag->fr_type to see if it is frag_align_code.  */
> >>    nops = frag_more (worst_case_bytes);
> >>
> >>    ex.X_op = O_constant;
> >> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
> >>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
> >>                &ex, false, BFD_RELOC_RISCV_ALIGN);
> >>
> >> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
> >> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
> >>
> >>    /* We need to start a new frag after the alignment which may be removed by
> >>       the linker, to prevent the assembler from computing static offsets.
> >> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
> >>      case rs_fill:
> >>      case rs_align:
> >>      case rs_align_test:
> >> -      riscv_mapping_state (MAP_DATA, max_chars);
> >> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
> >>        break;
> >>      case rs_align_code:
> >> -      riscv_mapping_state (MAP_INSN, max_chars);
> >> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
> >>        break;
> >>      default:
> >>        break;
> >> @@ -4418,6 +4509,7 @@ void
> >>  riscv_elf_final_processing (void)
> >>  {
> >>    riscv_set_abi_by_arch ();
> >> +  riscv_release_subset_list (riscv_subsets);
> >>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
> >>  }
> >>
> >> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
> >>    save_c = *input_line_pointer;
> >>    *input_line_pointer = '\0';
> >>
> >> -  riscv_mapping_state (MAP_INSN, 0);
> >> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
> >>
> >>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
> >>                                 &imm_reloc, insn_type_hash);
> >> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
> >>    unsigned int i;
> >>
> >>    /* Re-write architecture elf attribute.  */
> >> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
> >> +  arch_str = riscv_subsets->arch_str;
> >>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
> >> -  xfree ((void *) arch_str);
> >>
> >>    /* For the file without any instruction, we don't set the default_priv_spec
> >>       according to the privileged elf attributes since the md_assemble isn't
> >> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> >> index 802e7afe670..19c45ba2d12 100644
> >> --- a/gas/config/tc-riscv.h
> >> +++ b/gas/config/tc-riscv.h
> >> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
> >>  extern int riscv_convert_symbolic_attribute (const char *);
> >>
> >>  /* Set mapping symbol states.  */
> >> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
> >> -void riscv_mapping_state (enum riscv_seg_mstate, int);
> >> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
> >> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
> >>
> >>  /* Define target segment type.  */
> >>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
> >>  struct riscv_segment_info_type
> >>  {
> >>    enum riscv_seg_mstate map_state;
> >> +  /* The current mapping symbol with architecture string.  */
> >> +  symbolS *arch_map_symbol;
> >>  };
> >>
> >>  /* Define target fragment type.  */
> >> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> >> deleted file mode 100644
> >> index 989463f91ee..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-01.s
> >> +++ /dev/null
> >> @@ -1,17 +0,0 @@
> >> -       .option arch, -c
> >> -       .text
> >> -       .global funcA
> >> -funcA:
> >> -       add     a0, a0, a0
> >> -       j       funcB
> >> -       .global funcB
> >> -funcB:
> >> -       add     a1, a1, a1
> >> -       bne     a0, a1, funcB
> >> -
> >> -       .data
> >> -       .word 0x123456
> >> -
> >> -       .section        .foo, "ax"
> >> -foo:
> >> -       add     a2, a2, a2
> >> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> >> deleted file mode 100644
> >> index 32e0027a13d..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-01a.d
> >> +++ /dev/null
> >> @@ -1,17 +0,0 @@
> >> -#as:
> >> -#source: mapping-01.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$x
> >> -0+00 l    d  .foo      0+00 .foo
> >> -0+00 l       .foo      0+00 foo
> >> -0+00 l       .foo      0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> -0+00 g       .text     0+00 funcA
> >> -0+08 g       .text     0+00 funcB
> >> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
> >> deleted file mode 100644
> >> index e84b3d608f5..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-01b.d
> >> +++ /dev/null
> >> @@ -1,21 +0,0 @@
> >> -#as:
> >> -#source: mapping-01.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <funcA>:
> >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+4:[   ]+0040006f[     ]+j[    ]+8 <funcB>
> >> -
> >> -0+008 <funcB>:
> >> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+c:[   ]+feb51ee3[     ]+bne[  ]+a0,a1,8 <funcB>
> >> -
> >> -Disassembly of section .foo:
> >> -
> >> -0+000 <foo>:
> >> -[      ]+0:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> >> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> >> deleted file mode 100644
> >> index 79468c0d14f..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-02.s
> >> +++ /dev/null
> >> @@ -1,12 +0,0 @@
> >> -       .option arch, -c
> >> -       .text
> >> -       .word   1
> >> -       add     a0, a0, a0
> >> -
> >> -       .data
> >> -       .word   2
> >> -
> >> -       .text
> >> -       add     a1, a1, a1
> >> -       .short  3
> >> -       add     a2, a2, a2
> >> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> >> deleted file mode 100644
> >> index 333f12cd343..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-02a.d
> >> +++ /dev/null
> >> @@ -1,15 +0,0 @@
> >> -#as:
> >> -#source: mapping-02.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$d
> >> -0+04 l       .text     0+00 \$x
> >> -0+0c l       .text     0+00 \$d
> >> -0+0e l       .text     0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> >> deleted file mode 100644
> >> index 1ed6c081cf7..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-02b.d
> >> +++ /dev/null
> >> @@ -1,16 +0,0 @@
> >> -#as:
> >> -#source: mapping-02.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <.text>:
> >> -[      ]+0:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> -[      ]+4:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+c:[   ]+0003[         ]+.short[       ]+0x0003
> >> -[      ]+e:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> >> -#...
> >> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> >> deleted file mode 100644
> >> index 88f2601568d..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-03.s
> >> +++ /dev/null
> >> @@ -1,11 +0,0 @@
> >> -       .option arch, -c
> >> -       .text
> >> -       add     a0, a0, a0
> >> -       .long   0
> >> -       .balign 16
> >> -       .word   1
> >> -       add     a1, a1, a1
> >> -       .byte   2
> >> -       .long   3
> >> -       .balign 16
> >> -       .word   5
> >> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> >> deleted file mode 100644
> >> index d3663b663aa..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-03a.d
> >> +++ /dev/null
> >> @@ -1,20 +0,0 @@
> >> -#as:
> >> -#source: mapping-03.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$x
> >> -0+04 l       .text     0+00 \$d
> >> -0+08 l       .text     0+00 \$x
> >> -0+14 l       .text     0+00 \$d
> >> -0+18 l       .text     0+00 \$x
> >> -0+1c l       .text     0+00 \$d
> >> -0+21 l       .text     0+00 \$x
> >> -0+2d l       .text     0+00 \$d
> >> -0+31 l       .text     0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
> >> deleted file mode 100644
> >> index f4f67269981..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-03b.d
> >> +++ /dev/null
> >> @@ -1,24 +0,0 @@
> >> -#as:
> >> -#source: mapping-03.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <.text>:
> >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> >> -[      ]+8:[   ]+00000013[     ]+nop
> >> -[      ]+c:[   ]+00000013[     ]+nop
> >> -[      ]+10:[  ]+00000013[     ]+nop
> >> -[      ]+14:[  ]+00000001[     ]+.word[        ]+0x00000001
> >> -[      ]+18:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+1c:[  ]+00000302[     ]+.word[        ]+0x00000302
> >> -[      ]+20:[  ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+21:[  ]+00000013[     ]+nop
> >> -[      ]+25:[  ]+00000013[     ]+nop
> >> -[      ]+29:[  ]+00000013[     ]+nop
> >> -[      ]+2d:[  ]+00000005[     ]+.word[        ]+0x00000005
> >> -#...
> >> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> >> deleted file mode 100644
> >> index 804b0397737..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-04.s
> >> +++ /dev/null
> >> @@ -1,13 +0,0 @@
> >> -       .text
> >> -       .option arch, -c
> >> -       .fill   2, 4, 0x1001
> >> -       .byte   1
> >> -       .word   0
> >> -       .balign 8
> >> -       add     a0, a0, a0
> >> -       .fill   5, 2, 0x2002
> >> -       add     a1, a1, a1
> >> -
> >> -       .data
> >> -       .word   0x1
> >> -       .word   0x2
> >> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> >> deleted file mode 100644
> >> index 1ae9653212b..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-04a.d
> >> +++ /dev/null
> >> @@ -1,15 +0,0 @@
> >> -#as:
> >> -#source: mapping-04.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$d
> >> -0+0d l       .text     0+00 \$x
> >> -0+15 l       .text     0+00 \$d
> >> -0+1f l       .text     0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> >> deleted file mode 100644
> >> index 54bd0afb6c4..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> >> +++ /dev/null
> >> @@ -1,23 +0,0 @@
> >> -#as:
> >> -#source: mapping-04.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <.text>:
> >> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> >> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> >> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+d:[   ]+00000013[     ]+nop
> >> -[      ]+11:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+15:[  ]+20022002[     ]+.word[        ]+0x20022002
> >> -[      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
> >> -[      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
> >> -[      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
> >> -[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
> >> -#...
> >> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
> >> new file mode 100644
> >> index 00000000000..246f3672ade
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
> >> @@ -0,0 +1,84 @@
> >> +#as:
> >> +#source: mapping.s
> >> +#objdump: -d
> >> +
> >> +.*:[   ]+file format .*
> >> +
> >> +
> >> +Disassembly of section .text.cross.section.A:
> >> +
> >> +0+000 <funcA>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+bffd[         ]+j[    ]+0 <funcA>
> >> +
> >> +Disassembly of section .text.corss.section.B:
> >> +
> >> +0+000 <funcB>:
> >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> >> +[      ]+[0-9a-f]+:[   ]+fffff06f[     ]+j[    ]+0 <funcB>
> >> +
> >> +Disassembly of section .text.data:
> >> +
> >> +0+000 <.text.data>:
> >> +[      ]+[0-9a-f]+:[   ]+00000000[     ]+.word[        ]+0x00000000
> >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> >> +[      ]+[0-9a-f]+:[   ]+05000302[     ]+.word[        ]+0x05000302
> >> +
> >> +Disassembly of section .text.odd.align:
> >> +
> >> +0+000 <.text.odd.align>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+01[   ]+.byte[        ]+0x01
> >> +[      ]+[0-9a-f]+:[   ]+00[   ]+.byte[        ]+0x00
> >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> >> +
> >> +Disassembly of section .text.zero.fill.first:
> >> +
> >> +0+000 <.text.zero.fill.first>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +
> >> +Disassembly of section .text.zero.fill.last:
> >> +
> >> +0+000 <.text.zero.fill.last>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> >> +
> >> +Disassembly of section .text.zero.fill.align.A:
> >> +
> >> +0+000 <.text.zero.fill.align.A>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> >> +
> >> +Disassembly of section .text.zero.fill.align.B:
> >> +
> >> +0+000 <.text.zero.fill.align.B>:
> >> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> >> +
> >> +Disassembly of section .text.last.section:
> >> +
> >> +0+000 <.text.last.section>:
> >> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> +
> >> +Disassembly of section .text.section.padding:
> >> +
> >> +0+000 <.text.section.padding>:
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> >> +
> >> +Disassembly of section .text.relax.align:
> >> +
> >> +0+000 <.text.relax.align>:
> >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> >> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
> >> new file mode 100644
> >> index 00000000000..f69e719ff30
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
> >> @@ -0,0 +1,17 @@
> >> +#as:
> >> +#source: mapping-non-arch.s
> >> +#objdump: --syms --special-syms
> >> +
> >> +.*file format.*riscv.*
> >> +
> >> +SYMBOL TABLE:
> >> +00+00 l    d  .text    00+00 .text
> >> +00+00 l    d  .data    00+00 .data
> >> +00+00 l    d  .bss     00+00 .bss
> >> +00+00 l       .text    00+00 \$x
> >> +00+08 l       .text    00+00 \$d
> >> +00+0c l       .text    00+00 \$x
> >> +00+00 l    d  text.A   00+00 text.A
> >> +00+00 l       text.A   00+00 \$x
> >> +00+02 l       text.A   00+00 \$d
> >> +00+00 l    d  .riscv.attributes        00+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
> >> new file mode 100644
> >> index 00000000000..03b2d75a5dd
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
> >> @@ -0,0 +1,11 @@
> >> +.attribute arch, "rv32i"
> >> +.option arch, +c
> >> +.text
> >> +addi   a0, zero, 1
> >> +.align 3
> >> +.word 0x1
> >> +addi   a0, zero, 2
> >> +
> >> +.section text.A, "ax"
> >> +addi   a0, zero, 3
> >> +.word 0x2
> >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> >> deleted file mode 100644
> >> index 916f732b7f7..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> >> +++ /dev/null
> >> @@ -1,21 +0,0 @@
> >> -#as: -mno-relax
> >> -#source: mapping-03.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$x
> >> -0+04 l       .text     0+00 \$d
> >> -0+08 l       .text     0+00 \$x
> >> -0+10 l       .text     0+00 \$d
> >> -0+14 l       .text     0+00 \$x
> >> -0+18 l       .text     0+00 \$d
> >> -0+20 l       .text     0+00 \$d
> >> -0+24 l       .text     0+00 \$x
> >> -0+1d l       .text     0+00 \$d
> >> -0+1e l       .text     0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> >> deleted file mode 100644
> >> index 9e777351d1d..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> >> +++ /dev/null
> >> @@ -1,25 +0,0 @@
> >> -#as: -mno-relax
> >> -#source: mapping-03.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <.text>:
> >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> >> -[      ]+8:[   ]+00000013[     ]+nop
> >> -[      ]+c:[   ]+00000013[     ]+nop
> >> -[      ]+10:[  ]+00000001[     ]+.word[        ]+0x00000001
> >> -[      ]+14:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
> >> -[      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
> >> -[      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
> >> -[      ]+24:[  ]+00000013[     ]+nop
> >> -[      ]+28:[  ]+00000013[     ]+nop
> >> -[      ]+2c:[  ]+00000013[     ]+nop
> >> -#...
> >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> >> deleted file mode 100644
> >> index d552a7f632a..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> >> +++ /dev/null
> >> @@ -1,16 +0,0 @@
> >> -#as: -mno-relax
> >> -#source: mapping-04.s
> >> -#objdump: --syms --special-syms
> >> -
> >> -.*file format.*riscv.*
> >> -
> >> -SYMBOL TABLE:
> >> -0+00 l    d  .text     0+00 .text
> >> -0+00 l    d  .data     0+00 .data
> >> -0+00 l    d  .bss      0+00 .bss
> >> -0+00 l       .text     0+00 \$d
> >> -0+14 l       .text     0+00 \$d
> >> -0+1e l       .text     0+00 \$x
> >> -0+0d l       .text     0+00 \$d
> >> -0+0e l       .text     0+00 \$x
> >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> >> deleted file mode 100644
> >> index be668f29220..00000000000
> >> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> >> +++ /dev/null
> >> @@ -1,24 +0,0 @@
> >> -#as: -mno-relax
> >> -#source: mapping-04.s
> >> -#objdump: -d
> >> -
> >> -.*:[   ]+file format .*
> >> -
> >> -
> >> -Disassembly of section .text:
> >> -
> >> -0+000 <.text>:
> >> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> >> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> >> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> >> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+d:[   ]+00[   ]+.byte[        ]+0x00
> >> -[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
> >> -[      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> >> -[      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
> >> -[      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
> >> -[      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
> >> -[      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> >> -[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
> >> -[      ]+24:[  ]+00000013[     ]+nop
> >> -#...
> >> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
> >> new file mode 100644
> >> index 00000000000..83ee6528b79
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
> >> @@ -0,0 +1,48 @@
> >> +#as:
> >> +#source: mapping.s
> >> +#objdump: --syms --special-syms
> >> +
> >> +.*file format.*riscv.*
> >> +
> >> +SYMBOL TABLE:
> >> +0+00 l    d  .text     0+00 .text
> >> +0+00 l    d  .data     0+00 .data
> >> +0+00 l    d  .bss      0+00 .bss
> >> +0+00 l    d  .text.cross.section.A     0+00 .text.cross.section.A
> >> +0+00 l       .text.cross.section.A     0+00 \$xrv32i2p1_c2p0
> >> +0+00 l    d  .text.corss.section.B     0+00 .text.corss.section.B
> >> +0+00 l       .text.corss.section.B     0+00 \$xrv32i2p1_c2p0
> >> +0+02 l       .text.corss.section.B     0+00 \$xrv32i2p1
> >> +0+00 l    d  .text.data        0+00 .text.data
> >> +0+00 l       .text.data        0+00 \$d
> >> +0+08 l       .text.data        0+00 \$xrv32i2p1_c2p0
> >> +0+0c l       .text.data        0+00 \$d
> >> +0+00 l    d  .text.odd.align   0+00 .text.odd.align
> >> +0+00 l       .text.odd.align   0+00 \$xrv32i2p1_c2p0
> >> +0+02 l       .text.odd.align   0+00 \$d
> >> +0+08 l       .text.odd.align   0+00 \$xrv32i2p1
> >> +0+00 l    d  .text.zero.fill.first     0+00 .text.zero.fill.first
> >> +0+00 l       .text.zero.fill.first     0+00 \$xrv32i2p1_c2p0
> >> +0+00 l    d  .text.zero.fill.last      0+00 .text.zero.fill.last
> >> +0+00 l       .text.zero.fill.last      0+00 \$xrv32i2p1_c2p0
> >> +0+02 l       .text.zero.fill.last      0+00 \$x
> >> +0+00 l    d  .text.zero.fill.align.A   0+00 .text.zero.fill.align.A
> >> +0+00 l       .text.zero.fill.align.A   0+00 \$xrv32i2p1_c2p0
> >> +0+00 l    d  .text.zero.fill.align.B   0+00 .text.zero.fill.align.B
> >> +0+00 l       .text.zero.fill.align.B   0+00 \$xrv32i2p1
> >> +0+00 l    d  .text.last.section        0+00 .text.last.section
> >> +0+00 l       .text.last.section        0+00 \$xrv32i2p1
> >> +0+04 l       .text.last.section        0+00 \$d
> >> +0+00 l    d  .text.section.padding     0+00 .text.section.padding
> >> +0+00 l       .text.section.padding     0+00 \$xrv32i2p1_c2p0
> >> +0+04 l       .text.section.padding     0+00 \$xrv32i2p1_a2p1_c2p0
> >> +0+06 l       .text.section.padding     0+00 \$d
> >> +0+00 l    d  .text.relax.align 0+00 .text.relax.align
> >> +0+00 l       .text.relax.align 0+00 \$xrv32i2p1_c2p0
> >> +0+08 l       .text.relax.align 0+00 \$xrv32i2p1
> >> +0+0a l       .text.section.padding     0+00 \$x
> >> +0+03 l       .text.odd.align   0+00 \$d
> >> +0+04 l       .text.odd.align   0+00 \$x
> >> +0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> >> +0+00 g       .text.cross.section.A     0+00 funcA
> >> +0+00 g       .text.corss.section.B     0+00 funcB
> >> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
> >> new file mode 100644
> >> index 00000000000..a0e6c744107
> >> --- /dev/null
> >> +++ b/gas/testsuite/gas/riscv/mapping.s
> >> @@ -0,0 +1,112 @@
> >> +.attribute arch, "rv32ic"
> >> +.option norelax                        # FIXME: assembler fill the paddings after parsing everything,
> >> +                               # so we probably won't fill anything for the norelax region when
> >> +                               # the riscv_opts.relax is enabled at somewhere.
> >> +
> >> +.section .text.cross.section.A, "ax"
> >> +.option push
> >> +.global funcA
> >> +funcA:
> >> +addi   a0, zero, 1             # rv32i
> >> +.option arch, +c
> >> +j      funcA                   # rv32ic
> >> +.section .text.corss.section.B, "ax"
> >> +.globl funcB
> >> +funcB:
> >> +addi   a0, zero, 2             # rv32ic, need to be added since start of section
> >> +.option arch, -c
> >> +j      funcB                   # rv32i
> >> +.option pop
> >> +
> >> +.section .text.data, "ax"
> >> +.option push
> >> +.word  0                       # $d
> >> +.long  1
> >> +addi   a0, zero, 1             # rv32ic
> >> +.data
> >> +.word  2                       # don't add mapping symbols for non-text section
> >> +.section .text.data
> >> +addi   a0, zero, 2             # $x, but same as previous addi, so removed
> >> +.byte  2                       # $d, dumped as .word
> >> +.short 3
> >> +.byte  5
> >> +.option pop
> >> +
> >> +.section .text.odd.align, "ax"
> >> +.option push
> >> +.option norelax
> >> +.option arch, +c
> >> +addi   a0, zero, 1             # $xrv32ic
> >> +.byte  1                       # $d
> >> +.option arch, -c
> >> +.align 3                       # odd alignment, $x replaced by $d + $x
> >> +addi   a0, zero, 2             # $xrv32i
> >> +.option pop
> >> +
> >> +.section .text.zero.fill.first, "ax"
> >> +.option push
> >> +.option norelax
> >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> >> +addi   a0, zero, 1             # $xrv32ic
> >> +.option pop
> >> +
> >> +.section .text.zero.fill.last, "ax"
> >> +.option push
> >> +.option norelax
> >> +addi   a0, zero, 1             # $xrv32ic
> >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> >> +addi   a0, zero, 2             # $x, FIXME: need find a way to remove?
> >> +.option pop
> >> +
> >> +# last overlap next first
> >> +.section .text.zero.fill.align.A, "ax"
> >> +.option push
> >> +.option norelax
> >> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed
> >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> >> +addi   a0, zero, 1             # $x, should be removed in riscv_check_mapping_symbols
> >> +addi   a0, zero, 2
> >> +.option pop
> >> +
> >> +# last overlap next first
> >> +.section .text.zero.fill.align.B, "ax"
> >> +.option push
> >> +.option norelax
> >> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
> >> +                               # but will be removed in riscv_check_mapping_symbols
> >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> >> +.option arch, -c
> >> +addi   a0, zero, 1             # $xrv32i
> >> +addi   a0, zero, 2
> >> +.option pop
> >> +
> >> +.section .text.last.section, "ax"
> >> +.option push
> >> +.option norelax
> >> +.option arch, -c
> >> +addi   a0, zero, 1             # $xrv32i
> >> +.word  1                       # $d
> >> +.align 2                       # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
> >> +.option pop
> >> +
> >> +.section .text.section.padding, "ax"
> >> +.option push
> >> +.option norelax
> >> +.align 2
> >> +addi   a0, zero, 1             # $rv32ic
> >> +.option arch, +a
> >> +.align 2                       # 2-byte padding, $x, removed
> >> +addi   a0, zero, 2             # $xrv32iac
> >> +.word  1                       # $d
> >> +.option pop                    # 2-byte padding, $x
> >> +
> >> +.section .text.relax.align, "ax"
> >> +.option push
> >> +.option relax
> >> +.option arch, rv32ic
> >> +.balign        4                       # $xrv32ic, add at the start of section
> >> +addi   a0, zero, 1             # $x, won't added
> >> +.option arch, -c
> >> +.align 3                       # $x, won't added
> >> +addi   a0, zero, 2             # $xrv32i
> >> +.option pop
> >> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
> >> index aed4ca8e4d9..1d14c604dec 100644
> >> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
> >> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
> >> @@ -10,5 +10,5 @@ Disassembly of section .text:
> >>  0+000 <.text>:
> >>  [      ]+[0-9a-f]+:[   ]+952e[         ]+add[          ]+a0,a0,a1
> >>  [      ]+[0-9a-f]+:[   ]+00b50533[     ]+add[          ]+a0,a0,a1
> >> -[      ]+[0-9a-f]+:[   ]+00302573[     ]+csrr[         ]+a0,fcsr
> >> +[      ]+[0-9a-f]+:[   ]+00302573[     ]+frcsr[                ]+a0
> >>  #...
> >> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> >> index f2d399260c1..eb88c81c0f1 100644
> >> --- a/opcodes/riscv-dis.c
> >> +++ b/opcodes/riscv-dis.c
> >> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
> >>        /* If arch has ZFINX flags, use gpr for disassemble.  */
> >>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
> >>         riscv_fpr_names = riscv_gpr_names;
> >> +      else
> >> +       riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
> >> +                         riscv_fpr_names_abi : riscv_fpr_names_numeric;
> >>
> >>        for (; op->name; op++)
> >>         {
> >> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
> >>      *state = MAP_INSN;
> >>    else if (strcmp (name, "$d") == 0)
> >>      *state = MAP_DATA;
> >> +  else if (strncmp (name, "$xrv", 4) == 0)
> >> +    {
> >> +      *state = MAP_INSN;
> >> +      riscv_release_subset_list (&riscv_subsets);
> >> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
> >> +    }
> >>    else
> >>      return false;
> >>
> >> --
> >> 2.37.0 (Apple Git-136)
> >>
> >

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-10-28  7:10     ` Kito Cheng
@ 2022-10-28  9:23       ` Nelson Chu
  2022-10-28 14:43         ` Tsukasa OI
  0 siblings, 1 reply; 9+ messages in thread
From: Nelson Chu @ 2022-10-28  9:23 UTC (permalink / raw)
  To: Kito Cheng; +Cc: Tsukasa OI, Binutils

Yeah, one of the reasons to push this is because we can merge lots of
assembler test cases into just one file, so that they should be easier
to maintain.  For example, merge t-head extensions into one file,
merge crypto extensions into one file, and merge zic extensions into
one file, ....  Moreover, for those extensions which have different
encodings for rv32 and rv64 (gas/testsuite/gas/riscv/ext-32.d and
ext-64.d), we can also add ".option arch, "rv32ixxx"" and ".option
arch, "rv64ixxx"" into the same file, so that just one test case
should be enough.

I have seen that Tsukasa had sent some similar patches to add more
assembler test cases, so it would be good if those test cases can be
merged into as few files as possible.

Thanks
Nelson

On Fri, Oct 28, 2022 at 3:10 PM Kito Cheng <kito.cheng@gmail.com> wrote:
>
> Hi Nelson:
>
> Awesome, Nelson thanks for pushing this forward!
>
> Hi Tsukasa:
>
> It's really exciting that we could finally use that to improve disassembler!
>
> On Fri, Oct 28, 2022 at 3:02 PM Tsukasa OI via Binutils
> <binutils@sourceware.org> wrote:
> >
> > On 2022/10/28 12:16, Nelson Chu wrote:
> > > Committed after passing the regression of riscv-gnu-toolchain.
> > >
> > > Thanks
> > > Nelson
> >
> > That's great!  My upcoming disassembler optimization heavily depended on
> > whether this proposal is merged or not.  So, I'm finally ready to submit
> > next part (small optimizations + core RISC-V disassembler reorganization
> > for 2 larger optimizations).
> >
> > One thing I have to point out (again) is, it fails to build on my
> > environment (caused by a false positive of GCC's "maybe uninitialized"
> > variable detection).  I have submitted separate patch for it:
> >
> > <https://sourceware.org/pipermail/binutils/2022-October/123952.html>
> >
> > Thanks,
> > Tsukasa
> >
> > >
> > > On Fri, Sep 30, 2022 at 5:21 PM Nelson Chu <nelson@rivosinc.com> wrote:
> > >>
> > >> RISC-V Psabi pr196,
> > >> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
> > >>
> > >> bfd/
> > >>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
> > >>     (riscv_copy_subset_list): Copy arch_str as well.
> > >>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
> > >> gas/
> > >>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
> > >>     architecture string in the subset_list.
> > >>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
> > >>     architecture string.
> > >>     (s_riscv_option): Likewise.
> > >>     (need_arch_map_symbol): New boolean, used to indicate if .option
> > >>     directives do affect instructions.
> > >>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
> > >>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
> > >>     if reset_seg_arch_str is true.
> > >>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
> > >>     now, only add $x+arch if the architecture strings in subset list and segment
> > >>     are different.  Besides, always add $x+arch at the start of section, and do
> > >>     not add $x+arch for code alignment, since rvc for alignment can be judged
> > >>     from addend of R_RISCV_ALIGN.
> > >>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
> > >>     same value, then remove the current $x only if the previous is $x+arch;
> > >>     Otherwise, always remove previous.
> > >>     (riscv_add_odd_padding_symbol): Updated.
> > >>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
> > >>     need_arch_map_symbol is false, so changed them to $x.
> > >>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
> > >>     (riscv_init_frag): Likewise.
> > >>     (s_riscv_insn): Likewise.
> > >>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
> > >>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
> > >>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
> > >>     from riscv_subsets.
> > >>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
> > >>     symbol of each segment.
> > >>
> > >>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
> > >>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
> > >>     one file.
> > >>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
> > >>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
> > >>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
> > >>     does need any $x+arch.
> > >>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
> > >>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
> > >> opcodes/
> > >>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
> > >>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
> > >>     for some specfic code region.
> > >>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
> > >>     the architecture string once the ISA is different.
> > >> ---
> > >>  bfd/elfxx-riscv.c                             |   7 +
> > >>  bfd/elfxx-riscv.h                             |   1 +
> > >>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
> > >>  gas/config/tc-riscv.h                         |   6 +-
> > >>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
> > >>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
> > >>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
> > >>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
> > >>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
> > >>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
> > >>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
> > >>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
> > >>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
> > >>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
> > >>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
> > >>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
> > >>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
> > >>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
> > >>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
> > >>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
> > >>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
> > >>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
> > >>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
> > >>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
> > >>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
> > >>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
> > >>  opcodes/riscv-dis.c                           |   9 +
> > >>  27 files changed, 420 insertions(+), 328 deletions(-)
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
> > >>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
> > >>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
> > >>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
> > >>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
> > >>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
> > >>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
> > >>
> > >> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> > >> index c67d4167232..9247350c2c2 100644
> > >> --- a/bfd/elfxx-riscv.c
> > >> +++ b/bfd/elfxx-riscv.c
> > >> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
> > >>      }
> > >>
> > >>    subset_list->tail = NULL;
> > >> +
> > >> +  if (subset_list->arch_str != NULL)
> > >> +    {
> > >> +      free ((void*) subset_list->arch_str);
> > >> +      subset_list->arch_str = NULL;
> > >> +    }
> > >>  }
> > >>
> > >>  /* Parsing extension version.
> > >> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
> > >>  {
> > >>    riscv_subset_list_t *new = xmalloc (sizeof *new);
> > >>    new->head = riscv_copy_subset (new, subset_list->head);
> > >> +  new->arch_str = strdup (subset_list->arch_str);
> > >>    return new;
> > >>  }
> > >>
> > >> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> > >> index ea7126bdb4d..e2c1e3c1618 100644
> > >> --- a/bfd/elfxx-riscv.h
> > >> +++ b/bfd/elfxx-riscv.h
> > >> @@ -51,6 +51,7 @@ typedef struct
> > >>  {
> > >>    riscv_subset_t *head;
> > >>    riscv_subset_t *tail;
> > >> +  const char *arch_str;
> > >>  } riscv_subset_list_t;
> > >>
> > >>  extern void
> > >> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> > >> index d9f63b11398..99bd0a06d97 100644
> > >> --- a/gas/config/tc-riscv.c
> > >> +++ b/gas/config/tc-riscv.c
> > >> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
> > >>    true,                        /* check_unknown_prefixed_ext.  */
> > >>  };
> > >>
> > >> +/* Update the architecture string in the subset_list.  */
> > >> +
> > >> +static void
> > >> +riscv_reset_subsets_list_arch_str (void)
> > >> +{
> > >> +  if (riscv_subsets->arch_str != NULL)
> > >> +    free ((void *) riscv_subsets->arch_str);
> > >> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
> > >> +}
> > >> +
> > >>  /* This structure is used to hold a stack of .option values.  */
> > >>  struct riscv_option_stack
> > >>  {
> > >> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
> > >>        riscv_subsets = XNEW (riscv_subset_list_t);
> > >>        riscv_subsets->head = NULL;
> > >>        riscv_subsets->tail = NULL;
> > >> +      riscv_subsets->arch_str = NULL;
> > >>        riscv_rps_as.subset_list = riscv_subsets;
> > >>      }
> > >>    riscv_release_subset_list (riscv_subsets);
> > >>    riscv_parse_subset (&riscv_rps_as, s);
> > >> +  riscv_reset_subsets_list_arch_str ();
> > >>
> > >>    riscv_set_rvc (false);
> > >>    if (riscv_subset_supports (&riscv_rps_as, "c"))
> > >> @@ -459,21 +471,37 @@ static char *expr_end;
> > >>  #define OPCODE_MATCHES(OPCODE, OP) \
> > >>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
> > >>
> > >> +/* Indicate if .option directives do affect instructions.  Set to true means
> > >> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
> > >> +   should be enough.  */
> > >> +static bool need_arch_map_symbol = false;
> > >> +
> > >>  /* Create a new mapping symbol for the transition to STATE.  */
> > >>
> > >>  static void
> > >>  make_mapping_symbol (enum riscv_seg_mstate state,
> > >>                      valueT value,
> > >> -                    fragS *frag)
> > >> +                    fragS *frag,
> > >> +                    bool reset_seg_arch_str)
> > >>  {
> > >>    const char *name;
> > >> +  char *buff;
> > >>    switch (state)
> > >>      {
> > >>      case MAP_DATA:
> > >>        name = "$d";
> > >>        break;
> > >>      case MAP_INSN:
> > >> -      name = "$x";
> > >> +      if (reset_seg_arch_str)
> > >> +       {
> > >> +         const char *isa = riscv_subsets->arch_str;
> > >> +         size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
> > >> +         buff = xmalloc (size);
> > >> +         snprintf (buff, size, "$x%s", isa);
> > >> +         name = buff;
> > >> +       }
> > >> +      else
> > >> +       name = "$x";
> > >>        break;
> > >>      default:
> > >>        abort ();
> > >> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
> > >>
> > >>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
> > >>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> > >> +  if (reset_seg_arch_str)
> > >> +    {
> > >> +      /* Store current $x+arch into tc_segment_info.  */
> > >> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
> > >> +      xfree ((void *) buff);
> > >> +    }
> > >>
> > >>    /* If .fill or other data filling directive generates zero sized data,
> > >> -     or we are adding odd alignemnts, then the mapping symbol for the
> > >> -     following code will have the same value.  */
> > >> +     then mapping symbol for the following code will have the same value.
> > >> +
> > >> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
> > >> +     and .text.zero.fill.last.  */
> > >> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
> > >> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
> > >>    if (value == 0)
> > >>      {
> > >> -       if (frag->tc_frag_data.first_map_symbol != NULL)
> > >> +      if (first != NULL)
> > >>         {
> > >> -         know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> > >> -               == S_GET_VALUE (symbol));
> > >> +         know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
> > >> +               && first == last);
> > >>           /* Remove the old one.  */
> > >> -         symbol_remove (frag->tc_frag_data.first_map_symbol,
> > >> -                        &symbol_rootP, &symbol_lastP);
> > >> +         symbol_remove (first, &symbol_rootP, &symbol_lastP);
> > >>         }
> > >>        frag->tc_frag_data.first_map_symbol = symbol;
> > >>      }
> > >> -  if (frag->tc_frag_data.last_map_symbol != NULL)
> > >> +  else if (last != NULL)
> > >>      {
> > >>        /* The mapping symbols should be added in offset order.  */
> > >> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> > >> -                        <= S_GET_VALUE (symbol));
> > >> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
> > >>        /* Remove the old one.  */
> > >> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> > >> -         == S_GET_VALUE (symbol))
> > >> -       symbol_remove (frag->tc_frag_data.last_map_symbol,
> > >> -                      &symbol_rootP, &symbol_lastP);
> > >> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
> > >> +       symbol_remove (last, &symbol_rootP, &symbol_lastP);
> > >>      }
> > >>    frag->tc_frag_data.last_map_symbol = symbol;
> > >>  }
> > >> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
> > >>
> > >>  void
> > >>  riscv_mapping_state (enum riscv_seg_mstate to_state,
> > >> -                    int max_chars)
> > >> +                    int max_chars,
> > >> +                    bool frag_align_code)
> > >>  {
> > >>    enum riscv_seg_mstate from_state =
> > >>         seg_info (now_seg)->tc_segment_info_data.map_state;
> > >> +  bool reset_seg_arch_str = false;
> > >>
> > >>    if (!SEG_NORMAL (now_seg)
> > >> -      /* For now I only add the mapping symbols to text sections.
> > >> +      /* For now we only add the mapping symbols to text sections.
> > >>          Therefore, the dis-assembler only show the actual contents
> > >>          distribution for text.  Other sections will be shown as
> > >>          data without the details.  */
> > >> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
> > >>      return;
> > >>
> > >>    /* The mapping symbol should be emitted if not in the right
> > >> -     mapping state  */
> > >> -  if (from_state == to_state)
> > >> +     mapping state.  */
> > >> +  symbolS *seg_arch_symbol =
> > >> +       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
> > >> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
> > >> +    {
> > >> +      /* Always add $x+arch at the first instruction of section.  */
> > >> +      reset_seg_arch_str = true;
> > >> +    }
> > >> +  else if (seg_arch_symbol != 0
> > >> +          && to_state == MAP_INSN
> > >> +          && !frag_align_code
> > >> +          && strcmp (riscv_subsets->arch_str,
> > >> +                     S_GET_NAME (seg_arch_symbol) + 2) != 0)
> > >> +    {
> > >> +      reset_seg_arch_str = true;
> > >> +      need_arch_map_symbol = true;
> > >> +    }
> > >> +  else if (from_state == to_state)
> > >>      return;
> > >>
> > >>    valueT value = (valueT) (frag_now_fix () - max_chars);
> > >>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
> > >> -  make_mapping_symbol (to_state, value, frag_now);
> > >> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
> > >>  }
> > >>
> > >>  /* Add the odd bytes of paddings for riscv_handle_align.  */
> > >> @@ -544,9 +596,27 @@ static void
> > >>  riscv_add_odd_padding_symbol (fragS *frag)
> > >>  {
> > >>    /* If there was already a mapping symbol, it should be
> > >> -     removed in the make_mapping_symbol.  */
> > >> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
> > >> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
> > >> +     removed in the make_mapping_symbol.
> > >> +
> > >> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
> > >> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
> > >> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
> > >> +}
> > >> +
> > >> +/* If previous and current mapping symbol have same value, then remove the
> > >> +   current $x only if the previous is $x+arch; Otherwise, always remove the
> > >> +   previous.  */
> > >> +
> > >> +static void
> > >> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
> > >> +{
> > >> +  know (pre != NULL && cur != NULL
> > >> +       && S_GET_VALUE (pre) == S_GET_VALUE (cur));
> > >> +  symbolS *removed = pre;
> > >> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
> > >> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
> > >> +    removed = cur;
> > >> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
> > >>  }
> > >>
> > >>  /* Remove any excess mapping symbols generated for alignment frags in
> > >> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
> > >>    if (seginfo == NULL || seginfo->frchainP == NULL)
> > >>      return;
> > >>
> > >> +  /* If we don't set any .option arch directive, then the arch_map_symbol
> > >> +     in each segment must be the first instruction, and we don't need to
> > >> +     add $x+arch for them.  */
> > >> +  if (!need_arch_map_symbol
> > >> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
> > >> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
> > >> +
> > >>    for (fragp = seginfo->frchainP->frch_root;
> > >>         fragp != NULL;
> > >>         fragp = fragp->fr_next)
> > >> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
> > >>
> > >>        do
> > >>         {
> > >> -         if (next->tc_frag_data.first_map_symbol != NULL)
> > >> +         symbolS *next_first = next->tc_frag_data.first_map_symbol;
> > >> +         if (next_first != NULL)
> > >>             {
> > >>               /* The last mapping symbol overlaps with another one
> > >> -                which at the start of the next frag.  */
> > >> -             symbol_remove (last, &symbol_rootP, &symbol_lastP);
> > >> +                which at the start of the next frag.
> > >> +
> > >> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> > >> +                .text.zero.fill.align.A and .text.zero.fill.align.B.  */
> > >> +             riscv_remove_mapping_symbol (last, next_first);
> > >>               break;
> > >>             }
> > >>
> > >>           if (next->fr_next == NULL)
> > >>             {
> > >> -             /* The last mapping symbol is at the end of the section.  */
> > >> +             /* The last mapping symbol is at the end of the section.
> > >> +
> > >> +                Please see the gas/testsuite/gas/riscv/mapping.s:
> > >> +                .text.last.section.  */
> > >>               know (next->fr_fix == 0 && next->fr_var == 0);
> > >>               symbol_remove (last, &symbol_rootP, &symbol_lastP);
> > >>               break;
> > >> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
> > >>         return;
> > >>      }
> > >>
> > >> -  riscv_mapping_state (MAP_INSN, 0);
> > >> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
> > >>
> > >>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
> > >>                                                 &imm_reloc, op_hash);
> > >> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
> > >>    if (strcmp (name, "rvc") == 0)
> > >>      {
> > >>        riscv_update_subset (&riscv_rps_as, "+c");
> > >> +      riscv_reset_subsets_list_arch_str ();
> > >>        riscv_set_rvc (true);
> > >>      }
> > >>    else if (strcmp (name, "norvc") == 0)
> > >>      {
> > >>        riscv_update_subset (&riscv_rps_as, "-c");
> > >> +      riscv_reset_subsets_list_arch_str ();
> > >>        riscv_set_rvc (false);
> > >>      }
> > >>    else if (strcmp (name, "pic") == 0)
> > >> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
> > >>        if (ISSPACE (*name) && *name != '\0')
> > >>         name++;
> > >>        riscv_update_subset (&riscv_rps_as, name);
> > >> +      riscv_reset_subsets_list_arch_str ();
> > >>
> > >>        riscv_set_rvc (false);
> > >>        if (riscv_subset_supports (&riscv_rps_as, "c"))
> > >> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
> > >>    if (!riscv_opts.relax)
> > >>      return false;
> > >>
> > >> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
> > >> +     rather than just use frag_more to handle an alignment here?  So that we
> > >> +     don't need to call riscv_mapping_state again later, and then only need
> > >> +     to check frag->fr_type to see if it is frag_align_code.  */
> > >>    nops = frag_more (worst_case_bytes);
> > >>
> > >>    ex.X_op = O_constant;
> > >> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
> > >>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
> > >>                &ex, false, BFD_RELOC_RISCV_ALIGN);
> > >>
> > >> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
> > >> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
> > >>
> > >>    /* We need to start a new frag after the alignment which may be removed by
> > >>       the linker, to prevent the assembler from computing static offsets.
> > >> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
> > >>      case rs_fill:
> > >>      case rs_align:
> > >>      case rs_align_test:
> > >> -      riscv_mapping_state (MAP_DATA, max_chars);
> > >> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
> > >>        break;
> > >>      case rs_align_code:
> > >> -      riscv_mapping_state (MAP_INSN, max_chars);
> > >> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
> > >>        break;
> > >>      default:
> > >>        break;
> > >> @@ -4418,6 +4509,7 @@ void
> > >>  riscv_elf_final_processing (void)
> > >>  {
> > >>    riscv_set_abi_by_arch ();
> > >> +  riscv_release_subset_list (riscv_subsets);
> > >>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
> > >>  }
> > >>
> > >> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
> > >>    save_c = *input_line_pointer;
> > >>    *input_line_pointer = '\0';
> > >>
> > >> -  riscv_mapping_state (MAP_INSN, 0);
> > >> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
> > >>
> > >>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
> > >>                                 &imm_reloc, insn_type_hash);
> > >> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
> > >>    unsigned int i;
> > >>
> > >>    /* Re-write architecture elf attribute.  */
> > >> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
> > >> +  arch_str = riscv_subsets->arch_str;
> > >>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
> > >> -  xfree ((void *) arch_str);
> > >>
> > >>    /* For the file without any instruction, we don't set the default_priv_spec
> > >>       according to the privileged elf attributes since the md_assemble isn't
> > >> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> > >> index 802e7afe670..19c45ba2d12 100644
> > >> --- a/gas/config/tc-riscv.h
> > >> +++ b/gas/config/tc-riscv.h
> > >> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
> > >>  extern int riscv_convert_symbolic_attribute (const char *);
> > >>
> > >>  /* Set mapping symbol states.  */
> > >> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
> > >> -void riscv_mapping_state (enum riscv_seg_mstate, int);
> > >> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
> > >> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
> > >>
> > >>  /* Define target segment type.  */
> > >>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
> > >>  struct riscv_segment_info_type
> > >>  {
> > >>    enum riscv_seg_mstate map_state;
> > >> +  /* The current mapping symbol with architecture string.  */
> > >> +  symbolS *arch_map_symbol;
> > >>  };
> > >>
> > >>  /* Define target fragment type.  */
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> > >> deleted file mode 100644
> > >> index 989463f91ee..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-01.s
> > >> +++ /dev/null
> > >> @@ -1,17 +0,0 @@
> > >> -       .option arch, -c
> > >> -       .text
> > >> -       .global funcA
> > >> -funcA:
> > >> -       add     a0, a0, a0
> > >> -       j       funcB
> > >> -       .global funcB
> > >> -funcB:
> > >> -       add     a1, a1, a1
> > >> -       bne     a0, a1, funcB
> > >> -
> > >> -       .data
> > >> -       .word 0x123456
> > >> -
> > >> -       .section        .foo, "ax"
> > >> -foo:
> > >> -       add     a2, a2, a2
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> > >> deleted file mode 100644
> > >> index 32e0027a13d..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-01a.d
> > >> +++ /dev/null
> > >> @@ -1,17 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-01.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$x
> > >> -0+00 l    d  .foo      0+00 .foo
> > >> -0+00 l       .foo      0+00 foo
> > >> -0+00 l       .foo      0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> -0+00 g       .text     0+00 funcA
> > >> -0+08 g       .text     0+00 funcB
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
> > >> deleted file mode 100644
> > >> index e84b3d608f5..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-01b.d
> > >> +++ /dev/null
> > >> @@ -1,21 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-01.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <funcA>:
> > >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+4:[   ]+0040006f[     ]+j[    ]+8 <funcB>
> > >> -
> > >> -0+008 <funcB>:
> > >> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+c:[   ]+feb51ee3[     ]+bne[  ]+a0,a1,8 <funcB>
> > >> -
> > >> -Disassembly of section .foo:
> > >> -
> > >> -0+000 <foo>:
> > >> -[      ]+0:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> > >> deleted file mode 100644
> > >> index 79468c0d14f..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-02.s
> > >> +++ /dev/null
> > >> @@ -1,12 +0,0 @@
> > >> -       .option arch, -c
> > >> -       .text
> > >> -       .word   1
> > >> -       add     a0, a0, a0
> > >> -
> > >> -       .data
> > >> -       .word   2
> > >> -
> > >> -       .text
> > >> -       add     a1, a1, a1
> > >> -       .short  3
> > >> -       add     a2, a2, a2
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> > >> deleted file mode 100644
> > >> index 333f12cd343..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-02a.d
> > >> +++ /dev/null
> > >> @@ -1,15 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-02.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$d
> > >> -0+04 l       .text     0+00 \$x
> > >> -0+0c l       .text     0+00 \$d
> > >> -0+0e l       .text     0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> > >> deleted file mode 100644
> > >> index 1ed6c081cf7..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-02b.d
> > >> +++ /dev/null
> > >> @@ -1,16 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-02.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <.text>:
> > >> -[      ]+0:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> -[      ]+4:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+c:[   ]+0003[         ]+.short[       ]+0x0003
> > >> -[      ]+e:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
> > >> -#...
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> > >> deleted file mode 100644
> > >> index 88f2601568d..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-03.s
> > >> +++ /dev/null
> > >> @@ -1,11 +0,0 @@
> > >> -       .option arch, -c
> > >> -       .text
> > >> -       add     a0, a0, a0
> > >> -       .long   0
> > >> -       .balign 16
> > >> -       .word   1
> > >> -       add     a1, a1, a1
> > >> -       .byte   2
> > >> -       .long   3
> > >> -       .balign 16
> > >> -       .word   5
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> > >> deleted file mode 100644
> > >> index d3663b663aa..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-03a.d
> > >> +++ /dev/null
> > >> @@ -1,20 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-03.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$x
> > >> -0+04 l       .text     0+00 \$d
> > >> -0+08 l       .text     0+00 \$x
> > >> -0+14 l       .text     0+00 \$d
> > >> -0+18 l       .text     0+00 \$x
> > >> -0+1c l       .text     0+00 \$d
> > >> -0+21 l       .text     0+00 \$x
> > >> -0+2d l       .text     0+00 \$d
> > >> -0+31 l       .text     0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
> > >> deleted file mode 100644
> > >> index f4f67269981..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-03b.d
> > >> +++ /dev/null
> > >> @@ -1,24 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-03.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <.text>:
> > >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> > >> -[      ]+8:[   ]+00000013[     ]+nop
> > >> -[      ]+c:[   ]+00000013[     ]+nop
> > >> -[      ]+10:[  ]+00000013[     ]+nop
> > >> -[      ]+14:[  ]+00000001[     ]+.word[        ]+0x00000001
> > >> -[      ]+18:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+1c:[  ]+00000302[     ]+.word[        ]+0x00000302
> > >> -[      ]+20:[  ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+21:[  ]+00000013[     ]+nop
> > >> -[      ]+25:[  ]+00000013[     ]+nop
> > >> -[      ]+29:[  ]+00000013[     ]+nop
> > >> -[      ]+2d:[  ]+00000005[     ]+.word[        ]+0x00000005
> > >> -#...
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> > >> deleted file mode 100644
> > >> index 804b0397737..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-04.s
> > >> +++ /dev/null
> > >> @@ -1,13 +0,0 @@
> > >> -       .text
> > >> -       .option arch, -c
> > >> -       .fill   2, 4, 0x1001
> > >> -       .byte   1
> > >> -       .word   0
> > >> -       .balign 8
> > >> -       add     a0, a0, a0
> > >> -       .fill   5, 2, 0x2002
> > >> -       add     a1, a1, a1
> > >> -
> > >> -       .data
> > >> -       .word   0x1
> > >> -       .word   0x2
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> > >> deleted file mode 100644
> > >> index 1ae9653212b..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-04a.d
> > >> +++ /dev/null
> > >> @@ -1,15 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-04.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$d
> > >> -0+0d l       .text     0+00 \$x
> > >> -0+15 l       .text     0+00 \$d
> > >> -0+1f l       .text     0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> > >> deleted file mode 100644
> > >> index 54bd0afb6c4..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> > >> +++ /dev/null
> > >> @@ -1,23 +0,0 @@
> > >> -#as:
> > >> -#source: mapping-04.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <.text>:
> > >> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> > >> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> > >> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+d:[   ]+00000013[     ]+nop
> > >> -[      ]+11:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+15:[  ]+20022002[     ]+.word[        ]+0x20022002
> > >> -[      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
> > >> -[      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
> > >> -[      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
> > >> -[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
> > >> -#...
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
> > >> new file mode 100644
> > >> index 00000000000..246f3672ade
> > >> --- /dev/null
> > >> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
> > >> @@ -0,0 +1,84 @@
> > >> +#as:
> > >> +#source: mapping.s
> > >> +#objdump: -d
> > >> +
> > >> +.*:[   ]+file format .*
> > >> +
> > >> +
> > >> +Disassembly of section .text.cross.section.A:
> > >> +
> > >> +0+000 <funcA>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+bffd[         ]+j[    ]+0 <funcA>
> > >> +
> > >> +Disassembly of section .text.corss.section.B:
> > >> +
> > >> +0+000 <funcB>:
> > >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> > >> +[      ]+[0-9a-f]+:[   ]+fffff06f[     ]+j[    ]+0 <funcB>
> > >> +
> > >> +Disassembly of section .text.data:
> > >> +
> > >> +0+000 <.text.data>:
> > >> +[      ]+[0-9a-f]+:[   ]+00000000[     ]+.word[        ]+0x00000000
> > >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> > >> +[      ]+[0-9a-f]+:[   ]+05000302[     ]+.word[        ]+0x05000302
> > >> +
> > >> +Disassembly of section .text.odd.align:
> > >> +
> > >> +0+000 <.text.odd.align>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+01[   ]+.byte[        ]+0x01
> > >> +[      ]+[0-9a-f]+:[   ]+00[   ]+.byte[        ]+0x00
> > >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> > >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> > >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> > >> +
> > >> +Disassembly of section .text.zero.fill.first:
> > >> +
> > >> +0+000 <.text.zero.fill.first>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +
> > >> +Disassembly of section .text.zero.fill.last:
> > >> +
> > >> +0+000 <.text.zero.fill.last>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> > >> +
> > >> +Disassembly of section .text.zero.fill.align.A:
> > >> +
> > >> +0+000 <.text.zero.fill.align.A>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> > >> +
> > >> +Disassembly of section .text.zero.fill.align.B:
> > >> +
> > >> +0+000 <.text.zero.fill.align.B>:
> > >> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> > >> +
> > >> +Disassembly of section .text.last.section:
> > >> +
> > >> +0+000 <.text.last.section>:
> > >> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> +
> > >> +Disassembly of section .text.section.padding:
> > >> +
> > >> +0+000 <.text.section.padding>:
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> > >> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
> > >> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> > >> +
> > >> +Disassembly of section .text.relax.align:
> > >> +
> > >> +0+000 <.text.relax.align>:
> > >> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
> > >> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
> > >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> > >> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
> > >> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
> > >> new file mode 100644
> > >> index 00000000000..f69e719ff30
> > >> --- /dev/null
> > >> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
> > >> @@ -0,0 +1,17 @@
> > >> +#as:
> > >> +#source: mapping-non-arch.s
> > >> +#objdump: --syms --special-syms
> > >> +
> > >> +.*file format.*riscv.*
> > >> +
> > >> +SYMBOL TABLE:
> > >> +00+00 l    d  .text    00+00 .text
> > >> +00+00 l    d  .data    00+00 .data
> > >> +00+00 l    d  .bss     00+00 .bss
> > >> +00+00 l       .text    00+00 \$x
> > >> +00+08 l       .text    00+00 \$d
> > >> +00+0c l       .text    00+00 \$x
> > >> +00+00 l    d  text.A   00+00 text.A
> > >> +00+00 l       text.A   00+00 \$x
> > >> +00+02 l       text.A   00+00 \$d
> > >> +00+00 l    d  .riscv.attributes        00+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
> > >> new file mode 100644
> > >> index 00000000000..03b2d75a5dd
> > >> --- /dev/null
> > >> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
> > >> @@ -0,0 +1,11 @@
> > >> +.attribute arch, "rv32i"
> > >> +.option arch, +c
> > >> +.text
> > >> +addi   a0, zero, 1
> > >> +.align 3
> > >> +.word 0x1
> > >> +addi   a0, zero, 2
> > >> +
> > >> +.section text.A, "ax"
> > >> +addi   a0, zero, 3
> > >> +.word 0x2
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> > >> deleted file mode 100644
> > >> index 916f732b7f7..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> > >> +++ /dev/null
> > >> @@ -1,21 +0,0 @@
> > >> -#as: -mno-relax
> > >> -#source: mapping-03.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$x
> > >> -0+04 l       .text     0+00 \$d
> > >> -0+08 l       .text     0+00 \$x
> > >> -0+10 l       .text     0+00 \$d
> > >> -0+14 l       .text     0+00 \$x
> > >> -0+18 l       .text     0+00 \$d
> > >> -0+20 l       .text     0+00 \$d
> > >> -0+24 l       .text     0+00 \$x
> > >> -0+1d l       .text     0+00 \$d
> > >> -0+1e l       .text     0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> > >> deleted file mode 100644
> > >> index 9e777351d1d..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> > >> +++ /dev/null
> > >> @@ -1,25 +0,0 @@
> > >> -#as: -mno-relax
> > >> -#source: mapping-03.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <.text>:
> > >> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
> > >> -[      ]+8:[   ]+00000013[     ]+nop
> > >> -[      ]+c:[   ]+00000013[     ]+nop
> > >> -[      ]+10:[  ]+00000001[     ]+.word[        ]+0x00000001
> > >> -[      ]+14:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
> > >> -[      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
> > >> -[      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
> > >> -[      ]+24:[  ]+00000013[     ]+nop
> > >> -[      ]+28:[  ]+00000013[     ]+nop
> > >> -[      ]+2c:[  ]+00000013[     ]+nop
> > >> -#...
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> > >> deleted file mode 100644
> > >> index d552a7f632a..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> > >> +++ /dev/null
> > >> @@ -1,16 +0,0 @@
> > >> -#as: -mno-relax
> > >> -#source: mapping-04.s
> > >> -#objdump: --syms --special-syms
> > >> -
> > >> -.*file format.*riscv.*
> > >> -
> > >> -SYMBOL TABLE:
> > >> -0+00 l    d  .text     0+00 .text
> > >> -0+00 l    d  .data     0+00 .data
> > >> -0+00 l    d  .bss      0+00 .bss
> > >> -0+00 l       .text     0+00 \$d
> > >> -0+14 l       .text     0+00 \$d
> > >> -0+1e l       .text     0+00 \$x
> > >> -0+0d l       .text     0+00 \$d
> > >> -0+0e l       .text     0+00 \$x
> > >> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> > >> deleted file mode 100644
> > >> index be668f29220..00000000000
> > >> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> > >> +++ /dev/null
> > >> @@ -1,24 +0,0 @@
> > >> -#as: -mno-relax
> > >> -#source: mapping-04.s
> > >> -#objdump: -d
> > >> -
> > >> -.*:[   ]+file format .*
> > >> -
> > >> -
> > >> -Disassembly of section .text:
> > >> -
> > >> -0+000 <.text>:
> > >> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
> > >> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
> > >> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
> > >> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+d:[   ]+00[   ]+.byte[        ]+0x00
> > >> -[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
> > >> -[      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
> > >> -[      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
> > >> -[      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
> > >> -[      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
> > >> -[      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> > >> -[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
> > >> -[      ]+24:[  ]+00000013[     ]+nop
> > >> -#...
> > >> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
> > >> new file mode 100644
> > >> index 00000000000..83ee6528b79
> > >> --- /dev/null
> > >> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
> > >> @@ -0,0 +1,48 @@
> > >> +#as:
> > >> +#source: mapping.s
> > >> +#objdump: --syms --special-syms
> > >> +
> > >> +.*file format.*riscv.*
> > >> +
> > >> +SYMBOL TABLE:
> > >> +0+00 l    d  .text     0+00 .text
> > >> +0+00 l    d  .data     0+00 .data
> > >> +0+00 l    d  .bss      0+00 .bss
> > >> +0+00 l    d  .text.cross.section.A     0+00 .text.cross.section.A
> > >> +0+00 l       .text.cross.section.A     0+00 \$xrv32i2p1_c2p0
> > >> +0+00 l    d  .text.corss.section.B     0+00 .text.corss.section.B
> > >> +0+00 l       .text.corss.section.B     0+00 \$xrv32i2p1_c2p0
> > >> +0+02 l       .text.corss.section.B     0+00 \$xrv32i2p1
> > >> +0+00 l    d  .text.data        0+00 .text.data
> > >> +0+00 l       .text.data        0+00 \$d
> > >> +0+08 l       .text.data        0+00 \$xrv32i2p1_c2p0
> > >> +0+0c l       .text.data        0+00 \$d
> > >> +0+00 l    d  .text.odd.align   0+00 .text.odd.align
> > >> +0+00 l       .text.odd.align   0+00 \$xrv32i2p1_c2p0
> > >> +0+02 l       .text.odd.align   0+00 \$d
> > >> +0+08 l       .text.odd.align   0+00 \$xrv32i2p1
> > >> +0+00 l    d  .text.zero.fill.first     0+00 .text.zero.fill.first
> > >> +0+00 l       .text.zero.fill.first     0+00 \$xrv32i2p1_c2p0
> > >> +0+00 l    d  .text.zero.fill.last      0+00 .text.zero.fill.last
> > >> +0+00 l       .text.zero.fill.last      0+00 \$xrv32i2p1_c2p0
> > >> +0+02 l       .text.zero.fill.last      0+00 \$x
> > >> +0+00 l    d  .text.zero.fill.align.A   0+00 .text.zero.fill.align.A
> > >> +0+00 l       .text.zero.fill.align.A   0+00 \$xrv32i2p1_c2p0
> > >> +0+00 l    d  .text.zero.fill.align.B   0+00 .text.zero.fill.align.B
> > >> +0+00 l       .text.zero.fill.align.B   0+00 \$xrv32i2p1
> > >> +0+00 l    d  .text.last.section        0+00 .text.last.section
> > >> +0+00 l       .text.last.section        0+00 \$xrv32i2p1
> > >> +0+04 l       .text.last.section        0+00 \$d
> > >> +0+00 l    d  .text.section.padding     0+00 .text.section.padding
> > >> +0+00 l       .text.section.padding     0+00 \$xrv32i2p1_c2p0
> > >> +0+04 l       .text.section.padding     0+00 \$xrv32i2p1_a2p1_c2p0
> > >> +0+06 l       .text.section.padding     0+00 \$d
> > >> +0+00 l    d  .text.relax.align 0+00 .text.relax.align
> > >> +0+00 l       .text.relax.align 0+00 \$xrv32i2p1_c2p0
> > >> +0+08 l       .text.relax.align 0+00 \$xrv32i2p1
> > >> +0+0a l       .text.section.padding     0+00 \$x
> > >> +0+03 l       .text.odd.align   0+00 \$d
> > >> +0+04 l       .text.odd.align   0+00 \$x
> > >> +0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
> > >> +0+00 g       .text.cross.section.A     0+00 funcA
> > >> +0+00 g       .text.corss.section.B     0+00 funcB
> > >> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
> > >> new file mode 100644
> > >> index 00000000000..a0e6c744107
> > >> --- /dev/null
> > >> +++ b/gas/testsuite/gas/riscv/mapping.s
> > >> @@ -0,0 +1,112 @@
> > >> +.attribute arch, "rv32ic"
> > >> +.option norelax                        # FIXME: assembler fill the paddings after parsing everything,
> > >> +                               # so we probably won't fill anything for the norelax region when
> > >> +                               # the riscv_opts.relax is enabled at somewhere.
> > >> +
> > >> +.section .text.cross.section.A, "ax"
> > >> +.option push
> > >> +.global funcA
> > >> +funcA:
> > >> +addi   a0, zero, 1             # rv32i
> > >> +.option arch, +c
> > >> +j      funcA                   # rv32ic
> > >> +.section .text.corss.section.B, "ax"
> > >> +.globl funcB
> > >> +funcB:
> > >> +addi   a0, zero, 2             # rv32ic, need to be added since start of section
> > >> +.option arch, -c
> > >> +j      funcB                   # rv32i
> > >> +.option pop
> > >> +
> > >> +.section .text.data, "ax"
> > >> +.option push
> > >> +.word  0                       # $d
> > >> +.long  1
> > >> +addi   a0, zero, 1             # rv32ic
> > >> +.data
> > >> +.word  2                       # don't add mapping symbols for non-text section
> > >> +.section .text.data
> > >> +addi   a0, zero, 2             # $x, but same as previous addi, so removed
> > >> +.byte  2                       # $d, dumped as .word
> > >> +.short 3
> > >> +.byte  5
> > >> +.option pop
> > >> +
> > >> +.section .text.odd.align, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.option arch, +c
> > >> +addi   a0, zero, 1             # $xrv32ic
> > >> +.byte  1                       # $d
> > >> +.option arch, -c
> > >> +.align 3                       # odd alignment, $x replaced by $d + $x
> > >> +addi   a0, zero, 2             # $xrv32i
> > >> +.option pop
> > >> +
> > >> +.section .text.zero.fill.first, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> > >> +addi   a0, zero, 1             # $xrv32ic
> > >> +.option pop
> > >> +
> > >> +.section .text.zero.fill.last, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +addi   a0, zero, 1             # $xrv32ic
> > >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
> > >> +addi   a0, zero, 2             # $x, FIXME: need find a way to remove?
> > >> +.option pop
> > >> +
> > >> +# last overlap next first
> > >> +.section .text.zero.fill.align.A, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed
> > >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> > >> +addi   a0, zero, 1             # $x, should be removed in riscv_check_mapping_symbols
> > >> +addi   a0, zero, 2
> > >> +.option pop
> > >> +
> > >> +# last overlap next first
> > >> +.section .text.zero.fill.align.B, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
> > >> +                               # but will be removed in riscv_check_mapping_symbols
> > >> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> > >> +.option arch, -c
> > >> +addi   a0, zero, 1             # $xrv32i
> > >> +addi   a0, zero, 2
> > >> +.option pop
> > >> +
> > >> +.section .text.last.section, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.option arch, -c
> > >> +addi   a0, zero, 1             # $xrv32i
> > >> +.word  1                       # $d
> > >> +.align 2                       # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
> > >> +.option pop
> > >> +
> > >> +.section .text.section.padding, "ax"
> > >> +.option push
> > >> +.option norelax
> > >> +.align 2
> > >> +addi   a0, zero, 1             # $rv32ic
> > >> +.option arch, +a
> > >> +.align 2                       # 2-byte padding, $x, removed
> > >> +addi   a0, zero, 2             # $xrv32iac
> > >> +.word  1                       # $d
> > >> +.option pop                    # 2-byte padding, $x
> > >> +
> > >> +.section .text.relax.align, "ax"
> > >> +.option push
> > >> +.option relax
> > >> +.option arch, rv32ic
> > >> +.balign        4                       # $xrv32ic, add at the start of section
> > >> +addi   a0, zero, 1             # $x, won't added
> > >> +.option arch, -c
> > >> +.align 3                       # $x, won't added
> > >> +addi   a0, zero, 2             # $xrv32i
> > >> +.option pop
> > >> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
> > >> index aed4ca8e4d9..1d14c604dec 100644
> > >> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
> > >> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
> > >> @@ -10,5 +10,5 @@ Disassembly of section .text:
> > >>  0+000 <.text>:
> > >>  [      ]+[0-9a-f]+:[   ]+952e[         ]+add[          ]+a0,a0,a1
> > >>  [      ]+[0-9a-f]+:[   ]+00b50533[     ]+add[          ]+a0,a0,a1
> > >> -[      ]+[0-9a-f]+:[   ]+00302573[     ]+csrr[         ]+a0,fcsr
> > >> +[      ]+[0-9a-f]+:[   ]+00302573[     ]+frcsr[                ]+a0
> > >>  #...
> > >> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> > >> index f2d399260c1..eb88c81c0f1 100644
> > >> --- a/opcodes/riscv-dis.c
> > >> +++ b/opcodes/riscv-dis.c
> > >> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
> > >>        /* If arch has ZFINX flags, use gpr for disassemble.  */
> > >>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
> > >>         riscv_fpr_names = riscv_gpr_names;
> > >> +      else
> > >> +       riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
> > >> +                         riscv_fpr_names_abi : riscv_fpr_names_numeric;
> > >>
> > >>        for (; op->name; op++)
> > >>         {
> > >> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
> > >>      *state = MAP_INSN;
> > >>    else if (strcmp (name, "$d") == 0)
> > >>      *state = MAP_DATA;
> > >> +  else if (strncmp (name, "$xrv", 4) == 0)
> > >> +    {
> > >> +      *state = MAP_INSN;
> > >> +      riscv_release_subset_list (&riscv_subsets);
> > >> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
> > >> +    }
> > >>    else
> > >>      return false;
> > >>
> > >> --
> > >> 2.37.0 (Apple Git-136)
> > >>
> > >

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
  2022-10-28  9:23       ` Nelson Chu
@ 2022-10-28 14:43         ` Tsukasa OI
  0 siblings, 0 replies; 9+ messages in thread
From: Tsukasa OI @ 2022-10-28 14:43 UTC (permalink / raw)
  To: Nelson Chu, Kito Cheng, Binutils

[-- Attachment #1: Type: text/plain, Size: 54281 bytes --]

On 2022/10/28 18:23, Nelson Chu wrote:
> Yeah, one of the reasons to push this is because we can merge lots of
> assembler test cases into just one file, so that they should be easier
> to maintain.  For example, merge t-head extensions into one file,
> merge crypto extensions into one file, and merge zic extensions into
> one file, ....  Moreover, for those extensions which have different
> encodings for rv32 and rv64 (gas/testsuite/gas/riscv/ext-32.d and
> ext-64.d), we can also add ".option arch, "rv32ixxx"" and ".option
> arch, "rv64ixxx"" into the same file, so that just one test case
> should be enough.
> 
> I have seen that Tsukasa had sent some similar patches to add more
> assembler test cases, so it would be good if those test cases can be
> merged into as few files as possible.
> 
> Thanks
> Nelson

Ah yes, I sent patches to "split" existing tests but your change will
make this less necessary (not always but most of the time we no longer
need to split them, just use .option push/arch +xxx/pop).

While I'm rebasing my next patchset (RISC-V disassembler) to merge your
changes and investigating minor disassembler behavior, I found a bug in
the assembler (also in the disassembler but disasm bug is very minor and
will be taken care separately).

In certain cases, mapping symbols with ISA string is not emitted from
the assembler even if a non-default architecture is used.  I attached a
memo and submit a possible fix later.

Thanks,
Tsukasa

> 
> On Fri, Oct 28, 2022 at 3:10 PM Kito Cheng <kito.cheng@gmail.com> wrote:
>>
>> Hi Nelson:
>>
>> Awesome, Nelson thanks for pushing this forward!
>>
>> Hi Tsukasa:
>>
>> It's really exciting that we could finally use that to improve disassembler!
>>
>> On Fri, Oct 28, 2022 at 3:02 PM Tsukasa OI via Binutils
>> <binutils@sourceware.org> wrote:
>>>
>>> On 2022/10/28 12:16, Nelson Chu wrote:
>>>> Committed after passing the regression of riscv-gnu-toolchain.
>>>>
>>>> Thanks
>>>> Nelson
>>>
>>> That's great!  My upcoming disassembler optimization heavily depended on
>>> whether this proposal is merged or not.  So, I'm finally ready to submit
>>> next part (small optimizations + core RISC-V disassembler reorganization
>>> for 2 larger optimizations).
>>>
>>> One thing I have to point out (again) is, it fails to build on my
>>> environment (caused by a false positive of GCC's "maybe uninitialized"
>>> variable detection).  I have submitted separate patch for it:
>>>
>>> <https://sourceware.org/pipermail/binutils/2022-October/123952.html>
>>>
>>> Thanks,
>>> Tsukasa
>>>
>>>>
>>>> On Fri, Sep 30, 2022 at 5:21 PM Nelson Chu <nelson@rivosinc.com> wrote:
>>>>>
>>>>> RISC-V Psabi pr196,
>>>>> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
>>>>>
>>>>> bfd/
>>>>>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
>>>>>     (riscv_copy_subset_list): Copy arch_str as well.
>>>>>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
>>>>> gas/
>>>>>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
>>>>>     architecture string in the subset_list.
>>>>>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
>>>>>     architecture string.
>>>>>     (s_riscv_option): Likewise.
>>>>>     (need_arch_map_symbol): New boolean, used to indicate if .option
>>>>>     directives do affect instructions.
>>>>>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
>>>>>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
>>>>>     if reset_seg_arch_str is true.
>>>>>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
>>>>>     now, only add $x+arch if the architecture strings in subset list and segment
>>>>>     are different.  Besides, always add $x+arch at the start of section, and do
>>>>>     not add $x+arch for code alignment, since rvc for alignment can be judged
>>>>>     from addend of R_RISCV_ALIGN.
>>>>>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
>>>>>     same value, then remove the current $x only if the previous is $x+arch;
>>>>>     Otherwise, always remove previous.
>>>>>     (riscv_add_odd_padding_symbol): Updated.
>>>>>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
>>>>>     need_arch_map_symbol is false, so changed them to $x.
>>>>>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
>>>>>     (riscv_init_frag): Likewise.
>>>>>     (s_riscv_insn): Likewise.
>>>>>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
>>>>>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
>>>>>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
>>>>>     from riscv_subsets.
>>>>>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
>>>>>     symbol of each segment.
>>>>>
>>>>>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
>>>>>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
>>>>>     one file.
>>>>>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
>>>>>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
>>>>>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
>>>>>     does need any $x+arch.
>>>>>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
>>>>>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
>>>>> opcodes/
>>>>>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
>>>>>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
>>>>>     for some specfic code region.
>>>>>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
>>>>>     the architecture string once the ISA is different.
>>>>> ---
>>>>>  bfd/elfxx-riscv.c                             |   7 +
>>>>>  bfd/elfxx-riscv.h                             |   1 +
>>>>>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
>>>>>  gas/config/tc-riscv.h                         |   6 +-
>>>>>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
>>>>>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
>>>>>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
>>>>>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
>>>>>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
>>>>>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
>>>>>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
>>>>>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
>>>>>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
>>>>>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
>>>>>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
>>>>>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
>>>>>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
>>>>>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
>>>>>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
>>>>>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
>>>>>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
>>>>>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
>>>>>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
>>>>>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
>>>>>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
>>>>>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
>>>>>  opcodes/riscv-dis.c                           |   9 +
>>>>>  27 files changed, 420 insertions(+), 328 deletions(-)
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>>>>>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
>>>>>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
>>>>>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>>>>>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>>>>>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
>>>>>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
>>>>>
>>>>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>>>>> index c67d4167232..9247350c2c2 100644
>>>>> --- a/bfd/elfxx-riscv.c
>>>>> +++ b/bfd/elfxx-riscv.c
>>>>> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
>>>>>      }
>>>>>
>>>>>    subset_list->tail = NULL;
>>>>> +
>>>>> +  if (subset_list->arch_str != NULL)
>>>>> +    {
>>>>> +      free ((void*) subset_list->arch_str);
>>>>> +      subset_list->arch_str = NULL;
>>>>> +    }
>>>>>  }
>>>>>
>>>>>  /* Parsing extension version.
>>>>> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
>>>>>  {
>>>>>    riscv_subset_list_t *new = xmalloc (sizeof *new);
>>>>>    new->head = riscv_copy_subset (new, subset_list->head);
>>>>> +  new->arch_str = strdup (subset_list->arch_str);
>>>>>    return new;
>>>>>  }
>>>>>
>>>>> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
>>>>> index ea7126bdb4d..e2c1e3c1618 100644
>>>>> --- a/bfd/elfxx-riscv.h
>>>>> +++ b/bfd/elfxx-riscv.h
>>>>> @@ -51,6 +51,7 @@ typedef struct
>>>>>  {
>>>>>    riscv_subset_t *head;
>>>>>    riscv_subset_t *tail;
>>>>> +  const char *arch_str;
>>>>>  } riscv_subset_list_t;
>>>>>
>>>>>  extern void
>>>>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>>>>> index d9f63b11398..99bd0a06d97 100644
>>>>> --- a/gas/config/tc-riscv.c
>>>>> +++ b/gas/config/tc-riscv.c
>>>>> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
>>>>>    true,                        /* check_unknown_prefixed_ext.  */
>>>>>  };
>>>>>
>>>>> +/* Update the architecture string in the subset_list.  */
>>>>> +
>>>>> +static void
>>>>> +riscv_reset_subsets_list_arch_str (void)
>>>>> +{
>>>>> +  if (riscv_subsets->arch_str != NULL)
>>>>> +    free ((void *) riscv_subsets->arch_str);
>>>>> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
>>>>> +}
>>>>> +
>>>>>  /* This structure is used to hold a stack of .option values.  */
>>>>>  struct riscv_option_stack
>>>>>  {
>>>>> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
>>>>>        riscv_subsets = XNEW (riscv_subset_list_t);
>>>>>        riscv_subsets->head = NULL;
>>>>>        riscv_subsets->tail = NULL;
>>>>> +      riscv_subsets->arch_str = NULL;
>>>>>        riscv_rps_as.subset_list = riscv_subsets;
>>>>>      }
>>>>>    riscv_release_subset_list (riscv_subsets);
>>>>>    riscv_parse_subset (&riscv_rps_as, s);
>>>>> +  riscv_reset_subsets_list_arch_str ();
>>>>>
>>>>>    riscv_set_rvc (false);
>>>>>    if (riscv_subset_supports (&riscv_rps_as, "c"))
>>>>> @@ -459,21 +471,37 @@ static char *expr_end;
>>>>>  #define OPCODE_MATCHES(OPCODE, OP) \
>>>>>    (((OPCODE) & MASK_##OP) == MATCH_##OP)
>>>>>
>>>>> +/* Indicate if .option directives do affect instructions.  Set to true means
>>>>> +   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
>>>>> +   should be enough.  */
>>>>> +static bool need_arch_map_symbol = false;
>>>>> +
>>>>>  /* Create a new mapping symbol for the transition to STATE.  */
>>>>>
>>>>>  static void
>>>>>  make_mapping_symbol (enum riscv_seg_mstate state,
>>>>>                      valueT value,
>>>>> -                    fragS *frag)
>>>>> +                    fragS *frag,
>>>>> +                    bool reset_seg_arch_str)
>>>>>  {
>>>>>    const char *name;
>>>>> +  char *buff;
>>>>>    switch (state)
>>>>>      {
>>>>>      case MAP_DATA:
>>>>>        name = "$d";
>>>>>        break;
>>>>>      case MAP_INSN:
>>>>> -      name = "$x";
>>>>> +      if (reset_seg_arch_str)
>>>>> +       {
>>>>> +         const char *isa = riscv_subsets->arch_str;
>>>>> +         size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
>>>>> +         buff = xmalloc (size);
>>>>> +         snprintf (buff, size, "$x%s", isa);
>>>>> +         name = buff;
>>>>> +       }
>>>>> +      else
>>>>> +       name = "$x";
>>>>>        break;
>>>>>      default:
>>>>>        abort ();
>>>>> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>>>>>
>>>>>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
>>>>>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
>>>>> +  if (reset_seg_arch_str)
>>>>> +    {
>>>>> +      /* Store current $x+arch into tc_segment_info.  */
>>>>> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
>>>>> +      xfree ((void *) buff);
>>>>> +    }
>>>>>
>>>>>    /* If .fill or other data filling directive generates zero sized data,
>>>>> -     or we are adding odd alignemnts, then the mapping symbol for the
>>>>> -     following code will have the same value.  */
>>>>> +     then mapping symbol for the following code will have the same value.
>>>>> +
>>>>> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
>>>>> +     and .text.zero.fill.last.  */
>>>>> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
>>>>> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
>>>>>    if (value == 0)
>>>>>      {
>>>>> -       if (frag->tc_frag_data.first_map_symbol != NULL)
>>>>> +      if (first != NULL)
>>>>>         {
>>>>> -         know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
>>>>> -               == S_GET_VALUE (symbol));
>>>>> +         know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
>>>>> +               && first == last);
>>>>>           /* Remove the old one.  */
>>>>> -         symbol_remove (frag->tc_frag_data.first_map_symbol,
>>>>> -                        &symbol_rootP, &symbol_lastP);
>>>>> +         symbol_remove (first, &symbol_rootP, &symbol_lastP);
>>>>>         }
>>>>>        frag->tc_frag_data.first_map_symbol = symbol;
>>>>>      }
>>>>> -  if (frag->tc_frag_data.last_map_symbol != NULL)
>>>>> +  else if (last != NULL)
>>>>>      {
>>>>>        /* The mapping symbols should be added in offset order.  */
>>>>> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
>>>>> -                        <= S_GET_VALUE (symbol));
>>>>> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
>>>>>        /* Remove the old one.  */
>>>>> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
>>>>> -         == S_GET_VALUE (symbol))
>>>>> -       symbol_remove (frag->tc_frag_data.last_map_symbol,
>>>>> -                      &symbol_rootP, &symbol_lastP);
>>>>> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
>>>>> +       symbol_remove (last, &symbol_rootP, &symbol_lastP);
>>>>>      }
>>>>>    frag->tc_frag_data.last_map_symbol = symbol;
>>>>>  }
>>>>> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>>>>>
>>>>>  void
>>>>>  riscv_mapping_state (enum riscv_seg_mstate to_state,
>>>>> -                    int max_chars)
>>>>> +                    int max_chars,
>>>>> +                    bool frag_align_code)
>>>>>  {
>>>>>    enum riscv_seg_mstate from_state =
>>>>>         seg_info (now_seg)->tc_segment_info_data.map_state;
>>>>> +  bool reset_seg_arch_str = false;
>>>>>
>>>>>    if (!SEG_NORMAL (now_seg)
>>>>> -      /* For now I only add the mapping symbols to text sections.
>>>>> +      /* For now we only add the mapping symbols to text sections.
>>>>>          Therefore, the dis-assembler only show the actual contents
>>>>>          distribution for text.  Other sections will be shown as
>>>>>          data without the details.  */
>>>>> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
>>>>>      return;
>>>>>
>>>>>    /* The mapping symbol should be emitted if not in the right
>>>>> -     mapping state  */
>>>>> -  if (from_state == to_state)
>>>>> +     mapping state.  */
>>>>> +  symbolS *seg_arch_symbol =
>>>>> +       seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
>>>>> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
>>>>> +    {
>>>>> +      /* Always add $x+arch at the first instruction of section.  */
>>>>> +      reset_seg_arch_str = true;
>>>>> +    }
>>>>> +  else if (seg_arch_symbol != 0
>>>>> +          && to_state == MAP_INSN
>>>>> +          && !frag_align_code
>>>>> +          && strcmp (riscv_subsets->arch_str,
>>>>> +                     S_GET_NAME (seg_arch_symbol) + 2) != 0)
>>>>> +    {
>>>>> +      reset_seg_arch_str = true;
>>>>> +      need_arch_map_symbol = true;
>>>>> +    }
>>>>> +  else if (from_state == to_state)
>>>>>      return;
>>>>>
>>>>>    valueT value = (valueT) (frag_now_fix () - max_chars);
>>>>>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
>>>>> -  make_mapping_symbol (to_state, value, frag_now);
>>>>> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
>>>>>  }
>>>>>
>>>>>  /* Add the odd bytes of paddings for riscv_handle_align.  */
>>>>> @@ -544,9 +596,27 @@ static void
>>>>>  riscv_add_odd_padding_symbol (fragS *frag)
>>>>>  {
>>>>>    /* If there was already a mapping symbol, it should be
>>>>> -     removed in the make_mapping_symbol.  */
>>>>> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
>>>>> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
>>>>> +     removed in the make_mapping_symbol.
>>>>> +
>>>>> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
>>>>> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
>>>>> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
>>>>> +}
>>>>> +
>>>>> +/* If previous and current mapping symbol have same value, then remove the
>>>>> +   current $x only if the previous is $x+arch; Otherwise, always remove the
>>>>> +   previous.  */
>>>>> +
>>>>> +static void
>>>>> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
>>>>> +{
>>>>> +  know (pre != NULL && cur != NULL
>>>>> +       && S_GET_VALUE (pre) == S_GET_VALUE (cur));
>>>>> +  symbolS *removed = pre;
>>>>> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
>>>>> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
>>>>> +    removed = cur;
>>>>> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
>>>>>  }
>>>>>
>>>>>  /* Remove any excess mapping symbols generated for alignment frags in
>>>>> @@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>>>>>    if (seginfo == NULL || seginfo->frchainP == NULL)
>>>>>      return;
>>>>>
>>>>> +  /* If we don't set any .option arch directive, then the arch_map_symbol
>>>>> +     in each segment must be the first instruction, and we don't need to
>>>>> +     add $x+arch for them.  */
>>>>> +  if (!need_arch_map_symbol
>>>>> +      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
>>>>> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
>>>>> +
>>>>>    for (fragp = seginfo->frchainP->frch_root;
>>>>>         fragp != NULL;
>>>>>         fragp = fragp->fr_next)
>>>>> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>>>>>
>>>>>        do
>>>>>         {
>>>>> -         if (next->tc_frag_data.first_map_symbol != NULL)
>>>>> +         symbolS *next_first = next->tc_frag_data.first_map_symbol;
>>>>> +         if (next_first != NULL)
>>>>>             {
>>>>>               /* The last mapping symbol overlaps with another one
>>>>> -                which at the start of the next frag.  */
>>>>> -             symbol_remove (last, &symbol_rootP, &symbol_lastP);
>>>>> +                which at the start of the next frag.
>>>>> +
>>>>> +                Please see the gas/testsuite/gas/riscv/mapping.s:
>>>>> +                .text.zero.fill.align.A and .text.zero.fill.align.B.  */
>>>>> +             riscv_remove_mapping_symbol (last, next_first);
>>>>>               break;
>>>>>             }
>>>>>
>>>>>           if (next->fr_next == NULL)
>>>>>             {
>>>>> -             /* The last mapping symbol is at the end of the section.  */
>>>>> +             /* The last mapping symbol is at the end of the section.
>>>>> +
>>>>> +                Please see the gas/testsuite/gas/riscv/mapping.s:
>>>>> +                .text.last.section.  */
>>>>>               know (next->fr_fix == 0 && next->fr_var == 0);
>>>>>               symbol_remove (last, &symbol_rootP, &symbol_lastP);
>>>>>               break;
>>>>> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
>>>>>         return;
>>>>>      }
>>>>>
>>>>> -  riscv_mapping_state (MAP_INSN, 0);
>>>>> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>>>>>
>>>>>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>>>>>                                                 &imm_reloc, op_hash);
>>>>> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>>>>>    if (strcmp (name, "rvc") == 0)
>>>>>      {
>>>>>        riscv_update_subset (&riscv_rps_as, "+c");
>>>>> +      riscv_reset_subsets_list_arch_str ();
>>>>>        riscv_set_rvc (true);
>>>>>      }
>>>>>    else if (strcmp (name, "norvc") == 0)
>>>>>      {
>>>>>        riscv_update_subset (&riscv_rps_as, "-c");
>>>>> +      riscv_reset_subsets_list_arch_str ();
>>>>>        riscv_set_rvc (false);
>>>>>      }
>>>>>    else if (strcmp (name, "pic") == 0)
>>>>> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>>>>>        if (ISSPACE (*name) && *name != '\0')
>>>>>         name++;
>>>>>        riscv_update_subset (&riscv_rps_as, name);
>>>>> +      riscv_reset_subsets_list_arch_str ();
>>>>>
>>>>>        riscv_set_rvc (false);
>>>>>        if (riscv_subset_supports (&riscv_rps_as, "c"))
>>>>> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
>>>>>    if (!riscv_opts.relax)
>>>>>      return false;
>>>>>
>>>>> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
>>>>> +     rather than just use frag_more to handle an alignment here?  So that we
>>>>> +     don't need to call riscv_mapping_state again later, and then only need
>>>>> +     to check frag->fr_type to see if it is frag_align_code.  */
>>>>>    nops = frag_more (worst_case_bytes);
>>>>>
>>>>>    ex.X_op = O_constant;
>>>>> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
>>>>>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
>>>>>                &ex, false, BFD_RELOC_RISCV_ALIGN);
>>>>>
>>>>> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
>>>>> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
>>>>>
>>>>>    /* We need to start a new frag after the alignment which may be removed by
>>>>>       the linker, to prevent the assembler from computing static offsets.
>>>>> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
>>>>>      case rs_fill:
>>>>>      case rs_align:
>>>>>      case rs_align_test:
>>>>> -      riscv_mapping_state (MAP_DATA, max_chars);
>>>>> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
>>>>>        break;
>>>>>      case rs_align_code:
>>>>> -      riscv_mapping_state (MAP_INSN, max_chars);
>>>>> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
>>>>>        break;
>>>>>      default:
>>>>>        break;
>>>>> @@ -4418,6 +4509,7 @@ void
>>>>>  riscv_elf_final_processing (void)
>>>>>  {
>>>>>    riscv_set_abi_by_arch ();
>>>>> +  riscv_release_subset_list (riscv_subsets);
>>>>>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
>>>>>  }
>>>>>
>>>>> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>>>>>    save_c = *input_line_pointer;
>>>>>    *input_line_pointer = '\0';
>>>>>
>>>>> -  riscv_mapping_state (MAP_INSN, 0);
>>>>> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>>>>>
>>>>>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>>>>>                                 &imm_reloc, insn_type_hash);
>>>>> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
>>>>>    unsigned int i;
>>>>>
>>>>>    /* Re-write architecture elf attribute.  */
>>>>> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
>>>>> +  arch_str = riscv_subsets->arch_str;
>>>>>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
>>>>> -  xfree ((void *) arch_str);
>>>>>
>>>>>    /* For the file without any instruction, we don't set the default_priv_spec
>>>>>       according to the privileged elf attributes since the md_assemble isn't
>>>>> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
>>>>> index 802e7afe670..19c45ba2d12 100644
>>>>> --- a/gas/config/tc-riscv.h
>>>>> +++ b/gas/config/tc-riscv.h
>>>>> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
>>>>>  extern int riscv_convert_symbolic_attribute (const char *);
>>>>>
>>>>>  /* Set mapping symbol states.  */
>>>>> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
>>>>> -void riscv_mapping_state (enum riscv_seg_mstate, int);
>>>>> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
>>>>> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
>>>>>
>>>>>  /* Define target segment type.  */
>>>>>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
>>>>>  struct riscv_segment_info_type
>>>>>  {
>>>>>    enum riscv_seg_mstate map_state;
>>>>> +  /* The current mapping symbol with architecture string.  */
>>>>> +  symbolS *arch_map_symbol;
>>>>>  };
>>>>>
>>>>>  /* Define target fragment type.  */
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
>>>>> deleted file mode 100644
>>>>> index 989463f91ee..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-01.s
>>>>> +++ /dev/null
>>>>> @@ -1,17 +0,0 @@
>>>>> -       .option arch, -c
>>>>> -       .text
>>>>> -       .global funcA
>>>>> -funcA:
>>>>> -       add     a0, a0, a0
>>>>> -       j       funcB
>>>>> -       .global funcB
>>>>> -funcB:
>>>>> -       add     a1, a1, a1
>>>>> -       bne     a0, a1, funcB
>>>>> -
>>>>> -       .data
>>>>> -       .word 0x123456
>>>>> -
>>>>> -       .section        .foo, "ax"
>>>>> -foo:
>>>>> -       add     a2, a2, a2
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
>>>>> deleted file mode 100644
>>>>> index 32e0027a13d..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-01a.d
>>>>> +++ /dev/null
>>>>> @@ -1,17 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-01.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$x
>>>>> -0+00 l    d  .foo      0+00 .foo
>>>>> -0+00 l       .foo      0+00 foo
>>>>> -0+00 l       .foo      0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> -0+00 g       .text     0+00 funcA
>>>>> -0+08 g       .text     0+00 funcB
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
>>>>> deleted file mode 100644
>>>>> index e84b3d608f5..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-01b.d
>>>>> +++ /dev/null
>>>>> @@ -1,21 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-01.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <funcA>:
>>>>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+4:[   ]+0040006f[     ]+j[    ]+8 <funcB>
>>>>> -
>>>>> -0+008 <funcB>:
>>>>> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+c:[   ]+feb51ee3[     ]+bne[  ]+a0,a1,8 <funcB>
>>>>> -
>>>>> -Disassembly of section .foo:
>>>>> -
>>>>> -0+000 <foo>:
>>>>> -[      ]+0:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
>>>>> deleted file mode 100644
>>>>> index 79468c0d14f..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-02.s
>>>>> +++ /dev/null
>>>>> @@ -1,12 +0,0 @@
>>>>> -       .option arch, -c
>>>>> -       .text
>>>>> -       .word   1
>>>>> -       add     a0, a0, a0
>>>>> -
>>>>> -       .data
>>>>> -       .word   2
>>>>> -
>>>>> -       .text
>>>>> -       add     a1, a1, a1
>>>>> -       .short  3
>>>>> -       add     a2, a2, a2
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
>>>>> deleted file mode 100644
>>>>> index 333f12cd343..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-02a.d
>>>>> +++ /dev/null
>>>>> @@ -1,15 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-02.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$d
>>>>> -0+04 l       .text     0+00 \$x
>>>>> -0+0c l       .text     0+00 \$d
>>>>> -0+0e l       .text     0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
>>>>> deleted file mode 100644
>>>>> index 1ed6c081cf7..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-02b.d
>>>>> +++ /dev/null
>>>>> @@ -1,16 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-02.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <.text>:
>>>>> -[      ]+0:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> -[      ]+4:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+8:[   ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+c:[   ]+0003[         ]+.short[       ]+0x0003
>>>>> -[      ]+e:[   ]+00c60633[     ]+add[  ]+a2,a2,a2
>>>>> -#...
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
>>>>> deleted file mode 100644
>>>>> index 88f2601568d..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-03.s
>>>>> +++ /dev/null
>>>>> @@ -1,11 +0,0 @@
>>>>> -       .option arch, -c
>>>>> -       .text
>>>>> -       add     a0, a0, a0
>>>>> -       .long   0
>>>>> -       .balign 16
>>>>> -       .word   1
>>>>> -       add     a1, a1, a1
>>>>> -       .byte   2
>>>>> -       .long   3
>>>>> -       .balign 16
>>>>> -       .word   5
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
>>>>> deleted file mode 100644
>>>>> index d3663b663aa..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-03a.d
>>>>> +++ /dev/null
>>>>> @@ -1,20 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-03.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$x
>>>>> -0+04 l       .text     0+00 \$d
>>>>> -0+08 l       .text     0+00 \$x
>>>>> -0+14 l       .text     0+00 \$d
>>>>> -0+18 l       .text     0+00 \$x
>>>>> -0+1c l       .text     0+00 \$d
>>>>> -0+21 l       .text     0+00 \$x
>>>>> -0+2d l       .text     0+00 \$d
>>>>> -0+31 l       .text     0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
>>>>> deleted file mode 100644
>>>>> index f4f67269981..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-03b.d
>>>>> +++ /dev/null
>>>>> @@ -1,24 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-03.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <.text>:
>>>>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
>>>>> -[      ]+8:[   ]+00000013[     ]+nop
>>>>> -[      ]+c:[   ]+00000013[     ]+nop
>>>>> -[      ]+10:[  ]+00000013[     ]+nop
>>>>> -[      ]+14:[  ]+00000001[     ]+.word[        ]+0x00000001
>>>>> -[      ]+18:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+1c:[  ]+00000302[     ]+.word[        ]+0x00000302
>>>>> -[      ]+20:[  ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+21:[  ]+00000013[     ]+nop
>>>>> -[      ]+25:[  ]+00000013[     ]+nop
>>>>> -[      ]+29:[  ]+00000013[     ]+nop
>>>>> -[      ]+2d:[  ]+00000005[     ]+.word[        ]+0x00000005
>>>>> -#...
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
>>>>> deleted file mode 100644
>>>>> index 804b0397737..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-04.s
>>>>> +++ /dev/null
>>>>> @@ -1,13 +0,0 @@
>>>>> -       .text
>>>>> -       .option arch, -c
>>>>> -       .fill   2, 4, 0x1001
>>>>> -       .byte   1
>>>>> -       .word   0
>>>>> -       .balign 8
>>>>> -       add     a0, a0, a0
>>>>> -       .fill   5, 2, 0x2002
>>>>> -       add     a1, a1, a1
>>>>> -
>>>>> -       .data
>>>>> -       .word   0x1
>>>>> -       .word   0x2
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
>>>>> deleted file mode 100644
>>>>> index 1ae9653212b..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-04a.d
>>>>> +++ /dev/null
>>>>> @@ -1,15 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-04.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$d
>>>>> -0+0d l       .text     0+00 \$x
>>>>> -0+15 l       .text     0+00 \$d
>>>>> -0+1f l       .text     0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
>>>>> deleted file mode 100644
>>>>> index 54bd0afb6c4..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-04b.d
>>>>> +++ /dev/null
>>>>> @@ -1,23 +0,0 @@
>>>>> -#as:
>>>>> -#source: mapping-04.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <.text>:
>>>>> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
>>>>> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
>>>>> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+d:[   ]+00000013[     ]+nop
>>>>> -[      ]+11:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+15:[  ]+20022002[     ]+.word[        ]+0x20022002
>>>>> -[      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
>>>>> -[      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
>>>>> -[      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
>>>>> -[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
>>>>> -#...
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
>>>>> new file mode 100644
>>>>> index 00000000000..246f3672ade
>>>>> --- /dev/null
>>>>> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
>>>>> @@ -0,0 +1,84 @@
>>>>> +#as:
>>>>> +#source: mapping.s
>>>>> +#objdump: -d
>>>>> +
>>>>> +.*:[   ]+file format .*
>>>>> +
>>>>> +
>>>>> +Disassembly of section .text.cross.section.A:
>>>>> +
>>>>> +0+000 <funcA>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+bffd[         ]+j[    ]+0 <funcA>
>>>>> +
>>>>> +Disassembly of section .text.corss.section.B:
>>>>> +
>>>>> +0+000 <funcB>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>>>>> +[      ]+[0-9a-f]+:[   ]+fffff06f[     ]+j[    ]+0 <funcB>
>>>>> +
>>>>> +Disassembly of section .text.data:
>>>>> +
>>>>> +0+000 <.text.data>:
>>>>> +[      ]+[0-9a-f]+:[   ]+00000000[     ]+.word[        ]+0x00000000
>>>>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>>>>> +[      ]+[0-9a-f]+:[   ]+05000302[     ]+.word[        ]+0x05000302
>>>>> +
>>>>> +Disassembly of section .text.odd.align:
>>>>> +
>>>>> +0+000 <.text.odd.align>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+01[   ]+.byte[        ]+0x01
>>>>> +[      ]+[0-9a-f]+:[   ]+00[   ]+.byte[        ]+0x00
>>>>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>>>>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>>>>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>>>>> +
>>>>> +Disassembly of section .text.zero.fill.first:
>>>>> +
>>>>> +0+000 <.text.zero.fill.first>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +
>>>>> +Disassembly of section .text.zero.fill.last:
>>>>> +
>>>>> +0+000 <.text.zero.fill.last>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>>>>> +
>>>>> +Disassembly of section .text.zero.fill.align.A:
>>>>> +
>>>>> +0+000 <.text.zero.fill.align.A>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>>>>> +
>>>>> +Disassembly of section .text.zero.fill.align.B:
>>>>> +
>>>>> +0+000 <.text.zero.fill.align.B>:
>>>>> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>>>>> +
>>>>> +Disassembly of section .text.last.section:
>>>>> +
>>>>> +0+000 <.text.last.section>:
>>>>> +[      ]+[0-9a-f]+:[   ]+00100513[     ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> +
>>>>> +Disassembly of section .text.section.padding:
>>>>> +
>>>>> +0+000 <.text.section.padding>:
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>>>>> +[      ]+[0-9a-f]+:[   ]+4509[         ]+li[   ]+a0,2
>>>>> +[      ]+[0-9a-f]+:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>>>>> +
>>>>> +Disassembly of section .text.relax.align:
>>>>> +
>>>>> +0+000 <.text.relax.align>:
>>>>> +[      ]+[0-9a-f]+:[   ]+0001[         ]+nop
>>>>> +[      ]+[0-9a-f]+:[   ]+4505[         ]+li[   ]+a0,1
>>>>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>>>>> +[      ]+[0-9a-f]+:[   ]+00200513[     ]+li[   ]+a0,2
>>>>> +[      ]+[0-9a-f]+:[   ]+00000013[     ]+nop
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
>>>>> new file mode 100644
>>>>> index 00000000000..f69e719ff30
>>>>> --- /dev/null
>>>>> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
>>>>> @@ -0,0 +1,17 @@
>>>>> +#as:
>>>>> +#source: mapping-non-arch.s
>>>>> +#objdump: --syms --special-syms
>>>>> +
>>>>> +.*file format.*riscv.*
>>>>> +
>>>>> +SYMBOL TABLE:
>>>>> +00+00 l    d  .text    00+00 .text
>>>>> +00+00 l    d  .data    00+00 .data
>>>>> +00+00 l    d  .bss     00+00 .bss
>>>>> +00+00 l       .text    00+00 \$x
>>>>> +00+08 l       .text    00+00 \$d
>>>>> +00+0c l       .text    00+00 \$x
>>>>> +00+00 l    d  text.A   00+00 text.A
>>>>> +00+00 l       text.A   00+00 \$x
>>>>> +00+02 l       text.A   00+00 \$d
>>>>> +00+00 l    d  .riscv.attributes        00+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
>>>>> new file mode 100644
>>>>> index 00000000000..03b2d75a5dd
>>>>> --- /dev/null
>>>>> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
>>>>> @@ -0,0 +1,11 @@
>>>>> +.attribute arch, "rv32i"
>>>>> +.option arch, +c
>>>>> +.text
>>>>> +addi   a0, zero, 1
>>>>> +.align 3
>>>>> +.word 0x1
>>>>> +addi   a0, zero, 2
>>>>> +
>>>>> +.section text.A, "ax"
>>>>> +addi   a0, zero, 3
>>>>> +.word 0x2
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
>>>>> deleted file mode 100644
>>>>> index 916f732b7f7..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
>>>>> +++ /dev/null
>>>>> @@ -1,21 +0,0 @@
>>>>> -#as: -mno-relax
>>>>> -#source: mapping-03.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$x
>>>>> -0+04 l       .text     0+00 \$d
>>>>> -0+08 l       .text     0+00 \$x
>>>>> -0+10 l       .text     0+00 \$d
>>>>> -0+14 l       .text     0+00 \$x
>>>>> -0+18 l       .text     0+00 \$d
>>>>> -0+20 l       .text     0+00 \$d
>>>>> -0+24 l       .text     0+00 \$x
>>>>> -0+1d l       .text     0+00 \$d
>>>>> -0+1e l       .text     0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
>>>>> deleted file mode 100644
>>>>> index 9e777351d1d..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
>>>>> +++ /dev/null
>>>>> @@ -1,25 +0,0 @@
>>>>> -#as: -mno-relax
>>>>> -#source: mapping-03.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <.text>:
>>>>> -[      ]+0:[   ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+4:[   ]+00000000[     ]+.word[        ]+0x00000000
>>>>> -[      ]+8:[   ]+00000013[     ]+nop
>>>>> -[      ]+c:[   ]+00000013[     ]+nop
>>>>> -[      ]+10:[  ]+00000001[     ]+.word[        ]+0x00000001
>>>>> -[      ]+14:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
>>>>> -[      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
>>>>> -[      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
>>>>> -[      ]+24:[  ]+00000013[     ]+nop
>>>>> -[      ]+28:[  ]+00000013[     ]+nop
>>>>> -[      ]+2c:[  ]+00000013[     ]+nop
>>>>> -#...
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
>>>>> deleted file mode 100644
>>>>> index d552a7f632a..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
>>>>> +++ /dev/null
>>>>> @@ -1,16 +0,0 @@
>>>>> -#as: -mno-relax
>>>>> -#source: mapping-04.s
>>>>> -#objdump: --syms --special-syms
>>>>> -
>>>>> -.*file format.*riscv.*
>>>>> -
>>>>> -SYMBOL TABLE:
>>>>> -0+00 l    d  .text     0+00 .text
>>>>> -0+00 l    d  .data     0+00 .data
>>>>> -0+00 l    d  .bss      0+00 .bss
>>>>> -0+00 l       .text     0+00 \$d
>>>>> -0+14 l       .text     0+00 \$d
>>>>> -0+1e l       .text     0+00 \$x
>>>>> -0+0d l       .text     0+00 \$d
>>>>> -0+0e l       .text     0+00 \$x
>>>>> -0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
>>>>> deleted file mode 100644
>>>>> index be668f29220..00000000000
>>>>> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
>>>>> +++ /dev/null
>>>>> @@ -1,24 +0,0 @@
>>>>> -#as: -mno-relax
>>>>> -#source: mapping-04.s
>>>>> -#objdump: -d
>>>>> -
>>>>> -.*:[   ]+file format .*
>>>>> -
>>>>> -
>>>>> -Disassembly of section .text:
>>>>> -
>>>>> -0+000 <.text>:
>>>>> -[      ]+0:[   ]+00001001[     ]+.word[        ]+0x00001001
>>>>> -[      ]+4:[   ]+00001001[     ]+.word[        ]+0x00001001
>>>>> -[      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
>>>>> -[      ]+c:[   ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+d:[   ]+00[   ]+.byte[        ]+0x00
>>>>> -[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
>>>>> -[      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
>>>>> -[      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
>>>>> -[      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
>>>>> -[      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
>>>>> -[      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
>>>>> -[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
>>>>> -[      ]+24:[  ]+00000013[     ]+nop
>>>>> -#...
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
>>>>> new file mode 100644
>>>>> index 00000000000..83ee6528b79
>>>>> --- /dev/null
>>>>> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
>>>>> @@ -0,0 +1,48 @@
>>>>> +#as:
>>>>> +#source: mapping.s
>>>>> +#objdump: --syms --special-syms
>>>>> +
>>>>> +.*file format.*riscv.*
>>>>> +
>>>>> +SYMBOL TABLE:
>>>>> +0+00 l    d  .text     0+00 .text
>>>>> +0+00 l    d  .data     0+00 .data
>>>>> +0+00 l    d  .bss      0+00 .bss
>>>>> +0+00 l    d  .text.cross.section.A     0+00 .text.cross.section.A
>>>>> +0+00 l       .text.cross.section.A     0+00 \$xrv32i2p1_c2p0
>>>>> +0+00 l    d  .text.corss.section.B     0+00 .text.corss.section.B
>>>>> +0+00 l       .text.corss.section.B     0+00 \$xrv32i2p1_c2p0
>>>>> +0+02 l       .text.corss.section.B     0+00 \$xrv32i2p1
>>>>> +0+00 l    d  .text.data        0+00 .text.data
>>>>> +0+00 l       .text.data        0+00 \$d
>>>>> +0+08 l       .text.data        0+00 \$xrv32i2p1_c2p0
>>>>> +0+0c l       .text.data        0+00 \$d
>>>>> +0+00 l    d  .text.odd.align   0+00 .text.odd.align
>>>>> +0+00 l       .text.odd.align   0+00 \$xrv32i2p1_c2p0
>>>>> +0+02 l       .text.odd.align   0+00 \$d
>>>>> +0+08 l       .text.odd.align   0+00 \$xrv32i2p1
>>>>> +0+00 l    d  .text.zero.fill.first     0+00 .text.zero.fill.first
>>>>> +0+00 l       .text.zero.fill.first     0+00 \$xrv32i2p1_c2p0
>>>>> +0+00 l    d  .text.zero.fill.last      0+00 .text.zero.fill.last
>>>>> +0+00 l       .text.zero.fill.last      0+00 \$xrv32i2p1_c2p0
>>>>> +0+02 l       .text.zero.fill.last      0+00 \$x
>>>>> +0+00 l    d  .text.zero.fill.align.A   0+00 .text.zero.fill.align.A
>>>>> +0+00 l       .text.zero.fill.align.A   0+00 \$xrv32i2p1_c2p0
>>>>> +0+00 l    d  .text.zero.fill.align.B   0+00 .text.zero.fill.align.B
>>>>> +0+00 l       .text.zero.fill.align.B   0+00 \$xrv32i2p1
>>>>> +0+00 l    d  .text.last.section        0+00 .text.last.section
>>>>> +0+00 l       .text.last.section        0+00 \$xrv32i2p1
>>>>> +0+04 l       .text.last.section        0+00 \$d
>>>>> +0+00 l    d  .text.section.padding     0+00 .text.section.padding
>>>>> +0+00 l       .text.section.padding     0+00 \$xrv32i2p1_c2p0
>>>>> +0+04 l       .text.section.padding     0+00 \$xrv32i2p1_a2p1_c2p0
>>>>> +0+06 l       .text.section.padding     0+00 \$d
>>>>> +0+00 l    d  .text.relax.align 0+00 .text.relax.align
>>>>> +0+00 l       .text.relax.align 0+00 \$xrv32i2p1_c2p0
>>>>> +0+08 l       .text.relax.align 0+00 \$xrv32i2p1
>>>>> +0+0a l       .text.section.padding     0+00 \$x
>>>>> +0+03 l       .text.odd.align   0+00 \$d
>>>>> +0+04 l       .text.odd.align   0+00 \$x
>>>>> +0+00 l    d  .riscv.attributes 0+00 .riscv.attributes
>>>>> +0+00 g       .text.cross.section.A     0+00 funcA
>>>>> +0+00 g       .text.corss.section.B     0+00 funcB
>>>>> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
>>>>> new file mode 100644
>>>>> index 00000000000..a0e6c744107
>>>>> --- /dev/null
>>>>> +++ b/gas/testsuite/gas/riscv/mapping.s
>>>>> @@ -0,0 +1,112 @@
>>>>> +.attribute arch, "rv32ic"
>>>>> +.option norelax                        # FIXME: assembler fill the paddings after parsing everything,
>>>>> +                               # so we probably won't fill anything for the norelax region when
>>>>> +                               # the riscv_opts.relax is enabled at somewhere.
>>>>> +
>>>>> +.section .text.cross.section.A, "ax"
>>>>> +.option push
>>>>> +.global funcA
>>>>> +funcA:
>>>>> +addi   a0, zero, 1             # rv32i
>>>>> +.option arch, +c
>>>>> +j      funcA                   # rv32ic
>>>>> +.section .text.corss.section.B, "ax"
>>>>> +.globl funcB
>>>>> +funcB:
>>>>> +addi   a0, zero, 2             # rv32ic, need to be added since start of section
>>>>> +.option arch, -c
>>>>> +j      funcB                   # rv32i
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.data, "ax"
>>>>> +.option push
>>>>> +.word  0                       # $d
>>>>> +.long  1
>>>>> +addi   a0, zero, 1             # rv32ic
>>>>> +.data
>>>>> +.word  2                       # don't add mapping symbols for non-text section
>>>>> +.section .text.data
>>>>> +addi   a0, zero, 2             # $x, but same as previous addi, so removed
>>>>> +.byte  2                       # $d, dumped as .word
>>>>> +.short 3
>>>>> +.byte  5
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.odd.align, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.option arch, +c
>>>>> +addi   a0, zero, 1             # $xrv32ic
>>>>> +.byte  1                       # $d
>>>>> +.option arch, -c
>>>>> +.align 3                       # odd alignment, $x replaced by $d + $x
>>>>> +addi   a0, zero, 2             # $xrv32i
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.zero.fill.first, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
>>>>> +addi   a0, zero, 1             # $xrv32ic
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.zero.fill.last, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +addi   a0, zero, 1             # $xrv32ic
>>>>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol
>>>>> +addi   a0, zero, 2             # $x, FIXME: need find a way to remove?
>>>>> +.option pop
>>>>> +
>>>>> +# last overlap next first
>>>>> +.section .text.zero.fill.align.A, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed
>>>>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
>>>>> +addi   a0, zero, 1             # $x, should be removed in riscv_check_mapping_symbols
>>>>> +addi   a0, zero, 2
>>>>> +.option pop
>>>>> +
>>>>> +# last overlap next first
>>>>> +.section .text.zero.fill.align.B, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.align 2                       # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
>>>>> +                               # but will be removed in riscv_check_mapping_symbols
>>>>> +.fill  1, 0, 0                 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
>>>>> +.option arch, -c
>>>>> +addi   a0, zero, 1             # $xrv32i
>>>>> +addi   a0, zero, 2
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.last.section, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.option arch, -c
>>>>> +addi   a0, zero, 1             # $xrv32i
>>>>> +.word  1                       # $d
>>>>> +.align 2                       # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
>>>>> +.option pop
>>>>> +
>>>>> +.section .text.section.padding, "ax"
>>>>> +.option push
>>>>> +.option norelax
>>>>> +.align 2
>>>>> +addi   a0, zero, 1             # $rv32ic
>>>>> +.option arch, +a
>>>>> +.align 2                       # 2-byte padding, $x, removed
>>>>> +addi   a0, zero, 2             # $xrv32iac
>>>>> +.word  1                       # $d
>>>>> +.option pop                    # 2-byte padding, $x
>>>>> +
>>>>> +.section .text.relax.align, "ax"
>>>>> +.option push
>>>>> +.option relax
>>>>> +.option arch, rv32ic
>>>>> +.balign        4                       # $xrv32ic, add at the start of section
>>>>> +addi   a0, zero, 1             # $x, won't added
>>>>> +.option arch, -c
>>>>> +.align 3                       # $x, won't added
>>>>> +addi   a0, zero, 2             # $xrv32i
>>>>> +.option pop
>>>>> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
>>>>> index aed4ca8e4d9..1d14c604dec 100644
>>>>> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
>>>>> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
>>>>> @@ -10,5 +10,5 @@ Disassembly of section .text:
>>>>>  0+000 <.text>:
>>>>>  [      ]+[0-9a-f]+:[   ]+952e[         ]+add[          ]+a0,a0,a1
>>>>>  [      ]+[0-9a-f]+:[   ]+00b50533[     ]+add[          ]+a0,a0,a1
>>>>> -[      ]+[0-9a-f]+:[   ]+00302573[     ]+csrr[         ]+a0,fcsr
>>>>> +[      ]+[0-9a-f]+:[   ]+00302573[     ]+frcsr[                ]+a0
>>>>>  #...
>>>>> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>>>>> index f2d399260c1..eb88c81c0f1 100644
>>>>> --- a/opcodes/riscv-dis.c
>>>>> +++ b/opcodes/riscv-dis.c
>>>>> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>>>>>        /* If arch has ZFINX flags, use gpr for disassemble.  */
>>>>>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
>>>>>         riscv_fpr_names = riscv_gpr_names;
>>>>> +      else
>>>>> +       riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
>>>>> +                         riscv_fpr_names_abi : riscv_fpr_names_numeric;
>>>>>
>>>>>        for (; op->name; op++)
>>>>>         {
>>>>> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
>>>>>      *state = MAP_INSN;
>>>>>    else if (strcmp (name, "$d") == 0)
>>>>>      *state = MAP_DATA;
>>>>> +  else if (strncmp (name, "$xrv", 4) == 0)
>>>>> +    {
>>>>> +      *state = MAP_INSN;
>>>>> +      riscv_release_subset_list (&riscv_subsets);
>>>>> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
>>>>> +    }
>>>>>    else
>>>>>      return false;
>>>>>
>>>>> --
>>>>> 2.37.0 (Apple Git-136)
>>>>>
>>>>
> 

[-- Attachment #2: binutils-riscv-gas-bug-reproduction-20221028.tar.xz --]
[-- Type: application/octet-stream, Size: 1568 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
@ 2022-09-30  8:58 Nelson Chu
  0 siblings, 0 replies; 9+ messages in thread
From: Nelson Chu @ 2022-09-30  8:58 UTC (permalink / raw)
  To: binutils, kito.cheng, jrtc27, i; +Cc: nelson

RISC-V Psabi pr196,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196

bfd/
    * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
    (riscv_copy_subset_list): Copy arch_str as well.
    * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
gas/
    * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
    architecture string in the subset_list.
    (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
    architecture string.
    (s_riscv_option): Likewise.
    (need_arch_map_symbol): New boolean, used to indicate if .option
    directives do affect instructions.
    (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
    generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
    if reset_seg_arch_str is true.
    (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
    now, only add $x+arch if the architecture strings in subset list and segment
    are different.  Besides, always add $x+arch at the start of section, and do
    not add $x+arch for code alignment, since rvc for alignment can be judged
    from addend of R_RISCV_ALIGN.
    (riscv_remove_mapping_symbol): If current and previous mapping symbol have
    same value, then remove the current $x only if the previous is $x+arch;
    Otherwise, always remove previous.
    (riscv_add_odd_padding_symbol): Updated.
    (riscv_check_mapping_symbols): Don't need to add any $x+arch if
    need_arch_map_symbol is false, so changed them to $x.
    (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
    (riscv_init_frag): Likewise.
    (s_riscv_insn): Likewise.
    (riscv_elf_final_processing): Call riscv_release_subset_list to release
    riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
    (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
    from riscv_subsets.
    * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
    symbol of each segment.

    * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
    * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
    one file.
    * testsuite/gas/riscv/mapping-symbols.d: Likewise.
    * testsuite/gas/riscv/mapping-dis.d: Likewise.
    * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
    does need any $x+arch.
    * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
    * testsuite/gas/riscv/option-arch-01a.d: Updated.
opcodes/
    * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
    riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
    for some specfic code region.
    (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
    the architecture string once the ISA is different.
---
 bfd/elfxx-riscv.c                             |   7 +
 bfd/elfxx-riscv.h                             |   1 +
 gas/config/tc-riscv.c                         | 161 ++++++++++++++----
 gas/config/tc-riscv.h                         |   6 +-
 gas/testsuite/gas/riscv/mapping-01.s          |  17 --
 gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
 gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
 gas/testsuite/gas/riscv/mapping-02.s          |  12 --
 gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
 gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
 gas/testsuite/gas/riscv/mapping-03.s          |  11 --
 gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
 gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
 gas/testsuite/gas/riscv/mapping-04.s          |  13 --
 gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
 gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
 gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
 gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
 gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
 gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
 gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
 gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
 gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
 gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
 gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
 gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
 opcodes/riscv-dis.c                           |   9 +
 27 files changed, 420 insertions(+), 328 deletions(-)
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
 delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
 create mode 100644 gas/testsuite/gas/riscv/mapping.s

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index c67d4167232..9247350c2c2 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
     }
 
   subset_list->tail = NULL;
+
+  if (subset_list->arch_str != NULL)
+    {
+      free ((void*) subset_list->arch_str);
+      subset_list->arch_str = NULL;
+    }
 }
 
 /* Parsing extension version.
@@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
 {
   riscv_subset_list_t *new = xmalloc (sizeof *new);
   new->head = riscv_copy_subset (new, subset_list->head);
+  new->arch_str = strdup (subset_list->arch_str);
   return new;
 }
 
diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
index ea7126bdb4d..e2c1e3c1618 100644
--- a/bfd/elfxx-riscv.h
+++ b/bfd/elfxx-riscv.h
@@ -51,6 +51,7 @@ typedef struct
 {
   riscv_subset_t *head;
   riscv_subset_t *tail;
+  const char *arch_str;
 } riscv_subset_list_t;
 
 extern void
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index d9f63b11398..99bd0a06d97 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
   true,			/* check_unknown_prefixed_ext.  */
 };
 
+/* Update the architecture string in the subset_list.  */
+
+static void
+riscv_reset_subsets_list_arch_str (void)
+{
+  if (riscv_subsets->arch_str != NULL)
+    free ((void *) riscv_subsets->arch_str);
+  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
+}
+
 /* This structure is used to hold a stack of .option values.  */
 struct riscv_option_stack
 {
@@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
       riscv_subsets = XNEW (riscv_subset_list_t);
       riscv_subsets->head = NULL;
       riscv_subsets->tail = NULL;
+      riscv_subsets->arch_str = NULL;
       riscv_rps_as.subset_list = riscv_subsets;
     }
   riscv_release_subset_list (riscv_subsets);
   riscv_parse_subset (&riscv_rps_as, s);
+  riscv_reset_subsets_list_arch_str ();
 
   riscv_set_rvc (false);
   if (riscv_subset_supports (&riscv_rps_as, "c"))
@@ -459,21 +471,37 @@ static char *expr_end;
 #define OPCODE_MATCHES(OPCODE, OP) \
   (((OPCODE) & MASK_##OP) == MATCH_##OP)
 
+/* Indicate if .option directives do affect instructions.  Set to true means
+   we need to add $x+arch at somewhere; Otherwise just add $x for instructions
+   should be enough.  */
+static bool need_arch_map_symbol = false;
+
 /* Create a new mapping symbol for the transition to STATE.  */
 
 static void
 make_mapping_symbol (enum riscv_seg_mstate state,
 		     valueT value,
-		     fragS *frag)
+		     fragS *frag,
+		     bool reset_seg_arch_str)
 {
   const char *name;
+  char *buff;
   switch (state)
     {
     case MAP_DATA:
       name = "$d";
       break;
     case MAP_INSN:
-      name = "$x";
+      if (reset_seg_arch_str)
+	{
+	  const char *isa = riscv_subsets->arch_str;
+	  size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
+	  buff = xmalloc (size);
+	  snprintf (buff, size, "$x%s", isa);
+	  name = buff;
+	}
+      else
+	name = "$x";
       break;
     default:
       abort ();
@@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
 
   symbolS *symbol = symbol_new (name, now_seg, frag, value);
   symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
+  if (reset_seg_arch_str)
+    {
+      /* Store current $x+arch into tc_segment_info.  */
+      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
+      xfree ((void *) buff);
+    }
 
   /* If .fill or other data filling directive generates zero sized data,
-     or we are adding odd alignemnts, then the mapping symbol for the
-     following code will have the same value.  */
+     then mapping symbol for the following code will have the same value.
+
+     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
+     and .text.zero.fill.last.  */
+  symbolS *first = frag->tc_frag_data.first_map_symbol;
+  symbolS *last = frag->tc_frag_data.last_map_symbol;
   if (value == 0)
     {
-       if (frag->tc_frag_data.first_map_symbol != NULL)
+      if (first != NULL)
 	{
-	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
-		== S_GET_VALUE (symbol));
+	  know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
+		&& first == last);
 	  /* Remove the old one.  */
-	  symbol_remove (frag->tc_frag_data.first_map_symbol,
-			 &symbol_rootP, &symbol_lastP);
+	  symbol_remove (first, &symbol_rootP, &symbol_lastP);
 	}
       frag->tc_frag_data.first_map_symbol = symbol;
     }
-  if (frag->tc_frag_data.last_map_symbol != NULL)
+  else if (last != NULL)
     {
       /* The mapping symbols should be added in offset order.  */
-      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
-			 <= S_GET_VALUE (symbol));
+      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
       /* Remove the old one.  */
-      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
-	  == S_GET_VALUE (symbol))
-	symbol_remove (frag->tc_frag_data.last_map_symbol,
-		       &symbol_rootP, &symbol_lastP);
+      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
+	symbol_remove (last, &symbol_rootP, &symbol_lastP);
     }
   frag->tc_frag_data.last_map_symbol = symbol;
 }
@@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
 
 void
 riscv_mapping_state (enum riscv_seg_mstate to_state,
-		     int max_chars)
+		     int max_chars,
+		     bool frag_align_code)
 {
   enum riscv_seg_mstate from_state =
 	seg_info (now_seg)->tc_segment_info_data.map_state;
+  bool reset_seg_arch_str = false;
 
   if (!SEG_NORMAL (now_seg)
-      /* For now I only add the mapping symbols to text sections.
+      /* For now we only add the mapping symbols to text sections.
 	 Therefore, the dis-assembler only show the actual contents
 	 distribution for text.  Other sections will be shown as
 	 data without the details.  */
@@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
     return;
 
   /* The mapping symbol should be emitted if not in the right
-     mapping state  */
-  if (from_state == to_state)
+     mapping state.  */
+  symbolS *seg_arch_symbol =
+	seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
+  if (to_state == MAP_INSN && seg_arch_symbol == 0)
+    {
+      /* Always add $x+arch at the first instruction of section.  */
+      reset_seg_arch_str = true;
+    }
+  else if (seg_arch_symbol != 0
+	   && to_state == MAP_INSN
+	   && !frag_align_code
+	   && strcmp (riscv_subsets->arch_str,
+		      S_GET_NAME (seg_arch_symbol) + 2) != 0)
+    {
+      reset_seg_arch_str = true;
+      need_arch_map_symbol = true;
+    }
+  else if (from_state == to_state)
     return;
 
   valueT value = (valueT) (frag_now_fix () - max_chars);
   seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
-  make_mapping_symbol (to_state, value, frag_now);
+  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
 }
 
 /* Add the odd bytes of paddings for riscv_handle_align.  */
@@ -544,9 +596,27 @@ static void
 riscv_add_odd_padding_symbol (fragS *frag)
 {
   /* If there was already a mapping symbol, it should be
-     removed in the make_mapping_symbol.  */
-  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
-  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
+     removed in the make_mapping_symbol.
+
+     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
+  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
+  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
+}
+
+/* If previous and current mapping symbol have same value, then remove the
+   current $x only if the previous is $x+arch; Otherwise, always remove the
+   previous.  */
+
+static void
+riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
+{
+  know (pre != NULL && cur != NULL
+	&& S_GET_VALUE (pre) == S_GET_VALUE (cur));
+  symbolS *removed = pre;
+  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
+      && strcmp (S_GET_NAME (cur), "$x") == 0)
+    removed = cur;
+  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
 }
 
 /* Remove any excess mapping symbols generated for alignment frags in
@@ -565,6 +635,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
   if (seginfo == NULL || seginfo->frchainP == NULL)
     return;
 
+  /* If we don't set any .option arch directive, then the arch_map_symbol
+     in each segment must be the first instruction, and we don't need to
+     add $x+arch for them.  */
+  if (!need_arch_map_symbol
+      && seginfo->tc_segment_info_data.arch_map_symbol != 0)
+    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
+
   for (fragp = seginfo->frchainP->frch_root;
        fragp != NULL;
        fragp = fragp->fr_next)
@@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
 
       do
 	{
-	  if (next->tc_frag_data.first_map_symbol != NULL)
+	  symbolS *next_first = next->tc_frag_data.first_map_symbol;
+	  if (next_first != NULL)
 	    {
 	      /* The last mapping symbol overlaps with another one
-		 which at the start of the next frag.  */
-	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
+		 which at the start of the next frag.
+
+		 Please see the gas/testsuite/gas/riscv/mapping.s:
+		 .text.zero.fill.align.A and .text.zero.fill.align.B.  */
+	      riscv_remove_mapping_symbol (last, next_first);
 	      break;
 	    }
 
 	  if (next->fr_next == NULL)
 	    {
-	      /* The last mapping symbol is at the end of the section.  */
+	      /* The last mapping symbol is at the end of the section.
+
+		 Please see the gas/testsuite/gas/riscv/mapping.s:
+		 .text.last.section.  */
 	      know (next->fr_fix == 0 && next->fr_var == 0);
 	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
 	      break;
@@ -3438,7 +3522,7 @@ md_assemble (char *str)
        return;
     }
 
-  riscv_mapping_state (MAP_INSN, 0);
+  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
 
   const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
 						&imm_reloc, op_hash);
@@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
   if (strcmp (name, "rvc") == 0)
     {
       riscv_update_subset (&riscv_rps_as, "+c");
+      riscv_reset_subsets_list_arch_str ();
       riscv_set_rvc (true);
     }
   else if (strcmp (name, "norvc") == 0)
     {
       riscv_update_subset (&riscv_rps_as, "-c");
+      riscv_reset_subsets_list_arch_str ();
       riscv_set_rvc (false);
     }
   else if (strcmp (name, "pic") == 0)
@@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
       if (ISSPACE (*name) && *name != '\0')
 	name++;
       riscv_update_subset (&riscv_rps_as, name);
+      riscv_reset_subsets_list_arch_str ();
 
       riscv_set_rvc (false);
       if (riscv_subset_supports (&riscv_rps_as, "c"))
@@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
   if (!riscv_opts.relax)
     return false;
 
+  /* Maybe we should use frag_var to create a new rs_align_code fragment,
+     rather than just use frag_more to handle an alignment here?  So that we
+     don't need to call riscv_mapping_state again later, and then only need
+     to check frag->fr_type to see if it is frag_align_code.  */
   nops = frag_more (worst_case_bytes);
 
   ex.X_op = O_constant;
@@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
   fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
 	       &ex, false, BFD_RELOC_RISCV_ALIGN);
 
-  riscv_mapping_state (MAP_INSN, worst_case_bytes);
+  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
 
   /* We need to start a new frag after the alignment which may be removed by
      the linker, to prevent the assembler from computing static offsets.
@@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
     case rs_fill:
     case rs_align:
     case rs_align_test:
-      riscv_mapping_state (MAP_DATA, max_chars);
+      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
       break;
     case rs_align_code:
-      riscv_mapping_state (MAP_INSN, max_chars);
+      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
       break;
     default:
       break;
@@ -4418,6 +4509,7 @@ void
 riscv_elf_final_processing (void)
 {
   riscv_set_abi_by_arch ();
+  riscv_release_subset_list (riscv_subsets);
   elf_elfheader (stdoutput)->e_flags |= elf_flags;
 }
 
@@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
   save_c = *input_line_pointer;
   *input_line_pointer = '\0';
 
-  riscv_mapping_state (MAP_INSN, 0);
+  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
 
   struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
 				&imm_reloc, insn_type_hash);
@@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
   unsigned int i;
 
   /* Re-write architecture elf attribute.  */
-  arch_str = riscv_arch_str (xlen, riscv_subsets);
+  arch_str = riscv_subsets->arch_str;
   bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
-  xfree ((void *) arch_str);
 
   /* For the file without any instruction, we don't set the default_priv_spec
      according to the privileged elf attributes since the md_assemble isn't
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 802e7afe670..19c45ba2d12 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
 extern int riscv_convert_symbolic_attribute (const char *);
 
 /* Set mapping symbol states.  */
-#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
-void riscv_mapping_state (enum riscv_seg_mstate, int);
+#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
+void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
 
 /* Define target segment type.  */
 #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
 struct riscv_segment_info_type
 {
   enum riscv_seg_mstate map_state;
+  /* The current mapping symbol with architecture string.  */
+  symbolS *arch_map_symbol;
 };
 
 /* Define target fragment type.  */
diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
deleted file mode 100644
index 989463f91ee..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01.s
+++ /dev/null
@@ -1,17 +0,0 @@
-	.option arch, -c
-	.text
-	.global	funcA
-funcA:
-	add	a0, a0, a0
-	j	funcB
-	.global	funcB
-funcB:
-	add	a1, a1, a1
-	bne	a0, a1, funcB
-
-	.data
-	.word 0x123456
-
-	.section	.foo, "ax"
-foo:
-	add	a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
deleted file mode 100644
index 32e0027a13d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01a.d
+++ /dev/null
@@ -1,17 +0,0 @@
-#as:
-#source: mapping-01.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+00 l    d  .foo	0+00 .foo
-0+00 l       .foo	0+00 foo
-0+00 l       .foo	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
-0+00 g       .text	0+00 funcA
-0+08 g       .text	0+00 funcB
diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
deleted file mode 100644
index e84b3d608f5..00000000000
--- a/gas/testsuite/gas/riscv/mapping-01b.d
+++ /dev/null
@@ -1,21 +0,0 @@
-#as:
-#source: mapping-01.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <funcA>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
-
-0+008 <funcB>:
-[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
-
-Disassembly of section .foo:
-
-0+000 <foo>:
-[ 	]+0:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
deleted file mode 100644
index 79468c0d14f..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02.s
+++ /dev/null
@@ -1,12 +0,0 @@
-	.option arch, -c
-	.text
-	.word	1
-	add	a0, a0, a0
-
-	.data
-	.word	2
-
-	.text
-	add	a1, a1, a1
-	.short	3
-	add	a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
deleted file mode 100644
index 333f12cd343..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02a.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#as:
-#source: mapping-02.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+04 l       .text	0+00 \$x
-0+0c l       .text	0+00 \$d
-0+0e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
deleted file mode 100644
index 1ed6c081cf7..00000000000
--- a/gas/testsuite/gas/riscv/mapping-02b.d
+++ /dev/null
@@ -1,16 +0,0 @@
-#as:
-#source: mapping-02.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+4:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+c:[ 	]+0003[ 	]+.short[ 	]+0x0003
-[ 	]+e:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
deleted file mode 100644
index 88f2601568d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03.s
+++ /dev/null
@@ -1,11 +0,0 @@
-	.option arch, -c
-	.text
-	add	a0, a0, a0
-	.long	0
-	.balign	16
-	.word	1
-	add	a1, a1, a1
-	.byte	2
-	.long	3
-	.balign	16
-	.word	5
diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
deleted file mode 100644
index d3663b663aa..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03a.d
+++ /dev/null
@@ -1,20 +0,0 @@
-#as:
-#source: mapping-03.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+04 l       .text	0+00 \$d
-0+08 l       .text	0+00 \$x
-0+14 l       .text	0+00 \$d
-0+18 l       .text	0+00 \$x
-0+1c l       .text	0+00 \$d
-0+21 l       .text	0+00 \$x
-0+2d l       .text	0+00 \$d
-0+31 l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
deleted file mode 100644
index f4f67269981..00000000000
--- a/gas/testsuite/gas/riscv/mapping-03b.d
+++ /dev/null
@@ -1,24 +0,0 @@
-#as:
-#source: mapping-03.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
-[ 	]+10:[ 	]+00000013[ 	]+nop
-[ 	]+14:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+18:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+1c:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
-[ 	]+20:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+21:[ 	]+00000013[ 	]+nop
-[ 	]+25:[ 	]+00000013[ 	]+nop
-[ 	]+29:[ 	]+00000013[ 	]+nop
-[ 	]+2d:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
deleted file mode 100644
index 804b0397737..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04.s
+++ /dev/null
@@ -1,13 +0,0 @@
-	.text
-	.option	arch, -c
-	.fill	2, 4, 0x1001
-	.byte	1
-	.word	0
-	.balign	8
-	add	a0, a0, a0
-	.fill	5, 2, 0x2002
-	add	a1, a1, a1
-
-	.data
-	.word	0x1
-	.word	0x2
diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
deleted file mode 100644
index 1ae9653212b..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04a.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#as:
-#source: mapping-04.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+0d l       .text	0+00 \$x
-0+15 l       .text	0+00 \$d
-0+1f l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
deleted file mode 100644
index 54bd0afb6c4..00000000000
--- a/gas/testsuite/gas/riscv/mapping-04b.d
+++ /dev/null
@@ -1,23 +0,0 @@
-#as:
-#source: mapping-04.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+d:[ 	]+00000013[ 	]+nop
-[ 	]+11:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+15:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+19:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+1d:[ 	]+2002[ 	]+.short[ 	]+0x2002
-[ 	]+1f:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+23:[ 	]+0000[ 	]+.2byte[ 	]+0x0
-[ 	]+25:[ 	]+0000[ 	]+.2byte[ 	]+0x0
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
new file mode 100644
index 00000000000..246f3672ade
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-dis.d
@@ -0,0 +1,84 @@
+#as:
+#source: mapping.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text.cross.section.A:
+
+0+000 <funcA>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+bffd[ 	]+j[ 	]+0 <funcA>
+
+Disassembly of section .text.corss.section.B:
+
+0+000 <funcB>:
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+fffff06f[ 	]+j[ 	]+0 <funcB>
+
+Disassembly of section .text.data:
+
+0+000 <.text.data>:
+[ 	]+[0-9a-f]+:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+05000302[ 	]+.word[ 	]+0x05000302
+
+Disassembly of section .text.odd.align:
+
+0+000 <.text.odd.align>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+01[ 	]+.byte[ 	]+0x01
+[ 	]+[0-9a-f]+:[ 	]+00[ 	]+.byte[ 	]+0x00
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+
+Disassembly of section .text.zero.fill.first:
+
+0+000 <.text.zero.fill.first>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+
+Disassembly of section .text.zero.fill.last:
+
+0+000 <.text.zero.fill.last>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.zero.fill.align.A:
+
+0+000 <.text.zero.fill.align.A>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.zero.fill.align.B:
+
+0+000 <.text.zero.fill.align.B>:
+[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+
+Disassembly of section .text.last.section:
+
+0+000 <.text.last.section>:
+[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+
+Disassembly of section .text.section.padding:
+
+0+000 <.text.section.padding>:
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+
+Disassembly of section .text.relax.align:
+
+0+000 <.text.relax.align>:
+[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
+[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
+[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
new file mode 100644
index 00000000000..f69e719ff30
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
@@ -0,0 +1,17 @@
+#as:
+#source: mapping-non-arch.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+00+00 l    d  .text	00+00 .text
+00+00 l    d  .data	00+00 .data
+00+00 l    d  .bss	00+00 .bss
+00+00 l       .text	00+00 \$x
+00+08 l       .text	00+00 \$d
+00+0c l       .text	00+00 \$x
+00+00 l    d  text.A	00+00 text.A
+00+00 l       text.A	00+00 \$x
+00+02 l       text.A	00+00 \$d
+00+00 l    d  .riscv.attributes	00+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
new file mode 100644
index 00000000000..03b2d75a5dd
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
@@ -0,0 +1,11 @@
+.attribute arch, "rv32i"
+.option arch, +c
+.text
+addi	a0, zero, 1
+.align 3
+.word 0x1
+addi	a0, zero, 2
+
+.section text.A, "ax"
+addi	a0, zero, 3
+.word 0x2
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
deleted file mode 100644
index 916f732b7f7..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
+++ /dev/null
@@ -1,21 +0,0 @@
-#as: -mno-relax
-#source: mapping-03.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$x
-0+04 l       .text	0+00 \$d
-0+08 l       .text	0+00 \$x
-0+10 l       .text	0+00 \$d
-0+14 l       .text	0+00 \$x
-0+18 l       .text	0+00 \$d
-0+20 l       .text	0+00 \$d
-0+24 l       .text	0+00 \$x
-0+1d l       .text	0+00 \$d
-0+1e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
deleted file mode 100644
index 9e777351d1d..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
+++ /dev/null
@@ -1,25 +0,0 @@
-#as: -mno-relax
-#source: mapping-03.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
-[ 	]+10:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+14:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+18:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
-[ 	]+1c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+1d:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+1e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+20:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
-[ 	]+24:[ 	]+00000013[ 	]+nop
-[ 	]+28:[ 	]+00000013[ 	]+nop
-[ 	]+2c:[ 	]+00000013[ 	]+nop
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
deleted file mode 100644
index d552a7f632a..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
+++ /dev/null
@@ -1,16 +0,0 @@
-#as: -mno-relax
-#source: mapping-04.s
-#objdump: --syms --special-syms
-
-.*file format.*riscv.*
-
-SYMBOL TABLE:
-0+00 l    d  .text	0+00 .text
-0+00 l    d  .data	0+00 .data
-0+00 l    d  .bss	0+00 .bss
-0+00 l       .text	0+00 \$d
-0+14 l       .text	0+00 \$d
-0+1e l       .text	0+00 \$x
-0+0d l       .text	0+00 \$d
-0+0e l       .text	0+00 \$x
-0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
deleted file mode 100644
index be668f29220..00000000000
--- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
+++ /dev/null
@@ -1,24 +0,0 @@
-#as: -mno-relax
-#source: mapping-04.s
-#objdump: -d
-
-.*:[ 	]+file format .*
-
-
-Disassembly of section .text:
-
-0+000 <.text>:
-[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
-[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
-[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+d:[ 	]+00[ 	]+.byte[ 	]+0x00
-[ 	]+e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+10:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
-[ 	]+14:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+18:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
-[ 	]+1c:[ 	]+2002[ 	]+.short[ 	]+0x2002
-[ 	]+1e:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
-[ 	]+22:[ 	]+0001[ 	]+.2byte[ 	]+0x1
-[ 	]+24:[ 	]+00000013[ 	]+nop
-#...
diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
new file mode 100644
index 00000000000..83ee6528b79
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-symbols.d
@@ -0,0 +1,48 @@
+#as:
+#source: mapping.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l    d  .text	0+00 .text
+0+00 l    d  .data	0+00 .data
+0+00 l    d  .bss	0+00 .bss
+0+00 l    d  .text.cross.section.A	0+00 .text.cross.section.A
+0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.corss.section.B	0+00 .text.corss.section.B
+0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.corss.section.B	0+00 \$xrv32i2p1
+0+00 l    d  .text.data	0+00 .text.data
+0+00 l       .text.data	0+00 \$d
+0+08 l       .text.data	0+00 \$xrv32i2p1_c2p0
+0+0c l       .text.data	0+00 \$d
+0+00 l    d  .text.odd.align	0+00 .text.odd.align
+0+00 l       .text.odd.align	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.odd.align	0+00 \$d
+0+08 l       .text.odd.align	0+00 \$xrv32i2p1
+0+00 l    d  .text.zero.fill.first	0+00 .text.zero.fill.first
+0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.zero.fill.last	0+00 .text.zero.fill.last
+0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_c2p0
+0+02 l       .text.zero.fill.last	0+00 \$x
+0+00 l    d  .text.zero.fill.align.A	0+00 .text.zero.fill.align.A
+0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_c2p0
+0+00 l    d  .text.zero.fill.align.B	0+00 .text.zero.fill.align.B
+0+00 l       .text.zero.fill.align.B	0+00 \$xrv32i2p1
+0+00 l    d  .text.last.section	0+00 .text.last.section
+0+00 l       .text.last.section	0+00 \$xrv32i2p1
+0+04 l       .text.last.section	0+00 \$d
+0+00 l    d  .text.section.padding	0+00 .text.section.padding
+0+00 l       .text.section.padding	0+00 \$xrv32i2p1_c2p0
+0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_c2p0
+0+06 l       .text.section.padding	0+00 \$d
+0+00 l    d  .text.relax.align	0+00 .text.relax.align
+0+00 l       .text.relax.align	0+00 \$xrv32i2p1_c2p0
+0+08 l       .text.relax.align	0+00 \$xrv32i2p1
+0+0a l       .text.section.padding	0+00 \$x
+0+03 l       .text.odd.align	0+00 \$d
+0+04 l       .text.odd.align	0+00 \$x
+0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
+0+00 g       .text.cross.section.A	0+00 funcA
+0+00 g       .text.corss.section.B	0+00 funcB
diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
new file mode 100644
index 00000000000..a0e6c744107
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping.s
@@ -0,0 +1,112 @@
+.attribute arch, "rv32ic"
+.option norelax			# FIXME: assembler fill the paddings after parsing everything,
+				# so we probably won't fill anything for the norelax region when
+				# the riscv_opts.relax is enabled at somewhere.
+
+.section .text.cross.section.A, "ax"
+.option push
+.global funcA
+funcA:
+addi	a0, zero, 1		# rv32i
+.option arch, +c
+j	funcA			# rv32ic
+.section .text.corss.section.B, "ax"
+.globl funcB
+funcB:
+addi	a0, zero, 2		# rv32ic, need to be added since start of section
+.option arch, -c
+j	funcB			# rv32i
+.option pop
+
+.section .text.data, "ax"
+.option push
+.word	0			# $d
+.long	1
+addi	a0, zero, 1		# rv32ic
+.data
+.word	2			# don't add mapping symbols for non-text section
+.section .text.data
+addi	a0, zero, 2		# $x, but same as previous addi, so removed
+.byte	2			# $d, dumped as .word
+.short	3
+.byte	5
+.option pop
+
+.section .text.odd.align, "ax"
+.option push
+.option norelax
+.option arch, +c
+addi	a0, zero, 1		# $xrv32ic
+.byte	1			# $d
+.option arch, -c
+.align	3			# odd alignment, $x replaced by $d + $x
+addi	a0, zero, 2		# $xrv32i
+.option pop
+
+.section .text.zero.fill.first, "ax"
+.option push
+.option norelax
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
+addi	a0, zero, 1		# $xrv32ic
+.option pop
+
+.section .text.zero.fill.last, "ax"
+.option push
+.option norelax
+addi	a0, zero, 1		# $xrv32ic
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
+addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
+.option pop
+
+# last overlap next first
+.section .text.zero.fill.align.A, "ax"
+.option push
+.option norelax
+.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
+addi	a0, zero, 1		# $x, should be removed in riscv_check_mapping_symbols
+addi	a0, zero, 2
+.option pop
+
+# last overlap next first
+.section .text.zero.fill.align.B, "ax"
+.option push
+.option norelax
+.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed,
+				# but will be removed in riscv_check_mapping_symbols
+.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
+.option arch, -c
+addi	a0, zero, 1		# $xrv32i
+addi	a0, zero, 2
+.option pop
+
+.section .text.last.section, "ax"
+.option push
+.option norelax
+.option arch, -c
+addi	a0, zero, 1		# $xrv32i
+.word	1			# $d
+.align	2			# zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
+.option pop
+
+.section .text.section.padding, "ax"
+.option push
+.option norelax
+.align	2
+addi	a0, zero, 1		# $rv32ic
+.option arch, +a
+.align	2			# 2-byte padding, $x, removed
+addi	a0, zero, 2		# $xrv32iac
+.word	1			# $d
+.option pop			# 2-byte padding, $x
+
+.section .text.relax.align, "ax"
+.option push
+.option relax
+.option arch, rv32ic
+.balign	4			# $xrv32ic, add at the start of section
+addi	a0, zero, 1		# $x, won't added
+.option arch, -c
+.align	3			# $x, won't added
+addi	a0, zero, 2		# $xrv32i
+.option pop
diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
index aed4ca8e4d9..1d14c604dec 100644
--- a/gas/testsuite/gas/riscv/option-arch-01a.d
+++ b/gas/testsuite/gas/riscv/option-arch-01a.d
@@ -10,5 +10,5 @@ Disassembly of section .text:
 0+000 <.text>:
 [ 	]+[0-9a-f]+:[  	]+952e[    	]+add[        	]+a0,a0,a1
 [ 	]+[0-9a-f]+:[  	]+00b50533[    	]+add[        	]+a0,a0,a1
-[ 	]+[0-9a-f]+:[  	]+00302573[    	]+csrr[        	]+a0,fcsr
+[ 	]+[0-9a-f]+:[  	]+00302573[    	]+frcsr[        	]+a0
 #...
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index f2d399260c1..eb88c81c0f1 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       /* If arch has ZFINX flags, use gpr for disassemble.  */
       if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
 	riscv_fpr_names = riscv_gpr_names;
+      else
+	riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
+			  riscv_fpr_names_abi : riscv_fpr_names_numeric;
 
       for (; op->name; op++)
 	{
@@ -810,6 +813,12 @@ riscv_get_map_state (int n,
     *state = MAP_INSN;
   else if (strcmp (name, "$d") == 0)
     *state = MAP_DATA;
+  else if (strncmp (name, "$xrv", 4) == 0)
+    {
+      *state = MAP_INSN;
+      riscv_release_subset_list (&riscv_subsets);
+      riscv_parse_subset (&riscv_rps_dis, name + 2);
+    }
   else
     return false;
 
-- 
2.37.0 (Apple Git-136)


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-10-28 14:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-30  9:20 [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Nelson Chu
2022-09-30  9:20 ` [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations Nelson Chu
2022-10-03 11:17 ` [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Tsukasa OI
2022-10-28  3:16 ` Nelson Chu
2022-10-28  7:01   ` Tsukasa OI
2022-10-28  7:10     ` Kito Cheng
2022-10-28  9:23       ` Nelson Chu
2022-10-28 14:43         ` Tsukasa OI
  -- strict thread matches above, loose matches on Subject: below --
2022-09-30  8:58 Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).