ping

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  <wdijk...@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

Reply via email to