i386.c (ix86_expand_compare): Add bypass_test and second_test parameters.
* i386.c (ix86_expand_compare): Add bypass_test and second_test parameters. (ix86_expand_branch): Update. (ix86_expand_setcc): Update to handle multiple test conditions. (expand_int_movcc): Likewise. (expand_fp_movcc): Likewise. * i386-protos.h (ix86_expand_compare): New. * i386.md (andqi_?_slp, orqi_?_slp): New. (conditional trap expander): Update call to ix86_expand_compare. From-SVN: r39005
This commit is contained in:
parent
264ddbaa68
commit
a1b8572cac
@ -1,3 +1,15 @@
|
||||
Sun Jan 14 10:09:48 MET 2001 Jan hubicka <jh@suse.cz>
|
||||
|
||||
* i386.c (ix86_expand_compare): Add bypass_test and second_test
|
||||
parameters.
|
||||
(ix86_expand_branch): Update.
|
||||
(ix86_expand_setcc): Update to handle multiple test conditions.
|
||||
(expand_int_movcc): Likewise.
|
||||
(expand_fp_movcc): Likewise.
|
||||
* i386-protos.h (ix86_expand_compare): New.
|
||||
* i386.md (andqi_?_slp, orqi_?_slp): New.
|
||||
(conditional trap expander): Update call to ix86_expand_compare.
|
||||
|
||||
2001-01-14 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* config/vax/vax.md: Use nonimmediate_operand instead of
|
||||
|
@ -101,7 +101,7 @@ extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode
|
||||
extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
|
||||
rtx[]));
|
||||
extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
|
||||
extern rtx ix86_expand_compare PARAMS ((enum rtx_code));
|
||||
extern rtx ix86_expand_compare PARAMS ((enum rtx_code, rtx *, rtx *));
|
||||
extern int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
|
||||
extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx));
|
||||
extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
|
||||
|
@ -5161,16 +5161,22 @@ ix86_expand_fp_compare (code, op0, op1, scratch, second_test, bypass_test)
|
||||
}
|
||||
|
||||
rtx
|
||||
ix86_expand_compare (code)
|
||||
ix86_expand_compare (code, second_test, bypass_test)
|
||||
enum rtx_code code;
|
||||
rtx *second_test, *bypass_test;
|
||||
{
|
||||
rtx op0, op1, ret;
|
||||
op0 = ix86_compare_op0;
|
||||
op1 = ix86_compare_op1;
|
||||
|
||||
if (second_test)
|
||||
*second_test = NULL_RTX;
|
||||
if (bypass_test)
|
||||
*bypass_test = NULL_RTX;
|
||||
|
||||
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
|
||||
ret = ix86_expand_fp_compare (code, op0, op1, gen_reg_rtx (HImode),
|
||||
NULL, NULL);
|
||||
second_test, bypass_test);
|
||||
else
|
||||
ret = ix86_expand_int_compare (code, op0, op1);
|
||||
|
||||
@ -5189,7 +5195,7 @@ ix86_expand_branch (code, label)
|
||||
case QImode:
|
||||
case HImode:
|
||||
case SImode:
|
||||
tmp = ix86_expand_compare (code);
|
||||
tmp = ix86_expand_compare (code, NULL, NULL);
|
||||
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
|
||||
gen_rtx_LABEL_REF (VOIDmode, label),
|
||||
pc_rtx);
|
||||
@ -5404,7 +5410,8 @@ ix86_expand_setcc (code, dest)
|
||||
enum rtx_code code;
|
||||
rtx dest;
|
||||
{
|
||||
rtx ret, tmp;
|
||||
rtx ret, tmp, tmpreg;
|
||||
rtx second_test, bypass_test;
|
||||
int type;
|
||||
|
||||
if (GET_MODE (ix86_compare_op0) == DImode)
|
||||
@ -5430,13 +5437,15 @@ ix86_expand_setcc (code, dest)
|
||||
if (type == 0)
|
||||
emit_move_insn (dest, const0_rtx);
|
||||
|
||||
ret = ix86_expand_compare (code);
|
||||
ret = ix86_expand_compare (code, &second_test, &bypass_test);
|
||||
PUT_MODE (ret, QImode);
|
||||
|
||||
tmp = dest;
|
||||
tmpreg = dest;
|
||||
if (type == 0)
|
||||
{
|
||||
tmp = gen_lowpart (QImode, dest);
|
||||
tmpreg = tmp;
|
||||
tmp = gen_rtx_STRICT_LOW_PART (VOIDmode, tmp);
|
||||
}
|
||||
else if (type == 1)
|
||||
@ -5445,9 +5454,31 @@ ix86_expand_setcc (code, dest)
|
||||
tmp = gen_reg_rtx (QImode);
|
||||
else
|
||||
tmp = gen_lowpart (QImode, dest);
|
||||
tmpreg = tmp;
|
||||
}
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, tmp, ret));
|
||||
if (bypass_test || second_test)
|
||||
{
|
||||
rtx test = second_test;
|
||||
int bypass = 0;
|
||||
rtx tmp2 = gen_reg_rtx (QImode);
|
||||
if (bypass_test)
|
||||
{
|
||||
if (second_test)
|
||||
abort();
|
||||
test = bypass_test;
|
||||
bypass = 1;
|
||||
PUT_CODE (test, reverse_condition_maybe_unordered (GET_CODE (test)));
|
||||
}
|
||||
PUT_MODE (test, QImode);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, tmp2, test));
|
||||
|
||||
if (bypass)
|
||||
emit_insn (gen_andqi3 (tmp, tmpreg, tmp2));
|
||||
else
|
||||
emit_insn (gen_iorqi3 (tmp, tmpreg, tmp2));
|
||||
}
|
||||
|
||||
if (type == 1)
|
||||
{
|
||||
@ -5469,6 +5500,7 @@ ix86_expand_int_movcc (operands)
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]), compare_code;
|
||||
rtx compare_seq, compare_op;
|
||||
rtx second_test, bypass_test;
|
||||
|
||||
/* When the compare code is not LTU or GEU, we can not use sbbl case.
|
||||
In case comparsion is done with immediate, we can convert it to LTU or
|
||||
@ -5489,7 +5521,7 @@ ix86_expand_int_movcc (operands)
|
||||
}
|
||||
|
||||
start_sequence ();
|
||||
compare_op = ix86_expand_compare (code);
|
||||
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
|
||||
compare_seq = gen_sequence ();
|
||||
end_sequence ();
|
||||
|
||||
@ -5507,7 +5539,8 @@ ix86_expand_int_movcc (operands)
|
||||
HOST_WIDE_INT cf = INTVAL (operands[3]);
|
||||
HOST_WIDE_INT diff;
|
||||
|
||||
if (compare_code == LTU || compare_code == GEU)
|
||||
if ((compare_code == LTU || compare_code == GEU)
|
||||
&& !second_test && !bypass_test)
|
||||
{
|
||||
|
||||
/* Detect overlap between destination and compare sources. */
|
||||
@ -5796,11 +5829,36 @@ ix86_expand_int_movcc (operands)
|
||||
if (! nonimmediate_operand (operands[3], GET_MODE (operands[0])))
|
||||
operands[3] = force_reg (GET_MODE (operands[0]), operands[3]);
|
||||
|
||||
if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
|
||||
emit_move_insn (tmp, operands[3]);
|
||||
operands[3] = tmp;
|
||||
}
|
||||
if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
|
||||
emit_move_insn (tmp, operands[2]);
|
||||
operands[2] = tmp;
|
||||
}
|
||||
|
||||
emit_insn (compare_seq);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
|
||||
compare_op, operands[2],
|
||||
operands[3])));
|
||||
if (bypass_test)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
|
||||
bypass_test,
|
||||
operands[3],
|
||||
operands[0])));
|
||||
if (second_test)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
|
||||
second_test,
|
||||
operands[2],
|
||||
operands[0])));
|
||||
|
||||
return 1; /* DONE */
|
||||
}
|
||||
@ -5811,25 +5869,39 @@ ix86_expand_fp_movcc (operands)
|
||||
{
|
||||
enum rtx_code code;
|
||||
rtx tmp;
|
||||
rtx compare_op;
|
||||
rtx compare_op, second_test, bypass_test;
|
||||
|
||||
/* The floating point conditional move instructions don't directly
|
||||
support conditions resulting from a signed integer comparison. */
|
||||
|
||||
code = GET_CODE (operands[1]);
|
||||
compare_op = ix86_expand_compare (code);
|
||||
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
|
||||
|
||||
/* The floating point conditional move instructions don't directly
|
||||
support signed integer comparisons. */
|
||||
|
||||
if (!fcmov_comparison_operator (compare_op, GET_MODE (XEXP (compare_op, 0))))
|
||||
if (!fcmov_comparison_operator (compare_op, VOIDmode))
|
||||
{
|
||||
if (second_test != NULL || bypass_test != NULL)
|
||||
abort();
|
||||
tmp = gen_reg_rtx (QImode);
|
||||
ix86_expand_setcc (code, tmp);
|
||||
code = NE;
|
||||
ix86_compare_op0 = tmp;
|
||||
ix86_compare_op1 = const0_rtx;
|
||||
compare_op = ix86_expand_compare (code);
|
||||
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
|
||||
}
|
||||
if (bypass_test && reg_overlap_mentioned_p (operands[0], operands[3]))
|
||||
{
|
||||
tmp = gen_reg_rtx (GET_MODE (operands[0]));
|
||||
emit_move_insn (tmp, operands[3]);
|
||||
operands[3] = tmp;
|
||||
}
|
||||
if (second_test && reg_overlap_mentioned_p (operands[0], operands[2]))
|
||||
{
|
||||
tmp = gen_reg_rtx (GET_MODE (operands[0]));
|
||||
emit_move_insn (tmp, operands[2]);
|
||||
operands[2] = tmp;
|
||||
}
|
||||
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
@ -5837,6 +5909,18 @@ ix86_expand_fp_movcc (operands)
|
||||
compare_op,
|
||||
operands[2],
|
||||
operands[3])));
|
||||
if (bypass_test)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
|
||||
bypass_test,
|
||||
operands[3],
|
||||
operands[0])));
|
||||
if (second_test)
|
||||
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
|
||||
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
|
||||
second_test,
|
||||
operands[2],
|
||||
operands[0])));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -6263,6 +6263,16 @@
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI,QI,SI")])
|
||||
|
||||
(define_insn "*andqi_1_slp"
|
||||
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
|
||||
(and:QI (match_dup 0)
|
||||
(match_operand:QI 1 "general_operand" "qi,qmi")))
|
||||
(clobber (reg:CC 17))]
|
||||
""
|
||||
"and{b}\\t{%1, %0|%0, %1}"
|
||||
[(set_attr "type" "alu1")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*andqi_2"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI
|
||||
@ -6280,6 +6290,19 @@
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI,QI,SI")])
|
||||
|
||||
(define_insn "*andqi_2_slp"
|
||||
[(set (reg 17)
|
||||
(compare (and:QI
|
||||
(match_operand:QI 0 "nonimmediate_operand" "+q,qm")
|
||||
(match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
|
||||
(const_int 0)))
|
||||
(set (strict_low_part (match_dup 0))
|
||||
(and:QI (match_dup 0) (match_dup 1)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
"and{b}\\t{%1, %0|%0, %1}"
|
||||
[(set_attr "type" "alu1")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
;; ??? A bug in recog prevents it from recognizing a const_int as an
|
||||
;; operand to zero_extend in andqi_ext_1. It was checking explicitly
|
||||
;; for a QImode operand, which of course failed.
|
||||
@ -6479,6 +6502,16 @@
|
||||
or{b}\\t{%2, %0|%0, %2}
|
||||
or{l}\\t{%k2, %k0|%k0, %k2}"
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI,QI,SI")])
|
||||
|
||||
(define_insn "*iorqi_1_slp"
|
||||
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
|
||||
(ior:QI (match_dup 0)
|
||||
(match_operand:QI 1 "general_operand" "qmi,qi")))
|
||||
(clobber (reg:CC 17))]
|
||||
""
|
||||
"or{b}\\t{%1, %0|%0, %1}"
|
||||
[(set_attr "type" "alu1")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*iorqi_2"
|
||||
@ -6494,6 +6527,18 @@
|
||||
[(set_attr "type" "alu")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*iorqi_2_slp"
|
||||
[(set (reg 17)
|
||||
(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
|
||||
(match_operand:QI 1 "general_operand" "qim,qi"))
|
||||
(const_int 0)))
|
||||
(set (strict_low_part (match_dup 0))
|
||||
(ior:QI (match_dup 0) (match_dup 1)))]
|
||||
"ix86_match_ccmode (insn, CCNOmode)"
|
||||
"or{b}\\t{%1, %0|%0, %1}"
|
||||
[(set_attr "type" "alu1")
|
||||
(set_attr "mode" "QI")])
|
||||
|
||||
(define_insn "*iorqi_3"
|
||||
[(set (reg 17)
|
||||
(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
|
||||
@ -12496,7 +12541,8 @@
|
||||
"
|
||||
{
|
||||
emit_insn (gen_rtx_TRAP_IF (VOIDmode,
|
||||
ix86_expand_compare (GET_CODE (operands[0])),
|
||||
ix86_expand_compare (GET_CODE (operands[0]),
|
||||
NULL_RTX, NULL_RTX),
|
||||
operands[1]));
|
||||
DONE;
|
||||
}")
|
||||
|
Loading…
Reference in New Issue
Block a user