From: Kito Cheng <kito.ch...@gmail.com>

This patch added a configure time option, 
--with-riscv-attribute=[yes|no|default],
run time option, -mriscv-attribute to control the output of ELF attribute.

This feature is only enabled by default for ELF/Bare mental target
configuration.

Kito Cheng <kito.ch...@gmail.com>
Monk Chiang  <sh.chian...@gmail.com>

ChangeLog:
gcc:
        * common/config/riscv/riscv-common.c: Include sstream.
        (riscv_subset_list::to_string): New.
        (riscv_arch_str): Likewise.
        * config.gcc (riscv*-*-*): Hanlde --with-riscv-attribute=
        * config.in: Regen
        * config/riscv/riscv-protos.h (riscv_arch_str): New.
        * config/riscv/riscv.c (INCLUDE_STRING): Defined.
        (riscv_emit_attribute): New.
        (riscv_file_start): Emit attribute if needed.
        (riscv_option_override): Init riscv_emit_attribute_p.
        * config/riscv/riscv.opt (mriscv-attribute): New option.
        * configure.ac (riscv*-*-*): Check binutils is supporting ELF
        attribute.
        * doc/install.texi: Document --with-riscv-attribute.
        * doc/invoke.texi: Document -mriscv-attribute.

gcc/testsuite:

        * gcc.target/riscv/attribute-1.c: New.
        * gcc.target/riscv/attribute-2.c: Likewise.
        * gcc.target/riscv/attribute-3.c: Likewise.
        * gcc.target/riscv/attribute-4.c: Likewise.
        * gcc.target/riscv/attribute-5.c: Likewise.
        * gcc.target/riscv/attribute-6.c: Likewise.
        * gcc.target/riscv/attribute-7.c: Likewise.
        * gcc.target/riscv/attribute-8.c: Likewise.
        * gcc.target/riscv/attribute-9.c: Likewise.
---
 gcc/common/config/riscv/riscv-common.c       | 38 ++++++++++++++++++++++++++++
 gcc/config.gcc                               | 26 ++++++++++++++++++-
 gcc/config.in                                |  6 +++++
 gcc/config/riscv/riscv-protos.h              |  3 +++
 gcc/config/riscv/riscv.c                     | 25 ++++++++++++++++++
 gcc/config/riscv/riscv.opt                   |  4 +++
 gcc/configure.ac                             |  7 +++++
 gcc/doc/install.texi                         |  8 ++++++
 gcc/doc/invoke.texi                          |  7 ++++-
 gcc/testsuite/gcc.target/riscv/attribute-1.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-2.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-3.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-4.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-5.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-6.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-7.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-8.c |  7 +++++
 gcc/testsuite/gcc.target/riscv/attribute-9.c |  7 +++++
 18 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-3.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-4.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-5.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-6.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-7.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-8.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-9.c

diff --git a/gcc/common/config/riscv/riscv-common.c 
b/gcc/common/config/riscv/riscv-common.c
index e412acb..3f938ba 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -17,6 +17,8 @@ You should have received a copy of the GNU General Public 
License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#include <sstream>
+
 #define INCLUDE_STRING
 #include "config.h"
 #include "system.h"
@@ -78,6 +80,8 @@ public:
                          int major_version = RISCV_DONT_CARE_VERSION,
                          int minor_version = RISCV_DONT_CARE_VERSION) const;
 
+  std::string to_string() const;
+
   unsigned xlen() const {return m_xlen;};
 
   static riscv_subset_list *parse (const char *, location_t);
@@ -134,6 +138,32 @@ void riscv_subset_list::add (const char *subset,
   m_tail = s;
 }
 
+/* Convert subset info to string with explicit version info.  */
+
+std::string riscv_subset_list::to_string() const
+{
+  std::ostringstream oss;
+  oss << "rv" << m_xlen;
+
+  bool first = true;
+  riscv_subset_t *subset = m_head;
+
+  while (subset != NULL)
+    {
+      if (!first)
+       oss << '_';
+      first = false;
+
+      oss << subset->name
+         << subset->major_version
+         << 'p'
+         << subset->minor_version;
+      subset = subset->next;
+    }
+
+  return oss.str();
+}
+
 /* Find subset in list without version checking, return NULL if not found.  */
 
 riscv_subset_t *riscv_subset_list::lookup (const char *subset,
@@ -492,6 +522,14 @@ fail:
   return NULL;
 }
 
