ia64-protos.h: Update.
authorRichard Henderson <rth@cygnus.com>
Mon, 18 Sep 2000 19:03:37 +0000 (12:03 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 18 Sep 2000 19:03:37 +0000 (12:03 -0700)
* config/ia64/ia64-protos.h: Update.
* config/ia64/ia64.c (signed_inequality_operator): New.
(ia64_expand_compare): New.
(ia64_register_move_cost): Handle PR_REGS moves.
(ia64_secondary_reload_class): Require a GR when moving to a PR.
(struct reg_write_state): Add written_by_and/or.
(struct reg_flags): Add is_and/or.
(rws_update): Set them.
(rws_access_regno): Test them to allow parallel comparisons.
(rtx_needs_barrier): Recognize parallel comparisons.
(emit_insn_group_barriers): Set prev_insn after a call stop bit.
Call recog_memoized; ignore pred_rel_mutex.
(emit_predicate_relation_info): Don't call find_basic_blocks here.
(ia64_reorg): Do it here instead.
* config/ia64/ia64.h: s/CCmode/BImode/g
(MODES_TIEABLE_P): Don't tie BImode.
(PREFERRED_RELOAD_CLASS): Do not reload operations into AR regs.
(CONST_COSTS): Pick sensible values for CONST_INT based on context.
(RTX_COSTS): Make multiply 4 insns.
(MEMORY_MOVE_COST): New.
(PREDICATE_CODES): Update.
* config/ia64/ia64.md: s/CCmode/BImode/g
(movcci, movbi): New.
(andbi3, andcmbi3, iorbi3, iorcmbi3, one_cmplbi2): New.
(cmpsi_and_0, cmpsi_and_1, cmpsi_andnot_0, cmpsi_andnot_1): New.
(cmpdi_and_0, cmpdi_and_1, cmpdi_andnot_0, cmpdi_andnot_1): New.
(tbit_and_0, tbit_and_1, tbit_and_2, tbit_and_3): New.
(cmpsi_or_0, cmpsi_or_1, cmpsi_orcm_0, cmpsi_orcm_1): New.
(cmpdi_or_0, cmpdi_or_1, cmpdi_orcm_0, cmpdi_orcm_1): New.
(tbit_or_0, tbit_or_1, tbit_or_2, tbit_or_3): New.
(mulsi, muldi): Use xmpy not xma.
(cmpbi): New.
(movcc, movcc_internal): Remove.
(branch expanders): Use ia64_expand_compare.
(setcc expanders): Likewise.
(cmov insns): Use move_operand and ia64_move_ok.
(pred_rel_mutex): Use unspec not unspec_volatile.  Prevent the
scheduler from moving it past a use.
* config/ia64/build.hacks: Remove.

From-SVN: r36510

gcc/ChangeLog
gcc/config/ia64/build.hacks [deleted file]
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ia64/ia64.md

index b164a222cb683046d2d48715af84b6ef524ef127..4c0edc7a9ecc676d38760a8ca9419471dad6f1ce 100644 (file)
@@ -1,3 +1,45 @@
+2000-09-18  Richard Henderson  <rth@cygnus.com>
+
+       * config/ia64/ia64-protos.h: Update.
+       * config/ia64/ia64.c (signed_inequality_operator): New.
+       (ia64_expand_compare): New.
+       (ia64_register_move_cost): Handle PR_REGS moves.
+       (ia64_secondary_reload_class): Require a GR when moving to a PR.
+       (struct reg_write_state): Add written_by_and/or.
+       (struct reg_flags): Add is_and/or.
+       (rws_update): Set them.
+       (rws_access_regno): Test them to allow parallel comparisons.
+       (rtx_needs_barrier): Recognize parallel comparisons.
+       (emit_insn_group_barriers): Set prev_insn after a call stop bit.
+       Call recog_memoized; ignore pred_rel_mutex.
+       (emit_predicate_relation_info): Don't call find_basic_blocks here.
+       (ia64_reorg): Do it here instead.
+       * config/ia64/ia64.h: s/CCmode/BImode/g
+       (MODES_TIEABLE_P): Don't tie BImode.
+       (PREFERRED_RELOAD_CLASS): Do not reload operations into AR regs.
+       (CONST_COSTS): Pick sensible values for CONST_INT based on context.
+       (RTX_COSTS): Make multiply 4 insns.
+       (MEMORY_MOVE_COST): New.
+       (PREDICATE_CODES): Update.
+       * config/ia64/ia64.md: s/CCmode/BImode/g
+       (movcci, movbi): New.
+       (andbi3, andcmbi3, iorbi3, iorcmbi3, one_cmplbi2): New.
+       (cmpsi_and_0, cmpsi_and_1, cmpsi_andnot_0, cmpsi_andnot_1): New.
+       (cmpdi_and_0, cmpdi_and_1, cmpdi_andnot_0, cmpdi_andnot_1): New.
+       (tbit_and_0, tbit_and_1, tbit_and_2, tbit_and_3): New.
+       (cmpsi_or_0, cmpsi_or_1, cmpsi_orcm_0, cmpsi_orcm_1): New.
+       (cmpdi_or_0, cmpdi_or_1, cmpdi_orcm_0, cmpdi_orcm_1): New.
+       (tbit_or_0, tbit_or_1, tbit_or_2, tbit_or_3): New.
+       (mulsi, muldi): Use xmpy not xma.
+       (cmpbi): New.
+       (movcc, movcc_internal): Remove.
+       (branch expanders): Use ia64_expand_compare.
+       (setcc expanders): Likewise.
+       (cmov insns): Use move_operand and ia64_move_ok.
+       (pred_rel_mutex): Use unspec not unspec_volatile.  Prevent the
+       scheduler from moving it past a use.
+       * config/ia64/build.hacks: Remove.
+
 Mon 18-Sep-2000 19:21:35 BST  Neil Booth  <NeilB@earthling.net>
 
        * cpphash.h (HASHSTEP): Take character rather than pointer
diff --git a/gcc/config/ia64/build.hacks b/gcc/config/ia64/build.hacks
deleted file mode 100644 (file)
index 5da0d83..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-The gcse.c patch fixes an optimization problem.  This is probably not the right
-solution, but it was quick.  I will replace with a better solution later.
-
-The libio/libstdc++ patches are useful if you have a version of glibc without
-thread support.  There is no official ia64 glibc version yet, and some of the
-unofficial ones in common use are missing thread support.  libio/libstdc++
-assume that glibc always has thread support, so we need to patch them until
-the official ia64 glibc is available.
-
-Index: gcc/gcse.c
-===================================================================
-RCS file: /cvs/cvsfiles/devo/gcc/gcse.c,v
-retrieving revision 1.87
-diff -p -r1.87 gcse.c
-*** gcse.c     2000/01/11 14:59:28     1.87
---- gcse.c     2000/02/16 04:17:06
-*************** try_replace_reg (from, to, insn)
-*** 4039,4045 ****
-       information.  */
-    if (!success && !note)
-      {
-!       if (!set)
-       return 0;
-        note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
-                                                  copy_rtx (SET_SRC (set)),
---- 4039,4048 ----
-       information.  */
-    if (!success && !note)
-      {
-!       /* Don't add a REG_EQUAL note for a CCmode destination, because this
-!       confuses the code in cse.c that simplifies compare and branch
-!       instructions.  */
-!       if (!set || GET_MODE_CLASS (GET_MODE (SET_DEST (set))) == MODE_CC)
-       return 0;
-        note = REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL,
-                                                  copy_rtx (SET_SRC (set)),
-Index: libio/configure.in
-===================================================================
-RCS file: /cvs/cvsfiles/devo/libio/configure.in,v
-retrieving revision 1.57
-diff -p -r1.57 configure.in
-*** configure.in       1999/10/26 03:42:26     1.57
---- configure.in       2000/02/16 04:17:56
-*************** case "${target}" in
-*** 57,62 ****
---- 57,64 ----
-                frags="linux.mt linuxaxp1.mt mtsafe.mt" ;;
-    *-linux-gnulibc1)
-                frags=linuxlibc1.mt ;;
-+   # ??? glibc does not have thread support yet, so we can't use mtsafe.mt.
-+   ia64*-linux-gnu) frags="linux.mt" ;;
-    *-linux-gnu)   frags="linux.mt mtsafe.mt" ;;
-    *-sco3.2v[45]*)   frags=sco4.mt ;;
-    *-isc*)        frags=isc.mt ;;
-Index: libstdc++/configure.in
-===================================================================
-RCS file: /cvs/cvsfiles/devo/libstdc++/configure.in,v
-retrieving revision 1.46
-diff -p -r1.46 configure.in
-*** configure.in       1999/09/21 19:26:16     1.46
---- configure.in       2000/02/16 04:17:57
-*************** fi
-*** 89,94 ****
---- 89,96 ----
-  case "${target}" in
-    alpha*-*-linux-gnulibc1)   frags="${frags} linux.mt" ;;
-    powerpc*-*-linux-gnulibc1) frags="${frags} linux.mt" ;;
-+   # ??? ia64 glibc port does not have thread support yet.
-+   ia64*-*-linux-gnu)         ;;
-    *-*-linux-gnu)             frags="${frags} linux.mt" ;;
-    *-*-openbsd*)              
-       case "x${enable_threads}" in
-Index: libstdc++/stl/stl_config.h
-===================================================================
-RCS file: /cvs/cvsfiles/devo/libstdc++/stl/stl_config.h,v
-retrieving revision 1.17
-diff -p -r1.17 stl_config.h
-*** stl_config.h       1999/12/24 16:21:31     1.17
---- stl_config.h       2000/02/16 04:17:58
-***************
-*** 168,174 ****
-  #   if defined(__linux__)
-       /* glibc pre 2.0 is very buggy. We have to disable thread for it.
-          It should be upgraded to glibc 2.0 or later. */
-! #    if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS)
-  #      define __STL_PTHREADS
-  #      ifdef __STRICT_ANSI__
-           /* Work around a bug in the glibc 2.0.x pthread.h.  */
---- 168,175 ----
-  #   if defined(__linux__)
-       /* glibc pre 2.0 is very buggy. We have to disable thread for it.
-          It should be upgraded to glibc 2.0 or later. */
-!      /* ??? ia64 glibc port does not have thread support yet.  */
-! #    if !defined(_NOTHREADS) && __GLIBC__ >= 2 && defined(_G_USING_THUNKS) && !defined(__ia64__)
-  #      define __STL_PTHREADS
-  #      ifdef __STRICT_ANSI__
-           /* Work around a bug in the glibc 2.0.x pthread.h.  */
index d213b4180f8b8aeb6c057daaa5e3533debb037d6..7cde4ea8ca25c4d17c96d53a1ad1db7dcd6583d7 100644 (file)
@@ -56,6 +56,7 @@ extern int fetchadd_operand PARAMS((rtx, enum machine_mode));
 extern int fr_reg_or_fp01_operand PARAMS((rtx, enum machine_mode));
 extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
 extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
