Subject: Re: GCC produces MUL R5,R5,R5 instruction !
To: Todd Vierling <tv@pobox.com>
From: Richard Earnshaw <rearnsha@arm.com>
List: port-arm32
Date: 10/05/1998 18:08:15
This is a multipart MIME message.

--==_Exmh_548700160
Content-Type: text/plain; charset=us-ascii

> On Mon, 5 Oct 1998, Richard Earnshaw wrote:
> 
> : Todd, are you accepting patches to the MI part of the old compiler?
> 
> `I' am not necessarily the person to ask, but then, no one realy has direct
> responsibility over the old gcc 2.7 tree.  I'm as good as any, I suppose.

Should things like this be cc'ed to tech-toolchain?

> I'll review it and see if it affects any other ports, then ask other
> developers about adding it to the gcc 2.7 part of the tree.  Yes, if the fix
> is complete, we'll certainly take it.

The patch has been extracted directly from the FSF gcc development tree 
(part of the 2.8 development work, so it is already in egcs).  I've 
verified that it applies cleanly to the netbsd tree (but I haven't rebuilt 
the compiler yet -- not that I expect any problems); I've then regenerated 
the diff so that there should be no patch offset problems when applied to 
the -current version of 2.7.  Enclosed are the original ChangeLog entries.


Wed Apr 23 09:41:35 1997  Andreas Schwab  <schwab@issan.informatik.uni-dort
mund.de>

        * reload.c (push_reload): Fix last arg of call to 
find_dummy_reload.

Tue Mar 25 14:28:15 1997  Richard Earnshaw (rearnsha@armltd.co.uk)

        * reload.c (find_dummy_reload): New parameter earlyclobber.  If set
        then don't use IN for the reload if it also appears elsewhere in
        the insn.  All callers changed.



--==_Exmh_548700160
Content-Type: application/x-patch ; name="mul.patch"
Content-Description: mul.patch
Content-Disposition: attachment; filename="mul.patch"

Index: reload.c
===================================================================
RCS file: /xx/rearnsha.old/netbsd/usr/cvs/src/gnu/usr.bin/gcc/common/reload.c,v
retrieving revision 1.1.1.1
diff -p -r1.1.1.1 reload.c
*** reload.c	1998/07/25 00:06:52	1.1.1.1
--- reload.c	1998/10/05 16:55:31
*************** static void push_replacement	PROTO((rtx 
*** 298,304 ****
  static void combine_reloads	PROTO((void));
  static rtx find_dummy_reload	PROTO((rtx, rtx, rtx *, rtx *,
  				       enum machine_mode, enum machine_mode,
! 				       enum reg_class, int));
  static int earlyclobber_operand_p PROTO((rtx));
  static int hard_reg_set_here_p	PROTO((int, int, rtx));
  static struct decomposition decompose PROTO((rtx));
--- 298,304 ----
  static void combine_reloads	PROTO((void));
  static rtx find_dummy_reload	PROTO((rtx, rtx, rtx *, rtx *,
  				       enum machine_mode, enum machine_mode,
! 				       enum reg_class, int, int));
  static int earlyclobber_operand_p PROTO((rtx));
  static int hard_reg_set_here_p	PROTO((int, int, rtx));
  static struct decomposition decompose PROTO((rtx));
*************** push_reload (in, out, inloc, outloc, cla
*** 1312,1318 ****
      {
        reload_reg_rtx[i] = find_dummy_reload (in, out, inloc, outloc,
  					     inmode, outmode,
! 					     reload_reg_class[i], i);
  
        /* If the outgoing register already contains the same value
  	 as the incoming one, we can dispense with loading it.
--- 1312,1319 ----
      {
        reload_reg_rtx[i] = find_dummy_reload (in, out, inloc, outloc,
  					     inmode, outmode,
! 					     reload_reg_class[i], i,
! 					     earlyclobber_operand_p (out));
  
        /* If the outgoing register already contains the same value
  	 as the incoming one, we can dispense with loading it.
*************** combine_reloads ()
*** 1618,1633 ****
     to be computed, clear out reload_out[FOR_REAL].
  
     If FOR_REAL is -1, this should not be done, because this call
!    is just to see if a register can be found, not to find and install it.  */
  
  static rtx
  find_dummy_reload (real_in, real_out, inloc, outloc,
! 		   inmode, outmode, class, for_real)
       rtx real_in, real_out;
       rtx *inloc, *outloc;
       enum machine_mode inmode, outmode;
       enum reg_class class;
       int for_real;
  {
    rtx in = real_in;
    rtx out = real_out;
--- 1619,1640 ----
     to be computed, clear out reload_out[FOR_REAL].
  
     If FOR_REAL is -1, this should not be done, because this call
!    is just to see if a register can be found, not to find and install it.
! 
!    EARLYCLOBBER is non-zero if OUT is an earlyclobber operand.  This
!    puts an additional constraint on being able to use IN for OUT since
!    IN must not appear elsewhere in the insn (it is assumed that IN itself
!    is safe from the earlyclobber).  */
  
  static rtx
  find_dummy_reload (real_in, real_out, inloc, outloc,
! 		   inmode, outmode, class, for_real, earlyclobber)
       rtx real_in, real_out;
       rtx *inloc, *outloc;
       enum machine_mode inmode, outmode;
       enum reg_class class;
       int for_real;
+      int earlyclobber;
  {
    rtx in = real_in;
    rtx out = real_out;
*************** find_dummy_reload (real_in, real_out, in
*** 1709,1715 ****
       or if OUT dies in this insn (like the quotient in a divmod insn).
       We can't use IN unless it is dies in this insn,
       which means we must know accurately which hard regs are live.
!      Also, the result can't go in IN if IN is used within OUT.  */
    if (hard_regs_live_known
        && GET_CODE (in) == REG
        && REGNO (in) < FIRST_PSEUDO_REGISTER
--- 1716,1723 ----
       or if OUT dies in this insn (like the quotient in a divmod insn).
       We can't use IN unless it is dies in this insn,
       which means we must know accurately which hard regs are live.
!      Also, the result can't go in IN if IN is used within OUT,
!      or if OUT is an earlyclobber and IN appears elsewhere in the insn.  */
    if (hard_regs_live_known
        && GET_CODE (in) == REG
        && REGNO (in) < FIRST_PSEUDO_REGISTER
*************** find_dummy_reload (real_in, real_out, in
*** 1730,1736 ****
  
        if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
  	  && ! hard_reg_set_here_p (regno, regno + nwords,
! 				    PATTERN (this_insn)))
  	{
  	  int i;
  	  for (i = 0; i < nwords; i++)
--- 1738,1747 ----
  
        if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
  	  && ! hard_reg_set_here_p (regno, regno + nwords,
! 				    PATTERN (this_insn))
! 	  && (! earlyclobber
! 	      || ! refers_to_regno_for_reload_p (regno, regno + nwords,
! 						 PATTERN (this_insn), inloc)))
  	{
  	  int i;
  	  for (i = 0; i < nwords; i++)
*************** find_reloads (insn, replace, ind_levels,
*** 2781,2787 ****
  		      = find_dummy_reload (recog_operand[i], recog_operand[c],
  					   recog_operand_loc[i], recog_operand_loc[c],
  					   operand_mode[i], operand_mode[c],
! 					   this_alternative[c], -1);
  
  		    if (value != 0)
  		      losers--;
--- 2792,2799 ----
  		      = find_dummy_reload (recog_operand[i], recog_operand[c],
  					   recog_operand_loc[i], recog_operand_loc[c],
  					   operand_mode[i], operand_mode[c],
! 					   this_alternative[c], -1,
! 					   this_alternative_earlyclobber[c]);
  
  		    if (value != 0)
  		      losers--;

--==_Exmh_548700160--