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
This commit is contained in:
Jan Hubicka 2001-02-28 19:07:05 +01:00 committed by Jan Hubicka
parent 91afe94118
commit a46d1d38ae
3 changed files with 107 additions and 66 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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"