diff mbox

[1/4,v2,AArch64] Generalize CCMP support

Message ID 000c01d127b5$80186020$80492060$@arm.com
State New
Headers show

Commit Message

Wilco Dijkstra Nov. 25, 2015, 7:14 p.m. UTC
> James Greenhalgh wrote:
> > Could you please repost this with the word-wrapping issues fixed.
> > I can't apply it to my tree for review or to commit it on your behalf in the current form.

So it looks like Outlook no longer supports sending emails without wrapping and the
maximum is only 132 characters... Now attached.

Wilco
---
 gcc/ccmp.c                           |  21 ++-
 gcc/config/aarch64/aarch64-modes.def |  10 --
 gcc/config/aarch64/aarch64.c         | 305 ++++++++---------------------------
 gcc/config/aarch64/aarch64.md        |  68 ++------
 gcc/config/aarch64/predicates.md     |  17 --
 gcc/doc/tm.texi                      |  36 ++---
 gcc/target.def                       |  36 ++---
 7 files changed, 128 insertions(+), 365 deletions(-)
diff mbox

Patch

diff --git a/gcc/ccmp.c b/gcc/ccmp.c
index 20348d9..58ac126 100644
--- a/gcc/ccmp.c
+++ b/gcc/ccmp.c
@@ -65,6 +65,10 @@  along with GCC; see the file COPYING3.  If not see
 	 - gen_ccmp_first expands the first compare in CCMP.
 	 - gen_ccmp_next expands the following compares.
 
+       Both hooks return a comparison with the CC register that is equivalent
+       to the value of the gimple comparison.  This is used by the next CCMP
+       and in the final conditional store.
+
      * We use cstorecc4 pattern to convert the CCmode intermediate to
        the integer mode result that expand_normal is expecting.
 
@@ -130,10 +134,12 @@  ccmp_candidate_p (gimple *g)
   return false;
 }
 
-/* PREV is the CC flag from precvious compares.  The function expands the
-   next compare based on G which ops previous compare with CODE.
+/* PREV is a comparison with the CC register which represents the
+   result of the previous CMP or CCMP.  The function expands the
+   next compare based on G which is ANDed/ORed with the previous
+   compare depending on CODE.
    PREP_SEQ returns all insns to prepare opearands for compare.
-   GEN_SEQ returnss all compare insns.  */
+   GEN_SEQ returns all compare insns.  */
 static rtx
 expand_ccmp_next (gimple *g, enum tree_code code, rtx prev,
 		  rtx *prep_seq, rtx *gen_seq)
@@ -226,7 +232,7 @@  expand_ccmp_expr_1 (gimple *g, rtx *prep_seq, rtx *gen_seq)
   return NULL_RTX;
 }
 
-/* Main entry to expand conditional compare statement G. 
+/* Main entry to expand conditional compare statement G.
    Return NULL_RTX if G is not a legal candidate or expand fail.
    Otherwise return the target.  */
 rtx
@@ -249,9 +255,10 @@  expand_ccmp_expr (gimple *g)
       enum insn_code icode;
       enum machine_mode cc_mode = CCmode;
       tree lhs = gimple_assign_lhs (g);
+      rtx_code cmp_code = GET_CODE (tmp);
 
 #ifdef SELECT_CC_MODE
-      cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx);
+      cc_mode = SELECT_CC_MODE (cmp_code, XEXP (tmp, 0), const0_rtx);
 #endif
       icode = optab_handler (cstore_optab, cc_mode);
       if (icode != CODE_FOR_nothing)
@@ -262,8 +269,8 @@  expand_ccmp_expr (gimple *g)
 	  emit_insn (prep_seq);
 	  emit_insn (gen_seq);
 
-	  tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
-			     0, tmp, const0_rtx, 1, mode);
+	  tmp = emit_cstore (target, icode, cmp_code, cc_mode, cc_mode,
+			     0, XEXP (tmp, 0), const0_rtx, 1, mode);
 	  if (tmp)
 	    return tmp;
 	}
