Tag the floating-point calling convention used on m68k-elf (either hard-float
or soft-float) through the GNU assembler attribute. The use of the tag enables
the linker to ensure linked objects use a consistent floating-point ABI and
allows tools like GDB to infer the ABI used from the ELF file. It is based on
similar work done for PowerPC.

The patch has been tested for m68k-elf and x86-64/Linux. Since tagging is only
enabled when the m68k assembler supports GNU attributes, this patch can be
applied independently from the corresponding binutils patch.

If approved, I'll need a maintainer to commit on my behalf.

Thanks,

Pat Bernardi
AdaCore

---
2020-06-25  Pat Bernardi  <berna...@adacore.com>

gcc/ChangeLog
        * configure.ac: Check m68k assembler supports .gnu_attribute.
        * configure: Regenerate.
        * config/m68k/linux.h (TARGET_ELF, M68K_LINUX): Define.
        * config/m68k/m68kelf.h (TARGET_ELF): Define.
        * config/m68k/m68k.c (m68k_elf_file_end): New function.
        (TARGET_ASM_FILE_END): Define.
        (m68k_passes_float): New static variable.
        (m68k_libcall_value, m68k_function_value): set m68k_passes_float if
        value is floating point.
        (m68k_elf_file_end): New function.

gcc/testsuite/ChangeLog
        * gcc.target/m68k/gnuattr1.c: New file.
        * gcc.target/m68k/gnuattr2.c: Likewise.

diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h
index 0d18e5ae5ac..2e064ef486d 100644
--- a/gcc/config/m68k/linux.h
+++ b/gcc/config/m68k/linux.h
@@ -18,6 +18,11 @@ 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/>.  */

+/* Target is ELF and M68K_LINUX */
+
+#define TARGET_ELF
+#define M68K_LINUX
+
/* Add %(asm_cpu_spec) to a generic definition of ASM_SPEC.  */
#undef ASM_SPEC
#define ASM_SPEC "%(asm_cpu_spec) %(asm_pcrel_spec)"
@@ -226,8 +231,6 @@ along with GCC; see the file COPYING3.  If not see
     : "%d0", "%d2", "%d3");                                            \
}

-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
-
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)

diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 67b109447b3..f6809386bf2 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -196,7 +196,8 @@ static bool m68k_modes_tieable_p (machine_mode, 
machine_mode);
static machine_mode m68k_promote_function_mode (const_tree, machine_mode,
                                                int *, const_tree, int);
static void m68k_asm_final_postscan_insn (FILE *, rtx_insn *insn, rtx [], int);
-
+static void m68k_elf_file_end (void) ATTRIBUTE_UNUSED;
+
/* Initialize the GCC target structure.  */

#if INT_OP_GROUP == INT_OP_DOT_WORD
@@ -360,6 +361,11 @@ static void m68k_asm_final_postscan_insn (FILE *, rtx_insn 
*insn, rtx [], int);
#undef TARGET_ASM_FINAL_POSTSCAN_INSN
#define TARGET_ASM_FINAL_POSTSCAN_INSN m68k_asm_final_postscan_insn

+#ifdef TARGET_ELF
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END m68k_elf_file_end
+#endif
+
static const struct attribute_spec m68k_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
@@ -482,6 +488,11 @@ unsigned int m68k_cpu_flags;
/* The set of FL_* flags that apply to the processor to be tuned for.  */
unsigned int m68k_tune_flags;

+#ifdef HAVE_AS_GNU_ATTRIBUTE
+/* Flag whether floating point values have been passed/returned. */
+static bool m68k_passes_float;
+#endif
+
/* Asm templates for calling or jumping to an arbitrary symbolic address,
   or NULL if such calls or jumps are not supported.  The address is held
   in operand 0.  */
@@ -5823,6 +5834,9 @@ m68k_libcall_value (machine_mode mode)
  case E_SFmode:
  case E_DFmode:
  case E_XFmode:
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+    m68k_passes_float = true;
+#endif
    if (TARGET_68881)
      return gen_rtx_REG (mode, FP0_REG);
    break;
@@ -5846,6 +5860,9 @@ m68k_function_value (const_tree valtype, const_tree func 
ATTRIBUTE_UNUSED)
  case E_SFmode:
  case E_DFmode:
  case E_XFmode:
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+    m68k_passes_float = true;
+#endif
    if (TARGET_68881)
      return gen_rtx_REG (mode, FP0_REG);
    break;
@@ -7150,4 +7167,21 @@ m68k_promote_function_mode (const_tree type, 
machine_mode mode,
  return mode;
}

+/* Write out end of ELF file attributes */
+
+static void
+m68k_elf_file_end (void)
+{
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+  /* TARGET_68881 indicates use of hard-float ABI */
+  if (m68k_passes_float)
+      fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
+               TARGET_68881 ? 1 : 2);
+#endif
+
+#if defined (M68K_LINUX)
+  file_end_indicate_exec_stack ();
+#endif
+}
+
#include "gt-m68k.h"
diff --git a/gcc/config/m68k/m68kelf.h b/gcc/config/m68k/m68kelf.h
index f10dd326732..849481e9307 100644
--- a/gcc/config/m68k/m68kelf.h
+++ b/gcc/config/m68k/m68kelf.h
@@ -21,6 +21,9 @@ 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/>.  */

+/* Target is ELF */
+
+#define TARGET_ELF

#ifndef SWBEG_ASM_OP
#define SWBEG_ASM_OP "\t.swbeg\t"
diff --git a/gcc/configure.ac b/gcc/configure.ac
index e83f0833ef3..ed46d8fd955 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4892,6 +4892,14 @@ LCF0:
    esac
    ;;

+  m68k*-*-*)
+    gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
+      gcc_cv_as_m68k_gnu_attribute, [2,18,0],,
+      [.gnu_attribute 4,1],,
+      [AC_DEFINE(HAVE_AS_GNU_ATTRIBUTE, 1,
+         [Define if your assembler supports .gnu_attribute.])])
+    ;;
+
  mips*-*-*)
    gcc_GAS_CHECK_FEATURE([explicit relocation support],
      gcc_cv_as_mips_explicit_relocs, [2,14,0],,
diff --git a/gcc/testsuite/gcc.target/m68k/gnuattr1.c 
b/gcc/testsuite/gcc.target/m68k/gnuattr1.c
new file mode 100644
index 00000000000..c98617aa9ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/gnuattr1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { m68k-*-elf } } } */
+/* { dg-options "-mhard-float" } */
+/* { dg-final { scan-assembler "gnu_attribute 4, 1" } } */
+
+/* Check the correct gnu_attribute attribute is written when hard-float ABI
+   is used. */
+
+double a;
+
+double add1 (void)
+{
+  return a++;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/gnuattr2.c 
b/gcc/testsuite/gcc.target/m68k/gnuattr2.c
new file mode 100644
index 00000000000..3318adef4a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/gnuattr2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { m68k-*-elf } } } */
+/* { dg-options "-msoft-float" } */
+/* { dg-final { scan-assembler "gnu_attribute 4, 2" } } */
+
+/* Check the correct gnu_attribute attribute is written when the soft-float ABI
+   is used. */
+
+double a;
+
+double add1 (void)
+{
+  return a++;
+}
--
2.24.3

Reply via email to