mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 19:41:29 +08:00
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:
parent
b38ba46301
commit
24ea7948dc
@ -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.
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user