+/* Return the current arch string.  */
+
+std::string riscv_arch_str ()
+{
+  gcc_assert (current_subset_list);
+  return current_subset_list->to_string ();
+}
+
 /* Parse a RISC-V ISA string into an option mask.  Must clear or set all arch
    dependent mask bits, in case more than one -march string is passed.  */
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 31b47c5..5103476 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4209,7 +4209,7 @@ case "${target}" in
                ;;
 
        riscv*-*-*)
-               supported_defaults="abi arch tune"
+               supported_defaults="abi arch tune riscv_attribute"
 
                case "${target}" in
                riscv-* | riscv32*) xlen=32 ;;
@@ -4217,6 +4217,30 @@ case "${target}" in
                *) echo "Unsupported RISC-V target ${target}" 1>&2; exit 1 ;;
                esac
 
+               case "${with_riscv_attribute}" in
+               yes)
+                       tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=1"
+                       ;;
+               no)
+                       tm_defines="${tm_defines} TARGET_RISCV_ATTRIBUTE=0"
+                       ;;
+               ""|default)
+                       case "${target}" in
+                       riscv*-*-elf*)
+                               tm_defines="${tm_defines} 
TARGET_RISCV_ATTRIBUTE=1"
+                               ;;
+                       *)
+                               tm_defines="${tm_defines} 
TARGET_RISCV_ATTRIBUTE=0"
+                               ;;
+                       esac
+                       ;;
+               *)
+                       echo "--with-riscv-attribute=${with_riscv_attribute} is 
not supported.  The argument must begin with yes, no or default." 1>&2
+                       exit 1
+                       ;;
+               esac
+
+
                # Infer arch from --with-arch, --target, and --with-abi.
                case "${with_arch}" in
                rv32e* | rv32i* | rv32g* | rv64i* | rv64g*)
diff --git a/gcc/config.in b/gcc/config.in
index 48a533b..a718cea 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -601,6 +601,12 @@
 #endif
 
 
+/* Define if your assembler supports .attribute. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_RISCV_ATTRIBUTE
+#endif
+
+
 /* Define if your assembler supports relocs needed by -fpic. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_AS_SMALL_PIC_RELOCS
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index f0a5e11..b81eff0 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -84,4 +84,7 @@ extern rtx riscv_expand_builtin (tree, rtx, rtx, 
machine_mode, int);
 extern tree riscv_builtin_decl (unsigned int, bool);
 extern void riscv_init_builtins (void);
 
+/* Routines implemented in riscv-common.c.  */
+extern std::string riscv_arch_str ();
+
 #endif /* ! GCC_RISCV_PROTOS_H */
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index bf4571d..103e5f5 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #define IN_TARGET_CODE 1
 
+#define INCLUDE_STRING
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -4177,6 +4178,20 @@ riscv_issue_rate (void)
   return tune_info->issue_rate;
 }
 
+/* Auxiliary function for emit RISC-V ELF attribute. */
+static void
+riscv_emit_attribute ()
+{
+  fprintf (asm_out_file, "\t.attribute arch, \"%s\"\n",
+          riscv_arch_str ().c_str ());
+
+  fprintf (asm_out_file, "\t.attribute unaligned_access, %d\n",
+           TARGET_STRICT_ALIGN ? 0 : 1);
+
+  fprintf (asm_out_file, "\t.attribute stack_align, %d\n",
+           riscv_stack_boundary / 8);
+}
+
 /* Implement TARGET_ASM_FILE_START.  */
 
 static void
@@ -4191,6 +4206,9 @@ riscv_file_start (void)
      relaxation in the assembler.  */
   if (! riscv_mrelax)
     fprintf (asm_out_file, "\t.option norelax\n");
