PR target/95294: VAX: Convert backend to MODE_CC representation
authorMaciej W. Rozycki <macro@linux-mips.org>
Sat, 5 Dec 2020 18:26:27 +0000 (18:26 +0000)
committerMaciej W. Rozycki <macro@linux-mips.org>
Sat, 5 Dec 2020 18:26:27 +0000 (18:26 +0000)
In the VAX ISA INSV bit-field insert instruction is the only computational
operation that keeps the condition codes, held in the PSL or Processor
Status Longword register, intact.  The instruction is flexible enough it
could potentially be used for data moves post-reload, but then reportedly
it is not the best choice performance-wise, and then we have no addition
operation available that would keep the condition codes unchanged.

Futhermore, as usually with a complex CISC ISA, for many operations we
have several machine instructions or instruction sequences to choose
from that set condition codes in a different manner.

Use the approach then where the condition codes only get introduced by
reload, by definining instruction splitters for RTL insns that change
condition codes in some way, by default considering them clobbered.

Then to prevent code generated from regressing too much provide insns
that include a `compare' operation setting the condition codes in
parallel to the main operation.  The manner condition codes are set by
each insn is supposed to be provided by the whatever the SELECT_CC_MODE
macro expands to.

Given that individual patterns provided for the same RTL basic operation
may set the condion codes differently keeping the information away from
the insn patterns themselves would cause a maintenance nightmare and
would be bound to fail in a horrible way sooner or later.  Therefore
instead let the patterns themselves choose which condition modes they
support, by having one or more subst iterators applied and then have
individual comparison operators require the specific condition mode each
according to the codes used by the operation.

While subst iterators only support one alternative each, there is
actually no problem with applying multiple ones to a single insn with
the result as intended, and if the corresponding subst attribute
supplies an empty NO-SUBST-VALUE, then no mess results even.  Make use
of this observation.

Add appropriate subst iterators to all the computational patterns then,
according to the condition codes they usably set, including DImode ones
and a substitute DImode comparison instruction in the absence of a CMPQ
machine instruction, however do not provide a `cbranchdi4' named pattern
as without a further development it regresses code quality by resorting
to the `__cmpdi2' libcall where a simpler operation would do, e.g. to
check for negativity the TSTL machine instruction may be executed over
the upper longword only.  This is good material for further work.

Do not apply subst iterators to the increment- or decrement-and-branch
patterns at this time; these may yet have to be reviewed, in particular
whether `*jsobneq_minus_one' is still relevant in the context of the
recent integer constant cost review.

Also add a couple of peepholes to help eliminating comparisons in some
problematic cases, such as with the BIT instruction which is bitwise-AND
for condition codes only that has no direct counterpart for the actual
calculation, because the BIC instruction which does do bitwise-AND and
produces a result implements the operation with a bitwise negation of
its input `mask' operand.  Or the FFS instruction which sets the Z
condition code according to its `field' input operand rather than the
result produced.  Or the bit-field comparisons we don't have generic
middle-end support for.

Code size stats are as follows, obtained from 17640 and 9086 executables
built in `check-c' and `check-c++' GCC testing respectively:

                      check-c                 check-c++
              samples average  median  samples average  median
---------------------------------------------------------------
regressions      1813  0.578%  0.198%      289  0.349%  0.175%
unchanged       15160  0.000%  0.000%     8662  0.000%  0.000%
progressions      667 -0.589% -0.194%      135 -0.944% -0.191%
----------------------------------------------------------------
total           17640  0.037%  0.000%     9086 -0.003%  0.000%

Outliers:

old     new     change  %change filename
----------------------------------------------------
2406    2950    +544    +22.610 20111208-1.exe
4314    5329    +1015   +23.528 pr39417.exe
2235    3055    +820    +36.689 990404-1.exe
2631    4213    +1582   +60.129 pr57521.exe
3063    5579    +2516   +82.142 20000422-1.exe

and:

old     new     change  %change filename
----------------------------------------------------
6317    4845    -1472   -23.302 vector-compare-1.exe
6313    4845    -1468   -23.254 vector-compare-1.exe
6474    5002    -1472   -22.737 vector-compare-1.exe
6470    5002    -1468   -22.689 vector-compare-1.exe

We have some code quality regressions like:

    10861: 9e ef d9 12  movab 11b40 <p>,r0
    10865: 00 00 50
    10868: 90 a0 03 a0  movb 0x3(r0),0x2(r0)
    1086c: 02
    1086d: d1 60 8f 61  cmpl (r0),$0x64646261
    10871: 62 64 64
    10874: 13 07        beql 1087d <main_test+0x21>

to:

    10861: 9e ef e1 12  movab 11b48 <p>,r0
    10865: 00 00 50
    10868: 90 a0 03 a0  movb 0x3(r0),0x2(r0)
    1086c: 02
    1086d: d1 ef d5 12  cmpl 11b48 <p>,$0x64646261
    10871: 00 00 8f 61
    10875: 62 64 64
    10878: 13 07        beql 10881 <main_test+0x25>

