OSDN Git Service

PR target/31110
[pf3gnuchains/gcc-fork.git] / gcc / config / mn10300 / mn10300.c
index f63d778..0d2ae38 100644 (file)
@@ -1,13 +1,13 @@
 /* Subroutines for insn-output.c for Matsushita MN10300 series
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    Contributed by Jeff Law (law@cygnus.com).
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -16,9 +16,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -60,12 +59,12 @@ enum processor_type mn10300_processor = PROCESSOR_DEFAULT;
 /* The size of the callee register save area.  Right now we save everything
    on entry since it costs us nothing in code size.  It does cost us from a
    speed standpoint, so we want to optimize this sooner or later.  */
-#define REG_SAVE_BYTES (4 * regs_ever_live[2] \
-                       + 4 * regs_ever_live[3] \
-                       + 4 * regs_ever_live[6] \
-                       + 4 * regs_ever_live[7] \
-                       + 16 * (regs_ever_live[14] || regs_ever_live[15] \
-                               || regs_ever_live[16] || regs_ever_live[17]))
+#define REG_SAVE_BYTES (4 * df_regs_ever_live_p (2)    \
+                       + 4 * df_regs_ever_live_p (3)   \
+                       + 4 * df_regs_ever_live_p (6)   \
+                       + 4 * df_regs_ever_live_p (7)                   \
+                       + 16 * (df_regs_ever_live_p (14) || df_regs_ever_live_p (15) \
+                               || df_regs_ever_live_p (16) || df_regs_ever_live_p (17)))
 
 
 static bool mn10300_handle_option (size_t, const char *, int);
@@ -73,10 +72,11 @@ static int mn10300_address_cost_1 (rtx, int *);
 static int mn10300_address_cost (rtx);
 static bool mn10300_rtx_costs (rtx, int, int, int *);
 static void mn10300_file_start (void);
-static bool mn10300_return_in_memory (tree, tree);
+static bool mn10300_return_in_memory (const_tree, const_tree);
 static rtx mn10300_builtin_saveregs (void);
+static void mn10300_va_start (tree, rtx);
 static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
-                                      tree, bool);
+                                      const_tree, bool);
 static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
                                      tree, bool);
 \f
@@ -103,7 +103,7 @@ static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
 #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info
 
 #undef TARGET_PROMOTE_PROTOTYPES
-#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY mn10300_return_in_memory
 #undef TARGET_PASS_BY_REFERENCE
@@ -115,6 +115,8 @@ static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS mn10300_builtin_saveregs
+#undef TARGET_EXPAND_BUILTIN_VA_START
+#define TARGET_EXPAND_BUILTIN_VA_START mn10300_va_start
 
 static void mn10300_encode_section_info (tree, rtx, int);
 struct gcc_target targetm = TARGET_INITIALIZER;
@@ -274,7 +276,7 @@ print_operand (FILE *file, rtx x, int code)
        else
          print_operand (file, x, 0);
        break;
-     
+
       case 'D':
        switch (GET_CODE (x))
          {
@@ -387,7 +389,7 @@ print_operand (FILE *file, rtx x, int code)
                      gcc_unreachable ();
                    case VOIDmode:
                    case DImode:
-                     print_operand_address (file, 
+                     print_operand_address (file,
                                             GEN_INT (CONST_DOUBLE_HIGH (x)));
                      break;
                    default:
@@ -537,7 +539,7 @@ fp_regs_to_save (void)
     return 0;
 
   for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
-    if (regs_ever_live[i] && ! call_used_regs[i])
+    if (df_regs_ever_live_p (i) && ! call_used_regs[i])
       ++n;
 
   return n;
@@ -546,7 +548,7 @@ fp_regs_to_save (void)
 /* Print a set of registers in the format required by "movm" and "ret".
    Register K is saved if bit K of MASK is set.  The data and address
    registers can be stored individually, but the extended registers cannot.
-   We assume that the mask alread takes that into account.  For instance,
+   We assume that the mask already takes that into account.  For instance,
    bits 14 to 17 must have the same value.  */
 
 void
@@ -590,14 +592,14 @@ can_use_return_insn (void)
 
   return (reload_completed
          && size == 0
-         && !regs_ever_live[2]
-         && !regs_ever_live[3]
-         && !regs_ever_live[6]
-         && !regs_ever_live[7]
-         && !regs_ever_live[14]
-         && !regs_ever_live[15]
-         && !regs_ever_live[16]
-         && !regs_ever_live[17]
+         && !df_regs_ever_live_p (2)
+         && !df_regs_ever_live_p (3)
+         && !df_regs_ever_live_p (6)
+         && !df_regs_ever_live_p (7)
+         && !df_regs_ever_live_p (14)
+         && !df_regs_ever_live_p (15)
+         && !df_regs_ever_live_p (16)
+         && !df_regs_ever_live_p (17)
          && fp_regs_to_save () == 0
          && !frame_pointer_needed);
 }
@@ -614,7 +616,7 @@ mn10300_get_live_callee_saved_regs (void)
 
   mask = 0;
   for (i = 0; i <= LAST_EXTENDED_REGNUM; i++)
-    if (regs_ever_live[i] && ! call_used_regs[i])
+    if (df_regs_ever_live_p (i) && ! call_used_regs[i])
       mask |= (1 << i);
   if ((mask & 0x3c000) != 0)
     mask |= 0x3c000;
@@ -882,7 +884,7 @@ expand_prologue (void)
        default:
          gcc_unreachable ();
        }
