OSDN Git Service

* config/sh/sh.c (sh_override_options): When flag_exceptions or
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.c
index 18123c3..a4be11c 100644 (file)
@@ -38,7 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "recog.h"
 #include "integrate.h"
-#include "elf/dwarf2.h"
+#include "dwarf2.h"
 #include "tm_p.h"
 #include "target.h"
 #include "target-def.h"
@@ -257,6 +257,11 @@ static bool sh_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
 static tree sh_build_builtin_va_list (void);
 static void sh_va_start (tree, rtx);
 static tree sh_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
+static enum machine_mode sh_promote_function_mode (const_tree type,
+                                                  enum machine_mode,
+                                                  int *punsignedp,
+                                                  const_tree funtype,
+                                                  int for_return);
 static bool sh_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
                                  const_tree, bool);
 static bool sh_callee_copies (CUMULATIVE_ARGS *, enum machine_mode,
@@ -437,10 +442,8 @@ static const struct attribute_spec sh_attribute_table[] =
 
 #undef TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES sh_promote_prototypes
-#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS sh_promote_prototypes
-#undef TARGET_PROMOTE_FUNCTION_RETURN
-#define TARGET_PROMOTE_FUNCTION_RETURN sh_promote_prototypes
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE sh_promote_function_mode
 
 #undef TARGET_STRUCT_VALUE_RTX
 #define TARGET_STRUCT_VALUE_RTX sh_struct_value_rtx
@@ -871,6 +874,29 @@ sh_override_options (void)
        flag_schedule_insns = 0;
     }
 
+  /* Unwinding with -freorder-blocks-and-partition does not work on this
+     architecture, because it requires far jumps to label crossing between
+     hot/cold sections which are rejected on this architecture.  */
+  if (flag_reorder_blocks_and_partition)
+    {
+      if (flag_exceptions)
+       {
+         inform (input_location, 
+                 "-freorder-blocks-and-partition does not work with "
+                 "exceptions on this architecture");
+         flag_reorder_blocks_and_partition = 0;
+         flag_reorder_blocks = 1;
+       }
+      else if (flag_unwind_tables)
+       {
+         inform (input_location,
+                 "-freorder-blocks-and-partition does not support unwind "
+                 "info on this architecture");
+         flag_reorder_blocks_and_partition = 0;
+         flag_reorder_blocks = 1;
+       }
+    }
+
   if (align_loops == 0)
     align_loops =  1 << (TARGET_SH5 ? 3 : 2);
   if (align_jumps == 0)
@@ -6743,13 +6769,19 @@ sh_expand_prologue (void)
   /* If we're supposed to switch stacks at function entry, do so now.  */
   if (sp_switch_attr)
     {
+      rtx lab, newsrc;
       /* The argument specifies a variable holding the address of the
         stack the interrupt function should switch to/from at entry/exit.  */
+      tree arg = TREE_VALUE ( TREE_VALUE (sp_switch_attr));
       const char *s
-       = ggc_strdup (TREE_STRING_POINTER (TREE_VALUE (sp_switch_attr)));
+       = ggc_strdup (TREE_STRING_POINTER (arg));
       rtx sp_switch = gen_rtx_SYMBOL_REF (Pmode, s);
 
-      emit_insn (gen_sp_switch_1 (sp_switch));
+      lab = add_constant (sp_switch, SImode, 0);
+      newsrc = gen_rtx_LABEL_REF (VOIDmode, lab);
+      newsrc = gen_const_mem (SImode, newsrc);
+
+      emit_insn (gen_sp_switch_1 (newsrc));
     }
 
   d = calc_live_regs (&live_regs_mask);
@@ -7857,7 +7889,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
   if (result)
     {
       gimplify_assign (result, tmp, pre_p);
-
+      result = build1 (NOP_EXPR, TREE_TYPE (result), result);
       tmp = build1 (LABEL_EXPR, void_type_node, unshare_expr (lab_over));
       gimplify_and_add (tmp, pre_p);
     }
@@ -7890,6 +7922,17 @@ sh_dwarf_register_span (rtx reg)
                                              DBX_REGISTER_NUMBER (regno))));
 }
 
+static enum machine_mode
+sh_promote_function_mode (const_tree type, enum machine_mode mode,
+                         int *punsignedp, const_tree funtype,
+                         int for_return ATTRIBUTE_UNUSED)
+{
+  if (sh_promote_prototypes (funtype))
+    return promote_mode (type, mode, punsignedp);
+  else
+    return mode;
+}
+
 bool
 sh_promote_prototypes (const_tree type)
 {