(from `memmove-2.x2') due to the constant propagation passes eagerly
replacing pseudo registers with direct symbol references where possible,
which does not happen with CC0 even though the passes do run regardless.

There are further code quality regressions due to earlier compilation
stages trying to push expression evaluation earlier where possible so
as to make data dependencies further apart from each other.  This works
well for computations and architectures that do not involve condition
codes set as a side effect of calculations.  However for integer
negation that makes assembly code produced like:

movb *8(%ap),%r0
mnegb %r0,%r1
tstb %r0
jeql .L2

the RTL equibvalent of which the comparison elimination pass cannot
really do anything about, because the comparison is made on the source
rather than the target operand of the negation (we could add a peephole
for this, but this seems futile an effort, as one'd have to iterate over
all the possible such cases), even though this is really equivalent to:

movb *8(%ap),%r0
mnegb %r0,%r1
jeql .L2

or, if R0 is dead at the conclusion of the branch, even:

mnegb *8(%ap),%r1
jeql .L2

Since the compiler insists on doing the comparison on the source of the
negation it obviously has to load it into a temporary so as to avoid
accessing the original memory location twice, hence the sequence of
three instructions rather than just a single one.  A similar phenomenon
can be observed with the XOR operation and in other cases.

In some cases a comparison does get eliminated, however useless moves
into registers done in preparation to it remain, such as with:

movb *8(%ap),%r2
movb *12(%ap),%r1
subb3 %r1,%r2,%r0
jlssu .L2

where R1 and R2 are both dead at conclusion and therefore:

subb3 *12(%ap),*8(%ap),%r0
jlssu .L2

would obviously do, but there was to be a comparison before the branch:

cmpb %r2,%r1

All this looks like material for future improvement.

Test cases for comparison elimination and the peepholes will be supplied
separately.

gcc/
PR target/95294
* config/vax/elf.h (REGISTER_NAMES): Append `%psl'.
* config/vax/vax-modes.def (CCN, CCNZ, CCZ): New modes.
* config/vax/vax-protos.h (vax_select_cc_mode): New prototype.
(vax_maybe_split_dimode_move): Likewise.
(vax_notice_update_cc): Remove prototype.
* config/vax/vax.c (TARGET_FLAGS_REGNUM): New macro.
(TARGET_CC_MODES_COMPATIBLE): Likewise.
(TARGET_MD_ASM_ADJUST): Likewise.
(vax_select_cc_mode): New function
(vax_cc_modes_compatible): Likewise.
(vax_md_asm_adjust): Likewise.
(vax_notice_update_cc): Remove function.
(vax_output_int_move): Factor out code checking if a DImode move
may have to be split...
(vax_maybe_split_dimode_move): ... into this new function.
* config/vax/vax.h (FIRST_PSEUDO_REGISTER): Bump up.
(FIXED_REGISTERS): Append an entry for PSL.
(CALL_USED_REGISTERS): Likewise.
(NOTICE_UPDATE_CC, OUTPUT_JUMP): Remove macros.
(SELECT_CC_MODE): New macro.
(REGISTER_NAMES): Append `psl'.
* config/vax/predicates.md (const_zero_operand)
(vax_cc_comparison_operator, vax_ccn_comparison_operator)
(vax_ccnz_comparison_operator, vax_ccz_comparison_operator):
New predicates.
* config/vax/builtins.md: Rewrite for MODE_CC representation.
* config/vax/vax.md: Likewise.

gcc/config/vax/builtins.md
gcc/config/vax/elf.h
gcc/config/vax/predicates.md
gcc/config/vax/vax-modes.def
gcc/config/vax/vax-protos.h
gcc/config/vax/vax.c
gcc/config/vax/vax.h
gcc/config/vax/vax.md

index e96ac3f52abd62f97979a829a448535b4576346b..846d1f352fffa997758c43a45779332550069dbb 100644 (file)
 {
   rtx label = gen_label_rtx ();
   rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
-  rtx cond = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx);
+  rtx cond = gen_rtx_NE (VOIDmode, operands[1], const0_rtx);
   rtx target = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label_ref, pc_rtx);
 
-  emit_insn (gen_ctz<mode>2 (operands[0], operands[1]));
+  emit_insn (gen_ctz<mode>2_ccz (operands[0], operands[1]));
   emit_jump_insn (gen_rtx_SET (pc_rtx, target));
   emit_insn (gen_neg<mode>2 (operands[0], const1_rtx));
   emit_label (label);
   DONE;
 }")
 
-(define_insn "ctz<mode>2"
+(define_insn_and_split "ctz<mode>2"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
+  ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ctz:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ctz<mode>2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
        (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))
-   (set (cc0)
-       (compare (match_dup 1)
-                (const_int 0)))]
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "ffs $0,$<width>,%1,%0")
+
+(define_insn_and_split "ctz<mode>2_ccz"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_operand:VAXint 1 "general_operand" "nrQT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 0)
+          (ctz:SI (match_dup 1)))])]
+  "")
+
+(define_insn "*ctz<mode>2_ccz"
+  [(set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_operand:VAXint 1 "general_operand" "nrQT")
+                    (const_int 0)))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rQ")
+       (ctz:SI (match_dup 1)))]
+  "reload_completed"
   "ffs $0,$<width>,%1,%0")
 
 ;; Our FFS hardware instruction supports any field width,
 ;; so handle narrower inputs directly as well.
 (define_peephole2
-  [(set (match_operand:SI 0 "register_operand")
-        (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+          (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
    (parallel
      [(set (match_operand:SI 2 "nonimmediate_operand")
           (ctz:SI (match_dup 0)))
-      (set (cc0)
-          (compare (match_dup 2)
-                   (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
   "rtx_equal_p (operands[0], operands[2]) || peep2_reg_dead_p (2, operands[0])"
   [(parallel
      [(set (match_dup 2)
           (ctz:SI (match_dup 1)))
-      (set (cc0)
-          (compare (match_dup 1)
-                   (const_int 0)))])]
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+;; The FFS hardware instruction sets the Z condition code based on
+;; the input field rather than the output operand, so the compare
+;; elimination pass cannot handle it.  Try to get rid of the extra
+;; operation by hand.
+;;
+;; The "ctz<mode>2_ccz" patterns require their `operands[1]' not to
+;; have a mode dependent address, so all we need to verify is that
+;; the two operands are not the same, in which case it's the FFS
+;; output rather than input that condition codes are checked for.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "nonimmediate_operand")
+          (ctz:SI (match_operand:VAXint 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_dup 1)
+                    (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[1])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 0)
+          (ctz:SI (match_dup 1)))])]
+  "")
+
+;; This effectively combines the two peepholes above,
+;; matching the sequence produced by `ffs<mode>2'.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+          (any_extend:SI (match_operand:VAXintQH 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (parallel
+     [(set (match_operand:SI 2 "nonimmediate_operand")
+          (ctz:SI (match_dup 0)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:CCZ VAX_PSL_REGNUM)
+       (compare:CCZ (match_dup 0)
+                    (const_int 0)))]
+  "!rtx_equal_p (operands[0], operands[2])
+   && peep2_reg_dead_p (3, operands[0])"
+  [(parallel
+     [(set (reg:CCZ VAX_PSL_REGNUM)
+          (compare:CCZ (match_dup 1)
+                       (const_int 0)))
+      (set (match_dup 2)
+          (ctz:SI (match_dup 1)))])]
   "")
 
 (define_expand "sync_lock_test_and_set<mode>"
index 530b2c05ed2a5798957bb80c5d749fdf2ce7fd01..f6485eca3f474933057226dd60d5bfc2bb51d858 100644 (file)
@@ -26,7 +26,8 @@ along with GCC; see the file COPYING3.  If not see
 #define REGISTER_PREFIX "%"
 #define REGISTER_NAMES \
   { "%r0", "%r1",  "%r2",  "%r3", "%r4", "%r5", "%r6", "%r7", \
-    "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", }
+    "%r8", "%r9", "%r10", "%r11", "%ap", "%fp", "%sp", "%pc", \
+    "%psl" }
 
 #undef SIZE_TYPE
 #define SIZE_TYPE "long unsigned int"
index 7c97b36660471d3c51c709a3989650393290a327..92caf8384fab1c461350a8ea04603288f1cc8ca9 100644 (file)
 ;; along with GCC; see the file COPYING3.  If not see
 ;; <http://www.gnu.org/licenses/>.
 
+;; Return true if OP is a constant zero operand.
+(define_predicate "const_zero_operand"
+  (match_test "op == CONST0_RTX (mode)"))
+
 ;; Special case of a symbolic operand that's used as a
 ;; operand.
 
 (define_predicate "any_memory_operand"
   (ior (match_operand 0 "memory_operand")
        (match_operand 0 "volatile_mem_operand")))
+
+;; Return true if OP is a comparison operator that requires at least CCmode.
+(define_predicate "vax_cc_comparison_operator"
+  (match_code "geu,gtu,leu,ltu"))
+
+;; Return true if OP is a comparison operator that requires at least CCNmode.
+(define_predicate "vax_ccn_comparison_operator"
+  (match_code "ge,lt"))
+
+;; Return true if OP is a comparison operator that requires at least CCNZmode.
+(define_predicate "vax_ccnz_comparison_operator"
+  (match_code "gt,le"))
+
+;; Return true if OP is a comparison operator that requires at least CCZmode.
+(define_predicate "vax_ccz_comparison_operator"
+  (match_code "ne,eq"))
index 5f1c994665360695933892ec45940024e79e8bb0..2a7438ee77fcca3eed3f30931102de084b4d8dbf 100644 (file)
@@ -20,3 +20,14 @@ along with GCC; see the file COPYING3.  If not see
 /* We just need to reset the floating point formats.  */
 RESET_FLOAT_FORMAT (SF, vax_f_format);
 RESET_FLOAT_FORMAT (DF, vax_d_format);
+
+/* `DImode' addition and subtraction operations do their calculation
+   on the low and then the high longword with separate instructions,
+   and therefore only usably set N.  */
+CC_MODE (CCN);
+/* Non-arithmetic integer instructions such as MOV or XOR as well as
+   instructions that produce a floating-point result only usably set
+   N and Z.  */
+CC_MODE (CCNZ);
+/* The FFC and FFS instructions only usably set Z.  */
+CC_MODE (CCZ);
index 454d35e3383a6a6095b52ad851c6a5df9072e466..aa949c598d782288ba06c84ae11e05f437ed3168 100644 (file)
@@ -22,13 +22,14 @@ extern void vax_expand_prologue (void);
 
 #ifdef RTX_CODE
 extern bool vax_acceptable_pic_operand_p (rtx, bool, bool);
+extern machine_mode vax_select_cc_mode (enum rtx_code, rtx, rtx);
 extern const char *cond_name (rtx);
 extern bool adjacent_operands_p (rtx, rtx, machine_mode);
 extern const char *rev_cond_name (rtx);
 extern void print_operand_address (FILE *, rtx);
 extern void print_operand (FILE *, rtx, int);
-extern void vax_notice_update_cc (rtx, rtx);
 extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code);
+extern bool vax_maybe_split_dimode_move (rtx *);
 extern const char * vax_output_int_move (rtx, rtx *, machine_mode);
 extern const char * vax_output_int_add (rtx_insn *, rtx *, machine_mode);
 extern const char * vax_output_int_subtract (rtx_insn *, rtx *, machine_mode);
index 69a05b33e9590e14b1adef96bf50fb715317fc8c..54d83dc1da2e9a67242b0f0b3454390fcfb88b6d 100644 (file)
@@ -54,6 +54,10 @@ static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
 static int vax_address_cost_1 (rtx);
 static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
 static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode);
+static rtx_insn *vax_md_asm_adjust (vec<rtx> &, vec<rtx> &,
+                                   vec<const char *> &,
+                                   vec<rtx> &, HARD_REG_SET &);
 static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
 static void vax_function_arg_advance (cumulative_args_t,
                                      const function_arg_info &);
@@ -81,11 +85,23 @@ static HOST_WIDE_INT vax_starting_frame_offset (void);
 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
 
+/* Enable compare elimination pass.  */
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM VAX_PSL_REGNUM
+
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS vax_rtx_costs
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST vax_address_cost
 
+/* Return the narrowest CC mode that spans both modes offered.  */
+#undef TARGET_CC_MODES_COMPATIBLE
+#define TARGET_CC_MODES_COMPATIBLE vax_cc_modes_compatible
+
+/* Mark PSL as clobbered for compatibility with the CC0 representation.  */
+#undef TARGET_MD_ASM_ADJUST
+#define TARGET_MD_ASM_ADJUST vax_md_asm_adjust
+
 #undef TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
 
@@ -1070,6 +1086,102 @@ vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED,
   return true;
 }
 \f
+/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE,
+   return the mode to be used for the comparison.  As we have the same
+   interpretation of condition codes across all the instructions we just
+   return the narrowest mode suitable for the comparison code requested.  */
+
+extern machine_mode
+vax_select_cc_mode (enum rtx_code op,
+                   rtx x ATTRIBUTE_UNUSED, rtx y ATTRIBUTE_UNUSED)
+{
+  switch (op)
+    {
+    default:
+      gcc_unreachable ();
+    case NE:
+    case EQ:
+      return CCZmode;
+    case GE:
+    case LT:
+      return CCNmode;
+    case GT:
+    case LE:
+      return CCNZmode;
+    case GEU:
+    case GTU:
+    case LEU:
+    case LTU:
+      return CCmode;
+    }
+}
+
+/* Return the narrowest CC mode that spans both modes offered.  If they
+   intersect, this will be the wider of the two, and if they do not then
+   find find one that is a superset of both (i.e. CCNZmode for a pair
+   consisting of CCNmode and CCZmode).  A wider CC writer will satisfy
+   a narrower CC reader, e.g. a comparison operator that uses CCZmode
+   can use a CCNZmode output of a previous instruction.  */
+
+static machine_mode
+vax_cc_modes_compatible (machine_mode m1, machine_mode m2)
+{
+  switch (m1)
+    {
+    default:
+      gcc_unreachable ();
+    case E_CCmode:
+      switch (m2)
+       {
+       default:
+         gcc_unreachable ();
+       case E_CCmode:
+       case E_CCNZmode:
+       case E_CCNmode:
+       case E_CCZmode:
+         return m1;
+       }
+    case E_CCNZmode:
+      switch (m2)
+       {
+       default:
+         gcc_unreachable ();
+       case E_CCmode:
+         return m2;
+       case E_CCNmode:
+       case E_CCNZmode:
+       case E_CCZmode:
+         return m1;
+       }
+    case E_CCNmode:
+    case E_CCZmode:
+      switch (m2)
+       {
+       default:
+         gcc_unreachable ();
+       case E_CCmode:
+       case E_CCNZmode:
+         return m2;
+       case E_CCNmode:
+       case E_CCZmode:
+         return m1 == m2 ? m1 : E_CCNZmode;
+       }
+    }
+}
+\f
+/* Mark PSL as clobbered for compatibility with the CC0 representation.  */
+
+static rtx_insn *
+vax_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
+                  vec<rtx> &inputs ATTRIBUTE_UNUSED,
+                  vec<const char *> &constraints ATTRIBUTE_UNUSED,
+                  vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs)
+{
+  clobbers.safe_push (gen_rtx_REG (CCmode, VAX_PSL_REGNUM));
+  SET_HARD_REG_BIT (clobbered_regs, VAX_PSL_REGNUM);
+  return NULL;
+}
+\f
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.
        .mask   ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>  #conservative entry mask