diff --git a/gcc/config/aarch64/aarch64-modes.def b/gcc/config/aarch64/aarch64-modes.def
index 3bf3b2d..0c529e9 100644
--- a/gcc/config/aarch64/aarch64-modes.def
+++ b/gcc/config/aarch64/aarch64-modes.def
@@ -25,16 +25,6 @@  CC_MODE (CC_ZESWP); /* zero-extend LHS (but swap to make it RHS).  */
 CC_MODE (CC_SESWP); /* sign-extend LHS (but swap to make it RHS).  */
 CC_MODE (CC_NZ);    /* Only N and Z bits of condition flags are valid.  */
 CC_MODE (CC_Z);     /* Only Z bit of condition flags is valid.  */
-CC_MODE (CC_DNE);
-CC_MODE (CC_DEQ);
-CC_MODE (CC_DLE);
-CC_MODE (CC_DLT);
-CC_MODE (CC_DGE);
-CC_MODE (CC_DGT);
-CC_MODE (CC_DLEU);
-CC_MODE (CC_DLTU);
-CC_MODE (CC_DGEU);
-CC_MODE (CC_DGTU);
 
 /* Half-precision floating point for __fp16.  */
 FLOAT_MODE (HF, 2, 0);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 3bb4e64..c8bee3b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3907,7 +3907,6 @@  aarch64_get_condition_code (rtx x)
 static int
 aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code)
 {
-  int ne = -1, eq = -1;
   switch (mode)
     {
     case CCFPmode:
@@ -3930,56 +3929,6 @@  aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code)
 	}
       break;
 
-    case CC_DNEmode:
-      ne = AARCH64_NE;
-      eq = AARCH64_EQ;
-      break;
-
-    case CC_DEQmode:
-      ne = AARCH64_EQ;
-      eq = AARCH64_NE;
-      break;
-
-    case CC_DGEmode:
-      ne = AARCH64_GE;
-      eq = AARCH64_LT;
-      break;
-
-    case CC_DLTmode:
-      ne = AARCH64_LT;
-      eq = AARCH64_GE;
-      break;
-
-    case CC_DGTmode:
-      ne = AARCH64_GT;
-      eq = AARCH64_LE;
-      break;
-
-    case CC_DLEmode:
-      ne = AARCH64_LE;
-      eq = AARCH64_GT;
-      break;
-
-    case CC_DGEUmode:
-      ne = AARCH64_CS;
-      eq = AARCH64_CC;
-      break;
-
-    case CC_DLTUmode:
-      ne = AARCH64_CC;
-      eq = AARCH64_CS;
-      break;
-
-    case CC_DGTUmode:
-      ne = AARCH64_HI;
-      eq = AARCH64_LS;
-      break;
-
-    case CC_DLEUmode:
-      ne = AARCH64_LS;
-      eq = AARCH64_HI;
-      break;
-
     case CCmode:
       switch (comp_code)
 	{
@@ -4041,12 +3990,6 @@  aarch64_get_condition_code_1 (enum machine_mode mode, enum rtx_code comp_code)
       break;
     }
 
-  if (comp_code == NE)
-    return ne;
-
-  if (comp_code == EQ)
-    return eq;
-
   return -1;
 }
 
@@ -4087,69 +4030,27 @@  aarch64_const_vec_all_same_int_p (rtx x, HOST_WIDE_INT val)
 #define AARCH64_CC_Z (1 << 2)
 #define AARCH64_CC_N (1 << 3)
 
