sparc-protos.h (gen_compare_operator): Declare.

* config/sparc/sparc-protos.h (gen_compare_operator): Declare.
	(sparc_emit_float_lib_cmp): Change return type.
	* config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
	(gen_compare_operator): New function.
	(sparc_emit_float_lib_cmp): Return the new operator to be used in
	the comparison sequence.  Minor tweaks.
	* config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
	that the final operator and the result of sparc_emit_float_lib_cmp
	match for software TFmode; use emit_insn in lieu of emit_jump_insn.
	(beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
	buneq, bunge, bunle, bltgt): Assert that the final operator and the
	result of sparc_emit_float_lib_cmp match for software TFmode.
	(movqicc, movhicc, movsicc, movdicc): Merge into...
	(mov<I:mode>cc): ...this.
	(movsfcc, movdfcc, movtfcc): Merge into...
	(mov<F:mode>cc): ...this.
	(movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
	into...
	(mov<I:mode>_cc_v9): ...this.
	(movdi_cc_sp64_trunc): Delete.
	(movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
	movdi_cc_reg_sp64): Merge into...
	(mov<I:mode>_cc_reg_sp64): ...this.
	(movsf_cc_sp64): Rename into...
	(movsf_cc_v9): ...this.
	(movdf_cc_sp64): Rename into...
	(movdf_cc_v9): ...this.
	(movtf_cc_hq_sp64): Rename into...
	(movtf_cc_hq_v9): ...this.
	(movtf_cc_sp64): Rename into...
	(movtf_cc_v9): ...this.  Adjust for renaming of movdf_cc_sp64.

From-SVN: r140530
This commit is contained in:
Eric Botcazou 2008-09-21 19:25:48 +00:00 committed by Eric Botcazou
parent 4b7f8314ba
commit 19047e4a03
4 changed files with 250 additions and 385 deletions

View file

@ -1,3 +1,37 @@
2008-09-21 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc-protos.h (gen_compare_operator): Declare.
(sparc_emit_float_lib_cmp): Change return type.
* config/sparc/sparc.c (gen_compare_reg): Add comment about TFmode.
(gen_compare_operator): New function.
(sparc_emit_float_lib_cmp): Return the new operator to be used in
the comparison sequence. Minor tweaks.
* config/sparc/sparc.md (seq, sne, sgt, slt, sge, sle): Assert
that the final operator and the result of sparc_emit_float_lib_cmp
match for software TFmode; use emit_insn in lieu of emit_jump_insn.
(beq, bne, bgt, blt, bge, ble, bunordered, bordered, bungt, bunlt,
buneq, bunge, bunle, bltgt): Assert that the final operator and the
result of sparc_emit_float_lib_cmp match for software TFmode.
(movqicc, movhicc, movsicc, movdicc): Merge into...
(mov<I:mode>cc): ...this.
(movsfcc, movdfcc, movtfcc): Merge into...
(mov<F:mode>cc): ...this.
(movqi_cc_sp64, movhi_cc_sp64, movsi_cc_sp64, movdi_cc_sp64): Merge
into...
(mov<I:mode>_cc_v9): ...this.
(movdi_cc_sp64_trunc): Delete.
(movqi_cc_reg_sp64, movhi_cc_reg_sp64, movsi_cc_reg_sp64,
movdi_cc_reg_sp64): Merge into...
(mov<I:mode>_cc_reg_sp64): ...this.
(movsf_cc_sp64): Rename into...
(movsf_cc_v9): ...this.
(movdf_cc_sp64): Rename into...
(movdf_cc_v9): ...this.
(movtf_cc_hq_sp64): Rename into...
(movtf_cc_hq_v9): ...this.
(movtf_cc_sp64): Rename into...
(movtf_cc_v9): ...this. Adjust for renaming of movdf_cc_sp64.
2008-09-21 Diego Novillo <dnovillo@google.com>
* doc/gccint.texi: Include generic.texi and gimple.texi.

View file

@ -54,7 +54,8 @@ extern void sparc_output_scratch_registers (FILE *);
extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */
extern rtx gen_compare_reg (enum rtx_code code);
extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern rtx gen_compare_operator (enum rtx_code code);
extern enum rtx_code sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
extern void emit_tfmode_binop (enum rtx_code, rtx *);

View file

@ -2001,8 +2001,7 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
}
}
/* X and Y are two things to compare using CODE. Emit the compare insn and
return the rtx for the cc reg in the proper mode. */
/* Emit the compare insn and return the CC reg for a CODE comparison. */
rtx
gen_compare_reg (enum rtx_code code)
@ -2065,12 +2064,28 @@ gen_compare_reg (enum rtx_code code)
else
cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG);
emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
gen_rtx_COMPARE (mode, x, y)));
/* We shouldn't get there for TFmode if !TARGET_HARD_QUAD. If we do, this
will only result in an unrecognizable insn so no point in asserting. */
emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_COMPARE (mode, x, y)));
return cc_reg;
}
/* Same as above but return the whole compare operator. */
rtx
gen_compare_operator (enum rtx_code code)
{
rtx cc_reg;
if (GET_MODE (sparc_compare_op0) == TFmode && !TARGET_HARD_QUAD)
code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, code);
cc_reg = gen_compare_reg (code);
return gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
/* This function is used for v9 only.
CODE is the code for an Scc's comparison.
OPERANDS[0] is the target of the Scc insn.
@ -6099,41 +6114,45 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
}
/* Emit a library call comparison between floating point X and Y.
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
COMPARISON is the operator to compare with (EQ, NE, GT, etc).
Return the new operator to be used in the comparison sequence.
TARGET_ARCH64 uses _Qp_* functions, which use pointers to TFmode
values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */
void
enum rtx_code
sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
rtx slot0, slot1, result, tem, tem2;
enum machine_mode mode;
enum rtx_code new_comparison;
switch (comparison)
{
case EQ:
qpfunc = (TARGET_ARCH64) ? "_Qp_feq" : "_Q_feq";
qpfunc = (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq");
break;
case NE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fne" : "_Q_fne";
qpfunc = (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne");
break;
case GT:
qpfunc = (TARGET_ARCH64) ? "_Qp_fgt" : "_Q_fgt";
qpfunc = (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt");
break;
case GE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fge" : "_Q_fge";
qpfunc = (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge");
break;
case LT:
qpfunc = (TARGET_ARCH64) ? "_Qp_flt" : "_Q_flt";
qpfunc = (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt");
break;
case LE:
qpfunc = (TARGET_ARCH64) ? "_Qp_fle" : "_Q_fle";
qpfunc = (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle");
break;
case ORDERED:
@ -6144,7 +6163,7 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
case UNGE:
case UNLE:
case LTGT:
qpfunc = (TARGET_ARCH64) ? "_Qp_cmp" : "_Q_cmp";
qpfunc = (TARGET_ARCH64 ? "_Qp_cmp" : "_Q_cmp");
break;
default:
@ -6153,27 +6172,26 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
if (TARGET_ARCH64)
{
if (GET_CODE (x) != MEM)
if (MEM_P (x))
slot0 = x;
else
{
slot0 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot0, x);
}
else
slot0 = x;
if (GET_CODE (y) != MEM)
if (MEM_P (y))
slot1 = y;
else
{
slot1 = assign_stack_temp (TFmode, GET_MODE_SIZE(TFmode), 0);
emit_move_insn (slot1, y);
}
else
slot1 = y;
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
DImode, 2,
XEXP (slot0, 0), Pmode,
XEXP (slot1, 0), Pmode);
mode = DImode;
}
else
@ -6181,7 +6199,6 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_library_call (gen_rtx_SYMBOL_REF (Pmode, qpfunc), LCT_NORMAL,
SImode, 2,
x, TFmode, y, TFmode);
mode = SImode;
}
@ -6195,20 +6212,22 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
switch (comparison)
{
default:
emit_cmp_insn (result, const0_rtx, NE, NULL_RTX, mode, 0);
new_comparison = NE;
emit_cmp_insn (result, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case ORDERED:
case UNORDERED:
emit_cmp_insn (result, GEN_INT(3), comparison == UNORDERED ? EQ : NE,
NULL_RTX, mode, 0);
new_comparison = (comparison == UNORDERED ? EQ : NE);
emit_cmp_insn (result, GEN_INT(3), new_comparison, NULL_RTX, mode, 0);
break;
case UNGT:
case UNGE:
emit_cmp_insn (result, const1_rtx,
comparison == UNGT ? GT : NE, NULL_RTX, mode, 0);
new_comparison = (comparison == UNGT ? GT : NE);
emit_cmp_insn (result, const1_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNLE:
emit_cmp_insn (result, const2_rtx, NE, NULL_RTX, mode, 0);
new_comparison = NE;
emit_cmp_insn (result, const2_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNLT:
tem = gen_reg_rtx (mode);
@ -6216,7 +6235,8 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem, result, const1_rtx));
else
emit_insn (gen_anddi3 (tem, result, const1_rtx));
emit_cmp_insn (tem, const0_rtx, NE, NULL_RTX, mode, 0);
new_comparison = NE;
emit_cmp_insn (tem, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
case UNEQ:
case LTGT:
@ -6230,10 +6250,12 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
emit_insn (gen_andsi3 (tem2, tem, const2_rtx));
else
emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
emit_cmp_insn (tem2, const0_rtx, comparison == UNEQ ? EQ : NE,
NULL_RTX, mode, 0);
new_comparison = (comparison == UNEQ ? EQ : NE);
emit_cmp_insn (tem2, const0_rtx, new_comparison, NULL_RTX, mode, 0);
break;
}
return new_comparison;
}
/* Generate an unsigned DImode to FP conversion. This is the same code

View file

@ -621,8 +621,10 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -673,8 +675,10 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -693,8 +697,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -713,8 +719,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -733,8 +741,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -753,8 +763,10 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
emit_jump_insn (gen_sne (operands[0]));
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
gcc_assert (code == NE);
emit_insn (gen_sne (operands[0]));
DONE;
}
else if (TARGET_V9)
@ -1270,7 +1282,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1293,7 +1307,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1316,7 +1332,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1349,7 +1367,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1382,7 +1402,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1415,7 +1437,9 @@
}
else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1441,8 +1465,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
UNORDERED);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
gcc_assert (code == EQ);
emit_jump_insn (gen_beq (operands[0]));
DONE;
}
@ -1458,7 +1483,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1474,7 +1501,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
gcc_assert (code == GT);
emit_jump_insn (gen_bgt (operands[0]));
DONE;
}
@ -1490,7 +1519,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1506,7 +1537,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
gcc_assert (code == EQ);
emit_jump_insn (gen_beq (operands[0]));
DONE;
}
@ -1522,7 +1555,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1538,7 +1573,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -1554,7 +1591,9 @@
{
if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
{
sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
enum rtx_code code
= sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
gcc_assert (code == NE);
emit_jump_insn (gen_bne (operands[0]));
DONE;
}
@ -3015,7 +3054,7 @@
})
;; SPARC-V9 conditional move instructions.
;; SPARC-V9 conditional move instructions
;; We can handle larger constants here for some flavors, but for now we keep
;; it simple and only allow those constants supported by all flavors.
@ -3023,12 +3062,14 @@
;; 3 contains the constant if one is present, but we handle either for
;; generality (sparc.c puts a constant in operand 2).
(define_expand "movqicc"
[(set (match_operand:QI 0 "register_operand" "")
(if_then_else:QI (match_operand 1 "comparison_operator" "")
(match_operand:QI 2 "arith10_operand" "")
(match_operand:QI 3 "arith10_operand" "")))]
"TARGET_V9"
(define_mode_iterator I [QI HI SI DI])
(define_expand "mov<I:mode>cc"
[(set (match_operand:I 0 "register_operand" "")
(if_then_else:I (match_operand 1 "comparison_operator" "")
(match_operand:I 2 "arith10_operand" "")
(match_operand:I 3 "arith10_operand" "")))]
"TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
{
enum rtx_code code = GET_CODE (operands[1]);
@ -3040,100 +3081,18 @@
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
operands[1] = gen_compare_operator (code);
})
(define_expand "movhicc"
[(set (match_operand:HI 0 "register_operand" "")
(if_then_else:HI (match_operand 1 "comparison_operator" "")
(match_operand:HI 2 "arith10_operand" "")
(match_operand:HI 3 "arith10_operand" "")))]
"TARGET_V9"
{
enum rtx_code code = GET_CODE (operands[1]);
(define_mode_iterator F [SF DF TF])
if (GET_MODE (sparc_compare_op0) == DImode
&& ! TARGET_ARCH64)
FAIL;
if (sparc_compare_op1 == const0_rtx
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
})
(define_expand "movsicc"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (match_operand 1 "comparison_operator" "")
(match_operand:SI 2 "arith10_operand" "")
(match_operand:SI 3 "arith10_operand" "")))]
"TARGET_V9"
{
enum rtx_code code = GET_CODE (operands[1]);
enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
if (sparc_compare_op1 == const0_rtx
&& GET_CODE (sparc_compare_op0) == REG
&& (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
{
operands[1] = gen_rtx_fmt_ee (code, op0_mode,
sparc_compare_op0, sparc_compare_op1);
}
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
cc_reg, const0_rtx);
}
})
(define_expand "movdicc"
[(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI (match_operand 1 "comparison_operator" "")
(match_operand:DI 2 "arith10_operand" "")
(match_operand:DI 3 "arith10_operand" "")))]
"TARGET_ARCH64"
{
enum rtx_code code = GET_CODE (operands[1]);
if (sparc_compare_op1 == const0_rtx
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
cc_reg, const0_rtx);
}
})
(define_expand "movsfcc"
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "register_operand" "")))]
(define_expand "mov<F:mode>cc"
[(set (match_operand:F 0 "register_operand" "")
(if_then_else:F (match_operand 1 "comparison_operator" "")
(match_operand:F 2 "register_operand" "")
(match_operand:F 3 "register_operand" "")))]
"TARGET_V9 && TARGET_FPU"
{
enum rtx_code code = GET_CODE (operands[1]);
@ -3146,160 +3105,73 @@
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
operands[1] = gen_compare_operator (code);
})
(define_expand "movdfcc"
[(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "register_operand" "")
(match_operand:DF 3 "register_operand" "")))]
"TARGET_V9 && TARGET_FPU"
{
enum rtx_code code = GET_CODE (operands[1]);
;; Conditional move define_insns
if (GET_MODE (sparc_compare_op0) == DImode
&& ! TARGET_ARCH64)
FAIL;
if (sparc_compare_op1 == const0_rtx
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
})
(define_expand "movtfcc"
[(set (match_operand:TF 0 "register_operand" "")
(if_then_else:TF (match_operand 1 "comparison_operator" "")
(match_operand:TF 2 "register_operand" "")
(match_operand:TF 3 "register_operand" "")))]
"TARGET_V9 && TARGET_FPU"
{
enum rtx_code code = GET_CODE (operands[1]);
if (GET_MODE (sparc_compare_op0) == DImode
&& ! TARGET_ARCH64)
FAIL;
if (sparc_compare_op1 == const0_rtx
&& GET_CODE (sparc_compare_op0) == REG
&& GET_MODE (sparc_compare_op0) == DImode
&& v9_regcmp_p (code))
{
operands[1] = gen_rtx_fmt_ee (code, DImode,
sparc_compare_op0, sparc_compare_op1);
}
else
{
rtx cc_reg = gen_compare_reg (code);
operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
}
})
;; Conditional move define_insns.
(define_insn "*movqi_cc_sp64"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(if_then_else:QI (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:QI 3 "arith11_operand" "rL,0")
(match_operand:QI 4 "arith11_operand" "0,rL")))]
"TARGET_V9"
(define_insn "*mov<I:mode>_cc_v9"
[(set (match_operand:I 0 "register_operand" "=r,r")
(if_then_else:I (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:I 3 "arith11_operand" "rL,0")
(match_operand:I 4 "arith11_operand" "0,rL")))]
"TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movhi_cc_sp64"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(define_insn "*mov<I:mode>_cc_reg_sp64"
[(set (match_operand:I 0 "register_operand" "=r,r")
(if_then_else:I (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:HI 3 "arith11_operand" "rL,0")
(match_operand:HI 4 "arith11_operand" "0,rL")))]
"TARGET_V9"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movsi_cc_sp64"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:SI 3 "arith11_operand" "rL,0")
(match_operand:SI 4 "arith11_operand" "0,rL")))]
"TARGET_V9"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movdi_cc_sp64"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:DI 3 "arith11_operand" "rL,0")
(match_operand:DI 4 "arith11_operand" "0,rL")))]
(match_operand:I 3 "arith10_operand" "rM,0")
(match_operand:I 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
movr%D1\t%2, %r3, %0
movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movdi_cc_sp64_trunc"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:SI 3 "arith11_operand" "rL,0")
(match_operand:SI 4 "arith11_operand" "0,rL")))]
"TARGET_ARCH64"
"@
mov%C1\t%x2, %3, %0
mov%c1\t%x2, %4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movsf_cc_sp64"
(define_insn "*movsf_cc_v9"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:SF 3 "register_operand" "f,0")
(match_operand:SF 4 "register_operand" "0,f")))]
(match_operand:SF 3 "register_operand" "f,0")
(match_operand:SF 4 "register_operand" "0,f")))]
"TARGET_V9 && TARGET_FPU"
"@
fmovs%C1\t%x2, %3, %0
fmovs%c1\t%x2, %4, %0"
[(set_attr "type" "fpcmove")])
(define_insn "movdf_cc_sp64"
(define_insn "*movsf_cc_reg_sp64"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:SF 3 "register_operand" "f,0")
(match_operand:SF 4 "register_operand" "0,f")))]
"TARGET_ARCH64 && TARGET_FPU"
"@
fmovrs%D1\t%2, %3, %0
fmovrs%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")])
;; Named because invoked by movtf_cc_v9
(define_insn "movdf_cc_v9"
[(set (match_operand:DF 0 "register_operand" "=e,e")
(if_then_else:DF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:DF 3 "register_operand" "e,0")
(match_operand:DF 4 "register_operand" "0,e")))]
(match_operand:DF 3 "register_operand" "e,0")
(match_operand:DF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU"
"@
fmovd%C1\t%x2, %3, %0
@ -3307,26 +3179,54 @@
[(set_attr "type" "fpcmove")
(set_attr "fptype" "double")])
(define_insn "*movtf_cc_hq_sp64"
;; Named because invoked by movtf_cc_reg_sp64
(define_insn "movdf_cc_reg_sp64"
[(set (match_operand:DF 0 "register_operand" "=e,e")
(if_then_else:DF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:DF 3 "register_operand" "e,0")
(match_operand:DF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU"
"@
fmovrd%D1\t%2, %3, %0
fmovrd%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")
(set_attr "fptype" "double")])
(define_insn "*movtf_cc_hq_v9"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
"@
fmovq%C1\t%x2, %3, %0
fmovq%c1\t%x2, %4, %0"
[(set_attr "type" "fpcmove")])
(define_insn_and_split "*movtf_cc_sp64"
(define_insn "*movtf_cc_reg_hq_sp64"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
"@
fmovrq%D1\t%2, %3, %0
fmovrq%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")])
(define_insn_and_split "*movtf_cc_v9"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "comparison_operator"
[(match_operand 2 "icc_or_fcc_register_operand" "X,X")
(const_int 0)])
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
"#"
"&& reload_completed"
@ -3351,117 +3251,25 @@
if ((third && reg_overlap_mentioned_p (dest1, srcb2))
|| (!third && reg_overlap_mentioned_p (dest1, srca2)))
{
emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
}
else
{
emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
}
DONE;
}
[(set_attr "length" "2")])
(define_insn "*movqi_cc_reg_sp64"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(if_then_else:QI (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:QI 3 "arith10_operand" "rM,0")
(match_operand:QI 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
movr%D1\t%2, %r3, %0
movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movhi_cc_reg_sp64"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(if_then_else:HI (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:HI 3 "arith10_operand" "rM,0")
(match_operand:HI 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
movr%D1\t%2, %r3, %0
movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movsi_cc_reg_sp64"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(if_then_else:SI (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:SI 3 "arith10_operand" "rM,0")
(match_operand:SI 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
movr%D1\t%2, %r3, %0
movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movdi_cc_reg_sp64"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:DI 3 "arith10_operand" "rM,0")
(match_operand:DI 4 "arith10_operand" "0,rM")))]
"TARGET_ARCH64"
"@
movr%D1\t%2, %r3, %0
movr%d1\t%2, %r4, %0"
[(set_attr "type" "cmove")])
(define_insn "*movsf_cc_reg_sp64"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:SF 3 "register_operand" "f,0")
(match_operand:SF 4 "register_operand" "0,f")))]
"TARGET_ARCH64 && TARGET_FPU"
"@
fmovrs%D1\t%2, %3, %0
fmovrs%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")])
(define_insn "movdf_cc_reg_sp64"
[(set (match_operand:DF 0 "register_operand" "=e,e")
(if_then_else:DF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:DF 3 "register_operand" "e,0")
(match_operand:DF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU"
"@
fmovrd%D1\t%2, %3, %0
fmovrd%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")
(set_attr "fptype" "double")])
(define_insn "*movtf_cc_reg_hq_sp64"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
"@
fmovrq%D1\t%2, %3, %0
fmovrq%d1\t%2, %4, %0"
[(set_attr "type" "fpcrmove")])
(define_insn_and_split "*movtf_cc_reg_sp64"
[(set (match_operand:TF 0 "register_operand" "=e,e")
(if_then_else:TF (match_operator 1 "v9_register_compare_operator"
[(match_operand:DI 2 "register_operand" "r,r")
(const_int 0)])
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
(match_operand:TF 3 "register_operand" "e,0")
(match_operand:TF 4 "register_operand" "0,e")))]
"TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
"#"
"&& reload_completed"