@@ -1102,81 +1214,21 @@ vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
   return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
 }
 
-/* Worker function for NOTICE_UPDATE_CC.  */
+/* Output integer move instructions.  */
 
-void
-vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
+bool
+vax_maybe_split_dimode_move (rtx *operands)
 {
-  if (GET_CODE (exp) == SET)
-    {
-      if (GET_CODE (SET_SRC (exp)) == CALL)
-       CC_STATUS_INIT;
-      else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
-              && GET_CODE (SET_DEST (exp)) != PC)
-       {
-         cc_status.flags = 0;
-         /* The integer operations below don't set carry or
-            set it in an incompatible way.  That's ok though
-            as the Z bit is all we need when doing unsigned
-            comparisons on the result of these insns (since
-            they're always with 0).  Set CC_NO_OVERFLOW to
-            generate the correct unsigned branches.  */
-         switch (GET_CODE (SET_SRC (exp)))
-           {
-           case NEG:
-             if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
-               break;
-             /* FALLTHRU */
-           case AND:
-           case IOR:
-           case XOR:
-           case NOT:
-           case MEM:
-           case REG:
-             cc_status.flags = CC_NO_OVERFLOW;
-             break;
-           case CTZ:
-             cc_status.flags = CC_NOT_NEGATIVE;
-             break;
-           default:
-             break;
-           }
-         cc_status.value1 = SET_DEST (exp);
-         cc_status.value2 = SET_SRC (exp);
-       }
-    }
-  else if (GET_CODE (exp) == PARALLEL
-          && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
-    {
-      if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
-       CC_STATUS_INIT;
-      else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
-       {
-         cc_status.flags = 0;
-         cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
-         cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
-       }
-      else
-       /* PARALLELs whose first element sets the PC are aob,
-          sob insns.  They do change the cc's.  */
-       CC_STATUS_INIT;
-    }
-  else
-    CC_STATUS_INIT;
-  if (cc_status.value1 && REG_P (cc_status.value1)
-      && cc_status.value2
-      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
-    cc_status.value2 = 0;
-  if (cc_status.value1 && MEM_P (cc_status.value1)
-      && cc_status.value2
-      && MEM_P (cc_status.value2))
-    cc_status.value2 = 0;
-  /* Actual condition, one line up, should be that value2's address
-     depends on value1, but that is too much of a pain.  */
+  return (TARGET_QMATH
+         && (!MEM_P (operands[0])
+             || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
+             || GET_CODE (XEXP (operands[0], 0)) == POST_INC
+             || !illegal_addsub_di_memory_operand (operands[0], DImode))
+         && ((CONST_INT_P (operands[1])
+              && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
+             || GET_CODE (operands[1]) == CONST_DOUBLE));
 }
 
-/* Output integer move instructions.  */
-
 const char *
 vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
                     machine_mode mode)
@@ -1252,14 +1304,7 @@ vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
            }
        }
 
-      if (TARGET_QMATH
-         && (!MEM_P (operands[0])
-             || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
-             || GET_CODE (XEXP (operands[0], 0)) == POST_INC
-             || !illegal_addsub_di_memory_operand (operands[0], DImode))
-         && ((CONST_INT_P (operands[1])
-              && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
-             || GET_CODE (operands[1]) == CONST_DOUBLE))
+      if (vax_maybe_split_dimode_move (operands))
        {
          hi[0] = operands[0];
          hi[1] = operands[1];
index 43182ff1d888f1c816f5e8dd31042b572cf6fb84..8b2b2d177040550bc0e1c662c09895719c849f73 100644 (file)
@@ -120,12 +120,12 @@ along with GCC; see the file COPYING3.  If not see
    from 0 to just below FIRST_PSEUDO_REGISTER.
    All registers that the compiler knows about must be given numbers,
    even those that are not normally considered general registers.  */
-#define FIRST_PSEUDO_REGISTER 16
+#define FIRST_PSEUDO_REGISTER 17
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.
    On the VAX, these are the AP, FP, SP and PC.  */
-#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -133,7 +133,7 @@ along with GCC; see the file COPYING3.  If not see
    The latter must include the registers where values are returned
    and the register where structure-value addresses are passed.
    Aside from that, you can include as many other registers as you like.  */
-#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}
+#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}
 
 /* Specify the registers used for certain standard purposes.
    The values of these macros are register numbers.  */
@@ -465,24 +465,11 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 #define BRANCH_COST(speed_p, predictable_p) 0
 \f
-/* Tell final.c how to eliminate redundant test instructions.  */
-
-/* Here we define machine-dependent flags and fields in cc_status
-   (see `conditions.h').  No extra ones are needed for the VAX.  */
-
-/* Store in cc_status the expressions
-   that the condition codes will describe
-   after execution of an instruction whose pattern is EXP.
-   Do not alter them if the instruction would not alter the cc's.  */
-
-#define NOTICE_UPDATE_CC(EXP, INSN)    \
-  vax_notice_update_cc ((EXP), (INSN))
-
-#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV)      \
-  { if (cc_status.flags & CC_NO_OVERFLOW)      \
-      return NO_OV;                            \
-    return NORMAL;                             \
-  }
+/* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE,
+   return the mode to be used for the comparison.  As we have the same
+   interpretation of condition codes across all the instructions we just
+   return the narrowest mode suitable for the comparison code requested.  */
+#define SELECT_CC_MODE(OP, X, Y) vax_select_cc_mode (OP, X, Y)
 \f
 /* Control the assembler format that we output.  */
 
@@ -517,7 +504,8 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
 #define REGISTER_PREFIX ""
 #define REGISTER_NAMES                                 \
   { "r0", "r1",  "r2",  "r3", "r4", "r5", "r6", "r7",  \
-    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc", }
+    "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",  \
+    "psl" }
 
 /* This is BSD, so it wants DBX format.  */
 
index 1bb4e300caef50dc8c54b92ca5e02a1546a87527..b8cf4eed4bc9fb28d2ce5ca766c7d6081456b841 100644 (file)
@@ -22,9 +22,6 @@
 ;;- the first one in the file is chosen.
 ;;-
 ;;- See file "rtl.def" for documentation on define_insn, match_*, et al.
-;;-
-;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
-;;- updates for most instructions.
 
 ;; UNSPEC_VOLATILE usage:
 
@@ -40,6 +37,8 @@
    (VAX_FP_REGNUM 13)      ; Register 13 contains the frame pointer
    (VAX_SP_REGNUM 14)      ; Register 14 contains the stack pointer
    (VAX_PC_REGNUM 15)      ; Register 15 contains the program counter
+   (VAX_PSL_REGNUM 16)     ; Register 16 contains the processor status
+                           ; and condition codes in particular
   ]
 )
 
 ;; Some output patterns want integer immediates with a prefix...
 (define_mode_attr  iprefx [(QI "B") (HI "H") (SI "N")])
 
+(define_mode_iterator VAXcc [CC CCN CCNZ CCZ])
+(define_mode_iterator VAXccnz [CCN CCNZ CCZ])
+(define_mode_attr cc [(CC "cc") (CCN "ccn") (CCNZ "ccnz") (CCZ "ccz")])
+
+(define_code_iterator any_extract [sign_extract zero_extract])
+
 ;;
 (include "constraints.md")
 (include "predicates.md")
 