-         
+
       /* Now prepare register a0, if we have decided to use it.  */
       switch (strategy)
        {
@@ -900,14 +902,14 @@ expand_prologue (void)
            emit_insn (gen_addsi3 (reg, reg, GEN_INT (xsize)));
          reg = gen_rtx_POST_INC (SImode, reg);
          break;
-         
+
        default:
          gcc_unreachable ();
        }
-      
+
       /* Now actually save the FP registers.  */
       for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
-       if (regs_ever_live[i] && ! call_used_regs[i])
+       if (df_regs_ever_live_p (i) && ! call_used_regs[i])
          {
            rtx addr;
 
@@ -924,7 +926,7 @@ expand_prologue (void)
                  }
                else
                  addr = stack_pointer_rtx;
-               
+
                xsize += 4;
              }
 
@@ -944,24 +946,8 @@ expand_prologue (void)
     emit_insn (gen_addsi3 (stack_pointer_rtx,
                           stack_pointer_rtx,
                           GEN_INT (-size)));
-  if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
-    {
-      rtx insn = get_last_insn ();
-      rtx last = emit_insn (gen_GOTaddr2picreg ());
-
-      /* Mark these insns as possibly dead.  Sometimes, flow2 may
-        delete all uses of the PIC register.  In this case, let it
-        delete the initialization too.  */
-      do
-       {
-         insn = NEXT_INSN (insn);
-
-         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
-                                               const0_rtx,
-                                               REG_NOTES (insn));
-       }
-      while (insn != last);
-    }
+  if (flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM))
+    emit_insn (gen_GOTaddr2picreg ());
 }
 
 void
@@ -1109,7 +1095,7 @@ expand_epilogue (void)
                                              + REG_SAVE_BYTES - 252)));
              size = 252 - REG_SAVE_BYTES - 4 * num_regs_to_save;
              break;
-             
+
            case restore_a1:
              reg = gen_rtx_REG (SImode, FIRST_ADDRESS_REGNUM + 1);
              emit_insn (gen_movsi (reg, stack_pointer_rtx));
@@ -1127,10 +1113,10 @@ expand_epilogue (void)
        reg = gen_rtx_POST_INC (SImode, reg);
 
       for (i = FIRST_FP_REGNUM; i <= LAST_FP_REGNUM; ++i)
-       if (regs_ever_live[i] && ! call_used_regs[i])
+       if (df_regs_ever_live_p (i) && ! call_used_regs[i])
          {
            rtx addr;
-           
+
            if (reg)
              addr = reg;
            else if (size)
@@ -1167,7 +1153,7 @@ expand_epilogue (void)
 
      If the stack size + register save area is more than 255 bytes,
      then the stack must be cut back here since the size + register
-     save size is too big for a ret/retf instruction. 
+     save size is too big for a ret/retf instruction.
 
      Else leave it alone, it will be cut back as part of the
      ret/retf instruction, or there wasn't any stack to begin with.
@@ -1189,10 +1175,10 @@ expand_epilogue (void)
     }
 
   /* Adjust the stack and restore callee-saved registers, if any.  */
