aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2000-08-15 13:32:11 +0000
committerRichard Earnshaw <rearnsha@arm.com>2000-08-15 13:32:11 +0000
commita425e8b12b676e6ec314b2b275af1d2b30e474b5 (patch)
treebb68346d17b6c5420cc14af274a78ee50027c631
parenta8aec5d453f43d7cb393600b826f519d0ce015a0 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/merged-arm-thumb-backend-branch@35703 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/config/arm/arm.c58
-rw-r--r--gcc/config/arm/arm.h3
2 files changed, 56 insertions, 5 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 3a4acd79846..29336eecc39 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3001,6 +3001,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)
@@ -4213,7 +4224,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. */
@@ -7766,7 +7801,6 @@ get_arm_condition_code (comparison)
}
case CC_Zmode:
- case CCFPmode:
switch (comp_code)
{
case NE: return ARM_NE;
@@ -7775,12 +7809,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 ();
}
@@ -7936,11 +7985,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;
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 268f1c58d7d..5d352082b7c 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2856,6 +2856,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}}, \