Commit e45b72c4 by Richard Earnshaw

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
parent 05ed98a1
...@@ -3000,6 +3000,17 @@ equality_operator (x, mode) ...@@ -3000,6 +3000,17 @@ equality_operator (x, mode)
return GET_CODE (x) == EQ || GET_CODE (x) == NE; 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. */ /* Return TRUE for SMIN SMAX UMIN UMAX operators. */
int int
minmax_operator (x, mode) minmax_operator (x, mode)
...@@ -4194,7 +4205,31 @@ arm_select_cc_mode (op, x, y) ...@@ -4194,7 +4205,31 @@ arm_select_cc_mode (op, x, y)
/* All floating point compares return CCFP if it is an equality /* All floating point compares return CCFP if it is an equality
comparison, and CCFPE otherwise. */ comparison, and CCFPE otherwise. */
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 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 /* A compare with a shifted operand. Because of canonicalization, the
comparison will have to be swapped when we emit the assembler. */ comparison will have to be swapped when we emit the assembler. */
...@@ -7642,7 +7677,6 @@ get_arm_condition_code (comparison) ...@@ -7642,7 +7677,6 @@ get_arm_condition_code (comparison)
} }
case CC_Zmode: case CC_Zmode:
case CCFPmode:
switch (comp_code) switch (comp_code)
{ {
case NE: return ARM_NE; case NE: return ARM_NE;
...@@ -7651,12 +7685,27 @@ get_arm_condition_code (comparison) ...@@ -7651,12 +7685,27 @@ get_arm_condition_code (comparison)
} }
case CCFPEmode: 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) switch (comp_code)
{ {
case GE: return ARM_GE; case GE: return ARM_GE;
case GT: return ARM_GT; case GT: return ARM_GT;
case LE: return ARM_LS; case LE: return ARM_LS;
case LT: return ARM_MI; 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 (); default: abort ();
} }
...@@ -7812,11 +7861,10 @@ arm_final_prescan_insn (insn) ...@@ -7812,11 +7861,10 @@ arm_final_prescan_insn (insn)
int then_not_else = TRUE; int then_not_else = TRUE;
rtx this_insn = start_insn, label = 0; 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) 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; jump_clobbers = 1;
return; return;
} }
......
...@@ -2883,6 +2883,9 @@ extern int making_const_table; ...@@ -2883,6 +2883,9 @@ extern int making_const_table;
{"load_multiple_operation", {PARALLEL}}, \ {"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \ {"store_multiple_operation", {PARALLEL}}, \
{"equality_operator", {EQ, NE}}, \ {"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}}, \ {"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"const_shift_operand", {CONST_INT}}, \ {"const_shift_operand", {CONST_INT}}, \
{"multi_register_push", {PARALLEL}}, \ {"multi_register_push", {PARALLEL}}, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment