[PATCH] New function output_387_reg_move in i386.c

Roger Sayle roger@eyesopen.com
Sun Apr 11 02:31:00 GMT 2004


As promised, the following patch factors the duplicated logic for
implementing x87 FP register <-> register moves into it's own
subroutine.  What I hadn't suspected was that this idiom is currently
duplicated 12(!) times in i386.md, and only about half on those instances
contain the optimization to use the "ffreep" on processors that benefit
from it (such as the AMD athlon).  Not only does this patch reduce the
needless duplication, but all affected i386 patterns now perform this
optimization.


The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new failures.

Ok for mainline?



2004-04-10  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.c (output_387_reg_move): New function.
	* config/i386/i386-protos.h (output_387_reg_move): Prototype here.
	* config/i386/i386.md (*movsf_1, *movsf1_nointerunit,
	*movdf_nointeger, *movdf_integer, *movxf_nointeger, *movxf_integer,
	*extendsfdf2_1,  *extendsfxf2_1, *extenddfxf2_1, truncdfsf2_noop,
	truncxfsf2_noop, truncxfdf2_noop): Call output_387_reg_move.


Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.661
diff -c -3 -p -r1.661 i386.c
*** i386.c	2 Apr 2004 15:05:53 -0000	1.661
--- i386.c	10 Apr 2004 18:05:50 -0000
*************** ix86_reverse_condition (enum rtx_code co
*** 15909,15912 ****
--- 15909,15931 ----
  	  : reverse_condition_maybe_unordered (code));
  }

+ /* Output code to perform an x87 FP register move, from OPERANDS[1]
+    to OPERANDS[0].  */
+
+ const char *
+ output_387_reg_move (rtx insn, rtx *operands)
+ {
+   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";
+     }
+   if (STACK_TOP_P (operands[0]))
+     return "fld%z1\t%y1";
+   return "fst\t%y0";
+ }
+
  #include "gt-i386.h"
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.108
diff -c -3 -p -r1.108 i386-protos.h
*** i386-protos.h	16 Mar 2004 23:29:21 -0000	1.108
--- i386-protos.h	10 Apr 2004 18:05:50 -0000
*************** extern void split_ti (rtx[], int, rtx[],
*** 117,122 ****
--- 117,123 ----

  extern const char *output_set_got (rtx);
  extern const char *output_387_binary_op (rtx, rtx*);
+ extern const char *output_387_reg_move (rtx, rtx*);
  extern const char *output_fix_trunc (rtx, rtx*);
  extern const char *output_fp_compare (rtx, rtx*, int, int);

Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.525
diff -c -3 -p -r1.525 i386.md
*** i386.md	9 Apr 2004 01:36:47 -0000	1.525
--- i386.md	10 Apr 2004 18:05:57 -0000
***************
*** 2197,2209 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
--- 2197,2203 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
***************
*** 2291,2308 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
--- 2285,2291 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
***************
*** 2466,2483 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
--- 2449,2455 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
***************
*** 2578,2595 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
--- 2550,2556 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
***************
*** 2781,2798 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
--- 2742,2748 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
***************
*** 2825,2842 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
--- 2775,2781 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
***************
*** 3520,3539 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
          return "fstp%z0\t%y0";
-
        else
          return "fst%z0\t%y0";
      case 2:
        return "cvtss2sd\t{%1, %0|%0, %1}";

--- 3459,3472 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
          return "fstp%z0\t%y0";
        else
          return "fst%z0\t%y0";
+
      case 2:
        return "cvtss2sd\t{%1, %0|%0, %1}";

***************
*** 3575,3587 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
--- 3508,3514 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
***************
*** 3620,3632 ****
    switch (which_alternative)
      {
      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
!         return "fst\t%y0";

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
--- 3547,3553 ----
    switch (which_alternative)
      {
      case 0:
!       return output_387_reg_move (insn, operands);

      case 1:
        /* There is no non-popping store to memory for XFmode.  So if
***************
*** 3678,3690 ****
  	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   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
!     return "fst\t%y0";
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "SF")])
--- 3599,3605 ----
  	(float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   return output_387_reg_move (insn, operands);
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "SF")])
***************
*** 3931,3943 ****
  	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   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
!     return "fst\t%y0";
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "SF")])
--- 3846,3852 ----
  	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   return output_387_reg_move (insn, operands);
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "SF")])
***************
*** 4020,4032 ****
  	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   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
!     return "fst\t%y0";
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "DF")])
--- 3929,3935 ----
  	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
    "TARGET_80387 && flag_unsafe_math_optimizations"
  {
!   return output_387_reg_move (insn, operands);
  }
    [(set_attr "type" "fmov")
     (set_attr "mode" "DF")])


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list