diff mbox series

H8 cc0 conversion

Message ID 97ecedff-d840-a5cc-8178-39ce8e2175c5@redhat.com
State New
Headers show
Series H8 cc0 conversion | expand

Commit Message

Jeff Law Nov. 22, 2020, 7:27 p.m. UTC
This is the primary patch for cc0 removal on the H8 port.  It doesn't
have any of the optimization work and many patterns are simply disabled
at this time.  It's working well enough to not regress the testsuite.

The H8 is similar to the m68k and other ports in that the vast majority
of instructions clobber the condition codes, including most of the
arithmetic insns that reload needs to use.  While there's a special
adds/subs that does not modify the condition codes, they only accept
constant addends of 1, 2 and 4.  With that in mind, this port does not
expose cc0 until after reload.  So most patterns are defined using
define_insn_and_split.  The splitter adds the appropriate clobbers.  A
subsequent patch will add patterns that set the condition codes and
returns the port to generating roughly equivalent code to before
removing cc0 support.

One might argue that this is an effective rewrite since nearly every
pattern changes and as such I've been a bit more liberal than usual on
the ChangeLog entry.  For the highly mechanical changes, I've just
called out the change for the .md file as a whole rather than every
pattern that got changed.

This is a combination of my son's work as well as my own.

I'll be pushing this to the trunk shortly.  Subsequent patches will be
restoring code quality by using the compare-elim pass to eliminate
unnecessary test/compare insns.

Jeff
* config/h8300/addsub.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	(add<mod>3_incdec): Remove pattern
	(adds/subs splitter): Only run before reload.
	* config/h8300/bitfield.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output
	of the splitters.
	(cstoreqi4, cstorehi4, cstoresi4): Comment out
	(*bstzhireg, *cmpstz, *bstz, *bistz, *cmpcondset): Likewise
	(*condbset, *cmpcondbclr, *condbclr): Likewise.
	(*cmpcondbsetreg, *condbsetreg, *cmpcondbclrreg): Likewise.
	(*condbclrreg): Likewise.
	* config/h8300/combiner.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.  Add appropriate CC register clobbers to
	existing splitters.
	(*addsi3_and_r_1): Disable for now.
	(*addsi3_and_not_r_1, bit-test branches): Likewise.
	* config/h8300/divmod.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/extensions.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/genmova.sh: Drop "cc" attribute from patterns.
	* config/h8300/mova.md: Drop "cc" attribute from patterns.
	* config/h8300/h8300-modes.def: Add CCZN and CCZNV modes.
	* config/h8300/h8300-protosh (output_plussi): Update prototype.
	(compute_plussi_length): Likewise.
	(h8300_select_cc_mode): Add prototype.
	(compute_a_shift_cc): Remove prototype
	(cmpute_logical_op_cc): Likewise.
	* config/h8300/h8300.c (names_big): Add "cc" register.
	(names_extended, names_upper_extended): Likewise.
	(h8300_emit_stack_adjustment): Be more selective about setting
	RTX_FRAME_RELATED_P.
	(h8300_print_operand): Handle CCZN mode
	(h8300_select_cc_mode): New function.
	(notice_update_cc): if-0 out.  Only kept for reference purposes.
	(h8300_expand_store): Likewise.
	(h8300_binary_length): Handle new insn forms.
	(output_plussi): Add argument for NEED_FLAGS and handle that case.
	(compute_plussi_length): Likewise.
	(compute_logical_op_cc): Return integer.
	(TARGET_FLAGS_REGNUM): Define.
	* config/h8300/h8300,h (FIRST_PSEUDO_REGISTER): Bump for cc register.
	(FIXED_REGISTERS, CALL_USED_REGISTERS): Handle cc register.
	(REG_ALLOC_ORDER, REGISTER_NAMES): Likewise.
	(SELECT_CC_MODE): Define.
	* config/h8300/h8300.md: Add CC_REG.
	Do not include peepholes.md for now.
	* config/h8300/jumpcall.md (cbranchqi4): Consolidate into
	cbranch<mode>4.
	(cbranchhi4, cbranchsi4): Likewise.
	(cbranch<mode>4): New expander.
	(branch): New define_insn_and_split for use before reload.
	(branch_1, branch_1_false): New patterns to match splitter output.
	Remove code to manage cc_status.flags.
	* config/h8300/logical.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.  Move various peepholes into this file.
	* config/h8300/movepush.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/multiply.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/other.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/peepholes.md: Remove peepholes that were moved
	elsewhere.
	* config/h8300/predicates.md (simple_memory_operand): New.
	* config/h8300/proepi.md: Drop "cc" attribute setting.
	* config/h8300/shiftrotate.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.
	* config/h8300/testcompare.md: Turn existing patterns into
	define_insn_and_split style patterns where the splitter
	adds a clobber of the condition code register.  Drop "cc"
	attribute.  Add _clobber_flags patterns to match output of
	the splitters.  Disable various patterns for now.
	Move some peepholes that were previously in peepholes.md here.

Comments

Hans-Peter Nilsson Nov. 24, 2020, 4:49 a.m. UTC | #1
On Sun, 22 Nov 2020, Jeff Law via Gcc-patches wrote:
> This is the primary patch for cc0 removal on the H8 port.? It doesn't
> have any of the optimization work and many patterns are simply disabled
> at this time.? It's working well enough to not regress the testsuite.
>
> The H8 is similar to the m68k and other ports in that the vast majority
> of instructions clobber the condition codes, including most of the
> arithmetic insns that reload needs to use. While there's a special
> adds/subs that does not modify the condition codes, they only accept
> constant addends of 1, 2 and 4. With that in mind, this port does not
> expose cc0 until after reload. So most patterns are defined using
> define_insn_and_split. The splitter adds the appropriate clobbers.

JFTR (as I'm repeating a previous note for another port): if
you'd went for exposing cc0 *before* reload (adding a clobber to
each pattern that clobbers, then specifying exceptions removing
them), the amount of (required) define_insn_and_splits would
have been zero; typically much less churn in the port.  That
approach also has the benefit of insns not "silently" changing
behavior at reload-time.

You might think a parallel with a clobber for each insn hampers
some rtl optimizations, but I found that to be not an issue at
all, doing that for CRIS (at least when comparing to the cc0
version).

brgds, H-P
Jeff Law Nov. 24, 2020, 5:50 a.m. UTC | #2
On 11/23/20 9:49 PM, Hans-Peter Nilsson wrote:
> On Sun, 22 Nov 2020, Jeff Law via Gcc-patches wrote:
>> This is the primary patch for cc0 removal on the H8 port.? It doesn't
>> have any of the optimization work and many patterns are simply disabled
>> at this time.? It's working well enough to not regress the testsuite.
>>
>> The H8 is similar to the m68k and other ports in that the vast majority
>> of instructions clobber the condition codes, including most of the
>> arithmetic insns that reload needs to use. While there's a special
>> adds/subs that does not modify the condition codes, they only accept
>> constant addends of 1, 2 and 4. With that in mind, this port does not
>> expose cc0 until after reload. So most patterns are defined using
>> define_insn_and_split. The splitter adds the appropriate clobbers.
> JFTR (as I'm repeating a previous note for another port): if
> you'd went for exposing cc0 *before* reload (adding a clobber to
> each pattern that clobbers, then specifying exceptions removing
> them), the amount of (required) define_insn_and_splits would
> have been zero; typically much less churn in the port.  That
> approach also has the benefit of insns not "silently" changing
> behavior at reload-time.
>
> You might think a parallel with a clobber for each insn hampers
> some rtl optimizations, but I found that to be not an issue at
> all, doing that for CRIS (at least when comparing to the cc0
> version).
I've definitely seen cases where exposing the clobber early hurts, so I
went with exposing after reload.

I also had someone else doing most of the grunt work, my son :-)

Jeff
Hans-Peter Nilsson Nov. 24, 2020, 10:02 a.m. UTC | #3
On Mon, 23 Nov 2020, Jeff Law wrote:

> On 11/23/20 9:49 PM, Hans-Peter Nilsson wrote:
> > On Sun, 22 Nov 2020, Jeff Law via Gcc-patches wrote:
> >> This is the primary patch for cc0 removal on the H8 port.? It doesn't
> >> have any of the optimization work and many patterns are simply disabled
> >> at this time.? It's working well enough to not regress the testsuite.
> >>
> >> The H8 is similar to the m68k and other ports in that the vast majority
> >> of instructions clobber the condition codes, including most of the
> >> arithmetic insns that reload needs to use. While there's a special
> >> adds/subs that does not modify the condition codes, they only accept
> >> constant addends of 1, 2 and 4. With that in mind, this port does not
> >> expose cc0 until after reload. So most patterns are defined using
> >> define_insn_and_split. The splitter adds the appropriate clobbers.
> > JFTR (as I'm repeating a previous note for another port): if
> > you'd went for exposing cc0 *before* reload (adding a clobber to
> > each pattern that clobbers, then specifying exceptions removing
> > them), the amount of (required) define_insn_and_splits would
> > have been zero; typically much less churn in the port.  That
> > approach also has the benefit of insns not "silently" changing
> > behavior at reload-time.
> >
> > You might think a parallel with a clobber for each insn hampers
> > some rtl optimizations, but I found that to be not an issue at
> > all, doing that for CRIS (at least when comparing to the cc0
> > version).
> I've definitely seen cases where exposing the clobber early hurts, so I
> went with exposing after reload.

I'm intested in any notes, however vague, on that matter.  I was
a bit surprised to see that myself...that is, after fixing
*some* related regressions, like the one in combine.  (Did I
actually miss something?)

> I also had someone else doing most of the grunt work, my son :-)

Given horsework, for sure!

brgds, H-P
Eric Botcazou Nov. 24, 2020, 11:08 a.m. UTC | #4
> I'm intested in any notes, however vague, on that matter.  I was
> a bit surprised to see that myself...that is, after fixing
> *some* related regressions, like the one in combine.  (Did I
> actually miss something?)

My recollection for the Visium port would align with what Jeff saw but, on the 
other hand, this could have been very marginal a phenomenon in the end.
Jeff Law Nov. 24, 2020, 3:23 p.m. UTC | #5
On 11/24/20 4:08 AM, Eric Botcazou wrote:
>> I'm intested in any notes, however vague, on that matter.  I was
>> a bit surprised to see that myself...that is, after fixing
>> *some* related regressions, like the one in combine.  (Did I
>> actually miss something?)
> My recollection for the Visium port would align with what Jeff saw but, on the 
> other hand, this could have been very marginal a phenomenon in the end.
I never tried to quantify it myself.  I certainly saw improvements
dropping the unnecessary clobbers from the shifting patterns on the H8
independently of the cc0 converseion.

jeff
Hans-Peter Nilsson Nov. 25, 2020, 10:05 p.m. UTC | #6
On Tue, 24 Nov 2020, Eric Botcazou wrote:

> > I'm intested in any notes, however vague, on that matter.  I was
> > a bit surprised to see that myself...that is, after fixing
> > *some* related regressions, like the one in combine.  (Did I
> > actually miss something?)
>
> My recollection for the Visium port would align with what Jeff saw but, on the
> other hand, this could have been very marginal a phenomenon in the end.

Thanks.  Though, without claims substantiated as anything more
than a feeling, I'm going stick out my chin and say that you're
both seasoned enough gcc hackers to be influenced by earlier
experience, and that things have changed enough that this is no
longer true.

Also, early-debug cause-misattribuations may be a factor.  (For
the combine thing, I first suspected it being target rtx_costs.)

Also for visium, it very well be a remaining odd case in
dbr/reorg.  We've only fixed a few paths in that pile, but that
hasn't had any effect in *my* benchmarks.  Hm, I also realize I
can't speak about scheduling and LRA.

With the alternative being the machine description exploding
(linearly) with error-prone edits, I'll insist that for this
kind of machine it's better to expose the target_flags_regnum
clobbers before reload.  So, better try this approach first,
when it costs "nothing", before going for the big(ger) edit of
adding define_insn_and_splits for just-about-everything (bigger
than adding a register clobber to most patterns).

Current cc0 head-count is down to avr, cr16, h8300, vax, with
two of them recently having patches posted, alas not a lot of
ports left to try this advice.

brgds, H-P
Paul Koning Nov. 28, 2020, 6:44 p.m. UTC | #7
> On Nov 25, 2020, at 5:05 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:
> 
> On Tue, 24 Nov 2020, Eric Botcazou wrote:
> 
>>> I'm intested in any notes, however vague, on that matter.  I was
>>> a bit surprised to see that myself...that is, after fixing
>>> *some* related regressions, like the one in combine.  (Did I
>>> actually miss something?)
>> 
>> My recollection for the Visium port would align with what Jeff saw but, on the
>> other hand, this could have been very marginal a phenomenon in the end.
> 
> Thanks.  Though, without claims substantiated as anything more
> than a feeling, I'm going stick out my chin and say that you're
> both seasoned enough gcc hackers to be influenced by earlier
> experience, and that things have changed enough that this is no
> longer true.

FWIW, I used the Visium approach (and a pile of help from Eric), i.e., CC after reload, in the PDP-11 cc0 conversion.

	paul
Maciej W. Rozycki Dec. 4, 2020, 4:03 p.m. UTC | #8
On Wed, 25 Nov 2020, Hans-Peter Nilsson wrote:

> Current cc0 head-count is down to avr, cr16, h8300, vax, with
> two of them recently having patches posted, alas not a lot of
> ports left to try this advice.

 Hmm, the VAX port surely did not qualify for an innovative approach 
anyway (though still I made it a bit different by means of how I (ab)used 
subst iterators and chose to ignore both rtx's in SELECT_CC_MODE; arguably 
that was the only sustainable choice) as it has been too bitrotten to make 
experiments with without a major cleanup being made first, and by the time 
I started the effort no time has left for it.  Otherwise you would simply 
not know if any phenomenon observed is due to the change being made or 
unrelated breakage.

 As usually with software however nothing has been cast in stone (even 
things made to be as stable as ABIs do change from time to time), so with 
the conversion out of the way any remaining cleanup can be made and then 
we can try removing the splits in favour to clobbers exposed pre-reload 
and see what happens.  If that turns out feasible, then other ports of 
this kind may follow.

 You may want to have your observations posted in the wiki however.

  Maciej
Maciej W. Rozycki Dec. 8, 2020, 5:43 a.m. UTC | #9
On Sun, 22 Nov 2020, Jeff Law via Gcc-patches wrote:

> This is a combination of my son's work as well as my own.

 Congratulations to Austin for this achievement!

  Maciej
diff mbox series

Patch

diff --git a/gcc/config/h8300/addsub.md b/gcc/config/h8300/addsub.md
index f3392856b76..d0877c008bf 100644
--- a/gcc/config/h8300/addsub.md
+++ b/gcc/config/h8300/addsub.md
@@ -9,64 +9,78 @@ 
   ""
   "")
 
