ARM support for unordered FP operations.
authorRichard Earnshaw <rearnsha@gcc.gnu.org>
Tue, 15 Aug 2000 13:41:34 +0000 (13:41 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Tue, 15 Aug 2000 13:41:34 +0000 (13:41 +0000)
* 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

gcc/config/arm/arm.c
gcc/config/arm/arm.h

index 5d83e4b0175d3cf1507192f874e77deec68e5760..e905daeea747ce3b1fea2fc89dd61ac80588b7c3 100644 (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;
        }
index c45f86bfd5b8a764f8958f7f30ca4b6f584acf4e..04702f1134c47ad3486598042b874686cefe8ec7 100644 (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}},                                 \