Unordered compares and backends lacking them
Jan Hubicka
jh@suse.cz
Thu Mar 8 10:22:00 GMT 2001
Hi,
Here is an attempt to fix the mips bootstrap problem I've introduced by
reversal changes. It adds code to prepare_cmp_insn to break out the
comparisons into old ones, so targets supporting only old FP comparison
codes remain happy (and now will support the c99 builtins as well).
On mips target this allows me to get bit farer on compiling that file,
dying later trying to construct conditional move with unordered code.
Mips.md needs updating....
But for this particular problem, I believe patch bellow is optimal solution
(except teaching all backends to do unordered compares in optimal way using
some architecture dependent tricks, that may or may not be better then
the default sollution bellow).
Honza
Thu Mar 8 19:16:01 CET 2001 Jan Hubicka <jh@suse.cz>
* optabs.c (prepare_cmp_insn): Split unordered compares to
discrete equivalent.
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.89
diff -c -3 -p -r1.89 optabs.c
*** optabs.c 2001/03/07 19:29:36 1.89
--- optabs.c 2001/03/08 18:14:20
*************** prepare_cmp_insn (px, py, pcomparison, s
*** 3142,3149 ****
}
if (class == MODE_FLOAT)
! prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
else
abort ();
}
--- 3142,3218 ----
}
if (class == MODE_FLOAT)
! {
! enum rtx_code ordered_code = UNKNOWN;
! /* Attempt to split the unordered comparisons. */
! switch (*pcomparison)
! {
! case UNLT:
! ordered_code = LT;
! break;
! case UNLE:
! ordered_code = LE;
! break;
! case UNGT:
! ordered_code = GT;
! break;
! case UNGE:
! ordered_code = GE;
! break;
! case UNEQ:
! ordered_code = EQ;
! break;
! /* Handled as special cases later. */
! case LTGT:
! ordered_code = EQ;
! break;
! case UNORDERED:
! case ORDERED:
! ordered_code = NIL;
! break;
! default:
! break;
! }
! if (ordered_code != UNKNOWN
! && (can_compare_p (UNORDERED, mode, ccp_jump)
! || can_compare_p (EQ, mode, ccp_jump))
! && (can_compare_p (ordered_code, mode, ccp_store_flag)
! || can_compare_p (ordered_code, mode, ccp_jump)))
! {
! rtx label = gen_label_rtx ();
! rtx target = gen_reg_rtx (word_mode);
! int reverse = 0;
+ emit_move_insn (target, const1_rtx);
+
+ /* We also may be able to convert ORDERED to !UNORDERED here. */
+ if (can_compare_p (UNORDERED, mode, ccp_jump))
+ emit_cmp_and_jump_insn_1 (*px, *py, *pmode, UNORDERED, 0, label);
+ else
+ {
+ emit_cmp_and_jump_insn_1 (*px, *px, *pmode, NE, 0, label);
+ emit_cmp_and_jump_insn_1 (*py, *py, *pmode, NE, 0, label);
+ }
+ if (ordered_code != 1)
+ emit_store_flag_force (target, ordered_code, *px, *py, mode, 0, 0);
+ else
+ emit_move_insn (target, const0_rtx);
+ emit_label (label);
+
+ if (*pcomparison == LTGT || *pcomparison == ORDERED)
+ *pcomparison = EQ;
+ else
+ *pcomparison = NE;
+
+ *pmode = word_mode;
+ *px = target;
+ *py = const0_rtx;
+
+ return prepare_cmp_insn (px, py, pcomparison, 0, pmode, punsignedp, align,
+ purpose);
+ }
+ prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
+ }
else
abort ();
}
More information about the Gcc-patches
mailing list