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]

fix alpha explicit relocs alignment error


Found with an EV4 bootstrap, instead of my normal EV6 build.

With TARGET_EXPLICIT_RELOCS, we separate the call and the gp
reload into separate instructions.  However, these instructions
must remain contiguous, or the gp will be reloaded with the
wrong address.  This worked everywhere but in the alpha_reorg
where we manage code alignment.

Before and after looks like

        ldq $27,fprintf($29)            !literal
        mov $10,$16
-       jsr $26,($27),fprintf
        bis $31,$31,$31
+       jsr $26,($27),fprintf
        ldah $29,0($26)         !gpdisp!20
        cpys $f31,$f31,$f19
        lda $29,0($29)          !gpdisp!20


r~


        * config/alpha/alpha.c (alpha_align_insns): Suppress realignment
        immediately after a call; insert nops before a call.

Index: alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.211
diff -c -p -d -r1.211 alpha.c
*** alpha.c	2001/12/09 21:47:49	1.211
--- alpha.c	2001/12/09 21:52:18
*************** alpha_align_insns (insns, max_align, nex
*** 7622,7636 ****
        else if ((int) align < len)
  	{
  	  unsigned int new_log_align = len > 8 ? 4 : 3;
! 	  rtx where;
  
! 	  where = prev_nonnote_insn (i);
  	  if (!where || GET_CODE (where) != CODE_LABEL)
  	    where = i;
  
! 	  emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
! 	  align = 1 << new_log_align;
! 	  ofs = 0;
  	}
  
        /* If the group won't fit in the same INT16 as the previous,
--- 7622,7641 ----
        else if ((int) align < len)
  	{
  	  unsigned int new_log_align = len > 8 ? 4 : 3;
! 	  rtx prev, where;
  
! 	  where = prev = prev_nonnote_insn (i);
  	  if (!where || GET_CODE (where) != CODE_LABEL)
  	    where = i;
  
! 	  /* Can't realign between a call and its gp reload.  */
! 	  if (! (TARGET_EXPLICIT_RELOCS
! 		 && prev && GET_CODE (prev) == CALL_INSN))
! 	    {
! 	      emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
! 	      align = 1 << new_log_align;
! 	      ofs = 0;
! 	    }
  	}
  
        /* If the group won't fit in the same INT16 as the previous,
*************** alpha_align_insns (insns, max_align, nex
*** 7644,7651 ****
  	  int nop_count = (align - ofs) / 4;
  	  rtx where;
  
! 	  /* Insert nops before labels and branches to truely merge the
! 	     execution of the nops with the previous instruction group.  */
  	  where = prev_nonnote_insn (i);
  	  if (where)
  	    {
--- 7649,7656 ----
  	  int nop_count = (align - ofs) / 4;
  	  rtx where;
  
! 	  /* Insert nops before labels, branches, and calls to truely merge
! 	     the execution of the nops with the previous instruction group.  */
  	  where = prev_nonnote_insn (i);
  	  if (where)
  	    {
*************** alpha_align_insns (insns, max_align, nex
*** 7655,7661 ****
  		  if (where2 && GET_CODE (where2) == JUMP_INSN)
  		    where = where2;
  		}
! 	      else if (GET_CODE (where) != JUMP_INSN)
  		where = i;
  	    }
  	  else
--- 7660,7666 ----
  		  if (where2 && GET_CODE (where2) == JUMP_INSN)
  		    where = where2;
  		}
! 	      else if (GET_CODE (where) == INSN)
  		where = i;
  	    }
  	  else


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