]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/bfin/bfin.c
utils.c (init_gnat_to_gnu): Use typed GC allocation.
[thirdparty/gcc.git] / gcc / config / bfin / bfin.c
index bb679eabd3e06edc5183428cda92011c68992f2a..c187bf3bbc7dd37037cbb2974acaf05502071d4a 100644 (file)
@@ -1,5 +1,6 @@
 /* The Blackfin code generation auxiliary output file.
-   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    Contributed by Analog Devices.
 
    This file is part of GCC.
@@ -25,7 +26,6 @@
 #include "rtl.h"
 #include "regs.h"
 #include "hard-reg-set.h"
-#include "real.h"
 #include "insn-config.h"
 #include "insn-codes.h"
 #include "conditions.h"
@@ -2094,37 +2094,67 @@ bfin_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
   return !called_func->local || this_func->local;
 }
 \f
+/* Write a template for a trampoline to F.  */
+
+static void
+bfin_asm_trampoline_template (FILE *f)
+{
+  if (TARGET_FDPIC)
+    {
+      fprintf (f, "\t.dd\t0x00000000\n");      /* 0 */
+      fprintf (f, "\t.dd\t0x00000000\n");      /* 0 */
+      fprintf (f, "\t.dd\t0x0000e109\n");      /* p1.l = fn low */
+      fprintf (f, "\t.dd\t0x0000e149\n");      /* p1.h = fn high */
+      fprintf (f, "\t.dd\t0x0000e10a\n");      /* p2.l = sc low */
+      fprintf (f, "\t.dd\t0x0000e14a\n");      /* p2.h = sc high */
+      fprintf (f, "\t.dw\t0xac4b\n");          /* p3 = [p1 + 4] */
+      fprintf (f, "\t.dw\t0x9149\n");          /* p1 = [p1] */
+      fprintf (f, "\t.dw\t0x0051\n");          /* jump (p1)*/
+    }
+  else
+    {
+      fprintf (f, "\t.dd\t0x0000e109\n");      /* p1.l = fn low */
+      fprintf (f, "\t.dd\t0x0000e149\n");      /* p1.h = fn high */
+      fprintf (f, "\t.dd\t0x0000e10a\n");      /* p2.l = sc low */
+      fprintf (f, "\t.dd\t0x0000e14a\n");      /* p2.h = sc high */
+      fprintf (f, "\t.dw\t0x0051\n");          /* jump (p1)*/
+    }
+}
+
 /* Emit RTL insns to initialize the variable parts of a trampoline at
-   TRAMP. FNADDR is an RTX for the address of the function's pure
-   code.  CXT is an RTX for the static chain value for the function.  */
+   M_TRAMP. FNDECL is the target function.  CHAIN_VALUE is an RTX for
+   the static chain value for the function.  */
 
-void
-initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
+static void
+bfin_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
 {
-  rtx t1 = copy_to_reg (fnaddr);
-  rtx t2 = copy_to_reg (cxt);
-  rtx addr;
+  rtx t1 = copy_to_reg (XEXP (DECL_RTL (fndecl), 0));
+  rtx t2 = copy_to_reg (chain_value);
+  rtx mem;
   int i = 0;
 
+  emit_block_move (m_tramp, assemble_trampoline_template (),
+                  GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
+
   if (TARGET_FDPIC)
     {
-      rtx a = memory_address (Pmode, plus_constant (tramp, 8));
-      addr = memory_address (Pmode, tramp);
-      emit_move_insn (gen_rtx_MEM (SImode, addr), a);
+      rtx a = force_reg (Pmode, plus_constant (XEXP (m_tramp, 0), 8));
+      mem = adjust_address (m_tramp, Pmode, 0);
+      emit_move_insn (mem, a);
       i = 8;
     }
 
-  addr = memory_address (Pmode, plus_constant (tramp, i + 2));
-  emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
+  mem = adjust_address (m_tramp, HImode, i + 2);
+  emit_move_insn (mem, gen_lowpart (HImode, t1));
   emit_insn (gen_ashrsi3 (t1, t1, GEN_INT (16)));
-  addr = memory_address (Pmode, plus_constant (tramp, i + 6));
-  emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t1));
+  mem = adjust_address (m_tramp, HImode, i + 6);
+  emit_move_insn (mem, gen_lowpart (HImode, t1));
 
