reg-stack fix (installing as obvious)

Jan Hubicka jh@suse.cz
Sat Sep 8 12:35:00 GMT 2001


Hi,
in the last reg-stack change I made two thinkos that elliminated each other in
my testcase, but unfortunately not in the all cases.

The problem is that I've attempted to simulate fcmov as instruction that first
pops all arguments and then pushes result.  This does not work when
top-of-stack argument is the first one, as the stack after it's "pop", the real
pop is emitted, but it contains wrong offset, as in fact no pop is done.

This patch contains sollution IMO easier to understand (and hopefully correct).
I first "simulate" fxch, but don't do it really and then reverse conditional
in fcmov to compensate the trick.

As the problem is common enought to break almost any FP code, I am installing
the patch as obvious once bootstrapping and regtesting with -match=athlon
complettes.

Honza

Sat Sep  8 22:42:14 CEST 2001  Jan Hubicka  <jh@suse.cz>

	* reg-stack.c (subst_stack_regs_pat): Fix fcmov reversal code.

*** reg-stack.c.old	Sat Sep  8 21:12:41 2001
--- reg-stack.c	Sat Sep  8 22:37:40 2001
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1797,1816 ****
  		    || (REGNO (*src2) == regstack->reg[regstack->top]
  			&& src2_note))
  		  {
  
! 		    /* We know that both sources "dies", as one dies and other
! 		       is overwriten by the destination.  Claim both sources
! 		       to be dead, as the code bellow will properly pop the
! 		       non-top-of-stack note and replace top-of-stack by the
! 		       result by popping source first and then pushing result. */
! 		    if (!src1_note)
! 		      src1_note = REG_NOTES (insn)
! 			= gen_rtx_EXPR_LIST (REG_DEAD, *src1, REG_NOTES (insn));
! 		    if (!src2_note)
! 		      src2_note = REG_NOTES (insn)
! 			= gen_rtx_EXPR_LIST (REG_DEAD, *src2, REG_NOTES (insn));
! 
! 		    /* i386 do have comparison always reversible.  */
  		    PUT_CODE (XEXP (pat_src, 0),
  			      reversed_comparison_code (XEXP (pat_src, 0), insn));
  		  }
--- 1797,1814 ----
  		    || (REGNO (*src2) == regstack->reg[regstack->top]
  			&& src2_note))
  		  {
+ 		    int idx1 = (get_hard_regnum (regstack, *src1)
+ 				- FIRST_STACK_REG);
+ 		    int idx2 = (get_hard_regnum (regstack, *src2)
+ 				- FIRST_STACK_REG);
+ 
+ 		    /* Make reg-stack believe that the operands are already
+ 		       swapped on the stack */
+ 		    regstack->reg[regstack->top - idx1] = REGNO (*src2);
+ 		    regstack->reg[regstack->top - idx2] = REGNO (*src1);
  
! 		    /* Reverse condition to compensate the operand swap.
! 		       i386 do have comparison always reversible.  */
  		    PUT_CODE (XEXP (pat_src, 0),
  			      reversed_comparison_code (XEXP (pat_src, 0), insn));
  		  }
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1845,1855 ****
  				       EMIT_AFTER);
  		      }
  		    else
! 		      {
! 			CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
! 			replace_reg (&XEXP (src_note[i], 0), FIRST_STACK_REG);
! 			regstack->top--;
! 		      }
  		  }
  	    }
  
--- 1843,1851 ----
  				       EMIT_AFTER);
  		      }
  		    else
! 		      /* Top of stack never dies, as it is the
! 			 destination.  */
! 		      abort ();
  		  }
  	    }
  



More information about the Gcc-patches mailing list