OSDN Git Service

PR c/42312
[pf3gnuchains/gcc-fork.git] / gcc / config / mep / mep.c
index efed4b6..54d21c8 100644 (file)
@@ -229,6 +229,7 @@ static tree mep_build_builtin_va_list (void);
 static void mep_expand_va_start (tree, rtx);
 static tree mep_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 static bool mep_can_eliminate (const int, const int);
+static void mep_trampoline_init (rtx, tree, rtx);
 \f
 /* Initialize the GCC target structure.  */
 
@@ -300,8 +301,10 @@ static bool mep_can_eliminate (const int, const int);
 #define TARGET_EXPAND_BUILTIN_VA_START mep_expand_va_start
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define        TARGET_GIMPLIFY_VA_ARG_EXPR     mep_gimplify_va_arg_expr
-#undef TARGET_CAN_ELIMINATE
+#undef  TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE            mep_can_eliminate
+#undef  TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT         mep_trampoline_init
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
@@ -1211,6 +1214,20 @@ mep_multi_slot (rtx x)
 }
 
 
+bool
+mep_legitimate_constant_p (rtx x)
+{
+  /* We can't convert symbol values to gp- or tp-rel values after
+     reload, as reload might have used $gp or $tp for other
+     purposes.  */
+  if (GET_CODE (x) == SYMBOL_REF && (reload_in_progress || reload_completed))
+    {
+      char e = mep_section_tag (x);
+      return (e != 't' && e != 'b');
+    }
+  return 1;
+}
+
 /* Be careful not to use macros that need to be compiled one way for
    strict, and another way for not-strict, like REG_OK_FOR_BASE_P.  */
 
@@ -1982,7 +1999,7 @@ mep_emit_cbranch (rtx *operands, int ne)
 {
   if (GET_CODE (operands[1]) == REG)
     return ne ? "bne\t%0, %1, %l2" : "beq\t%0, %1, %l2";
-  else if (INTVAL (operands[1]) == 0)
+  else if (INTVAL (operands[1]) == 0 && !mep_vliw_function_p(cfun->decl))
     return ne ? "bnez\t%0, %l2" : "beqz\t%0, %l2";
   else
     return ne ? "bnei\t%0, %1, %l2" : "beqi\t%0, %1, %l2";
@@ -2836,7 +2853,7 @@ mep_expand_prologue (void)
   int i, rss, sp_offset = 0;
   int reg_save_size;
   int frame_size;
-  int really_need_stack_frame = frame_size;
+  int really_need_stack_frame;
 
   /* We must not allow register renaming in interrupt functions,
      because that invalidates the correctness of the set of call-used
@@ -2850,6 +2867,7 @@ mep_expand_prologue (void)
 
   reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM);
   frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
+  really_need_stack_frame = frame_size;
 
   really_need_stack_frame |= mep_assign_save_slots (reg_save_size);
 
@@ -4564,6 +4582,8 @@ mep_encode_section_info (tree decl, rtx rtl, int first)
       idp = get_identifier (newname);
       XEXP (rtl, 0) =
        gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+      SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl);
+      SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl);
 
       switch (encoding)
        {
@@ -4906,9 +4926,12 @@ mep_output_aligned_common (FILE *stream, tree decl, const char *name,
 
 /* Trampolines.  */
 
-void
-mep_init_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
+static void
+mep_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
 {
+  rtx addr = XEXP (m_tramp, 0);
+  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
+
   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__mep_trampoline_helper"),
                     LCT_NORMAL, VOIDmode, 3,
                     addr, Pmode,