-/* N Z C V flags for ccmp.  The first code is for AND op and the other
-   is for IOR op.  Indexed by AARCH64_COND_CODE.  */
-static const int aarch64_nzcv_codes[][2] =
-{
-  {AARCH64_CC_Z, 0}, /* EQ, Z == 1.  */
-  {0, AARCH64_CC_Z}, /* NE, Z == 0.  */
-  {AARCH64_CC_C, 0}, /* CS, C == 1.  */
-  {0, AARCH64_CC_C}, /* CC, C == 0.  */
-  {AARCH64_CC_N, 0}, /* MI, N == 1.  */
-  {0, AARCH64_CC_N}, /* PL, N == 0.  */
-  {AARCH64_CC_V, 0}, /* VS, V == 1.  */
-  {0, AARCH64_CC_V}, /* VC, V == 0.  */
-  {AARCH64_CC_C, 0}, /* HI, C ==1 && Z == 0.  */
-  {0, AARCH64_CC_C}, /* LS, !(C == 1 && Z == 0).  */
-  {0, AARCH64_CC_V}, /* GE, N == V.  */
-  {AARCH64_CC_V, 0}, /* LT, N != V.  */
-  {0, AARCH64_CC_Z}, /* GT, Z == 0 && N == V.  */
-  {AARCH64_CC_Z, 0}, /* LE, !(Z == 0 && N == V).  */
-  {0, 0}, /* AL, Any.  */
-  {0, 0}, /* NV, Any.  */
+/* N Z C V flags for ccmp.  Indexed by AARCH64_COND_CODE.  */
+static const int aarch64_nzcv_codes[] =
+{
+  0,		/* EQ, Z == 1.  */
+  AARCH64_CC_Z,	/* NE, Z == 0.  */
+  0,		/* CS, C == 1.  */
+  AARCH64_CC_C,	/* CC, C == 0.  */
+  0,		/* MI, N == 1.  */
+  AARCH64_CC_N, /* PL, N == 0.  */
+  0,		/* VS, V == 1.  */
+  AARCH64_CC_V, /* VC, V == 0.  */
+  0,		/* HI, C ==1 && Z == 0.  */
+  AARCH64_CC_C,	/* LS, !(C == 1 && Z == 0).  */
+  AARCH64_CC_V,	/* GE, N == V.  */
+  0,		/* LT, N != V.  */
+  AARCH64_CC_Z, /* GT, Z == 0 && N == V.  */
+  0,		/* LE, !(Z == 0 && N == V).  */
+  0,		/* AL, Any.  */
+  0		/* NV, Any.  */
 };
 
-int
-aarch64_ccmp_mode_to_code (enum machine_mode mode)
-{
-  switch (mode)
-    {
-    case CC_DNEmode:
-      return NE;
-
-    case CC_DEQmode:
-      return EQ;
-
-    case CC_DLEmode:
-      return LE;
-
-    case CC_DGTmode:
-      return GT;
-
-    case CC_DLTmode:
-      return LT;
-
-    case CC_DGEmode:
-      return GE;
-
-    case CC_DLEUmode:
-      return LEU;
-
-    case CC_DGTUmode:
-      return GTU;
-
-    case CC_DLTUmode:
-      return LTU;
-
-    case CC_DGEUmode:
-      return GEU;
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
-
 void
 aarch64_print_operand (FILE *f, rtx x, char code)
 {
@@ -4248,36 +4149,17 @@  aarch64_print_operand (FILE *f, rtx x, char code)
       asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
       break;
 
-    case 'm':
-      {
-        int cond_code;
-        /* Print a condition (eq, ne, etc).  */
-
-        /* CONST_TRUE_RTX means always -- that's the default.  */
-        if (x == const_true_rtx)
-	  return;
-
-        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':
+    case 'm':
       {
         int cond_code;
-        /* Print the inverse of a condition (eq <-> ne, etc).  */
+	/* Print a condition (eq, ne, etc) or its inverse.  */
 
-        /* CONST_TRUE_RTX means never -- that's the default.  */
-        if (x == const_true_rtx)
+	/* CONST_TRUE_RTX means al/nv (al is the default, don't print it).  */
+	if (x == const_true_rtx)
 	  {
-	    fputs ("nv", f);
+	    if (code == 'M')
+	      fputs ("nv", f);
 	    return;
 	  }
 
@@ -4286,10 +4168,12 @@  aarch64_print_operand (FILE *f, rtx x, char code)
 	    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);
+	if (code == 'M')
+	  cond_code = AARCH64_INVERSE_CONDITION_CODE (cond_code);
+	fputs (aarch64_condition_codes[cond_code], f);
       }
       break;
 
@@ -4533,37 +4417,20 @@  aarch64_print_operand (FILE *f, rtx x, char code)
       output_addr_const (asm_out_file, x);
       break;
 
-    case 'K':
-      {
-	int cond_code;
-	/* Print nzcv.  */
-
-	if (!COMPARISON_P (x))
-	  {
-	    output_operand_lossage ("invalid operand for '%%%c'", code);
-	    return;
-	  }
-
-	cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
-	gcc_assert (cond_code >= 0);
-	asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][0]);
-      }
-      break;
-
     case 'k':
       {
-	int cond_code;
+	HOST_WIDE_INT cond_code;
 	/* Print nzcv.  */
 
-	if (!COMPARISON_P (x))
+	if (!CONST_INT_P (x))
 	  {
 	    output_operand_lossage ("invalid operand for '%%%c'", code);
 	    return;
 	  }
 
-	cond_code = aarch64_get_condition_code_1 (CCmode, GET_CODE (x));
-	gcc_assert (cond_code >= 0);
-	asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code][1]);
+	cond_code = INTVAL (x);
+	gcc_assert (cond_code >= 0 && cond_code <= AARCH64_NV);
+	asm_fprintf (f, "%d", aarch64_nzcv_codes[cond_code]);
       }
       break;
 