-  if (size || regs_ever_live[2] || regs_ever_live[3]
-      || regs_ever_live[6] || regs_ever_live[7]
-      || regs_ever_live[14] || regs_ever_live[15]
-      || regs_ever_live[16] || regs_ever_live[17]
+  if (size || df_regs_ever_live_p (2) || df_regs_ever_live_p (3)
+      || df_regs_ever_live_p (6) || df_regs_ever_live_p (7)
+      || df_regs_ever_live_p (14) || df_regs_ever_live_p (15)
+      || df_regs_ever_live_p (16) || df_regs_ever_live_p (17)
       || frame_pointer_needed)
     emit_jump_insn (gen_return_internal_regs
                    (GEN_INT (size + REG_SAVE_BYTES)));
@@ -1333,7 +1319,7 @@ store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 }
 
 /* What (if any) secondary registers are needed to move IN with mode
-   MODE into a register in register class CLASS. 
+   MODE into a register in register class CLASS.
 
    We might be able to simplify this.  */
 enum reg_class
@@ -1375,14 +1361,11 @@ mn10300_secondary_reload_class (enum reg_class class, enum machine_mode mode,
   if (GET_CODE (in) == PLUS
       && (XEXP (in, 0) == stack_pointer_rtx
          || XEXP (in, 1) == stack_pointer_rtx))
-    {
-      if (TARGET_AM33)
-       return DATA_OR_EXTENDED_REGS;
-      return DATA_REGS;
-    }
+    return GENERAL_REGS;
+
   if (TARGET_AM33_2 && class == FP_REGS
-      && GET_CODE (in) == MEM && ! OK_FOR_Q (in))
+      && GET_CODE (in) == MEM
+      && ! (GET_CODE (in) == MEM && !CONSTANT_ADDRESS_P (XEXP (in, 0))))
     {
       if (TARGET_AM33)
        return DATA_OR_EXTENDED_REGS;
@@ -1400,10 +1383,10 @@ initial_offset (int from, int to)
      is the size of the callee register save area.  */
   if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
     {
-      if (regs_ever_live[2] || regs_ever_live[3]
-         || regs_ever_live[6] || regs_ever_live[7]
-         || regs_ever_live[14] || regs_ever_live[15]
-         || regs_ever_live[16] || regs_ever_live[17]
+      if (df_regs_ever_live_p (2) || df_regs_ever_live_p (3)
+         || df_regs_ever_live_p (6) || df_regs_ever_live_p (7)
+         || df_regs_ever_live_p (14) || df_regs_ever_live_p (15)
+         || df_regs_ever_live_p (16) || df_regs_ever_live_p (17)
          || fp_regs_to_save ()
          || frame_pointer_needed)
        return REG_SAVE_BYTES
@@ -1417,20 +1400,20 @@ initial_offset (int from, int to)
      area, and the fixed stack space needed for function calls (if any).  */
   if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
     {
-      if (regs_ever_live[2] || regs_ever_live[3]
-         || regs_ever_live[6] || regs_ever_live[7]
-         || regs_ever_live[14] || regs_ever_live[15]
-         || regs_ever_live[16] || regs_ever_live[17]
+      if (df_regs_ever_live_p (2) || df_regs_ever_live_p (3)
+         || df_regs_ever_live_p (6) || df_regs_ever_live_p (7)
+         || df_regs_ever_live_p (14) || df_regs_ever_live_p (15)
+         || df_regs_ever_live_p (16) || df_regs_ever_live_p (17)
          || fp_regs_to_save ()
          || frame_pointer_needed)
        return (get_frame_size () + REG_SAVE_BYTES
                + 4 * fp_regs_to_save ()
                + (current_function_outgoing_args_size
-                  ? current_function_outgoing_args_size + 4 : 0)); 
+                  ? current_function_outgoing_args_size + 4 : 0));
       else
        return (get_frame_size ()
                + (current_function_outgoing_args_size
-                  ? current_function_outgoing_args_size + 4 : 0)); 
+                  ? current_function_outgoing_args_size + 4 : 0));
     }
 
   /* The difference between the frame pointer and stack pointer is the sum
@@ -1439,7 +1422,7 @@ initial_offset (int from, int to)
   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
     return (get_frame_size ()
            + (current_function_outgoing_args_size
-              ? current_function_outgoing_args_size + 4 : 0)); 
+              ? current_function_outgoing_args_size + 4 : 0));
 
   gcc_unreachable ();
 }
@@ -1447,7 +1430,7 @@ initial_offset (int from, int to)
 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
 
 static bool
-mn10300_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+mn10300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
 {
   /* Return values > 8 bytes in length in memory.  */
   return (int_size_in_bytes (type) > 8
@@ -1466,7 +1449,7 @@ mn10300_builtin_saveregs (void)
                    && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
                        != void_type_node)))
                 ? UNITS_PER_WORD : 0);
