diff options
author | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2000-08-15 13:41:34 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2000-08-15 13:41:34 +0000 |
commit | e45b72c408a765beb3687e966af9c946cd6c1330 (patch) | |
tree | 21a08ec005e530c8439d5c34a0ba5d2e0132b452 | |
parent | 05ed98a11fe00c67e745f36dfda87f346c3d8983 (diff) | |
download | gcc-e45b72c408a765beb3687e966af9c946cd6c1330.zip gcc-e45b72c408a765beb3687e966af9c946cd6c1330.tar.gz gcc-e45b72c408a765beb3687e966af9c946cd6c1330.tar.bz2 |
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
-rw-r--r-- | gcc/config/arm/arm.c | 58 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 3 |
2 files changed, 56 insertions, 5 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 5d83e4b..e905dae 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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; } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index c45f86b..04702f1 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -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}}, \ |