-(define_insn "*addqi3"
+(define_insn_and_split "*addqi3"
   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
 	(plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
 		 (match_operand:QI 2 "h8300_src_operand" "rQi")))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addqi3_clobber_flags"
+  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+	(plus:QI (match_operand:QI 1 "h8300_dst_operand" "%0")
+		 (match_operand:QI 2 "h8300_src_operand" "rQi")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && h8300_operands_match_p (operands)"
   "add.b	%X2,%X0"
-  [(set_attr "length_table" "add")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length_table" "add")])
 
-(define_insn "*addhi3_h8300hs"
+(define_insn_and_split "*addhi"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
 	(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
 		 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))]
   "!TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addhi3_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
+	(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
+		 (match_operand:HI 2 "h8300_src_operand" "L,N,J,n,r")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && !TARGET_H8300SX"
   "@
    adds	%2,%S0
    subs	%G2,%S0
    add.b	%t2,%t0
    add.w	%T2,%T0
    add.w	%T2,%T0"
-  [(set_attr "length" "2,2,2,4,2")
-   (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
-
-(define_insn "*add<mode>3_incdec"
-  [(set (match_operand:HSI 0 "register_operand" "=r,r")
-	(unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
-		     (match_operand:HSI 2 "incdec_operand" "M,O")]
-		    UNSPEC_INCDEC))]
-  ""
-  {
-    if (which_alternative == 0)
-      return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
-    else if (which_alternative == 1)
-      return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
-    gcc_unreachable ();
-   }
-  [(set_attr "length" "2,2")
-   (set_attr "cc" "set_zn,set_zn")])
+  [(set_attr "length" "2,2,2,4,2")])
 
-(define_insn "*addhi3_h8sx"
+(define_insn_and_split "*addhi3_h8sx"
   [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
 	(plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
 		 (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
   "TARGET_H8300SX && h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (plus:HI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addhi3_h8sx_clobber_flags"
+  [(set (match_operand:HI 0 "h8300_dst_operand" "=rU,rU,r,rQ")
+	(plus:HI (match_operand:HI 1 "h8300_dst_operand" "%0,0,0,0")
+		 (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && TARGET_H8300SX && h8300_operands_match_p (operands)"
   "@
    add.w	%T2:3,%T0
    sub.w	%G2:3,%T0
    add.b	%t2,%t0
    add.w	%T2,%T0"
   [(set_attr "length_table" "short_immediate,short_immediate,*,add")
-   (set_attr "length" "*,*,2,*")
-   (set_attr "cc" "set_zn")])
+   (set_attr "length" "*,*,2,*")])
 
 (define_split
   [(set (match_operand:HSI 0 "register_operand" "")
 	(plus:HSI (match_dup 0)
 		 (match_operand:HSI 1 "two_insn_adds_subs_operand" "")))]
-  ""
+  "!reload_completed"
   [(const_int 0)]
   {
     split_adds_subs (<MODE>mode, operands);
@@ -74,18 +88,27 @@ 
   })
 
 
-(define_insn "*addsi_h8300hs"
+(define_insn_and_split "*addsi"
   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
 	(plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
 		 (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addsi_clobber_flags"
+  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
+	(plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
+		 (match_operand:SI 2 "h8300_src_operand" "i,rQ")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && h8300_operands_match_p (operands)"
 {
-  return output_plussi (operands);
+  return output_plussi (operands, false);
 }
   [(set (attr "length")
-	(symbol_ref "compute_plussi_length (operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_plussi_cc (operands)"))])
+	(symbol_ref "compute_plussi_length (operands, false)"))])
 
 ;; ----------------------------------------------------------------------
 ;; SUBTRACT INSTRUCTIONS
@@ -95,24 +118,43 @@ 
   [(set (match_operand:QHSI 0 "register_operand" "")
 	(minus:QHSI (match_operand:QHSI 1 "register_operand" "")
 		    (match_operand:QHSI 2 "h8300_src_operand" "")))]
-  ""
-  {
-  })
+  "")
 
-(define_insn "*subqi3"
+(define_insn_and_split "*subqi3"
   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
 	(minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
 		  (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (minus:QI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*subqi3_clobber_flags"
+  [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
+	(minus:QI (match_operand:QI 1 "h8300_dst_operand" "0")
+		  (match_operand:QI 2 "h8300_dst_operand" "rQ")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && h8300_operands_match_p (operands)"
   "sub.b	%X2,%X0"
-  [(set_attr "length_table" "add")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length_table" "add")])
 
-(define_insn "*sub<mode>3_h8300hs"
+(define_insn_and_split "*sub<mode>3"
   [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
 	(minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
 		   (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (minus:HSI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*sub<mode>3_clobber_flags"
+  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
+	(minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
+		   (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed && h8300_operands_match_p (operands)"
   { 
     if (<MODE>mode == HImode)
       return "sub.w	%T2,%T0";
@@ -120,8 +162,7 @@ 
       return "sub.l	%S2,%S0";
     gcc_unreachable ();
   }
-  [(set_attr "length_table" "add")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length_table" "add")])
 
 ;; ----------------------------------------------------------------------
 ;; NEGATION INSTRUCTIONS
@@ -133,10 +174,20 @@ 
   ""
   "")
 
-(define_insn "*neg<mode>2"
+(define_insn_and_split "*neg<mode>2"
   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
 	(neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (neg:QHSI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*neg<mode>2_clobber_flags"
+  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+	(neg:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed"
   {
     if (<MODE>mode == E_QImode)
       return "neg	%X0";
@@ -146,14 +197,21 @@ 
       return "neg.l	%S0";
     gcc_unreachable ();
   }
-  [(set_attr "length_table" "unary")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length_table" "unary")])
 
-
-(define_insn "*negsf2_h8300hs"
+(define_insn_and_split "*negsf2"
   [(set (match_operand:SF 0 "register_operand" "=r")
-       (neg:SF (match_operand:SF 1 "register_operand" "0")))]
+	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (neg:SF (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+  
+(define_insn "*negsf2_clobber_flags"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+       (neg:SF (match_operand:SF 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "reload_completed"
   "xor.w\\t#32768,%e0"
   [(set_attr "length" "4")])
-
diff --git a/gcc/config/h8300/bitfield.md b/gcc/config/h8300/bitfield.md
index bed712d830b..8fa6fde433a 100644
--- a/gcc/config/h8300/bitfield.md
+++ b/gcc/config/h8300/bitfield.md
@@ -15,7 +15,7 @@ 
 ;; Inverted loads with a 16bit destination.
 ;;
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:HI 0 "register_operand" "=&r")
 	(zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
 				 (match_operand:HI 3 "const_int_operand" "n"))
@@ -23,6 +23,23 @@ 
 			 (match_operand:HI 2 "const_int_operand" "n")))]
   "(TARGET_H8300SX)
     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:HI (xor:HI (match_dup 1) (match_dup 3))
+				    (const_int 1)
+				    (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=&r")
+	(zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r")
+				 (match_operand:HI 3 "const_int_operand" "n"))
+			 (const_int 1)
+			 (match_operand:HI 2 "const_int_operand" "n")))
+   (clobber (reg:CC CC_REG))]
+  "(TARGET_H8300SX)
+    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
   "sub.w	%0,%0\;bild	%Z2,%Y1\;bst	#0,%X0"
   [(set_attr "length" "8")])
 
@@ -30,12 +47,25 @@ 
 ;; Normal loads with a 32bit destination.
 ;;
 
-(define_insn "*extzv_1_r_h8300hs"
+(define_insn_and_split "*extzv_1_r"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
 			 (const_int 1)
 			 (match_operand 2 "const_int_operand" "n,n")))]
   "INTVAL (operands[2]) < 16"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:SI (match_dup 1) (const_int 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_1_r_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
+			 (const_int 1)
+			 (match_operand 2 "const_int_operand" "n,n")))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[2]) < 16"
 {
   return output_simode_bld (0, operands);
 }
@@ -46,7 +76,7 @@ 
 ;; Inverted loads with a 32bit destination.
 ;;
 
-(define_insn "*extzv_1_r_inv_h8300hs"
+(define_insn_and_split "*extzv_1_r_inv"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
 				 (match_operand 3 "const_int_operand" "n,n"))
@@ -54,6 +84,23 @@ 
 			 (match_operand 2 "const_int_operand" "n,n")))]
   "INTVAL (operands[2]) < 16
     && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:SI (xor:SI (match_dup 1) (match_dup 3))
+				    (const_int 1)
+				    (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_1_r_inv_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(zero_extract:SI (xor:SI (match_operand:SI 1 "register_operand" "?0,r")
+				 (match_operand 3 "const_int_operand" "n,n"))
+			 (const_int 1)
+			 (match_operand 2 "const_int_operand" "n,n")))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[2]) < 16
+    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
 {
   return output_simode_bld (1, operands);
 }
@@ -107,12 +154,25 @@ 
     FAIL;
   })
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
 			 (const_int 1)
 			 (match_operand:HI 1 "immediate_operand" "n"))
 	(match_operand:HI 2 "register_operand" "r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:HI (match_dup 0) (const_int 1) (match_dup 1))
+		   (match_dup 2))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r")
+			 (const_int 1)
+			 (match_operand:HI 1 "immediate_operand" "n"))
+	(match_operand:HI 2 "register_operand" "r"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "bld	#0,%R2\;bst	%Z1,%Y0 ; i1"
   [(set_attr "length" "4")])
 
@@ -164,7 +224,7 @@ 
 
 ;; BAND, BOR, and BXOR patterns
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:HI 0 "bit_operand" "=Ur")
 	(match_operator:HI 4 "bit_operator"
 	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
@@ -172,10 +232,28 @@ 
 			   (match_operand:HI 2 "immediate_operand" "n"))
 	  (match_operand:HI 3 "bit_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 4 [(zero_extract:HI (match_dup 1)
+						     (const_int 1)
+						     (match_dup 2))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "bit_operand" "=Ur")
+	(match_operator:HI 4 "bit_operator"
+	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+			   (const_int 1)
+			   (match_operand:HI 2 "immediate_operand" "n"))
+	  (match_operand:HI 3 "bit_operand" "0")]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "bld	%Z2,%Y1\;b%c4	#0,%R0\;bst	#0,%R0; bl1"
   [(set_attr "length" "6")])
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:HI 0 "bit_operand" "=Ur")
 	(match_operator:HI 5 "bit_operator"
 	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
@@ -185,15 +263,50 @@ 
 			   (const_int 1)
 			   (match_operand:HI 4 "immediate_operand" "n"))]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 5 [(zero_extract:HI (match_dup 1)
+						     (const_int 1)
+						     (match_dup 2))
+				    (zero_extract:HI (match_dup 3)
+						     (const_int 1)
+						     (match_dup 4))]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "bit_operand" "=Ur")
+	(match_operator:HI 5 "bit_operator"
+	 [(zero_extract:HI (match_operand:HI 1 "register_operand" "r")
+			   (const_int 1)
+			   (match_operand:HI 2 "immediate_operand" "n"))
+	  (zero_extract:HI (match_operand:HI 3 "register_operand" "r")
+			   (const_int 1)
+			   (match_operand:HI 4 "immediate_operand" "n"))]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "bld	%Z2,%Y1\;b%c5	%Z4,%Y3\;bst	#0,%R0; bl3"
   [(set_attr "length" "6")])
 
-(define_insn "bfld"
+(define_insn_and_split "bfld"
   [(set (match_operand:QI 0 "register_operand" "=r")
 	(zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
 			 (match_operand:QI 2 "immediate_operand" "n")
 			 (match_operand:QI 3 "immediate_operand" "n")))]
   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:QI (match_dup 1) (match_dup 2) (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "bfld_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+	(zero_extract:QI (match_operand:QI 1 "bit_memory_operand" "WU")
+			 (match_operand:QI 2 "immediate_operand" "n")
+			 (match_operand:QI 3 "immediate_operand" "n")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
 {
   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
 			 - (1 << INTVAL (operands[3])));
@@ -202,12 +315,25 @@ 
   [(set_attr "cc" "none_0hit")
    (set_attr "length_table" "bitfield")])
 
-(define_insn "bfst"
+(define_insn_and_split "bfst"
   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
 			 (match_operand:QI 2 "immediate_operand" "n")
 			 (match_operand:QI 3 "immediate_operand" "n"))
 	(match_operand:QI 1 "register_operand" "r"))]
   "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:QI (match_dup 0) (match_dup 2) (match_dup 3))
+		   (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "bfst_clobber_flags"
+  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+			 (match_operand:QI 2 "immediate_operand" "n")
+			 (match_operand:QI 3 "immediate_operand" "n"))
+	(match_operand:QI 1 "register_operand" "r"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX && INTVAL (operands[2]) + INTVAL (operands[3]) <= 8"
 {
   operands[2] = GEN_INT ((1 << (INTVAL (operands[2]) + INTVAL (operands[3])))
 			 - (1 << INTVAL (operands[3])));
@@ -216,225 +342,203 @@ 
   [(set_attr "cc" "none_0hit")
    (set_attr "length_table" "bitfield")])
 
-(define_expand "cstoreqi4"
-  [(use (match_operator 1 "eqne_operator"
-         [(match_operand:QI 2 "h8300_dst_operand" "")
-          (match_operand:QI 3 "h8300_src_operand" "")]))
-   (clobber (match_operand:HI 0 "register_operand"))]
-  "TARGET_H8300SX"
-  {
-    h8300_expand_store (operands);
-    DONE;
-  })
-
-(define_expand "cstorehi4"
-  [(use (match_operator 1 "eqne_operator"
-         [(match_operand:HI 2 "h8300_dst_operand" "")
-          (match_operand:HI 3 "h8300_src_operand" "")]))
-   (clobber (match_operand:HI 0 "register_operand"))]
-  "TARGET_H8300SX"
-  {
-    h8300_expand_store (operands);
-    DONE;
-  })
-
-(define_expand "cstoresi4"
-  [(use (match_operator 1 "eqne_operator"
-         [(match_operand:SI 2 "h8300_dst_operand" "")
-          (match_operand:SI 3 "h8300_src_operand" "")]))
-   (clobber (match_operand:HI 0 "register_operand"))]
-  "TARGET_H8300SX"
-  {
-    h8300_expand_store (operands);
-    DONE;
-  })
-
-(define_insn "*bstzhireg"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
-  "TARGET_H8300SX"
-  "mulu.w	#0,%T0\;b%k1	.Lh8BR%=\;inc.w	#1,%T0\\n.Lh8BR%=:"
-  [(set_attr "cc" "clobber")])
-
-(define_insn_and_split "*cmpstz"
-  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
-			 (const_int 1)
-			 (match_operand:QI 1 "immediate_operand" "n,n"))
-	(match_operator:QI 2 "eqne_operator"
-	 [(match_operand 3 "h8300_dst_operand" "r,rQ")
-	  (match_operand 4 "h8300_src_operand" "I,rQi")]))]
-  "TARGET_H8300SX
-   && (GET_MODE (operands[3]) == GET_MODE (operands[4])
-       || GET_CODE (operands[4]) == CONST_INT)
-   && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
-   && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
-  "#"
-  "reload_completed"
-  [(set (cc0) (match_dup 5))
-   (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
-	(match_op_dup:QI 2 [(cc0) (const_int 0)]))]
-  {
-    operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
-  }
-  [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*bstz"
-  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
-			 (const_int 1)
-			 (match_operand:QI 1 "immediate_operand" "n"))
-	(eq:QI (cc0) (const_int 0)))]
-  "TARGET_H8300SX && reload_completed"
-  "bstz	%1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "unary")])
-
-(define_insn "*bistz"
-  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
-			 (const_int 1)
-			 (match_operand:QI 1 "immediate_operand" "n"))
-	(ne:QI (cc0) (const_int 0)))]
-  "TARGET_H8300SX && reload_completed"
-  "bistz	%1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "unary")])
-
-(define_insn_and_split "*cmpcondbset"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
-	(if_then_else:QI (match_operator 1 "eqne_operator"
-			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
-			   (match_operand 3 "h8300_src_operand" "I,rQi")])
-			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
-				 (match_operand:QI 5 "single_one_operand" "n,n"))
-			 (match_dup 4)))]
-  "TARGET_H8300SX"
-  "#"
-  "reload_completed"
-  [(set (cc0) (match_dup 6))
-   (set (match_dup 0)
-	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
-			 (ior:QI (match_dup 4) (match_dup 5))
-			 (match_dup 4)))]
-  {
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-  }
-  [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbset"
-  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
-	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
-			  [(cc0) (const_int 0)])
-			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
-				 (match_operand:QI 1 "single_one_operand" "n"))
-			 (match_dup 3)))]
-  "TARGET_H8300SX && reload_completed"
-  "bset/%j2\t%V1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbclr"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
-	(if_then_else:QI (match_operator 1 "eqne_operator"
-			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
-			   (match_operand 3 "h8300_src_operand" "I,rQi")])
-			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
-				 (match_operand:QI 5 "single_zero_operand" "n,n"))
-			 (match_dup 4)))]
-  "TARGET_H8300SX"
-  "#"
-  "reload_completed"
-  [(set (cc0) (match_dup 6))
-   (set (match_dup 0)
-	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
-			 (and:QI (match_dup 4) (match_dup 5))
-			 (match_dup 4)))]
-  {
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-  }
-  [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbclr"
-  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
-	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
-			  [(cc0) (const_int 0)])
-			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
-				 (match_operand:QI 1 "single_zero_operand" "n"))
-			 (match_dup 3)))]
-  "TARGET_H8300SX && reload_completed"
-  "bclr/%j2\t%W1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbsetreg"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
-	(if_then_else:QI (match_operator 1 "eqne_operator"
-			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
-			   (match_operand 3 "h8300_src_operand" "I,rQi")])
-			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 5 "register_operand" "r,r")))
-			 (match_dup 4)))]
-  "TARGET_H8300SX"
-  "#"
-  "reload_completed"
-  [(set (cc0) (match_dup 6))
-   (set (match_dup 0)
-	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
-			 (ior:QI (match_dup 4)
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 5 "register_operand" "r,r")))
-			 (match_dup 4)))]
-  {
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-  }
-  [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbsetreg"
-  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
-	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
-			  [(cc0) (const_int 0)])
-			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 1 "register_operand" "r")))
-			 (match_dup 3)))]
-  "TARGET_H8300SX && reload_completed"
-  "bset/%j2\t%R1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "logicb")])
-
-(define_insn_and_split "*cmpcondbclrreg"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
-	(if_then_else:QI (match_operator 1 "eqne_operator"
-			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
-			   (match_operand 3 "h8300_src_operand" "I,rQi")])
-			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 5 "register_operand" "r,r")))
-			 (match_dup 4)))]
-  "TARGET_H8300SX"
-  "#"
-  "reload_completed"
-  [(set (cc0) (match_dup 6))
-   (set (match_dup 0)
-	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
-			 (and:QI (match_dup 4)
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 5 "register_operand" "r,r")))
-			 (match_dup 4)))]
-  {
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-  }
-  [(set_attr "cc" "set_znv,compare")])
-
-(define_insn "*condbclrreg"
-  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
-	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
-			  [(cc0) (const_int 0)])
-			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
-				 (ashift:QI (const_int 1)
-					    (match_operand:QI 1 "register_operand" "r")))
-			 (match_dup 3)))]
-  "TARGET_H8300SX && reload_completed"
-  "bclr/%j2\t%R1,%0"
-  [(set_attr "cc" "none_0hit")
-   (set_attr "length_table" "logicb")])
+;;(define_expand "cstore<mode>4"
+;;  [(use (match_operator 1 "eqne_operator"
+;;         [(match_operand:QHSI 2 "h8300_dst_operand" "")
+;;          (match_operand:QHSI 3 "h8300_src_operand" "")]))
+;;   (clobber (match_operand:QHSI 0 "register_operand"))]
+;;  "TARGET_H8300SX"
+;;  {
+;;    h8300_expand_store (operands);
+;;    DONE;
+;;  })
+
+;;(define_insn "*bstzhireg"
+;;  [(set (match_operand:HI 0 "register_operand" "=r")
+;;	(match_operator:HI 1 "eqne_operator" [(cc0) (const_int 0)]))]
+;;  "TARGET_H8300SX"
+;;  "mulu.w	#0,%T0\;b%k1	.Lh8BR%=\;inc.w	#1,%T0\\n.Lh8BR%=:"
+;;  [(set_attr "cc" "clobber")])
+
+;;(define_insn_and_split "*cmpstz"
+;;  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
+;;			 (const_int 1)
+;;			 (match_operand:QI 1 "immediate_operand" "n,n"))
+;;	(match_operator:QI 2 "eqne_operator"
+;;	 [(match_operand 3 "h8300_dst_operand" "r,rQ")
+;;	  (match_operand 4 "h8300_src_operand" "I,rQi")]))]
+;;  "TARGET_H8300SX
+;;   && (GET_MODE (operands[3]) == GET_MODE (operands[4])
+;;       || GET_CODE (operands[4]) == CONST_INT)
+;;   && GET_MODE_CLASS (GET_MODE (operands[3])) == MODE_INT
+;;   && GET_MODE_SIZE (GET_MODE (operands[3])) <= 4"
+;;  "#"
+;;  "reload_completed"
+;;  [(set (cc0) (match_dup 5))
+;;   (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
+;;	(match_op_dup:QI 2 [(cc0) (const_int 0)]))]
+;;  {
+;;    operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
+;;  }
+;;  [(set_attr "cc" "set_znv,compare")])
+
+;;(define_insn "*bstz"
+;;  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+;;			 (const_int 1)
+;;			 (match_operand:QI 1 "immediate_operand" "n"))
+;;	(eq:QI (cc0) (const_int 0)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bstz	%1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "unary")])
+
+;;(define_insn "*bistz"
+;;  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
+;;			 (const_int 1)
+;;			 (match_operand:QI 1 "immediate_operand" "n"))
+;;	(ne:QI (cc0) (const_int 0)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bistz	%1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "unary")])
+
+;;(define_insn_and_split "*cmpcondbset"
+;;  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;;	(if_then_else:QI (match_operator 1 "eqne_operator"
+;;			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;;			   (match_operand 3 "h8300_src_operand" "I,rQi")])
+;;			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;;				 (match_operand:QI 5 "single_one_operand" "n,n"))
+;;			 (match_dup 4)))]
+;;  "TARGET_H8300SX"
+;;  "#"
+;;  "reload_completed"
+;;  [(set (cc0) (match_dup 6))
+;;   (set (match_dup 0)
+;;	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;;			 (ior:QI (match_dup 4) (match_dup 5))
+;;			 (match_dup 4)))]
+;;  {
+;;    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;;  }
+;; [(set_attr "cc" "set_znv,compare")])
+
+;;(define_insn "*condbset"
+;;  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;;	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;;			  [(cc0) (const_int 0)])
+;;			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;;				 (match_operand:QI 1 "single_one_operand" "n"))
+;;			 (match_dup 3)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bset/%j2\t%V1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbclr"
+;;  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;;	(if_then_else:QI (match_operator 1 "eqne_operator"
+;;			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;;			   (match_operand 3 "h8300_src_operand" "I,rQi")])
+;;			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;;				 (match_operand:QI 5 "single_zero_operand" "n,n"))
+;;			 (match_dup 4)))]
+;;  "TARGET_H8300SX"
+;;  "#"
+;;  "reload_completed"
+;;  [(set (cc0) (match_dup 6))
+;;   (set (match_dup 0)
+;;	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;;			 (and:QI (match_dup 4) (match_dup 5))
+;;			 (match_dup 4)))]
+;;  {
+;;    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;;  }
+;;  [(set_attr "cc" "set_znv,compare")])
+
+;;(define_insn "*condbclr"
+;;  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;;	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;;			  [(cc0) (const_int 0)])
+;;			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;;				 (match_operand:QI 1 "single_zero_operand" "n"))
+;;			 (match_dup 3)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bclr/%j2\t%W1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbsetreg"
+;;  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;;	(if_then_else:QI (match_operator 1 "eqne_operator"
+;;			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;;			   (match_operand 3 "h8300_src_operand" "I,rQi")])
+;;			 (ior:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 5 "register_operand" "r,r")))
+;;			 (match_dup 4)))]
+;;  "TARGET_H8300SX"
+;;  "#"
+;;  "reload_completed"
+;;  [(set (cc0) (match_dup 6))
+;;   (set (match_dup 0)
+;;	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;;			 (ior:QI (match_dup 4)
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 5 "register_operand" "r,r")))
+;;			 (match_dup 4)))]
+;;  {
+;;    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;;  }
+;;  [(set_attr "cc" "set_znv,compare")])
+
+;;(define_insn "*condbsetreg"
+;;  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;;	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;;			  [(cc0) (const_int 0)])
+;;			 (ior:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 1 "register_operand" "r")))
+;;			 (match_dup 3)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bset/%j2\t%R1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "logicb")])
+
+;;(define_insn_and_split "*cmpcondbclrreg"
+;;  [(set (match_operand:QI 0 "nonimmediate_operand" "=WU,WU")
+;;	(if_then_else:QI (match_operator 1 "eqne_operator"
+;;			  [(match_operand 2 "h8300_dst_operand" "r,rQ")
+;;			   (match_operand 3 "h8300_src_operand" "I,rQi")])
+;;			 (and:QI (match_operand:QI 4 "bit_memory_operand" "0,0")
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 5 "register_operand" "r,r")))
+;;			 (match_dup 4)))]
+;;  "TARGET_H8300SX"
+;;  "#"
+;;  "reload_completed"
+;;  [(set (cc0) (match_dup 6))
+;;   (set (match_dup 0)
+;;	(if_then_else:QI (match_op_dup 1 [(cc0) (const_int 0)])
+;;			 (and:QI (match_dup 4)
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 5 "register_operand" "r,r")))
+;;			 (match_dup 4)))]
+;;  {
+;;    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
+;;  }
+;;  [(set_attr "cc" "set_znv,compare")])
+
+;;(define_insn "*condbclrreg"
+;;  [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
+;;	(if_then_else:QI (match_operator:QI 2 "eqne_operator"
+;;			  [(cc0) (const_int 0)])
+;;			 (and:QI (match_operand:QI 3 "bit_memory_operand" "0")
+;;				 (ashift:QI (const_int 1)
+;;					    (match_operand:QI 1 "register_operand" "r")))
+;;			 (match_dup 3)))]
+;;  "TARGET_H8300SX && reload_completed"
+;;  "bclr/%j2\t%R1,%0"
+;;  [(set_attr "cc" "none_0hit")
+;;   (set_attr "length_table" "logicb")])
 
