This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Patch: prologue on NT


On Mon, Apr 19, 1999 at 05:48:33PM -0600, Donn Terry wrote:
>   ldah Rx, Hi(r31)  // Need not be contiguous with following
>   lda rx, Lo(r31)
>  followed by
>   subq sp, Rx, sp  # MUST be a single instruction.

Ho hum.  Try the following.

> There's also a whole long tap-dance about the exact order in
> which registers must be saved; LAST I looked this seemed OK
> in gcc, but I haven't looked at it really closely in egcs, yet
> (but the debugger seems OK so far, so it isn't TOO far off)

Do you mean the sequence of the stores, or the order of the 
addresses on the stack?  The former can be messed up sometimes
by the scheduler.  Perhaps it doesn't happen often with the
scheduling barrier in place as it is.


r~


Index: alpha.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.c,v
retrieving revision 1.79
diff -c -p -d -r1.79 alpha.c
*** alpha.c	1999/04/17 19:03:03	1.79
--- alpha.c	1999/04/20 05:24:44
*************** alpha_expand_prologue ()
*** 3421,3426 ****
--- 3421,3427 ----
        HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
        rtx ptr = gen_rtx_REG (DImode, 22);
        rtx count = gen_rtx_REG (DImode, 23);
+       rtx seq;
  
        emit_move_insn (count, GEN_INT (blocks));
        emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
*************** alpha_expand_prologue ()
*** 3441,3473 ****
  	  /* For NT stack unwind (done by 'reverse execution'), it's
  	     not OK to take the result of a loop, even though the value
  	     is already in ptr, so we reload it via a single operation
! 	     and add it to sp.  */
  
  	  HOST_WIDE_INT lo, hi;
  	  lo = ((-frame_size & 0xffff) ^ 0x8000) - 0x8000;
  	  hi = -frame_size - lo;
  
! 	  FRP (emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (hi))));
! 	  FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, GEN_INT (lo))));
  	}
        else
  	{
- 	  rtx seq;
- 
  	  seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
  				       GEN_INT (-leftover)));
- 
- 	  /* This alternative is special, because the DWARF code cannot
- 	     possibly intuit through the loop above.  So we invent this
- 	     note it looks at instead.  */
- 	  RTX_FRAME_RELATED_P (seq) = 1;
- 	  REG_NOTES (seq)
- 	    = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- 				 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- 				   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- 						 GEN_INT (-frame_size))),
- 				 REG_NOTES (seq));
  	}
      }
  
    /* Cope with very large offsets to the register save area.  */
--- 3442,3478 ----
  	  /* For NT stack unwind (done by 'reverse execution'), it's
  	     not OK to take the result of a loop, even though the value
  	     is already in ptr, so we reload it via a single operation
! 	     and subtract it to sp. 
! 
! 	     Yes, that's correct -- we have to reload the whole constant
! 	     into a temporary via ldah+lda then subtract from sp.  To
! 	     ensure we get ldah+lda, we use a special pattern.  */
  
  	  HOST_WIDE_INT lo, hi;
  	  lo = ((-frame_size & 0xffff) ^ 0x8000) - 0x8000;
  	  hi = -frame_size - lo;
  
! 	  emit_move_insn (ptr, GEN_INT (hi));
! 	  emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
! 	  seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
! 				       ptr));
  	}
        else
  	{
  	  seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
  				       GEN_INT (-leftover)));
  	}
+ 
+       /* This alternative is special, because the DWARF code cannot
+          possibly intuit through the loop above.  So we invent this
+          note it looks at instead.  */
+       RTX_FRAME_RELATED_P (seq) = 1;
+       REG_NOTES (seq)
+         = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ 			     gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ 			       gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ 					     GEN_INT (-frame_size))),
+ 			     REG_NOTES (seq));
      }
  
    /* Cope with very large offsets to the register save area.  */
Index: alpha.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.76
diff -c -p -d -r1.76 alpha.md
*** alpha.md	1999/04/17 23:31:34	1.76
--- alpha.md	1999/04/20 05:24:44
***************
*** 29,34 ****
--- 29,35 ----
  ;;	3	mskxh
  ;;	4	cvtlq
  ;;	5	cvtql
+ ;;	6	nt_lda
  ;;	
  ;; UNSPEC_VOLATILE:
  ;;
***************
*** 5160,5165 ****
--- 5161,5176 ----
        operands[2] = ra;
      }
  }")
+ 
+ ;; In creating a large stack frame, NT _must_ use ldah+lda to load
+ ;; the frame size into a register.  We use this pattern to ensure
+ ;; we get lda instead of addq.
+ (define_insn "nt_lda"
+   [(set (match_operand:DI 0 "register_operand" "r")
+ 	(unspec:DI [(match_dup 0)
+ 		    (match_operand:DI 1 "const_int_operand" "n")] 6))]
+   ""
+   "lda %0,%1(%0)")
  
  (define_expand "builtin_longjmp"
    [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]