[PATCH, i386]: Improve FP moves through integer registers

Uros Bizjak ubizjak@gmail.com
Fri Jul 17 08:09:00 GMT 2015


If the target only has integer registers, we don't have to go through
delicately tuned alternatives, balanced between x87 regs, SSE regs and
integer regs. Attached patch introduces simple and effective
alternatives in this case.

Testcases will be provided later by HJ.

2015-07-17  Uros Bizjak  <ubizjak@gmail.com>

    PR target/66824
    * config/i386/i386.h (TARGET_HARD_SF_REGS): New define.
    (TARGET_HARD_DF_REGS): Ditto.
    (TARGET_HARD_XF_REGS): Ditto.
    * config/i386/i386.md (*movxf_internal): Add alternatives 9 and 10.
    Enable alternatives 9 and 10 only for !TARGET_HARD_XF_REG target.
    (*movdf_internal): Add alternatives 22, 23, 24 and 25. Enable
    alternatives 22, 23, 24 and 25 only for !TARGET_HARD_DF_REG target.
    (*movsf_internal): Add alternatives 16 and 17. Enable
    alternatives 16 and 17 only for !TARGET_HARD_SF_REG target.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32} and
committed to mainline.

Uros.
-------------- next part --------------
Index: config/i386/i386.h
===================================================================
--- config/i386/i386.h	(revision 225857)
+++ config/i386/i386.h	(working copy)
@@ -524,6 +524,10 @@
 #define TARGET_MIX_SSE_I387 \
  ((ix86_fpmath & (FPMATH_SSE | FPMATH_387)) == (FPMATH_SSE | FPMATH_387))
 
+#define TARGET_HARD_SF_REGS	(TARGET_80387 || TARGET_MMX || TARGET_SSE)
+#define TARGET_HARD_DF_REGS	(TARGET_80387 || TARGET_SSE)
+#define TARGET_HARD_XF_REGS	(TARGET_80387)
+
 #define TARGET_GNU_TLS		(ix86_tls_dialect == TLS_DIALECT_GNU)
 #define TARGET_GNU2_TLS		(ix86_tls_dialect == TLS_DIALECT_GNU2)
 #define TARGET_ANY_GNU_TLS	(TARGET_GNU_TLS || TARGET_GNU2_TLS)