diff --git a/gcc/config/h8300/combiner.md b/gcc/config/h8300/combiner.md
index 4f49c7fba34..432c1d88a61 100644
--- a/gcc/config/h8300/combiner.md
+++ b/gcc/config/h8300/combiner.md
@@ -4,85 +4,193 @@ 
 
 ;; insv:SI
 
-(define_insn "*insv_si_1_n"
+(define_insn_and_split "*insv_si_1_n"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
 			 (const_int 1)
 			 (match_operand:SI 1 "const_int_operand" "n"))
 	(match_operand:SI 2 "register_operand" "r"))]
   "INTVAL (operands[1]) < 16"
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+		   (match_dup 2))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_clobber_flags"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+			 (const_int 1)
+			 (match_operand:SI 1 "const_int_operand" "n"))
+	(match_operand:SI 2 "register_operand" "r"))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[1]) < 16"
   "bld\\t#0,%w2\;bst\\t%Z1,%Y0"
   [(set_attr "length" "4")])
 
-(define_insn "*insv_si_1_n_lshiftrt"
+(define_insn_and_split "*insv_si_1_n_lshiftrt"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
 			 (const_int 1)
 			 (match_operand:SI 1 "const_int_operand" "n"))
 	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
 		     (match_operand:SI 3 "const_int_operand" "n")))]
   "INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16"
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+		   (lshiftrt:SI (match_dup 2) (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_lshiftrt_clobber_flags"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+			 (const_int 1)
+			 (match_operand:SI 1 "const_int_operand" "n"))
+	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+		     (match_operand:SI 3 "const_int_operand" "n")))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16"
   "bld\\t%Z3,%Y2\;bst\\t%Z1,%Y0"
   [(set_attr "length" "4")])
 
-(define_insn "*insv_si_1_n_lshiftrt_16"
+(define_insn_and_split "*insv_si_1_n_lshiftrt_16"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
 			 (const_int 1)
 			 (match_operand:SI 1 "const_int_operand" "n"))
 	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
 		     (const_int 16)))]
   "INTVAL (operands[1]) < 16"
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 1) (match_dup 1))
+		   (lshiftrt:SI (match_dup 2) (const_int 16)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_1_n_lshiftrt_16_clobber_flags"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+			 (const_int 1)
+			 (match_operand:SI 1 "const_int_operand" "n"))
+	(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+		     (const_int 16)))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[1]) < 16"
   "rotr.w\\t%e2\;rotl.w\\t%e2\;bst\\t%Z1,%Y0"
   [(set_attr "length" "6")])
 
-(define_insn "*insv_si_8_8"
+(define_insn_and_split "*insv_si_8_8"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
 			 (const_int 8)
 			 (const_int 8))
 	(match_operand:SI 1 "register_operand" "r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+		   (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_8_8_clobber_flags"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+			 (const_int 8)
+			 (const_int 8))
+	(match_operand:SI 1 "register_operand" "r"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%w1,%x0"
   [(set_attr "length" "2")])
 
-(define_insn "*insv_si_8_8_lshiftrt_8"
+(define_insn_and_split "*insv_si_8_8_lshiftrt_8"
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
 			 (const_int 8)
 			 (const_int 8))
 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 		     (const_int 8)))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+		   (lshiftrt:SI (match_dup 1) (const_int 8)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*insv_si_8_8_lshiftrt_8_clobber_flags"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
+			 (const_int 8)
+			 (const_int 8))
+	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+		     (const_int 8)))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%x1,%x0"
   [(set_attr "length" "2")])
 
 ;; extzv:SI
 
-(define_insn "*extzv_8_8"
+(define_insn_and_split "*extzv_8_8"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
 			 (const_int 8)
 			 (const_int 8)))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_8_8_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "?0,r")
+			 (const_int 8)
+			 (const_int 8)))
+   (clobber (reg:CC CC_REG))]
+  ""
   "@
    mov.b\\t%x1,%w0\;extu.w\\t%f0\;extu.l\\t%S0
    sub.l\\t%S0,%S0\;mov.b\\t%x1,%w0"
   [(set_attr "cc" "set_znv,clobber")
    (set_attr "length" "6,4")])
 
-(define_insn "*extzv_8_16"
+(define_insn_and_split "*extzv_8_16"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
 			 (const_int 8)
 			 (const_int 16)))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:SI (match_dup 1) (const_int 8) (const_int 16)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_8_16_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+			 (const_int 8)
+			 (const_int 16)))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.w\\t%e1,%f0\;extu.w\\t%f0\;extu.l\\t%S0"
   [(set_attr "cc" "set_znv")
    (set_attr "length" "6")])
 
-(define_insn "*extzv_16_8"
+(define_insn_and_split "*extzv_16_8"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
 			 (const_int 16)
 			 (const_int 8)))
    (clobber (match_scratch:SI 2 "=&r"))]
   "TARGET_H8300H"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (zero_extract:SI (match_dup 1) (const_int 16) (const_int 8)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extzv_16_8_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+			 (const_int 16)
+			 (const_int 8)))
+   (clobber (match_scratch:SI 2 "=&r"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300H"
   "mov.w\\t%e1,%f2\;mov.b\\t%x1,%w0\;mov.b\\t%w2,%x0\;extu.l\\t%S0"
   [(set_attr "length" "8")
    (set_attr "cc" "set_znv")])
@@ -100,12 +208,13 @@ 
   [(parallel [(set (match_dup 0)
 		   (ashift:SI (match_dup 0)
 			      (const_int 1)))
-	      (clobber (scratch:QI))])
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (lshiftrt:SI (match_dup 0)
 				(const_int 24)))
-	      (clobber (scratch:QI))])]
-  "")
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])])
 
 ;; and:SI
 
@@ -122,12 +231,13 @@ 
   [(parallel [(set (match_dup 0)
 		   (ashift:SI (match_dup 0)
 			      (const_int 16)))
-	      (clobber (scratch:QI))])
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (lshiftrt:SI (match_dup 0)
 				(const_int 1)))
-	      (clobber (scratch:QI))])]
-  "")
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])])
 
 ;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).
 
@@ -145,22 +255,39 @@ 
   [(parallel [(set (match_dup 5)
 		   (ashift:HI (match_dup 5)
 			      (match_dup 2)))
-	      (clobber (match_dup 4))])
-   (set (match_dup 0)
-	(zero_extend:SI (match_dup 5)))]
+	      (clobber (match_dup 4))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (zero_extend:SI (match_dup 5)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
 
 ;; Accept (A >> 30) & 2 and the like.
 
-(define_insn "*andsi3_lshiftrt_n_sb"
+(define_insn_and_split "*andsi3_lshiftrt_n_sb"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
 			     (match_operand:SI 2 "const_int_operand" "n"))
 		(match_operand:SI 3 "single_one_operand" "n")))]
   "exact_log2 (INTVAL (operands[3])) < 16
    && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
+  "#"
+  ""
+  [(parallel [(set (match_dup 0)
+		   (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
+			   (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andsi3_lshiftrt_n_sb"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+			     (match_operand:SI 2 "const_int_operand" "n"))
+		(match_operand:SI 3 "single_one_operand" "n")))
+   (clobber (reg:CC CC_REG))]
+  "exact_log2 (INTVAL (operands[3])) < 16
+   && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31"
 {
   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
   return "shll.l\\t%S0\;xor.l\\t%S0,%S0\;bst\\t%Z3,%Y0";
@@ -175,172 +302,330 @@ 
   ""
   "#"
   "&& reload_completed"
-  [(set (match_dup 0)
-	(and:SI (lshiftrt:SI (match_dup 0)
-			     (const_int 25))
-		(const_int 64)))
+  [(parallel [(set (match_dup 0)
+		   (and:SI (lshiftrt:SI (match_dup 0) (const_int 25))
+			   (const_int 64)))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (ashift:SI (match_dup 0)
 			      (const_int 16)))
-	      (clobber (scratch:QI))])]
-  "")
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])])
 
 ;; plus:SI
 
-(define_insn "*addsi3_upper"
+(define_insn_and_split "*addsi3_upper"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
 			  (const_int 65536))
 		 (match_operand:SI 2 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (plus:SI (mult:SI (match_dup 1) (const_int 65536))
+			    (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*addsi3_upper_clobber_regs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+			  (const_int 65536))
+		 (match_operand:SI 2 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "add.w\\t%f1,%e0"
   [(set_attr "length" "2")])
 
-(define_insn "*addsi3_lshiftrt_16_zexthi"
+(define_insn_and_split "*addsi3_lshiftrt_16_zexthi"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 			      (const_int 16))
 		 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))]
   ""
-  "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
-  [(set_attr "length" "6")])
-
-(define_insn_and_split "*addsi3_and_r_1"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-	(plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
-			 (const_int 1))
-		 (match_operand:SI 2 "register_operand" "0")))]
-  ""
   "#"
-  "&& reload_completed"
-  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
-					(const_int 1)
-					(const_int 0))
-		       (const_int 0)))
-   (set (pc)
-        (if_then_else (eq (cc0)
-			  (const_int 0))
-		      (label_ref (match_dup 3))
-		      (pc)))
-   (set (match_dup 2)
-        (plus:SI (match_dup 2)
-		 (const_int 1)))
-   (match_dup 3)]
-  {
-    operands[3] = gen_label_rtx ();
-  })
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (plus:SI (lshiftrt:SI (match_dup 1) (const_int 16))
+			    (zero_extend:SI (match_dup 2))))
+	      (clobber (reg:CC CC_REG))])])
 
-(define_insn_and_split "*addsi3_and_not_r_1"
+(define_insn "*addsi3_lshiftrt_16_zexthi_clobber_flags"
   [(set (match_operand:SI 0 "register_operand" "=r")
-	(plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
-			 (const_int 1))
-		 (match_operand:SI 2 "register_operand" "0")))]
+	(plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+			      (const_int 16))
+		 (zero_extend:SI (match_operand:HI 2 "register_operand" "0"))))
+   (clobber (reg:CC CC_REG))]
   ""
-  "#"
-  "&& reload_completed"
-  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
-					(const_int 1)
-					(const_int 0))
-		       (const_int 0)))
-   (set (pc)
-        (if_then_else (ne (cc0)
-			  (const_int 0))
-		      (label_ref (match_dup 3))
-		      (pc)))
-   (set (match_dup 2)
-        (plus:SI (match_dup 2)
-		 (const_int 1)))
-   (match_dup 3)]
-  {
-    operands[3] = gen_label_rtx ();
-  })
+  "add.w\\t%e1,%f0\;xor.w\\t%e0,%e0\;rotxl.w\\t%e0"
+  [(set_attr "length" "6")])
+
+;;(define_insn_and_split "*addsi3_and_r_1"
+;;  [(set (match_operand:SI 0 "register_operand" "=r")
+;;	(plus:SI (and:SI (match_operand:SI 1 "register_operand" "r")
+;;			 (const_int 1))
+;;		 (match_operand:SI 2 "register_operand" "0")))]
+;;  ""
+;;  "#"
+;;  "&& reload_completed"
+;;  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+;;					(const_int 1)
+;;					(const_int 0))
+;;		       (const_int 0)))
+;;   (set (pc)
+;;        (if_then_else (eq (cc0)
+;;			  (const_int 0))
+;;		      (label_ref (match_dup 3))
+;;		      (pc)))
+;;   (set (match_dup 2)
+;;        (plus:SI (match_dup 2)
+;;		 (const_int 1)))
+;;   (match_dup 3)]
+;;  {
+;;    operands[3] = gen_label_rtx ();
+;;  })
+
+;;(define_insn_and_split "*addsi3_and_not_r_1"
+;;  [(set (match_operand:SI 0 "register_operand" "=r")
+;;	(plus:SI (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
+;;			 (const_int 1))
+;;		 (match_operand:SI 2 "register_operand" "0")))]
+;;  ""
+;;  "#"
+;;  "&& reload_completed"
+;;  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+;;					(const_int 1)
+;;					(const_int 0))
+;;		       (const_int 0)))
+;;   (set (pc)
+;;        (if_then_else (ne (cc0)
+;;			  (const_int 0))
+;;		      (label_ref (match_dup 3))
+;;		      (pc)))
+;;   (set (match_dup 2)
+;;        (plus:SI (match_dup 2)
+;;		 (const_int 1)))
+;;   (match_dup 3)]
+;;  {
+;;    operands[3] = gen_label_rtx ();
+;;  })
 
 ;; [ix]or:HI
 
-(define_insn "*ixorhi3_zext"
+(define_insn_and_split "*ixorhi3_zext"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(match_operator:HI 1 "iorxor_operator"
 	 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
 	  (match_operand:HI 3 "register_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 1 [(zero_extend:HI (match_dup 2))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "*ixorhi3_zext_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(match_operator:HI 1 "iorxor_operator"
+	 [(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))
+	  (match_operand:HI 3 "register_operand" "0")]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "%c1.b\\t%X2,%s0"
   [(set_attr "length" "2")])
 
 ;; [ix]or:SI
 
-(define_insn "*ixorsi3_zext_qi"
+(define_insn_and_split "*ixorsi3_zext_qi"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operator:SI 1 "iorxor_operator"
 	 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
 	  (match_operand:SI 3 "register_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 1 [(zero_extend:SI (match_dup 2))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_zext_qi_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(match_operator:SI 1 "iorxor_operator"
+	 [(zero_extend:SI (match_operand:QI 2 "register_operand" "r"))
+	  (match_operand:SI 3 "register_operand" "0")]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "%c1.b\\t%X2,%w0"
   [(set_attr "length" "2")])
 
-(define_insn "*ixorsi3_zext_hi"
+(define_insn_and_split "*ixorsi3_zext_hi"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operator:SI 1 "iorxor_operator"
 	 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
 	  (match_operand:SI 3 "register_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 1 [(zero_extend:SI (match_dup 2))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_zext_hi_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(match_operator:SI 1 "iorxor_operator"
+	 [(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))
+	  (match_operand:SI 3 "register_operand" "0")]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "%c1.w\\t%T2,%f0"
   [(set_attr "length" "2")])
 
-(define_insn "*ixorsi3_ashift_16"
+(define_insn_and_split "*ixorsi3_ashift_16"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operator:SI 1 "iorxor_operator"
 	 [(ashift:SI (match_operand:SI 2 "register_operand" "r")
 		     (const_int 16))
 	  (match_operand:SI 3 "register_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 1 [(ashift:SI (match_dup 2) (const_int 16))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_ashift_16_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(match_operator:SI 1 "iorxor_operator"
+	 [(ashift:SI (match_operand:SI 2 "register_operand" "r")
+		     (const_int 16))
+	  (match_operand:SI 3 "register_operand" "0")]))
+  (clobber (reg:CC CC_REG))]
+  ""
   "%c1.w\\t%f2,%e0"
   [(set_attr "length" "2")])
 
-(define_insn "*ixorsi3_lshiftrt_16"
+(define_insn_and_split "*ixorsi3_lshiftrt_16"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(match_operator:SI 1 "iorxor_operator"
 	 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
 		       (const_int 16))
 	  (match_operand:SI 3 "register_operand" "0")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 1 [(lshiftrt:SI (match_dup 2) (const_int 16))
+				    (match_dup 3)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*ixorsi3_lshiftrt_16_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(match_operator:SI 1 "iorxor_operator"
+	 [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+		       (const_int 16))
+	  (match_operand:SI 3 "register_operand" "0")]))
+   (clobber (reg:CC CC_REG))]
+  ""
   "%c1.w\\t%e2,%f0"
   [(set_attr "length" "2")])
 
 ;; ior:HI
 
-(define_insn "*iorhi3_ashift_8"
+(define_insn_and_split "*iorhi3_ashift_8"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
 			   (const_int 8))
 		(match_operand:HI 2 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:HI (ashift:HI (match_dup 1) (const_int 8))
+			   (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_ashift_8_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
+			   (const_int 8))
+		(match_operand:HI 2 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "or.b\\t%s1,%t0"
   [(set_attr "length" "2")])
 
-(define_insn "*iorhi3_lshiftrt_8"
+(define_insn_and_split "*iorhi3_lshiftrt_8"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
 			     (const_int 8))
 		(match_operand:HI 2 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:HI (lshiftrt:HI (match_dup 1) (const_int 8))
+			   (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_lshiftrt_8_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(ior:HI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
+			     (const_int 8))
+		(match_operand:HI 2 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "or.b\\t%t1,%s0"
   [(set_attr "length" "2")])
 
-(define_insn "*iorhi3_two_qi"
+(define_insn_and_split "*iorhi3_two_qi"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
 		(ashift:HI (match_operand:HI 2 "register_operand" "r")
 			   (const_int 8))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:HI (zero_extend:HI (match_dup 1))
+			   (ashift:HI (match_dup 2) (const_int 8))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_two_qi_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(ior:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
+		(ashift:HI (match_operand:HI 2 "register_operand" "r")
+			   (const_int 8))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%s2,%t0"
   [(set_attr "length" "2")])
 
-(define_insn "*iorhi3_two_qi_mem"
+(define_insn_and_split "*iorhi3_two_qi_mem"
   [(set (match_operand:HI 0 "register_operand" "=&r")
 	(ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
 		(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
 			   (const_int 8))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:HI (zero_extend:HI (match_dup 1))
+			   (ashift:HI (subreg:HI (match_dup 2) 0)
+				      (const_int 8))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorhi3_two_qi_mem_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=&r")
+	(ior:HI (zero_extend:HI (match_operand:QI 1 "memory_operand" "m"))
+		(ashift:HI (subreg:HI (match_operand:QI 2 "memory_operand" "m") 0)
+			   (const_int 8))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%X2,%t0\;mov.b\\t%X1,%s0"
   [(set_attr "length" "16")])
 
@@ -351,20 +636,34 @@ 
 			   (const_int 8))))]
   "reload_completed
    && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))"
-  [(set (match_dup 0)
-	(match_dup 3))]
+  [(parallel [(set (match_dup 0) (match_dup 3))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));
   })
 
 ;; ior:SI
 
-(define_insn "*iorsi3_two_hi"
+(define_insn_and_split "*iorsi3_two_hi"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
 		(ashift:SI (match_operand:SI 2 "register_operand" "r")
 			   (const_int 16))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (zero_extend:SI (match_dup 1))
+			   (ashift:SI (match_dup 2) (const_int 16))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_two_hi_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
+		(ashift:SI (match_operand:SI 2 "register_operand" "r")
+			   (const_int 16))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.w\\t%f2,%e0"
   [(set_attr "length" "2")])
 
@@ -377,23 +676,39 @@ 
   ""
   "#"
   "&& reload_completed"
-  [(set (match_dup 3)
-	(ior:HI (zero_extend:HI (match_dup 1))
-		(ashift:HI (subreg:HI (match_dup 2) 0)
-			   (const_int 8))))
-   (set (match_dup 0)
-	(zero_extend:SI (match_dup 3)))]
+  [(parallel [(set (match_dup 3)
+		   (ior:HI (zero_extend:HI (match_dup 1))
+			   (ashift:HI (subreg:HI (match_dup 2) 0)
+				      (const_int 8))))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
 
-(define_insn "*iorsi3_e2f"
+(define_insn_and_split "*iorsi3_e2f"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
 			(const_int -65536))
 		(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
 			     (const_int 16))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (match_dup 1) (const_int -65536))
+			   (lshiftrt:SI (match_dup 2) (const_int 16))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_e2f_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+			(const_int -65536))
+		(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
+			     (const_int 16))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.w\\t%e2,%f0"
   [(set_attr "length" "2")])
 
@@ -405,43 +720,87 @@ 
   ""
   "#"
   "&& reload_completed"
-  [(set (match_dup 3)
-	(ior:HI (zero_extend:HI (match_dup 1))
-		(ashift:HI (match_dup 4)
-			   (const_int 8))))
-   (set (match_dup 0)
-	(sign_extend:SI (match_dup 3)))]
+  [(parallel [(set (match_dup 3)
+		   (ior:HI (zero_extend:HI (match_dup 1))
+			   (ashift:HI (match_dup 4) (const_int 8))))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
   })
 
-(define_insn "*iorsi3_w"
+(define_insn_and_split "*iorsi3_w"
   [(set (match_operand:SI 0 "register_operand" "=r,&r")
 	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
 			(const_int -256))
 		(zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (match_dup 1) (const_int -256))
+			   (zero_extend:SI (match_dup 2))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_w_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,&r")
+	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0,0")
+			(const_int -256))
+		(zero_extend:SI (match_operand:QI 2 "general_operand_src" "r,g>"))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%X2,%w0"
   [(set_attr "length" "2,8")])
 
-(define_insn "*iorsi3_ashift_31"
+(define_insn_and_split "*iorsi3_ashift_31"
   [(set (match_operand:SI 0 "register_operand" "=&r")
 	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
 			   (const_int 31))
 		(match_operand:SI 2 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (ashift:SI (match_dup 1) (const_int 31))
+			   (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_ashift_31_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=&r")
+	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+			   (const_int 31))
+		(match_operand:SI 2 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "rotxl.l\\t%S0\;bor\\t#0,%w1\;rotxr.l\\t%S0"
   [(set_attr "length" "6")
    (set_attr "cc" "set_znv")])
 
-(define_insn "*iorsi3_and_ashift"
+(define_insn_and_split "*iorsi3_and_ashift"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
 				   (match_operand:SI 2 "const_int_operand" "n"))
 			(match_operand:SI 3 "single_one_operand" "n"))
 		(match_operand:SI 4 "register_operand" "0")))]
   "(INTVAL (operands[3]) & ~0xffff) == 0"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (ashift:SI (match_dup 1) (match_dup 2))
+				   (match_dup 3))
+			  (match_dup 4)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_ashift_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
+				   (match_operand:SI 2 "const_int_operand" "n"))
+			(match_operand:SI 3 "single_one_operand" "n"))
+		(match_operand:SI 4 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "(INTVAL (operands[3]) & ~0xffff) == 0"
 {
   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
 			- INTVAL (operands[2]));
@@ -452,13 +811,29 @@ 
 }
   [(set_attr "length" "6")])
 
-(define_insn "*iorsi3_and_lshiftrt"
+(define_insn_and_split "*iorsi3_and_lshiftrt"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				     (match_operand:SI 2 "const_int_operand" "n"))
 			(match_operand:SI 3 "single_one_operand" "n"))
 		(match_operand:SI 4 "register_operand" "0")))]
   "((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
+				   (match_dup 3))
+			   (match_dup 4)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_lshiftrt_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				     (match_operand:SI 2 "const_int_operand" "n"))
+			(match_operand:SI 3 "single_one_operand" "n"))
+		(match_operand:SI 4 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0"
 {
   rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3]))
 			+ INTVAL (operands[2]));
@@ -469,27 +844,60 @@ 
 }
   [(set_attr "length" "6")])
 
-(define_insn "*iorsi3_zero_extract"
+(define_insn_and_split "*iorsi3_zero_extract"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
 				 (const_int 1)
 				 (match_operand:SI 2 "const_int_operand" "n"))
 		(match_operand:SI 3 "register_operand" "0")))]
   "INTVAL (operands[2]) < 16"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (zero_extract:SI (match_dup 1)
+					    (const_int 1)
+					    (match_dup 2))
+			   (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_zero_extract_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
+				 (const_int 1)
+				 (match_operand:SI 2 "const_int_operand" "n"))
+		(match_operand:SI 3 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "INTVAL (operands[2]) < 16"
   "bld\\t%Z2,%Y1\;bor\\t#0,%w0\;bst\\t#0,%w0"
   [(set_attr "length" "6")])
 