@@ -12500,60 +12367,16 @@  aarch64_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
   return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
 }
 
-static enum machine_mode
-aarch64_code_to_ccmode (enum rtx_code code)
-{
-  switch (code)
-    {
-    case NE:
-      return CC_DNEmode;
-
-    case EQ:
-      return CC_DEQmode;
-
-    case LE:
-      return CC_DLEmode;
-
-    case LT:
-      return CC_DLTmode;
-
-    case GE:
-      return CC_DGEmode;
-
-    case GT:
-      return CC_DGTmode;
-
-    case LEU:
-      return CC_DLEUmode;
-
-    case LTU:
-      return CC_DLTUmode;
-
-    case GEU:
-      return CC_DGEUmode;
-
-    case GTU:
-      return CC_DGTUmode;
-
-    default:
-      return CCmode;
-    }
-}
-
 static rtx
 aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
 			int code, tree treeop0, tree treeop1)
 {
-  enum machine_mode op_mode, cmp_mode, cc_mode;
-  rtx op0, op1, cmp, target;
+  machine_mode op_mode, cmp_mode, cc_mode = CCmode;
+  rtx op0, op1;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
-  enum insn_code icode;
+  insn_code icode;
   struct expand_operand ops[4];
 
-  cc_mode = aarch64_code_to_ccmode ((enum rtx_code) code);
-  if (cc_mode == CCmode)
-    return NULL_RTX;
-
   start_sequence ();
   expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
 
@@ -12580,8 +12403,8 @@  aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
       return NULL_RTX;
     }
 
-  op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
-  op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
+  op0 = prepare_operand (icode, op0, 0, op_mode, cmp_mode, unsignedp);
+  op1 = prepare_operand (icode, op1, 1, op_mode, cmp_mode, unsignedp);
   if (!op0 || !op1)
     {
       end_sequence ();
@@ -12590,16 +12413,11 @@  aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
   *prep_seq = get_insns ();
   end_sequence ();
 
-  cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
-  target = gen_rtx_REG (CCmode, CC_REGNUM);
-
-  create_output_operand (&ops[0], target, CCmode);
-  create_fixed_operand (&ops[1], cmp);
-  create_fixed_operand (&ops[2], op0);
-  create_fixed_operand (&ops[3], op1);
+  create_fixed_operand (&ops[0], op0);
+  create_fixed_operand (&ops[1], op1);
 
   start_sequence ();
-  if (!maybe_expand_insn (icode, 4, ops))
+  if (!maybe_expand_insn (icode, 2, ops))
     {
       end_sequence ();
       return NULL_RTX;
@@ -12607,22 +12425,20 @@  aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
   *gen_seq = get_insns ();
   end_sequence ();
 
-  return gen_rtx_REG (cc_mode, CC_REGNUM);
+  return gen_rtx_fmt_ee ((rtx_code) code, cc_mode,
+			 gen_rtx_REG (cc_mode, CC_REGNUM), const0_rtx);
 }
 
 static rtx
 aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
 		       tree treeop0, tree treeop1, int bit_code)
 {
-  rtx op0, op1, cmp0, cmp1, target;
-  enum machine_mode op_mode, cmp_mode, cc_mode;
+  rtx op0, op1, target;
+  machine_mode op_mode, cmp_mode, cc_mode = CCmode;
   int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
-  enum insn_code icode = CODE_FOR_ccmp_andsi;
+  insn_code icode;
   struct expand_operand ops[6];
-
-  cc_mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code);
-  if (cc_mode == CCmode)
-    return NULL_RTX;
+  int aarch64_cond;
 
   push_to_sequence ((rtx_insn*) *prep_seq);
   expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
@@ -12637,14 +12453,12 @@  aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
     case HImode:
     case SImode:
       cmp_mode = SImode;
-      icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_andsi
-						: CODE_FOR_ccmp_iorsi;
+      icode = CODE_FOR_ccmpsi;
       break;
 
     case DImode:
       cmp_mode = DImode;
