aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-02-28 19:07:05 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2001-02-28 18:07:05 +0000
commita46d1d38ae9c0e71f9d3effb106f9214ba8a6cec (patch)
tree672884f5264adb96e2688f82b14dac21e3ba6d03
parent91afe94118b050444d4b720f1de24a91b2acccbb (diff)
downloadgcc-a46d1d38ae9c0e71f9d3effb106f9214ba8a6cec.zip
gcc-a46d1d38ae9c0e71f9d3effb106f9214ba8a6cec.tar.gz
gcc-a46d1d38ae9c0e71f9d3effb106f9214ba8a6cec.tar.bz2
i386.md (sse_setccsf, [...]): New.
* i386.md (sse_setccsf, sse_setccdf): New. (sse_cmp* patterns): Use '%D' instead of outputtting condition flag directly. * i386.c (sse_comparison_operator): Accept the supported unordered comparses; be ready for fast_math. (print_operand): Support 'D'. From-SVN: r40131
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c69
-rw-r--r--gcc/config/i386/i386.md95
3 files changed, 107 insertions, 66 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7c91121..193ed5a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+Wed Feb 28 19:05:37 CET 2001 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse_setccsf, sse_setccdf): New.
+ (sse_cmp* patterns): Use '%D' instead of outputtting condition
+ flag directly.
+ * i386.c (sse_comparison_operator): Accept the supported unordered
+ comparses; be ready for fast_math.
+ (print_operand): Support 'D'.
+
Wed Feb 28 18:54:51 CET 2001 Jan Hubicka <jh@suse.cz>
* jump.c (reversed_comparison_code): Kill.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7dfc3c5..7ae13f9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1318,7 +1318,29 @@ sse_comparison_operator (op, mode)
enum machine_mode mode ATTRIBUTE_UNUSED;
{
enum rtx_code code = GET_CODE (op);
- return code == EQ || code == LT || code == LE || code == UNORDERED;
+ switch (code)
+ {
+ /* Operations supported directly. */
+ case EQ:
+ case LT:
+ case LE:
+ case UNORDERED:
+ case NE:
+ case UNGE:
+ case UNGT:
+ case ORDERED:
+ return 1;
+ /* These are equivalent to ones above in non-IEEE comparisons. */
+ case UNEQ:
+ case UNLT:
+ case UNLE:
+ case LTGT:
+ case GE:
+ case GT:
+ return !TARGET_IEEE_FP;
+ default:
+ return 0;
+ }
}
/* Return 1 if OP is a valid comparison operator in valid mode. */
int
@@ -3326,7 +3348,9 @@ print_reg (x, code, file)
k -- likewise, print the SImode name of the register.
h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
y -- print "st(0)" instead of "st" as a register.
- m -- print "st(n)" as an mmx register. */
+ m -- print "st(n)" as an mmx register.
+ D -- print condition for SSE cmp instruction.
+ */
void
print_operand (file, x, code)
@@ -3460,6 +3484,47 @@ print_operand (file, x, code)
}
return;
+ case 'D':
+ /* Little bit of braindamage here. The SSE compare instructions
+ does use completely different names for the comparisons that the
+ fp conditional moves. */
+ switch (GET_CODE (x))
+ {
+ case EQ:
+ case UNEQ:
+ fputs ("eq", file);
+ break;
+ case LT:
+ case UNLT:
+ fputs ("lt", file);
+ break;
+ case LE:
+ case UNLE:
+ fputs ("le", file);
+ break;
+ case UNORDERED:
+ fputs ("unord", file);
+ break;
+ case NE:
+ case LTGT:
+ fputs ("neq", file);
+ break;
+ case UNGE:
+ case GE:
+ fputs ("nlt", file);
+ break;
+ case UNGT:
+ case GT:
+ fputs ("nle", file);
+ break;
+ case ORDERED:
+ fputs ("ord", file);
+ break;
+ default:
+ abort ();
+ break;
+ }
+ return;
case 'C':
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
return;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 0e65701..38d035e 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9323,6 +9323,33 @@
[(set_attr "type" "setcc")
(set_attr "mode" "QI")])
+;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
+;; subsequent logical operations are used to imitate conditional moves.
+;; 0xffffffff is NaN, but not in normalized form, so we can't represent
+;; it directly. Futher holding this value in pseudo register might bring
+;; problem in implicit normalization in spill code.
+;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
+;; instructions after reload by splitting the conditional move patterns.
+
+(define_insn "*sse_setccsf"
+ [(set (match_operand:SF 0 "register_operand" "=x")
+ (match_operator:SF 1 "sse_comparison_operator"
+ [(match_operand:SF 2 "register_operand" "0")
+ (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
+ "TARGET_SSE && reload_completed"
+ "cmp%D1ss\\t{%3, %0|%0, %3}"
+ [(set_attr "type" "sse")
+ (set_attr "mode" "SF")])
+
+(define_insn "*sse_setccdf"
+ [(set (match_operand:DF 0 "register_operand" "=Y")
+ (match_operator:DF 1 "sse_comparison_operator"
+ [(match_operand:DF 2 "register_operand" "0")
+ (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
+ "TARGET_SSE2 && reload_completed"
+ "cmp%D1sd\\t{%3, %0|%0, %3}"
+ [(set_attr "type" "sse")
+ (set_attr "mode" "DF")])
;; Basic conditional jump instructions.
;; We ignore the overflow flag for signed branch instructions.
@@ -14111,22 +14138,7 @@
[(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
"TARGET_SSE"
- "*
-{
- switch (GET_CODE (operands[3]))
- {
- case EQ:
- return \"cmpeqps\\t{%2, %0|%0, %2}\";
- case LT:
- return \"cmpltps\\t{%2, %0|%0, %2}\";
- case LE:
- return \"cmpleps\\t{%2, %0|%0, %2}\";
- case UNORDERED:
- return \"cmpunordps\\t{%2, %0|%0, %2}\";
- default:
- abort ();
- }
-}"
+ "cmp%D3ps\\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "maskncmpv4sf3"
@@ -14136,22 +14148,7 @@
[(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
"TARGET_SSE"
- "*
-{
- switch (GET_CODE (operands[3]))
- {
- case EQ:
- return \"cmpneqps\\t{%2, %0|%0, %2}\";
- case LT:
- return \"cmpnltps\\t{%2, %0|%0, %2}\";
- case LE:
- return \"cmpnleps\\t{%2, %0|%0, %2}\";
- case UNORDERED:
- return \"cmpordps\\t{%2, %0|%0, %2}\";
- default:
- abort ();
- }
-}"
+ "cmpn%D3ps\\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "vmmaskcmpv4sf3"
@@ -14163,22 +14160,7 @@
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
- "*
-{
- switch (GET_CODE (operands[3]))
- {
- case EQ:
- return \"cmpeqss\\t{%2, %0|%0, %2}\";
- case LT:
- return \"cmpltss\\t{%2, %0|%0, %2}\";
- case LE:
- return \"cmpless\\t{%2, %0|%0, %2}\";
- case UNORDERED:
- return \"cmpunordss\\t{%2, %0|%0, %2}\";
- default:
- abort ();
- }
-}"
+ "cmp%D3ss\\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "vmmaskncmpv4sf3"
@@ -14191,22 +14173,7 @@
(subreg:V4SI (match_dup 1) 0)
(const_int 1)))]
"TARGET_SSE"
- "*
-{
- switch (GET_CODE (operands[3]))
- {
- case EQ:
- return \"cmpneqss\\t{%2, %0|%0, %2}\";
- case LT:
- return \"cmpnltss\\t{%2, %0|%0, %2}\";
- case LE:
- return \"cmpnless\\t{%2, %0|%0, %2}\";
- case UNORDERED:
- return \"cmpordss\\t{%2, %0|%0, %2}\";
- default:
- abort ();
- }
-}"
+ "cmp%D3ss\\t{%2, %0|%0, %2}"
[(set_attr "type" "sse")])
(define_insn "sse_comi"