i386.md (abs?f expander): Support SSE case.
authorJan Hubicka <jh@suse.cz>
Tue, 13 Mar 2001 13:40:09 +0000 (14:40 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 13 Mar 2001 13:40:09 +0000 (13:40 +0000)
* i386.md (abs?f expander): Support SSE case.
(abd?f_if): Add new "USE"; add splitters.

From-SVN: r40440

gcc/ChangeLog
gcc/config/i386/i386.md

index b18f273..ef79224 100644 (file)
@@ -1,3 +1,8 @@
+Tue Mar 13 14:38:44 CET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (abs?f expander): Support SSE case.
+       (abd?f_if): Add new "USE"; add splitters.
+
 2001-03-13  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * cpp.texi (poison): Explain the macro expansion exception.
index 19f91d2..5f6cef6 100644 (file)
                   (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
   "TARGET_80387"
-  "ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
+  "if (TARGET_SSE)
+     {
+       /* In case operand is in memory,  we will not use SSE.  */
+       if (memory_operand (operands[0], VOIDmode)
+          && rtx_equal_p (operands[0], operands[1]))
+        emit_insn (gen_abssf2_memory (operands[0], operands[1]));
+       else
+       {
+         /* Using SSE is tricky, since we need bitwise negation of -0
+            in register.  */
+         rtx reg = gen_reg_rtx (SFmode);
+         emit_move_insn (reg, gen_lowpart (SFmode, GEN_INT (0x80000000)));
+         emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
+       }
+       DONE;
+     }
+   ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
+
+(define_insn "abssf2_memory"
+  [(set (match_operand:SF 0 "memory_operand" "=m")
+       (abs:SF (match_operand:SF 1 "memory_operand" "0")))
+   (clobber (reg:CC 17))]
+  "ix86_unary_operator_ok (ABS, SFmode, operands)"
+  "#")
+
+(define_insn "abssf2_ifs"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,r#xf")
+       (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
+   (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*X#x,*X#x"))
+   (clobber (reg:CC 17))]
+  "TARGET_SSE"
+  "#")
+
+(define_split
+  [(set (match_operand:SF 0 "memory_operand" "")
+       (abs:SF (match_operand:SF 1 "memory_operand" "")))
+   (use (match_operand:SF 2 "" ""))
+   (clobber (reg:CC 17))]
+  ""
+  [(parallel [(set (match_dup 0)
+                  (abs:SF (match_dup 1)))
+             (clobber (reg:CC 17))])])
+
+(define_split
+  [(set (match_operand:SF 0 "register_operand" "")
+       (abs:SF (match_operand:SF 1 "register_operand" "")))
+   (use (match_operand:SF 2 "" ""))
+   (clobber (reg:CC 17))]
+  "reload_completed && !SSE_REG_P (operands[0])"
+  [(parallel [(set (match_dup 0)
+                  (abs:SF (match_dup 1)))
+             (clobber (reg:CC 17))])])
+
+(define_split
+  [(set (match_operand:SF 0 "register_operand" "")
+       (abs:SF (match_operand:SF 1 "register_operand" "")))
+   (use (match_operand:SF 2 "register_operand" ""))
+   (clobber (reg:CC 17))]
+  "reload_completed && SSE_REG_P (operands[0])"
+  [(set (subreg:TI (match_dup 0) 0)
+       (and:TI (not:TI (subreg:TI (match_dup 2) 0))
+               (subreg:TI (match_dup 1) 0)))])
 
 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
        (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
    (clobber (reg:CC 17))]
-  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
+  "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
   "#")
 
 (define_split
                   (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
              (clobber (reg:CC 17))])]
   "TARGET_80387"
-  "ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
+  "if (TARGET_SSE2)
+     {
+       /* In case operand is in memory,  we will not use SSE.  */
+       if (memory_operand (operands[0], VOIDmode)
+          && rtx_equal_p (operands[0], operands[1]))
+        emit_insn (gen_absdf2_memory (operands[0], operands[1]));
+       else
+       {
+         /* Using SSE is tricky, since we need bitwise negation of -0
+            in register.  */
+         rtx reg = gen_reg_rtx (DFmode);
+#if HOST_BITS_PER_WIDE_INT >= 64
+         rtx imm = gen_reg_rtx (GEN_INT (0x80000000));
+#else
+         rtx imm = immed_double_const (0, 0x80000000, DImode);
+#endif
+         emit_move_insn (reg, gen_lowpart (DFmode, imm));
+         emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
+       }
+       DONE;
+     }
+   ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
+
+(define_insn "absdf2_memory"
+  [(set (match_operand:DF 0 "memory_operand" "=m")
+       (abs:DF (match_operand:DF 1 "memory_operand" "0")))
+   (clobber (reg:CC 17))]
+  "ix86_unary_operator_ok (ABS, DFmode, operands)"
+  "#")
+
+(define_insn "absdf2_ifs"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,f#Yr,r#Yf")
+       (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
+   (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*X#Y,*X#Y"))
+   (clobber (reg:CC 17))]
+  "TARGET_SSE2"
+  "#")
+
+(define_split
+  [(set (match_operand:DF 0 "memory_operand" "")
+       (abs:DF (match_operand:DF 1 "memory_operand" "")))
+   (use (match_operand:DF 2 "" ""))
+   (clobber (reg:CC 17))]
+  ""
+  [(parallel [(set (match_dup 0)
+                  (abs:DF (match_dup 1)))
+             (clobber (reg:CC 17))])])
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (abs:DF (match_operand:DF 1 "register_operand" "")))
+   (use (match_operand:DF 2 "" ""))
+   (clobber (reg:CC 17))]
+  "reload_completed && !SSE_REG_P (operands[0])"
+  [(parallel [(set (match_dup 0)
+                  (abs:DF (match_dup 1)))
+             (clobber (reg:CC 17))])])
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (abs:DF (match_operand:DF 1 "register_operand" "")))
+   (use (match_operand:DF 2 "register_operand" ""))
+   (clobber (reg:CC 17))]
+  "reload_completed && SSE_REG_P (operands[0])"
+  [(set (subreg:TI (match_dup 0) 0)
+       (and:TI (not:TI (subreg:TI (match_dup 2) 0))
+               (subreg:TI (match_dup 1) 0)))])
+
 
 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS