This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SH: improve reloads into FPUL


Currently, whenever reload has to load some memory data into FPUL, it
does that through an FP register, even though it could load the memory
value directly into FPUL.  Furthermore, we were not making use of FPUL
post-inc stores and pre-dec loads.  This patch introduces these
improvements.

And so that it qualifies for the slushy period...  :-) It also fixes a
bug.  In case fmovd is enabled (none of the standard multilibs), the
use of an FP register for FPUL reloading triggered a problem in reload
is loading a single-precision value into the FPUL operand of
extendsfdf2_i4, that runs in double mode.  If the FPSCR.SZ is set in
double mode, which is only possible if libgcc is compiled with
-DFMOVD_WORKS, reload might end up introducing a load into an FP
register, that must run in single-precision mode, before the
extendsfdf2_i4 insn, without any intervening mode changes, and we
don't make any attempts of mode switching later on.  I'm convinced
reload won't introduce inappropriate-mode instructions in any other
situation on the SH.

I'm checking this in.  Tested on i686-pc-linux-gnu-x-sh-elf.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* config/sh/sh.md (reload_outsf): Removed.
	(movsf_ie): Introduce constraints for FPUL loads and stores.
	(reload_insf): Broaden the output constraint.

Index: gcc/config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/sh/sh.md,v
retrieving revision 1.76
diff -u -p -r1.76 sh.md
--- gcc/config/sh/sh.md 2001/02/04 11:04:37 1.76
+++ gcc/config/sh/sh.md 2001/02/07 06:02:03
@@ -2940,41 +2940,6 @@
   DONE;
 }")
 
-;; The '&' for operand 2 is not really true, but push_secondary_reload
-;; insists on it.
-;; Operand 1 must accept FPUL_REGS in case fpul is reloaded to memory,
-;; to avoid a bogus tertiary reload.
-;; We need a tertiary reload when a floating point register is reloaded
-;; to memory, so the predicate for operand 0 must accept this, while the 
-;; constraint of operand 1 must reject the secondary reload register.
-;; Thus, the secondary reload register for this case has to be GENERAL_REGS,
-;; too.
-;; By having the predicate for operand 0 reject any register, we make
-;; sure that the ordinary moves that just need an intermediate register
-;; won't get a bogus tertiary reload.
-;; We use tertiary_reload_operand instead of memory_operand here because
-;; memory_operand rejects operands that are not directly addressible, e.g.:
-;; (mem:SF (plus:SI (reg:SI FP_REG)
-;;         (const_int 132)))
-
-(define_expand "reload_outsf"
-  [(parallel [(set (match_operand:SF 2 "register_operand" "=&r")
-		   (match_operand:SF 1 "register_operand" "y"))
-	      (clobber (scratch:SI))])
-   (parallel [(set (match_operand:SF 0 "tertiary_reload_operand" "=m")
-		   (match_dup 2))
-	      (clobber (scratch:SI))])]
-  ""
-  "
-{
-  if (TARGET_SH3E)
-    {
-      emit_insn (gen_movsf_ie (operands[2], operands[1], get_fpscr_rtx ()));
-      emit_insn (gen_movsf_ie (operands[0], operands[2], get_fpscr_rtx ()));
-      DONE;
-    }
-}")
-
 ;; If the output is a register and the input is memory or a register, we have
 ;; to be careful and see which word needs to be loaded first.  
 
@@ -3119,15 +3084,22 @@
 ;; when the destination changes mode.
 (define_insn "movsf_ie"
   [(set (match_operand:SF 0 "general_movdst_operand"
-	 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,y")
+	 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r<,y,y")
 	(match_operand:SF 1 "general_movsrc_operand"
-	  "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y"))
+	  "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r>,y"))
    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
    (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X"))]
 
   "TARGET_SH3E
    && (arith_reg_operand (operands[0], SFmode)
-       || arith_reg_operand (operands[1], SFmode))"
+       || arith_reg_operand (operands[1], SFmode)
+       || arith_reg_operand (operands[3], SImode)
+       || (fpul_operand (operands[0], SFmode)
+	   && memory_operand (operands[1], SFmode)
+	   && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
+       || (fpul_operand (operands[1], SFmode)
+	   && memory_operand (operands[0], SFmode)
+	   && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
   "@
 	fmov	%1,%0
 	mov	%1,%0
@@ -3188,7 +3160,7 @@
    (set_attr "type" "nil")])
 
 (define_expand "reload_insf"
-  [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
+  [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
 		   (match_operand:SF 1 "immediate_operand" "FQ"))
 	      (use (reg:PSI FPSCR_REG))
 	      (clobber (match_operand:SI 2 "register_operand" "=&z"))])]

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]