-(define_insn "*iorsi3_and_lshiftrt_n_sb"
+(define_insn_and_split "*iorsi3_and_lshiftrt_n_sb"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				     (const_int 30))
 			(const_int 2))
 		(match_operand:SI 2 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (const_int 30))
+				   (const_int 2))
+			   (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi3_and_lshiftrt_n_sb_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				     (const_int 30))
+			(const_int 2))
+		(match_operand:SI 2 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "rotl.l\\t%S1\;rotr.l\\t%S1\;bor\\t#1,%w0\;bst\\t#1,%w0"
   [(set_attr "length" "8")])
 
-(define_insn "*iorsi3_and_lshiftrt_9_sb"
+(define_insn_and_split "*iorsi3_and_lshiftrt_9_sb"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				     (const_int 9))
@@ -497,6 +905,25 @@ 
 		(match_operand:SI 2 "register_operand" "0")))
    (clobber (match_scratch:HI 3 "=&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (lshiftrt:SI (match_dup 1) (const_int 9))
+				   (const_int 4194304))
+			   (match_dup 2)))
+	      (clobber (match_dup 3))
+	      (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "*iorsi3_and_lshiftrt_9_sb_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				     (const_int 9))
+			(const_int 4194304))
+		(match_operand:SI 2 "register_operand" "0")))
+   (clobber (match_scratch:HI 3 "=&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
     return "shll.l\\t%S1\;xor.w\\t%T3,%T3\;bst\\t#6,%s3\;or.w\\t%T3,%e0";
@@ -528,11 +955,12 @@ 
   [(parallel [(set (match_dup 3)
 		   (ashift:HI (match_dup 3)
 			      (const_int 7)))
-	      (clobber (scratch:QI))])
-   (set (match_dup 0)
-	(ior:SI (ashift:SI (match_dup 1)
-			   (const_int 16))
-		(match_dup 0)))]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		    (ior:SI (ashift:SI (match_dup 1) (const_int 16))
+			    (match_dup 0)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
   })
@@ -546,27 +974,43 @@ 
   "epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
 	&& REGNO (operands[0]) != REGNO (operands[1]))"
-  [(set (match_dup 2)
-	(match_dup 1))
+  [(parallel [(set (match_dup 2) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 3)
 		   (ashift:HI (match_dup 3)
 			      (const_int 7)))
-	      (clobber (scratch:QI))])
-   (set (match_dup 0)
-	(ior:SI (ashift:SI (match_dup 2)
-			   (const_int 16))
-		(match_dup 0)))]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (ior:SI (ashift:SI (match_dup 2) (const_int 16))
+			   (match_dup 0)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
   })
 
-(define_insn "*iorsi2_and_1_lshiftrt_1"
+(define_insn_and_split "*iorsi2_and_1_lshiftrt_1"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
 			(const_int 1))
 		(lshiftrt:SI (match_dup 1)
 			     (const_int 1))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (ior:SI (and:SI (match_dup 1) (const_int 1))
+			   (lshiftrt:SI (match_dup 1) (const_int 1))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*iorsi2_and_1_lshiftrt_1_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (match_operand:SI 1 "register_operand" "0")
+			(const_int 1))
+		(lshiftrt:SI (match_dup 1)
+			     (const_int 1))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "shlr.l\\t%S0\;bor\\t#0,%w0\;bst\\t#0,%w0"
   [(set_attr "length" "6")])
 
@@ -579,14 +1023,15 @@ 
   ""
   "#"
   "&& reload_completed"
-  [(set (match_dup 3)
-        (ior:HI (ashift:HI (match_dup 4)
-			   (const_int 8))
-		(match_dup 3)))
+  [(parallel [(set (match_dup 3)
+		   (ior:HI (ashift:HI (match_dup 4) (const_int 8))
+			   (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (ashift:SI (match_dup 0)
 			      (const_int 16)))
-	      (clobber (scratch:QI))])]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
@@ -602,14 +1047,16 @@ 
   ""
   "#"
   "&& reload_completed"
-  [(set (match_dup 3)
-        (ior:HI (zero_extend:HI (match_dup 1))
-		(ashift:HI (subreg:HI (match_dup 2) 0)
-			   (const_int 8))))
+  [(parallel [(set (match_dup 3)
+		   (ior:HI (zero_extend:HI (match_dup 1))
+			   (ashift:HI (subreg:HI (match_dup 2) 0)
+				      (const_int 8))))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (ashift:SI (match_dup 0)
 			      (const_int 16)))
-	      (clobber (scratch:QI))])]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
@@ -637,11 +1084,12 @@ 
   [(parallel [(set (match_dup 3)
 		   (ashift:HI (match_dup 3)
 			      (const_int 7)))
-	      (clobber (scratch:QI))])
-   (set (match_dup 0)
-	(plus:SI (mult:SI (match_dup 1)
-			  (const_int 65536))
-		 (match_dup 0)))]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (plus:SI (mult:SI (match_dup 1) (const_int 65536))
+			    (match_dup 0)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));
   })
@@ -655,16 +1103,17 @@ 
   "epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
 	&& REGNO (operands[0]) != REGNO (operands[1]))"
-  [(set (match_dup 2)
-	(match_dup 1))
+  [(parallel [(set (match_dup 2) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 3)
 		   (ashift:HI (match_dup 3)
 			      (const_int 7)))
-	      (clobber (scratch:QI))])
-   (set (match_dup 0)
-	(plus:SI (mult:SI (match_dup 2)
-			  (const_int 65536))
-		 (match_dup 0)))]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (plus:SI (mult:SI (match_dup 2) (const_int 65536))
+			    (match_dup 0)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));
   })
@@ -681,93 +1130,149 @@ 
   [(parallel [(set (match_dup 2)
 		   (ashift:HI (match_dup 2)
 			      (const_int 8)))
-	      (clobber (scratch:QI))])
-   (set (match_dup 0)
-	(sign_extend:SI (match_dup 2)))
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])
    (parallel [(set (match_dup 0)
 		   (ashiftrt:SI (match_dup 0)
 				(const_int 1)))
-	      (clobber (scratch:QI))])]
+	      (clobber (scratch:QI))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
 
 ;; Storing a part of HImode to QImode.
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
 	(subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
 				(const_int 8)) 1))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (subreg:QI (lshiftrt:HI (match_dup 1)
+							 (const_int 8)) 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+	(subreg:QI (lshiftrt:HI (match_operand:HI 1 "register_operand" "r")
+				(const_int 8)) 1))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%t1,%R0"
   [(set_attr "cc" "set_znv")
    (set_attr "length" "8")])
 
 ;; Storing a part of SImode to QImode.
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
 	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				(const_int 8)) 3))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 8)) 3))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				(const_int 8)) 3))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.b\\t%x1,%R0"
   [(set_attr "cc" "set_znv")
    (set_attr "length" "8")])
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
 	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				(const_int 16)) 3))
    (clobber (match_scratch:SI 2 "=&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 16)) 3))
+	      (clobber (match_dup 2))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				(const_int 16)) 3))
+   (clobber (match_scratch:SI 2 "=&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.w\\t%e1,%f2\;mov.b\\t%w2,%R0"
   [(set_attr "cc" "set_znv")
    (set_attr "length" "10")])
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
 	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
 				(const_int 24)) 3))
    (clobber (match_scratch:SI 2 "=&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (subreg:QI (lshiftrt:SI (match_dup 1) (const_int 24)) 3))
+	      (clobber (match_dup 2))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QI 0 "general_operand_dst" "=rm<")
+	(subreg:QI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
+				(const_int 24)) 3))
+   (clobber (match_scratch:SI 2 "=&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.w\\t%e1,%f2\;mov.b\\t%x2,%R0"
   [(set_attr "cc" "set_znv")
    (set_attr "length" "10")])
 
-(define_insn_and_split ""
-  [(set (pc)
-	(if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
-					   (const_int 1)
-					   (const_int 7))
-			  (const_int 0))
-		      (match_operand 1 "pc_or_label_operand" "")
-		      (match_operand 2 "pc_or_label_operand" "")))]
-  "operands[1] == pc_rtx || operands[2] == pc_rtx"
-  "#"
-  ""
-  [(set (cc0) (compare (match_dup 0)
-		       (const_int 0)))
-   (set (pc)
-	(if_then_else (ge (cc0)
-			  (const_int 0))
-		      (match_dup 1)
-		      (match_dup 2)))])
-
-(define_insn_and_split ""
-  [(set (pc)
-	(if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
-					   (const_int 1)
-					   (const_int 7))
-			  (const_int 0))
-		      (match_operand 1 "pc_or_label_operand" "")
-		      (match_operand 2 "pc_or_label_operand" "")))]
-  "operands[1] == pc_rtx || operands[2] == pc_rtx"
-  "#"
-  ""
-  [(set (cc0) (compare (match_dup 0)
-		       (const_int 0)))
-   (set (pc)
-	(if_then_else (lt (cc0)
-			  (const_int 0))
-		      (match_dup 1)
-		      (match_dup 2)))])
+;;(define_insn_and_split ""
+;;  [(set (pc)
+;;	(if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
+;;					   (const_int 1)
+;;					   (const_int 7))
+;;			  (const_int 0))
+;;		      (label_ref (match_operand 1 "" ""))
+;;		      (pc)))]
+;;  ""
+;;  "#"
+;;  ""
+;;  [(set (cc0) (compare (match_dup 0)
+;;		       (const_int 0)))
+;;   (set (pc)
+;;	(if_then_else (ge (cc0)
+;;			  (const_int 0))
+;;		      (label_ref (match_dup 1))
+;;		      (pc)))]
+;;  "")
+;; 
+;; (define_insn_and_split ""
+;;  [(set (pc)
+;; 	(if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 "register_operand" "") 0)
+;; 					   (const_int 1)
+;; 					   (const_int 7))
+;; 			  (const_int 0))
+;; 		      (label_ref (match_operand 1 "" ""))
+;; 		      (pc)))]
+;;   ""
+;;   "#"
+;;   ""
+;;   [(set (cc0) (compare (match_dup 0)
+;; 		       (const_int 0)))
+;;    (set (pc)
+;; 	(if_then_else (lt (cc0)
+;; 			  (const_int 0))
+;; 		      (label_ref (match_dup 1))
+;; 		      (pc)))]
+;;   "")
diff --git a/gcc/config/h8300/divmod.md b/gcc/config/h8300/divmod.md
index 7e0d7f09dc9..b5ab6b727bb 100644
--- a/gcc/config/h8300/divmod.md
+++ b/gcc/config/h8300/divmod.md
@@ -2,23 +2,45 @@ 
 ;; DIVIDE/MOD INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "udiv<mode>3"
