ARM support for unordered FP operations.

* arm-protos.h (arm_comparison_operator): Declare.
* arm.c (arm_comparison_operator): New function.
(arm_select_cc_mode): Add unordered comparison codes.
(get_arm_condition_code): Likewise.
(arm_final_prescan_insn): Can't handle unordered jumps that can't
be done in one insn.
* arm.h (PREDICATE_CODES): Add arm_comparison_operator.
* arm.md (all uses of comparison_operator): Replace with
arm_comparison_operator.
(bunordered, bordered, bugt, bunlt, bunge, bunle, buneq, bltgt): New
expands.
(arm_buneq, arm_bltgt, arm_buneq_reversed, arm_bltgt_reveresed): New
patterns.

From-SVN: r35705
This commit is contained in:
Richard Earnshaw 2000-08-15 13:41:34 +00:00
parent 05ed98a11f
commit e45b72c408
2 changed files with 56 additions and 5 deletions

View File

@ -3000,6 +3000,17 @@ equality_operator (x, mode)
return GET_CODE (x) == EQ || GET_CODE (x) == NE;
}
/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
int
arm_comparison_operator (x, mode)
rtx x;
enum machine_mode mode;
{
return (comparison_operator (x, mode)
&& GET_CODE (x) != LTGT
&& GET_CODE (x) != UNEQ);
}
/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
int
minmax_operator (x, mode)
@ -4194,7 +4205,31 @@ arm_select_cc_mode (op, x, y)
/* All floating point compares return CCFP if it is an equality
comparison, and CCFPE otherwise. */
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
return (op == EQ || op == NE) ? CCFPmode : CCFPEmode;
{
switch (op)
{
case EQ:
case NE:
case UNORDERED:
case ORDERED:
case UNLT:
case UNLE:
case UNGT:
case UNGE:
case UNEQ:
case LTGT:
return CCFPmode;
case LT:
case LE:
case GT:
case GE:
return CCFPEmode;
default:
abort ();
}
}
/* A compare with a shifted operand. Because of canonicalization, the
comparison will have to be swapped when we emit the assembler. */
@ -7642,7 +7677,6 @@ get_arm_condition_code (comparison)
}
case CC_Zmode:
case CCFPmode:
switch (comp_code)
{
case NE: return ARM_NE;
@ -7651,12 +7685,27 @@ get_arm_condition_code (comparison)
}
case CCFPEmode:
case CCFPmode:
/* These encodings assume that AC=1 in the FPA system control
byte. This allows us to handle all cases except UNEQ and
LTGT. */
switch (comp_code)
{
case GE: return ARM_GE;
case GT: return ARM_GT;
case LE: return ARM_LS;
case LT: return ARM_MI;
case NE: return ARM_NE;
case EQ: return ARM_EQ;
case ORDERED: return ARM_VC;
case UNORDERED: return ARM_VS;
case UNLT: return ARM_LT;
case UNLE: return ARM_LE;
case UNGT: return ARM_HI;
case UNGE: return ARM_PL;
/* UNEQ and LTGT do not have a representation. */
case UNEQ: /* Fall through. */
case LTGT: /* Fall through. */
default: abort ();
}
@ -7812,11 +7861,10 @@ arm_final_prescan_insn (insn)
int then_not_else = TRUE;
rtx this_insn = start_insn, label = 0;
/* If the jump cannot be done with one instruction, we cannot
conditionally execute the instruction in the inverse case. */
if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
{
/* The code below is wrong for these, and I haven't time to
fix it now. So we just do the safe thing and return. This
whole function needs re-writing anyway. */
jump_clobbers = 1;
return;
}

View File

@ -2883,6 +2883,9 @@ extern int making_const_table;
{"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \
{"equality_operator", {EQ, NE}}, \
{"arm_comparison_operator", {EQ, NE, LE, LT, GE, GT, GEU, GTU, LEU, \
LTU, UNORDERED, ORDERED, UNLT, UNLE, \
UNGE, UNGT}}, \
{"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"const_shift_operand", {CONST_INT}}, \
{"multi_register_push", {PARALLEL}}, \