Fix m68k-linux-gnu libgcc build for ColdFire (PR target/68467)

Message ID alpine.DEB.2.20.1801242223170.24303@digraph.polyomino.org.uk
State New
Headers show
Series
  • Fix m68k-linux-gnu libgcc build for ColdFire (PR target/68467)
Related show

Commit Message

Joseph Myers Jan. 24, 2018, 10:24 p.m.
PR target/68467 is libgcc failing to build for m68k-linux-gnu
configured for ColdFire.

Jeff has an analysis in the PR identifying the problem as resulting
from the callers of libcalls with 1-byte or 2-byte arguments wanting
to push just 1 or 2 bytes on the stack, while the libcall
implementations have the normal C ABI and expect 4-byte arguments.
For normal C functions, I believe the TARGET_PROMOTE_PROTOTYPES
definition would ensure such arguments get passed as 4-byte, but that
does not apply for libcalls.

This patch fixes the issue by defining TARGET_PROMOTE_FUNCTION_MODE
for m68k.  The definition is conservative, only applying promotions in
the case of arguments to libcalls; otherwise it returns the unpromoted
type, which I believe matches what the default implementation of the
hook would have done on m68k.

I have tested that this fixes the libgcc build for ColdFire, and, in
conjunction with one glibc patch, this enables glibc to build cleanly
for ColdFire and to pass the compilation parts of the glibc testsuite
except for one test unrelated to this patch (while glibc and the
compilation parts of the testsuite continue to build OK for
non-ColdFire m68k, as expected).  I have *not* run any GCC tests for
this patch, or any execution tests for m68k.

OK to commit?

2018-01-24  Joseph Myers  <joseph@codesourcery.com>

	PR target/68467
	* config/m68k/m68k.c (m68k_promote_function_mode): New function.
	(TARGET_PROMOTE_FUNCTION_MODE): New macro.


-- 
Joseph S. Myers
joseph@codesourcery.com

Comments

Jeff Law Jan. 24, 2018, 10:38 p.m. | #1
On 01/24/2018 03:24 PM, Joseph Myers wrote:
> PR target/68467 is libgcc failing to build for m68k-linux-gnu

> configured for ColdFire.

> 

> Jeff has an analysis in the PR identifying the problem as resulting

> from the callers of libcalls with 1-byte or 2-byte arguments wanting

> to push just 1 or 2 bytes on the stack, while the libcall

> implementations have the normal C ABI and expect 4-byte arguments.

> For normal C functions, I believe the TARGET_PROMOTE_PROTOTYPES

> definition would ensure such arguments get passed as 4-byte, but that

> does not apply for libcalls.

> 

> This patch fixes the issue by defining TARGET_PROMOTE_FUNCTION_MODE

> for m68k.  The definition is conservative, only applying promotions in

> the case of arguments to libcalls; otherwise it returns the unpromoted

> type, which I believe matches what the default implementation of the

> hook would have done on m68k.

> 

> I have tested that this fixes the libgcc build for ColdFire, and, in

> conjunction with one glibc patch, this enables glibc to build cleanly

> for ColdFire and to pass the compilation parts of the glibc testsuite

> except for one test unrelated to this patch (while glibc and the

> compilation parts of the testsuite continue to build OK for

> non-ColdFire m68k, as expected).  I have *not* run any GCC tests for

> this patch, or any execution tests for m68k.

> 

> OK to commit?

> 

> 2018-01-24  Joseph Myers  <joseph@codesourcery.com>

> 

> 	PR target/68467

> 	* config/m68k/m68k.c (m68k_promote_function_mode): New function.

> 	(TARGET_PROMOTE_FUNCTION_MODE): New macro.

So assuming my analysis in the BZ was correct the remaining concern
would be any libcalls that were implemented in assembly code which had
char or short arguments.  Wandering through libgcc, I don't see anything
which fits those constraints (there's lots of stuff that accepts a 32bit
float, but those aren't changed by your patch).

So I think the verdict is this should be OK.

Jeff

Patch

Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	(revision 257030)
+++ gcc/config/m68k/m68k.c	(working copy)
@@ -192,6 +192,8 @@ 
 static unsigned int m68k_hard_regno_nregs (unsigned int, machine_mode);
 static bool m68k_hard_regno_mode_ok (unsigned int, machine_mode);
 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);
 
 /* Initialize the GCC target structure.  */
 
@@ -347,6 +349,9 @@ 
 #undef TARGET_MODES_TIEABLE_P
 #define TARGET_MODES_TIEABLE_P m68k_modes_tieable_p
 
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE m68k_promote_function_mode
+
 static const struct attribute_spec m68k_attribute_table[] =
 {
   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
@@ -6621,4 +6626,20 @@ 
   return (bytes + 1) & ~1;
 }
 
+/* Implement TARGET_PROMOTE_FUNCTION_MODE.  */
+
+static machine_mode
+m68k_promote_function_mode (const_tree type, machine_mode mode,
+                            int *punsignedp ATTRIBUTE_UNUSED,
+                            const_tree fntype ATTRIBUTE_UNUSED,
+                            int for_return)
+{
+  /* Promote libcall arguments narrower than int to match the normal C
+     ABI (for which promotions are handled via
+     TARGET_PROMOTE_PROTOTYPES).  */
+  if (type == NULL_TREE && !for_return && (mode == QImode || mode == HImode))
+    return SImode;
+  return mode;
+}
+
 #include "gt-m68k.h"