-      icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_anddi
-						: CODE_FOR_ccmp_iordi;
+      icode = CODE_FOR_ccmpdi;
       break;
 
     default:
@@ -12663,15 +12477,22 @@  aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
   end_sequence ();
 
   target = gen_rtx_REG (cc_mode, CC_REGNUM);
-  cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, cmp_mode, op0, op1);
-  cmp0 = gen_rtx_fmt_ee (NE, cmp_mode, prev, const0_rtx);
+  aarch64_cond = aarch64_get_condition_code_1 (cc_mode, (rtx_code) cmp_code);
 
-  create_fixed_operand (&ops[0], prev);
+  if (bit_code != AND)
+    {
+      prev = gen_rtx_fmt_ee (REVERSE_CONDITION (GET_CODE (prev),
+						GET_MODE (XEXP (prev, 0))),
+			     VOIDmode, XEXP (prev, 0), const0_rtx);
+      aarch64_cond = AARCH64_INVERSE_CONDITION_CODE (aarch64_cond);
+    }
+
+  create_fixed_operand (&ops[0], XEXP (prev, 0));
   create_fixed_operand (&ops[1], target);
   create_fixed_operand (&ops[2], op0);
   create_fixed_operand (&ops[3], op1);
-  create_fixed_operand (&ops[4], cmp0);
-  create_fixed_operand (&ops[5], cmp1);
+  create_fixed_operand (&ops[4], prev);
+  create_fixed_operand (&ops[5], GEN_INT (aarch64_cond));
 
   push_to_sequence ((rtx_insn*) *gen_seq);
   if (!maybe_expand_insn (icode, 6, ops))
@@ -12683,7 +12504,7 @@  aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
   *gen_seq = get_insns ();
   end_sequence ();
 
-  return target;
+  return gen_rtx_fmt_ee ((rtx_code) cmp_code, VOIDmode, target, const0_rtx);
 }
 
 #undef TARGET_GEN_CCMP_FIRST
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index db1a19c..fab65c6 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -261,18 +261,17 @@ 
   ""
   "")
 
