OSDN Git Service

Merge remote-tracking branch 'gnu/gcc-4_7-branch' into rework
[pf3gnuchains/gcc-fork.git] / gcc / config / picochip / picochip.c
index dd4e34e..d7f9aeb 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines used for code generation on picoChip processors.
-   Copyright (C) 2001, 2008, 2009, 2010   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2008, 2009, 2010, 2011   Free Software Foundation, Inc.
    Contributed by Picochip Ltd. (http://www.picochip.com)
    Maintained by Daniel Towner (daniel.towner@picochip.com) and
    Hariharan Sandanagobalane (hariharan@picochip.com)
@@ -77,16 +77,16 @@ void picochip_asm_file_end (void);
 void picochip_init_libfuncs (void);
 void picochip_reorg (void);
 
-int picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum,
+int picochip_arg_partial_bytes (cumulative_args_t p_cum,
                                       enum machine_mode mode,
                                       tree type, bool named);
-rtx picochip_function_arg (CUMULATIVE_ARGS * p_cum,
+rtx picochip_function_arg (cumulative_args_t p_cum,
                           enum machine_mode mode,
                           const_tree type, bool named);
-rtx picochip_incoming_function_arg (CUMULATIVE_ARGS * p_cum,
+rtx picochip_incoming_function_arg (cumulative_args_t p_cum,
                                    enum machine_mode mode,
                                    const_tree type, bool named);
-void picochip_arg_advance (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
+void picochip_arg_advance (cumulative_args_t p_cum, enum machine_mode mode,
                           const_tree type, bool named);
 unsigned int picochip_function_arg_boundary (enum machine_mode mode,
                                             const_tree type);
@@ -101,7 +101,8 @@ int picochip_sched_reorder (FILE * file, int verbose, rtx * ready,
 void picochip_init_builtins (void);
 rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 
-bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total, bool speed);
+bool picochip_rtx_costs (rtx x, int code, int outer_code, int opno,
+                        int* total, bool speed);
 bool picochip_return_in_memory(const_tree type,
                               const_tree fntype ATTRIBUTE_UNUSED);
 bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
@@ -192,13 +193,6 @@ static struct recog_data picochip_saved_recog_data;
 /* Determine which ALU to use for the instruction in
    picochip_current_prescan_insn. */
 static char picochip_get_vliw_alu_id (void);
-
-/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
-static const struct default_options picochip_option_optimization_table[] =
-  {
-    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
-    { OPT_LEVELS_NONE, 0, NULL, 0 }
-  };
 \f
 /* Initialize the GCC target structure.  */
 
@@ -250,9 +244,6 @@ static const struct default_options picochip_option_optimization_table[] =
 #undef TARGET_ASM_NAMED_SECTION
 #define TARGET_ASM_NAMED_SECTION picochip_asm_named_section
 
-#undef TARGET_HAVE_NAMED_SECTIONS
-#define TARGET_HAVE_NAMED_SECTIONS 1
-
 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS 1
 
@@ -330,11 +321,16 @@ static const struct default_options picochip_option_optimization_table[] =
 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION_TABLE
-#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table
+/* The 2nd scheduling pass option is switched off, and a machine
+   dependent reorganisation ensures that it is run later on, after the
+   second jump optimisation.  */
+#undef TARGET_DELAY_SCHED2
+#define TARGET_DELAY_SCHED2 true
 
-#undef TARGET_EXCEPT_UNWIND_INFO
-#define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
+/* Variable tracking should be run after all optimizations which
+   change order of insns.  It also needs a valid CFG.  */
+#undef TARGET_DELAY_VARTRACK
+#define TARGET_DELAY_VARTRACK true
 
 /* The 2nd scheduling pass option is switched off, and a machine
    dependent reorganisation ensures that it is run later on, after the
@@ -837,9 +833,10 @@ picochip_compute_arg_size (const_tree type, enum machine_mode mode)
 
 /* Determine where the next outgoing arg should be placed. */
 rtx
-picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+picochip_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
                       const_tree type, bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int reg = 0;
   int type_align_in_units = 0;
   int type_size_in_units;
@@ -935,7 +932,7 @@ picochip_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
    passed in registers, which are then pushed onto the stack by the
    function prologue). */
 rtx
-picochip_incoming_function_arg (CUMULATIVE_ARGS *cum,
+picochip_incoming_function_arg (cumulative_args_t cum,
                                enum machine_mode mode,
                                const_tree type, bool named)
 {
@@ -969,7 +966,7 @@ picochip_function_arg_boundary (enum machine_mode mode,
 
 /* Compute partial registers. */
 int
-picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
+picochip_arg_partial_bytes (cumulative_args_t p_cum, enum machine_mode mode,
                            tree type, bool named ATTRIBUTE_UNUSED)
 {
   int type_align_in_units = 0;
@@ -977,7 +974,7 @@ picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
   int new_offset = 0;
   int offset_overflow = 0;
 
-  unsigned cum = *((unsigned *) p_cum);
+  unsigned cum = *get_cumulative_args (p_cum);
 
   /* VOIDmode is passed when computing the second argument to a `call'
      pattern. This can be ignored. */
@@ -1025,9 +1022,10 @@ picochip_arg_partial_bytes (CUMULATIVE_ARGS * p_cum, enum machine_mode mode,
 
 /* Advance the cumulative args counter CUM. */
 void
-picochip_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+picochip_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
                      const_tree type, bool named ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int type_align_in_units = 0;
   int type_size_in_units;
   int new_offset = 0;
@@ -2264,7 +2262,7 @@ picochip_expand_epilogue (int is_sibling_call ATTRIBUTE_UNUSED)
     rtvec p;
     p = rtvec_alloc (2);
 
-    RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
+    RTVEC_ELT (p, 0) = ret_rtx;
     RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
                                    gen_rtx_REG (Pmode, LINK_REGNUM));
     emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -3234,13 +3232,20 @@ reorder_var_tracking_notes (void)
                     }
                 }
             }
-          else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
+          else if (NOTE_P (insn))
             {
                rtx prev = PREV_INSN (insn);
                PREV_INSN (next) = prev;
                NEXT_INSN (prev) = next;
-               PREV_INSN (insn) = queue;
-               queue = insn;
+               /* Ignore call_arg notes. They are expected to be just after the
+                  call insn. If the call is start of a long VLIW, labels are
+                  emitted in the middle of a VLIW, which our assembler can not
+                  handle. */
+               if (NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION)
+                 {
+                   PREV_INSN (insn) = queue;
+                   queue = insn;
+                 }
             }
         }
         /* Make sure we are not dropping debug instructions.*/
@@ -3748,7 +3753,8 @@ gen_SImode_mem(rtx opnd1,rtx opnd2)
 }
 
 bool
-picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int* total, bool speed)
+picochip_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+                   int opno ATTRIBUTE_UNUSED, int* total, bool speed)
 {
 
   int localTotal = 0;
@@ -4208,18 +4214,6 @@ void
 picochip_init_builtins (void)
 {
   tree noreturn;
-  tree endlink = void_list_node;
-  tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
-  tree unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink);
-  tree long_endlink = tree_cons (NULL_TREE, long_integer_type_node, endlink);
-  tree int_int_endlink =
-    tree_cons (NULL_TREE, integer_type_node, int_endlink);
-  tree int_int_int_endlink =
-    tree_cons (NULL_TREE, integer_type_node, int_int_endlink);
-  tree int_long_endlink =
-    tree_cons (NULL_TREE, integer_type_node, long_endlink);
-  tree long_int_int_int_endlink =
-    tree_cons (NULL_TREE, long_integer_type_node, int_int_int_endlink);
 
   tree int_ftype_int, int_ftype_int_int;
   tree long_ftype_int, long_ftype_int_int_int;
@@ -4228,36 +4222,51 @@ picochip_init_builtins (void)
   tree void_ftype_void, unsigned_ftype_unsigned;
 
   /* void func (void) */
-  void_ftype_void = build_function_type (void_type_node, endlink);
+  void_ftype_void = build_function_type_list (void_type_node, NULL_TREE);
 
   /* int func (int) */
-  int_ftype_int = build_function_type (integer_type_node, int_endlink);
+  int_ftype_int = build_function_type_list (integer_type_node,
+                                           integer_type_node, NULL_TREE);
 
   /* unsigned int func (unsigned int) */
-  unsigned_ftype_unsigned = build_function_type (unsigned_type_node, unsigned_endlink);
+  unsigned_ftype_unsigned
+    = build_function_type_list (unsigned_type_node,
+                               unsigned_type_node, NULL_TREE);
 
   /* int func(int, int) */
   int_ftype_int_int
-    = build_function_type (integer_type_node, int_int_endlink);
+    = build_function_type_list (integer_type_node,
+                               integer_type_node, integer_type_node,
+                               NULL_TREE);
 
   /* long func(int) */
-  long_ftype_int = build_function_type (long_integer_type_node, int_endlink);
+  long_ftype_int = build_function_type_list (long_integer_type_node,
+                                            integer_type_node, NULL_TREE);
 
   /* long func(int, int, int) */
   long_ftype_int_int_int
-    = build_function_type (long_integer_type_node, int_int_int_endlink);
+    = build_function_type_list (long_integer_type_node,
+                               integer_type_node, integer_type_node,
+                               integer_type_node, NULL_TREE);
 
   /* int func(int, int, int) */
   int_ftype_int_int_int
-    = build_function_type (integer_type_node, int_int_int_endlink);
+    = build_function_type_list (integer_type_node,
+                               integer_type_node, integer_type_node,
+                               integer_type_node, NULL_TREE);
 
   /* void func(int, long) */
   void_ftype_int_long
-    = build_function_type (void_type_node, int_long_endlink);
+    = build_function_type_list (void_type_node,
+                               integer_type_node, long_integer_type_node,
+                               NULL_TREE);
 
   /* void func(long, int, int, int) */
   void_ftype_long_int_int_int
-    = build_function_type (void_type_node, long_int_int_int_endlink);
+    = build_function_type_list (void_type_node,
+                               long_integer_type_node, integer_type_node,
+                               integer_type_node, integer_type_node,
+                               NULL_TREE);
 
   /* Initialise the sign-bit-count function. */
   add_builtin_function ("__builtin_sbc", int_ftype_int,