OSDN Git Service

* c-decl.c, config/avr/avr.c, config/avr/avr.h,
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / spu.c
index d4fefdd..5297a7b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
 
    This file 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
@@ -1606,7 +1606,7 @@ spu_expand_prologue (void)
     {
       if (flag_stack_check)
        {
-         /* We compare agains total_size-1 because
+         /* We compare against total_size-1 because
             ($sp >= total_size) <=> ($sp > total_size-1) */
          rtx scratch_v4si = gen_rtx_REG (V4SImode, REGNO (scratch_reg_0));
          rtx sp_v4si = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
@@ -1629,21 +1629,18 @@ spu_expand_prologue (void)
        {
          /* In this case we save the back chain first. */
          insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size);
-         RTX_FRAME_RELATED_P (insn) = 1;
          insn =
            frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0);
        }
       else if (satisfies_constraint_K (GEN_INT (-total_size)))
        {
          insn = emit_move_insn (scratch_reg_0, sp_reg);
-         RTX_FRAME_RELATED_P (insn) = 1;
          insn =
            emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)));
        }
       else
        {
          insn = emit_move_insn (scratch_reg_0, sp_reg);
-         RTX_FRAME_RELATED_P (insn) = 1;
          insn =
            frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1);
        }
@@ -1656,7 +1653,6 @@ spu_expand_prologue (void)
        {
          /* Save the back chain ptr */
          insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0);
-         RTX_FRAME_RELATED_P (insn) = 1;
        }
 
       if (frame_pointer_needed)
@@ -1665,7 +1661,12 @@ spu_expand_prologue (void)
          HOST_WIDE_INT fp_offset = STACK_POINTER_OFFSET
            + current_function_outgoing_args_size;
          /* Set the new frame_pointer */
-         frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
+         insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
+         RTX_FRAME_RELATED_P (insn) = 1;
+         real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset));
+         REG_NOTES (insn) = 
+           gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+                              real, REG_NOTES (insn));
        }
     }
 
@@ -1701,8 +1702,6 @@ spu_expand_epilogue (bool sibcall_p)
   if (total_size > 0)
     {
       if (current_function_calls_alloca)
-       /* Load it from the back chain because our save_stack_block and
-          restore_stack_block do nothing. */
        frame_emit_load (STACK_POINTER_REGNUM, sp_reg, 0);
       else
        frame_emit_add_imm (sp_reg, sp_reg, total_size, scratch_reg_0);
@@ -2261,7 +2260,7 @@ spu_sched_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED,
      jump_insn.  We adjust here so higher cost insns will get scheduled
      earlier. */
   if (GET_CODE (insn) == JUMP_INSN && REG_NOTE_KIND (link) == REG_DEP_ANTI)
-    return INSN_COST (dep_insn) - 3;
+    return insn_cost (dep_insn) - 3;
   return cost;
 }
 \f
@@ -2385,7 +2384,7 @@ cpat_info(unsigned char *arr, int size, int *prun, int *pstart)
 }
 
 /* OP is a CONSTANT_P.  Determine what instructions can be used to load
-   it into a regiser.  MODE is only valid when OP is a CONST_INT. */
+   it into a register.  MODE is only valid when OP is a CONST_INT. */
 static enum immediate_class
 classify_immediate (rtx op, enum machine_mode mode)
 {
@@ -2793,7 +2792,7 @@ spu_handle_vector_attribute (tree * node, tree name,
   return NULL_TREE;
 }
 
-/* Return non-zero if FUNC is a naked function.  */
+/* Return nonzero if FUNC is a naked function.  */
 static int
 spu_naked_function_p (tree func)
 {
@@ -4305,6 +4304,32 @@ spu_init_builtins (void)
     }
 }
 
+void
+spu_restore_stack_block (rtx op0 ATTRIBUTE_UNUSED, rtx op1)
+{
+  static unsigned char arr[16] =
+    { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
+
+  rtx temp = gen_reg_rtx (Pmode);
+  rtx temp2 = gen_reg_rtx (V4SImode);
+  rtx temp3 = gen_reg_rtx (V4SImode);
+  rtx pat = gen_reg_rtx (TImode);
+  rtx sp = gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM);
+
+  emit_move_insn (pat, array_to_constant (TImode, arr));
+
+  /* Restore the sp.  */
+  emit_move_insn (temp, op1);
+  emit_move_insn (temp2, gen_frame_mem (V4SImode, stack_pointer_rtx));
+
+  /* Compute available stack size for sp.  */
+  emit_insn (gen_subsi3 (temp, temp, stack_pointer_rtx));
+  emit_insn (gen_shufb (temp3, temp, temp, pat));
+
+  emit_insn (gen_addv4si3 (sp, sp, temp3));
+  emit_move_insn (gen_frame_mem (V4SImode, stack_pointer_rtx), temp2);
+}
+
 int
 spu_safe_dma (HOST_WIDE_INT channel)
 {