-  addr = memory_address (Pmode, plus_constant (tramp, i + 10));
-  emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
+  mem = adjust_address (m_tramp, HImode, i + 10);
+  emit_move_insn (mem, gen_lowpart (HImode, t2));
   emit_insn (gen_ashrsi3 (t2, t2, GEN_INT (16)));
-  addr = memory_address (Pmode, plus_constant (tramp, i + 14));
-  emit_move_insn (gen_rtx_MEM (HImode, addr), gen_lowpart (HImode, t2));
+  mem = adjust_address (m_tramp, HImode, i + 14);
+  emit_move_insn (mem, gen_lowpart (HImode, t2));
 }
 
 /* Emit insns to move operands[1] into operands[0].  */
@@ -2604,11 +2634,7 @@ bfin_handle_option (size_t code, const char *arg, int value)
 static struct machine_function *
 bfin_init_machine_status (void)
 {
-  struct machine_function *f;
-
-  f = GGC_CNEW (struct machine_function);
-
-  return f;
+  return ggc_alloc_cleared_machine_function ();
 }
 
 /* Implement the macro OVERRIDE_OPTIONS.  */
@@ -3836,7 +3862,7 @@ length_for_loop (rtx insn)
        length = 4;
     }
 
-  if (INSN_P (insn))
+  if (NONDEBUG_INSN_P (insn))
     length += get_attr_length (insn);
 
   return length;
@@ -4073,7 +4099,7 @@ bfin_optimize_loop (loop_info loop)
     {
       for (; last_insn != BB_HEAD (bb);
           last_insn = find_prev_insn_start (last_insn))
-       if (INSN_P (last_insn))
+       if (NONDEBUG_INSN_P (last_insn))
          break;
 
       if (last_insn != BB_HEAD (bb))
@@ -4837,7 +4863,7 @@ bfin_gen_bundles (void)
          int at_end;
          rtx delete_this = NULL_RTX;
 
-         if (INSN_P (insn))
+         if (NONDEBUG_INSN_P (insn))
            {
              enum attr_type type = get_attr_type (insn);
 
@@ -5091,6 +5117,8 @@ trapping_loads_p (rtx insn, int np_reg, bool after_np_branch)
 static rtx
 find_load (rtx insn)
 {
+  if (!NONDEBUG_INSN_P (insn))
+    return NULL_RTX;
   if (get_attr_type (insn) == TYPE_MCLD)
     return insn;
   if (GET_MODE (insn) != SImode)
@@ -5211,7 +5239,7 @@ workaround_speculation (void)
              delay_needed = 3;
            }
        }
-      else if (INSN_P (insn))
+      else if (NONDEBUG_INSN_P (insn))
        {
          rtx load_insn = find_load (insn);
          enum attr_type type = type_for_anomaly (insn);
@@ -5324,7 +5352,7 @@ workaround_speculation (void)
                  || GET_CODE (pat) == ADDR_DIFF_VEC || asm_noperands (pat) >= 0)
                continue;
 
-             if (INSN_P (target))
+             if (NONDEBUG_INSN_P (target))
                {
                  rtx load_insn = find_load (target);
                  enum attr_type type = type_for_anomaly (target);
@@ -5467,7 +5495,11 @@ bfin_reorg (void)
       add_sched_insns_for_speculation ();
 
       timevar_push (TV_SCHED2);
-      schedule_insns ();
+      if (flag_selective_scheduling2
+         && !maybe_skip_selective_scheduling ())
+        run_selective_scheduling ();
+      else
+       schedule_insns ();
       timevar_pop (TV_SCHED2);
 
       /* Examine the schedule and insert nops as necessary for 64-bit parallel
@@ -6617,4 +6649,9 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE bfin_can_eliminate
 
+#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
+#define TARGET_ASM_TRAMPOLINE_TEMPLATE bfin_asm_trampoline_template
+#undef TARGET_TRAMPOLINE_INIT
+#define TARGET_TRAMPOLINE_INIT bfin_trampoline_init
+
 struct gcc_target targetm = TARGET_INITIALIZER;