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]
Other format: [Raw text]

patch applied to SH port


2003-08-07  J"orn Rennecke <joern.rennecke@superh.com>

	* sh.c (calc_live_regs): If the return address pointer is live,
	force pr live.
	(sh5_schedule_saves): Exclude PR_MEDIA_REG from being a temp register
	for saves / restores.
	(sh_expand_epilogue): If sh_media_register_for_return returns a
	register number, flag the instructions that restores PR_MEDIA_REG
	as possibly dead.
	Remove dead update of offset.
	(sh_get_pr_initial_val): Use UNSPEC_RA if we don't know yet if
	we can use the result of get_hard_reg_initial_val.
	* sh.md (UNSPEC_RA): New constant.
	(movsi_i_lowpart+1): Changed into a define_insn_and_split, named:
	(load_ra).  Handle UNSPEC_RA.
	(sibcall_media): Use PR_MEDIA_REG.

diff -p /swbuild/build/srcw/gcc/config/sh/sh.c config/sh/sh.c
*** /swbuild/build/srcw/gcc/config/sh/sh.c	Thu Aug  7 21:48:59 2003
--- config/sh/sh.c	Thu Aug  7 23:31:36 2003
*************** calc_live_regs (live_regs_mask)
*** 4848,4853 ****
--- 4848,4855 ----
       the initial value can become the PR_MEDIA_REG hard register, as seen for
       execute/20010122-1.c:test9.  */
    if (TARGET_SHMEDIA)
+     /* ??? this function is called from initial_elimination_offset, hence we
+        can't use the result of sh_media_register_for_return here.  */
      pr_live = sh_pr_n_sets ();
    else
      {
*************** calc_live_regs (live_regs_mask)
*** 4856,4861 ****
--- 4858,4867 ----
  		 ? (GET_CODE (pr_initial) != REG
  		    || REGNO (pr_initial) != (PR_REG))
  		 : regs_ever_live[PR_REG]);
+       /* For Shcompact, if not optimizing, we end up with a memory reference
+ 	 using the return address pointer for __builtin_return_address even
+ 	 though there is no actual need to put the PR register on the stack.  */
+       pr_live |= regs_ever_live[RETURN_ADDRESS_POINTER_REGNUM];
      }
    /* Force PR to be live if the prologue has to call the SHmedia
       argument decoder or register saver.  */
*************** sh5_schedule_saves (HARD_REG_SET *live_r
*** 5027,5033 ****
  
    if (! current_function_interrupt)
      for (i = FIRST_GENERAL_REG; tmpx < MAX_TEMPS && i <= LAST_GENERAL_REG; i++)
!       if (call_used_regs[i] && ! fixed_regs[i]
  	  && ! FUNCTION_ARG_REGNO_P (i)
  	  && i != FIRST_RET_REG
  	  && ! (current_function_needs_context && i == STATIC_CHAIN_REGNUM)
--- 5033,5039 ----
  
    if (! current_function_interrupt)
      for (i = FIRST_GENERAL_REG; tmpx < MAX_TEMPS && i <= LAST_GENERAL_REG; i++)
!       if (call_used_regs[i] && ! fixed_regs[i] && i != PR_MEDIA_REG
  	  && ! FUNCTION_ARG_REGNO_P (i)
  	  && i != FIRST_RET_REG
  	  && ! (current_function_needs_context && i == STATIC_CHAIN_REGNUM)
*************** sh_expand_prologue ()
*** 5169,5174 ****
--- 5175,5183 ----
  	  rtx insn = emit_move_insn (gen_rtx_REG (DImode, tr),
  				     gen_rtx_REG (DImode, PR_MEDIA_REG));
  
+ 	  /* ??? We should suppress saving pr when we don't need it, but this
+ 	     is tricky because of builtin_return_address.  */
+ 
  	  /* If this function only exits with sibcalls, this copy
  	     will be flagged as dead.  */
  	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
*************** sh_expand_epilogue ()
*** 5552,5558 ****
        save_schedule schedule;
        save_entry *entry;
        int *tmp_pnt;
!       
        entry = sh5_schedule_saves (&live_regs_mask, &schedule, d_rounding);
        offset_base = -entry[1].offset + d_rounding;
        tmp_pnt = schedule.temps;
--- 5561,5567 ----
        save_schedule schedule;
        save_entry *entry;
        int *tmp_pnt;
! 
        entry = sh5_schedule_saves (&live_regs_mask, &schedule, d_rounding);
        offset_base = -entry[1].offset + d_rounding;
        tmp_pnt = schedule.temps;
*************** sh_expand_epilogue ()
*** 5660,5667 ****
  	    }
  
  	  insn = emit_move_insn (reg_rtx, mem_rtx);
! 
! 	  offset += GET_MODE_SIZE (mode);
  	}
  
        if (entry->offset + offset_base != d + d_rounding)
--- 5669,5679 ----
  	    }
  
  	  insn = emit_move_insn (reg_rtx, mem_rtx);