-(define_insn "ccmp_and<mode>"
-  [(set (match_operand 1 "ccmp_cc_register" "")
-	(compare
-	 (and:SI
+(define_insn "ccmp<mode>"
+  [(set (match_operand:CC 1 "cc_register" "")
+	(if_then_else:CC
 	  (match_operator 4 "aarch64_comparison_operator"
-	   [(match_operand 0 "ccmp_cc_register" "")
+	   [(match_operand 0 "cc_register" "")
 	    (const_int 0)])
-	  (match_operator 5 "aarch64_comparison_operator"
-	   [(match_operand:GPI 2 "register_operand" "r,r,r")
-	    (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
-	 (const_int 0)))]
-  "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
+	  (compare:CC
+	    (match_operand:GPI 2 "register_operand" "r,r,r")
+	    (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn"))
+	  (match_operand 5 "immediate_operand")))]
+  ""
   "@
    ccmp\\t%<w>2, %<w>3, %k5, %m4
    ccmp\\t%<w>2, %3, %k5, %m4
@@ -280,39 +279,6 @@ 
   [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
 )
 
-(define_insn "ccmp_ior<mode>"
-  [(set (match_operand 1 "ccmp_cc_register" "")
-	(compare
-	 (ior:SI
-	  (match_operator 4 "aarch64_comparison_operator"
-	   [(match_operand 0 "ccmp_cc_register" "")
-	    (const_int 0)])
-	  (match_operator 5 "aarch64_comparison_operator"
-	   [(match_operand:GPI 2 "register_operand" "r,r,r")
-	    (match_operand:GPI 3 "aarch64_ccmp_operand" "r,Uss,Usn")]))
-	 (const_int 0)))]
-  "aarch64_ccmp_mode_to_code (GET_MODE (operands[1])) == GET_CODE (operands[5])"
-  "@
-   ccmp\\t%<w>2, %<w>3, %K5, %M4
-   ccmp\\t%<w>2, %3, %K5, %M4
-   ccmn\\t%<w>2, #%n3, %K5, %M4"
-  [(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
-)
-
-(define_expand "cmp<mode>"
-  [(set (match_operand 0 "cc_register" "")
-        (match_operator:CC 1 "aarch64_comparison_operator"
-         [(match_operand:GPI 2 "register_operand" "")
-          (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
-  ""
-  {
-    operands[1] = gen_rtx_fmt_ee (COMPARE,
-				  SELECT_CC_MODE (GET_CODE (operands[1]),
-						  operands[2], operands[3]),
-				  operands[2], operands[3]);
-  }
-)
-
 ;; Expansion of signed mod by a power of 2 using CSNEG.
 ;; For x0 % n where n is a power of 2 produce:
 ;; negs   x1, x0
@@ -2816,7 +2782,7 @@ 
 ;; Comparison insns
 ;; -------------------------------------------------------------------
 
-(define_insn "*cmp<mode>"
+(define_insn "cmp<mode>"
   [(set (reg:CC CC_REGNUM)
 	(compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
 		    (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
@@ -2903,7 +2869,7 @@ 
 (define_expand "cstorecc4"
   [(set (match_operand:SI 0 "register_operand")
        (match_operator 1 "aarch64_comparison_operator"
-        [(match_operand 2 "ccmp_cc_register")
+	[(match_operand 2 "cc_register")
          (match_operand 3 "const0_operand")]))]
   ""
 "{
@@ -3072,19 +3038,15 @@ 
 			   (match_operand:ALLI 3 "register_operand" "")))]
   ""
   {
+    rtx ccreg;
     enum rtx_code code = GET_CODE (operands[1]);
 
     if (code == UNEQ || code == LTGT)
       FAIL;
 
-    if (!ccmp_cc_register (XEXP (operands[1], 0),
-			   GET_MODE (XEXP (operands[1], 0))))
-      {
-	rtx ccreg;
-	ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
-					 XEXP (operands[1], 1));
-	operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-      }
+    ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
+				     XEXP (operands[1], 1));
+    operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
   }
 )
 
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 046f852..f89fb61 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -43,23 +43,6 @@ 
   (ior (match_operand 0 "register_operand")
        (match_operand 0 "aarch64_ccmp_immediate")))
 
-(define_special_predicate "ccmp_cc_register"
-  (and (match_code "reg")
-       (and (match_test "REGNO (op) == CC_REGNUM")
-	    (ior (match_test "mode == GET_MODE (op)")
-		 (match_test "mode == VOIDmode
-			      && (GET_MODE (op) == CC_DNEmode
-				  || GET_MODE (op) == CC_DEQmode
-				  || GET_MODE (op) == CC_DLEmode
-				  || GET_MODE (op) == CC_DLTmode
-				  || GET_MODE (op) == CC_DGEmode
-				  || GET_MODE (op) == CC_DGTmode
-				  || GET_MODE (op) == CC_DLEUmode
-				  || GET_MODE (op) == CC_DLTUmode
-				  || GET_MODE (op) == CC_DGEUmode
-				  || GET_MODE (op) == CC_DGTUmode)"))))
-)
-
 (define_predicate "aarch64_simd_register"
   (and (match_code "reg")
        (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 3b1e2dc..3b7cec3 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11333,27 +11333,27 @@  modes and they have different conditional execution capability, such as ARM.
 
 @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (rtx *@var{prep_seq}, rtx *@var{gen_seq}, int @var{code}, tree @var{op0}, tree @var{op1})
 This function prepares to emit a comparison insn for the first compare in a
- sequence of conditional comparisions.  It returns a appropriate @code{CC}
- for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.  The insns to
- prepare the compare are saved in @var{prep_seq} and the compare insns are
- saved in @var{gen_seq}.  They will be emitted when all the compares in the
- the conditional comparision are generated without error.  @var{code} is
- the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
+ sequence of conditional comparisions.  It returns an appropriate comparison
+ with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
+ The insns to prepare the compare are saved in @var{prep_seq} and the compare
+ insns are saved in @var{gen_seq}.  They will be emitted when all the
+ compares in the the conditional comparision are generated without error.
+ @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
 @end deftypefn
 
 @deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx *@var{prep_seq}, rtx *@var{gen_seq}, rtx @var{prev}, int @var{cmp_code}, tree @var{op0}, tree @var{op1}, int @var{bit_code})
-This function prepare to emit a conditional comparison within a sequence of
- conditional comparisons.  It returns a appropriate @code{CC} for passing to
- @code{gen_ccmp_next} or @code{cbranch_optab}.  The insns to prepare the
- compare are saved in @var{prep_seq} and the compare insns are saved in
- @var{gen_seq}.  They will be emitted when all the compares in the conditional
- comparision are generated without error.  The @var{prev} expression is the
- result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}.  It
- may return @code{NULL} if the combination of @var{prev} and this comparison is
- not supported, otherwise the result must be appropriate for passing to
- @code{gen_ccmp_next} or @code{cbranch_optab}.  @var{code} is the
- @code{rtx_code} of the compare for @var{op0} and @var{op1}.  @var{bit_code}
- is @code{AND} or @code{IOR}, which is the op on the two compares.
+This function prepares to emit a conditional comparison within a sequence
+ of conditional comparisons.  It returns an appropriate comparison with
+ @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
+ The insns to prepare the compare are saved in @var{prep_seq} and the compare
+ insns are saved in @var{gen_seq}.  They will be emitted when all the
+ compares in the conditional comparision are generated without error.  The
+ @var{prev} expression is the result of a prior call to @code{gen_ccmp_first}
+ or @code{gen_ccmp_next}.  It may return @code{NULL} if the combination of
+ @var{prev} and this comparison is not supported, otherwise the result must
+ be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.
+ @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
+ @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the two compares.
 @end deftypefn
 
 @deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, struct loop *@var{loop})
diff --git a/gcc/target.def b/gcc/target.def
index 773b6ef..64892e0 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2605,29 +2605,29 @@  modes and they have different conditional execution capability, such as ARM.",
 DEFHOOK
 (gen_ccmp_first,
  "This function prepares to emit a comparison insn for the first compare in a\n\
- sequence of conditional comparisions.  It returns a appropriate @code{CC}\n\
- for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.  The insns to\n\
- prepare the compare are saved in @var{prep_seq} and the compare insns are\n\
- saved in @var{gen_seq}.  They will be emitted when all the compares in the\n\
- the conditional comparision are generated without error.  @var{code} is\n\
- the @code{rtx_code} of the compare for @var{op0} and @var{op1}.",
+ sequence of conditional comparisions.  It returns an appropriate comparison\n\
+ with @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
+ The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\
+ insns are saved in @var{gen_seq}.  They will be emitted when all the\n\
+ compares in the the conditional comparision are generated without error.\n\
+ @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.",
  rtx, (rtx *prep_seq, rtx *gen_seq, int code, tree op0, tree op1),
  NULL)
 
 DEFHOOK
 (gen_ccmp_next,
- "This function prepare to emit a conditional comparison within a sequence of\n\
- conditional comparisons.  It returns a appropriate @code{CC} for passing to\n\
- @code{gen_ccmp_next} or @code{cbranch_optab}.  The insns to prepare the\n\
- compare are saved in @var{prep_seq} and the compare insns are saved in\n\
- @var{gen_seq}.  They will be emitted when all the compares in the conditional\n\
- comparision are generated without error.  The @var{prev} expression is the\n\
- result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}.  It\n\
- may return @code{NULL} if the combination of @var{prev} and this comparison is\n\
- not supported, otherwise the result must be appropriate for passing to\n\
- @code{gen_ccmp_next} or @code{cbranch_optab}.  @var{code} is the\n\
- @code{rtx_code} of the compare for @var{op0} and @var{op1}.  @var{bit_code}\n\
- is @code{AND} or @code{IOR}, which is the op on the two compares.",
+ "This function prepares to emit a conditional comparison within a sequence\n\
+ of conditional comparisons.  It returns an appropriate comparison with\n\
+ @code{CC} for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
+ The insns to prepare the compare are saved in @var{prep_seq} and the compare\n\
+ insns are saved in @var{gen_seq}.  They will be emitted when all the\n\
+ compares in the conditional comparision are generated without error.  The\n\
+ @var{prev} expression is the result of a prior call to @code{gen_ccmp_first}\n\
+ or @code{gen_ccmp_next}.  It may return @code{NULL} if the combination of\n\
+ @var{prev} and this comparison is not supported, otherwise the result must\n\
+ be appropriate for passing to @code{gen_ccmp_next} or @code{cbranch_optab}.\n\
+ @var{code} is the @code{rtx_code} of the compare for @var{op0} and @var{op1}.\n\
+ @var{bit_code} is @code{AND} or @code{IOR}, which is the op on the two compares.",
  rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code),
  NULL)