Home | History | Annotate | Line # | Download | only in h8300
      1 ;; ----------------------------------------------------------------------
      2 ;; TEST INSTRUCTIONS
      3 ;; ----------------------------------------------------------------------
      4 
      5 ;; (define_insn_and_split "*tst_extzv_1_n"
      6 ;;   [(set (cc0)
      7 ;; 	(compare (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
      8 ;; 				  (const_int 1)
      9 ;; 				  (match_operand 1 "const_int_operand" "n,n,n"))
     10 ;; 		 (const_int 0)))
     11 ;;   (clobber (match_scratch:QI 2 "=X,X,&r"))]
     12 ;;  "!CONSTANT_P (operands[0])"
     13 ;;  "@
     14 ;;   btst\\t%Z1,%Y0
     15 ;;   btst\\t%Z1,%Y0
     16 ;;   #"
     17 ;;  "&& reload_completed
     18 ;;   && !satisfies_constraint_U (operands[0])"
     19 ;;  [(set (match_dup 2)
     20 ;;	(match_dup 0))
     21 ;;   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
     22 ;;						   (const_int 1)
     23 ;;						   (match_dup 1))
     24 ;;				  (const_int 0)))
     25 ;;	      (clobber (scratch:QI))])]
     26 ;;  ""
     27 ;;  [(set_attr "length" "2,8,10")])
     28 ;;
     29 (define_insn ""
     30   [(set (reg:CCZ CC_REG)
     31 	(eq (zero_extract:HSI (match_operand:HSI 0 "register_operand" "r")
     32 			      (const_int 1)
     33 			      (match_operand 1 "const_int_operand" "n"))
     34 	    (const_int 0)))]
     35   "INTVAL (operands[1]) < 16"
     36   "btst	%Z1,%Y0"
     37   [(set_attr "length" "2")])
     38 
     39 (define_insn "*tst<mode>"
     40   [(set (reg:CCZN CC_REG)
     41 	(compare:CCZN (match_operand:QHSI 0 "register_operand" "r")
     42 		      (const_int 0)))]
     43   ""
     44   {
     45     if (<MODE>mode == QImode)
     46       return "mov.b	%X0,%X0";
     47     else if (<MODE>mode == HImode)
     48       return "mov.w	%T0,%T0";
     49     else if (<MODE>mode == SImode)
     50       return "mov.l	%S0,%S0";
     51     gcc_unreachable ();
     52   }
     53   [(set_attr "length" "2")])
     54 
     55 (define_insn "*tsthi_upper"
     56   [(set (reg:CCZN CC_REG)
     57 	(compare (and:HI (match_operand:HI 0 "register_operand" "r")
     58 			 (const_int -256))
     59 		 (const_int 0)))]
     60   "reload_completed"
     61   "mov.b	%t0,%t0"
     62   [(set_attr "length" "2")])
     63 
     64 (define_insn "*tsthi_upper_z"
     65   [(set (reg:CCZ CC_REG)
     66 	(compare (and:HI (match_operand:HI 0 "register_operand" "r")
     67 			 (const_int -256))
     68 		 (const_int 0)))]
     69   "reload_completed"
     70   "mov.b	%t0,%t0"
     71   [(set_attr "length" "2")])
     72 
     73 (define_insn "*tstsi_upper"
     74   [(set (reg:CCZN CC_REG)
     75 	(compare (and:SI (match_operand:SI 0 "register_operand" "r")
     76 			 (const_int -65536))
     77 		 (const_int 0)))]
     78   "reload_completed"
     79   "mov.w	%e0,%e0"
     80   [(set_attr "length" "2")])
     81 
     82 (define_insn "*cmp<mode>_c"
     83   [(set (reg:CCC CC_REG)
     84 	(ltu (match_operand:QHSI 0 "h8300_dst_operand" "rQ")
     85 	     (match_operand:QHSI 1 "h8300_src_operand" "rQi")))]
     86   "reload_completed"
     87   {
     88     if (<MODE>mode == QImode)
     89       return "cmp.b	%X1,%X0";
     90     else if (<MODE>mode == HImode)
     91       return "cmp.w	%T1,%T0";
     92     else if (<MODE>mode == SImode)
     93       return "cmp.l	%S1,%S0";
     94     gcc_unreachable ();
     95   }
     96   [(set_attr "length_table" "add")])
     97 
     98 (define_insn "*cmpqi_z"
     99   [(set (reg:CCZ CC_REG)
    100 	(eq (match_operand:QI 0 "h8300_dst_operand" "rQ")
    101 	    (match_operand:QI 1 "h8300_src_operand" "rQi")))]
    102   "reload_completed"
    103   { return "cmp.b	%X1,%X0"; }
    104   [(set_attr "length_table" "add")])
    105 
    106 (define_insn "*cmphi_z"
    107   [(set (reg:CCZ CC_REG)
    108 	(eq (match_operand:HI 0 "h8300_dst_operand" "rQ")
    109 	    (match_operand:HI 1 "h8300_src_operand" "rQi")))]
    110   "reload_completed"
    111   { return "cmp.w	%T1,%T0"; }
    112   [(set_attr "length_table" "add")])
    113 
    114 (define_insn "*cmpsi_z"
    115   [(set (reg:CCZ CC_REG)
    116 	(eq (match_operand:SI 0 "h8300_dst_operand" "rQ")
    117 	    (match_operand:SI 1 "h8300_src_operand" "rQi")))]
    118   "reload_completed"
    119   { return "cmp.l	%S1,%S0"; }
    120   [(set_attr "length_table" "add")])
    121 
    122 (define_insn "*cmpqi"
    123   [(set (reg:CC CC_REG)
    124 	(compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
    125 		 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
    126   "reload_completed"
    127   "cmp.b	%X1,%X0"
    128   [(set_attr "length_table" "add")])
    129 
    130 (define_insn "*cmphi"
    131   [(set (reg:CC CC_REG)
    132 	(compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
    133 		 (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
    134   "reload_completed"
    135 {
    136   switch (which_alternative)
    137     {
    138     case 0:
    139       if (!TARGET_H8300SX)
    140 	return "cmp.w	%T1,%T0";
    141       else
    142 	return "cmp.w	%T1:3,%T0";
    143     case 1:
    144       return "cmp.w	%T1,%T0";
    145     default:
    146       gcc_unreachable ();
    147       }
    148 }
    149   [(set_attr "length_table" "short_immediate,add")])
    150 
    151 (define_insn "cmpsi"
    152   [(set (reg:CC CC_REG)
    153 	(compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
    154 		 (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
    155   "reload_completed"
    156 {
    157   switch (which_alternative)
    158     {
    159     case 0:
    160       if (!TARGET_H8300SX)
    161 	return "cmp.l	%S1,%S0";
    162       else
    163 	return "cmp.l	%S1:3,%S0";
    164     case 1:
    165       return "cmp.l	%S1,%S0";
    166     default:
    167       gcc_unreachable ();
    168     }
    169 }
    170   [(set_attr "length" "2,*")
    171    (set_attr "length_table" "*,add")])
    172 
    173 ;; Convert a memory comparison to a move if there is a scratch register.
    174 ;; This is preferred over the next as we can proactively avoid the
    175 ;; comparison.
    176 (define_peephole2
    177   [(match_scratch:QHSI 1 "r")
    178    (set (reg:CC CC_REG)
    179 	(compare (match_operand:QHSI 0 "memory_operand" "")
    180 		 (const_int 0)))]
    181   "!mode_dependent_address_p (XEXP (operands[0], 0), MEM_ADDR_SPACE (operands[0]))"
    182   [(parallel [(set (reg:CCZN CC_REG) (compare:CCZN (match_dup 0) (const_int 0)))
    183 	      (set (match_dup 1) (match_dup 0))])])
    184 
    185 ;; Similarly, but used when the memory reference is an autoinc address
    186 ;; mode.
    187 (define_peephole2
    188   [(match_scratch:QHSI 1 "r")
    189    (set (reg:CC CC_REG)
    190 	(compare (match_operand:QHSI 0 "memory_operand" "")
    191 		 (const_int 0)))]
    192   "mode_dependent_address_p (XEXP (operands[0], 0), MEM_ADDR_SPACE (operands[0]))"
    193   [(parallel [(set (match_dup 1) (match_dup 0)) (clobber (reg:CC CC_REG))])
    194    (set (reg:CC CC_REG) (compare:CC (match_dup 1) (const_int 0)))])
    195 
    196 ;; The compare-elimination pass does not handle memory reference.  So this
    197 ;; little peephole helps fill the gap and avoid code quality regressions.
    198 (define_peephole2
    199   [(parallel [(set (match_operand:QHSI 0 "register_operand" "")
    200 		   (match_operand:QHSI 1 "simple_memory_operand" ""))
    201 	      (clobber (reg:CC CC_REG))])
    202    (set (reg:CCZN CC_REG)
    203 	(compare:CCZN (match_dup 0) (const_int 0)))]
    204   ""
    205   [(parallel [(set (reg:CCZN CC_REG) (compare:CCZN (match_dup 1) (const_int 0)))
    206 	      (set (match_dup 0) (match_dup 1))])])
    207 
    208 ;; This exists solely to convince ifcvt to try some store-flag sequences.
    209 ;;
    210 ;; Essentially we don't want to expose a general store-flag capability.
    211 ;; The only generally useful/profitable case is when we want to test the
    212 ;; C bit.  In that case we can use addx, subx, bst, or bist to get the bit
    213 ;; into a GPR.
    214 ;;
    215 ;; Others could be handled with stc, shifts and masking, but it likely isn't
    216 ;; profitable.
    217 ;;
    218 (define_expand "cstore<mode>4"
    219   [(use (match_operator 1 "eqne_operator"
    220          [(match_operand:QHSI 2 "h8300_dst_operand" "")
    221           (match_operand:QHSI 3 "h8300_src_operand" "")]))
    222    (clobber (match_operand:QHSI 0 "register_operand"))]
    223   ""
    224   {
    225     FAIL;
    226   })
    227 
    228 ;; Storing the C bit is pretty simple since there are many ways to
    229 ;; introduce it into a GPR.  addx, subx and a variety of bit manipulation
    230 ;; instructions
    231 ;;
    232 (define_insn "*store_c_<mode>"
    233   [(set (match_operand:QHSI 0 "register_operand" "=r")
    234 	(eqne:QHSI (reg:CCC CC_REG) (const_int 0)))]
    235   "reload_completed"
    236   {
    237     if (<CODE> == NE)
    238       {
    239 	if (<MODE>mode == QImode)
    240 	  return "xor.b\t%X0,%X0\;bst\t#0,%X0";
    241 	else if (<MODE>mode == HImode)
    242 	  return "xor.w\t%T0,%T0\;bst\t#0,%s0";
    243 	else if (<MODE>mode == SImode)
    244 	  return "xor.l\t%S0,%S0\;bst\t#0,%w0";
    245 	gcc_unreachable ();
    246       }
    247     else if (<CODE> == EQ)
    248       {
    249 	if (<MODE>mode == QImode)
    250 	  return "xor.b\t%X0,%X0\;bist\t#0,%X0";
    251 	else if (<MODE>mode == HImode)
    252 	  return "xor.w\t%T0,%T0\;bist\t#0,%s0";
    253 	else if (<MODE>mode == SImode)
    254 	  return "xor.l\t%S0,%S0\;bist\t#0,%w0";
    255 	gcc_unreachable ();
    256       }
    257     else
    258       gcc_unreachable ();
    259   }
    260   [(set (attr "length") (symbol_ref "<MODE>mode == SImode ? 6 : 4"))])
    261 
    262 ;; Similarly, but with a negated result
    263 (define_insn "*store_neg_c_<mode>"
    264   [(set (match_operand:QHSI 0 "register_operand" "=r")
    265 	(neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))]
    266   "reload_completed"
    267   {
    268     if (<MODE>mode == QImode)
    269       return "subx\t%X0,%X0";
    270     else if (<MODE>mode == HImode)
    271       return "subx\t%X0,%X0\;exts.w\t%T0";
    272     else if (<MODE>mode == SImode)
    273       return "subx\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0";
    274     gcc_unreachable ();
    275   }
    276   [(set
    277      (attr "length")
    278      (symbol_ref "(<MODE>mode == SImode ? 6 : <MODE>mode == HImode ? 4 : 2)"))])
    279 
    280 ;; Using b[i]st we can store the C bit into any of the low 16 bits of
    281 ;; a destination.  We can also rotate it up into the high bit of a 32 bit
    282 ;; destination.
    283 (define_insn "*store_shifted_c<mode>"
    284   [(set (match_operand:QHSI 0 "register_operand" "=r")
    285 	(ashift:QHSI (eqne:QHSI (reg:CCC CC_REG) (const_int 0))
    286 		     (match_operand 1 "immediate_operand" "n")))]
    287   "(reload_completed
    288     && (INTVAL (operands[1]) == 31 || INTVAL (operands[1]) <= 15))"
    289   {
    290     if (<CODE> == NE)
    291       {
    292 	if (<MODE>mode == QImode)
    293 	  return "xor.b\t%X0,%X0\;bst\t%1,%X0";
    294 	else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
    295 	  return "xor.w\t%T0,%T0\;bst\t%1,%X0";
    296 	else if (<MODE>mode == HImode)
    297 	  {
    298 	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
    299 	    output_asm_insn ("xor.w\t%T0,%T0\;bst\t%1,%t0", operands);
    300 	    return "";
    301 	  }
    302 	else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
    303 	  return "xor.l\t%S0,%S0\;rotxr.l\t%S0";
    304 	else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
    305 	  return "xor.l\t%S0,%S0\;bst\t%1,%X0";
    306 	else if (<MODE>mode == SImode)
    307 	  {
    308 	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
    309 	    output_asm_insn ("xor.l\t%S0,%S0\;bst\t%1,%t0", operands);
    310 	    return "";
    311 	  }
    312 	gcc_unreachable ();
    313       }
    314     else if (<CODE> == EQ)
    315       {
    316 	if (<MODE>mode == QImode)
    317 	  return "xor.b\t%X0,%X0\;bist\t%1,%X0";
    318 	else if (<MODE>mode == HImode && INTVAL (operands[1]) < 8)
    319 	  return "xor.w\t%T0,%T0\;bist\t%1,%X0";
    320 	else if (<MODE>mode == HImode)
    321 	  {
    322 	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
    323 	    output_asm_insn ("xor.w\t%T0,%T0\;bist\t%1,%t0", operands);
    324 	    return "";
    325 	  }
    326 	else if (<MODE>mode == SImode && INTVAL (operands[1]) == 31)
    327 	  return "xor.l\t%S0,%S0\;bixor\t#0,%X0\;rotxr.l\t%S0";
    328 	else if (<MODE>mode == SImode && INTVAL (operands[1]) < 8)
    329 	  return "xor.l\t%S0,%S0\;bist\t%1,%X0";
    330 	else if (<MODE>mode == SImode)
    331 	  {
    332 	    operands[1] = GEN_INT (INTVAL (operands[1]) - 8);
    333 	    output_asm_insn ("xor.l\t%S0,%S0\;bist\t%1,%t0", operands);
    334 	    return "";
    335 	  }
    336 	gcc_unreachable ();
    337       }
    338     gcc_unreachable ();
    339   }
    340   [(set
    341      (attr "length")
    342      (symbol_ref "(<MODE>mode == QImode ? 4
    343 		   : <MODE>mode == HImode ? 4
    344 		   : <CODE> == NE ? 6
    345 		   : INTVAL (operands[1]) == 31 ? 8 : 6)"))])
    346 
    347 ;; Recognize this scc and generate code we can match
    348 (define_insn_and_split "*store_c"
    349   [(set (match_operand:QHSI 0 "register_operand" "=r")
    350 	(geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
    351 		     (match_operand:QHSI2 2 "register_operand" "r")))]
    352   ""
    353   "#"
    354   "&& reload_completed"
    355   [(set (reg:CCC CC_REG)
    356 	(ltu:CCC (match_dup 1) (match_dup 2)))
    357    (set (match_dup 0)
    358 	(<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0)))])
    359 
    360 ;; We can fold in negation of the result and generate better code than
    361 ;; what the generic bits would do when testing for C == 1
    362 (define_insn_and_split "*store_neg_c"
    363   [(set (match_operand:QHSI 0 "register_operand" "=r")
    364 	(neg:QHSI
    365 	  (ltu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
    366 		    (match_operand:QHSI2 2 "register_operand" "r"))))]
    367   ""
    368   "#"
    369   "&& reload_completed"
    370   [(set (reg:CCC CC_REG)
    371 	(ltu:CCC (match_dup 1) (match_dup 2)))
    372    (set (match_dup 0)
    373 	(neg:QHSI (ne:QHSI (reg:CCC CC_REG) (const_int 0))))])
    374 
    375 ;; We can use rotates and bst/bist to put the C bit into various places
    376 ;; in the destination.
    377 (define_insn_and_split "*store_shifted_c"
    378   [(set (match_operand:QHSI 0 "register_operand" "=r")
    379        (ashift:QHSI (geultu:QHSI (match_operand:QHSI2 1 "register_operand" "r")
    380                                  (match_operand:QHSI2 2 "register_operand" "r"))
    381 		    (match_operand 3 "immediate_operand" "n")))]
    382   "INTVAL (operands[3]) == 31 || INTVAL (operands[3]) <= 15"
    383   "#"
    384   "&& reload_completed"
    385   [(set (reg:CCC CC_REG) (ltu:CCC (match_dup 1) (match_dup 2)))
    386    (set (match_dup 0)
    387 	(ashift:QHSI (<geultu_to_c>:QHSI (reg:CCC CC_REG) (const_int 0))
    388 		     (match_dup 3)))])
    389 
    390 ;; Storing Z into a QImode destination is fairly easy on the H8/S and
    391 ;; newer as the stc; shift; mask is just 3 insns/6 bytes.  On the H8/300H
    392 ;; it is 4 insns/8 bytes which is a speed improvement, but a size
    393 ;; regression relative to the branchy sequence
    394 ;;
    395 ;; Storing inverted Z in QImode is not profitable on the H8/300H, but
    396 ;; is a speed improvement on the H8S.
    397 (define_insn_and_split "*store_z_qi"
    398   [(set (match_operand:QI 0 "register_operand" "=r")
    399 	(eq:QI (match_operand:HI 1 "register_operand" "r")
    400 	       (match_operand:HI 2 "register_operand" "r")))]
    401   "TARGET_H8300S || !optimize_size"
    402   "#"
    403   "&& reload_completed"
    404   [(set (reg:CCZ CC_REG)
    405 	(eq:CCZ (match_dup 1) (match_dup 2)))
    406    (set (match_dup 0)
    407 	(ne:QI (reg:CCZ CC_REG) (const_int 0)))])
    408 
    409 (define_insn_and_split "*store_z_i_qi"
    410   [(set (match_operand:QI 0 "register_operand" "=r")
    411 	(ne:QI (match_operand:HI 1 "register_operand" "r")
    412 	       (match_operand:HI 2 "register_operand" "r")))]
    413   "TARGET_H8300S"
    414   "#"
    415   "&& reload_completed"
    416   [(set (reg:CCZ CC_REG)
    417 	(eq:CCZ (match_dup 1) (match_dup 2)))
    418    (set (match_dup 0)
    419 	(eq:QI (reg:CCZ CC_REG) (const_int 0)))])
    420 
    421 (define_insn "*store_z_qi"
    422   [(set (match_operand:QI 0 "register_operand" "=r")
    423 	(ne:QI (reg:CCZ CC_REG) (const_int 0)))]
    424   "(TARGET_H8300S || !optimize_size) && reload_completed"
    425   {
    426     if (TARGET_H8300S)
    427       return "stc\tccr,%X0\;shar\t#2,%X0\;and\t#0x1,%X0";
    428     else
    429       return "stc\tccr,%X0\;shar\t%X0\;shar\t%X0\;and\t#0x1,%X0";
    430   }
    431   [(set (attr "length") (symbol_ref "TARGET_H8300S ? 6 : 8"))])
    432 
    433 (define_insn "*store_z_i_qi"
    434   [(set (match_operand:QI 0 "register_operand" "=r")
    435 	(eq:QI (reg:CCZ CC_REG) (const_int 0)))]
    436   "(TARGET_H8300S || !optimize_size) && reload_completed"
    437   "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,%X0";
    438   [(set_attr "length" "8")])
    439 
    440 ;; Storing Z or an inverted Z into a HImode destination is
    441 ;; profitable on the H8/S and older variants, but not on the
    442 ;; H8/SX where the branchy sequence can use the two-byte
    443 ;; mov-immediate that is specific to the H8/SX
    444 (define_insn_and_split "*store_z_hi"
    445   [(set (match_operand:HSI 0 "register_operand" "=r")
    446 	(eqne:HSI (match_operand:HSI2 1 "register_operand" "r")
    447 		  (match_operand:HSI2 2 "register_operand" "r")))]
    448   "!TARGET_H8300SX"
    449   "#"
    450   "&& reload_completed"
    451   [(set (reg:CCZ CC_REG)
    452 	(eq:CCZ (match_dup 1) (match_dup 2)))
    453    (set (match_dup 0)
    454 	(<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0)))])
    455 
    456 ;; Similar, but putting the result into the sign bit
    457 (define_insn_and_split "*store_z_hi_sb"
    458   [(set (match_operand:HSI 0 "register_operand" "=r")
    459 	(ashift:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r")
    460 			      (match_operand:HSI2 2 "register_operand" "r"))
    461 		     (const_int 15)))]
    462   "!TARGET_H8300SX"
    463   "#"
    464   "&& reload_completed"
    465   [(set (reg:CCZ CC_REG)
    466 	(eq:CCZ (match_dup 1) (match_dup 2)))
    467    (set (match_dup 0)
    468 	(ashift:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0))
    469 		    (const_int 15)))])
    470 
    471 ;; Similar, but negating the result
    472 (define_insn_and_split "*store_z_hi_neg"
    473   [(set (match_operand:HSI 0 "register_operand" "=r")
    474 	(neg:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r")
    475 			   (match_operand:HSI2 2 "register_operand" "r"))))]
    476   "!TARGET_H8300SX"
    477   "#"
    478   "&& reload_completed"
    479   [(set (reg:CCZ CC_REG)
    480 	(eq:CCZ (match_dup 1) (match_dup 2)))
    481    (set (match_dup 0)
    482 	(neg:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0))))])
    483 
    484 (define_insn_and_split "*store_z_hi_and"
    485   [(set (match_operand:HSI 0 "register_operand" "=r")
    486 	(and:HSI (eqne:HSI (match_operand:HSI2 1 "register_operand" "r")
    487 			   (match_operand:HSI2 2 "register_operand" "r"))
    488 		 (match_operand:HSI 3 "register_operand" "r")))]
    489   "!TARGET_H8300SX"
    490   "#"
    491   "&& reload_completed"
    492   [(set (reg:CCZ CC_REG)
    493 	(eq:CCZ (match_dup 1) (match_dup 2)))
    494    (set (match_dup 0)
    495 	(and:HSI (<eqne_invert>:HSI (reg:CCZ CC_REG) (const_int 0))
    496 		 (match_dup 3)))])
    497 
    498 (define_insn "*store_z_<mode>"
    499   [(set (match_operand:HSI 0 "register_operand" "=r")
    500 	(eqne:HSI (reg:CCZ CC_REG) (const_int 0)))]
    501   "!TARGET_H8300SX"
    502   {
    503     if (<MODE>mode == HImode)
    504       {
    505 	if (<CODE> == NE)
    506 	  {
    507 	    if (TARGET_H8300S)
    508 	      return "stc\tccr,%X0\;shlr.b\t#2,%X0\;and.w\t#1,%T0";
    509 	    return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#0,%X0";
    510 	  }
    511 	else
    512 	  return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,%X0";
    513       }
    514     else if (<MODE>mode == SImode)
    515       {
    516 	if (<CODE> == NE)
    517 	  {
    518 	    if (TARGET_H8300S)
    519 	      return "stc\tccr,%X0\;shlr.b\t#2,%X0\;and.l\t#1,%S0";
    520 	    return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%S0,%S0\;bst\t#0,%X0";
    521 	  }
    522 	else
    523 	  return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%S0,%S0\;bist\t#0,%X0";
    524       }
    525     gcc_unreachable ();
    526   }
    527 ;; XXXSImode is 2 bytes longer
    528   [(set_attr "length" "8")])
    529 
    530 (define_insn "*store_z_<mode>_sb"
    531   [(set (match_operand:HSI 0 "register_operand" "=r")
    532 	(ashift:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0))
    533 		    (const_int 15)))]
    534   "!TARGET_H8300SX"
    535   {
    536     if (<MODE>mode == HImode)
    537       {
    538 	if (<CODE> == NE)
    539 	  return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#7,%t0";
    540 	else
    541 	  return "stc\tccr,%X0\;bld\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#7,%t0";
    542       }
    543     else if (<MODE>mode == SImode)
    544       {
    545 	if (<CODE> == NE)
    546 	  return "stc\tccr,%X0\;bld\t#2,%X0\;xor.l\t%T0,%T0\;rotxr.l\t%S0";
    547 	else
    548 	  return "stc\tccr,%X0\;bild\t#2,%X0\;xor.l\t%T0,%T0\;rotxr.l\t%S0";
    549       }
    550     gcc_unreachable ();
    551   }
    552   ;; XXX SImode is larger
    553   [(set_attr "length" "8")])
    554 
    555 (define_insn "*store_z_<mode>_neg"
    556   [(set (match_operand:HSI 0 "register_operand" "=r")
    557 	(neg:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0))))]
    558   "!TARGET_H8300SX"
    559   {
    560     if (<MODE>mode == HImode)
    561       {
    562 	if (<CODE> == NE)
    563 	  return "stc\tccr,%X0\;bld\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0";
    564 	else
    565 	  return "stc\tccr,%X0\;bild\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0";
    566       }
    567     else if (<MODE>mode == SImode)
    568       {
    569 	if (<CODE> == NE)
    570 	  return "stc\tccr,%X0\;bld\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0";
    571 	else
    572 	  return "stc\tccr,%X0\;bild\t#2,%X0\;subx.b\t%X0,%X0\;exts.w\t%T0\;exts.l\t%S0";
    573       }
    574     gcc_unreachable ();
    575   }
    576   ;; XXX simode is an instruction longer
    577   [(set_attr "length" "8")])
    578 
    579 (define_insn "*store_z_<mode>_and"
    580   [(set (match_operand:HSI 0 "register_operand" "=r")
    581 	(and:HSI (eqne:HSI (reg:CCZ CC_REG) (const_int 0))
    582 		 (match_operand:HSI 1 "register_operand" "r")))]
    583   "!TARGET_H8300SX"
    584   {
    585     if (<MODE>mode == HImode)
    586       {
    587 	if (<CODE> == NE)
    588 	  return "bld\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.w\t%T0,%T0\;bst\t#0,%X0";
    589 	else
    590 	  return "bild\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.w\t%T0,%T0\;bist\t#0,X0";
    591       }
    592     else if (<MODE>mode == SImode)
    593       {
    594 	if (<CODE> == NE)
    595 	  return "bld\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.l\t%S0,%S0\;bst\t#0,%X0";
    596 	else
    597 	  return "bild\t#0,%X1\;stc\tccr,%X0\;band\t#2,%X0\;xor.l\t%S0,%S0\;bist\t#0,X0";
    598       }
    599     gcc_unreachable ();
    600   }
    601   ;; XXX simode is an instruction longer
    602   [(set_attr "length" "8")])
    603 
    604 ;; We can test the upper byte of a HImode register and the upper word
    605 ;; of a SImode register
    606 
    607 ;; We can test the upper byte of a HImode register and the upper word
    608 ;; of a SImode register
    609 (define_insn_and_split "*store_z"
    610   [(set (match_operand:HI 0 "register_operand" "=r")
    611 	(eqne:HI (and:HI (match_operand:HI 1 "register_operand" "r")
    612 			 (const_int -256))
    613 		 (const_int 0)))]
    614   "!TARGET_H8300SX"
    615   "#"
    616   "&& reload_completed"
    617   [(set (reg:CCZ CC_REG)
    618 	(compare (and:HI (match_dup 1) (const_int -256))
    619 		 (const_int 0)))
    620    (set (match_dup 0)
    621 	(<eqne_invert>:HI (reg:CCZ CC_REG) (const_int 0)))])
    622