+
+  if (riscv_emit_attribute_p)
+    riscv_emit_attribute ();
 }
 
 /* Implement TARGET_ASM_OUTPUT_MI_THUNK.  Generate rtl rather than asm text
@@ -4361,6 +4379,13 @@ riscv_option_override (void)
 
       riscv_stack_boundary = 8 << riscv_preferred_stack_boundary_arg;
     }
+
+  if (riscv_emit_attribute_p < 0)
+#ifdef HAVE_AS_RISCV_ATTRIBUTE
+    riscv_emit_attribute_p = TARGET_RISCV_ATTRIBUTE;
+#else
+    riscv_emit_attribute_p = 0;
+#endif
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index bb8ec95..1cf035f 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -127,3 +127,7 @@ Mask(DOUBLE_FLOAT)
 Mask(RVC)
 
 Mask(RVE)
+
+mriscv-attribute
+Target Report Var(riscv_emit_attribute_p) Init(-1)
+Emit RISC-V attribute.
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 7837035..666ae97 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4881,6 +4881,13 @@ pointers into PC-relative form.])
        [Requesting --with-nan= requires assembler support for -mnan=])
     fi
     ;;
+    riscv*-*-*)
+    gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
+      gcc_cv_as_riscv_attribute, [2,32,0],,
+      [.attribute stack_align,4],,
+      [AC_DEFINE(HAVE_AS_RISCV_ATTRIBUTE, 1,
+         [Define if your assembler supports .attribute.])])
+    ;;
     s390*-*-*)
     gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
       gcc_cv_as_s390_gnu_attribute, [2,18,0],,
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 1d925eb..666e536 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2161,6 +2161,14 @@ is used, it is enabled on Linux/x86 if target binutils
 supports @code{Intel CET} instructions and disabled otherwise.
 In this case the target libraries are configured to get additional
 @option{-fcf-protection} option.
+
+@item --with-riscv-attribute=@samp{yes}, @samp{no} or @samp{default}
+Generate RISC-V attribute by default, in order to record extra build 
information
+in object.
+
+The option is disabled by default. It is enabled on RISC-V/ELF (bare-metal)
+target if target binutils supported.
+
 @end table
 
 @subheading Cross-Compiler-Specific Options
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f5044a6..be09abf 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1057,7 +1057,8 @@ See RS/6000 and PowerPC Options.
 -mstrict-align  -mno-strict-align @gol
 -mcmodel=medlow  -mcmodel=medany @gol
 -mexplicit-relocs  -mno-explicit-relocs @gol
--mrelax  -mno-relax}
+-mrelax  -mno-relax @gol
+-mriscv-attribute  -mmo-riscv-attribute}
 
 @emph{RL78 Options}
 @gccoptlist{-msim  -mmul=none  -mmul=g13  -mmul=g14  -mallregs @gol
@@ -23798,6 +23799,10 @@ Take advantage of linker relaxations to reduce the 
number of instructions
 required to materialize symbol addresses. The default is to take advantage of
 linker relaxations.
 
+@item -memit-attribute
+@itemx -mno-emit-attribute
+Emit RISC-V attribute to record extra information into ELF objects.
+
 @end table
 
 @node RL78 Options
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-1.c 
b/gcc/testsuite/gcc.target/riscv/attribute-1.c
new file mode 100644
index 0000000..e835876
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-1.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-2.c 
b/gcc/testsuite/gcc.target/riscv/attribute-2.c
new file mode 100644
index 0000000..f7aa066
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-2.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mno-riscv-attribute" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler-not ".attribute arch" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-3.c 
b/gcc/testsuite/gcc.target/riscv/attribute-3.c
new file mode 100644
index 0000000..0bd2523
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-3.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -mpreferred-stack-boundary=8" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute stack_align, 256" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-4.c 
b/gcc/testsuite/gcc.target/riscv/attribute-4.c
new file mode 100644
index 0000000..51240b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-4.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -mstrict-align" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute unaligned_access, 0" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-5.c 
b/gcc/testsuite/gcc.target/riscv/attribute-5.c
new file mode 100644
index 0000000..d500534
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-5.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -mno-strict-align" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute unaligned_access, 1" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-6.c 
b/gcc/testsuite/gcc.target/riscv/attribute-6.c
new file mode 100644
index 0000000..6a034b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-6.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32g2p0 -mabi=ilp32" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv32i2p0_m2p0_a2p0_f2p0_d2p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-7.c 
b/gcc/testsuite/gcc.target/riscv/attribute-7.c
new file mode 100644
index 0000000..f48bbee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-7.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32e1p9 -mabi=ilp32e" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32e1p9\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-8.c 
b/gcc/testsuite/gcc.target/riscv/attribute-8.c
new file mode 100644
index 0000000..0a74e69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-8.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32i2p0xv5_xabc -mabi=ilp32" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, \"rv32i2p0_xv5p0_xabc2p0\"" } 
} */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-9.c 
b/gcc/testsuite/gcc.target/riscv/attribute-9.c
new file mode 100644
index 0000000..6db2509
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-9.c
@@ -0,0 +1,7 @@
+/* Verify the return instruction is mret.  */
+/* { dg-do compile } */
+/* { dg-options "-O -mriscv-attribute -march=rv32i2p0xbar_sabc_sxfoo 
-mabi=ilp32e" } */
+int foo()
+{
+}
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv32i2p0_xbar2p0_sabc2p0_sxfoo2p0\"" } } */
-- 
1.8.3.1

Reply via email to