+extern int signed_inequality_operator PARAMS((rtx, enum machine_mode));
 extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode));
 extern int destination_operand PARAMS((rtx, enum machine_mode));
 extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
@@ -71,6 +72,7 @@ extern int ia64_depz_field_mask PARAMS((rtx, rtx));
 extern rtx ia64_gp_save_reg PARAMS((int));
 extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
 extern rtx spill_tfmode_operand PARAMS((rtx, int));
+extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
 
 extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
 extern void ia64_expand_prologue PARAMS((void));
index 57de975c8701fb217a6ecabc753a127977ce9f37..31c54bceb4ff4ae2af1358fc851a0739d78975d1 100644 (file)
@@ -115,7 +115,7 @@ static void ia64_add_gc_roots PARAMS ((void));
 static void ia64_init_machine_status PARAMS ((struct function *));
 static void ia64_mark_machine_status PARAMS ((struct function *));
 static void emit_insn_group_barriers PARAMS ((rtx));
-static void emit_predicate_relation_info PARAMS ((rtx));
+static void emit_predicate_relation_info PARAMS ((void));
 static int process_set PARAMS ((FILE *, rtx));
 
 static rtx ia64_expand_fetch_and_op PARAMS ((optab, enum machine_mode,
@@ -663,6 +663,19 @@ adjusted_comparison_operator (op, mode)
          && (code == LT || code == GE || code == LTU || code == GEU));
 }
 
+/* Return 1 if this is a signed inequality operator.  */
+
+int
+signed_inequality_operator (op, mode)
+    register rtx op;
+    enum machine_mode mode;
+{
+  enum rtx_code code = GET_CODE (op);
+  return ((mode == VOIDmode || GET_MODE (op) == mode)
+         && (code == GE || code == GT
+             || code == LE || code == LT));
+}
+
 /* Return 1 if OP is a call returning an HFA.  It is known to be a PARALLEL
    and the first section has already been tested.  */
 
@@ -1000,6 +1013,37 @@ spill_tfmode_operand (in, force)
   else
     return in;
 }
+
+/* Emit comparison instruction if necessary, returning the expression
+   that holds the compare result in the proper mode.  */
+
+rtx
+ia64_expand_compare (code, mode)
+     enum rtx_code code;
+     enum machine_mode mode;
+{
+  rtx op0 = ia64_compare_op0, op1 = ia64_compare_op1;
+  rtx cmp;
+
+  /* If we have a BImode input, then we already have a compare result, and
+     do not need to emit another comparison.  */
+  if (GET_MODE (op0) == BImode)
+    {
+      if ((code == NE || code == EQ) && op1 == const0_rtx)
+       cmp = op0;
+      else
+       abort ();
+    }
+  else
+    {
+      cmp = gen_reg_rtx (BImode);
+      emit_insn (gen_rtx_SET (VOIDmode, cmp,
+                             gen_rtx_fmt_ee (code, BImode, op0, op1)));
+      code = NE;
+    }
+
+  return gen_rtx_fmt_ee (code, mode, cmp, const0_rtx);
+}
 \f
 /* Begin the assembly file.  */
 
@@ -3247,6 +3291,7 @@ ia64_register_move_cost (from, to)
   int from_hard, to_hard;
   int from_gr, to_gr;
   int from_fr, to_fr;
+  int from_pr, to_pr;
 
   from_hard = (from == BR_REGS || from == AR_M_REGS || from == AR_I_REGS);
   to_hard = (to == BR_REGS || to == AR_M_REGS || to == AR_I_REGS);
@@ -3254,12 +3299,21 @@ ia64_register_move_cost (from, to)
   to_gr = (to == GENERAL_REGS);
   from_fr = (from == FR_REGS);
   to_fr = (to == FR_REGS);
+  from_pr = (from == PR_REGS);
+  to_pr = (to == PR_REGS);
 
   if (from_hard && to_hard)
     return 8;
   else if ((from_hard && !to_gr) || (!from_gr && to_hard))
     return 6;
 
+  /* Moving between PR registers takes two insns.  */
+  else if (from_pr && to_pr)
+    return 3;
+  /* Moving between PR and anything but GR is impossible.  */
+  else if ((from_pr && !to_gr) || (!from_gr && to_pr))
+    return 6;
+
   /* ??? Moving from FR<->GR must be more expensive than 2, so that we get
      secondary memory reloads for TFmode moves.  Unfortunately, we don't
      have the mode here, so we can't check that.  */
@@ -3335,7 +3389,7 @@ ia64_secondary_reload_class (class, mode, x)
       break;
 
     case PR_REGS:
-      /* ??? This happens if we cse/gcse a CCmode value across a call,
+      /* ??? This happens if we cse/gcse a BImode value across a call,
         and the function has a nonlocal goto.  This is because global
         does not allocate call crossing pseudos to hard registers when
         current_function_has_nonlocal_goto is true.  This is relatively
@@ -3343,6 +3397,11 @@ ia64_secondary_reload_class (class, mode, x)
         return NO_REGS and compile libstdc++.  */
       if (GET_CODE (x) == MEM)
        return GR_REGS;
+
+      /* This can happen when we take a BImode subreg of a DImode value,
+        and that DImode value winds up in some non-GR register.  */
+      if (regno >= 0 && ! GENERAL_REGNO_P (regno) && ! PR_REGNO_P (regno))
+       return GR_REGS;
       break;
 
     case GR_REGS:
@@ -3539,21 +3598,33 @@ ia64_override_options ()
 #define AR_UNAT_BIT_0  (FIRST_PSEUDO_REGISTER + 3)
 #define NUM_REGS       (AR_UNAT_BIT_0 + 64)
 
-/* For each register, we keep track of how many times it has been
-   written in the current instruction group.  If a register is written
-   unconditionally (no qualifying predicate), WRITE_COUNT is set to 2
-   and FIRST_PRED is ignored.  If a register is written if its
-   qualifying predicate P is true, we set WRITE_COUNT to 1 and
-   FIRST_PRED to P.  Later on, the same register may be written again
-   by the complement of P (P+1 if P is even, P-1, otherwise) and when
-   this happens, WRITE_COUNT gets set to 2.  The result of this is
-   that whenever an insn attempts to write a register whose
-   WRITE_COUNT is two, we need to issue a insn group barrier first.  */
+/* For each register, we keep track of how it has been written in the
+   current instruction group.
+
+   If a register is written unconditionally (no qualifying predicate),
+   WRITE_COUNT is set to 2 and FIRST_PRED is ignored.
+
+   If a register is written if its qualifying predicate P is true, we
+   set WRITE_COUNT to 1 and FIRST_PRED to P.  Later on, the same register
+   may be written again by the complement of P (P^1) and when this happens,
+   WRITE_COUNT gets set to 2.
+
+   The result of this is that whenever an insn attempts to write a register
+   whose WRITE_COUNT is two, we need to issue a insn group barrier first.
+
+   If a predicate register is written by a floating-point insn, we set
+   WRITTEN_BY_FP to true.
+
+   If a predicate register is written by an AND.ORCM we set WRITTEN_BY_AND
+   to true; if it was written by an OR.ANDCM we set WRITTEN_BY_OR to true.  */
+
 struct reg_write_state
 {
-  char write_count;
-  char written_by_fp;  /* Was register written by a floating-point insn?  */
-  short first_pred;    /* 0 means ``no predicate'' */
+  unsigned int write_count : 2;
+  unsigned int first_pred : 16;
+  unsigned int written_by_fp : 1;
+  unsigned int written_by_and : 1;
+  unsigned int written_by_or : 1;
 };
 
 /* Cumulative info for the current instruction group.  */
@@ -3569,6 +3640,8 @@ struct reg_flags
   unsigned int is_write : 1;   /* Is register being written?  */
   unsigned int is_fp : 1;      /* Is register used as part of an fp op?  */
   unsigned int is_branch : 1;  /* Is register used as part of a branch?  */
