[AArch64] Use CC_Z and CC_NZ with csinc and similar instructions.
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2014 15:53:08 +0000 (15:53 +0000)
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Sep 2014 15:53:08 +0000 (15:53 +0000)
* config/aarch64/predicates.md (aarch64_comparison_operation):
New special predicate.
* config/aarch64/aarch64.md (*csinc2<mode>_insn): Use
aarch64_comparison_operation instead of matching an operator.
Update operand numbers.
(csinc3<mode>_insn): Likewise.
(*csinv3<mode>_insn): Likewise.
(*csneg3<mode>_insn): Likewise.
(ffs<mode>2): Update gen_csinc3<mode>_insn callsite.
* config/aarch64/aarch64.c (aarch64_get_condition_code):
Return -1 instead of aborting on invalid condition codes.
(aarch64_print_operand): Update aarch64_get_condition_code callsites
to assert that the returned condition code is valid.
* config/aarch64/aarch64-protos.h (aarch64_get_condition_code): Export.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214824 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/predicates.md

index 910c04d..35148ff 100644 (file)
@@ -1,3 +1,20 @@
+2014-09-02  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/predicates.md (aarch64_comparison_operation):
+       New special predicate.
+       * config/aarch64/aarch64.md (*csinc2<mode>_insn): Use
+       aarch64_comparison_operation instead of matching an operator.
+       Update operand numbers.
+       (csinc3<mode>_insn): Likewise.
+       (*csinv3<mode>_insn): Likewise.
+       (*csneg3<mode>_insn): Likewise.
+       (ffs<mode>2): Update gen_csinc3<mode>_insn callsite.
+       * config/aarch64/aarch64.c (aarch64_get_condition_code):
+       Return -1 instead of aborting on invalid condition codes.
+       (aarch64_print_operand): Update aarch64_get_condition_code callsites
+       to assert that the returned condition code is valid.
+       * config/aarch64/aarch64-protos.h (aarch64_get_condition_code): Export.
+
 2014-09-02  Aldy Hernandez  <aldyh@redhat.com>
 
        * Makefile.in (TAGS): Handle constructs in common.opt, rtl.def,
index cca3bc9..6878f7d 100644 (file)
@@ -173,6 +173,7 @@ struct tune_params
 };
 
 HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
+int aarch64_get_condition_code (rtx);
 bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode);
 bool aarch64_cannot_change_mode_class (enum machine_mode,
                                       enum machine_mode,
index 3f66b8f..c48cdf0 100644 (file)
@@ -3587,7 +3587,7 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
   return CCmode;
 }
 
-static unsigned
+int
 aarch64_get_condition_code (rtx x)
 {
   enum machine_mode mode = GET_MODE (XEXP (x, 0));
@@ -3614,7 +3614,7 @@ aarch64_get_condition_code (rtx x)
        case UNLE: return AARCH64_LE;
        case UNGT: return AARCH64_HI;
        case UNGE: return AARCH64_PL;
-       default: gcc_unreachable ();
+       default: return -1;
        }
       break;
 
@@ -3631,7 +3631,7 @@ aarch64_get_condition_code (rtx x)
        case GTU: return AARCH64_HI;
        case LEU: return AARCH64_LS;
        case LTU: return AARCH64_CC;
-       default: gcc_unreachable ();
+       default: return -1;
        }
       break;
 
@@ -3650,7 +3650,7 @@ aarch64_get_condition_code (rtx x)
        case GTU: return AARCH64_CC;
        case LEU: return AARCH64_CS;
        case LTU: return AARCH64_HI;
-       default: gcc_unreachable ();
+       default: return -1;
        }
       break;
 
@@ -3661,7 +3661,7 @@ aarch64_get_condition_code (rtx x)
        case EQ: return AARCH64_EQ;
        case GE: return AARCH64_PL;
        case LT: return AARCH64_MI;
-       default: gcc_unreachable ();
+       default: return -1;
        }
       break;
 
@@ -3670,12 +3670,12 @@ aarch64_get_condition_code (rtx x)
        {
        case NE: return AARCH64_NE;
        case EQ: return AARCH64_EQ;
-       default: gcc_unreachable ();
+       default: return -1;
        }
       break;
 
     default:
-      gcc_unreachable ();
+      return -1;
       break;
     }
 }
@@ -3793,39 +3793,48 @@ aarch64_print_operand (FILE *f, rtx x, char code)
       break;
 
     case 'm':
