This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH 1/4 v2][AArch64] Generalize CCMP support


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.

Here it is again, hopefully no wrapping:

This patch series generalizes CCMP by adding FCCMP support and enabling more
optimizations. The first patch simplifies the representation of CCMP
patterns by using if-then-else which closely matches real instruction
semantics. As a result the existing special CC modes and functions are no
longer required. The condition of the CCMP is the if condition which
compares the previously set CC register. The then part does the compare like
a normal compare. The else part contains the integer value of the AArch64
condition that must be set if the if condition is false.

ChangeLog:
2015-11-12  Wilco Dijkstra  <wdijkstr@arm.com>

	* gcc/target.def (gen_ccmp_first): Update documentation.
	(gen_ccmp_next): Likewise.
	* gcc/doc/tm.texi (gen_ccmp_first): Update documentation.
	(gen_ccmp_next): Likewise.
	* gcc/ccmp.c (expand_ccmp_expr): Extract cmp_code from return value
of 
	expand_ccmp_expr_1.  Improve comments.
	* gcc/config/aarch64/aarch64.md (ccmp_and): Use if_then_else for
ccmp.
	(ccmp_ior<mode>): Remove pattern.
	(cmp<mode>): Remove expand.
	(cmp): Globalize pattern.
	(cstorecc4): Use cc_register.
	(mov<mode>cc): Remove ccmp_cc_register check.
	* gcc/config/aarch64/aarch64.c (aarch64_get_condition_code_1):
	Simplify after removal of CC_DNE/* modes.
	(aarch64_ccmp_mode_to_code): Remove.
	(aarch64_print_operand): Remove 'K' case.  Merge 'm' and 'M' cases.
	In 'k' case use integer as condition.
	(aarch64_nzcv_codes): Remove inverted cases.
	(aarch64_code_to_ccmode): Remove.
	(aarch64_gen_ccmp_first): Use cmp pattern directly.  Return the
correct 
	comparison with CC register to be used in folowing CCMP/branch/CSEL.
	(aarch64_gen_ccmp_next): Use previous comparison and mode in CCMP
	pattern.  Return the comparison with CC register.  Invert conditions
	when bitcode is OR.
	* gcc/config/aarch64/aarch64-modes.def: Remove CC_DNE/* modes.
	* gcc/config/aarch64/predicates.md (ccmp_cc_register): Remove.


---
 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 --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)
 
-- 
1.9.1




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]