+  unsigned int is_and : 1;     /* Is register used as part of and.orcm?  */
+  unsigned int is_or : 1;      /* Is register used as part of or.andcm?  */
 };
 
 static void rws_update PARAMS ((struct reg_write_state *, int,
@@ -3589,6 +3662,9 @@ rws_update (rws, regno, flags, pred)
 {
   rws[regno].write_count += pred ? 1 : 2;
   rws[regno].written_by_fp |= flags.is_fp;
+  /* ??? Not tracking and/or across differing predicates.  */
+  rws[regno].written_by_and = flags.is_and;
+  rws[regno].written_by_or = flags.is_or;
   rws[regno].first_pred = pred;
 }
 
@@ -3607,6 +3683,9 @@ rws_access_regno (regno, flags, pred)
   if (regno >= NUM_REGS)
     abort ();
 
+  if (! PR_REGNO_P (regno))
+    flags.is_and = flags.is_or = 0;
+
   if (flags.is_write)
     {
       int write_count;
@@ -3631,7 +3710,11 @@ rws_access_regno (regno, flags, pred)
             not a complementary predicate, then we need a barrier.  */
          /* ??? This assumes that P and P+1 are always complementary
             predicates for P even.  */
-         if ((rws_sum[regno].first_pred ^ 1) != pred)
+         if (flags.is_and && rws_sum[regno].written_by_and)
+           ; 
+         else if (flags.is_or && rws_sum[regno].written_by_or)
+           ;
+         else if ((rws_sum[regno].first_pred ^ 1) != pred)
            need_barrier = 1;
          rws_update (rws_sum, regno, flags, pred);
          break;
@@ -3639,7 +3722,14 @@ rws_access_regno (regno, flags, pred)
        case 2:
          /* The register has been unconditionally written already.  We
             need a barrier.  */
-         need_barrier = 1;
+         if (flags.is_and && rws_sum[regno].written_by_and)
+           ;
+         else if (flags.is_or && rws_sum[regno].written_by_or)
+           ;
+         else
+           need_barrier = 1;
+         rws_sum[regno].written_by_and = flags.is_and;
+         rws_sum[regno].written_by_or = flags.is_or;
          break;
 
        default:
@@ -3669,6 +3759,11 @@ rws_access_regno (regno, flags, pred)
            return 0;
        }
 
+      if (flags.is_and && rws_sum[regno].written_by_and)
+       return 0;
+      if (flags.is_or && rws_sum[regno].written_by_or)
+       return 0;
+
       switch (rws_sum[regno].write_count)
        {
        case 0:
@@ -3806,6 +3901,15 @@ rtx_needs_barrier (x, flags, pred)
               with a floating point comparison when processing the
               destination of the SET.  */
            new_flags.is_fp = 1;
+
+         /* Discover if this is a parallel comparison.  We only handle
+            and.orcm and or.andcm at present, since we must retain a
+            strict inverse on the predicate pair.  */
+         else if (GET_CODE (src) == AND)
+           new_flags.is_and = flags.is_and = 1;
+         else if (GET_CODE (src) == IOR)
+           new_flags.is_or = flags.is_or = 1;
+
          break;
        }
       need_barrier = rtx_needs_barrier (src, flags, pred);
@@ -3991,6 +4095,7 @@ rtx_needs_barrier (x, flags, pred)
          need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
          break;
 
+       case 7: /* pred_rel_mutex */
         case 12: /* mf */
         case 19: /* fetchadd_acq */
        case 20: /* mov = ar.bsp */
@@ -4162,6 +4267,8 @@ emit_insn_group_barriers (insns)
              memset (rws_sum, 0, sizeof (rws_sum));
              prev_insn = NULL_RTX;
            }
+         else
+           prev_insn = insn;
          break;
        
        case JUMP_INSN:
@@ -4179,7 +4286,7 @@ emit_insn_group_barriers (insns)
              rtx pat = PATTERN (insn);
 
              /* Ug.  Hack hacks hacked elsewhere.  */
-             switch (INSN_CODE (insn))
+             switch (recog_memoized (insn))
                {
                  /* We play dependency tricks with the epilogue in order
                     to get proper schedules.  Undo this for dv analysis.  */
@@ -4205,6 +4312,10 @@ emit_insn_group_barriers (insns)
                  pat = XVECEXP (pat, 0, 0);
                  break;
 
+                 /* Doesn't generate code.  */
+               case CODE_FOR_pred_rel_mutex:
+                 continue;
+
                default:
                  break;
                }
@@ -4250,15 +4361,10 @@ emit_insn_group_barriers (insns)
    straight-line code.  */
 
 static void
-emit_predicate_relation_info (insns)
-     rtx insns;
+emit_predicate_relation_info ()
 {
   int i;
 
-  /* Make sure the CFG and global_live_at_start are correct.  */
-  find_basic_blocks (insns, max_reg_num (), NULL);
-  life_analysis (insns, NULL, 0);
-
   for (i = n_basic_blocks - 1; i >= 0; --i)
     {
       basic_block bb = BASIC_BLOCK (i);
@@ -4275,7 +4381,7 @@ emit_predicate_relation_info (insns)
       for (r = PR_REG (0); r < PR_REG (64); r += 2)
        if (REGNO_REG_SET_P (bb->global_live_at_start, r))
          {
-           rtx p = gen_rtx_REG (CCmode, r);
+           rtx p = gen_rtx_REG (BImode, r);
            rtx n = emit_insn_after (gen_pred_rel_mutex (p), head);
            if (head == bb->end)
              bb->end = n;
@@ -4323,8 +4429,13 @@ ia64_reorg (insns)
   if (optimize == 0)
     split_all_insns (0);
 
-  emit_predicate_relation_info (insns);
+  /* Make sure the CFG and global_live_at_start are correct
+     for emit_predicate_relation_info.  */
+  find_basic_blocks (insns, max_reg_num (), NULL);
+  life_analysis (insns, NULL, 0);
+
   emit_insn_group_barriers (insns);
+  emit_predicate_relation_info ();
 }
 \f
 /* Return true if REGNO is used by the epilogue.  */
index 1f975f3913dd139cd2cca1c16b08489e15efb71c..f2402a38ea430c90eba4450f84babbc5f0b2dbcf 100644 (file)
@@ -813,13 +813,13 @@ while (0)
 /* A C expression for the number of consecutive hard registers, starting at
    register number REGNO, required to hold a value of mode MODE.  */
 
-/* ??? We say that CCmode values require two registers.  This allows us to
+/* ??? We say that BImode PR values require two registers.  This allows us to
    easily store the normal and inverted values.  We use CCImode to indicate
    a single predicate register.  */
 
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
   ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64                      \
-   : PR_REGNO_P (REGNO) && (MODE) == CCmode ? 2                                \
+   : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2                                \
    : PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1                       \
    : FR_REGNO_P (REGNO) && (MODE) == TFmode ? 1                                \
    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -828,12 +828,14 @@ while (0)
    MODE in hard register number REGNO (or in several registers starting with
    that one).  */
 
-#define HARD_REGNO_MODE_OK(REGNO, MODE)                                        \
-  (FR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) != MODE_CC && (MODE) != TImode \
-   : PR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC             \
-   : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode                \
-   : AR_REGNO_P (REGNO) ? (MODE) == DImode                             \
-   : BR_REGNO_P (REGNO) ? (MODE) == DImode                             \
+#define HARD_REGNO_MODE_OK(REGNO, MODE)                                \
+  (FR_REGNO_P (REGNO) ?                                                \
+     GET_MODE_CLASS (MODE) != MODE_CC && (MODE) != TImode && (MODE) != BImode \
+   : PR_REGNO_P (REGNO) ?                                      \
+     (MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC      \
+   : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode        \
+   : AR_REGNO_P (REGNO) ? (MODE) == DImode                     \
+   : BR_REGNO_P (REGNO) ? (MODE) == DImode                     \
    : 0)
 
 /* A C expression that is nonzero if it is desirable to choose register
@@ -843,22 +845,13 @@ while (0)
    If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
    ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
    zero.  */
-/* ??? If the comments are true, then this must be zero if one mode is CCmode,
-   INTEGRAL_MODE_P or FLOAT_MODE_P and the other is not.  Otherwise, it is
-   true.  */
 /* Don't tie integer and FP modes, as that causes us to get integer registers
    allocated for FP instructions.  TFmode only supported in FP registers so
    we can't tie it with any other modes.  */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
-  ((GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) \
-   && (((MODE1) == TFmode) == ((MODE2) == TFmode)))
-
-/* Define this macro if the compiler should avoid copies to/from CCmode
-   registers.  You should only define this macro if support fo copying to/from
-   CCmode is incomplete.  */
-/* ??? CCmode copies are very expensive, so we might want this defined.  */
-/* #define AVOID_CCMODE_COPIES */
-
+#define MODES_TIEABLE_P(MODE1, MODE2)                  \
+  (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)    \
+   && (((MODE1) == TFmode) == ((MODE2) == TFmode))     \
+   && (((MODE1) == BImode) == ((MODE2) == BImode)))
 \f
 /* Handling Leaf Functions */
 
@@ -910,9 +903,8 @@ enum reg_class
 /* An initializer containing the names of the register classes as C string
    constants.  These names are used in writing some of the debugging dumps.  */
 #define REG_CLASS_NAMES \
-{ "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", \
-  "FR_REGS", "GR_AND_FR_REGS", "AR_M_REGS", "AR_I_REGS", \
-  "ALL_REGS" }
+{ "NO_REGS", "PR_REGS", "BR_REGS", "ADDL_REGS", "GR_REGS", "FR_REGS", \
+  "GR_AND_FR_REGS", "AR_M_REGS", "AR_I_REGS", "ALL_REGS" }
 
 /* An initializer containing the contents of the register classes, as integers
    which are bit masks.  The Nth integer specifies the contents of class N.
@@ -1022,11 +1014,13 @@ enum reg_class
 
 /* Don't allow volatile mem reloads into floating point registers.  This
    is defined to force reload to choose the r/m case instead of the f/f case
-   when reloading (set (reg fX) (mem/v)).  */
+   when reloading (set (reg fX) (mem/v)).
+
+   Do not reload expressions into AR regs.  */
 
 #define PREFERRED_RELOAD_CLASS(X, CLASS) \
-  ((CLASS == FR_REGS && GET_CODE (X) == MEM && MEM_VOLATILE_P (X))     \
-   ? NO_REGS                                                           \
+  (CLASS == FR_REGS && GET_CODE (X) == MEM && MEM_VOLATILE_P (X) ? NO_REGS   \
+   : GET_RTX_CLASS (GET_CODE (X)) != 'o' && CLASS > GR_AND_FR_REGS ? NO_REGS \
    : CLASS)
 
 /* You should define this macro to indicate to the reload phase that it may
@@ -1061,7 +1055,7 @@ enum reg_class
    This is closely related to the macro `HARD_REGNO_NREGS'.  */
 
 #define CLASS_MAX_NREGS(CLASS, MODE) \
-  ((MODE) == CCmode && (CLASS) == PR_REGS ? 2                  \
+  ((MODE) == BImode && (CLASS) == PR_REGS ? 2                  \
    : ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1              \
    : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
@@ -1823,29 +1817,49 @@ do {                                                                    \
 
 /* ??? This is incomplete.  */
 
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
+#define CONST_COSTS(X, CODE, OUTER_CODE)                               \
   case CONST_INT:                                                      \
     if ((X) == const0_rtx)                                             \
       return 0;                                                                \
+    switch (OUTER_CODE)                                                        \
+      {                                                                        \
+      case SET:                                                                \
+       return CONST_OK_FOR_J (INTVAL (X)) ? 0 : COSTS_N_INSNS (1);     \
+      case PLUS:                                                       \
+       if (CONST_OK_FOR_I (INTVAL (X)))                                \
+         return 0;                                                     \
+       if (CONST_OK_FOR_J (INTVAL (X)))                                \
+         return 1;                                                     \
+       return COSTS_N_INSNS (1);                                       \
+      default:                                                         \
+       if (CONST_OK_FOR_K (INTVAL (X)) || CONST_OK_FOR_L (INTVAL (X))) \
+         return 0;                                                     \
+       return COSTS_N_INSNS (1);                                       \
+      }                                                                        \
   case CONST_DOUBLE:                                                   \
+    return COSTS_N_INSNS (1);                                          \
   case CONST:                                                          \
   case SYMBOL_REF:                                                     \
   case LABEL_REF:                                                      \
-    return COSTS_N_INSNS (1);
+    return COSTS_N_INSNS (2);
 
 /* Like `CONST_COSTS' but applies to nonconstant RTL expressions.  */
 
-/* ??? Should define this to get better optimized code.  */
-
-/* We make divide expensive, so that divide-by-constant will be optimized to
-   a multiply.  */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
+#define RTX_COSTS(X, CODE, OUTER_CODE)                                 \
+  case MULT:                                                           \
+    /* For multiplies wider than HImode, we have to go to the FPU,     \
+       which normally involves copies.  Plus there's the latency       \
+       of the multiply itself.  */                                     \
+    if (GET_MODE_SIZE (GET_MODE (X)) > 2)                              \
+      return COSTS_N_INSNS (4);                                                \
+    return COSTS_N_INSNS (1);                                          \
   case DIV:                                                            \
   case UDIV:                                                           \
   case MOD:                                                            \
   case UMOD:                                                           \
-    return COSTS_N_INSNS (20);
+    /* We make divide expensive, so that divide-by-constant will be    \
+       optimized to a multiply.  */                                    \
+    return COSTS_N_INSNS (60);
 
 /* An expression giving the cost of an addressing mode that contains ADDRESS.
    If not defined, the cost is computed from the ADDRESS expression and the
@@ -1859,10 +1873,10 @@ do {                                                                    \
 #define REGISTER_MOVE_COST(FROM, TO) \
   ia64_register_move_cost((FROM), (TO))
 
-/* A C expression for the cost of moving data of mode M between a register and
-   memory.  */
-/* ??? Investigate.  Might get better code by defining this.  */
-/* #define MEMORY_MOVE_COST(M,C,I) */
+/* A C expression for the cost of moving data of mode M between a
+   register and memory.  */
+#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
+  ((CLASS) == GENERAL_REGS || (CLASS) == FR_REGS ? 4 : 10)
 
 /* A C expression for the cost of a branch instruction.  A value of 1 is the
    default; other values are interpreted relative to that.  Used by the 
@@ -2682,6 +2696,7 @@ do {                                                                      \
 { "fr_reg_or_fp01_operand", {SUBREG, REG, CONST_DOUBLE}},              \
 { "normal_comparison_operator", {EQ, NE, GT, LE, GTU, LEU}},           \
 { "adjusted_comparison_operator", {LT, GE, LTU, GEU}},                 \
+{ "signed_inequality_operator", {GE, GT, LE, LT}},                     \
 { "call_multiple_values_operation", {PARALLEL}},                       \
 { "predicate_operator", {NE, EQ}},                                     \
 { "ar_lc_reg_operand", {REG}},                                         \
index 704959222d24a98a44857e380f8d721e4af5f706..45479a22c771d82801fb0669e6ba86c67ea60fb1 100644 (file)
@@ -60,6 +60,7 @@
 ;;     3       fr_spill
 ;;     4       fr_restore
 ;;     5       recip_approx
+;;     7       pred_rel_mutex
 ;;     8       popcnt
 ;;     12      mf
 ;;     13      cmpxchg_acq
@@ -72,7 +73,6 @@
 ;;     1       blockage
 ;;     2       insn_group_barrier
 ;;     5       set_bsp
-;;     7       pred.rel.mutex
 ;;     8       pred.safe_across_calls all
 ;;     9       pred.safe_across_calls normal
 \f
 ;; ::
 ;; ::::::::::::::::::::
 
+;; Set of a single predicate register.  This is only used to implement
+;; pr-to-pr move and complement.
+
+(define_insn "*movcci"
+  [(set (match_operand:CCI 0 "register_operand" "=c,c,c")
+       (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))]
+  ""
+  "@
+   cmp.ne %0, p0 = r0, r0
+   cmp.eq %0, p0 = r0, r0
+   (%1) cmp.eq.unc %0, p0 = r0, r0"
+  [(set_attr "type" "A")
+   (set_attr "predicable" "no")])
+
+(define_insn "movbi"
+  [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m")
+       (match_operand:BI 1 "move_operand"         " O,n, c,  c,*r, n,*m,*r"))]
+  ""
+  "@
+   cmp.ne %0, %I0 = r0, r0
+   cmp.eq %0, %I0 = r0, r0
+   #
+   #
+   tbit.nz %0, %I0 = %1, 0
+   adds %0 = %1, r0
+   ld1%O1 %0 = %1%P1
+   st1%Q0 %0 = %1%P0"
+  [(set_attr "type" "A,A,unknown,unknown,I,A,M,M")])
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (match_operand:BI 1 "register_operand" ""))]
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
+  [(cond_exec (ne (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 1)))
+   (cond_exec (eq (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 0)))]
+  "")
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (match_operand:BI 1 "register_operand" ""))]
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
+  [(set (match_dup 2) (match_dup 4))
+   (set (match_dup 3) (match_dup 5))
+   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
+  "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0]));
+   operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1);
+   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1]));
+   operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);")
+
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
        (match_operand:QI 1 "general_operand" ""))]
 (define_insn "*movqicc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c,c")
         (const_int 0)])
      (set (match_operand:QI 0 "register_operand"  "=r,r, r,*f,*f")
          (match_operand:QI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
 (define_insn "*movhicc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c,c")
         (const_int 0)])
      (set (match_operand:HI 0 "register_operand"  "=r,r, r,*f,*f")
          (match_operand:HI 1 "nonmemory_operand" "rO,J,*f,rO,*f")))]
 (define_insn "*movsicc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c,c,c,c,c")
         (const_int 0)])
      (set (match_operand:SI 0 "register_operand"  "=r,r,r, r,*f,*f, r,*d")
          (match_operand:SI 1 "nonmemory_operand" "rO,J,i,*f,rO,*f,*d,rK")))]
 (define_insn ""
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c,c,c,c,c,c,c,c")
         (const_int 0)])
      (set (match_operand:DI 0 "register_operand"
                              "=r,r,r, r,*f,*f,   r,*b,*e, r,*d")
 (define_insn "*movsfcc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c")
         (const_int 0)])
      (set (match_operand:SF 0 "register_operand"  "=f,*r, f,*r")
          (match_operand:SF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
 (define_insn "*movdfcc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c,c,c,c")
+       [(match_operand:BI 3 "register_operand" "c,c,c,c")
         (const_int 0)])
      (set (match_operand:DF 0 "register_operand"  "=f,*r, f,*r")
          (match_operand:DF 1 "nonmemory_operand" "fG,fG,*r,*r")))]
 (define_insn "*movtfcc_astep"
   [(cond_exec
      (match_operator 2 "predicate_operator"
-       [(match_operand:CC 3 "register_operand" "c")
+       [(match_operand:BI 3 "register_operand" "c")
         (const_int 0)])
      (set (match_operand:TF 0 "register_operand"  "=f")
          (match_operand:TF 1 "nonmemory_operand" "fG")))]
 \f
 ;; ::::::::::::::::::::
 ;; ::
+;; :: 1 bit Integer arithmetic
+;; ::
+;; ::::::::::::::::::::
+
+(define_insn_and_split "andbi3"
+  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
+       (and:BI (match_operand:BI 1 "register_operand" "%0,0,r")
+               (match_operand:BI 2 "register_operand" "c,r,r")))]
+  ""
+  "@
+   #
+   tbit.nz.and.orcm %0, %I0 = %2, 0
+   and %0 = %2, %1"
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
+  [(cond_exec (eq (match_dup 2) (const_int 0))
+     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
+                               (match_dup 0))))]
+  ""
+  [(set_attr "type" "unknown,I,A")])
+
+(define_insn_and_split "*andcmbi3"
+  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
+       (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r"))
+               (match_operand:BI 2 "register_operand" "0,0,r")))]
+  ""
+  "@
+   #
+   tbit.z.and.orcm %0, %I0 = %2, 0
+   andcm %0 = %2, %1"
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
+  [(cond_exec (ne (match_dup 1) (const_int 0))
+     (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0))
+                               (match_dup 0))))]
+  ""
+  [(set_attr "type" "unknown,I,A")])
+
+(define_insn_and_split "iorbi3"
+  [(set (match_operand:BI 0 "register_operand" "=c,c,r")
+       (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r")
+               (match_operand:BI 2 "register_operand" "c,r,r")))]
+  ""
+  "@
+   #
+   tbit.nz.or.andcm %0, %I0 = %2, 0
+   or %0 = %2, %1"
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
+  [(cond_exec (ne (match_dup 2) (const_int 0))
+     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
+                               (match_dup 0))))]
+  ""
+  [(set_attr "type" "unknown,I,A")])
+
+(define_insn_and_split "*iorcmbi3"
+  [(set (match_operand:BI 0 "register_operand" "=c,c")
+       (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r"))
+               (match_operand:BI 2 "register_operand" "0,0")))]
+  ""
+  "@
+   #
+   tbit.z.or.andcm %0, %I0 = %2, 0"
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))"
+  [(cond_exec (eq (match_dup 1) (const_int 0))
+     (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0))
+                               (match_dup 0))))]
+  ""
+  [(set_attr "type" "unknown,I")])
+
+(define_insn "one_cmplbi2"
+  [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c")
+       (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c")))
+   (clobber (match_scratch:BI 2 "=X,X,c,X"))]
+  ""
+  "@
+   tbit.z %0, %I0 = %1, 0
+   xor %0 = 1, %1
+   #
+   #"
+  [(set_attr "type" "I,A,unknown,unknown")])
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (not:BI (match_operand:BI 1 "register_operand" "")))
+   (clobber (match_scratch:BI 2 ""))]
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
+   && rtx_equal_p (operands[0], operands[1])"
+  [(set (match_dup 4) (match_dup 3))
+   (set (match_dup 0) (const_int 1))
+   (cond_exec (ne (match_dup 2) (const_int 0))
+     (set (match_dup 0) (const_int 0)))
+   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
+  "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1]));
+   operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));")
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (not:BI (match_operand:BI 1 "register_operand" "")))
+   (clobber (match_scratch:BI 2 ""))]
+  "reload_completed
+   && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0]))
+   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))
+   && ! rtx_equal_p (operands[0], operands[1])"
+  [(cond_exec (ne (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 0)))
+   (cond_exec (eq (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 1)))
+   (set (match_dup 0) (unspec:BI [(match_dup 0)] 7))]
+  "")
+
+(define_insn "*cmpsi_and_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (match_operator:BI 4 "predicate_operator"
+                 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
+                  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C4.and.orcm %0, %I0 = %3, %r2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_and_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (match_operator:BI 3 "signed_inequality_operator"
+                 [(match_operand:SI 2 "gr_register_operand" "r")
+                  (const_int 0)])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C3.and.orcm %0, %I0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_andnot_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
+                        [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
+                         (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C4.or.andcm %I0, %0 = %3, %r2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_andnot_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
+                         [(match_operand:SI 2 "gr_register_operand" "r")
+                          (const_int 0)]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C3.or.andcm %I0, %0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_and_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (match_operator:BI 4 "predicate_operator"
+                 [(match_operand:DI 2 "gr_register_operand" "r")
+                  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C4.and.orcm %0, %I0 = %3, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_and_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (match_operator:BI 3 "signed_inequality_operator"
+                 [(match_operand:DI 2 "gr_register_operand" "r")
+                  (const_int 0)])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C3.and.orcm %0, %I0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_andnot_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (not:BI (match_operator:BI 4 "predicate_operator"
+                        [(match_operand:DI 2 "gr_register_operand" "r")
+                         (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C4.or.andcm %I0, %0 = %3, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_andnot_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
+                         [(match_operand:DI 2 "gr_register_operand" "r")
+                          (const_int 0)]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C3.or.andcm %I0, %0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*tbit_and_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
+                              (const_int 1))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.nz.and.orcm %0, %I0 = %1, 0"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_and_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
+                              (const_int 1))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.z.and.orcm %0, %I0 = %1, 0"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_and_2"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (ne:BI (zero_extract:DI
+                        (match_operand:DI 1 "gr_register_operand" "r")
+                        (const_int 1)
+                        (match_operand:DI 2 "const_int_operand" "n"))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.nz.and.orcm %0, %I0 = %1, %2"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_and_3"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (and:BI (eq:BI (zero_extract:DI
+                        (match_operand:DI 1 "gr_register_operand" "r")
+                        (const_int 1)
+                        (match_operand:DI 2 "const_int_operand" "n"))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.z.and.orcm %0, %I0 = %1, %2"
+  [(set_attr "type" "I")])
+
+(define_insn "*cmpsi_or_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (match_operator:BI 4 "predicate_operator"
+                 [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
+                  (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C4.or.andcm %0, %I0 = %3, %r2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_or_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (match_operator:BI 3 "signed_inequality_operator"
+                 [(match_operand:SI 2 "gr_register_operand" "r")
+                  (const_int 0)])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C3.or.andcm %0, %I0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_orcm_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
+                        [(match_operand:SI 2 "gr_reg_or_0_operand" "rO")
+                         (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C4.and.orcm %I0, %0 = %3, %r2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpsi_orcm_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
+                         [(match_operand:SI 2 "gr_register_operand" "r")
+                          (const_int 0)]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp4.%C3.and.orcm %I0, %0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_or_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (match_operator:BI 4 "predicate_operator"
+                 [(match_operand:DI 2 "gr_register_operand" "r")
+                  (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C4.or.andcm %0, %I0 = %3, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_or_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (match_operator:BI 3 "signed_inequality_operator"
+                 [(match_operand:DI 2 "gr_register_operand" "r")
+                  (const_int 0)])
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C3.or.andcm %0, %I0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_orcm_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (not:BI (match_operator:BI 4 "predicate_operator"
+                        [(match_operand:DI 2 "gr_register_operand" "r")
+                         (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C4.and.orcm %I0, %0 = %3, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*cmpdi_orcm_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator"
+                         [(match_operand:DI 2 "gr_register_operand" "r")
+                          (const_int 0)]))
+               (match_operand:BI 1 "register_operand" "0")))]
+  ""
+  "cmp.%C3.and.orcm %I0, %0 = r0, %2"
+  [(set_attr "type" "A")])
+
+(define_insn "*tbit_or_0"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
+                              (const_int 1))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.nz.or.andcm %0, %I0 = %1, 0"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_or_1"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r")
+                              (const_int 1))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.z.or.andcm %0, %I0 = %1, 0"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_or_2"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (ne:BI (zero_extract:DI
+                        (match_operand:DI 1 "gr_register_operand" "r")
+                        (const_int 1)
+                        (match_operand:DI 2 "const_int_operand" "n"))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.nz.or.andcm %0, %I0 = %1, %2"
+  [(set_attr "type" "I")])
+
+(define_insn "*tbit_or_3"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ior:BI (eq:BI (zero_extract:DI
+                        (match_operand:DI 1 "gr_register_operand" "r")
+                        (const_int 1)
+                        (match_operand:DI 2 "const_int_operand" "n"))
+                      (const_int 0))
+               (match_operand:BI 3 "register_operand" "0")))]
+  ""
+  "tbit.z.or.andcm %0, %I0 = %1, %2"
+  [(set_attr "type" "I")])
+
+;; Transform test of and/or of setcc into parallel comparisons.
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
+                             (const_int 0))
+                      (match_operand:DI 3 "register_operand" ""))
+              (const_int 0)))]
+  ""
+  [(set (match_dup 0)
+       (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
+               (match_dup 2)))]
+  "")
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "")
+                             (const_int 0))
+                      (match_operand:DI 3 "register_operand" ""))
+              (const_int 0)))]
+  ""
+  [(set (match_dup 0)
+       (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0))
+               (match_dup 2)))
+   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
+             (clobber (scratch))])]
+  "")
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
+                             (const_int 0))
+                      (match_operand:DI 3 "register_operand" ""))
+              (const_int 0)))]
+  ""
+  [(set (match_dup 0) 
+       (ior:BI (ne:BI (match_dup 3) (const_int 0))
+               (match_dup 2)))]
+  "")
+
+(define_split
+  [(set (match_operand:BI 0 "register_operand" "")
+       (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "")
+                             (const_int 0))
+                      (match_operand:DI 3 "register_operand" ""))
+              (const_int 0)))]
+  ""
+  [(set (match_dup 0) 
+       (ior:BI (ne:BI (match_dup 3) (const_int 0))
+               (match_dup 2)))
+   (parallel [(set (match_dup 0) (not:BI (match_dup 0)))
+             (clobber (scratch))])]
+  "")
+
+;; ??? Incredibly hackish.  Either need four proper patterns with all
+;; the alternatives, or rely on sched1 to split the insn and hope that
+;; nothing bad happens to the comparisons in the meantime.
+;;
+;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming
+;; that we're doing height reduction.
+;
+;(define_insn_and_split ""
+;  [(set (match_operand:BI 0 "register_operand" "=c")
+;      (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
+;                        [(match_operand 2 "" "")
+;                         (match_operand 3 "" "")])
+;                      (match_operator:BI 4 "comparison_operator"
+;                        [(match_operand 5 "" "")
+;                         (match_operand 6 "" "")]))
+;              (match_dup 0)))]
+;  "flag_schedule_insns"
+;  "#"
+;  ""
+;  [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0)))
+;   (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))]
+;  "")
+;
+;(define_insn_and_split ""
+;  [(set (match_operand:BI 0 "register_operand" "=c")
+;      (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
+;                        [(match_operand 2 "" "")
+;                         (match_operand 3 "" "")])
+;                      (match_operator:BI 4 "comparison_operator"
+;                        [(match_operand 5 "" "")
+;                         (match_operand 6 "" "")]))
+;              (match_dup 0)))]
+;  "flag_schedule_insns"
+;  "#"
+;  ""
+;  [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0)))
+;   (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))]
+;  "")
+;
+;(define_split
+;  [(set (match_operand:BI 0 "register_operand" "")
+;      (and:BI (and:BI (match_operator:BI 1 "comparison_operator"
+;                        [(match_operand 2 "" "")
+;                         (match_operand 3 "" "")])
+;                      (match_operand:BI 7 "register_operand" ""))
+;              (and:BI (match_operator:BI 4 "comparison_operator"
+;                        [(match_operand 5 "" "")
+;                         (match_operand 6 "" "")])
+;                      (match_operand:BI 8 "register_operand" ""))))]
+;  ""
+;  [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8)))
+;   (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4))
+;                            (match_dup 0)))]
+;  "")
+;
+;(define_split
+;  [(set (match_operand:BI 0 "register_operand" "")
+;      (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator"
+;                        [(match_operand 2 "" "")
+;                         (match_operand 3 "" "")])
+;                      (match_operand:BI 7 "register_operand" ""))
+;              (ior:BI (match_operator:BI 4 "comparison_operator"
+;                        [(match_operand 5 "" "")
+;                         (match_operand 6 "" "")])
+;                      (match_operand:BI 8 "register_operand" ""))))]
+;  ""
+;  [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8)))
+;   (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4))
+;                            (match_dup 0)))]
+;  "")
+
+;; Try harder to avoid predicate copies by duplicating compares.
+;; Note that we'll have already split the predicate copy, which
+;; is kind of a pain, but oh well.
+
+(define_peephole2
+  [(set (match_operand:BI 0 "register_operand" "")
+       (match_operand:BI 1 "comparison_operator" ""))
+   (set (match_operand:CCI 2 "register_operand" "")
+       (match_operand:CCI 3 "register_operand" ""))
+   (set (match_operand:CCI 4 "register_operand" "")
+       (match_operand:CCI 5 "register_operand" ""))
+   (set (match_operand:BI 6 "register_operand" "")
+       (unspec:BI [(match_dup 6)] 7))]
+  "REGNO (operands[3]) == REGNO (operands[0])
+   && REGNO (operands[4]) == REGNO (operands[0]) + 1
+   && REGNO (operands[4]) == REGNO (operands[2]) + 1
+   && REGNO (operands[6]) == REGNO (operands[2])"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 6) (match_dup 7))]
+  "operands[7] = copy_rtx (operands[1]);")
+\f
+;; ::::::::::::::::::::
+;; ::
 ;; :: 16 bit Integer arithmetic
 ;; ::
 ;; ::::::::::::::::::::
        (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
                 (match_operand:SI 2 "grfr_register_operand" "f")))]
   ""
-  "xma.l %0 = %1, %2, f0%B0"
+  "xmpy.l %0 = %1, %2%B0"
   [(set_attr "type" "F")])
 
 (define_insn "maddsi4"
 
 (define_expand "abssi2"
   [(set (match_dup 2)
-       (ge:CC (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
+       (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0)))
    (set (match_operand:SI 0 "gr_register_operand" "")
-       (if_then_else:SI (eq:CC (match_dup 2) (const_int 0))
+       (if_then_else:SI (eq (match_dup 2) (const_int 0))
                         (neg:SI (match_dup 1))
                         (match_dup 1)))]
   ""
   "
 {
-  operands[2] = gen_reg_rtx (CCmode);
+  operands[2] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "sminsi3"
   [(set (match_dup 3)
-       (ge:CC (match_operand:SI 1 "gr_register_operand" "")
+       (ge:BI (match_operand:SI 1 "gr_register_operand" "")
               (match_operand:SI 2 "gr_register_operand" "")))
    (set (match_operand:SI 0 "gr_register_operand" "")
-       (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:SI (ne (match_dup 3) (const_int 0))
                         (match_dup 2) (match_dup 1)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "smaxsi3"
   [(set (match_dup 3)
-       (ge:CC (match_operand:SI 1 "gr_register_operand" "")
+       (ge:BI (match_operand:SI 1 "gr_register_operand" "")
               (match_operand:SI 2 "gr_register_operand" "")))
    (set (match_operand:SI 0 "gr_register_operand" "")
-       (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:SI (ne (match_dup 3) (const_int 0))
                         (match_dup 1) (match_dup 2)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "uminsi3"
   [(set (match_dup 3)
-       (geu:CC (match_operand:SI 1 "gr_register_operand" "")
+       (geu:BI (match_operand:SI 1 "gr_register_operand" "")
                (match_operand:SI 2 "gr_register_operand" "")))
    (set (match_operand:SI 0 "gr_register_operand" "")
-       (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:SI (ne (match_dup 3) (const_int 0))
                         (match_dup 2) (match_dup 1)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "umaxsi3"
   [(set (match_dup 3)
-       (geu:CC (match_operand:SI 1 "gr_register_operand" "")
+       (geu:BI (match_operand:SI 1 "gr_register_operand" "")
                (match_operand:SI 2 "gr_register_operand" "")))
    (set (match_operand:SI 0 "gr_register_operand" "")
-       (if_then_else:SI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:SI (ne (match_dup 3) (const_int 0))
                         (match_dup 1) (match_dup 2)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "divsi3"
                          (match_operand:TF 2 "fr_register_operand" "f"))))
    (clobber (match_scratch:TF 4 "=&f"))
    (clobber (match_scratch:TF 5 "=&f"))
-   (clobber (match_scratch:CC 6 "=c"))
+   (clobber (match_scratch:BI 6 "=c"))
    (use (match_operand:TF 3 "fr_register_operand" "f"))]
   "TARGET_INLINE_DIV"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
-             (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+             (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 6) (const_int 0))
      (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
        (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
                 (match_operand:DI 2 "grfr_register_operand" "f")))]
   ""
-  "xma.l %0 = %1, %2, f0%B0"
+  "xmpy.l %0 = %1, %2%B0"
   [(set_attr "type" "F")])
 
 ;; ??? If operand 3 is an eliminable reg, then register elimination causes the
                     (match_operand:DI 2 "fr_register_operand" "f")))
          (const_int 64))))]
   ""
-  "xma.h %0 = %1, %2, f0%B0"
+  "xmpy.h %0 = %1, %2%B0"
   [(set_attr "type" "F")])
 
 (define_insn "umuldi3_highpart"
                     (match_operand:DI 2 "fr_register_operand" "f")))
          (const_int 64))))]
   ""
-  "xma.hu %0 = %1, %2, f0%B0"
+  "xmpy.hu %0 = %1, %2%B0"
   [(set_attr "type" "F")])
 
 (define_insn "negdi2"
 
 (define_expand "absdi2"
   [(set (match_dup 2)
-       (ge:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
+       (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (eq:CC (match_dup 2) (const_int 0))
+       (if_then_else:DI (eq (match_dup 2) (const_int 0))
                         (neg:DI (match_dup 1))
                         (match_dup 1)))]
   ""
   "
 {
-  operands[2] = gen_reg_rtx (CCmode);
+  operands[2] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "smindi3"
   [(set (match_dup 3)
-       (ge:CC (match_operand:DI 1 "gr_register_operand" "")
+       (ge:BI (match_operand:DI 1 "gr_register_operand" "")
               (match_operand:DI 2 "gr_register_operand" "")))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:DI (ne (match_dup 3) (const_int 0))
                         (match_dup 2) (match_dup 1)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "smaxdi3"
   [(set (match_dup 3)
-       (ge:CC (match_operand:DI 1 "gr_register_operand" "")
+       (ge:BI (match_operand:DI 1 "gr_register_operand" "")
               (match_operand:DI 2 "gr_register_operand" "")))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:DI (ne (match_dup 3) (const_int 0))
                         (match_dup 1) (match_dup 2)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "umindi3"
   [(set (match_dup 3)
-       (geu:CC (match_operand:DI 1 "gr_register_operand" "")
+       (geu:BI (match_operand:DI 1 "gr_register_operand" "")
                (match_operand:DI 2 "gr_register_operand" "")))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:DI (ne (match_dup 3) (const_int 0))
                         (match_dup 2) (match_dup 1)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "umaxdi3"
   [(set (match_dup 3)
-       (geu:CC (match_operand:DI 1 "gr_register_operand" "")
+       (geu:BI (match_operand:DI 1 "gr_register_operand" "")
                (match_operand:DI 2 "gr_register_operand" "")))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (ne:CC (match_dup 3) (const_int 0))
+       (if_then_else:DI (ne (match_dup 3) (const_int 0))
                         (match_dup 1) (match_dup 2)))]
   ""
   "
 {
-  operands[3] = gen_reg_rtx (CCmode);
+  operands[3] = gen_reg_rtx (BImode);
 }")
 
 (define_expand "ffsdi2"
   [(set (match_dup 6)
-       (eq:CC (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
+       (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0)))
    (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
    (set (match_dup 5) (const_int 0))
    (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
    (set (match_dup 4) (unspec:DI [(match_dup 3)] 8))
    (set (match_operand:DI 0 "gr_register_operand" "")
-       (if_then_else:DI (ne:CC (match_dup 6) (const_int 0))
+       (if_then_else:DI (ne (match_dup 6) (const_int 0))
                         (match_dup 5) (match_dup 4)))]
   ""
   "
   operands[3] = gen_reg_rtx (DImode);
   operands[4] = gen_reg_rtx (DImode);
   operands[5] = gen_reg_rtx (DImode);
-  operands[6] = gen_reg_rtx (CCmode);
+  operands[6] = gen_reg_rtx (BImode);
 }")
 
 (define_insn "*popcnt"
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=&f"))
    (clobber (match_scratch:TF 5 "=&f"))
-   (clobber (match_scratch:CC 6 "=c"))]
+   (clobber (match_scratch:BI 6 "=c"))]
   "TARGET_INLINE_DIV_LAT"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
-             (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+             (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 6) (const_int 0))
      (parallel [(set (match_dup 3)
                          (match_operand:TF 2 "fr_register_operand" "f"))))
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=f"))
-   (clobber (match_scratch:CC 5 "=c"))]
+   (clobber (match_scratch:BI 5 "=c"))]
   "TARGET_INLINE_DIV_THR"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
-             (set (match_dup 5) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+             (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 5) (const_int 0))
      (parallel [(set (match_dup 3)
                (match_operand:SF 2 "fr_register_operand" "f")))
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=f"))
-   (clobber (match_scratch:CC 5 "=c"))]
+   (clobber (match_scratch:BI 5 "=c"))]
   "TARGET_INLINE_DIV_LAT"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
-             (set (match_dup 5) (unspec:CC [(match_dup 7) (match_dup 8)] 5))
+             (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 5) (const_int 0))
      (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
                (match_operand:SF 2 "fr_register_operand" "f")))
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=f"))
-   (clobber (match_scratch:CC 5 "=c"))]
+   (clobber (match_scratch:BI 5 "=c"))]
   "TARGET_INLINE_DIV_THR"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
-             (set (match_dup 5) (unspec:CC [(match_dup 7) (match_dup 8)] 5))
+             (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 5) (const_int 0))
      (parallel [(set (match_dup 3)
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=&f"))
    (clobber (match_scratch:TF 5 "=&f"))
-   (clobber (match_scratch:CC 6 "=c"))]
+   (clobber (match_scratch:BI 6 "=c"))]
   "TARGET_INLINE_DIV_LAT"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
-             (set (match_dup 6) (unspec:CC [(match_dup 8) (match_dup 9)] 5))
+             (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 6) (const_int 0))
      (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
                (match_operand:DF 2 "fr_register_operand" "f")))
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:DF 4 "=f"))
-   (clobber (match_scratch:CC 5 "=c"))]
+   (clobber (match_scratch:BI 5 "=c"))]
   "TARGET_INLINE_DIV_THR"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
-             (set (match_dup 5) (unspec:CC [(match_dup 7) (match_dup 8)] 5))
+             (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 5) (const_int 0))
      (parallel [(set (match_dup 3)
    (clobber (match_scratch:TF 4 "=&f"))
    (clobber (match_scratch:TF 5 "=&f"))
    (clobber (match_scratch:TF 6 "=&f"))
-   (clobber (match_scratch:CC 7 "=c"))]
+   (clobber (match_scratch:BI 7 "=c"))]
   "TARGET_INLINE_DIV_LAT"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
-             (set (match_dup 7) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+             (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 7) (const_int 0))
      (parallel [(set (match_dup 3)
                (match_operand:TF 2 "fr_register_operand" "f")))
    (clobber (match_scratch:TF 3 "=&f"))
    (clobber (match_scratch:TF 4 "=&f"))
-   (clobber (match_scratch:CC 5 "=c"))]
+   (clobber (match_scratch:BI 5 "=c"))]
   "TARGET_INLINE_DIV_THR"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
-             (set (match_dup 5) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+             (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 5))
              (use (const_int 1))])
    (cond_exec (ne (match_dup 5) (const_int 0))
      (parallel [(set (match_dup 3)
   [(set (match_operand:TF 0 "fr_register_operand" "=f")
        (div:TF (const_int 1)
                (match_operand:TF 3 "fr_register_operand" "f")))
-   (set (match_operand:CC 1 "register_operand" "=c")
-       (unspec:CC [(match_operand:TF 2 "fr_register_operand" "f")
+   (set (match_operand:BI 1 "register_operand" "=c")
+       (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
                    (match_dup 3)] 5))
    (use (match_operand:SI 4 "const_int_operand" ""))]
   ""
 ;; ::
 ;; ::::::::::::::::::::
 
+(define_expand "cmpbi"
+  [(set (cc0)
+        (compare (match_operand:BI 0 "register_operand" "")
+                (match_operand:BI 1 "const_int_operand" "")))]
+  ""
+  "
+{
+  ia64_compare_op0 = operands[0];
+  ia64_compare_op1 = operands[1];
+  DONE;
+}")
+
 (define_expand "cmpsi"
   [(set (cc0)
         (compare (match_operand:SI 0 "gr_register_operand" "")
 }")
 
 (define_insn "*cmpsi_normal"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "normal_comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "normal_comparison_operator"
           [(match_operand:SI 2 "gr_register_operand" "r")
            (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))]
   ""
   [(set_attr "type" "A")])
 
 (define_insn "*cmpsi_adjusted"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "adjusted_comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "adjusted_comparison_operator"
           [(match_operand:SI 2 "gr_register_operand" "r")
            (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
   ""
   [(set_attr "type" "A")])
 
 (define_insn "*cmpdi_normal"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "normal_comparison_operator"
-          [(match_operand:DI 2 "gr_register_operand" "r")
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "normal_comparison_operator"
+          [(match_operand:DI 2 "gr_reg_or_0_operand" "rO")
            (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))]
   ""
-  "cmp.%C1 %0, %I0 = %3, %2"
+  "cmp.%C1 %0, %I0 = %3, %r2"
   [(set_attr "type" "A")])
 
 (define_insn "*cmpdi_adjusted"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "adjusted_comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "adjusted_comparison_operator"
           [(match_operand:DI 2 "gr_register_operand" "r")
            (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))]
   ""
   [(set_attr "type" "A")])
 
 (define_insn "*cmpsf_internal"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "comparison_operator"
           [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
            (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))]
   ""
   [(set_attr "type" "F")])
 
 (define_insn "*cmpdf_internal"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "comparison_operator"
           [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
            (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))]
   ""
   [(set_attr "type" "F")])
 
 (define_insn "*cmptf_internal"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (match_operator:CC 1 "comparison_operator"
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (match_operator:BI 1 "comparison_operator"
                   [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
                    (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
   ""
 ;; ??? Can this pattern be generated?
 
 (define_insn "*bit_zero"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (eq:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
                                (const_int 1)
                                (match_operand:DI 2 "immediate_operand" "n"))
               (const_int 0)))]
   [(set_attr "type" "I")])
 
 (define_insn "*bit_one"
-  [(set (match_operand:CC 0 "register_operand" "=c")
-       (ne:CC (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
+  [(set (match_operand:BI 0 "register_operand" "=c")
+       (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r")
                                (const_int 1)
                                (match_operand:DI 2 "immediate_operand" "n"))
               (const_int 0)))]
   ""
   "tbit.nz %0, %I0 = %1, %2"
   [(set_attr "type" "I")])
-
-;; ??? We also need this if we run out of PR regs and need to spill some.
-
-;; ??? We need this if a CCmode value does not get allocated to a hard
-;; register.  This happens if we cse/gcse a CCmode value across a call, and the
-;; function has a nonlocal goto.  This is because global does not allocate
-;; call crossing pseudos to hard registers when current_function_has_
-;; nonlocal_goto is true.  This is relatively common for C++ programs that
-;; use exceptions.  See ia64_secondary_reload_class.
-
-;; We use a define_expand here so that cse/gcse/combine can't accidentally
-;; create movcc insns.  If this was a named define_insn, we would not be able
-;; to make it conditional on reload.
-
-(define_expand "movcc"
-  [(set (match_operand:CC 0 "nonimmediate_operand" "")
-       (match_operand:CC 1 "move_operand" ""))]
-  ""
-  "
-{
-  if (! reload_in_progress && ! reload_completed)
-    FAIL;
-}")
-
-(define_insn "*movcc_internal"
-  [(set (match_operand:CC 0 "nonimmediate_operand" "=r,c,r,m")
-       (match_operand:CC 1 "move_operand" "c,r,m,r"))]
-  "reload_in_progress || reload_completed"
-  "@
-   #
-   cmp4.ne %0, %I0 = %1, r0
-   ld4%O1 %0 = %1%P1
-   st4%Q0 %0 = %1%P0"
-  [(set_attr "type" "unknown,A,M,M")])
-
-(define_split
-  [(set (match_operand:CC 0 "register_operand" "")
-       (match_operand:CC 1 "register_operand" ""))]
-  "reload_completed
-   && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))
-   && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))"
-  [(set (match_dup 2)
-       (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
-                        (const_int 1)
-                        (match_dup 2)))
-   (set (match_dup 2)
-       (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
-                        (match_dup 2)
-                        (const_int 0)))]
-  "operands[2] = gen_rtx_SUBREG (DImode, operands[0], 0);")
-
 \f
 ;; ::::::::::::::::::::
 ;; ::
 ;; ::::::::::::::::::::
 
 (define_expand "beq"
-  [(set (match_dup 1)
-       (eq:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
 
 (define_expand "bne"
-  [(set (match_dup 1)
-       (ne:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (NE, VOIDmode);")
 
 (define_expand "blt"
-  [(set (match_dup 1)
-       (lt:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LT, VOIDmode);")
 
 (define_expand "ble"
-  [(set (match_dup 1)
-       (le:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LE, VOIDmode);")
 
 (define_expand "bgt"
-  [(set (match_dup 1)
-       (gt:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GT, VOIDmode);")
 
 (define_expand "bge"
-  [(set (match_dup 1)
-       (ge:CC (match_dup 2)
-              (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GE, VOIDmode);")
 
 (define_expand "bltu"
-  [(set (match_dup 1)
-       (ltu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
 
 (define_expand "bleu"
-  [(set (match_dup 1)
-       (leu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
 
 (define_expand "bgtu"
-  [(set (match_dup 1)
-       (gtu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
 
 (define_expand "bgeu"
-  [(set (match_dup 1)
-       (geu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
 
 (define_expand "bunordered"
-  [(set (match_dup 1)
-       (unordered:CC (match_dup 2)
-                     (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
 
 (define_expand "bordered"
-  [(set (match_dup 1)
-       (ordered:CC (match_dup 2)
-                     (match_dup 3)))
-   (set (pc)
-       (if_then_else (ne:CC (match_dup 1)
-                            (const_int 0))
+  [(set (pc)
+       (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
 
 (define_insn "*br_true"
   [(set (pc)
        (if_then_else (match_operator 0 "predicate_operator"
-                       [(match_operand:CC 1 "register_operand" "c")
+                       [(match_operand:BI 1 "register_operand" "c")
                         (const_int 0)])
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
 (define_insn "*br_false"
   [(set (pc)
        (if_then_else (match_operator 0 "predicate_operator"
-                       [(match_operand:CC 1 "register_operand" "c")
+                       [(match_operand:BI 1 "register_operand" "c")
                         (const_int 0)])
                      (pc)
                      (label_ref (match_operand 2 "" ""))))]
 ;; ::::::::::::::::::::
 
 (define_expand "seq"
-  [(set (match_dup 1)
-       (eq:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (EQ, DImode);")
 
 (define_expand "sne"
-  [(set (match_dup 1)
-       (ne:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (NE, DImode);")
 
 (define_expand "slt"
-  [(set (match_dup 1)
-       (lt:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LT, DImode);")
 
 (define_expand "sle"
-  [(set (match_dup 1)
-       (le:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LE, DImode);")
 
 (define_expand "sgt"
-  [(set (match_dup 1)
-       (gt:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GT, DImode);")
 
 (define_expand "sge"
-  [(set (match_dup 1)
-       (ge:CC (match_dup 2)
-              (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GE, DImode);")
 
 (define_expand "sltu"
-  [(set (match_dup 1)
-       (ltu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LTU, DImode);")
 
 (define_expand "sleu"
-  [(set (match_dup 1)
-       (leu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (LEU, DImode);")
 
 (define_expand "sgtu"
-  [(set (match_dup 1)
-       (gtu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GTU, DImode);")
 
 (define_expand "sgeu"
-  [(set (match_dup 1)
-       (geu:CC (match_dup 2)
-               (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (GEU, DImode);")
 
 (define_expand "sunordered"
-  [(set (match_dup 1)
-       (unordered:CC (match_dup 2)
-                     (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
 
 (define_expand "sordered"
-  [(set (match_dup 1)
-       (ordered:CC (match_dup 2)
-                     (match_dup 3)))
-   (set (match_operand:DI 0 "gr_register_operand" "")
-       (ne:DI (match_dup 1) (const_int 0)))]
+  [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
   ""
-  "
-{
-  operands[1] = gen_reg_rtx (CCmode);
-  operands[2] = ia64_compare_op0;
-  operands[3] = ia64_compare_op1;
-}")
+  "operands[1] = ia64_expand_compare (ORDERED, DImode);")
 
 ;; Don't allow memory as destination here, because cmov/cmov/st is more
 ;; efficient than mov/mov/cst/cst.
 
 (define_insn_and_split "*sne_internal"
   [(set (match_operand:DI 0 "gr_register_operand" "=r")
-       (ne:DI (match_operand:CC 1 "register_operand" "c")
+       (ne:DI (match_operand:BI 1 "register_operand" "c")
               (const_int 0)))]
   ""
   "#"
   "reload_completed"
-  [(set (match_dup 0)
-       (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
-                        (const_int 1)
-                        (match_dup 0)))
-   (set (match_dup 0)
-       (if_then_else:DI (ne:CC (match_dup 1) (const_int 0))
-                        (match_dup 0)
-                        (const_int 0)))]
+  [(cond_exec (ne (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 1)))
+   (cond_exec (eq (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 0)))]
   ""
   [(set_attr "type" "unknown")])
 
-;; ??? Unknown if this can be matched.
-
 (define_insn_and_split "*seq_internal"
   [(set (match_operand:DI 0 "gr_register_operand" "=r")
-       (eq:DI (match_operand:CC 1 "register_operand" "c")
+       (eq:DI (match_operand:BI 1 "register_operand" "c")
               (const_int 0)))]
   ""
   "#"
   "reload_completed"
-  [(set (match_dup 0)
-       (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
-                        (const_int 1)
-                        (match_dup 0)))
-   (set (match_dup 0)
-       (if_then_else:DI (eq:CC (match_dup 1) (const_int 0))
-                        (match_dup 0)
-                        (const_int 0)))]
+  [(cond_exec (ne (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 0)))
+   (cond_exec (eq (match_dup 1) (const_int 0))
+     (set (match_dup 0) (const_int 1)))]
   ""
   [(set_attr "type" "unknown")])
-
 \f
 ;; ::::::::::::::::::::
 ;; ::
 
 ;; Errata 72 workaround.
 (define_insn "*cmovdi_internal_astep"
-  [(set (match_operand:DI 0 "nonimmediate_operand"
-               "=r,*f,Q,*b,r,*f,Q,*b,r,*f,Q,*b")
+  [(set (match_operand:DI 0 "register_operand"
+               "=r,*f,*b,r,*f,*b,r,*f,*b")
        (if_then_else:DI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand"
-                              "c,c,c,c,c,c,c,c,c,c,c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand"
+                              "c,c,c,c,c,c,c,c,c")
             (const_int 0)])
-         (match_operand:DI 2 "general_operand"
-               "0,0,0,0,ri*f*b,rO,*f,r,ri*f*b,rO,*f,r")
-         (match_operand:DI 3 "general_operand"
-               "ri*f*b,rO,*f,r,0,0,0,0,ri*f*b,rO,*f,r")))]
-  "TARGET_A_STEP"
+         (match_operand:DI 2 "move_operand"
+               "0,0,0,ri*f*b,rO,r,ri*f*b,rO,r")
+         (match_operand:DI 3 "move_operand"
+               "ri*f*b,rO,r,0,0,0,ri*f*b,rO,r")))]
+  "TARGET_A_STEP
+   && ia64_move_ok (operands[0], operands[2])
+   && ia64_move_ok (operands[0], operands[3])"
   "* abort ();"
   [(set_attr "predicable" "no")])
 
 (define_insn "*cmovdi_internal"
-  [(set (match_operand:DI 0 "nonimmediate_operand"
+  [(set (match_operand:DI 0 "destination_operand"
                "=r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e,r,m,*f,Q,*b,*d*e")
        (if_then_else:DI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand"
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand"
                               "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
             (const_int 0)])
-         (match_operand:DI 2 "general_operand"
+         (match_operand:DI 2 "move_operand"
                "0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK,rim*f*b*d*e,rO,rOQ,*f,rO,rK")
-         (match_operand:DI 3 "general_operand"
+         (match_operand:DI 3 "move_operand"
                "rim*f*b*d*e,rO,rOQ,*f,rO,rK,0,0,0,0,0,0,rim*f*b*d*e,rO,rOQ,*f,rO,rK")))]
-  "! TARGET_A_STEP"
+  "! TARGET_A_STEP
+   && ia64_move_ok (operands[0], operands[2])
+   && ia64_move_ok (operands[0], operands[3])"
   "* abort ();"
   [(set_attr "predicable" "no")])
 
 (define_split
-  [(set (match_operand 0 "nonimmediate_operand" "")
+  [(set (match_operand 0 "destination_operand" "")
        (if_then_else
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "")
             (const_int 0)])
-         (match_operand 2 "general_operand" "")
-         (match_operand 3 "general_operand" "")))]
+         (match_operand 2 "move_operand" "")
+         (match_operand 3 "move_operand" "")))]
   "reload_completed"
   [(const_int 0)]
   "
   if (! rtx_equal_p (operands[0], operands[3]))
     {
       tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
-                           CCmode, operands[1], const0_rtx);
+                           VOIDmode, operands[1], const0_rtx);
       tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
                               gen_rtx_SET (VOIDmode, operands[0],
                                            operands[3]));
 (define_insn "*absdi2_internal"
   [(set (match_operand:DI 0 "gr_register_operand" "=r,r")
        (if_then_else:DI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI"))
          (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))]
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
        (if_then_else:DI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
          (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
        (if_then_else:DI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" ""))
          (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))]
   "
 {
   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
-                               CCmode, operands[1], const0_rtx);
+                               VOIDmode, operands[1], const0_rtx);
 }")
 
 ;;
 ;;
 
 (define_insn "*cmovsi_internal_astep"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,*f,r,*f,r,*f")
+  [(set (match_operand:SI 0 "register_operand" "=r,*f,r,*f,r,*f")
        (if_then_else:SI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c")
             (const_int 0)])
-         (match_operand:SI 2 "general_operand"
-                   "0,0,ri*f,rO,ri*f,rO")
-         (match_operand:SI 3 "general_operand"
-                   "ri*f,rO,0,0,ri*f,rO")))]
-  "TARGET_A_STEP"
+         (match_operand:SI 2 "move_operand" "0,0,ri*f,rO,ri*f,rO")
+         (match_operand:SI 3 "move_operand" "ri*f,rO,0,0,ri*f,rO")))]
+  "TARGET_A_STEP
+   && ia64_move_ok (operands[0], operands[2])
+   && ia64_move_ok (operands[0], operands[3])"
   "* abort ();"
   [(set_attr "predicable" "no")])
 
 (define_insn "*cmovsi_internal"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f")
+  [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f")
        (if_then_else:SI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
             (const_int 0)])
-         (match_operand:SI 2 "general_operand"
+         (match_operand:SI 2 "move_operand"
                    "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
-         (match_operand:SI 3 "general_operand"
+         (match_operand:SI 3 "move_operand"
                    "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
-  "! TARGET_A_STEP"
+  "! TARGET_A_STEP
+   && ia64_move_ok (operands[0], operands[2])
+   && ia64_move_ok (operands[0], operands[3])"
   "* abort ();"
   [(set_attr "predicable" "no")])
 
 (define_insn "*abssi2_internal"
   [(set (match_operand:SI 0 "gr_register_operand" "=r,r")
        (if_then_else:SI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI"))
          (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))]
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (if_then_else:SI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
          (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (if_then_else:SI
-         (match_operator:CC 4 "predicate_operator"
-           [(match_operand:CC 1 "register_operand" "c,c")
+         (match_operator 4 "predicate_operator"
+           [(match_operand:BI 1 "register_operand" "c,c")
             (const_int 0)])
          (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" ""))
          (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))]
   "
 {
   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
-                               CCmode, operands[1], const0_rtx);
+                               VOIDmode, operands[1], const0_rtx);
 }")
 
 \f
 (define_insn "*return_true"
   [(set (pc)
        (if_then_else (match_operator 0 "predicate_operator"
-                       [(match_operand:CC 1 "register_operand" "c")
+                       [(match_operand:BI 1 "register_operand" "c")
                         (const_int 0)])
                      (return)
                      (pc)))]
 (define_insn "*return_false"
   [(set (pc)
        (if_then_else (match_operator 0 "predicate_operator"
-                       [(match_operand:CC 1 "register_operand" "c")
+                       [(match_operand:BI 1 "register_operand" "c")
                         (const_int 0)])
                      (pc)
                      (return)))]
 
 (define_cond_exec
   [(match_operator 0 "predicate_operator"
-     [(match_operand:CC 1 "register_operand" "c")
+     [(match_operand:BI 1 "register_operand" "c")
       (const_int 0)])]
   ""
   "(%J0)")
 
 (define_insn "pred_rel_mutex"
-  [(unspec_volatile [(match_operand:CC 0 "register_operand" "c")] 7)]
+  [(set (match_operand:BI 0 "register_operand" "+c")
+       (unspec:BI [(match_dup 0)] 7))]
   ""
   ".pred.rel.mutex %0, %I0"
   [(set_attr "type" "unknown")