Index: config/i386/i386.md
===================================================================
--- config/i386/i386.md	(revision 225857)
+++ config/i386/i386.md	(working copy)
@@ -3087,9 +3087,9 @@
 ;; in alternatives 4, 6, 7 and 8.
 (define_insn "*movxf_internal"
   [(set (match_operand:XF 0 "nonimmediate_operand"
-	 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
+	 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o")
 	(match_operand:XF 1 "general_operand"
-	 "fm,f,G,roF,r , *roF,*r,F ,C"))]
+	 "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (!can_create_pseudo_p ()
        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -3098,7 +3098,8 @@
 	   && standard_80387_constant_p (operands[1]) > 0
 	   && !memory_operand (operands[0], XFmode))
        || (!TARGET_MEMORY_MISMATCH_STALL
-	   && memory_operand (operands[0], XFmode)))"
+	   && memory_operand (operands[0], XFmode))
+       || !TARGET_HARD_XF_REGS)"
 {
   switch (get_attr_type (insn))
     {
@@ -3122,12 +3123,12 @@
 	      ]
 	      (const_string "*")))
    (set (attr "type")
-	(cond [(eq_attr "alternative" "3,4,5,6,7,8")
+	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
 		 (const_string "multi")
 	      ]
 	      (const_string "fmov")))
    (set (attr "mode")
-	(cond [(eq_attr "alternative" "3,4,5,6,7,8")
+	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
 		 (if_then_else (match_test "TARGET_64BIT")
 		   (const_string "DI")
 		   (const_string "SI"))
@@ -3136,14 +3137,24 @@
    (set (attr "preferred_for_size")
      (cond [(eq_attr "alternative" "3,4")
               (symbol_ref "false")]
-           (symbol_ref "true")))])
+           (symbol_ref "true")))
+   (set (attr "enabled")
+     (cond [(eq_attr "alternative" "9,10")
+              (if_then_else
+		(match_test "TARGET_HARD_XF_REGS")
+		(symbol_ref "false")
+		(const_string "*"))
+            (not (match_test "TARGET_HARD_XF_REGS"))
+	      (symbol_ref "false")
+	   ]
+	   (const_string "*")))])
    
 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
 (define_insn "*movdf_internal"
   [(set (match_operand:DF 0 "nonimmediate_operand"
-    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
+    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
 	(match_operand:DF 1 "general_operand"
-    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
+    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (!can_create_pseudo_p ()
        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -3155,7 +3166,8 @@
 		   && standard_sse_constant_p (operands[1])))
 	   && !memory_operand (operands[0], DFmode))
        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
-	   && memory_operand (operands[0], DFmode)))"
+	   && memory_operand (operands[0], DFmode))
+       || !TARGET_HARD_DF_REGS)"
 {
   switch (get_attr_type (insn))
     {
@@ -3216,9 +3228,9 @@
     }
 }
   [(set (attr "isa")
-	(cond [(eq_attr "alternative" "3,4,5,6,7")
+	(cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
 		 (const_string "nox64")
-	       (eq_attr "alternative" "8,9,10,11,20,21")
+	       (eq_attr "alternative" "8,9,10,11,20,21,24,25")
 		 (const_string "x64")
 	       (eq_attr "alternative" "12,13,14,15")
 		 (const_string "sse2")
@@ -3227,9 +3239,9 @@
    (set (attr "type")
 	(cond [(eq_attr "alternative" "0,1,2")
 		 (const_string "fmov")
-	       (eq_attr "alternative" "3,4,5,6,7")
+	       (eq_attr "alternative" "3,4,5,6,7,22,23")
 		 (const_string "multi")
-	       (eq_attr "alternative" "8,9,10,11")
+	       (eq_attr "alternative" "8,9,10,11,24,25")
 		 (const_string "imov")
 	       (eq_attr "alternative" "12,16")
 		 (const_string "sselog1")
@@ -3254,9 +3266,9 @@
        (const_string "1")
        (const_string "*")))
    (set (attr "mode")
-	(cond [(eq_attr "alternative" "3,4,5,6,7,10")
+	(cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
 		 (const_string "SI")
-	       (eq_attr "alternative" "8,9,11,20,21")
+	       (eq_attr "alternative" "8,9,11,20,21,24,25")
 		 (const_string "DI")
 
 	       /* xorps is one byte shorter for non-AVX targets.  */
@@ -3320,13 +3332,23 @@
    (set (attr "preferred_for_speed")
      (cond [(eq_attr "alternative" "3,4")
               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
-           (symbol_ref "true")))])
+           (symbol_ref "true")))
+   (set (attr "enabled")
+     (cond [(eq_attr "alternative" "22,23,24,25")
+              (if_then_else
+		(match_test "TARGET_HARD_DF_REGS")
+		(symbol_ref "false")
+		(const_string "*"))
+            (not (match_test "TARGET_HARD_DF_REGS"))
+	      (symbol_ref "false")
+	   ]
+	   (const_string "*")))])
 
 (define_insn "*movsf_internal"
   [(set (match_operand:SF 0 "nonimmediate_operand"
-	  "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
+	  "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
 	(match_operand:SF 1 "general_operand"
-	  "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
+	  "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
    && (!can_create_pseudo_p ()
        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -3336,7 +3358,8 @@
 		&& standard_80387_constant_p (operands[1]) > 0)
 	       || (TARGET_SSE_MATH
 		   && standard_sse_constant_p (operands[1]))))
-       || memory_operand (operands[0], SFmode))"
+       || memory_operand (operands[0], SFmode)
+       || !TARGET_HARD_SF_REGS)"
 {
   switch (get_attr_type (insn))
     {
@@ -3390,7 +3413,7 @@
   [(set (attr "type")
 	(cond [(eq_attr "alternative" "0,1,2")
 		 (const_string "fmov")
-	       (eq_attr "alternative" "3,4")
+	       (eq_attr "alternative" "3,4,16,17")
 		 (const_string "imov")
 	       (eq_attr "alternative" "5")
 		 (const_string "sselog1")
@@ -3407,7 +3430,7 @@
        (const_string "1")
        (const_string "*")))
    (set (attr "mode")
-        (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
+        (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
 		 (const_string "SI")
 	       (eq_attr "alternative" "11")
 		 (const_string "DI")
@@ -3445,7 +3468,17 @@
 		       ]
 		       (const_string "SF"))
 	      ]
-	      (const_string "SF")))])
+	      (const_string "SF")))
+   (set (attr "enabled")
+     (cond [(eq_attr "alternative" "16,17")
+              (if_then_else
+		(match_test "TARGET_HARD_SF_REGS")
+		(symbol_ref "false")
+		(const_string "*"))
+            (not (match_test "TARGET_HARD_SF_REGS"))
+	      (symbol_ref "false")
+	   ]
+	   (const_string "*")))])
 
 (define_split
   [(set (match_operand 0 "any_fp_register_operand")


More information about the Gcc-patches mailing list