+(define_insn_and_split "udiv<mode>3"
   [(set (match_operand:HSI 0 "register_operand" "=r")
 	(udiv:HSI (match_operand:HSI 1 "register_operand" "0")
 		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (udiv:HSI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "udiv<mode>3_clobber_flags"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+	(udiv:HSI (match_operand:HSI 1 "register_operand" "0")
+		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
   [(set_attr "length" "4")])
 
-(define_insn "div<mode>3"
+(define_insn_and_split "div<mode>3"
   [(set (match_operand:HSI 0 "register_operand" "=r")
 	(div:HSI (match_operand:HSI 1 "register_operand" "0")
 		 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (div:HSI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "div<mode>3_clobber_flags"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+	(div:HSI (match_operand:HSI 1 "register_operand" "0")
+		 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
   [(set_attr "length" "4")])
 
-(define_insn "udivmodqi4"
+(define_insn_and_split "udivmodqi4"
   [(set (match_operand:QI 0 "register_operand" "=r")
 	(truncate:QI
 	  (udiv:HI
@@ -30,6 +52,30 @@ 
 	    (match_dup 1)
 	    (zero_extend:HI (match_dup 2)))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (truncate:QI
+				   (udiv:HI (match_dup 1)
+					    (zero_extend:HI (match_dup 2)))))
+	      (set (match_dup 3) (truncate:QI
+				   (umod:HI (match_dup 1)
+					    (zero_extend:HI (match_dup 2)))))
+	      (clobber (reg:CC CC_REG))])])
+							
+
+(define_insn "udivmodqi4_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+	(truncate:QI
+	  (udiv:HI
+	    (match_operand:HI 1 "register_operand" "0")
+	    (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))
+   (set (match_operand:QI 3 "register_operand" "=r")
+	(truncate:QI
+	  (umod:HI
+	    (match_dup 1)
+	    (zero_extend:HI (match_dup 2)))))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
     return "divxu.b\\t%X2,%T0";
@@ -38,7 +84,7 @@ 
 }
   [(set_attr "length" "4")])
 
-(define_insn "divmodqi4"
+(define_insn_and_split "divmodqi4"
   [(set (match_operand:QI 0 "register_operand" "=r")
 	(truncate:QI
 	  (div:HI
@@ -50,6 +96,29 @@ 
 	    (match_dup 1)
 	    (sign_extend:HI (match_dup 2)))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (truncate:QI
+				   (div:HI (match_dup 1)
+					   (sign_extend:HI (match_dup 2)))))
+	      (set (match_dup 3) (truncate:QI
+				   (mod:HI (match_dup 1)
+					   (sign_extend:HI (match_dup 2)))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "divmodqi4_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r")
+	(truncate:QI
+	  (div:HI
+	    (match_operand:HI 1 "register_operand" "0")
+	    (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))
+   (set (match_operand:QI 3 "register_operand" "=r")
+	(truncate:QI
+	  (mod:HI
+	    (match_dup 1)
+	    (sign_extend:HI (match_dup 2)))))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
     return "divxs.b\\t%X2,%T0";
@@ -58,7 +127,7 @@ 
 }
   [(set_attr "length" "6")])
 
-(define_insn "udivmodhi4"
+(define_insn_and_split "udivmodhi4"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(truncate:HI
 	  (udiv:SI
@@ -70,6 +139,29 @@ 
 	    (match_dup 1)
 	    (zero_extend:SI (match_dup 2)))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (truncate:HI
+				   (udiv:SI (match_dup 1)
+					    (zero_extend:SI (match_dup 2)))))
+	      (set (match_dup 3) (truncate:HI
+				   (umod:SI (match_dup 1)
+					    (zero_extend:SI (match_dup 2)))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "udivmodhi4_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(truncate:HI
+	  (udiv:SI
+	    (match_operand:SI 1 "register_operand" "0")
+	    (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))
+   (set (match_operand:HI 3 "register_operand" "=r")
+	(truncate:HI
+	  (umod:SI
+	    (match_dup 1)
+	    (zero_extend:SI (match_dup 2)))))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
     return "divxu.w\\t%T2,%S0";
@@ -78,7 +170,7 @@ 
 }
   [(set_attr "length" "4")])
 
-(define_insn "divmodhi4"
+(define_insn_and_split "divmodhi4"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(truncate:HI
 	  (div:SI
@@ -90,6 +182,29 @@ 
 	    (match_dup 1)
 	    (sign_extend:SI (match_dup 2)))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (truncate:HI
+				   (div:SI (match_dup 1)
+					   (sign_extend:SI (match_dup 2)))))
+	      (set (match_dup 3) (truncate:HI
+				   (mod:SI (match_dup 1)
+					   (sign_extend:SI (match_dup 2)))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "divmodhi4_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(truncate:HI
+	  (div:SI
+	    (match_operand:SI 1 "register_operand" "0")
+	    (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))
+   (set (match_operand:HI 3 "register_operand" "=r")
+	(truncate:HI
+	  (mod:SI
+	    (match_dup 1)
+	    (sign_extend:SI (match_dup 2)))))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (find_reg_note (insn, REG_UNUSED, operands[3]))
     return "divxs.w\\t%T2,%S0";
diff --git a/gcc/config/h8300/extensions.md b/gcc/config/h8300/extensions.md
index cf6fb6d1eb9..7631230ac33 100644
--- a/gcc/config/h8300/extensions.md
+++ b/gcc/config/h8300/extensions.md
@@ -11,15 +11,24 @@ 
       operands[1] = force_reg (QImode, operands[1]);
   })
 
-(define_insn "*zero_extendqihi2_h8300hs"
+(define_insn_and_split "*zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
 	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (zero_extend:HI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendqihi2_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "@
   extu.w	%T0
   #"
-  [(set_attr "length" "2,10")
-   (set_attr "cc" "set_znv,set_znv")])
+  [(set_attr "length" "2,10")])
 
 ;; Split the zero extension of a general operand (actually a memory
 ;; operand) into a load of the operand and the actual zero extension
@@ -28,34 +37,36 @@ 
 
 (define_split
   [(set (match_operand:HI 0 "register_operand" "")
-	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
+	(zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))
+   (clobber (reg:CC CC_REG))]
   "reload_completed"
-  [(set (match_dup 2)
-	(match_dup 1))
-   (set (match_dup 0)
-	(zero_extend:HI (match_dup 2)))]
+  [(set (match_dup 2) (match_dup 1))
+   (parallel [(set (match_dup 0) (zero_extend:HI (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
   })
 
-(define_insn "*zero_extendqisi2_h8300hs"
+(define_insn "*zero_extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
-  "!TARGET_H8300SX"
+  "!reload_completed && !TARGET_H8300SX"
   "#")
 
+;; Two cases for the !H8/SX target.  One where there is an overlap
+;; between the source and destination, one where there is no overlap
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
 	(zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
   "!TARGET_H8300SX
     && reg_overlap_mentioned_p (operands[0], operands[1])
     && reload_completed"
-  [(set (match_dup 2)
-	(match_dup 1))
-   (set (match_dup 3)
-	(zero_extend:HI (match_dup 2)))
-   (set (match_dup 0)
-	(zero_extend:SI (match_dup 3)))]
+  [(parallel [(set (match_dup 2) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 3) (zero_extend:HI (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[2] = gen_lowpart (QImode, operands[0]);
     operands[3] = gen_lowpart (HImode, operands[0]);
@@ -67,21 +78,30 @@ 
   "!TARGET_H8300SX
     && !reg_overlap_mentioned_p (operands[0], operands[1])
     && reload_completed"
-  [(set (match_dup 0)
-	(const_int 0))
-   (set (strict_low_part (match_dup 2))
-	(match_dup 1))]
+  [(parallel [(set (match_dup 0) (const_int 0))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (strict_low_part (match_dup 2)) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
   })
 
-(define_insn "*zero_extendqisi2_h8sx"
+(define_insn_and_split "*zero_extendqisi2_h8sx"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendqisi2_h8sx_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "extu.l\t#2,%0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
 
 (define_expand "zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "")
@@ -89,13 +109,22 @@ 
   ""
   "")
 
-(define_insn "*zero_extendhisi2_h8300hs"
+(define_insn_and_split "*zero_extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*zero_extendhisi2_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "extu.l	%S0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
 
 (define_expand "extendqi<mode>2"
   [(set (match_operand:HSI 0 "register_operand" "")
@@ -103,39 +132,57 @@ 
   ""
   "")
 
-(define_insn "*extendqihi2_h8300hs"
+(define_insn_and_split "*extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (sign_extend:HI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendqihi2_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(sign_extend:HI (match_operand:QI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "exts.w	%T0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
 
 ;; The following pattern is needed because without the pattern, the
 ;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
 ;; shifts, one ashift and one ashiftrt.
 
-(define_insn_and_split "*extendqisi2_h8300hs"
+(define_insn_and_split "*extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
   "!TARGET_H8300SX"
   "#"
   "&& reload_completed"
-  [(set (match_dup 2)
-	(sign_extend:HI (match_dup 1)))
-   (set (match_dup 0)
-	(sign_extend:SI (match_dup 2)))]
+  [(parallel [(set (match_dup 2) (sign_extend:HI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (sign_extend:SI (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])]
   {
     operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
 
-(define_insn "*extendqisi2_h8sx"
+(define_insn_and_split "*extendqisi2_h8sx"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendqisi2_h8sx_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "exts.l\t#2,%0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "")
@@ -143,10 +190,19 @@ 
   ""
   "")
 
-(define_insn "*extendhisi2_h8300hs"
+(define_insn_and_split "*extendhisi2"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*extendhisi2_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(sign_extend:SI (match_operand:HI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "exts.l	%S0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
diff --git a/gcc/config/h8300/genmova.sh b/gcc/config/h8300/genmova.sh
index 22b01cc4e20..8ab018f70e1 100644
--- a/gcc/config/h8300/genmova.sh
+++ b/gcc/config/h8300/genmova.sh
@@ -71,8 +71,7 @@  for s in QI HI; do
 		 (match_operand:$d 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/b.l @(%o2%C2,$src),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 EOF
 	;;
@@ -115,8 +114,7 @@  EOF
 		 (match_operand:$d 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/$opsize.l @(%o2%C2,$src),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 EOF
 	    ;;
@@ -134,8 +132,7 @@  EOF
 		  (const_int $amount)))]
   "TARGET_H8300SX"
   "mova/$opsize.l @(0,$src),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:$d 0 "register_operand" "=r,r")
@@ -144,8 +141,7 @@  EOF
 		 (match_operand:$d 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/$opsize.l @(%o2%C2,$src),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 EOF
 
@@ -174,8 +170,7 @@  EOF
 		(const_int $mask)))]
   "TARGET_H8300SX"
   "mova/$opsize.l @(0,$src),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:$d 0 "register_operand" "=r")
@@ -185,8 +180,7 @@  EOF
 		 (match_operand:$d 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/$opsize.l @(%o2%C2,$src),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 EOF
 	      done
diff --git a/gcc/config/h8300/h8300-modes.def b/gcc/config/h8300/h8300-modes.def
new file mode 100644
index 00000000000..2f36c7ead8d
--- /dev/null
+++ b/gcc/config/h8300/h8300-modes.def
@@ -0,0 +1,21 @@ 
+/* Definitions of target machine for GNU compiler. 
+   Copyright (C) 2020 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+CC_MODE (CCZN);
+CC_MODE (CCZNV);
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 8a8ebf6f490..2d900369ef5 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -26,8 +26,8 @@  along with GCC; see the file COPYING3.  If not see
 /* Declarations for functions used in insn-output.c.  */
 #ifdef RTX_CODE
 extern unsigned int compute_mov_length (rtx *);
-extern const char *output_plussi (rtx *);
-extern unsigned int compute_plussi_length (rtx *);
+extern const char *output_plussi (rtx *, bool);
+extern unsigned int compute_plussi_length (rtx *, bool);
 extern const char *output_a_shift (rtx *);
 extern unsigned int compute_a_shift_length (rtx, rtx *);
 extern const char *output_a_rotate (enum rtx_code, rtx *);
@@ -35,14 +35,16 @@  extern unsigned int compute_a_rotate_length (rtx *);
 extern const char *output_simode_bld (int, rtx[]);
 extern void final_prescan_insn (rtx_insn *, rtx *, int);
 extern int h8300_expand_movsi (rtx[]);
+extern machine_mode  h8300_select_cc_mode (RTX_CODE, rtx, rtx);
 extern void notice_update_cc (rtx, rtx_insn *);
 extern const char *output_logical_op (machine_mode, rtx *);
 extern unsigned int compute_logical_op_length (machine_mode,
 					       rtx *);
+
+extern int compute_logical_op_cc (machine_mode, rtx *);
+extern int compute_a_shift_cc (rtx, rtx *);
 #ifdef HAVE_ATTR_cc
 extern enum attr_cc compute_plussi_cc (rtx *);
-extern enum attr_cc compute_a_shift_cc (rtx, rtx *);
-extern enum attr_cc compute_logical_op_cc (machine_mode, rtx *);
 #endif
 extern void h8300_expand_branch (rtx[]);
 extern void h8300_expand_store (rtx[]);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 1a22169a067..942b9bb63bd 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -132,13 +132,13 @@  static int pragma_interrupt;
 static int pragma_saveall;
 
 static const char *const names_big[] =
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" };
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "cc" };
 
 static const char *const names_extended[] =
-{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7" };
+{ "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7", "cc" };
 
 static const char *const names_upper_extended[] =
-{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7" };
+{ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "cc" };
 
 /* Points to one of the above.  */
 /* ??? The above could be put in an array indexed by CPU_TYPE.  */
@@ -469,11 +469,11 @@  h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size, bool in_prologue)
 					   stack_pointer_rtx,
 					    GEN_INT (sign * size)));
       if (size < 4)
-        F (x, in_prologue);
+        F (x, 0);
     }
   else
     F (emit_insn (gen_addsi3 (stack_pointer_rtx,
-			      stack_pointer_rtx, GEN_INT (sign * size))), in_prologue);
+			      stack_pointer_rtx, GEN_INT (sign * size))), 0);
 }
 
 /* Round up frame size SIZE.  */
@@ -520,7 +520,7 @@  push (int rn, bool in_prologue)
     x = gen_push_h8300hs_advanced (reg);
   else
     x = gen_push_h8300hs_normal (reg);
-  x = F (emit_insn (x), in_prologue);
+  x = F (emit_insn (x), 0);
   add_reg_note (x, REG_INC, stack_pointer_rtx);
   return x;
 }
@@ -756,7 +756,7 @@  h8300_expand_prologue (void)
     {
       /* Push fp.  */
       push (HARD_FRAME_POINTER_REGNUM, true);
-      F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), true);
+      F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), 0);
     }
 
   /* Push the rest of the registers in ascending order.  */
@@ -1508,10 +1508,20 @@  h8300_print_operand (FILE *file, rtx x, int code)
 	}
       break;
     case 'j':
-      fputs (cond_string (GET_CODE (x)), file);
+      if (GET_CODE (x) == LT && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+	fputs ("mi", file);
+      else if (GET_CODE (x) == GE && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+	fputs ("pl", file);
+      else
+	fputs (cond_string (GET_CODE (x)), file);
       break;
     case 'k':
-      fputs (cond_string (reverse_condition (GET_CODE (x))), file);
+      if (GET_CODE (x) == LT && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+	fputs ("pl", file);
+      else if (GET_CODE (x) == GE && GET_MODE (XEXP (x, 0)) == E_CCZNmode)
+	fputs ("mi", file);
+      else
+	fputs (cond_string (reverse_condition (GET_CODE (x))), file);
       break;
     case 'm':
       gcc_assert (GET_CODE (x) == CONST_INT);
@@ -1920,6 +1930,23 @@  h8300_return_addr_rtx (int count, rtx frame)
   return ret;
 }
 
+
+machine_mode
+h8300_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1)
+{
+  if (op1 == const0_rtx
+      && (cond == EQ || cond == NE || cond == LT || cond == GE)
+      && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
+          || GET_CODE (op0) == NEG || GET_CODE (op0) == AND
+          || GET_CODE (op0) == IOR || GET_CODE (op0) == XOR
+          || GET_CODE (op0) == NOT || GET_CODE (op0) == ASHIFT
+	  || GET_CODE (op0) == REG || GET_CODE (op0) == MULT))
+    return CCZNmode;
+
+  return CCmode;
+}
+
+#if 0
 /* Update the condition code from the insn.  */
 
 void
@@ -1986,6 +2013,7 @@  notice_update_cc (rtx body, rtx_insn *insn)
       break;
     }
 }
+#endif
 
 /* Given that X occurs in an address of the form (plus X constant),
    return the part of X that is expected to be a register.  There are
@@ -2344,8 +2372,18 @@  static unsigned int
 h8300_binary_length (rtx_insn *insn, const h8300_length_table *table)
 {
   rtx set;
+  rtx pattern;
+
+  if (GET_CODE (insn) != INSN)
+    gcc_unreachable ();
 
-  set = single_set (insn);
+  pattern = PATTERN (insn);
+  if (GET_CODE (pattern) == PARALLEL
+      && GET_CODE (XVECEXP (pattern, 0, 0)) == SET
+      && GET_CODE (SET_SRC (XVECEXP (pattern, 0, 0))) == COMPARE)
+    set = XVECEXP (pattern, 0, 1);
+  else
+    set = single_set (insn);
   gcc_assert (set);
 
   if (BINARY_P (SET_SRC (set)))
@@ -2678,7 +2716,7 @@  compute_mov_length (rtx *operands)
 /* Output an addition insn.  */
 
 const char *
-output_plussi (rtx *operands)
+output_plussi (rtx *operands, bool need_flags)
 {
   machine_mode mode = GET_MODE (operands[0]);
 
@@ -2698,25 +2736,54 @@  output_plussi (rtx *operands)
 
       switch ((unsigned int) intval & 0xffffffff)
 	{
+	/* INC/DEC set the flags, but adds/subs do not.  So if we
+	   need flags, use the former and not the latter.  */
 	case 0x00000001:
+	  if (need_flags)
+	    return "inc.l\t#1,%S0";
+	  else
+	    return "adds\t%2,%S0";
 	case 0x00000002:
-	case 0x00000004:
-	  return "adds\t%2,%S0";
-
+	  if (need_flags)
+	    return "inc.l\t#2,%S0";
+	  else
+	    return "adds\t%2,%S0";
 	case 0xffffffff:
+	  if (need_flags)
+	    return "dec.l\t#1,%S0";
+	  else
+	    return "subs\t%G2,%S0";
 	case 0xfffffffe:
+	  if (need_flags)
+	    return "dec.l\t#2,%S0";
+	  else
+	    return "subs\t%G2,%S0";
+
+	/* These six cases have optimized paths when we do not
+	   need flags.  Otherwise we let them fallthru.  */
+	case 0x00000004:
+	  if (!need_flags)
+	    return "adds\t%2,%S0";
+
 	case 0xfffffffc:
-	  return "subs\t%G2,%S0";
+	  if (!need_flags)
+	    return "subs\t%G2,%S0";
 
 	case 0x00010000:
 	case 0x00020000:
-	  operands[2] = GEN_INT (intval >> 16);
-	  return "inc.w\t%2,%e0";
+	  if (!need_flags)
+	    {
+	      operands[2] = GEN_INT (intval >> 16);
+	      return "inc.w\t%2,%e0";
+	    }
 
 	case 0xffff0000:
 	case 0xfffe0000:
-	  operands[2] = GEN_INT (intval >> 16);
-	  return "dec.w\t%G2,%e0";
+	  if (!need_flags)
+	    {
+	      operands[2] = GEN_INT (intval >> 16);
+	      return "dec.w\t%G2,%e0";
+	    }
 	}
 
       /* See if we can finish with 4 bytes.  */
@@ -2740,7 +2807,7 @@  output_plussi (rtx *operands)
 /* Compute the length of an addition insn.  */
 
 unsigned int
-compute_plussi_length (rtx *operands)
+compute_plussi_length (rtx *operands, bool need_flags)
 {
   machine_mode mode = GET_MODE (operands[0]);
 
@@ -2762,21 +2829,31 @@  compute_plussi_length (rtx *operands)
 	{
 	case 0x00000001:
 	case 0x00000002:
-	case 0x00000004:
 	  return 2;
+	case 0x00000004:
+	  if (need_flags)
+	    return 6;
+	  else
+	    return 2;
 
 	case 0xffffffff:
 	case 0xfffffffe:
-	case 0xfffffffc:
 	  return 2;
+	case 0xfffffffc:
+	  if (need_flags)
+	    return 6;
+	  else
+	    return 2;
 
 	case 0x00010000:
 	case 0x00020000:
-	  return 2;
+	  if (!need_flags)
+	    return 2;
 
 	case 0xffff0000:
 	case 0xfffe0000:
-	  return 2;
+	  if (!need_flags)
+	    return 2;
 	}
 
       /* See if we can finish with 4 bytes.  */
@@ -3122,7 +3199,7 @@  compute_logical_op_length (machine_mode mode, rtx *operands)
 
 /* Compute which flag bits are valid after a logical insn.  */
 
-enum attr_cc
+int
 compute_logical_op_cc (machine_mode mode, rtx *operands)
 {
   /* Figure out the logical op that we need to perform.  */
@@ -3195,6 +3272,7 @@  compute_logical_op_cc (machine_mode mode, rtx *operands)
   return cc;
 }
 
+#if 0
 /* Expand a conditional branch.  */
 
 void
@@ -3234,6 +3312,7 @@  h8300_expand_store (rtx operands[])
   tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx);
   emit_insn (gen_rtx_SET (dest, tmp));
 }
+#endif
 
 /* Shifts.
 
@@ -4299,7 +4378,7 @@  compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 
 /* Compute which flag bits are valid after a shift insn.  */
 
-enum attr_cc
+int
 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 {
   rtx shift = operands[3];
@@ -5538,4 +5617,7 @@  h8300_push_rounding (poly_int64 bytes)
 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
 
+#undef TARGET_FLAGS_REGNUM
+#define TARGET_FLAGS_REGNUM 12
+
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index bf20ce28e24..99d85ff8138 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -195,14 +195,14 @@  extern const char * const *h8_reg_names;
    eliminated during reloading in favor of either the stack or frame
    pointer.  */
 
-#define FIRST_PSEUDO_REGISTER 12
+#define FIRST_PSEUDO_REGISTER 13
 
 /* 1 for registers that have pervasive standard uses
    and are not available for the register allocator.  */
 
 #define FIXED_REGISTERS				\
-/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */	\
-  { 0, 0, 0, 0, 0, 0, 0, 1,  0, 1,  1, 1 }
+/* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp cc */	\
+  { 0, 0, 0, 0, 0, 0, 0, 1,  0, 1,  1, 1, 1 }
 
 /* 1 for registers not available across function calls.
    These must include the FIXED_REGISTERS and also any
@@ -216,11 +216,11 @@  extern const char * const *h8_reg_names;
 
 #define CALL_USED_REGISTERS			\
 /* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap fp */	\
-  { 1, 1, 1, 1, 0, 0, 0, 1,  1, 1,  1, 1 }
+  { 1, 1, 1, 1, 0, 0, 0, 1,  1, 1,  1, 1, 1 }
 
 #define REG_ALLOC_ORDER				\
 /* r0 r1 r2 r3 r4 r5 r6 r7 mac ap rap  fp */	\
-  { 2, 3, 0, 1, 4, 5, 6, 8,  7, 9, 10, 11 }
+  { 2, 3, 0, 1, 4, 5, 6, 8,  7, 9, 10, 11, 12 }
 
 /* A C expression that is nonzero if hard register NEW_REG can be
    considered for use as a rename register for OLD_REG register */
@@ -521,6 +521,8 @@  struct cum_arg
 #define MOVE_MAX	4
 #define MAX_MOVE_MAX	4
 
+#define SELECT_CC_MODE(OP, X, Y)       h8300_select_cc_mode (OP, X, Y)
+
 /* Nonzero if access to memory by bytes is slow and undesirable.  */
 #define SLOW_BYTE_ACCESS TARGET_SLOWBYTE
 
@@ -633,7 +635,7 @@  struct cum_arg
    This sequence is indexed by compiler's hard-register-number (see above).  */
 
 #define REGISTER_NAMES \
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp" }
+{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "sp", "mac", "ap", "rap", "fp", "cc" }
 
 #define ADDITIONAL_REGISTER_NAMES \
 { {"er0", 0}, {"er1", 1}, {"er2", 2}, {"er3", 3}, {"er4", 4}, \
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 46ab2442576..7ed2453f433 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -65,7 +65,8 @@ 
    (MAC_REG	 8)
    (AP_REG	 9)
    (RAP_REG	10)
-   (FP_REG	11)])
+   (FP_REG	11)
+   (CC_REG	12)])
 
 ;; ----------------------------------------------------------------------
 ;; ATTRIBUTES
@@ -211,4 +212,4 @@ 
 (include "shiftrotate.md")
 (include "bitfield.md")
 (include "combiner.md")
-(include "peepholes.md")
+;;(include "peepholes.md")
diff --git a/gcc/config/h8300/jumpcall.md b/gcc/config/h8300/jumpcall.md
index 650b5e6fb70..6c72724b669 100644
--- a/gcc/config/h8300/jumpcall.md
+++ b/gcc/config/h8300/jumpcall.md
@@ -4,57 +4,41 @@ 
 
 ;; Conditional jump instructions
 
-(define_expand "cbranchqi4"
-  [(use (match_operator 0 "ordered_comparison_operator"
-         [(match_operand:QI 1 "h8300_dst_operand" "")
-          (match_operand:QI 2 "h8300_src_operand" "")]))
-   (use (match_operand 3 ""))]
-  ""
-  {
-    h8300_expand_branch (operands);
-    DONE;
-  })
-
-(define_expand "cbranchhi4"
-  [(use (match_operator 0 "ordered_comparison_operator"
-         [(match_operand:HI 1 "h8300_dst_operand" "")
-          (match_operand:HI 2 "h8300_src_operand" "")]))
-   (use (match_operand 3 ""))]
-  ""
-  {
-    h8300_expand_branch (operands);
-    DONE;
-  })
+(define_expand "cbranch<mode>4"
+  [(set (pc)
+	(if_then_else (match_operator 0 "ordered_comparison_operator"
+		        [(match_operand:QHSI 1 "h8300_dst_operand")
+			 (match_operand:QHSI 2 "h8300_src_operand")])
+		      (label_ref (match_operand 3 ""))
+		      (pc)))]
+  "")
 
-(define_expand "cbranchsi4"
-  [(use (match_operator 0 "ordered_comparison_operator"
-         [(match_operand:SI 1 "h8300_dst_operand" "")
-          (match_operand:SI 2 "h8300_src_operand" "")]))
-   (use (match_operand 3 ""))]
+(define_insn_and_split "*branch"
+  [(set (pc)
+	(if_then_else (match_operator 0 "comparison_operator"
+		       [(match_operand:QHSI 1 "h8300_dst_operand" "rQ")
+			(match_operand:QHSI 2 "h8300_src_operand" "rQi")])
+		      (label_ref (match_operand 3 "" ""))
+		      (pc)))]
   ""
-  {
-    h8300_expand_branch (operands);
-    DONE;
-  })
+  "#"
+  "reload_completed"
+  [(set (reg:CC CC_REG)
+	(compare:CC (match_dup 1) (match_dup 2)))
+   (set (pc)
+	(if_then_else (match_op_dup 0
+		       [(reg:CC CC_REG) (const_int 0)])
+		      (label_ref (match_dup 3)) (pc)))]
+  "")
 
-(define_insn "branch_true"
+(define_insn "*branch_1"
   [(set (pc)
 	(if_then_else (match_operator 1 "comparison_operator"
-		       [(cc0) (const_int 0)])
+		       [(reg:CC CC_REG) (const_int 0)])
 		      (label_ref (match_operand 0 "" ""))
 		      (pc)))]
-  ""
+  "reload_completed"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
-      && (GET_CODE (operands[1]) == GT
-	  || GET_CODE (operands[1]) == GE
-	  || GET_CODE (operands[1]) == LE
-	  || GET_CODE (operands[1]) == LT))
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
   if (get_attr_length (insn) == 2)
     return "b%j1	%l0";
   else if (get_attr_length (insn) == 4)
@@ -65,24 +49,15 @@ 
  [(set_attr "type" "branch")
    (set_attr "cc" "none")])
 
-(define_insn "branch_false"
+
+(define_insn "*branch_1_false"
   [(set (pc)
 	(if_then_else (match_operator 1 "comparison_operator"
-		       [(cc0) (const_int 0)])
+		       [(reg:CC CC_REG) (const_int 0)])
 		      (pc)
 		      (label_ref (match_operand 0 "" ""))))]
-  ""
+  "reload_completed"
 {
-  if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
-      && (GET_CODE (operands[1]) == GT
-	  || GET_CODE (operands[1]) == GE
-	  || GET_CODE (operands[1]) == LE
-	  || GET_CODE (operands[1]) == LT))
-    {
-      cc_status.flags &= ~CC_OVERFLOW_UNUSABLE;
-      return 0;
-    }
-
   if (get_attr_length (insn) == 2)
     return "b%k1	%l0";
   else if (get_attr_length (insn) == 4)
@@ -90,7 +65,7 @@ 
   else
     return "b%j1	.Lh8BR%=\;jmp	@%l0\\n.Lh8BR%=:";
 }
-  [(set_attr "type" "branch")
+ [(set_attr "type" "branch")
    (set_attr "cc" "none")])
 
 ;; The brabc/brabs patterns have been disabled because their length computation
@@ -125,8 +100,7 @@ 
     }
 }
   [(set_attr "type" "bitbranch")
-   (set_attr "length_table" "bitbranch")
-   (set_attr "cc" "none")])
+   (set_attr "length_table" "bitbranch")])
 
 (define_insn "*brabs"
   [(set (pc)
@@ -150,8 +124,7 @@ 
     }
 }
   [(set_attr "type" "bitbranch")
-   (set_attr "length_table" "bitbranch")
-   (set_attr "cc" "none")])
+   (set_attr "length_table" "bitbranch")])
 
 ;; Unconditional and other jump instructions.
 
diff --git a/gcc/config/h8300/logical.md b/gcc/config/h8300/logical.md
index 7d24fad360a..e4d3d330b6e 100644
--- a/gcc/config/h8300/logical.md
+++ b/gcc/config/h8300/logical.md
@@ -24,30 +24,59 @@ 
     operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
   })
 
-(define_insn "*andqi3_2"
+(define_insn "bclrhi_msx"
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+	(and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+		(match_operand:HI 2 "single_zero_operand" "Y0")))]
+  "TARGET_H8300SX"
+  "bclr\\t%W2,%0"
+  [(set_attr "length" "8")])
+
+(define_insn_and_split "*andqi3_2"
   [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
 	(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
 		(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andqi3_2_clobber_flags"
+  [(set (match_operand:QI 0 "bit_operand" "=U,rQ,r")
+	(and:QI (match_operand:QI 1 "bit_operand" "%0,0,WU")
+		(match_operand:QI 2 "h8300_src_operand" "Y0,rQi,IP1>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "@
    bclr\\t %W2,%R0
    and  %X2,%X0
    bfld %2,%1,%R0"
   [(set_attr "length" "8,*,8")
-   (set_attr "length_table" "*,logicb,*")
-   (set_attr "cc" "none_0hit,set_znv,none_0hit")])
+   (set_attr "length_table" "*,logicb,*")])
 
-(define_insn "andqi3_1"
+(define_insn_and_split "andqi3_1"
   [(set (match_operand:QI 0 "bit_operand" "=U,r")
 	(and:QI (match_operand:QI 1 "bit_operand" "%0,0")
 		(match_operand:QI 2 "h8300_src_operand" "Y0,rn")))]
   "register_operand (operands[0], QImode)
    || single_zero_operand (operands[2], QImode)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (and:QI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "andqi3_1_clobber_flags"
+  [(set (match_operand:QI 0 "bit_operand" "=U,r")
+	(and:QI (match_operand:QI 1 "bit_operand" "%0,0")
+		(match_operand:QI 2 "h8300_src_operand" "Y0,rn")))
+   (clobber (reg:CC CC_REG))]
+  "register_operand (operands[0], QImode)
+   || single_zero_operand (operands[2], QImode)"
   "@
    bclr %W2,%R0
    and  %X2,%X0"
-  [(set_attr "length" "2,8")
-   (set_attr "cc" "none_0hit,set_znv")])
+  [(set_attr "length" "2,8")])
 
 (define_expand "and<mode>3"
   [(set (match_operand:QHSI 0 "register_operand" "")
@@ -56,7 +85,7 @@ 
   ""
   "")
 
-(define_insn "*andor<mode>3"
+(define_insn_and_split "*andor<mode>3"
   [(set (match_operand:QHSI 0 "register_operand" "=r")
 	(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
 			    (match_operand:QHSI 3 "single_one_operand" "n"))
@@ -65,6 +94,23 @@ 
     || <MODE>mode == HImode
     || (<MODE>mode == SImode
 	&& (INTVAL (operands[3]) & 0xffff) != 0))"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (ior:QHSI (and:QHSI (match_dup 2)
+						     (match_dup 3))
+					   (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andor<mode>3_clobber_flags"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
+			    (match_operand:QHSI 3 "single_one_operand" "n"))
+		  (match_operand:QHSI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  "(<MODE>mode == QImode
+    || <MODE>mode == HImode
+    || (<MODE>mode == SImode
+	&& (INTVAL (operands[3]) & 0xffff) != 0))"
   {
     if (<MODE>mode == QImode)
       return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
@@ -96,13 +142,29 @@ 
   }
   [(set_attr "length" "6")])
 
-(define_insn "*andorsi3_shift_8"
+(define_insn_and_split "*andorsi3_shift_8"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
 				   (const_int 8))
 			(const_int 65280))
 		(match_operand:SI 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (ior:SI (and:SI (ashift:SI (match_dup 2)
+							    (const_int 8))
+						 (const_int 65280))
+					 (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*andorsi3_shift_8_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(ior:SI (and:SI (ashift:SI (match_operand:SI 2 "register_operand" "r")
+				   (const_int 8))
+			(const_int 65280))
+		(match_operand:SI 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "or.b\\t%w2,%x0"
   [(set_attr "length" "2")])
 
@@ -118,36 +180,41 @@ 
   { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
   [(set_attr "length" "8")])
 
-(define_split
-  [(set (match_operand:HI 0 "bit_register_indirect_operand")
-	(ors:HI (match_operand:HI 1 "bit_register_indirect_operand")
-		(match_operand:HI 2 "single_one_operand")))]
-  "TARGET_H8300SX && abs (INTVAL (operands[2])) > 0xff"
-  [(set (match_dup 0)
-	(and:QI (match_dup 1)
-		(match_dup 2)))]
-  {
-    operands[0] = adjust_address (operands[0], QImode, 0);
-    operands[1] = adjust_address (operands[1], QImode, 0);
-    operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
-  })
+(define_insn "b<code>hi_msx"
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+	(ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+		(match_operand:HI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
+  [(set_attr "length" "8")])
 
-(define_insn "<code>qi3_1"
+(define_insn_and_split "<code>qi3_1"
   [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
 	(ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
 		(match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
   "TARGET_H8300SX || register_operand (operands[0], QImode)
    || single_one_operand (operands[2], QImode)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (ors:QI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "<code>qi3_1_clobber_flags"
+  [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
+	(ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
+		(match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX || register_operand (operands[0], QImode)
+   || single_one_operand (operands[2], QImode)"
   {
     if (which_alternative == 0)
-      return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; 
+      return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0";
     else if (which_alternative == 1)
       return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
     gcc_unreachable ();
   }
   [(set_attr "length" "8,*")
-   (set_attr "length_table" "*,logicb")
-   (set_attr "cc" "none_0hit,set_znv")])
+   (set_attr "length_table" "*,logicb")])
 
 (define_expand "<code><mode>3"
   [(set (match_operand:QHSI 0 "register_operand" "")
@@ -160,27 +227,48 @@ 
 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
 ;; ----------------------------------------------------------------------
 
-(define_insn "*logical<mode>3"
+(define_insn_and_split "*logical<mode>3"
   [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
 	(match_operator:HSI 3 "bit_operator"
 	  [(match_operand:HSI 1 "h8300_dst_operand" "%0")
 	   (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*logical<mode>3_clobber_flags"
+  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
+	(match_operator:HSI 3 "bit_operator"
+	  [(match_operand:HSI 1 "h8300_dst_operand" "%0")
+	   (match_operand:HSI 2 "h8300_src_operand" "rQi")]))
+   (clobber (reg:CC CC_REG))]
+  "h8300_operands_match_p (operands)"
   { return output_logical_op (<MODE>mode, operands); }
   [(set (attr "length")
-	(symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
+	(symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))])
 
 
 ;; ----------------------------------------------------------------------
 ;; NOT INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "one_cmpl<mode>2"
+(define_insn_and_split "one_cmpl<mode>2"
   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
 	(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (not:QHSI (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "one_cmpl<mode>2_clobber_flags"
+  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+	(not:QHSI (match_operand:QHSI 1 "h8300_dst_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   {
     if (<MODE>mode == E_QImode)
       return "not	%X0";
@@ -192,3 +280,92 @@ 
   }
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_znv")])
+
+;; The next four peephole2's will try to transform
+;;
+;;   mov.b A,r0l    (or mov.l A,er0)
+;;   and.l #CST,er0
+;;
+;; into
+;;
+;;   sub.l er0
+;;   mov.b A,r0l
+;;   and.b #CST,r0l (if CST is not 255)
+
+(define_peephole2
+  [(parallel [(set (match_operand:QI 0 "register_operand" "")
+		   (match_operand:QI 1 "general_operand" ""))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_operand:SI 2 "register_operand" "")
+		   (and:SI (match_dup 2) (const_int 255)))
+	      (clobber (reg:CC CC_REG))])]
+  "!reg_overlap_mentioned_p (operands[2], operands[1])
+   && REGNO (operands[0]) == REGNO (operands[2])"
+  [(parallel [(set (match_dup 2) (const_int 0))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_peephole2
+  [(parallel [(set (match_operand:SI 0 "register_operand" "")
+		   (match_operand:SI 1 "nonimmediate_operand" ""))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0)
+		   (and:SI (match_dup 0) (const_int 255)))
+	      (clobber (reg:CC CC_REG))])]
+  "!reg_overlap_mentioned_p (operands[0], operands[1])
+   && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
+   && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
+  [(parallel [(set (match_dup 0) (const_int 0))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (strict_low_part (match_dup 2)) (match_dup 3))
+	      (clobber (reg:CC CC_REG))])]
+  {
+    operands[2] = gen_lowpart (QImode, operands[0]);
+    operands[3] = gen_lowpart (QImode, operands[1]);
+  })
+
+(define_peephole2
+  [(parallel [(set (match_operand 0 "register_operand" "")
+		   (match_operand 1 "nonimmediate_operand" ""))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_operand:SI 2 "register_operand" "")
+		   (and:SI (match_dup 2)
+			   (match_operand:SI 3 "const_int_qi_operand" "")))
+	      (clobber (reg:CC CC_REG))])]
+  "(GET_MODE (operands[0]) == QImode
+    || GET_MODE (operands[0]) == HImode
+    || GET_MODE (operands[0]) == SImode)
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])
+   && REGNO (operands[0]) == REGNO (operands[2])
+   && !reg_overlap_mentioned_p (operands[2], operands[1])
+   && !(GET_MODE (operands[1]) != QImode
+	&& GET_CODE (operands[1]) == MEM
+	&& !offsettable_memref_p (operands[1]))
+   && !(GET_MODE (operands[1]) != QImode
+	&& GET_CODE (operands[1]) == MEM
+	&& MEM_VOLATILE_P (operands[1]))"
+  [(parallel [(set (match_dup 2) (const_int 0))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (strict_low_part (match_dup 4)) (match_dup 5))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 2) (and:SI (match_dup 2) (match_dup 6)))
+	      (clobber (reg:CC CC_REG))])]
+  {
+    operands[4] = gen_lowpart (QImode, operands[0]);
+    operands[5] = gen_lowpart (QImode, operands[1]);
+    operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
+  })
+
+(define_peephole2
+  [(parallel [(set (match_operand:SI 0 "register_operand" "")
+		   (match_operand:SI 1 "register_operand" ""))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65280)))
+	      (clobber (reg:CC CC_REG))])]
+  "!reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(parallel [(set (match_dup 0) (const_int 0))
+	      (clobber (reg:CC CC_REG))])
+   (parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
+		   (lshiftrt:SI (match_dup 1) (const_int 8)))
+	      (clobber (reg:CC CC_REG))])])
diff --git a/gcc/config/h8300/mova.md b/gcc/config/h8300/mova.md
index 926edbb2c3c..cdcd4b8f6a4 100644
--- a/gcc/config/h8300/mova.md
+++ b/gcc/config/h8300/mova.md
@@ -24,8 +24,7 @@ 
 		 (match_operand:QI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -34,8 +33,7 @@ 
 		 (match_operand:QI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -44,8 +42,7 @@ 
 		 (match_operand:QI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "register_operand" "=r,r")
@@ -54,8 +51,7 @@ 
 		 (match_operand:QI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -63,8 +59,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/b.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -72,8 +67,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -82,8 +76,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -92,8 +85,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -103,8 +95,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -113,8 +104,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -124,8 +114,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -133,8 +122,7 @@ 
 		  (const_int 1)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -143,8 +131,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -153,8 +140,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -164,8 +150,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -174,8 +159,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -185,8 +169,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -194,8 +177,7 @@ 
 		  (const_int 4)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -204,8 +186,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -214,8 +195,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -225,8 +205,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -235,8 +214,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -246,8 +224,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -255,8 +232,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -265,8 +241,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -275,8 +250,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -286,8 +260,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -296,8 +269,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -307,8 +279,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -316,8 +287,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/b.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -325,8 +295,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -335,8 +304,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -345,8 +313,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -356,8 +323,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -366,8 +332,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -377,8 +342,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -386,8 +350,7 @@ 
 		  (const_int 1)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -396,8 +359,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -406,8 +368,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -417,8 +378,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -427,8 +387,7 @@ 
 		(const_int 510)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -438,8 +397,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -447,8 +405,7 @@ 
 		  (const_int 4)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -457,8 +414,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -467,8 +423,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -478,8 +433,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -488,8 +442,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -499,8 +452,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -508,8 +460,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -518,8 +469,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -528,8 +478,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -539,8 +488,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -549,8 +497,7 @@ 
 		(const_int 1020)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%X1.b),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -560,8 +507,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%X1.b),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -570,8 +516,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -580,8 +525,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -590,8 +534,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -600,8 +543,7 @@ 
 		 (match_operand:HI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -609,8 +551,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/b.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -618,8 +559,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -628,8 +568,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -638,8 +577,7 @@ 
 		(const_int 131070)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -649,8 +587,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -659,8 +596,7 @@ 
 		(const_int 131070)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -670,8 +606,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -679,8 +614,7 @@ 
 		  (const_int 1)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -689,8 +623,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -699,8 +632,7 @@ 
 		(const_int 131070)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -710,8 +642,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -720,8 +651,7 @@ 
 		(const_int 131070)))]
   "TARGET_H8300SX"
   "mova/w.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -731,8 +661,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/w.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -740,8 +669,7 @@ 
 		  (const_int 4)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -750,8 +678,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -760,8 +687,7 @@ 
 		(const_int 262140)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -771,8 +697,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -781,8 +706,7 @@ 
 		(const_int 262140)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -792,8 +716,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -801,8 +724,7 @@ 
 		  (const_int 2)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -811,8 +733,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i,i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -821,8 +742,7 @@ 
 		(const_int 262140)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -832,8 +752,7 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -842,8 +761,7 @@ 
 		(const_int 262140)))]
   "TARGET_H8300SX"
   "mova/l.l @(0,%T1.w),%S0"
-  [(set_attr "length_table" "mova_zero")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova_zero")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -853,6 +771,5 @@ 
 		 (match_operand:SI 2 "immediate_operand" "i")))]
   "TARGET_H8300SX"
   "mova/l.l @(%o2%C2,%T1.w),%S0"
-  [(set_attr "length_table" "mova")
-   (set_attr "cc" "none")])
+  [(set_attr "length_table" "mova")])
 
diff --git a/gcc/config/h8300/movepush.md b/gcc/config/h8300/movepush.md
index a8241b90a45..b106cd54f5d 100644
--- a/gcc/config/h8300/movepush.md
+++ b/gcc/config/h8300/movepush.md
@@ -4,11 +4,20 @@ 
 
 ;; movqi
 
-(define_insn "*movqi_h8nosx"
+(define_insn_and_split "*movqi"
   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
 	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
-  "!TARGET_H8300SX
-    && h8300_move_ok (operands[0], operands[1])"
+  "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movqi_clobber_flags"
+  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
+	(match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_H8300SX && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.b	%X0,%X0
    mov.b	%R1,%X0
@@ -16,19 +25,26 @@ 
    mov.b	%R1,%X0
    mov.b	%R1,%X0
    mov.b	%X1,%R0"
-  [(set (attr "length")
-	(symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
 
-(define_insn "*movqi_h8sx"
+(define_insn_and_split "*movqi_h8sx"
   [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
 	(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movqi_h8sx_clobber_flags"
+  [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
+	(match_operand:QI 1 "general_operand_src" "P4>X,rQi"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "@
     mov.b	%X1:4,%X0
     mov.b	%X1,%X0"
-  [(set_attr "length_table" "mov_imm4,movb")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length_table" "mov_imm4,movb")])
 
 (define_expand "mov<mode>"
   [(set (match_operand:QHSIF 0 "general_operand_dst" "")
@@ -48,24 +64,45 @@ 
       }
   })
 
-(define_insn "movstrictqi"
+(define_insn_and_split "movstrictqi"
   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
 			 (match_operand:QI 1 "general_operand_src" "I,rmi>"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+
+(define_insn "movstrictqi_clobber_flags"
+  [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "+r,r"))
+			 (match_operand:QI 1 "general_operand_src" "I,rmi>"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "@
    sub.b	%X0,%X0
    mov.b	%X1,%X0"
   [(set_attr "length" "2,*")
-   (set_attr "length_table" "*,movb")
-   (set_attr "cc" "set_zn,set_znv")])
+   (set_attr "length_table" "*,movb")])
 
 ;; movhi
 
-(define_insn "*movhi_h8nosx"
+(define_insn_and_split "*movhi"
   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
 	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
   "!TARGET_H8300SX
     && h8300_move_ok (operands[0], operands[1])"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movhi_clobber_flags"
+  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
+	(match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_H8300SX
+    && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.w	%T0,%T0
    mov.w	%T1,%T0
@@ -73,14 +110,22 @@ 
    mov.w	%T1,%T0
    mov.w	%T1,%T0
    mov.w	%T1,%T0"
-  [(set (attr "length")
-	(symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
 
-(define_insn "*movhi_h8sx"
+(define_insn_and_split "*movhi_h8sx"
   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
 	(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+  
+(define_insn "*movhi_h8sx_clobber_flags"
+  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,Z,Q,rQ")
+	(match_operand:HI 1 "general_operand_src" "I,P3>X,P4>X,IP8>X,rQi"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "@
    sub.w	%T0,%T0
    mov.w	%T1:3,%T0
@@ -88,27 +133,46 @@ 
    mov.w	%T1,%T0
    mov.w	%T1,%T0"
   [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
-   (set_attr "length" "2,2,*,*,*")
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
+   (set_attr "length" "2,2,*,*,*")])
 
-(define_insn "movstricthi"
+(define_insn_and_split "movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
 			 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (strict_low_part (match_dup 0)) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "movstricthi_clobber_flags"
+  [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
+			 (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "@
    sub.w	%T0,%T0
    mov.w	%T1,%T0
    mov.w	%T1,%T0"
   [(set_attr "length" "2,2,*")
-   (set_attr "length_table" "*,*,movw")
-   (set_attr "cc" "set_zn,set_znv,set_znv")])
+   (set_attr "length_table" "*,*,movw")])
 
 ;; movsi
-(define_insn "*movsi_h8300hs"
+(define_insn_and_split "*movsi"
   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
 	(match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))]
   "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
     && h8300_move_ok (operands[0], operands[1])"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsi_clobber_flags"
+  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,<,r,r,m,*a,*a,r")
+	(match_operand:SI 1 "general_operand_src" "I,r,i,r,>,m,r,I,r,*a"))
+   (clobber (reg:CC CC_REG))]
+  "(TARGET_H8300S || TARGET_H8300H) && !TARGET_H8300SX
+    && h8300_move_ok (operands[0], operands[1])"
 {
   switch (which_alternative)
     {
@@ -169,14 +233,22 @@ 
     }
    return "mov.l	%S1,%S0";
 }
-  [(set (attr "length")
-	(symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
 
-(define_insn "*movsi_h8sx"
+(define_insn_and_split "*movsi_h8sx"
   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
 	(match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsi_h8sx_clobber_flags"
+  [(set (match_operand:SI 0 "general_operand_dst" "=r,r,Q,rQ,*a,*a,r")
+	(match_operand:SI 1 "general_operand_src" "I,P3>X,IP8>X,rQi,I,r,*a"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "@
    sub.l	%S0,%S0
    mov.l	%S1:3,%S0
@@ -186,26 +258,46 @@ 
    clrmac\;ldmac	%1,macl
    stmac	macl,%0"
   [(set_attr "length_table" "*,*,short_immediate,movl,*,*,*")
-   (set_attr "length" "2,2,*,*,2,6,4")
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")])
+   (set_attr "length" "2,2,*,*,2,6,4")])
 
-(define_insn "*movsf_h8sx"
+(define_insn_and_split "*movsf_h8sx"
   [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
 	(match_operand:SF 1 "general_operand_src" "G,rQi"))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsf_h8sx_clobber_flags"
+  [(set (match_operand:SF 0 "general_operand_dst" "=r,rQ")
+	(match_operand:SF 1 "general_operand_src" "G,rQi"))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "@
     sub.l	%S0,%S0
     mov.l	%S1,%S0"
   [(set_attr "length" "2,*")
-   (set_attr "length_table" "*,movl")
-   (set_attr "cc" "set_zn,set_znv")])
+   (set_attr "length_table" "*,movl")])
 
-(define_insn "*movsf_h8300hs"
+(define_insn_and_split "*movsf"
   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
 	(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))]
   "!TARGET_H8300SX
     && (register_operand (operands[0], SFmode)
 	|| register_operand (operands[1], SFmode))"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_dup 1))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*movsf_clobber_flags"
+  [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r")
+	(match_operand:SF 1 "general_operand_src" "G,r,im,r,r,>"))
+   (clobber (reg:CC CC_REG))]
+  "!TARGET_H8300SX
+    && (register_operand (operands[0], SFmode)
+	|| register_operand (operands[1], SFmode))"
   "@
    sub.l	%S0,%S0
    mov.l	%S1,%S0
@@ -213,21 +305,35 @@ 
    mov.l	%S1,%S0
    mov.l	%S1,%S0
    mov.l	%S1,%S0"
-  [(set (attr "length")
-	(symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
+  [(set (attr "length") (symbol_ref "compute_mov_length (operands)"))])
 
 ;; ----------------------------------------------------------------------
 ;; PUSH INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "*push1_h8300hs_<QHI:mode>"
+(define_insn_and_split "*push1_<QHI:mode>"
   [(set (mem:QHI
 	(pre_modify:P
 	  (reg:P SP_REG)
 	  (plus:P (reg:P SP_REG) (const_int -4))))
 	(match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (mem:QHI
+		     (pre_modify:P (reg:P SP_REG)
+				   (plus:P (reg:P SP_REG) (const_int -4))))
+		   (match_dup 0))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*push1_<QHI:mode>_clobber_flags"
+  [(set (mem:QHI
+	(pre_modify:P
+	  (reg:P SP_REG)
+	  (plus:P (reg:P SP_REG) (const_int -4))))
+	(match_operand:QHI 0 "register_no_sp_elim_operand" "r"))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mov.l\\t%S0,@-er7"
   [(set_attr "length" "4")])
 
diff --git a/gcc/config/h8300/multiply.md b/gcc/config/h8300/multiply.md
index 4e9112f970c..56f2b6fb214 100644
--- a/gcc/config/h8300/multiply.md
+++ b/gcc/config/h8300/multiply.md
@@ -15,23 +15,46 @@ 
       operands[2] = gen_rtx_SIGN_EXTEND (HImode, operands[2]);
   })
 
-(define_insn "*mulqihi3_const"
+(define_insn_and_split "*mulqihi3_const"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
 		 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (mult:HI (sign_extend:HI (match_dup 1)) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulqihi3_const_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+		 (match_operand:QI 2 "nibble_operand" "IP4>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "mulxs.b	%X2,%T0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
-(define_insn "*mulqihi3"
+(define_insn_and_split "*mulqihi3"
   [(set (match_operand:HI 0 "register_operand" "=r")
 	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
 		 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (mult:HI (sign_extend:HI (match_dup 1))
+			    (sign_extend:HI (match_dup 2))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulqihi3_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0"))
+		 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mulxs.b	%X2,%T0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
 (define_expand "mulhisi3"
   [(set (match_operand:SI 0 "register_operand" "")
@@ -44,23 +67,46 @@ 
       operands[2] = gen_rtx_SIGN_EXTEND (SImode, operands[2]);
   })
 
-(define_insn "*mulhisi3_const"
+(define_insn_and_split "*mulhisi3_const"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
 		 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (mult:SI (sign_extend:SI (match_dup 1)) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulhisi3_const_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+		 (match_operand:SI 2 "nibble_operand" "IP4>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   "mulxs.w	%T2,%S0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
-(define_insn "*mulhisi3"
+(define_insn_and_split "*mulhisi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
 		 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (mult:SI (sign_extend:SI (match_dup 1))
+			    (sign_extend:SI (match_dup 2))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*mulhisi3_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%0"))
+		 (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))
+   (clobber (reg:CC CC_REG))]
+  ""
   "mulxs.w	%T2,%S0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
 (define_expand "umulqihi3"
   [(set (match_operand:HI 0 "register_operand" "")
@@ -79,8 +125,7 @@ 
 		 (match_operand:QI 2 "nibble_operand" "IP4>X")))]
   "TARGET_H8300SX"
   "mulxu.b	%X2,%T0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
 (define_insn "*umulqihi3"
   [(set (match_operand:HI 0 "register_operand" "=r")
@@ -88,8 +133,7 @@ 
 		 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
   ""
   "mulxu.b	%X2,%T0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "none_0hit")])
+  [(set_attr "length" "2")])
 
 (define_expand "umulhisi3"
   [(set (match_operand:SI 0 "register_operand" "")
@@ -108,8 +152,7 @@ 
 		 (match_operand:SI 2 "nibble_operand" "IP4>X")))]
   "TARGET_H8300SX"
   "mulxu.w	%T2,%S0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
 (define_insn "*umulhisi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -117,23 +160,32 @@ 
 		 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
   ""
   "mulxu.w	%T2,%S0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "none_0hit")])
+  [(set_attr "length" "2")])
 
 ;; We could have used mulu.[wl] here, but mulu.[lw] is only available
 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
 ;; on all H8SX variants.
 
-(define_insn "mul<mode>3"
+(define_insn_and_split "mul<mode>3"
   [(set (match_operand:HSI 0 "register_operand" "=r")
         (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
 		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (mult:HSI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "mul<mode>3_clobber_flags"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+        (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
+		  (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SX"
   { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
-(define_insn "smulsi3_highpart"
+(define_insn_and_split "smulsi3_highpart"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(truncate:SI
 	 (lshiftrt:DI
@@ -142,9 +194,27 @@ 
 	   (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
 	  (const_int 32))))]
   "TARGET_H8300SXMUL"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0)
+		   (truncate:SI (lshiftrt:DI (mult:DI
+					       (sign_extend:DI (match_dup 1))
+					       (sign_extend:DI (match_dup 2)))
+					     (const_int 32))))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "smulsi3_highpart_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(truncate:SI
+	 (lshiftrt:DI
+	  (mult:DI
+	   (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
+	   (sign_extend:DI (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))
+	  (const_int 32))))
+   (clobber (reg:CC CC_REG))]
+  "TARGET_H8300SXMUL"
   "muls/u.l\\t%S2,%S0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_zn")])
+  [(set_attr "length" "4")])
 
 (define_insn "umulsi3_highpart"
   [(set (match_operand:SI 0 "register_operand" "=r")
@@ -156,8 +226,7 @@ 
 	    (const_int 32))))]
   "TARGET_H8300SX"
   "mulu/u.l\\t%S2,%S0"
-  [(set_attr "length" "4")
-   (set_attr "cc" "none_0hit")])
+  [(set_attr "length" "4")])
 
 ;; This is a "bridge" instruction.  Combine can't cram enough insns
 ;; together to crate a MAC instruction directly, but it can create
@@ -176,8 +245,7 @@ 
 	    (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))]
   "TARGET_MAC"
   "clrmac\;mac	@%2+,@%1+"
-  [(set_attr "length" "6")
-   (set_attr "cc" "none_0hit")])
+  [(set_attr "length" "6")])
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=a")
@@ -189,6 +257,5 @@ 
 	      (match_operand:SI 3 "register_operand" "0")))]
   "TARGET_MAC"
   "mac	@%2+,@%1+"
-  [(set_attr "length" "4")
-   (set_attr "cc" "none_0hit")])
+  [(set_attr "length" "4")])
 
diff --git a/gcc/config/h8300/other.md b/gcc/config/h8300/other.md
index 4b96a7c4a40..572a29fb2d9 100644
--- a/gcc/config/h8300/other.md
+++ b/gcc/config/h8300/other.md
@@ -2,10 +2,20 @@ 
 ;; ABSOLUTE VALUE INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "abssf2"
+(define_insn_and_split "abssf2"
   [(set (match_operand:SF 0 "register_operand" "=r")
 	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (abs:SF (match_dup 1)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "abssf2_clobber_flags"
+  [(set (match_operand:SF 0 "register_operand" "=r")
+	(abs:SF (match_operand:SF 1 "register_operand" "0")))
+   (clobber (reg:CC CC_REG))]
+  ""
   "and.w\\t#32767,%e0"
   [(set_attr "length" "4")])
 
@@ -13,5 +23,4 @@ 
   [(const_int 0)]
   ""
   "nop"
-  [(set_attr "cc" "none")
-   (set_attr "length" "2")])
+  [(set_attr "length" "2")])
diff --git a/gcc/config/h8300/peepholes.md b/gcc/config/h8300/peepholes.md
index 8442cd80a5e..bd6901877ee 100644
--- a/gcc/config/h8300/peepholes.md
+++ b/gcc/config/h8300/peepholes.md
@@ -433,96 +433,6 @@ 
 		   : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));
   })
 
-;; The next three peephole2's will try to transform
-;;
-;;   mov.b A,r0l    (or mov.l A,er0)
-;;   and.l #CST,er0
-;;
-;; into
-;;
-;;   sub.l er0
-;;   mov.b A,r0l
-;;   and.b #CST,r0l (if CST is not 255)
-
-(define_peephole2
-  [(set (match_operand:QI 0 "register_operand" "")
-	(match_operand:QI 1 "general_operand" ""))
-   (set (match_operand:SI 2 "register_operand" "")
-	(and:SI (match_dup 2)
-		(const_int 255)))]
-  "!reg_overlap_mentioned_p (operands[2], operands[1])
-   && REGNO (operands[0]) == REGNO (operands[2])"
-  [(set (match_dup 2)
-	(const_int 0))
-   (set (strict_low_part (match_dup 0))
-	(match_dup 1))]
-  "")
-
-(define_peephole2
-  [(set (match_operand:SI 0 "register_operand" "")
-	(match_operand:SI 1 "nonimmediate_operand" ""))
-   (set (match_dup 0)
-	(and:SI (match_dup 0)
-		(const_int 255)))]
-  "!reg_overlap_mentioned_p (operands[0], operands[1])
-   && !(GET_CODE (operands[1]) == MEM && !offsettable_memref_p (operands[1]))
-   && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))"
-  [(set (match_dup 0)
-	(const_int 0))
-   (set (strict_low_part (match_dup 2))
-	(match_dup 3))]
-  {
-    operands[2] = gen_lowpart (QImode, operands[0]);
-    operands[3] = gen_lowpart (QImode, operands[1]);
-  })
-
-(define_peephole2
-  [(set (match_operand 0 "register_operand" "")
-	(match_operand 1 "nonimmediate_operand" ""))
-   (set (match_operand:SI 2 "register_operand" "")
-	(and:SI (match_dup 2)
-		(match_operand:SI 3 "const_int_qi_operand" "")))]
-  "(GET_MODE (operands[0]) == QImode
-    || GET_MODE (operands[0]) == HImode
-    || GET_MODE (operands[0]) == SImode)
-   && GET_MODE (operands[0]) == GET_MODE (operands[1])
-   && REGNO (operands[0]) == REGNO (operands[2])
-   && !reg_overlap_mentioned_p (operands[2], operands[1])
-   && !(GET_MODE (operands[1]) != QImode
-	&& GET_CODE (operands[1]) == MEM
-	&& !offsettable_memref_p (operands[1]))
-   && !(GET_MODE (operands[1]) != QImode
-	&& GET_CODE (operands[1]) == MEM
-	&& MEM_VOLATILE_P (operands[1]))"
-  [(set (match_dup 2)
-	(const_int 0))
-   (set (strict_low_part (match_dup 4))
-	(match_dup 5))
-   (set (match_dup 2)
-	(and:SI (match_dup 2)
-		(match_dup 6)))]
-  {
-    operands[4] = gen_lowpart (QImode, operands[0]);
-    operands[5] = gen_lowpart (QImode, operands[1]);
-    operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));
-  })
-
-(define_peephole2
-  [(set (match_operand:SI 0 "register_operand" "")
-	(match_operand:SI 1 "register_operand" ""))
-   (set (match_dup 0)
-	(and:SI (match_dup 0)
-		(const_int 65280)))]
-  "!reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (match_dup 0)
-	(const_int 0))
-   (set (zero_extract:SI (match_dup 0)
-			 (const_int 8)
-			 (const_int 8))
-	(lshiftrt:SI (match_dup 1)
-		     (const_int 8)))]
-  "")
-
 ;; If a load of mem:SI is followed by an AND that turns off the upper
 ;; half, then we can load mem:HI instead.
 
@@ -546,20 +456,6 @@ 
     operands[4] = gen_lowpart (HImode, operands[1]);
   })
 
-;; Convert a memory comparison to a move if there is a scratch register.
-
-(define_peephole2
-  [(match_scratch:QHSI 1 "r")
-   (set (cc0)
-	(compare (match_operand:QHSI 0 "memory_operand" "")
-		 (const_int 0)))]
-  ""
-  [(set (match_dup 1)
-	(match_dup 0))
-   (set (cc0) (compare (match_dup 1)
-		       (const_int 0)))]
-  "")
-
 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
 ;; are grouped for each define_peephole2.
diff --git a/gcc/config/h8300/predicates.md b/gcc/config/h8300/predicates.md
index b530c2cb23e..7c4e12ab374 100644
--- a/gcc/config/h8300/predicates.md
+++ b/gcc/config/h8300/predicates.md
@@ -501,3 +501,12 @@ 
 (define_predicate "pc_or_label_operand"
   (match_code "pc,label_ref"))
 
+(define_predicate "simple_memory_operand"
+  (match_code "mem")
+{
+  if (GET_MODE (op) == mode
+      && (GET_CODE (XEXP (op, 0)) != PRE_DEC
+	  && GET_CODE (XEXP (op, 0)) != POST_INC))
+    return 1;
+  return 0;
+})
diff --git a/gcc/config/h8300/proepi.md b/gcc/config/h8300/proepi.md
index 9d19ff54084..44d59682496 100644
--- a/gcc/config/h8300/proepi.md
+++ b/gcc/config/h8300/proepi.md
@@ -36,8 +36,7 @@ 
 				   XVECLEN (operands[0], 0) - 2));
   return "ldm.l\t@er7+,%S1-%S3";
 }
-  [(set_attr "cc" "none")
-   (set_attr "length" "4")])
+  [(set_attr "length" "4")])
 
 (define_insn "stm_h8300sx"
   [(match_parallel           0 "h8300_stm_parallel"
@@ -49,8 +48,7 @@ 
 				  XVECLEN (operands[0], 0) - 2));
   return "stm.l\t%S2-%S3,@-er7";
 }
-  [(set_attr "cc" "none")
-   (set_attr "length" "4")])
+  [(set_attr "length" "4")])
 
 (define_insn "return_h8sx"
   [(match_parallel           0 "h8300_return_parallel"
@@ -67,8 +65,7 @@ 
   else
     return "rts/l\t%S1-%S3";
 }
-  [(set_attr "cc" "none")
-   (set_attr "can_delay" "no")
+  [(set_attr "can_delay" "no")
    (set_attr "length" "2")])
 
 (define_expand "return"
@@ -86,8 +83,7 @@ 
   else
     return "rts";
 }
-  [(set_attr "cc" "none")
-   (set_attr "can_delay" "no")
+  [(set_attr "can_delay" "no")
    (set_attr "length" "2")])
 
 (define_expand "prologue"
diff --git a/gcc/config/h8300/shiftrotate.md b/gcc/config/h8300/shiftrotate.md
index 5a85e1673fe..f1c86f7da1c 100644
--- a/gcc/config/h8300/shiftrotate.md
+++ b/gcc/config/h8300/shiftrotate.md
@@ -50,12 +50,24 @@ 
 
 ;; QI/HI/SI BIT SHIFTS
 
-(define_insn ""
+(define_insn_and_split ""
   [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
 	(match_operator:QHSI 3 "h8sx_unary_shift_operator"
 	 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
 	  (match_operand:QI 2 "const_int_operand" "")]))]
   "h8300_operands_match_p (operands)"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+	(match_operator:QHSI 3 "h8sx_unary_shift_operator"
+	 [(match_operand:QHSI 1 "h8300_dst_operand" "0")
+	  (match_operand:QI 2 "const_int_operand" "")]))
+   (clobber (reg:CC CC_REG))]
+  "h8300_operands_match_p (operands)"
 {
   if (<MODE>mode == E_QImode)
     return output_h8sx_shift (operands, 'b', 'X');
@@ -65,15 +77,47 @@ 
     return output_h8sx_shift (operands, 'l', 'S');
   gcc_unreachable ();
 }
-  [(set_attr "length_table" "unary")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length_table" "unary")])
 
 (define_insn ""
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN
+	  (match_operator:QHSI 3 "h8sx_unary_shift_operator"
+	    [(match_operand:QHSI 1 "h8300_dst_operand" "0")
+	     (match_operand:QI 2 "const_int_operand" "")])
+	  (const_int 0)))
+   (set (match_operand:QHSI 0 "h8300_dst_operand" "=rQ")
+	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
+  "h8300_operands_match_p (operands)"
+{
+  if (<MODE>mode == E_QImode)
+    return output_h8sx_shift (operands, 'b', 'X');
+  if (<MODE>mode == E_HImode)
+    return output_h8sx_shift (operands, 'w', 'T');
+  if (<MODE>mode == E_SImode)
+    return output_h8sx_shift (operands, 'l', 'S');
+  gcc_unreachable ();
+}
+  [(set_attr "length_table" "unary")])
+
+(define_insn_and_split ""
   [(set (match_operand:QHSI 0 "register_operand" "=r")
 	(match_operator:QHSI 3 "h8sx_binary_shift_operator"
 	 [(match_operand:QHSI 1 "register_operand" "0")
 	  (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn ""
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(match_operator:QHSI 3 "h8sx_binary_shift_operator"
+	 [(match_operand:QHSI 1 "register_operand" "0")
+	  (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   if (<MODE>mode == QImode)
     return output_h8sx_shift (operands, 'b', 'X');
@@ -83,25 +127,57 @@ 
     return output_h8sx_shift (operands, 'l', 'S');
   gcc_unreachable ();
 }
-  [(set_attr "length" "4")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "4")])
 
-(define_insn "*shiftqi"
+(define_insn ""
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN
+	  (match_operator:QHSI 3 "h8sx_binary_shift_operator"
+	   [(match_operand:QHSI 1 "register_operand" "0")
+	    (match_operand:QI 2 "nonmemory_operand" "r P5>X")])
+	  (const_int 0)))
+   (set (match_operand:QHSI 0 "register_operand" "=r")
+	(match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
+  ""
+{
+  if (<MODE>mode == QImode)
+    return output_h8sx_shift (operands, 'b', 'X');
+  if (<MODE>mode == HImode)
+    return output_h8sx_shift (operands, 'w', 'T');
+  if (<MODE>mode == SImode)
+    return output_h8sx_shift (operands, 'l', 'S');
+  gcc_unreachable ();
+}
+  [(set_attr "length" "4")])
+
+(define_insn_and_split "*shiftqi"
   [(set (match_operand:QI 0 "register_operand" "=r,r")
 	(match_operator:QI 3 "nshift_operator"
 	 [(match_operand:QI 1 "register_operand" "0,0")
 	  (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
    (clobber (match_scratch:QI 4 "=X,&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (match_dup 4))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftqi_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r,r")
+	(match_operator:QI 3 "nshift_operator"
+	 [(match_operand:QI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
+   (clobber (match_scratch:QI 4 "=X,&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
-(define_insn "*shiftqi_noscratch"
+(define_insn_and_split "*shiftqi_noscratch"
   [(set (match_operand:QI 0 "register_operand" "=r,r")
 	(match_operator:QI 3 "nshift_operator"
 	 [(match_operand:QI 1 "register_operand" "0,0")
@@ -109,34 +185,72 @@ 
   "(GET_CODE (operands[2]) == CONST_INT
     && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode,
 				     GET_CODE (operands[3])))"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftqi_noscratch_clobber_flags"
+  [(set (match_operand:QI 0 "register_operand" "=r,r")
+	(match_operator:QI 3 "nshift_operator"
+	 [(match_operand:QI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "R,rn")]))
+   (clobber (reg:CC CC_REG))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), QImode,
+				     GET_CODE (operands[3])))"
 {
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
-(define_insn "*shifthi"
+(define_insn_and_split "*shifthi"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
 	(match_operator:HI 3 "nshift_operator"
 	 [(match_operand:HI 1 "register_operand" "0,0")
 	  (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
    (clobber (match_scratch:QI 4 "=X,&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (match_dup 4))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shifthi_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+	(match_operator:HI 3 "nshift_operator"
+	 [(match_operand:HI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "S,rn")]))
+   (clobber (match_scratch:QI 4 "=X,&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
-(define_insn "*shifthi_noscratch"
+(define_insn_and_split "*shifthi_noscratch"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
 	(match_operator:HI 3 "nshift_operator"
 	 [(match_operand:HI 1 "register_operand" "0,0")
-	  (match_operand:QI 2 "nonmemory_operand" "S,rn")]))]
+	  (match_operand:HI 2 "nonmemory_operand" "S,rn")]))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode,
+				     GET_CODE (operands[3])))"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shifthi_noscratch_clobber_flags"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+	(match_operator:HI 3 "nshift_operator"
+	 [(match_operand:HI 1 "register_operand" "0,0")
+	  (match_operand:HI 2 "nonmemory_operand" "S,rn")]))
+   (clobber (reg:CC CC_REG))]
   "(GET_CODE (operands[2]) == CONST_INT
     && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), HImode,
 				     GET_CODE (operands[3])))"
@@ -144,26 +258,36 @@ 
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
-(define_insn "*shiftsi"
+(define_insn_and_split "*shiftsi"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(match_operator:SI 3 "nshift_operator"
 	 [(match_operand:SI 1 "register_operand" "0,0")
 	  (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
    (clobber (match_scratch:QI 4 "=X,&r"))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (match_dup 4))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftsi_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(match_operator:SI 3 "nshift_operator"
+	 [(match_operand:SI 1 "register_operand" "0,0")
+	  (match_operand:QI 2 "nonmemory_operand" "T,rn")]))
+   (clobber (match_scratch:QI 4 "=X,&r"))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
-(define_insn "*shiftsi_noscratch"
+(define_insn_and_split "*shiftsi_noscratch"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(match_operator:SI 3 "nshift_operator"
 	 [(match_operand:SI 1 "register_operand" "0,0")
@@ -171,14 +295,25 @@ 
   "(GET_CODE (operands[2]) == CONST_INT
     && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode,
 				     GET_CODE (operands[3])))"
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "*shiftsi_noscratch_clobber_flags"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(match_operator:SI 3 "nshift_operator"
+	 [(match_operand:SI 1 "register_operand" "0,0")
+	  (match_operand:SI 2 "nonmemory_operand" "T,rn")]))
+   (clobber (reg:CC CC_REG))]
+  "(GET_CODE (operands[2]) == CONST_INT
+    && !h8300_shift_needs_scratch_p (INTVAL (operands[2]), SImode,
+				     GET_CODE (operands[3])))"
 {
   return output_a_shift (operands);
 }
   [(set (attr "length")
-	(symbol_ref "compute_a_shift_length (insn, operands)"))
-   (set (attr "cc")
-	(symbol_ref "compute_a_shift_cc (insn, operands)"))])
-
+	(symbol_ref "compute_a_shift_length (insn, operands)"))])
 
 ;; Split a variable shift into a loop.  If the register containing
 ;; the shift count dies, then we just use that register.
@@ -188,12 +323,12 @@ 
 	(match_operator 2 "nshift_operator"
 	 [(match_dup 0)
 	  (match_operand:QI 1 "register_operand" "")]))
-   (clobber (match_operand:QI 3 "register_operand" ""))]
+   (clobber (match_operand:QI 3 "register_operand" ""))
+   (clobber (reg:CC CC_REG))]
   "epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
-  [(set (cc0) (compare (match_dup 1) (const_int 0)))
-   (set (pc)
-        (if_then_else (le (cc0) (const_int 0))
+  [(set (pc)
+        (if_then_else (le (match_dup 1) (const_int 0))
 		      (label_ref (match_dup 5))
 		      (pc)))
    (match_dup 4)
@@ -202,9 +337,8 @@ 
 	   (match_op_dup 2 [(match_dup 0) (const_int 1)]))
       (clobber (scratch:QI))])
    (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
-   (set (cc0) (compare (match_dup 1) (const_int 0)))
    (set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
+        (if_then_else (ne (match_dup 1) (const_int 0))
 		      (label_ref (match_dup 4))
 		      (pc)))
    (match_dup 5)]
@@ -218,14 +352,14 @@ 
 	(match_operator 2 "nshift_operator"
 	 [(match_dup 0)
 	  (match_operand:QI 1 "register_operand" "")]))
-   (clobber (match_operand:QI 3 "register_operand" ""))]
+   (clobber (match_operand:QI 3 "register_operand" ""))
+   (clobber (reg:CC CC_REG))]
   "epilogue_completed
    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
   [(set (match_dup 3)
 	(match_dup 1))
-   (set (cc0) (compare (match_dup 3) (const_int 0)))
    (set (pc)
-        (if_then_else (le (cc0) (const_int 0))
+        (if_then_else (le (match_dup 3) (const_int 0))
 		      (label_ref (match_dup 5))
 		      (pc)))
    (match_dup 4)
@@ -234,9 +368,8 @@ 
 	   (match_op_dup 2 [(match_dup 0) (const_int 1)]))
       (clobber (scratch:QI))])
    (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1)))
-   (set (cc0) (compare (match_dup 3) (const_int 0)))
    (set (pc)
-        (if_then_else (ne (cc0) (const_int 0))
+        (if_then_else (ne (match_dup 3) (const_int 0))
 		      (label_ref (match_dup 4))
 		      (pc)))
    (match_dup 5)]
@@ -244,6 +377,18 @@ 
     operands[4] = gen_label_rtx ();
     operands[5] = gen_label_rtx ();
   })
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand")
+	(match_operator:SI 3 "nshift_operator"
+	 [(match_operand:SI 1 "register_operand")
+	  (match_operand:QI 2 "nonmemory_operand")]))
+   (clobber (match_scratch:QI 4))]
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+	      (clobber (match_dup 4))
+	      (clobber (reg:CC CC_REG))])])
+
 
 ;; ----------------------------------------------------------------------
 ;; ROTATIONS
@@ -259,11 +404,22 @@ 
     DONE;
   })
 
-(define_insn "rotl<mode>3_1"
+(define_insn_and_split "rotl<mode>3_1"
   [(set (match_operand:QHSI 0 "register_operand" "=r")
 	(rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
 		     (match_operand:QI 2 "immediate_operand" "")))]
   ""
+  "#"
+  "reload_completed"
+  [(parallel [(set (match_dup 0) (rotate:QHSI (match_dup 1) (match_dup 2)))
+	      (clobber (reg:CC CC_REG))])])
+
+(define_insn "rotl<mode>3_1_clobber_flags"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+	(rotate:QHSI (match_operand:QHSI 1 "register_operand" "0")
+		     (match_operand:QI 2 "immediate_operand" "")))
+   (clobber (reg:CC CC_REG))]
+  ""
 {
   return output_a_rotate (ROTATE, operands);
 }
diff --git a/gcc/config/h8300/testcompare.md b/gcc/config/h8300/testcompare.md
index 118db145a8a..3ec961dd717 100644
--- a/gcc/config/h8300/testcompare.md
+++ b/gcc/config/h8300/testcompare.md
@@ -2,164 +2,155 @@ 
 ;; TEST INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn_and_split "*tst_extzv_1_n"
-  [(set (cc0)
-	(compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
-				  (const_int 1)
-				  (match_operand 1 "const_int_operand" "n,n,n"))
-		 (const_int 0)))
-   (clobber (match_scratch:QI 2 "=X,X,&r"))]
-  "!CONSTANT_P (operands[0])"
-  "@
-   btst\\t%Z1,%Y0
-   btst\\t%Z1,%Y0
-   #"
-  "&& reload_completed
-   && !satisfies_constraint_U (operands[0])"
-  [(set (match_dup 2)
-	(match_dup 0))
-   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
-						   (const_int 1)
-						   (match_dup 1))
-				  (const_int 0)))
-	      (clobber (scratch:QI))])]
-  ""
-  [(set_attr "length" "2,8,10")
-   (set_attr "cc" "set_zn,set_zn,set_zn")])
-
-(define_insn ""
-  [(set (cc0)
-	(compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
-				   (const_int 1)
-				   (match_operand 1 "const_int_operand" "n"))
-		 (const_int 0)))]
-  "INTVAL (operands[1]) <= 15"
-  "btst	%Z1,%Y0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_zn")])
-
-(define_insn_and_split "*tstsi_upper_bit"
-  [(set (cc0)
-	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-				  (const_int 1)
-				  (match_operand 1 "const_int_operand" "n"))
-		 (const_int 0)))
-   (clobber (match_scratch:SI 2 "=&r"))]
-  "INTVAL (operands[1]) >= 16"
-  "#"
-  "&& reload_completed"
-  [(set (match_dup 2)
-	(ior:SI (and:SI (match_dup 2)
-			(const_int -65536))
-		(lshiftrt:SI (match_dup 0)
-			     (const_int 16))))
-   (set (cc0)
-	(compare (zero_extract:SI (match_dup 2)
-				  (const_int 1)
-				  (match_dup 3))
-		 (const_int 0)))]
-  {
-    operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
-  })
-
-(define_insn "*tstsi_variable_bit"
-  [(set (cc0)
-	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-				  (const_int 1)
-				  (and:SI (match_operand:SI 1 "register_operand" "r")
-					  (const_int 7)))
-		 (const_int 0)))]
-  ""
-  "btst	%w1,%w0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_zn")])
-
-(define_insn_and_split "*tstsi_variable_bit_qi"
-  [(set (cc0)
-	(compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
-				  (const_int 1)
-				  (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
-					  (const_int 7)))
-		 (const_int 0)))
-   (clobber (match_scratch:QI 2 "=X,X,&r"))]
-  "!CONSTANT_P (operands[0])"
-  "@
-   btst\\t%w1,%X0
-   btst\\t%w1,%X0
-   #"
-  "&& reload_completed
-   && !satisfies_constraint_U (operands[0])"
-  [(set (match_dup 2)
-	(match_dup 0))
-   (parallel [(set (cc0)
-		   (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
-					     (const_int 1)
-					     (and:SI (match_dup 1)
-						     (const_int 7)))
-			    (const_int 0)))
-	      (clobber (scratch:QI))])]
-  ""
-  [(set_attr "length" "2,8,10")
-   (set_attr "cc" "set_zn,set_zn,set_zn")])
+;; (define_insn_and_split "*tst_extzv_1_n"
+;;   [(set (cc0)
+;; 	(compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+;; 				  (const_int 1)
+;; 				  (match_operand 1 "const_int_operand" "n,n,n"))
+;; 		 (const_int 0)))
+;;   (clobber (match_scratch:QI 2 "=X,X,&r"))]
+;;  "!CONSTANT_P (operands[0])"
+;;  "@
+;;   btst\\t%Z1,%Y0
+;;   btst\\t%Z1,%Y0
+;;   #"
+;;  "&& reload_completed
+;;   && !satisfies_constraint_U (operands[0])"
+;;  [(set (match_dup 2)
+;;	(match_dup 0))
+;;   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+;;						   (const_int 1)
+;;						   (match_dup 1))
+;;				  (const_int 0)))
+;;	      (clobber (scratch:QI))])]
+;;  ""
+;;  [(set_attr "length" "2,8,10")
+;;   (set_attr "cc" "set_zn,set_zn,set_zn")])
+;;
+;;(define_insn ""
+;;  [(set (cc0)
+;;	(compare (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
+;;				   (const_int 1)
+;;				   (match_operand 1 "const_int_operand" "n"))
+;;		 (const_int 0)))]
+;;  "INTVAL (operands[1]) <= 15"
+;;  "btst	%Z1,%Y0"
+;;  [(set_attr "length" "2")
+;;   (set_attr "cc" "set_zn")])
+;;
+;;(define_insn_and_split "*tstsi_upper_bit"
+;;  [(set (cc0)
+;;	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+;;				  (const_int 1)
+;;				  (match_operand 1 "const_int_operand" "n"))
+;;		 (const_int 0)))
+;;   (clobber (match_scratch:SI 2 "=&r"))]
+;;  "INTVAL (operands[1]) >= 16"
+;;  "#"
+;;  "&& reload_completed"
+;;  [(set (match_dup 2)
+;;	(ior:SI (and:SI (match_dup 2)
+;;			(const_int -65536))
+;;		(lshiftrt:SI (match_dup 0)
+;;			     (const_int 16))))
+;;   (set (cc0)
+;;	(compare (zero_extract:SI (match_dup 2)
+;;				  (const_int 1)
+;;				  (match_dup 3))
+;;		 (const_int 0)))]
+;;  {
+;;    operands[3] = GEN_INT (INTVAL (operands[1]) - 16);
+;;  })
+;;
+;;(define_insn "*tstsi_variable_bit"
+;;  [(set (cc0)
+;;	(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+;;				  (const_int 1)
+;;				  (and:SI (match_operand:SI 1 "register_operand" "r")
+;;					  (const_int 7)))
+;;		 (const_int 0)))]
+;;  ""
+;;  "btst	%w1,%w0"
+;;  [(set_attr "length" "2")
+;;   (set_attr "cc" "set_zn")])
+;;
+;;(define_insn_and_split "*tstsi_variable_bit_qi"
+;;  [(set (cc0)
+;;	(compare (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+;;				  (const_int 1)
+;;				  (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+;;					  (const_int 7)))
+;;		 (const_int 0)))
+;;   (clobber (match_scratch:QI 2 "=X,X,&r"))]
+;;  "!CONSTANT_P (operands[0])"
+;;  "@
+;;   btst\\t%w1,%X0
+;;   btst\\t%w1,%X0
+;;   #"
+;;  "&& reload_completed
+;;   && !satisfies_constraint_U (operands[0])"
+;;  [(set (match_dup 2)
+;;	(match_dup 0))
+;;   (parallel [(set (cc0)
+;;		   (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+;;					     (const_int 1)
+;;					     (and:SI (match_dup 1)
+;;						     (const_int 7)))
+;;			    (const_int 0)))
+;;	      (clobber (scratch:QI))])]
+;;  ""
+;;  [(set_attr "length" "2,8,10")
+;;   (set_attr "cc" "set_zn,set_zn,set_zn")])
 
 (define_insn "*tst<mode>"
-  [(set (cc0)
-	(compare (match_operand:QHI 0 "register_operand" "r")
-		 (const_int 0)))]
+  [(set (reg:CCZN CC_REG)
+	(compare:CCZN (match_operand:QHSI 0 "register_operand" "r")
+		      (const_int 0)))]
   ""
   {
     if (<MODE>mode == QImode)
       return "mov.b	%X0,%X0";
     else if (<MODE>mode == HImode)
       return "mov.w	%T0,%T0";
+    else if (<MODE>mode == SImode)
+      return "mov.l	%S0,%S0";
     gcc_unreachable ();
   }
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*tsthi_upper"
-  [(set (cc0)
+  [(set (reg:CCZN CC_REG)
 	(compare (and:HI (match_operand:HI 0 "register_operand" "r")
 			 (const_int -256))
 		 (const_int 0)))]
-  ""
+  "reload_completed"
   "mov.b	%t0,%t0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
-
-(define_insn "*tstsi"
-  [(set (cc0)
-	(compare (match_operand:SI 0 "register_operand" "r")
-		 (const_int 0)))]
-  ""
-  "mov.l	%S0,%S0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_znv")])
+  [(set_attr "length" "2")])
 
 (define_insn "*tstsi_upper"
-  [(set (cc0)
+  [(set (reg:CCZN CC_REG)
 	(compare (and:SI (match_operand:SI 0 "register_operand" "r")
 			 (const_int -65536))
 		 (const_int 0)))]
-  ""
+  "reload_completed"
   "mov.w	%e0,%e0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*cmpqi"
-  [(set (cc0)
+  [(set (reg:CC CC_REG)
 	(compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
 		 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
-  ""
+  "reload_completed"
   "cmp.b	%X1,%X0"
-  [(set_attr "length_table" "add")
-   (set_attr "cc" "compare")])
+  [(set_attr "length_table" "add")])
 
-(define_insn "*cmphi_h8300hs_znvc"
-  [(set (cc0)
+(define_insn "*cmphi"
+  [(set (reg:CC CC_REG)
 	(compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
 		 (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
-  ""
+  "reload_completed"
 {
   switch (which_alternative)
     {
@@ -174,14 +165,13 @@ 
       gcc_unreachable ();
       }
 }
-  [(set_attr "length_table" "short_immediate,add")
-   (set_attr "cc" "compare,compare")])
+  [(set_attr "length_table" "short_immediate,add")])
 
 (define_insn "cmpsi"
-  [(set (cc0)
+  [(set (reg:CC CC_REG)
 	(compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
 		 (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
-  ""
+  "reload_completed"
 {
   switch (which_alternative)
     {
@@ -197,5 +187,28 @@ 
     }
 }
   [(set_attr "length" "2,*")
-   (set_attr "length_table" "*,add")
-   (set_attr "cc" "compare,compare")])
+   (set_attr "length_table" "*,add")])
+
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+  [(match_scratch:QHSI 1 "r")
+   (set (reg:CC CC_REG)
+	(compare (match_operand:QHSI 0 "memory_operand" "")
+		 (const_int 0)))]
+  ""
+  [(parallel [(set (match_dup 1) (match_dup 0)) (clobber (reg:CC CC_REG))])
+   (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))])
+
+;; The compare-elimination pass does not handle memory reference.  So this
+;; little peephole helps fill the gap and avoid code quality regressions.
+(define_peephole2
+  [(parallel [(set (match_operand:QHSI 0 "register_operand" "")
+		   (match_operand:QHSI 1 "simple_memory_operand" ""))
+	      (clobber (reg:CC CC_REG))])
+   (set (reg:CCZN CC_REG)
+	(compare:CCZN (match_dup 0) (const_int 0)))]
+  ""
+  [(parallel [(set (reg:CCZN CC_REG) (compare:CCZN (match_dup 1) (const_int 0)))
+	      (set (match_dup 0) (match_dup 1))])])
+