This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.4-BIB] Use FFREEp
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com
- Date: Fri, 22 Nov 2002 20:51:27 +0100
- Subject: [3.4-BIB] Use FFREEp
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