OSDN Git Service

* config/sh/sh.c (prepare_cbranch_operands): Use
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.c
index 14892ce..cf6e1a7 100644 (file)
@@ -1,6 +1,6 @@
 /* Output routines for GCC for Renesas / SuperH SH.
    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com).
    Improved by Jim Wilson (wilson@cygnus.com).
 
@@ -405,6 +405,9 @@ static int sh2a_function_vector_p (tree);
 #undef TARGET_MACHINE_DEPENDENT_REORG
 #define TARGET_MACHINE_DEPENDENT_REORG sh_reorg
 
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN sh_dwarf_register_span
+
 #ifdef HAVE_AS_TLS
 #undef TARGET_HAVE_TLS
 #define TARGET_HAVE_TLS true
@@ -1375,7 +1378,7 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
   rtx op1;
   rtx scratch = NULL_RTX;
 
-  if (comparison == CODE_FOR_nothing)
+  if (comparison == LAST_AND_UNUSED_RTX_CODE)
     comparison = GET_CODE (operands[0]);
   else
     scratch = operands[4];
@@ -1475,9 +1478,7 @@ expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
                                           operands[1], operands[2])));
   jump = emit_jump_insn (branch_expander (operands[3]));
   if (probability >= 0)
-    REG_NOTES (jump)
-      = gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (probability),
-                           REG_NOTES (jump));
+    add_reg_note (jump, REG_BR_PROB, GEN_INT (probability));
 
 }
 
@@ -1515,7 +1516,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
   op2h = gen_highpart_mode (SImode, DImode, operands[2]);
   op1l = gen_lowpart (SImode, operands[1]);
   op2l = gen_lowpart (SImode, operands[2]);
-  msw_taken = msw_skip = lsw_taken = CODE_FOR_nothing;
+  msw_taken = msw_skip = lsw_taken = LAST_AND_UNUSED_RTX_CODE;
   prob = split_branch_probability;
   rev_prob = REG_BR_PROB_BASE - prob;
   switch (comparison)
@@ -1606,9 +1607,9 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
       break;
     default: return false;
     }
-  num_branches = ((msw_taken != CODE_FOR_nothing)
-                 + (msw_skip != CODE_FOR_nothing)
-                 + (lsw_taken != CODE_FOR_nothing));
+  num_branches = ((msw_taken != LAST_AND_UNUSED_RTX_CODE)
+                 + (msw_skip != LAST_AND_UNUSED_RTX_CODE)
+                 + (lsw_taken != LAST_AND_UNUSED_RTX_CODE));
   if (comparison != EQ && comparison != NE && num_branches > 1)
     {
       if (!CONSTANT_P (operands[2])
@@ -1634,20 +1635,21 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
   operands[4] = NULL_RTX;
   if (reload_completed
       && ! arith_reg_or_0_operand (op2h, SImode) && true_regnum (op1h)
-      && (msw_taken != CODE_FOR_nothing || msw_skip != CODE_FOR_nothing))
+      && (msw_taken != LAST_AND_UNUSED_RTX_CODE
+         || msw_skip != LAST_AND_UNUSED_RTX_CODE))
     {
       emit_move_insn (scratch, operands[2]);
       operands[2] = scratch;
     }
-  if (msw_taken != CODE_FOR_nothing)
+  if (msw_taken != LAST_AND_UNUSED_RTX_CODE)
     expand_cbranchsi4 (operands, msw_taken, msw_taken_prob);
-  if (msw_skip != CODE_FOR_nothing)
+  if (msw_skip != LAST_AND_UNUSED_RTX_CODE)
     {
       rtx taken_label = operands[3];
 
       /* Operands were possibly modified, but msw_skip doesn't expect this.
         Always use the original ones.  */
