From 47c9ac72414bb26cf9ec67aa24e115b037205b56 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Tue, 20 Nov 2012 12:22:44 +0000
Subject: [PATCH] rx.c (rx_function_arg_boundary): When using the RX ABI align
 stack arguments to their natural alignment.

	* config/rx/rx.c (rx_function_arg_boundary): When using the RX ABI
	align stack arguments to their natural alignment.
	(rx_narrow_volatile_bitfield): New function.  Allows narrow
	volatile bitfields.
	(rx_ok_to_inline): New function.  Do not inline functions with
	local variables into a naked caller.
	(TARGET_NARROW_VOLATILE_BITFIELD): Define.
	(TARGET_CAN_INLINE_P): Define.
	* config/rx/rx.c (TARGET_CPU_CPP_BUILTINS): Define __RX_ABI__ or
	__RX_GC_ABI__.
	(ASM_SPEC): Pass -mgcc-abi on to the assembler.
	(STRICT_ALIGNMENT): Set to false.
	(CTORS_SECTION_ASM_OP): Add executable attribute.
	(DTORS_SECTION_ASM_OP): Add executable attribute.
	(INIT_ARRAY_SECTION_ASM_OP): Add executable attribute.
	(FINI_ARRAY_SECTION_ASM_OP): Add executable attribute.
	* config/rx/rx.md (subdi3): Don't allow MEMs as the third operand,
	as it causes too much reload pressure.
	* config/rx/rx.opt (mgcc-abi): New option.
	(mrx-abi): New option.
	* config/rx/t-rx (MULTILIB_OPTIONS): Show how to add an ABI
	multilib.
	(MULTILIB_DIRNAMES): Likewise.

From-SVN: r193659
---
 gcc/ChangeLog        | 26 ++++++++++++++++++++++
 gcc/config/rx/rx.c   | 51 +++++++++++++++++++++++++++++++++++++++++---
 gcc/config/rx/rx.h   | 27 ++++++++++++++---------
 gcc/config/rx/rx.md  |  2 +-
 gcc/config/rx/rx.opt | 10 ++++++++-
 gcc/config/rx/t-rx   |  5 +++++
 6 files changed, 106 insertions(+), 15 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1403715cda79..367792f1dd51 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2012-11-20  Nick Clifton  <nickc@redhat.com>
+
+	* config/rx/rx.c (rx_function_arg_boundary): When using the RX ABI
+	align stack arguments to their natural alignment.
+	(rx_narrow_volatile_bitfield): New function.  Allows narrow
+	volatile bitfields.
+	(rx_ok_to_inline): New function.  Do not inline functions with
+	local variables into a naked caller.
+	(TARGET_NARROW_VOLATILE_BITFIELD): Define.
+	(TARGET_CAN_INLINE_P): Define.
+	* config/rx/rx.c (TARGET_CPU_CPP_BUILTINS): Define __RX_ABI__ or
+	__RX_GC_ABI__.
+	(ASM_SPEC): Pass -mgcc-abi on to the assembler.
+	(STRICT_ALIGNMENT): Set to false.
+	(CTORS_SECTION_ASM_OP): Add executable attribute.
+	(DTORS_SECTION_ASM_OP): Add executable attribute.
+	(INIT_ARRAY_SECTION_ASM_OP): Add executable attribute.
+	(FINI_ARRAY_SECTION_ASM_OP): Add executable attribute.
+	* config/rx/rx.md (subdi3): Don't allow MEMs as the third operand,
+	as it causes too much reload pressure.
+	* config/rx/rx.opt (mgcc-abi): New option.
+	(mrx-abi): New option.
+	* config/rx/t-rx (MULTILIB_OPTIONS): Show how to add an ABI
+	multilib.
+	(MULTILIB_DIRNAMES): Likewise.
+
 2012-11-20  James Greenhalgh  <james.greenhalgh@arm.com>
 	    Tejas Belagod  <tejas.belagod@arm.com>
 
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 8cd9253e4d58..5b7b87da3c20 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -1086,7 +1086,20 @@ static unsigned int
 rx_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
 			  const_tree type ATTRIBUTE_UNUSED)
 {
-  return 32;
+  /* Older versions of the RX backend aligned all on-stack arguements
+     to 32-bits.  The RX C ABI however says that they should be
+     aligned to their natural alignment.  (See section 5.2.2 of the ABI).  */
+  if (TARGET_GCC_ABI)
+    return STACK_BOUNDARY;
+
+  if (type)
+    {
+      if (DECL_P (type))
+	return DECL_ALIGN (type);
+      return TYPE_ALIGN (type);
+    }
+
+  return PARM_BOUNDARY;
 }
 
 /* Return an RTL describing where a function return value of type RET_TYPE
@@ -3202,7 +3215,39 @@ rx_adjust_insn_length (rtx insn, int current_length)
 
   return (zero && factor == 1) ? 4 : 5;
 }
+
+static bool
+rx_narrow_volatile_bitfield (void)
+{
+  return true;
+}
+
+static bool
+rx_ok_to_inline (tree caller, tree callee)
+{
+  /* Do not inline functions with local variables
+     into a naked CALLER - naked function have no stack frame and
+     locals need a frame in order to have somewhere to live.
+
+     Unfortunately we have no way to determine the presence of
+     local variables in CALLEE, so we have to be cautious and
+     assume that there might be some there.
+
+     We do allow inlining when CALLEE has the "inline" type
+     modifier or the "always_inline" or "gnu_inline" attributes.  */
+  return lookup_attribute ("naked", DECL_ATTRIBUTES (caller)) == NULL_TREE
+    || DECL_DECLARED_INLINE_P (callee)
+    || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE
+    || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE;
+}
+
 
