OSDN Git Service

* spu.h (STACK_SAVE_AREA): Use VOIDmode for SAVE_FUNCTION, SImode
authorbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jan 2007 05:24:01 +0000 (05:24 +0000)
committerbje <bje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Jan 2007 05:24:01 +0000 (05:24 +0000)
for SAVE_NONLOCAL and Pmode for any other save level.
* spu-protos.h (spu_restore_stack_block): Declare.
* spu.md (save_stack_block): Remove.
(restore_stack_block): Call spu_restore_stack_block.
* spu.c (spu_restore_stack_block): New function.
(spu_expand_epilogue): Remove old comment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120633 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/spu/spu-protos.h
gcc/config/spu/spu.c
gcc/config/spu/spu.h
gcc/config/spu/spu.md

index b85f8bb..3d1f018 100644 (file)
@@ -1,3 +1,14 @@
+2007-01-10  Sa Liu  <saliu@de.ibm.com>
+           Ben Elliston  <bje@au.ibm.com>
+
+       * spu.h (STACK_SAVE_AREA): Use VOIDmode for SAVE_FUNCTION, SImode
+       for SAVE_NONLOCAL and Pmode for any other save level.
+       * spu-protos.h (spu_restore_stack_block): Declare.
+       * spu.md (save_stack_block): Remove.
+       (restore_stack_block): Call spu_restore_stack_block.
+       * spu.c (spu_restore_stack_block): New function.
+       (spu_expand_epilogue): Remove old comment.
+
 2007-01-09  Zdenek Dvorak <dvorakz@suse.cz>
 
        PR tree-optimization/30322
index 01f5c60..6f87ec0 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
@@ -78,6 +78,7 @@ extern rtx array_to_constant (enum machine_mode mode, unsigned char *arr);
 extern enum machine_mode spu_eh_return_filter_mode (void);
 extern void spu_allocate_stack (rtx op0, rtx op1);
 extern void spu_restore_stack_nonlocal (rtx op0, rtx op1);
+extern void spu_restore_stack_block (rtx op0, rtx op1);
 extern rtx spu_gen_subreg (enum machine_mode mode, rtx x);
 extern int spu_safe_dma(HOST_WIDE_INT channel);
 extern void spu_builtin_splats (rtx ops[]);
index b724b80..e30d00e 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
@@ -1702,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);
@@ -4306,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)
 {
index 74db224..240d245 100644 (file)
@@ -96,7 +96,10 @@ extern const char *spu_fixed_range_string;
 
 #define MAX_FIXED_MODE_SIZE 128
 
-#define STACK_SAVEAREA_MODE(save_level) SImode
+#define STACK_SAVEAREA_MODE(save_level) \
+  (save_level == SAVE_FUNCTION ? VOIDmode \
+    : save_level == SAVE_NONLOCAL ? SImode \
+      : Pmode)
 
 #define STACK_SIZE_MODE SImode
 
index 7978361..8e8fad2 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
@@ -3116,16 +3116,19 @@ selb\t%0,%4,%0,%3"
   "spu_allocate_stack (operands[0], operands[1]); DONE;")
 
 ;; These patterns say how to save and restore the stack pointer.  We need not
-;; save the stack pointer at function or block level since we are careful to
-;; preserve the backchain.  Doing nothing at block level means the stack space
-;; is allocated until the end of the function.  This is currently safe to do
-;; because gcc uses the frame pointer for the whole function, so the worst that
-;; happens is wasted stack space.  That could be bad if a VLA is declared in a
-;; loop, because new space will be allocated every iteration, but users can
-;; work around that case.  Ideally we could detect when we are in a loop and
-;; generate the more complicated code in that case.
+;; save the stack pointer at function level since we are careful to preserve 
+;; the backchain.  
+;; 
+
+;; At block level the stack pointer is saved and restored, so that the
+;; stack space allocated within a block is deallocated when leaving
+;; block scope.  By default, according to the SPU ABI, the stack
+;; pointer and available stack size are saved in a register. Upon
+;; restoration, the stack pointer is simply copied back, and the
+;; current available stack size is calculated against the restored
+;; stack pointer.
 ;;
-;; For nonlocal gotos, we must save both the stack pointer and its
+;; For nonlocal gotos, we must save the stack pointer and its
 ;; backchain and restore both.  Note that in the nonlocal case, the
 ;; save area is a memory location.
 
@@ -3141,19 +3144,15 @@ selb\t%0,%4,%0,%3"
   ""
   "DONE;")
 
-(define_expand "save_stack_block"
-  [(match_operand 0 "general_operand" "")
-   (match_operand 1 "general_operand" "")]
-  ""
-  "DONE; ")
-
 (define_expand "restore_stack_block"
-  [(use (match_operand 0 "spu_reg_operand" ""))
-   (set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (match_operand 1 "spu_reg_operand" ""))
-   (set (match_dup 3) (match_dup 2))]
+  [(match_operand 0 "spu_reg_operand" "")
+   (match_operand 1 "memory_operand" "")]
   ""
-  "DONE;")
+  "
+  {
+    spu_restore_stack_block (operands[0], operands[1]);
+    DONE;
+  }")
 
 (define_expand "save_stack_nonlocal"
   [(match_operand 0 "memory_operand" "")