! 	  if (reg == PR_MEDIA_REG && sh_media_register_for_return () >= 0)
! 	    /* This is dead, unless we return with a sibcall.  */
! 	    REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
! 						  const0_rtx,
! 						  REG_NOTES (insn));
  	}
  
        if (entry->offset + offset_base != d + d_rounding)
*************** scavenge_reg (HARD_REG_SET *s)
*** 8835,8851 ****
  rtx
  sh_get_pr_initial_val (void)
  {
    /* ??? Unfortunately, get_hard_reg_initial_val doesn't always work for the
       PR register on SHcompact, because it might be clobbered by the prologue.
!      We don't know if that's the case before rtl generation is finished.  */
    if (TARGET_SHCOMPACT
!       && (rtx_equal_function_value_matters
! 	  || (current_function_args_info.call_cookie
! 	       & ~ CALL_COOKIE_RET_TRAMP (1))
  	  || current_function_has_nonlocal_label))
      return gen_rtx_MEM (SImode, return_address_pointer_rtx);
!   return
!     get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
  }
  
  #include "gt-sh.h"
--- 8847,8875 ----
  rtx
  sh_get_pr_initial_val (void)
  {
+   rtx val;
+ 
    /* ??? Unfortunately, get_hard_reg_initial_val doesn't always work for the
       PR register on SHcompact, because it might be clobbered by the prologue.
!      We check first if that is known to be the case.  */
    if (TARGET_SHCOMPACT
!       && ((current_function_args_info.call_cookie
! 	   & ~ CALL_COOKIE_RET_TRAMP (1))
  	  || current_function_has_nonlocal_label))
      return gen_rtx_MEM (SImode, return_address_pointer_rtx);
! 
!   /* If we haven't finished rtl generation, there might be a nonlocal label
!      that we haven't seen yet.
!      ??? get_hard_reg_initial_val fails if it is called while no_new_pseudos
!      is set, unless it has been called before for the same register.  And even
!      then, we end in trouble if we didn't use the register in the same
!      basic block before.  So call get_hard_reg_initial_val now and wrap it
!      in an unspec if we might need to replace it.  */
!   val
!     = get_hard_reg_initial_val (Pmode, TARGET_SHMEDIA ? PR_MEDIA_REG : PR_REG);
!   if (TARGET_SHCOMPACT && rtx_equal_function_value_matters)
!     return gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_RA);
!   return val;
  }
  
  #include "gt-sh.h"
diff -p /swbuild/build/srcw/gcc/config/sh/sh.md config/sh/sh.md
*** /swbuild/build/srcw/gcc/config/sh/sh.md	Wed Aug  6 20:16:07 2003
--- config/sh/sh.md	Thu Aug  7 22:55:07 2003
***************
*** 142,147 ****
--- 142,148 ----
    (UNSPEC_DTPOFF	23)
    (UNSPEC_GOTTPOFF	24)
    (UNSPEC_TPOFF		25)
+   (UNSPEC_RA		26)
  
    ;; These are used with unspec_volatile.
    (UNSPECV_BLOCKAGE	0)
***************
*** 3471,3486 ****
  	fake	%1,%0"
    [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
  
! (define_split
    [(set (match_operand:SI 0 "general_movdst_operand" "")
! 	(mem:SI (reg:SI RAP_REG)))]
!   "TARGET_SHCOMPACT
!    && ! rtx_equal_function_value_matters
!    && ! ((current_function_args_info.call_cookie
! 	  & ~ CALL_COOKIE_RET_TRAMP (1))
! 	 || current_function_has_nonlocal_label)"
    [(set (match_dup 0) (match_dup 1))]
!   "operands[1] = sh_get_pr_initial_val ();")
  
  (define_insn "*movsi_media"
    [(set (match_operand:SI 0 "general_movdst_operand"
--- 3472,3489 ----
  	fake	%1,%0"
    [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
  
! (define_insn_and_split "load_ra"
    [(set (match_operand:SI 0 "general_movdst_operand" "")
! 	(unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
!   "TARGET_SHCOMPACT"
!   "#"
!   "&& ! rtx_equal_function_value_matters"
    [(set (match_dup 0) (match_dup 1))]
!   "
! {
!   if (current_function_has_nonlocal_label)
!     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
! }")
  
  (define_insn "*movsi_media"
    [(set (match_operand:SI 0 "general_movdst_operand"
***************
*** 6174,6179 ****
--- 6177,6183 ----
  (define_insn "sibcall_media"
    [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
  	 (match_operand 1 "" ""))
+    (use (reg:SI PR_MEDIA_REG))
     (return)]
    "TARGET_SHMEDIA"
    "blink	%0, r63"


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