-      if (msw_taken != CODE_FOR_nothing)
+      if (msw_taken != LAST_AND_UNUSED_RTX_CODE)
        {
          operands[1] = op1h;
          operands[2] = op2h;
@@ -1659,14 +1661,14 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
     }
   operands[1] = op1l;
   operands[2] = op2l;
-  if (lsw_taken != CODE_FOR_nothing)
+  if (lsw_taken != LAST_AND_UNUSED_RTX_CODE)
     {
       if (reload_completed
          && ! arith_reg_or_0_operand (op2l, SImode) && true_regnum (op1l))
        operands[4] = scratch;
       expand_cbranchsi4 (operands, lsw_taken, lsw_taken_prob);
     }
-  if (msw_skip != CODE_FOR_nothing)
+  if (msw_skip != LAST_AND_UNUSED_RTX_CODE)
     emit_label (skip_label);
   return true;
 }
@@ -1763,7 +1765,7 @@ from_compare (rtx *operands, int code)
   else
     insn = gen_rtx_SET (VOIDmode,
                        gen_rtx_REG (SImode, T_REG),
-                       gen_rtx_fmt_ee (code, SImode,
+                       gen_rtx_fmt_ee ((enum rtx_code) code, SImode,
                                        sh_compare_op0, sh_compare_op1));
   if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
     {
@@ -3826,6 +3828,10 @@ untangle_mova (int *num_mova, rtx *first_mova, rtx new_mova)
 
   if (optimize)
     {
+      /* If NEW_MOVA has no address yet, it will be handled later.  */
+      if (INSN_ADDRESSES_SIZE() <= (unsigned) INSN_UID (new_mova))
+       return -1;
+
       n_addr = INSN_ADDRESSES (INSN_UID (new_mova));
       n_target = INSN_ADDRESSES (INSN_UID (XEXP (MOVA_LABELREF (new_mova), 0)));
       if (n_addr > n_target || n_addr + 1022 < n_target)
@@ -5697,12 +5703,10 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
              insn = emit_fn (GEN_ADD3 (reg, reg, const_reg));
            }
          if (! epilogue_p)
-           REG_NOTES (insn)
-             = (gen_rtx_EXPR_LIST
-                (REG_FRAME_RELATED_EXPR,
-                 gen_rtx_SET (VOIDmode, reg,
-                              gen_rtx_PLUS (SImode, reg, GEN_INT (size))),
-                 REG_NOTES (insn)));
+           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
+                         gen_rtx_SET (VOIDmode, reg,
+                                      gen_rtx_PLUS (SImode, reg,
+                                                    GEN_INT (size))));
        }
     }
 }
@@ -5738,9 +5742,7 @@ push (int rn)
     x = gen_push (gen_rtx_REG (SImode, rn));
 
   x = frame_insn (x);
-  REG_NOTES (x)
-    = gen_rtx_EXPR_LIST (REG_INC,
-                        gen_rtx_REG (SImode, STACK_POINTER_REGNUM), 0);
+  add_reg_note (x, REG_INC, gen_rtx_REG (SImode, STACK_POINTER_REGNUM));
   return x;
 }
 
@@ -5767,9 +5769,7 @@ pop (int rn)
     x = gen_pop (gen_rtx_REG (SImode, rn));
 
   x = emit_insn (x);
-  REG_NOTES (x)
-    = gen_rtx_EXPR_LIST (REG_INC,
-                        gen_rtx_REG (SImode, STACK_POINTER_REGNUM), 0);
+  add_reg_note (x, REG_INC, gen_rtx_REG (SImode, STACK_POINTER_REGNUM));
 }
 
 /* Generate code to push the regs specified in the mask.  */