-      /* Print a condition (eq, ne, etc).  */
-
-      /* CONST_TRUE_RTX means always -- that's the default.  */
-      if (x == const_true_rtx)
-       return;
+      {
+        int cond_code;
+        /* Print a condition (eq, ne, etc).  */
 
-      if (!COMPARISON_P (x))
-       {
-         output_operand_lossage ("invalid operand for '%%%c'", code);
+        /* CONST_TRUE_RTX means always -- that's the default.  */
+        if (x == const_true_rtx)
          return;
-       }
 
-      fputs (aarch64_condition_codes[aarch64_get_condition_code (x)], f);
+        if (!COMPARISON_P (x))
+         {
+           output_operand_lossage ("invalid operand for '%%%c'", code);
+           return;
+         }
+
+        cond_code = aarch64_get_condition_code (x);
+        gcc_assert (cond_code >= 0);
+        fputs (aarch64_condition_codes[cond_code], f);
+      }
       break;
 
     case 'M':
-      /* Print the inverse of a condition (eq <-> ne, etc).  */
-
-      /* CONST_TRUE_RTX means never -- that's the default.  */
-      if (x == const_true_rtx)
-       {
-         fputs ("nv", f);
-         return;
-       }
+      {
+        int cond_code;
+        /* Print the inverse of a condition (eq <-> ne, etc).  */
 
-      if (!COMPARISON_P (x))
-       {
-         output_operand_lossage ("invalid operand for '%%%c'", code);
-         return;
-       }
+        /* CONST_TRUE_RTX means never -- that's the default.  */
+        if (x == const_true_rtx)
+         {
+           fputs ("nv", f);
+           return;
+         }
 
-      fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE
-                                 (aarch64_get_condition_code (x))], f);
+        if (!COMPARISON_P (x))
+         {
+           output_operand_lossage ("invalid operand for '%%%c'", code);
+           return;
+         }
+        cond_code = aarch64_get_condition_code (x);
+        gcc_assert (cond_code >= 0);
+        fputs (aarch64_condition_codes[AARCH64_INVERSE_CONDITION_CODE
+                                       (cond_code)], f);
+      }
       break;
 
     case 'b':
index 1f7ab91..b5be79c 100644 (file)
 
 (define_insn "*csinc2<mode>_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
-        (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
-                 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
-                (match_operand:GPI 1 "register_operand" "r")))]
+        (plus:GPI (match_operand 2 "aarch64_comparison_operation" "")
+                  (match_operand:GPI 1 "register_operand" "r")))]
   ""
   "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
   [(set_attr "type" "csel")]
 (define_insn "csinc3<mode>_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
         (if_then_else:GPI
-         (match_operator:GPI 1 "aarch64_comparison_operator"
-          [(match_operand:CC 2 "cc_register" "") (const_int 0)])
-         (plus:GPI (match_operand:GPI 3 "register_operand" "r")
+         (match_operand 1 "aarch64_comparison_operation" "")
+         (plus:GPI (match_operand:GPI 2 "register_operand" "r")
                    (const_int 1))
-         (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+         (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
   ""
-  "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
+  "csinc\\t%<w>0, %<w>3, %<w>2, %M1"
   [(set_attr "type" "csel")]
 )
 
 (define_insn "*csinv3<mode>_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
         (if_then_else:GPI
-         (match_operator:GPI 1 "aarch64_comparison_operator"
-          [(match_operand:CC 2 "cc_register" "") (const_int 0)])
-         (not:GPI (match_operand:GPI 3 "register_operand" "r"))
-         (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+         (match_operand 1 "aarch64_comparison_operation" "")
+         (not:GPI (match_operand:GPI 2 "register_operand" "r"))
+         (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
   ""
-  "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
+  "csinv\\t%<w>0, %<w>3, %<w>2, %M1"
   [(set_attr "type" "csel")]
 )
 
 (define_insn "*csneg3<mode>_insn"
   [(set (match_operand:GPI 0 "register_operand" "=r")
         (if_then_else:GPI
-         (match_operator:GPI 1 "aarch64_comparison_operator"
-          [(match_operand:CC 2 "cc_register" "") (const_int 0)])
-         (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
-         (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
+         (match_operand 1 "aarch64_comparison_operation" "")
+         (neg:GPI (match_operand:GPI 2 "register_operand" "r"))
+         (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")))]
   ""
-  "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
+  "csneg\\t%<w>0, %<w>3, %<w>2, %M1"
   [(set_attr "type" "csel")]
 )
 
 
     emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
     emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
-    emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
+    emit_insn (gen_csinc3<mode>_insn (operands[0], x, operands[0], const0_rtx));
     DONE;
   }
 )
index 3dd83ca..c1510ca 100644 (file)
 (define_special_predicate "aarch64_comparison_operator"
   (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
 
+(define_special_predicate "aarch64_comparison_operation"
+  (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt")
+{
+  if (XEXP (op, 1) != const0_rtx)
+    return false;
+  rtx op0 = XEXP (op, 0);
+  if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
+    return false;
+  return aarch64_get_condition_code (op) >= 0;
+})
+
+
 ;; True if the operand is memory reference suitable for a load/store exclusive.
 (define_predicate "aarch64_sync_memory_operand"
   (and (match_operand 0 "memory_operand")