aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-03-13 14:40:09 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-03-13 13:40:09 +0000
commitca29d1dcff95b0fe9fafe84983727437714720f4 (patch)
tree0d09949e0e8bcfcb7a1846de5fbc0e91f645cd50 /gcc
parentbf4ab281678450284b14a53089c1f364132cb203 (diff)
downloadgcc-ca29d1dcff95b0fe9fafe84983727437714720f4.zip
gcc-ca29d1dcff95b0fe9fafe84983727437714720f4.tar.gz
gcc-ca29d1dcff95b0fe9fafe84983727437714720f4.tar.bz2
i386.md (abs?f expander): Support SSE case.
* i386.md (abs?f expander): Support SSE case. (abd?f_if): Add new "USE"; add splitters. From-SVN: r40440
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md134
2 files changed, 136 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b18f2733..ef79224 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 19f91d2..5f6cef6 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -7572,7 +7572,68 @@
(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
@@ -7581,7 +7642,7 @@
[(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
@@ -7627,7 +7688,74 @@
(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