+#undef  TARGET_NARROW_VOLATILE_BITFIELD
+#define TARGET_NARROW_VOLATILE_BITFIELD		rx_narrow_volatile_bitfield
+
+#undef  TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P			rx_ok_to_inline
+
 #undef  TARGET_ASM_JUMP_ALIGN_MAX_SKIP
 #define TARGET_ASM_JUMP_ALIGN_MAX_SKIP			rx_max_skip_for_label
 #undef  TARGET_ASM_LOOP_ALIGN_MAX_SKIP
@@ -3344,8 +3389,8 @@ rx_adjust_insn_length (rtx insn, int current_length)
 #undef  TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS		rx_legitimize_address
 
-#undef TARGET_WARN_FUNC_RETURN
-#define TARGET_WARN_FUNC_RETURN rx_warn_func_return
+#undef  TARGET_WARN_FUNC_RETURN
+#define TARGET_WARN_FUNC_RETURN 		rx_warn_func_return
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 065079fbbbdc..292938444943 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -1,5 +1,5 @@
 /* GCC backend definitions for the Renesas RX processor.
-   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
    Contributed by Red Hat.
 
    This file is part of GCC.
@@ -49,6 +49,11 @@
 	builtin_define ("__RX_AS100_SYNTAX__"); \
       else					\
 	builtin_define ("__RX_GAS_SYNTAX__");   \
+						\
+      if (TARGET_GCC_ABI)			\
+	builtin_define ("__RX_GCC_ABI__");	\
+      else					\
+	builtin_define ("__RX_ABI__");		\
     }                                           \
   while (0)
 
@@ -79,6 +84,7 @@
 %{mrelax:-relax} \
 %{mpid} \
 %{mint-register=*} \
+%{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \
 "
 
 #undef  LIB_SPEC
@@ -119,7 +125,8 @@
 
 #define DEFAULT_SIGNED_CHAR		0
 
-#define STRICT_ALIGNMENT 		1
+/* RX load/store instructions can handle unaligned addresses.  */
+#define STRICT_ALIGNMENT 		0
 #define FUNCTION_BOUNDARY 		8
 #define BIGGEST_ALIGNMENT 		32
 #define STACK_BOUNDARY 			32
@@ -370,13 +377,13 @@ typedef unsigned int CUMULATIVE_ARGS;
 # else
 #  define TEXT_SECTION_ASM_OP	      "\t.section P,\"ax\""
 #  define CTORS_SECTION_ASM_OP	      \
-  "\t.section\t.init_array,\"aw\",@init_array"
+  "\t.section\t.init_array,\"awx\",@init_array"
 #  define DTORS_SECTION_ASM_OP	      \
-  "\t.section\t.fini_array,\"aw\",@fini_array"
+  "\t.section\t.fini_array,\"awx\",@fini_array"
 #  define INIT_ARRAY_SECTION_ASM_OP   \
-  "\t.section\t.init_array,\"aw\",@init_array"
+  "\t.section\t.init_array,\"awx\",@init_array"
 #  define FINI_ARRAY_SECTION_ASM_OP   \
-  "\t.section\t.fini_array,\"aw\",@fini_array"
+  "\t.section\t.fini_array,\"awx\",@fini_array"
 # endif
 #else
 # define TEXT_SECTION_ASM_OP	      \
@@ -384,19 +391,19 @@ typedef unsigned int CUMULATIVE_ARGS;
 
 # define CTORS_SECTION_ASM_OP			      \
   (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
-   : "\t.section\t.init_array,\"aw\",@init_array")
+   : "\t.section\t.init_array,\"awx\",@init_array")
 
 # define DTORS_SECTION_ASM_OP			      \
   (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
-   : "\t.section\t.fini_array,\"aw\",@fini_array")
+   : "\t.section\t.fini_array,\"awx\",@fini_array")
 
 # define INIT_ARRAY_SECTION_ASM_OP		      \
   (TARGET_AS100_SYNTAX ? "\t.SECTION init_array,CODE" \
-   : "\t.section\t.init_array,\"aw\",@init_array")
+   : "\t.section\t.init_array,\"awx\",@init_array")
 
 # define FINI_ARRAY_SECTION_ASM_OP		      \
   (TARGET_AS100_SYNTAX ? "\t.SECTION fini_array,CODE" \
-   : "\t.section\t.fini_array,\"aw\",@fini_array")
+   : "\t.section\t.fini_array,\"awx\",@fini_array")
 #endif
 
 #define GLOBAL_ASM_OP 		\
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index d6e748c41e77..9d430aa8d65b 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -1651,7 +1651,7 @@
 (define_expand "subdi3"
   [(set (match_operand:DI           0 "register_operand")
 	(minus:DI (match_operand:DI 1 "register_operand")
-		  (match_operand:DI 2 "rx_compare_operand")))]
+		  (match_operand:DI 2 "register_operand")))]
   ""
 {
   rtx op0l, op0h, op1l, op1h, op2l, op2h;
diff --git a/gcc/config/rx/rx.opt b/gcc/config/rx/rx.opt
index f0a57b1fae11..4a38988b579a 100644
--- a/gcc/config/rx/rx.opt
+++ b/gcc/config/rx/rx.opt
@@ -1,5 +1,5 @@
 ; Command line options for the Renesas RX port of GCC.
-; Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+; Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 ; Contributed by Red Hat.
 ;
 ; This file is part of GCC.
@@ -124,3 +124,11 @@ Enables Position-Independent-Data (PID) mode.
 mwarn-multiple-fast-interrupts
 Target Report Var(rx_warn_multiple_fast_interrupts) Init(1) Warning
 Warn when multiple, different, fast interrupt handlers are in the compilation unit.
+
+mgcc-abi
+Target RejectNegative Report Mask(GCC_ABI)
+Enable the use of the old, broken, ABI where all stacked function arguments are aligned to 32-bits.
+
+mrx-abi
+Target RejectNegative Report InverseMask(GCC_ABI)
+Enable the use the standard RX ABI where all stacked function arguments are naturally aligned.  This is the default.
diff --git a/gcc/config/rx/t-rx b/gcc/config/rx/t-rx
index 9a5dca9056a6..dbd82da0c5a0 100644
--- a/gcc/config/rx/t-rx
+++ b/gcc/config/rx/t-rx
@@ -23,6 +23,11 @@
 MULTILIB_OPTIONS    = m64bit-doubles  nofpu        mbig-endian-data  mpid
 MULTILIB_DIRNAMES   =  64-bit-double  no-fpu-libs   big-endian-data   pid
 
+# If necessary uncomment the next two lines to generate multilibs
+# using the old, broken, ABI.
+# MULTILIB_OPTIONS    += mgcc-abi
+# MULTILIB_DIRNAMES   +=  gcc-abi
+
 MULTILIB_MATCHES    = nofpu=mnofpu  nofpu=mcpu?rx200
 
 MULTILIB_EXCEPTIONS =
-- 
GitLab