ia64.c (cmptf_libfunc): New static.

* config/ia64/ia64.c (cmptf_libfunc): New static.
	(ia64_expand_compare): Add logic to open-code calls to
	_U_Qfcmp for TFmode comparisons.
	(ia64_hpux_init_libfuncs): Initialize cmptf_libfunc.
	Set libfuncs for TFmode eq/ne/gt/ge/lt/gt to 0; these should
	never be generated anymore.
	* config/ia64/ia64.md (cmptf): New expander.

From-SVN: r73028
This commit is contained in:
Zack Weinberg 2003-10-29 01:28:09 +00:00 committed by Zack Weinberg
parent b38ba46301
commit 24ea7948dc
3 changed files with 86 additions and 6 deletions

View File

@ -1,3 +1,13 @@
2003-10-28 Zack Weinberg <zack@codesourcery.com>
* config/ia64/ia64.c (cmptf_libfunc): New static.
(ia64_expand_compare): Add logic to open-code calls to
_U_Qfcmp for TFmode comparisons.
(ia64_hpux_init_libfuncs): Initialize cmptf_libfunc.
Set libfuncs for TFmode eq/ne/gt/ge/lt/gt to 0; these should
never be generated anymore.
* config/ia64/ia64.md (cmptf): New expander.
2003-10-28 Zack Weinberg <zack@codesourcery.com>
* ia64.md (UNSPEC_SETF_EXP,UNSPEC_FR_SQRT_RECIP_APPROX): New constants.

View File

@ -1465,6 +1465,8 @@ spill_xfmode_operand (rtx in, int force)
/* Emit comparison instruction if necessary, returning the expression
that holds the compare result in the proper mode. */
static GTY(()) rtx cmptf_libfunc;
rtx
ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
{
@ -1480,6 +1482,59 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
else
abort ();
}
/* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
magic number as its third argument, that indicates what to do.
The return value is an integer to be compared against zero. */
else if (TARGET_HPUX && GET_MODE (op0) == TFmode)
{
enum qfcmp_magic {
QCMP_INV = 1, /* Raise FP_INVALID on SNaN as a side effect. */
QCMP_UNORD = 2,
QCMP_EQ = 4,
QCMP_LT = 8,
QCMP_GT = 16
} magic;
enum rtx_code ncode;
rtx ret, insns;
if (GET_MODE (op1) != TFmode)
abort ();
switch (code)
{
/* 1 = equal, 0 = not equal. Equality operators do
not raise FP_INVALID when given an SNaN operand. */
case EQ: magic = QCMP_EQ; ncode = NE; break;
case NE: magic = QCMP_EQ; ncode = EQ; break;
/* isunordered() from C99. */
case UNORDERED: magic = QCMP_UNORD; ncode = NE; break;
/* Relational operators raise FP_INVALID when given
an SNaN operand. */
case LT: magic = QCMP_LT |QCMP_INV; ncode = NE; break;
case LE: magic = QCMP_LT|QCMP_EQ|QCMP_INV; ncode = NE; break;
case GT: magic = QCMP_GT |QCMP_INV; ncode = NE; break;
case GE: magic = QCMP_GT|QCMP_EQ|QCMP_INV; ncode = NE; break;
/* FUTURE: Implement UNEQ, UNLT, UNLE, UNGT, UNGE, LTGT.
Expanders for buneq etc. weuld have to be added to ia64.md
for this to be useful. */
default: abort ();
}
start_sequence ();
ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode, 3,
op0, TFmode, op1, TFmode,
GEN_INT (magic), DImode);
cmp = gen_reg_rtx (BImode);
emit_insn (gen_rtx_SET (VOIDmode, cmp,
gen_rtx_fmt_ee (ncode, BImode,
ret, const0_rtx)));
insns = get_insns ();
end_sequence ();
emit_libcall_block (insns, cmp, cmp,
gen_rtx_fmt_ee (code, BImode, op0, op1));
code = NE;
}
else
{
cmp = gen_reg_rtx (BImode);
@ -8338,12 +8393,16 @@ ia64_hpux_init_libfuncs (void)
set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
set_optab_libfunc (eq_optab, TFmode, "_U_Qfeq");
set_optab_libfunc (ne_optab, TFmode, "_U_Qfne");
set_optab_libfunc (gt_optab, TFmode, "_U_Qfgt");
set_optab_libfunc (ge_optab, TFmode, "_U_Qfge");
set_optab_libfunc (lt_optab, TFmode, "_U_Qflt");
set_optab_libfunc (le_optab, TFmode, "_U_Qfle");
/* ia64_expand_compare uses this. */
cmptf_libfunc = init_one_libfunc ("_U_Qfcmp");
/* These should never be used. */
set_optab_libfunc (eq_optab, TFmode, 0);
set_optab_libfunc (ne_optab, TFmode, 0);
set_optab_libfunc (gt_optab, TFmode, 0);
set_optab_libfunc (ge_optab, TFmode, 0);
set_optab_libfunc (lt_optab, TFmode, 0);
set_optab_libfunc (le_optab, TFmode, 0);
set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");

View File

@ -4484,6 +4484,17 @@
DONE;
})
(define_expand "cmptf"
[(set (cc0)
(compare (match_operand:TF 0 "gr_register_operand" "")
(match_operand:TF 1 "gr_register_operand" "")))]
"TARGET_HPUX"
{
ia64_compare_op0 = operands[0];
ia64_compare_op1 = operands[1];
DONE;
})
(define_insn "*cmpsi_normal"
[(set (match_operand:BI 0 "register_operand" "=c")
(match_operator:BI 1 "normal_comparison_operator"