-  int set = get_varargs_alias_set ();
+  alias_set_type set = get_varargs_alias_set ();
 
   if (argadj)
     offset = plus_constant (current_function_arg_offset_rtx, argadj);
@@ -1487,7 +1470,7 @@ mn10300_builtin_saveregs (void)
                                    offset, 0, 0, OPTAB_LIB_WIDEN));
 }
 
-void
+static void
 mn10300_va_start (tree valist, rtx nextarg)
 {
   nextarg = expand_builtin_saveregs ();
@@ -1498,7 +1481,7 @@ mn10300_va_start (tree valist, rtx nextarg)
 
 static bool
 mn10300_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
-                          enum machine_mode mode, tree type,
+                          enum machine_mode mode, const_tree type,
                           bool named ATTRIBUTE_UNUSED)
 {
   unsigned HOST_WIDE_INT size;
@@ -1608,7 +1591,7 @@ mn10300_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
    callers relying on this extra copy.  */
 
 rtx
-mn10300_function_value (tree valtype, tree func, int outgoing)
+mn10300_function_value (const_tree valtype, const_tree func, int outgoing)
 {
   rtx rv;
   enum machine_mode mode = TYPE_MODE (valtype);
@@ -1624,7 +1607,7 @@ mn10300_function_value (tree valtype, tree func, int outgoing)
     = gen_rtx_EXPR_LIST (VOIDmode,
                         gen_rtx_REG (mode, FIRST_ADDRESS_REGNUM),
                         GEN_INT (0));
-  
+
   XVECEXP (rv, 0, 1)
     = gen_rtx_EXPR_LIST (VOIDmode,
                         gen_rtx_REG (mode, FIRST_DATA_REGNUM),
@@ -1672,7 +1655,7 @@ output_tst (rtx operand, rtx insn)
        }
 
       /* Are we setting a data register to zero (this does not win for
-        address registers)? 
+        address registers)?
 
         If it's a call clobbered register, have we past a call?
 
@@ -1688,7 +1671,7 @@ output_tst (rtx operand, rtx insn)
              == REGNO_REG_CLASS (REGNO (operand)))
          && REGNO_REG_CLASS (REGNO (SET_DEST (set))) != EXTENDED_REGS
          && REGNO (SET_DEST (set)) != REGNO (operand)
-         && (!past_call 
+         && (!past_call
              || !call_used_regs[REGNO (SET_DEST (set))]))
        {
          rtx xoperands[2];
@@ -1707,7 +1690,7 @@ output_tst (rtx operand, rtx insn)
              != REGNO_REG_CLASS (REGNO (operand)))
          && REGNO_REG_CLASS (REGNO (SET_DEST (set))) == EXTENDED_REGS
          && REGNO (SET_DEST (set)) != REGNO (operand)
-         && (!past_call 
+         && (!past_call
              || !call_used_regs[REGNO (SET_DEST (set))]))
        {
          rtx xoperands[2];
@@ -2087,7 +2070,7 @@ mn10300_wide_const_load_uses_clr (rtx operands[2])
        val[1] = INTVAL (high);
       }
       break;
-      
+
     case CONST_DOUBLE:
       if (GET_MODE (operands[1]) == DFmode)
        {
@@ -2103,7 +2086,7 @@ mn10300_wide_const_load_uses_clr (rtx operands[2])
          val[1] = CONST_DOUBLE_HIGH (operands[1]);
        }
       break;
-      
+
     default:
       return false;
     }