More PA64 related fixes

Jeffrey A Law law@cygnus.com
Mon Aug 30 00:07:00 GMT 1999


Another wonderfully fun bug exposed by the PA64 ABI support.

Basically the PA64 ABI mandates an incoming argument pointer that can not
be expressed in terms of the stack/frame pointer and can not be a fixed
register (%r29).

In this case one of the first things we do for each function is copy the
incoming arg pointer into a new pseudo termed the "internal_arg_pointer".

This is fine and good and avoids a boatload of interesting issues, but it
also creates a couple fun issues (like the jump/cse problem I fixed yesterday).

Today's problem is function inlining.  When inlining and we see a reference
to the VIRTUAL_INCOMING_ARGS_REGUM we allocate a fake incoming argument block
for the callee.  This gives the callee the illusion that it has a normal
looking stack frame.  So if the callee needs to flush arguments back to their
homes it can do so.

Unfortunately, this does not happen when the argument pointer is being
kept in a pseudo :(  No space gets allocated, but code which references
the flushback stack slots still exists and loses in a big way.


The solution is to treat a reference to the internal_arg_pointer in a
manner similar to a reference to the VIRTUAL_INCOMING_ARGS_REGNUM.


	* integrate.c (copy_rtx_and_substitute): Handle internal_arg_pointer
	just like we would the virtual incoming args register when 
	integrating.
	
Index: integrate.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/integrate.c,v
retrieving revision 1.141
diff -c -3 -p -r1.141 integrate.c
*** integrate.c	1999/08/18 15:11:40	1.141
--- integrate.c	1999/08/30 06:53:53
*************** copy_rtx_and_substitute (orig, map)
*** 2329,2335 ****
  	 Small hard registers are returned as-is.  Pseudo-registers
  	 go through their `reg_map'.  */
        regno = REGNO (orig);
!       if (regno <= LAST_VIRTUAL_REGISTER)
  	{
  	  /* Some hard registers are also mapped,
  	     but others are not translated.  */
--- 2329,2337 ----
  	 Small hard registers are returned as-is.  Pseudo-registers
  	 go through their `reg_map'.  */
        regno = REGNO (orig);
!       if (regno <= LAST_VIRTUAL_REGISTER
! 	  || (map->integrating
! 	      && DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer == orig))
  	{
  	  /* Some hard registers are also mapped,
  	     but others are not translated.  */
*************** copy_rtx_and_substitute (orig, map)
*** 2380,2386 ****
  	      emit_insn_after (seq, map->insns_at_start);
  	      return temp;
  	    }
! 	  else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
  	    {
  	      /* Do the same for a block to contain any arguments referenced
  		 in memory.  */
--- 2382,2391 ----
  	      emit_insn_after (seq, map->insns_at_start);
  	      return temp;
  	    }
! 	  else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM
! 		   || (map->integrating
! 		       && (DECL_SAVED_INSNS (map->fndecl)->internal_arg_pointer
! 			   == orig)))
  	    {
  	      /* Do the same for a block to contain any arguments referenced
  		 in memory.  */





More information about the Gcc-patches mailing list