From a46d1d38ae9c0e71f9d3effb106f9214ba8a6cec Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 28 Feb 2001 19:07:05 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 ++++ gcc/config/i386/i386.c | 69 +++++++++++++++++++++++++++++- gcc/config/i386/i386.md | 95 ++++++++++++++--------------------------- 3 files changed, 107 insertions(+), 66 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7c911214e81..193ed5a9252 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +Wed Feb 28 19:05:37 CET 2001 Jan Hubicka + + * 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 * jump.c (reversed_comparison_code): Kill. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 7dfc3c543c3..7ae13f9cd14 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 0e65701ee54..38d035efea3 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"