@@ -5962,7 +5962,9 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
              && crtl->args.info.call_cookie
              && reg == PIC_OFFSET_TABLE_REGNUM)
             || (df_regs_ever_live_p (reg)
-                && (!call_really_used_regs[reg]
+                && ((!call_really_used_regs[reg]
+                     && !(reg != PIC_OFFSET_TABLE_REGNUM
+                          && fixed_regs[reg] && call_used_regs[reg]))
                     || (trapa_handler && reg == FPSCR_REG && TARGET_FPU_ANY)))
             || (crtl->calls_eh_return
                 && (reg == EH_RETURN_DATA_REGNO (0)
@@ -6472,27 +6474,23 @@ sh_expand_prologue (void)
               a direct save from the to-be-saved register.  */
            if (REGNO (reg_rtx) != reg)
              {
-               rtx set, note_rtx;
+               rtx set;
 
                set = gen_rtx_SET (VOIDmode, mem_rtx, orig_reg_rtx);
-               note_rtx = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, set,
-                                             REG_NOTES (insn));
-               REG_NOTES (insn) = note_rtx;
+               add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
              }
 
            if (TARGET_SHCOMPACT && (offset_in_r0 != -1))
              {
                rtx reg_rtx = gen_rtx_REG (mode, reg);
-               rtx set, note_rtx;
+               rtx set;
                rtx mem_rtx = gen_frame_mem (mode,
                                             gen_rtx_PLUS (Pmode,
                                                           stack_pointer_rtx,
                                                           GEN_INT (offset)));
 
                set = gen_rtx_SET (VOIDmode, mem_rtx, reg_rtx);
-               note_rtx = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, set,
-                                             REG_NOTES (insn));
-               REG_NOTES (insn) = note_rtx;
+               add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
              }
          }
        }
@@ -7420,6 +7418,26 @@ sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
   return result;
 }
 
+/* 64 bit floating points memory transfers are paired single precision loads
+   or store. So DWARF information needs fixing in little endian (unless
+   PR=SZ=1 in FPSCR).  */
+rtx
+sh_dwarf_register_span (rtx reg)
+{
+  unsigned regno = REGNO (reg);
+
+  if (WORDS_BIG_ENDIAN || GET_MODE (reg) != DFmode)
+    return NULL_RTX;
+
+  return
+    gen_rtx_PARALLEL (VOIDmode,
+                     gen_rtvec (2,
+                                gen_rtx_REG (SFmode,
+                                             DBX_REGISTER_NUMBER (regno+1)),
+                                gen_rtx_REG (SFmode,
+                                             DBX_REGISTER_NUMBER (regno))));
+}
+
 bool
 sh_promote_prototypes (const_tree type)
 {
@@ -8722,7 +8740,7 @@ sh_insn_length_adjustment (rtx insn)
 
   /* SH2e has a bug that prevents the use of annulled branches, so if
      the delay slot is not filled, we'll have to put a NOP in it.  */
-  if (sh_cpu == CPU_SH2E
+  if (sh_cpu_attr == CPU_SH2E
       && GET_CODE (insn) == JUMP_INSN
       && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
       && GET_CODE (PATTERN (insn)) != ADDR_VEC
@@ -9807,7 +9825,7 @@ sh_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
          || (!(TARGET_SH4A_ARCH || TARGET_SH4_300) && TARGET_USERMODE))
        emit_library_call (function_symbol (NULL, "__ic_invalidate",
                                            FUNCTION_ORDINARY),
-                          0, VOIDmode, 1, tramp, SImode);
+                          LCT_NORMAL, VOIDmode, 1, tramp, SImode);
       else
        emit_insn (gen_ic_invalidate_line (tramp));
     }
@@ -10144,7 +10162,7 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
       argmode = TYPE_MODE (TREE_TYPE (arg));
       if (argmode != opmode)
        arg = build1 (NOP_EXPR, optype, arg);
-      op[nop] = expand_expr (arg, NULL_RTX, opmode, 0);
+      op[nop] = expand_expr (arg, NULL_RTX, opmode, EXPAND_NORMAL);
       if (! (*insn_data[icode].operand[nop].predicate) (op[nop], opmode))
        op[nop] = copy_to_mode_reg (opmode, op[nop]);
     }