[3.4-BIB] Use FFREEp

Jan Hubicka jh@suse.cz
Fri Nov 22 11:51:00 GMT 2002


Hi,
this is remake of patch I sent in 1999.  It makes GCC to use ffreep instruction
to pop top of stack as it is slightly faster for Athlon.  <The instruction is
not documented by IA-32 description, but all CPUs in existence support it and
majorty of assemblers seems to know it too.  In case we will hit assembler that
don't I will add configure script code for that.

Regtested/bootstrapped BIB branch.  OK for bib branch?

Honza
Fri Nov 22 20:28:35 CET 2002  Jan Hubicka  <jh@suse.cz>
	* i386.c (x86_use_ffreep): New global variable.
	* i386.h (x86_use_frfeep): Declare
	(TARGET_USE_FFREEP): New macro
	* i386.md  (movs?f*): Use freep when asked for.
	(push?f): Always use splitter.
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.447.2.26
diff -c -3 -p -r1.447.2.26 i386.c
*** i386.c	20 Nov 2002 22:25:16 -0000	1.447.2.26
--- i386.c	22 Nov 2002 19:27:34 -0000
*************** const int x86_sse_partial_reg_dependency
*** 506,511 ****
--- 506,512 ----
  const int x86_sse_partial_regs = m_ATHLON_K8;
  const int x86_sse_typeless_stores = m_ATHLON_K8;
  const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
+ const int x86_use_ffreep = m_ATHLON_K8;
  
  /* In case the avreage insn count for single function invocation is
     lower than this constant, emit fast (but longer) prologue and
Index: i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.280.4.18
diff -c -3 -p -r1.280.4.18 i386.h
*** i386.h	20 Nov 2002 21:00:39 -0000	1.280.4.18
--- i386.h	22 Nov 2002 19:27:36 -0000
*************** extern const int x86_epilogue_using_move
*** 229,234 ****
--- 229,235 ----
  extern const int x86_arch_always_fancy_math_387, x86_shift1;
  extern const int x86_sse_partial_reg_dependency, x86_sse_partial_regs;
  extern const int x86_sse_typeless_stores, x86_sse_load0_by_pxor;
+ extern const int x86_use_ffreep;
  extern int x86_prefetch_sse;
  
  #define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
*************** extern int x86_prefetch_sse;
*** 277,282 ****
--- 278,284 ----
  #define TARGET_DECOMPOSE_LEA (x86_decompose_lea & CPUMASK)
  #define TARGET_PREFETCH_SSE (x86_prefetch_sse)
  #define TARGET_SHIFT1 (x86_shift1 & CPUMASK)
+ #define TARGET_USE_FFREEP (x86_use_ffreep & CPUMASK)
  
  #define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
  
Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.380.4.28
diff -c -3 -p -r1.380.4.28 i386.md
*** i386.md	20 Nov 2002 21:00:39 -0000	1.380.4.28
--- i386.md	22 Nov 2002 19:27:48 -0000
***************
*** 2149,2155 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2149,2160 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2269,2283 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (8);
-       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
-       else
- 	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
      case 1:
      case 2:
      case 3:
--- 2274,2279 ----
***************
*** 2298,2319 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (8);
-       if (TARGET_64BIT)
- 	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- 	else
- 	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-       else
- 	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- 	else
- 	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
- 
      case 1:
      case 2:
        return "#";
--- 2294,2299 ----
***************
*** 2368,2374 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2348,2359 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2376,2382 ****
  
      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp%z0\t%y0";
        else
          return "fst%z0\t%y0";
  
--- 2361,2372 ----
  
      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else
          return "fst%z0\t%y0";
  
***************
*** 2482,2488 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2472,2483 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2490,2496 ****
  
      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp%z0\t%y0";
        else
          return "fst%z0\t%y0";
  
--- 2485,2496 ----
  
      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else
          return "fst%z0\t%y0";
  
***************
*** 2638,2652 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (12);
-       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
-       else
- 	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
      case 1:
      case 2:
        return "#";
--- 2638,2643 ----
***************
*** 2666,2680 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (16);
-       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
-       else
- 	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
      case 1:
      case 2:
        return "#";
--- 2657,2662 ----
***************
*** 2694,2708 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (12);
-       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
-       else
- 	return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
      case 1:
        return "#";
  
--- 2676,2681 ----
***************
*** 2721,2741 ****
    switch (which_alternative)
      {
      case 0:
-       /* %%% We loose REG_DEAD notes for controling pops if we split late.  */
-       operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
-       operands[2] = stack_pointer_rtx;
-       operands[3] = GEN_INT (16);
-       if (TARGET_64BIT)
- 	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	  return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- 	else
- 	  return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-       else
- 	if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- 	  return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- 	else
- 	  return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- 
      case 1:
        return "#";
  
--- 2694,2699 ----
***************
*** 2794,2800 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2752,2763 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2841,2847 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2804,2815 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2888,2894 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2856,2867 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
***************
*** 2935,2941 ****
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
!         return "fstp\t%y0";
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else
--- 2908,2919 ----
      case 0:
        if (REG_P (operands[1])
            && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	{
! 	  if (REGNO (operands[0]) == FIRST_STACK_REG
! 	      && TARGET_USE_FFREEP)
! 	    return "ffreep\t%y0";
!           return "fstp\t%y0";
! 	}
        else if (STACK_TOP_P (operands[0]))
          return "fld%z1\t%y1";
        else



More information about the Gcc-patches mailing list