-(define_insn "*cmp<mode>"
-  [(set (cc0)
-       (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
-                (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
+;; Make instructions that set the N, N+Z, and Z condition codes respectively.
+(define_subst "subst_<cc>"
+  [(set (match_operand 0 "")
+       (match_operand 1 ""))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
   ""
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz (match_dup 1)
+                        (const_int 0)))
+   (set (match_dup 0)
+       (match_dup 1))])
+
+(define_subst "subst_f<cc>"
+  [(set (match_operand 0 "")
+       (match_operand 1 ""))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  ""
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz (match_dup 1)
+                        (const_double_zero)))
+   (set (match_dup 0)
+       (match_dup 1))])
+
+;; Select all from the attributes below that apply to a given insn that
+;; has a clobber on CC for the comparison elimination pass to use it in
+;; place of a subsequent comparison instruction matching the mode used
+;; by a comparison operator in branch.
+;;
+;; For example a branch doing `eq' in SImode will use `*cmpsi_ccz', so
+;; to eliminate it a `*movsi_ccz', etc. pattern will be required via the
+;; `ccz' substitution.  Analogously for the other CC modes.
+;;
+;; The general `cc' mode, which sets all of the C, N, V and Z condition
+;; codes, has to be handled specially as it makes no sense for the usual
+;; comparison against zero, so no substitution has been defined for it.
+(define_subst_attr "ccn" "subst_ccn" "" "_ccn")
+(define_subst_attr "ccnz" "subst_ccnz" "" "_ccnz")
+(define_subst_attr "ccz" "subst_ccz" "" "_ccz")
+(define_subst_attr "fccn" "subst_fccn" "" "_ccn")
+(define_subst_attr "fccnz" "subst_fccnz" "" "_ccnz")
+(define_subst_attr "fccz" "subst_fccz" "" "_ccz")
+
+(define_insn "*cmp<VAXint:mode>_<VAXcc:mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc (match_operand:VAXint 0 "general_operand" "nrmT,nrmT")
+                      (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
+  "reload_completed"
   "@
    tst<VAXint:isfx> %0
    cmp<VAXint:isfx> %0,%1")
 
-(define_insn "*cmp<mode>"
-  [(set (cc0)
-       (compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
-                (match_operand:VAXfp 1 "general_operand" "G,gF")))]
-  ""
+;; We don't have a CMPQ instruction, but we can set the N and Z condition
+;; codes with MOVQ, and also this comparison can be folded into a preceding
+;; operation by the post-reload comparison elimination pass.
+(define_insn "*cmpdi_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz (match_operand:DI 0 "general_operand" "r,nmT")
+                        (match_operand:DI 1 "const_zero_operand" "I,I")))
+   (clobber (match_scratch:DI 2 "=X,r"))]
+  "reload_completed"
+  "@
+   movq %0,%0
+   movq %0,%2")
+
+(define_insn "*cmp<VAXfp:mode>_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz (match_operand:VAXfp 0 "general_operand" "gF,gF")
+                        (match_operand:VAXfp 1 "general_operand" "G,gF")))]
+  "reload_completed"
   "@
    tst<VAXfp:fsfx> %0
    cmp<VAXfp:fsfx> %0,%1")
 
-(define_insn "*bit<mode>"
-  [(set (cc0)
-       (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
-                            (match_operand:VAXint 1 "general_operand" "nrmT"))
-                (const_int 0)))]
-  ""
+(define_insn "*bit<VAXint:mode>_<VAXccnz:mode>"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz
+         (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
+                     (match_operand:VAXint 1 "general_operand" "nrmT"))
+         (const_int 0)))]
+  "reload_completed"
   "bit<VAXint:isfx> %0,%1")
 
 ;; The VAX has no sCOND insns.  It does have add/subtract with carry
 ;; and has been deleted.
 
 \f
-(define_insn "mov<mode>"
+(define_insn_and_split "mov<mode>"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
        (match_operand:VAXfp 1 "general_operand" "G,gF"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mov<mode><fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+       (match_operand:VAXfp 1 "general_operand" "G,gF"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    clr<VAXfp:fsfx> %0
    mov<VAXfp:fsfx> %1,%0")
 
 ;; Some VAXen don't support this instruction.
-;;(define_insn "movti"
+;;(define_insn_and_split "movti"
 ;;  [(set (match_operand:TI 0 "nonimmediate_operand" "=g")
 ;;     (match_operand:TI 1 "general_operand" "g"))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;        (match_dup 1))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*movti<ccn><ccnz><ccz>"
+;;  [(set (match_operand:TI 0 "nonimmediate_operand" "=g")
+;;     (match_operand:TI 1 "general_operand" "g"))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "movo %1,%0")
 
-(define_insn "movdi"
+(define_insn_and_split "movdi"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (match_operand:DI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+;; In some cases `vax_output_int_move' splits a `DImode' move into a pair
+;; of `SImode' moves, in which case the flags aren't usefully set.  Have
+;; separate patterns then, for the cases where the move may and may not be
+;; split each.  We use the outer condition only so in some cases we will
+;; fail to notice the move does not actually get split, but this is OK.
+(define_insn "*movdi_maybe_split"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (match_operand:DI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed && vax_maybe_split_dimode_move (operands)"
+  "* return vax_output_int_move (insn, operands, DImode);")
+
+(define_insn "*movdi_unsplit<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (match_operand:DI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed && !vax_maybe_split_dimode_move (operands)"
   "* return vax_output_int_move (insn, operands, DImode);")
 
 ;; The VAX move instructions have space-time tradeoffs.  On a MicroVAX
 #endif
 }")
 
-(define_insn "movsi_2"
+(define_insn_and_split "movsi_2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsi_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (match_operand:SI 1 "nonsymbolic_operand" "nrmT"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_move (insn, operands, SImode);")
 
-(define_insn "mov<mode>"
+(define_insn_and_split "mov<mode>"
   [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
        (match_operand:VAXintQH 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mov<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:VAXintQH 0 "nonimmediate_operand" "=g")
+       (match_operand:VAXintQH 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_move (insn, operands, <MODE>mode);")
 
-(define_insn "movstricthi"
-  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+g"))
+(define_insn_and_split "movstricthi"
+  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
        (match_operand:HI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (strict_low_part (match_dup 0))
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movstricthi<ccn><ccnz><ccz>"
+  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
+       (match_operand:HI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (CONST_INT_P (operands[1]))
   return \"movw %1,%0\";
 }")
 
-(define_insn "movstrictqi"
-  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+g"))
+(define_insn_and_split "movstrictqi"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
        (match_operand:QI 1 "general_operand" "g"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (strict_low_part (match_dup 0))
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movstrictqi<ccn><ccnz><ccz>"
+  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+r"))
+       (match_operand:QI 1 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (CONST_INT_P (operands[1]))
 ;; that anything generated as this insn will be recognized as one
 ;; and that it won't successfully combine with anything.
 
-(define_insn "movmemhi1"
+(define_insn_and_split "movmemhi1"
   [(set (match_operand:BLK 0 "memory_operand" "=o")
        (match_operand:BLK 1 "memory_operand" "o"))
    (use (match_operand:HI 2 "general_operand" "g"))
    (clobber (reg:SI 4))
    (clobber (reg:SI 5))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (use (match_dup 2))
+      (clobber (reg:SI 0))
+      (clobber (reg:SI 1))
+      (clobber (reg:SI 2))
+      (clobber (reg:SI 3))
+      (clobber (reg:SI 4))
+      (clobber (reg:SI 5))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movmemhi1"
+  [(set (match_operand:BLK 0 "memory_operand" "=o")
+       (match_operand:BLK 1 "memory_operand" "o"))
+   (use (match_operand:HI 2 "general_operand" "g"))
+   (clobber (reg:SI 0))
+   (clobber (reg:SI 1))
+   (clobber (reg:SI 2))
+   (clobber (reg:SI 3))
+   (clobber (reg:SI 4))
+   (clobber (reg:SI 5))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movc3 %2,%1,%0")
 \f
 ;; Extension and truncation insns.
 
-(define_insn "truncsiqi2"
+(define_insn_and_split "truncsiqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
        (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (truncate:QI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncsiqi2<ccn><ccnz><ccz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+       (truncate:QI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtlb %1,%0")
 
-(define_insn "truncsihi2"
+(define_insn_and_split "truncsihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
        (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (truncate:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncsihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+       (truncate:HI (match_operand:SI 1 "nonimmediate_operand" "nrmT")))
+      (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtlw %1,%0")
 
-(define_insn "trunchiqi2"
+(define_insn_and_split "trunchiqi2"
   [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
        (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (truncate:QI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*trunchiqi2<ccn><ccnz><ccz>"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=g")
+       (truncate:QI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtwb %1,%0")
 
-(define_insn "extendhisi2"
+(define_insn_and_split "extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendhisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtwl %1,%0")
 
-(define_insn "extendqihi2"
+(define_insn_and_split "extendqihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
        (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extend:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendqihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+       (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtbw %1,%0")
 
-(define_insn "extendqisi2"
+(define_insn_and_split "extendqisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendqisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtbl %1,%0")
 
-(define_insn "extendsfdf2"
+(define_insn_and_split "extendsfdf2"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
        (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (float_extend:DF (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extendsfdf2<fccn><fccnz><fccz>"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=g")
+       (float_extend:DF (match_operand:SF 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvtf%# %1,%0")
 
-(define_insn "truncdfsf2"
+(define_insn_and_split "truncdfsf2"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
        (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (float_truncate:SF (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*truncdfsf2<fccn><fccnz><fccz>"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=g")
+       (float_truncate:SF (match_operand:DF 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt%#f %1,%0")
 
-(define_insn "zero_extendhisi2"
+(define_insn_and_split "zero_extendhisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendhisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzwl %1,%0")
 
-(define_insn "zero_extendqihi2"
+(define_insn_and_split "zero_extendqihi2"
   [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extend:HI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendqihi2<ccn><ccnz><ccz>"
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=g")
+       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzbw %1,%0")
 
-(define_insn "zero_extendqisi2"
+(define_insn_and_split "zero_extendqisi2"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extend:SI (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*zero_extendqisi2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movzbl %1,%0")
 \f
 ;; Fix-to-float conversion insns.
 
-(define_insn "float<VAXint:mode><VAXfp:mode>2"
+(define_insn_and_split "float<VAXint:mode><VAXfp:mode>2"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
        (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (float:VAXfp (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*float<VAXint:mode><VAXfp:mode>2<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
+       (float:VAXfp (match_operand:VAXint 1 "nonimmediate_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt<VAXint:isfx><VAXfp:fsfx> %1,%0")
 
 ;; Float-to-fix conversion insns.
 
-(define_insn "fix_trunc<VAXfp:mode><VAXint:mode>2"
+(define_insn_and_split "fix_trunc<VAXfp:mode><VAXint:mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
        (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (fix:VAXint (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*fix_trunc<VAXfp:mode><VAXint:mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+       (fix:VAXint (match_operand:VAXfp 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "cvt<VAXfp:fsfx><VAXint:isfx> %1,%0")
 
 (define_expand "fixuns_trunc<VAXfp:mode><VAXint:mode>2"
 \f
 ;;- All kinds of add instructions.
 
-(define_insn "add<mode>3"
+(define_insn_and_split "add<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
        (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
                    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:VAXfp (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*add<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
+       (plus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
+                   (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    add<VAXfp:fsfx>2 %2,%0
    add<VAXfp:fsfx>2 %1,%0
    add<VAXfp:fsfx>3 %1,%2,%0")
 
-(define_insn "add<mode>3"
+(define_insn_and_split "add<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
        (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
                     (match_operand:VAXint 2 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:VAXint (match_dup 1)
+                       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*add<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+       (plus:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")
+                    (match_operand:VAXint 2 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "* return vax_output_int_add (insn, operands, <MODE>mode);")
 
 (define_expand "adddi3"
   "!reload_in_progress"
   "vax_expand_addsub_di_operands (operands, PLUS); DONE;")
 
-(define_insn "adcdi3"
+(define_insn_and_split "adcdi3"
   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
        (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
                 (match_operand:DI 2 "general_addsub_di_operand" "nRr")))]
   "TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:DI (match_dup 1)
+                   (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*adcdi3<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr")
+       (plus:DI (match_operand:DI 1 "general_addsub_di_operand" "%0")
+                (match_operand:DI 2 "general_addsub_di_operand" "nRr")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "TARGET_QMATH && reload_completed"
   "* return vax_output_int_add (insn, operands, DImode);")
 
 ;; The add-with-carry (adwc) instruction only accepts two operands.
-(define_insn "adddi3_old"
+(define_insn_and_split "adddi3_old"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
        (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
                 (match_operand:DI 2 "general_operand" "Fsro,Fs")))]
   "!TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:DI (match_dup 1)
+                   (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*adddi3_old<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro>,ro>")
+       (plus:DI (match_operand:DI 1 "general_operand" "%0,ro>")
+                (match_operand:DI 2 "general_operand" "Fsro,Fs")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_QMATH && reload_completed"
   "* return vax_output_int_add (insn, operands, DImode);")
 \f
 ;;- All kinds of subtract instructions.
 
-(define_insn "sub<mode>3"
+(define_insn_and_split "sub<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
        (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
                     (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (minus:VAXfp (match_dup 1)
+                       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sub<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+       (minus:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
+                    (match_operand:VAXfp 2 "general_operand" "gF,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    sub<VAXfp:fsfx>2 %2,%0
    sub<VAXfp:fsfx>3 %2,%1,%0")
 
-(define_insn "sub<mode>3"
+(define_insn_and_split "sub<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
        (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
                      (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (minus:VAXint (match_dup 1)
+                        (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sub<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (minus:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+                     (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "@
+   sub<VAXint:isfx>2 %2,%0
+   sub<VAXint:isfx>3 %2,%1,%0")
+
+(define_insn "*sub<mode>3_cc"
+  [(set (reg:CC VAX_PSL_REGNUM)
+       (compare:CC (match_operand:VAXint 1 "general_operand" "0,nrmT")
+                   (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (minus:VAXint (match_dup 1)
+                     (match_dup 2)))]
+  "reload_completed"
   "@
    sub<VAXint:isfx>2 %2,%0
    sub<VAXint:isfx>3 %2,%1,%0")
   "!reload_in_progress"
   "vax_expand_addsub_di_operands (operands, MINUS); DONE;")
 
-(define_insn "sbcdi3"
+(define_insn_and_split "sbcdi3"
   [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
        (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
                  (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))]
   "TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (minus:DI (match_dup 1)
+                    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*sbcdi3<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_addsub_di_operand" "=Rr,Rr")
+       (minus:DI (match_operand:DI 1 "general_addsub_di_operand" "0,I")
+                 (match_operand:DI 2 "general_addsub_di_operand" "nRr,Rr")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "TARGET_QMATH && reload_completed"
   "* return vax_output_int_subtract (insn, operands, DImode);")
 
 ;; The subtract-with-carry (sbwc) instruction only takes two operands.
-(define_insn "subdi3_old"
+(define_insn_and_split "subdi3_old"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
        (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
                  (match_operand:DI 2 "general_operand" "Fsor,Fs")))]
   "!TARGET_QMATH"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (minus:DI (match_dup 1)
+                    (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*subdi3_old<ccn>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=or>,or>")
+       (minus:DI (match_operand:DI 1 "general_operand" "0,or>")
+                 (match_operand:DI 2 "general_operand" "Fsor,Fs")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_QMATH && reload_completed"
   "* return vax_output_int_subtract (insn, operands, DImode);")
 \f
 ;;- Multiply instructions.
 
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
        (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
                    (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (mult:VAXfp (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mul<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g,g")
+       (mult:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF,gF")
+                   (match_operand:VAXfp 2 "general_operand" "gF,0,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    mul<VAXfp:fsfx>2 %2,%0
    mul<VAXfp:fsfx>2 %1,%0
    mul<VAXfp:fsfx>3 %1,%2,%0")
 
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
        (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
                     (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (mult:VAXint (match_dup 1)
+                       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mul<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+       (mult:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+                    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    mul<VAXint:isfx>2 %2,%0
    mul<VAXint:isfx>2 %1,%0
    mul<VAXint:isfx>3 %1,%2,%0")
 
-(define_insn "mulsidi3"
+(define_insn_and_split "mulsidi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (mult:DI
          (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
          (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (mult:DI
+            (sign_extend:DI (match_dup 1))
+            (sign_extend:DI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*mulsidi3<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (mult:DI
+         (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+         (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "emul %1,%2,$0,%0")
 
-(define_insn "*maddsidi4"
+(define_insn_and_split "*maddsidi4"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (plus:DI
          (mult:DI
            (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
          (sign_extend:DI (match_operand:SI 3 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:DI
+            (mult:DI
+              (sign_extend:DI (match_dup 1))
+              (sign_extend:DI (match_dup 2)))
+            (sign_extend:DI (match_dup 3))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*maddsidi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (plus:DI
+         (mult:DI
+           (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+           (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+         (sign_extend:DI (match_operand:SI 3 "nonimmediate_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "emul %1,%2,%3,%0")
 
 ;; 'F' constraint means type CONST_DOUBLE
-(define_insn "*maddsidi4_const"
+(define_insn_and_split "*maddsidi4_const"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (plus:DI
          (mult:DI
          (match_operand:DI 3 "immediate_operand" "F")))]
   "GET_CODE (operands[3]) == CONST_DOUBLE
    && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:DI
+            (mult:DI
+              (sign_extend:DI (match_dup 1))
+              (sign_extend:DI (match_dup 2)))
+            (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*maddsidi4_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (plus:DI
+         (mult:DI
+           (sign_extend:DI (match_operand:SI 1 "general_operand" "nrmT"))
+           (sign_extend:DI (match_operand:SI 2 "general_operand" "nrmT")))
+         (match_operand:DI 3 "immediate_operand" "F")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "GET_CODE (operands[3]) == CONST_DOUBLE
+   && CONST_DOUBLE_HIGH (operands[3]) == (CONST_DOUBLE_LOW (operands[3]) >> 31)
+   && reload_completed"
   "*
 {
   if (CONST_DOUBLE_HIGH (operands[3]))
 \f
 ;;- Divide instructions.
 
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
        (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
                   (match_operand:VAXfp 2 "general_operand" "gF,gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (div:VAXfp (match_dup 1)
+                     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*div<mode>3<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g,g")
+       (div:VAXfp (match_operand:VAXfp 1 "general_operand" "0,gF")
+                  (match_operand:VAXfp 2 "general_operand" "gF,gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    div<VAXfp:fsfx>2 %2,%0
    div<VAXfp:fsfx>3 %2,%1,%0")
 
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
        (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
                    (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (div:VAXint (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*div<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (div:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+                   (match_operand:VAXint 2 "general_operand" "nrmT,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    div<VAXint:isfx>2 %2,%0
    div<VAXint:isfx>3 %2,%1,%0")
 
 ;; This is left out because it is very slow;
 ;; we are better off programming around the "lack" of this insn.
-;;(define_insn "divmoddisi4"
+;;(define_insn_and_split "divmoddisi4"
 ;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;;     (div:SI (match_operand:DI 1 "general_operand" "g")
 ;;             (match_operand:SI 2 "general_operand" "g")))
 ;;     (mod:SI (match_dup 1)
 ;;             (match_dup 2)))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;        (div:SI (match_dup 1)
+;;                (match_dup 2)))
+;;      (set (match_dup 3)
+;;        (mod:SI (match_dup 1)
+;;                (match_dup 2)))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*divmoddisi4<ccn><ccnz><ccz>"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;     (div:SI (match_operand:DI 1 "general_operand" "g")
+;;             (match_operand:SI 2 "general_operand" "g")))
+;;   (set (match_operand:SI 3 "nonimmediate_operand" "=g")
+;;     (mod:SI (match_dup 1)
+;;             (match_dup 2)))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "ediv %2,%1,%0,%3")
 \f
 ;; Bit-and on the VAX is done with a clear-bits insn.
     operands[1] = expand_unop (<MODE>mode, one_cmpl_optab, op1, 0, 1);
 }")
 
-(define_insn "*and<mode>"
+(define_insn_and_split "*and<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
-       (and:VAXint (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
+       (and:VAXint (not:VAXint
+                     (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
                    (match_operand:VAXint 2 "general_operand" "0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (and:VAXint (not:VAXint
+                        (match_dup 1))
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*and<mode>3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (and:VAXint (not:VAXint
+                     (match_operand:VAXint 1 "general_operand" "nrmT,nrmT"))
+                   (match_operand:VAXint 2 "general_operand" "0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bic<VAXint:isfx>2 %1,%0
    bic<VAXint:isfx>3 %1,%2,%0")
 ;; longer a problem.  However, having these patterns allows optimization
 ;; opportunities in combine.c.
 
-(define_insn "*and<mode>_const_int"
+(define_insn_and_split "*and<mode>3_const_int"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
        (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
                    (match_operand:VAXint 2 "const_int_operand" "n,n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (and:VAXint (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*and<mode>3_2_const_int<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (and:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT")
+                   (match_operand:VAXint 2 "const_int_operand" "n,n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bic<VAXint:isfx>2 %<VAXint:iprefx>2,%0
    bic<VAXint:isfx>3 %<VAXint:iprefx>2,%1,%0")
 
+;; We have no direct AND operation and consequently the RTL sequence
+;; the "and<mode>3" pattern produces does not match the instruction
+;; the "*bit<mode>" pattern does for the purpose of the compare
+;; elimination pass.  Try to get rid of the extra operation by hand
+;; and where the sequence is used to set the condition codes only
+;; convert MNEG/BIC => BIT.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:VAXint 0 "register_operand")
+          (not:VAXint (match_operand:VAXint 1 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (parallel
+     [(set (reg:VAXccnz VAX_PSL_REGNUM)
+          (compare:VAXccnz
+            (and:VAXint (not:VAXint (match_dup 0))
+                        (match_operand:VAXint 3 "general_operand"))
+            (const_int 0)))
+      (set (match_operand:VAXint 2 "register_operand")
+          (and:VAXint (not:VAXint (match_dup 0))
+                      (match_dup 3)))])]
+  "peep2_reg_dead_p (2, operands[0]) && peep2_reg_dead_p (2, operands[2])"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz
+         (and:VAXint (match_dup 1)
+                     (match_dup 3))
+         (const_int 0)))]
+  "")
 \f
 ;;- Bit set instructions.
 
-(define_insn "ior<mode>3"
+(define_insn_and_split "ior<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
        (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
                    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ior:VAXint (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ior<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+       (ior:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+                   (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    bis<VAXint:isfx>2 %2,%0
    bis<VAXint:isfx>2 %1,%0
 
 ;;- xor instructions.
 
-(define_insn "xor<mode>3"
+(define_insn_and_split "xor<mode>3"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
        (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
                    (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (xor:VAXint (match_dup 1)
+                      (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*xor<mode>3<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g,g")
+       (xor:VAXint (match_operand:VAXint 1 "general_operand" "0,nrmT,nrmT")
+                   (match_operand:VAXint 2 "general_operand" "nrmT,0,nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "@
    xor<VAXint:isfx>2 %2,%0
    xor<VAXint:isfx>2 %1,%0
    xor<VAXint:isfx>3 %2,%1,%0")
-
 \f
-(define_insn "neg<mode>2"
+(define_insn_and_split "neg<mode>2"
   [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
        (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (neg:VAXfp (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*neg<mode>2<fccn><fccnz><fccz>"
+  [(set (match_operand:VAXfp 0 "nonimmediate_operand" "=g")
+       (neg:VAXfp (match_operand:VAXfp 1 "general_operand" "gF")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mneg<VAXfp:fsfx> %1,%0")
 
-(define_insn "neg<mode>2"
+(define_insn_and_split "neg<mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
        (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (neg:VAXint (match_dup 1)))
+        (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*neg<mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+       (neg:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "mneg<VAXint:isfx> %1,%0")
+
+(define_insn "*neg<mode>2_cc"
+  [(set (reg:CC VAX_PSL_REGNUM)
+       (compare:CC (const_int 0)
+                   (neg:VAXint
+                     (match_operand:VAXint 1 "general_operand" "0,nrmT"))))
+   (set (match_operand:VAXint 0 "nonimmediate_operand" "=g,g")
+       (neg:VAXint (match_dup 1)))]
+  "reload_completed"
   "mneg<VAXint:isfx> %1,%0")
 
-(define_insn "one_cmpl<mode>2"
+(define_insn_and_split "one_cmpl<mode>2"
   [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
        (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))]
   ""
-  "mcom<VAXint:isfx> %1,%0")
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (not:VAXint (match_dup 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
 
+(define_insn "*one_cmpl<mode>2<ccn><ccnz><ccz>"
+  [(set (match_operand:VAXint 0 "nonimmediate_operand" "=g")
+       (not:VAXint (match_operand:VAXint 1 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
+  "mcom<VAXint:isfx> %1,%0")
 \f
 ;; Arithmetic right shift on the VAX works by negating the shift count,
 ;; then emitting a right shift with the shift count negated.  This means
     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegsi3_const_int"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
                     (match_operand:QI 2 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ashiftrt:SI (match_dup 1)
+                       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegsi3_const_int_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+                    (match_operand:QI 2 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashl $%n2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ashiftrt:SI (match_dup 1)
+                       (neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegsi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+                    (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashl %2,%1,%0")
 
-(define_insn "ashlsi3"
+(define_insn_and_split "ashlsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
                   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ashift:SI (match_dup 1)
+                     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlsi3<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
+                  (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (operands[2] == const1_rtx && rtx_equal_p (operands[0], operands[1]))
   operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn "ashldi3"
+(define_insn_and_split "ashldi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (ashift:DI (match_operand:DI 1 "general_operand" "g")
                   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ashift:DI (match_dup 1)
+                     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashldi3<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (ashift:DI (match_operand:DI 1 "general_operand" "g")
+                  (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashq %2,%D1,%0")
 
-(define_insn ""
+(define_insn_and_split "*ashlnegdi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
        (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (ashiftrt:DI (match_dup 1)
+                       (neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*ashlnegdi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=g")
+       (ashiftrt:DI (match_operand:DI 1 "general_operand" "g")
+                    (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "ashq %2,%D1,%0")
 
 ;; We used to have expand_shift handle logical right shifts by using extzv,
     operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
 }")
 
-(define_insn "rotlsi3"
+(define_insn_and_split "rotlsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
                   (match_operand:QI 2 "general_operand" "g")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (rotate:SI (match_dup 1)
+                     (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotlsi3<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (rotate:SI (match_operand:SI 1 "general_operand" "nrmT")
+                  (match_operand:QI 2 "general_operand" "g")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*rotrsi3_const_int"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
                     (match_operand:QI 2 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (rotatert:SI (match_dup 1)
+                       (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotrsi3_const_int_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
+                    (match_operand:QI 2 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %R2,%1,%0")
 
-(define_insn ""
+(define_insn_and_split "*rotrnegsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
                     (neg:QI (match_operand:QI 2 "general_operand" "g"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (rotatert:SI (match_dup 1)
+                       (neg:QI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*rotrnegsi3_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (rotatert:SI (match_operand:SI 1 "general_operand" "nrmT")
+                    (neg:QI (match_operand:QI 2 "general_operand" "g"))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "rotl %2,%1,%0")
 
 ;; This insn is probably slower than a multiply and an add.
-;;(define_insn "*amulsi4"
+;;(define_insn_and_split "*amulsi4"
 ;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
 ;;     (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
 ;;                       (match_operand:SI 2 "general_operand" "g"))
 ;;              (match_operand:SI 3 "general_operand" "g")))]
 ;;  ""
+;;  "#"
+;;  "reload_completed"
+;;  [(parallel
+;;     [(set (match_dup 0)
+;;        (mult:SI (plus:SI (match_dup 1)
+;;                          (match_dup 2))
+;;                 (match_dup 3)))
+;;      (clobber (reg:CC VAX_PSL_REGNUM))])]
+;;  "")
+;;
+;;(define_insn "*amulsi4_2<ccn><ccnz><ccz>"
+;;  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+;;     (mult:SI (plus:SI (match_operand:SI 1 "general_operand" "g")
+;;                       (match_operand:SI 2 "general_operand" "g"))
+;;              (match_operand:SI 3 "general_operand" "g")))
+;;   (clobber (reg:CC VAX_PSL_REGNUM))]
+;;  "reload_completed"
 ;;  "index %1,$0x80000000,$0x7fffffff,%3,%2,%0")
 \f
 ;; Special cases of bit-field insns which we should
 ;; These handle aligned 8-bit and 16-bit fields
 ;; that can be done with move or convert instructions.
 
-(define_insn "*insv_aligned"
+(define_insn_and_split "*insv_aligned"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
                         (match_operand:QI 1 "const_int_operand" "n")
                         (match_operand:SI 2 "const_int_operand" "n"))
    && (!(REG_P (operands[0])
         || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
        || INTVAL (operands[2]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (zero_extract:SI (match_dup 0)
+                           (match_dup 1)
+                           (match_dup 2))
+          (match_dup 3))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*insv_aligned_2<ccn><ccnz><ccz>"
+  [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
+                        (match_operand:QI 1 "const_int_operand" "n")
+                        (match_operand:SI 2 "const_int_operand" "n"))
+       (match_operand:SI 3 "general_operand" "g"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
+   && INTVAL (operands[2]) % INTVAL (operands[1]) == 0
+   && (!MEM_P (operands[0])
+       || ((!flag_pic
+           || vax_acceptable_pic_operand_p (XEXP (operands[0], 0),
+                                            true, true))
+          && !mode_dependent_address_p (XEXP (operands[0], 0),
+                                        MEM_ADDR_SPACE (operands[0]))))
+   && (!(REG_P (operands[0])
+        || (SUBREG_P (operands[0]) && REG_P (SUBREG_REG (operands[0]))))
+       || INTVAL (operands[2]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[0]))
   else
     gcc_assert (INTVAL (operands[2]) == 0);
 
-  CC_STATUS_INIT;
   if (INTVAL (operands[1]) == 8)
     return \"movb %3,%0\";
   return \"movw %3,%0\";
 }")
 
-(define_insn "*extzv_aligned"
+(define_insn_and_split "*extzv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
        (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
                         (match_operand:QI 2 "const_int_operand" "n")
    && (!(REG_P (operands[1])
         || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_aligned_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=&g")
+       (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+                        (match_operand:QI 2 "const_int_operand" "n")
+                        (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
+   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
+   && (!MEM_P (operands[1])
+       || ((!flag_pic
+           || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+                                            true, true))
+          && !mode_dependent_address_p (XEXP (operands[1], 0),
+                                        MEM_ADDR_SPACE (operands[1]))))
+   && (!(REG_P (operands[1])
+        || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[1]))
   return \"movzwl %1,%0\";
 }")
 
-(define_insn "*extv_aligned"
+(define_insn_and_split "*extv_aligned"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
                         (match_operand:QI 2 "const_int_operand" "n")
    && (!(REG_P (operands[1])
         || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
        || INTVAL (operands[3]) == 0)"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_aligned_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+                        (match_operand:QI 2 "const_int_operand" "n")
+                        (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
+   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0
+   && (!MEM_P (operands[1])
+       || ((!flag_pic
+           || vax_acceptable_pic_operand_p (XEXP (operands[1], 0),
+                                            true, true))
+          && !mode_dependent_address_p (XEXP (operands[1], 0),
+                                        MEM_ADDR_SPACE (operands[1]))))
+   && (!(REG_P (operands[1])
+        || (SUBREG_P (operands[1]) && REG_P (SUBREG_REG (operands[1]))))
+       || INTVAL (operands[3]) == 0)
+   && reload_completed"
   "*
 {
   if (!REG_P (operands[1]))
 \f
 ;; Register and non-offsettable-memory SImode cases of bit-field insns.
 
-(define_insn "*cmpv"
-  [(set (cc0)
-       (compare
+(define_insn "*cmpv_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc
         (sign_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
                          (match_operand:QI 1 "general_operand" "g")
                          (match_operand:SI 2 "general_operand" "nrmT"))
         (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpv %2,%1,%0,%3")
 
-(define_insn "*cmpzv"
-  [(set (cc0)
-       (compare
+(define_insn "*cmpzv_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc
         (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "ro")
                          (match_operand:QI 1 "general_operand" "g")
                          (match_operand:SI 2 "general_operand" "nrmT"))
         (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpzv %2,%1,%0,%3")
 
 ;; When the field position and size are constant and the destination
 ;; by a bicl or sign extension.  Because we might end up choosing ext[z]v
 ;; anyway, we can't allow immediate values for the primary source operand.
 
-(define_insn "*extv_non_const"
+(define_insn_and_split "*extv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
                         (match_operand:QI 2 "general_operand" "g")
                         (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_non_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+                        (match_operand:QI 2 "general_operand" "g")
+                        (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
   return \"rotl %R3,%1,%0\;cvtwl %0,%0\";
 }")
 
-(define_insn "*extzv_non_const"
+(define_insn_and_split "*extzv_non_const"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
                         (match_operand:QI 2 "general_operand" "g")
                         (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_non_const_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
+                        (match_operand:QI 2 "general_operand" "g")
+                        (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (! CONST_INT_P (operands[3]) || ! CONST_INT_P (operands[2])
 ;; nonimmediate_operand is used to make sure that mode-ambiguous cases
 ;; don't match these (and therefore match the cases above instead).
 
-(define_insn "*cmpv_2"
-  [(set (cc0)
-       (compare
+(define_insn "*cmpv_2_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc
         (sign_extract:SI (match_operand:QI 0 "memory_operand" "m")
                          (match_operand:QI 1 "general_operand" "g")
                          (match_operand:SI 2 "general_operand" "nrmT"))
         (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpv %2,%1,%0,%3")
 
-(define_insn "*cmpzv_2"
-  [(set (cc0)
-       (compare
+(define_insn "*cmpzv_2_<mode>"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc
         (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
                          (match_operand:QI 1 "general_operand" "g")
                          (match_operand:SI 2 "general_operand" "nrmT"))
         (match_operand:SI 3 "general_operand" "nrmT")))]
-  ""
+  "reload_completed"
   "cmpzv %2,%1,%0,%3")
 
 (define_expand "extv"
   ""
   "")
 
-(define_insn "*extv"
+(define_insn_and_split "*extv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
                         (match_operand:QI 2 "general_operand" "g")
                         (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (sign_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extv_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
+                        (match_operand:QI 2 "general_operand" "g")
+                        (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
   ""
   "")
 
-(define_insn "*extzv"
+(define_insn_and_split "*extzv"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
                         (match_operand:QI 2 "general_operand" "g")
                         (match_operand:SI 3 "general_operand" "nrmT")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (zero_extract:SI (match_dup 1)
+                           (match_dup 2)
+                           (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*extzv_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
+                        (match_operand:QI 2 "general_operand" "g")
+                        (match_operand:SI 3 "general_operand" "nrmT")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   if (!REG_P (operands[0]) || !CONST_INT_P (operands[2])
   return \"rotl %R3,%1,%0\;bicl2 %M2,%0\";
 }")
 
+;; Combine EXTV/CMPL and EXTZV/CMPL sequences where the output of
+;; extraction is used for the comparison only into CMPV and CMPZV
+;; respectively.
+(define_peephole2
+  [(parallel
+     [(set (match_operand:SI 0 "register_operand")
+          (any_extract:SI (match_operand 1 "general_operand")
+                          (match_operand:QI 2 "general_operand")
+                          (match_operand:SI 3 "general_operand")))
+      (clobber (reg:CC VAX_PSL_REGNUM))])
+   (set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc (match_dup 0)
+                      (match_operand:SI 4 "general_operand")))]
+  "peep2_reg_dead_p (2, operands[0])"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc
+         (any_extract:SI (match_dup 1)
+                         (match_dup 2)
+                         (match_dup 3))
+         (match_dup 4)))]
+  "")
+
 (define_expand "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "")
                         (match_operand:QI 1 "general_operand" "")
   ""
   "")
 
+;; This one actually doesn't change CC.
 (define_insn "*insv"
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
                         (match_operand:QI 1 "general_operand" "g")
   return \"insv %3,%2,%1,%0\";
 }")
 
+;; This one actually doesn't change CC.
 (define_insn "*insv_2"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+ro")
                         (match_operand:QI 1 "general_operand" "g")
 ;; Conditional jumps
 
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-        (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
-                 (match_operand:VAXint 2 "general_operand" "")))
+  [(set (pc)
+       (if_then_else
+         (match_operator 0 "ordered_comparison_operator"
+                         [(match_operand:VAXint 1 "general_operand" "")
+                          (match_operand:VAXint 2 "general_operand" "")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  ""
+  "")
+
+(define_insn_and_split "*cbranch<VAXint:mode>4_<VAXcc:mode>"
+  [(set (pc)
+       (if_then_else
+         (match_operator 0 "vax_<cc>_comparison_operator"
+                         [(match_operand:VAXint 1 "general_operand" "nrmT")
+                          (match_operand:VAXint 2 "general_operand" "nrmT")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:VAXcc VAX_PSL_REGNUM)
+       (compare:VAXcc (match_dup 1) (match_dup 2)))
    (set (pc)
-        (if_then_else
-              (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                               (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
-              (pc)))]
- "")
+       (if_then_else
+         (match_op_dup 0 [(reg:VAXcc VAX_PSL_REGNUM)
+                          (const_int 0)])
+        (label_ref (match_operand 3 "" ""))
+        (pc)))]
 "")
 
 (define_expand "cbranch<mode>4"
-  [(set (cc0)
-        (compare (match_operand:VAXfp 1 "general_operand" "")
-                 (match_operand:VAXfp 2 "general_operand" "")))
+  [(set (pc)
+       (if_then_else
+         (match_operator 0 "ordered_comparison_operator"
+                         [(match_operand:VAXfp 1 "general_operand" "")
+                          (match_operand:VAXfp 2 "general_operand" "")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  ""
+  "")
+
+(define_insn_and_split "*cbranch<VAXfp:mode>4_<VAXccnz:mode>"
+  [(set (pc)
+       (if_then_else
+         (match_operator 0 "vax_<cc>_comparison_operator"
+                         [(match_operand:VAXfp 1 "general_operand" "gF")
+                          (match_operand:VAXfp 2 "general_operand" "gF")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
+  ""
+  "#"
+  "reload_completed"
+  [(set (reg:VAXccnz VAX_PSL_REGNUM)
+       (compare:VAXccnz (match_dup 1) (match_dup 2)))
    (set (pc)
-        (if_then_else
-              (match_operator 0 "ordered_comparison_operator" [(cc0)
-                                                               (const_int 0)])
-              (label_ref (match_operand 3 "" ""))
-              (pc)))]
- "")
-
-(define_insn "*branch"
+       (if_then_else
+         (match_op_dup 0 [(reg:VAXccnz VAX_PSL_REGNUM)
+                          (const_int 0)])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))]
 "")
+
+(define_insn "*branch_<mode>"
   [(set (pc)
-       (if_then_else (match_operator 0 "ordered_comparison_operator"
-                                     [(cc0)
+       (if_then_else (match_operator 0 "vax_<cc>_comparison_operator"
+                                     [(reg:VAXcc VAX_PSL_REGNUM)
                                       (const_int 0)])
                      (label_ref (match_operand 1 "" ""))
                      (pc)))]
-  ""
+  "reload_completed"
   "j%k0 %l1")
 
 ;; Recognize reversed jumps.
-(define_insn "*branch_reversed"
+(define_insn "*branch_<mode>_reversed"
   [(set (pc)
-       (if_then_else (match_operator 0 "ordered_comparison_operator"
-                                     [(cc0)
+       (if_then_else (match_operator 0 "vax_<cc>_comparison_operator"
+                                     [(reg:VAXcc VAX_PSL_REGNUM)
                                       (const_int 0)])
                      (pc)
                      (label_ref (match_operand 1 "" ""))))]
-  ""
+  "reload_completed"
   "j%K0 %l1") ; %K0 negates condition
 \f
 ;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
 
 ;; Normal sob insns.
 
-(define_insn ""
+(define_insn_and_split "*jsobgtr"
   [(set (pc)
        (if_then_else
         (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int -1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (gt (plus:SI (match_dup 0)
+                        (const_int -1))
+               (const_int 0))
+           (label_ref (match_dup 1))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobgtr_2"
+  [(set (pc)
+       (if_then_else
+        (gt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+                     (const_int -1))
+            (const_int 0))
+        (label_ref (match_operand 1 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jsobgtr %0,%l1")
 
-(define_insn ""
+(define_insn_and_split "*jsobgeq"
   [(set (pc)
        (if_then_else
         (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int -1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (ge (plus:SI (match_dup 0)
+                        (const_int -1))
+               (const_int 0))
+           (label_ref (match_dup 1))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobgeq_2"
+  [(set (pc)
+       (if_then_else
+        (ge (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+                     (const_int -1))
+            (const_int 0))
+        (label_ref (match_operand 1 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jsobgeq %0,%l1")
 
 ;; Normal aob insns.  Define a version for when operands[1] is a constant.
-(define_insn ""
+(define_insn_and_split "*jaoblss"
   [(set (pc)
        (if_then_else
         (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int 1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (lt (plus:SI (match_dup 0)
+                        (const_int 1))
+               (match_dup 1))
+           (label_ref (match_dup 2))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaoblss_2"
+  [(set (pc)
+       (if_then_else
+        (lt (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+                     (const_int 1))
+            (match_operand:SI 1 "general_operand" "nrmT"))
+        (label_ref (match_operand 2 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jaoblss %1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaoblss_const"
   [(set (pc)
        (if_then_else
         (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int 1)))]
   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (lt (match_dup 0)
+               (match_dup 1))
+           (label_ref (match_dup 2))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaoblss_const_2"
+  [(set (pc)
+       (if_then_else
+        (lt (match_operand:SI 0 "nonimmediate_operand" "+g")
+            (match_operand:SI 1 "general_operand" "nrmT"))
+        (label_ref (match_operand 2 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed"
   "jaoblss %P1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaobleq"
   [(set (pc)
        (if_then_else
         (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int 1)))]
   "!TARGET_UNIX_ASM"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (le (plus:SI (match_dup 0)
+                        (const_int 1))
+               (match_dup 1))
+           (label_ref (match_dup 2))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaobleq_2"
+  [(set (pc)
+       (if_then_else
+        (le (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+g")
+                     (const_int 1))
+            (match_operand:SI 1 "general_operand" "nrmT"))
+        (label_ref (match_operand 2 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && reload_completed"
   "jaobleq %1,%0,%l2")
 
-(define_insn ""
+(define_insn_and_split "*jaobleq_const"
   [(set (pc)
        (if_then_else
         (le (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int 1)))]
   "!TARGET_UNIX_ASM && CONST_INT_P (operands[1])"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (le (match_dup 0)
+               (match_dup 1))
+           (label_ref (match_dup 2))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int 1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jaobleq_const_2"
+  [(set (pc)
+       (if_then_else
+        (le (match_operand:SI 0 "nonimmediate_operand" "+g")
+            (match_operand:SI 1 "general_operand" "nrmT"))
+        (label_ref (match_operand 2 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int 1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "!TARGET_UNIX_ASM && CONST_INT_P (operands[1]) && reload_completed"
   "jaobleq %P1,%0,%l2")
 
 ;; Something like a sob insn, but compares against -1.
 ;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.
 
-(define_insn ""
+(define_insn_and_split "*jsobneq_minus_one"
   [(set (pc)
        (if_then_else
         (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
        (plus:SI (match_dup 0)
                 (const_int -1)))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (pc)
+          (if_then_else
+           (ne (match_dup 0)
+               (const_int 0))
+           (label_ref (match_dup 1))
+           (pc)))
+      (set (match_dup 0)
+          (plus:SI (match_dup 0)
+                   (const_int -1)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*jsobneq_minus_one_2"
+  [(set (pc)
+       (if_then_else
+        (ne (match_operand:SI 0 "nonimmediate_operand" "+g")
+            (const_int 0))
+        (label_ref (match_operand 1 "" ""))
+        (pc)))
+   (set (match_dup 0)
+       (plus:SI (match_dup 0)
+                (const_int -1)))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "decl %0\;jgequ %l1")
 \f
 (define_expand "call_pop"
 ;; This insn is a bit of a lier.  It actually falls through if no case
 ;; matches.  But, we prevent that from ever happening by emitting a jump
 ;; before this, see the define_expand above.
-(define_insn "casesi1"
+(define_insn_and_split "casesi1"
   [(match_operand:SI 1 "const_int_operand" "n")
    (set (pc)
        (plus:SI (sign_extend:SI
-                 (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "general_operand" "nrmT")
-                                           (const_int 2))
-                         (pc))))
+                  (mem:HI (plus:SI
+                            (mult:SI
+                              (match_operand:SI 0 "general_operand" "nrmT")
+                              (const_int 2))
+                            (pc))))
                 (label_ref:SI (match_operand 2 "" ""))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(match_dup 1)
+      (set (pc)
+          (plus:SI (sign_extend:SI
+                     (mem:HI (plus:SI
+                               (mult:SI
+                                 (match_dup 0)
+                                 (const_int 2))
+                               (pc))))
+                   (label_ref:SI (match_dup 2))))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*casesi1"
+  [(match_operand:SI 1 "const_int_operand" "n")
+   (set (pc)
+       (plus:SI (sign_extend:SI
+                  (mem:HI (plus:SI
+                            (mult:SI
+                              (match_operand:SI 0 "general_operand" "nrmT")
+                              (const_int 2))
+                            (pc))))
+                (label_ref:SI (match_operand 2 "" ""))))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "casel %0,$0,%1")
 \f
-(define_insn "*pushsym"
+(define_insn_and_split "*pushsym"
   [(set (match_operand:SI 0 "push_operand" "=g")
        (match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushsym_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+       (match_operand:SI 1 "pic_symbolic_operand" "A"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pushab %a1")
 
-(define_insn "*movsym"
+(define_insn_and_split "*movsym"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (match_operand:SI 1 "pic_symbolic_operand" "A"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsym_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (match_operand:SI 1 "pic_symbolic_operand" "A"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "movab %a1,%0")
 
-(define_insn "*pushsymreg"
+(define_insn_and_split "*pushsymreg"
   [(set (match_operand:SI 0 "push_operand" "=g")
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
                 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
   "flag_pic"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:SI (match_dup 1)
+                   (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushsymreg_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+       (plus:SI (match_operand:SI 1 "register_operand" "%r")
+                (match_operand:SI 2 "pic_symbolic_operand" "A")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "flag_pic && reload_completed"
   "pushab %a2[%1]")
 
-(define_insn "*movsymreg"
+(define_insn_and_split "*movsymreg"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (plus:SI (match_operand:SI 1 "register_operand" "%r")
                 (match_operand:SI 2 "pic_symbolic_operand" "A")))]
   "flag_pic"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (plus:SI (match_dup 1)
+                   (match_dup 2)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movsymreg_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (plus:SI (match_operand:SI 1 "register_operand" "%r")
+                (match_operand:SI 2 "pic_symbolic_operand" "A")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "flag_pic && reload_completed"
   "movab %a2[%1],%0")
 \f
 ;;- load or push effective address
 ;; It does not work to use constraints to distinguish pushes from moves,
 ;; because < matches any autodecrement, not just a push.
 
-(define_insn "pushaddr<mode>"
+(define_insn_and_split "pushaddr<mode>"
   [(set (match_operand:SI 0 "push_operand" "=g")
        (match_operand:VAXintQHSD 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+       (match_operand:VAXintQHSD 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pusha<VAXintQHSD:isfx> %a1")
 
-(define_insn "movaddr<mode>"
+(define_insn_and_split "movaddr<mode>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (match_operand:VAXintQHSD 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (match_operand:VAXintQHSD 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mova<VAXintQHSD:isfx> %a1,%0")
 
-(define_insn "pushaddr<mode>"
+(define_insn_and_split "pushaddr<mode>"
   [(set (match_operand:SI 0 "push_operand" "=g")
        (match_operand:VAXfp 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*pushaddr<mode><ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "push_operand" "=g")
+       (match_operand:VAXfp 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "pusha<VAXfp:fsfx> %a1")
 
-(define_insn "movaddr<mode>"
+(define_insn_and_split "movaddr<mode>"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
        (match_operand:VAXfp 1 "address_operand" "p"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (match_dup 1))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*movaddr<mode>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+       (match_operand:VAXfp 1 "address_operand" "p"))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "mova<VAXfp:fsfx> %a1,%0")
 \f
 ;; These used to be peepholes, but it is more straightforward to do them
 ;; with other operands constant.  This is what the combiner converts the
 ;; above sequences to before attempting to recognize the new insn.
 
-(define_insn ""
+(define_insn_and_split "*andashlnegsi4"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
        (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
                             (match_operand:QI 2 "const_int_operand" "n"))
                (match_operand:SI 3 "const_int_operand" "n")))]
   "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0"
+  "#"
+  "&& reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (and:SI (ashiftrt:SI (match_dup 1)
+                               (match_dup 2))
+                  (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*andashlnegsi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
+       (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "nrmT")
+                            (match_operand:QI 2 "const_int_operand" "n"))
+               (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0
+   && reload_completed"
   "*
 {
   unsigned long mask1 = INTVAL (operands[3]);
 ;; bits that the ashl would anyways, in which case it should have been
 ;; optimized away.
 
-(define_insn ""
+(define_insn_and_split "*andashlsi4"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
        (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
                           (match_operand:QI 2 "const_int_operand" "n"))
                (match_operand:SI 3 "const_int_operand" "n")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel
+     [(set (match_dup 0)
+          (and:SI (ashift:SI (match_dup 1)
+                             (match_dup 2))
+                  (match_dup 3)))
+      (clobber (reg:CC VAX_PSL_REGNUM))])]
+  "")
+
+(define_insn "*andashlsi4_2<ccn><ccnz><ccz>"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
+       (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "nrmT")
+                          (match_operand:QI 2 "const_int_operand" "n"))
+               (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC VAX_PSL_REGNUM))]
+  "reload_completed"
   "*
 {
   operands[3]