OSDN Git Service

* h8300/h8300.md (andhi3): If 2nd operand is a CONST_INT that
[pf3gnuchains/gcc-fork.git] / gcc / config / h8300 / h8300.md
1 ;; GCC machine description for Hitachi H8/300
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
3
4 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
5 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
6
7 ;; This file is part of GNU CC.
8
9 ;; GNU CC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU CC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
26
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28
29 (define_attr "cpu" "h8300,h8300h"
30   (const (symbol_ref "cpu_type")))
31
32 ;; ??? If we can remove the operand type on all the insns, do it.
33 ;; ??? Otherwise, try to have the operand type on all the insns.
34 ;; ??? Many patterns have overly conservative lengths.  In particular:
35 ;;
36 ;;      * movXX insns using register indirect addressing.
37 ;;      * insns referencing the 8-bit area with an 8-bit address.
38
39 ;; Some move patterns have conditions which check that one operand
40 ;; is a register.  Shouldn't all of them have such a condition?
41
42 ;; Consistently use "a" constraint.  Probably makes little difference
43 ;; in the generated code, but it's easy to do.
44
45 ;; Loading some 32bit integer constants could be done more
46 ;; efficiently.  For example loading the value 4 as a 32bit
47 ;; is normally done via mov.l #4,erX.  sub.l erX,erX, inc.l #4,erX 
48 ;; would be more efficient time and space-wise.  Similar sequences
49 ;; can be found using bit-set insns dec, etc
50
51 ;; Many logical operations should have "bit" variants if only one
52 ;; bit is going to be operated on.
53
54 ;; Should be HI & SImode tstXX insns which test one bit using btst.
55
56
57 (define_attr "type" "branch,bcs,return,call,arith,move,float,multi"
58   (const_string "arith"))
59
60 ;; The size of instructions in bytes.
61
62 (define_attr "length" "" 
63   (cond [(eq_attr "type" "branch")
64          (if_then_else (and (ge (minus (pc) (match_dup 0))
65                                 (const_int -120))
66                             (le (minus (pc) (match_dup 0))
67                                 (const_int 120)))
68                        (const_int 2)
69                        (if_then_else (and (eq_attr "cpu" "h8300h")
70                                           (and (ge (minus (pc) (match_dup 0))
71                                                    (const_int -32000))
72                                                (le (minus (pc) (match_dup 0))
73                                                    (const_int 32000))))
74                                      (const_int 4)
75                                      (const_int 6)))
76          (eq_attr "type" "bcs")
77          (if_then_else (and (ge (minus (pc) (match_dup 0))
78                                 (const_int -120))
79                             (le (minus (pc) (match_dup 0))
80                                 (const_int 120)))
81                        (if_then_else
82                          (match_operand 2 "register_operand" "")
83                          (const_int 4)
84                          (const_int 6))
85                        (if_then_else (and (eq_attr "cpu" "h8300h")
86                                           (and (ge (minus (pc) (match_dup 0))
87                                                    (const_int -32000))
88                                                (le (minus (pc) (match_dup 0))
89                                                    (const_int 32000))))
90                                      (if_then_else
91                                        (match_operand 2 "register_operand" "")
92                                        (const_int 6)
93                                        (const_int 8))
94                                      (if_then_else
95                                        (match_operand 2 "register_operand" "")
96                                        (const_int 8)
97                                        (const_int 10))))
98          (eq_attr "type" "move")        (const_int 4)
99          (eq_attr "type" "return")      (const_int 2)
100          (eq_attr "type" "float")       (const_int 12)
101          (eq_attr "type" "call")        (const_int 4)]
102         (const_int 200)))
103
104 ;; Condition code settings.
105 ;; none - insn does not affect cc
106 ;; none_0hit - insn does not affect cc but it does modify operand 0
107 ;;      This attribute is used to keep track of when operand 0 changes.
108 ;;      See the description of NOTICE_UPDATE_CC for more info.
109 ;; set - insn sets flags z,n.  v,c are set to 0.
110 ;;      (c may not really be set to 0 but that's ok, we don't need it anyway).
111 ;; set_zn_c0 - insn sets z,n to usable values.  v is unknown.  c may or may not
112 ;;      be known (if it isn't that's ok, we don't need it anyway).
113 ;; compare - compare instruction
114 ;; clobber - value of cc is unknown
115 (define_attr "cc" "none,none_0hit,set,set_zn_c0,compare,clobber"
116   (const_string "clobber"))
117 \f
118 ;; ----------------------------------------------------------------------
119 ;; MOVE INSTRUCTIONS
120 ;; ----------------------------------------------------------------------
121
122 ;; movqi
123
124 (define_insn "movqi_push"
125   [(set (match_operand:QI 0 "push_operand" "=<")
126         (match_operand:QI 1 "register_operand" "r"))]
127   ""
128   "*
129 {
130   if (TARGET_H8300)
131     return \"push.w     %T1\";
132   else
133     return \"push.l     %S1\";
134 }"
135   [(set_attr "type" "move")
136    (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
137    (set_attr "cc" "set")])
138
139 (define_insn "movqi_internal"
140   [(set (match_operand:QI 0 "general_operand_dst" "=r,r,<,r,o")
141         (match_operand:QI 1 "general_operand_src" "I,r>,r,io,r"))]
142   "register_operand (operands[0],QImode)
143    || register_operand (operands[1], QImode)"
144   "@
145    sub.b        %X0,%X0
146    mov.b        %R1,%X0
147    mov.b        %X1,%R0
148    mov.b        %R1,%X0
149    mov.b        %X1,%R0"
150   [(set_attr "type" "move")
151    (set_attr_alternative "length"
152      [(const_int 2) (const_int 2) (const_int 2)
153       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
154       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
155    (set_attr "cc" "set_zn_c0,set,set,set,set")])
156
157 (define_expand "movqi"
158   [(set (match_operand:QI 0 "general_operand_dst" "")
159         (match_operand:QI 1 "general_operand_src" ""))]
160   ""
161   "
162 {
163   /* One of the ops has to be in a register */
164   if (!register_operand(operand0, QImode)
165       && !register_operand(operand1, QImode))
166     {
167       operands[1] = copy_to_mode_reg(QImode, operand1);
168     }
169 }")
170
171 (define_insn "movstrictqi"
172   [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r"))
173                          (match_operand:QI 1 "general_operand_src" "I,r,io"))]
174   ""
175   "@
176    sub.b        %X0,%X0
177    mov.b        %X1,%X0
178    mov.b        %R1,%X0"
179   [(set_attr "type" "move")
180    (set_attr_alternative "length"
181      [(const_int 2) (const_int 2)
182       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
183    (set_attr "cc" "set_zn_c0,set,set")])
184    
185 ;; movhi
186
187 ;; ??? We use push.l on the h8300h to push a 16bit value?!?  We have
188 ;; 16bit push insns!
189 (define_insn "movhi_push"
190   [(set (match_operand:HI 0 "push_operand" "=<")
191         (match_operand:HI 1 "register_operand" "ra"))]
192   ""
193   "*
194 {
195   if (TARGET_H8300)
196     return \"push.w     %T1\";
197   else
198     return \"push.l     %S1\";
199 }"
200   [(set_attr "type" "move")
201    (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)))
202    (set_attr "cc" "set")])
203
204 (define_insn "movhi_internal"
205   [(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,<,ra,o")
206         (match_operand:HI 1 "general_operand_src" "I,ra>,ra,ion,ra"))]
207   "register_operand (operands[0],HImode)
208    || register_operand (operands[1], HImode)"
209   "@
210    sub.w        %T0,%T0
211    mov.w        %T1,%T0
212    mov.w        %T1,%T0
213    mov.w        %T1,%T0
214    mov.w        %T1,%T0"
215   [(set_attr "type" "move")
216    (set_attr_alternative "length"
217      [(const_int 2) (const_int 2) (const_int 2)
218       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))
219       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
220    (set_attr "cc" "set_zn_c0,set,set,set,set")])
221
222 (define_expand "movhi"
223   [(set (match_operand:HI 0 "general_operand_dst" "")
224         (match_operand:HI 1 "general_operand_src" ""))]
225   ""
226   "
227 {
228   /* One of the ops has to be in a register */
229   if (!register_operand(operand1, HImode)
230       && !register_operand(operand0, HImode))
231     {
232       operands[1] = copy_to_mode_reg(HImode, operand1);
233     }
234 }")
235
236 (define_insn "movstricthi"
237   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r"))
238                          (match_operand:HI 1 "general_operand_src" "I,r,io"))]
239   ""
240   "@
241    sub.w        %T0,%T0
242    mov.w        %T1,%T0
243    mov.w        %T1,%T0"
244   [(set_attr "type" "move")
245    (set_attr_alternative "length"
246      [(const_int 2) (const_int 2)
247       (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))])
248    (set_attr "cc" "set_zn_c0,set,set")])
249
250 ;; movsi
251
252 (define_expand "movsi"
253   [(set (match_operand:SI 0 "general_operand_dst" "")
254         (match_operand:SI 1 "general_operand_src" ""))]
255   ""
256   "
257 {
258   if (TARGET_H8300)
259     {
260       if (do_movsi (operands))
261         DONE;
262     }
263   else /* TARGET_H8300H */
264     {
265       /* One of the ops has to be in a register.  */
266       if (!register_operand (operand1, SImode)
267           && !register_operand (operand0, SImode))
268         {
269           operands[1] = copy_to_mode_reg (SImode, operand1);
270         }
271     }
272 }")
273
274 (define_expand "movsf"
275   [(set (match_operand:SF 0 "general_operand_dst" "")
276         (match_operand:SF 1 "general_operand_src" ""))]
277   ""
278   "
279 {
280   if (TARGET_H8300)
281     {
282       if (do_movsi (operands))
283         DONE;
284     }
285   else /* TARGET_H8300H */
286     {
287       /* One of the ops has to be in a register.  */
288       if (!register_operand (operand1, SFmode)
289           && !register_operand (operand0, SFmode))
290         {
291           operands[1] = copy_to_mode_reg (SFmode, operand1);
292         }
293     }
294 }")
295
296 (define_insn "movsi_h8300"
297   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
298         (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))]
299   "TARGET_H8300
300    && (register_operand (operands[0], SImode)
301        || register_operand (operands[1], SImode))"
302   "*
303 {
304   int rn = -1;
305   switch (which_alternative)
306     {
307     case 0:
308       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
309     case 1:
310       if (REGNO(operands[0]) < REGNO(operands[1]))
311         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
312       else 
313         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
314     case 2:
315       /* Make sure we don't trample the register we index with.  */
316     
317       if (GET_CODE(operands[1]) == MEM) 
318         {
319           rtx inside = XEXP (operands[1],0);
320           if  (REG_P (inside)) 
321             {
322               rn = REGNO(inside);
323             }
324           else if (GET_CODE (inside) == PLUS) 
325             {
326               rtx lhs = XEXP (inside,0);
327               rtx rhs = XEXP (inside,1);
328               if (REG_P (lhs)) rn = REGNO (lhs);
329               if (REG_P (rhs)) rn = REGNO (rhs);
330             }
331         }
332       if (rn == REGNO (operands[0]))    
333         {
334           /* Move the second word first.  */
335           return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
336         }
337       else 
338         {
339           /* See if either half is zero.  If so, use sub.w to clear
340              that half.  */
341         if (GET_CODE (operands[1]) == CONST_INT)
342           {
343             if ((INTVAL (operands[1]) & 0xffff) == 0)
344               return \"mov.w    %e1,%e0\;sub.w  %f0,%f0\";
345             if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0)
346               return \"sub.w    %e0,%e0\;mov.w  %f1,%f0\";
347           }
348         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
349         }
350     case 3:
351         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
352     case 4:
353       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
354     case 5:
355       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
356     }
357 }"
358   [(set_attr "type" "move")
359    (set_attr "length" "4,4,8,8,4,4")
360    (set_attr "cc" "clobber")])
361
362 (define_insn "movsf_h8300"
363   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
364         (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))]
365   "TARGET_H8300
366    && (register_operand (operands[0], SFmode)
367        || register_operand (operands[1], SFmode))"
368   "*
369 {
370   /* Copy of the movsi stuff */
371   int rn = -1;
372   switch (which_alternative)
373     {
374     case 0:
375       return \"sub.w    %e0,%e0\;sub.w  %f0,%f0\";
376     case 1:
377       if (REGNO(operands[0]) < REGNO(operands[1]))
378         return \"mov.w  %e1,%e0\;mov.w  %f1,%f0\";
379       else 
380         return \"mov.w  %f1,%f0\;mov.w  %e1,%e0\";
381     case 2:
382       /* Make sure we don't trample the register we index with.  */
383     
384       if (GET_CODE (operands[1]) == MEM) 
385         {
386           rtx inside = XEXP (operands[1],0);
387           if (REG_P (inside))
388             {
389               rn = REGNO (inside);
390             }
391           else if (GET_CODE (inside) == PLUS) 
392             {
393               rtx lhs = XEXP (inside,0);
394               rtx rhs = XEXP (inside,1);
395               if (REG_P (lhs)) rn = REGNO (lhs);
396               if (REG_P (rhs)) rn = REGNO (rhs);
397             }
398         }
399       if (rn == REGNO (operands[0]))
400         {
401           /* move the second word first */
402           return \"mov.w        %f1,%f0\;mov.w  %e1,%e0\";
403         }
404       else 
405         {
406           return \"mov.w        %e1,%e0\;mov.w  %f1,%f0\";
407         }
408     
409     case 3:
410       return \"mov.w    %e1,%e0\;mov.w  %f1,%f0\";
411     case 4:
412       return \"mov.w    %f1,%T0\;mov.w  %e1,%T0\";
413     case 5:
414       return \"mov.w    %T1,%e0\;mov.w  %T1,%f0\";
415
416     }
417 }"
418   [(set_attr "type" "move")
419    (set_attr "length" "4,4,8,8,4,4")
420    (set_attr "cc" "clobber")])
421
422 (define_insn "movsi_h8300h"
423   [(set (match_operand:SI 0 "general_operand_dst" "=ra,ra,ra,o,<,ra")
424         (match_operand:SI 1 "general_operand_src" "I,ra,ion,ra,ra,>"))]
425   "TARGET_H8300H
426    && (register_operand (operands[0], SImode)
427        || register_operand (operands[1], SImode))"
428   "*
429 {
430   if (which_alternative == 0)
431     return \"sub.l      %S0,%S0\";
432   if (GET_CODE (operands[1]) == CONST_INT)
433     {
434       int val = INTVAL (operands[1]);
435
436       /* Look for constants which can be made by adding an 8-bit
437          number to zero in one of the two low bytes.  */
438       if (val == (val & 0xff))
439         {
440           operands[1] = GEN_INT ((char)val & 0xff);
441           return \"sub.l %S0,%S0\;add.b %1,%w0\";
442         }
443      
444       if (val == (val & 0xff00))
445         {
446           operands[1] = GEN_INT ((char)(val >> 8) & 0xff);
447           return \"sub.l %S0,%S0\;add.b %1,%x0\";
448         }
449
450       /* Now look for small negative numbers.  We can subtract them
451          from zero to get the desired constant.  */
452       if (val == -4 || val == -2 || val == -1)
453         {
454           operands[1] = GEN_INT (-INTVAL (operands[1]));
455           return \"sub.l %S0,%S0\;subs %1,%S0\";
456         }
457     }
458    return \"mov.l       %S1,%S0\";
459 }"
460   [(set_attr "type" "move")
461    (set_attr "length" "2,2,10,10,4,4")
462    (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
463
464 (define_insn "movsf_h8300h"
465   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
466         (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))]
467   "TARGET_H8300H
468    && (register_operand (operands[0], SFmode)
469        || register_operand (operands[1], SFmode))"
470   "@
471    sub.l        %S0,%S0
472    mov.l        %S1,%S0
473    mov.l        %S1,%S0
474    mov.l        %S1,%S0
475    mov.l        %S1,%S0
476    mov.l        %S1,%S0"
477   [(set_attr "type" "move")
478    (set_attr "length" "2,2,10,10,4,4")
479    (set_attr "cc" "set_zn_c0,set,set,set,set,set")])
480 \f
481 ;; ----------------------------------------------------------------------
482 ;; TEST INSTRUCTIONS
483 ;; ----------------------------------------------------------------------
484
485 (define_insn ""
486   [(set (cc0) (and:QI (match_operand:QI 0 "bit_operand" "Ur")
487                       (match_operand:QI 1 "o_operand" "O")))]
488   ""
489   "btst %W1,%R0"
490   [(set_attr "type" "arith")
491    (set_attr "length" "2")
492    (set_attr "cc" "set_zn_c0")])
493   
494 (define_insn "tstqi"
495   [(set (cc0) (match_operand:QI 0 "general_operand" "ra"))]
496   ""
497   "mov.b        %X0,%X0"
498   [(set_attr "type" "arith")
499    (set_attr "length" "2")
500    (set_attr "cc" "set")])
501
502 (define_insn "tsthi"
503   [(set (cc0) (match_operand:HI 0 "general_operand" "ra"))]
504   ""
505   "mov.w        %T0,%T0"
506   [(set_attr "type" "arith")
507    (set_attr "length" "2")
508    (set_attr "cc" "set")])
509
510 (define_insn "tstsi"
511   [(set (cc0) (match_operand:SI 0 "general_operand" "ra"))]
512   "TARGET_H8300H"
513   "mov.l        %S0,%S0"
514   [(set_attr "type" "arith")
515    (set_attr "length" "2")
516    (set_attr "cc" "set")])
517
518 (define_insn "cmpqi"
519   [(set (cc0)
520         (compare:QI (match_operand:QI 0 "register_operand" "ra")
521                     (match_operand:QI 1 "nonmemory_operand" "rai")))]
522   ""
523   "cmp.b        %X1,%X0"
524   [(set_attr "type" "arith")
525    (set_attr "length" "2")
526    (set_attr "cc" "compare")])
527
528 (define_expand "cmphi"
529   [(set (cc0)
530         (compare:HI (match_operand:HI 0 "register_operand" "")
531                     (match_operand:HI 1 "nonmemory_operand" "")))]
532   ""
533   "
534 {
535   /* Force operand1 into a register if we're compiling
536      for the h8/300.  */
537   if (GET_CODE (operands[1]) != REG && !TARGET_H8300H)
538     operands[1] = force_reg (HImode, operands[1]);
539 }")
540
541 (define_insn ""
542   [(set (cc0)
543         (compare:HI (match_operand:HI 0 "register_operand" "ra")
544                     (match_operand:HI 1 "register_operand" "ra")))]
545   "!TARGET_H8300H"
546   "cmp.w        %T1,%T0"
547   [(set_attr "type" "arith")
548    (set_attr "length" "2")
549    (set_attr "cc" "compare")])
550
551 (define_insn ""
552   [(set (cc0)
553         (compare:HI (match_operand:HI 0 "register_operand" "ra")
554                     (match_operand:HI 1 "nonmemory_operand" "rai")))]
555   "TARGET_H8300H"
556   "cmp.w        %T1,%T0"
557   [(set_attr "type" "arith")
558    (set_attr "length" "2")
559    (set_attr "cc" "compare")])
560
561 (define_insn "cmpsi"
562   [(set (cc0)
563         (compare:SI (match_operand:SI 0 "register_operand" "ra")
564                     (match_operand:SI 1 "nonmemory_operand" "rai")))]
565   "TARGET_H8300H"
566   "cmp.l        %S1,%S0"
567   [(set_attr "type" "arith")
568    (set_attr "length" "2")
569    (set_attr "cc" "compare")])
570 \f
571 ;; ----------------------------------------------------------------------
572 ;; ADD INSTRUCTIONS
573 ;; ----------------------------------------------------------------------
574
575 (define_insn "addqi3"
576   [(set (match_operand:QI 0 "register_operand" "=r")
577         (plus:QI (match_operand:QI 1 "register_operand" "%0")
578                  (match_operand:QI 2 "nonmemory_operand" "ri")))]
579   ""
580   "add.b        %X2,%X0"
581   [(set_attr "type" "arith")
582    (set_attr "length" "2")
583    (set_attr "cc" "set_zn_c0")])
584
585 ;; h8300h: adds operates on the 32bit register.  We can use it because we don't
586 ;; use the e0-7 registers.
587
588 (define_expand "addhi3"
589   [(set (match_operand:HI 0 "register_operand" "")
590         (plus:HI (match_operand:HI 1 "register_operand" "")
591                  (match_operand:HI 2 "nonmemory_operand" "")))]
592   ""
593   "")
594
595 ;; Specialized version using adds/subs.  This must come before
596 ;; the more general patterns below.
597 (define_insn ""
598   [(set (match_operand:HI 0 "register_operand" "=ra")
599         (plus:HI (match_operand:HI 1 "register_operand" "%0")
600                  (match_operand:HI 2 "adds_subs_operand" "i")))]
601   ""
602   "* return output_adds_subs (operands);"
603   [(set_attr "type" "arith")
604    (set_attr "length" "4")
605    (set_attr "cc" "none_0hit")])
606
607 (define_insn ""
608   [(set (match_operand:HI 0 "register_operand" "=&ra,ra")
609         (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
610                  (match_operand:HI 2 "nonmemory_operand" "n,ra")))]
611   "TARGET_H8300"
612   "@
613    add.b        %s2,%s0\;addx   %t2,%t0 
614    add.w        %T2,%T0"
615   [(set_attr "type" "multi,arith")
616    (set_attr "length" "4,2")
617    (set_attr "cc" "clobber,set_zn_c0")])
618
619 (define_insn ""
620   [(set (match_operand:HI 0 "register_operand" "=ra,ra")
621         (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
622                  (match_operand:HI 2 "nonmemory_operand" "i,ra")))]
623   "TARGET_H8300H"
624   "@
625    add.w        %T2,%T0
626    add.w        %T2,%T0"
627   [(set_attr "type" "arith,arith")
628    (set_attr "length" "4,2")
629    (set_attr "cc" "set_zn_c0,set_zn_c0")])
630
631 (define_expand "addsi3"
632   [(set (match_operand:SI 0 "register_operand" "")
633         (plus:SI (match_operand:SI 1 "register_operand" "")
634                  (match_operand:SI 2 "nonmemory_operand" "")))]
635   ""
636   "")
637
638 ;; Specialized version using adds/subs.  This must come before
639 ;; the more general patterns below.
640 (define_insn ""
641   [(set (match_operand:SI 0 "register_operand" "=ra")
642         (plus:SI (match_operand:SI 1 "register_operand" "%0")
643                  (match_operand:SI 2 "adds_subs_operand" "i")))]
644   "TARGET_H8300H"
645   "* return output_adds_subs (operands);"
646   [(set_attr "type" "arith")
647    (set_attr "length" "4")
648    (set_attr "cc" "none_0hit")])
649
650 (define_insn "addsi_h8300"
651   [(set (match_operand:SI 0 "register_operand" "=ra,ra,&ra")
652         (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r")
653                  (match_operand:SI 2 "nonmemory_operand" "n,r,r")))]
654   "TARGET_H8300"
655   "@
656    add  %w2,%w0\;addx   %x2,%x0\;addx   %y2,%y0\;addx   %z2,%z0
657    add.w        %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0
658    mov  %f1,%f0\;mov    %e1,%e0\;add.w  %f2,%f0\;addx   %y2,%y0\;addx   %z2,%z0"
659   [(set_attr "type" "arith")
660    (set_attr "length" "8,6,20")
661    (set_attr "cc" "clobber")])
662
663 (define_insn "addsi_h8300h"
664   [(set (match_operand:SI 0 "register_operand" "=ra,ra")
665         (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
666                  (match_operand:SI 2 "nonmemory_operand" "i,ra")))]
667   "TARGET_H8300H"
668   "@
669    add.l        %S2,%S0
670    add.l        %S2,%S0"
671   [(set_attr "type" "arith,arith")
672    (set_attr "length" "6,2")
673    (set_attr "cc" "set_zn_c0,set_zn_c0")])
674
675 ;; ----------------------------------------------------------------------
676 ;; SUBTRACT INSTRUCTIONS
677 ;; ----------------------------------------------------------------------
678
679 (define_insn "subqi3"
680   [(set (match_operand:QI 0 "register_operand" "=r,r")
681         (minus:QI (match_operand:QI 1 "register_operand" "0,0")
682                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
683   ""
684   "@
685    sub.b        %X2,%X0
686    add.b        %G2,%X0"
687   [(set_attr "type" "arith")
688    (set_attr "length" "2")
689    (set_attr "cc" "set_zn_c0")])
690
691 ;; h8300h: subs operates on the 32bit register.  We can use it because we don't
692 ;; use the e0-7 registers.
693
694 (define_expand "subhi3"
695   [(set (match_operand:HI 0 "register_operand" "")
696         (minus:HI (match_operand:HI 1 "general_operand" "")
697                   (match_operand:HI 2 "nonmemory_operand" "")))]
698   ""
699   "")
700
701 ;; Specialized version using adds/subs.  This must come before
702 ;; the more general patterns below.  This may not be needed
703 ;; due to instruction canonicalization.
704 (define_insn ""
705   [(set (match_operand:HI 0 "register_operand" "=ra")
706         (minus:HI (match_operand:HI 1 "register_operand" "r")
707                   (match_operand:HI 2 "adds_subs_operand" "i")))]
708   ""
709   "*
710 {
711   operands[2] = GEN_INT (-INTVAL (operands[2]));
712   return output_adds_subs (operands);
713 }"
714   [(set_attr "type" "arith")
715    (set_attr "length" "4")
716    (set_attr "cc" "none_0hit")])
717
718 (define_insn ""
719   [(set (match_operand:HI 0 "register_operand" "=ra,&ra")
720         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
721                   (match_operand:HI 2 "nonmemory_operand" "ra,n")))]
722   "TARGET_H8300"
723   "@
724    sub.w        %T2,%T0
725    add.b        %E2,%s0\;addx   %F2,%t0 ; -%0"
726   [(set_attr "type" "arith,multi")
727    (set_attr "length" "2,4")
728    (set_attr "cc" "set_zn_c0,clobber")])
729
730 (define_insn ""
731   [(set (match_operand:HI 0 "register_operand" "=ra,&ra")
732         (minus:HI (match_operand:HI 1 "general_operand" "0,0")
733                   (match_operand:HI 2 "nonmemory_operand" "ra,i")))]
734   "TARGET_H8300H"
735   "@
736    sub.w        %T2,%T0
737    sub.w        %T2,%T0"
738   [(set_attr "type" "arith")
739    (set_attr "length" "2,4")
740    (set_attr "cc" "set_zn_c0,set_zn_c0")])
741
742 (define_expand "subsi3"
743   [(set (match_operand:SI 0 "register_operand" "")
744         (minus:SI (match_operand:SI 1 "register_operand" "")
745                   (match_operand:SI 2 "nonmemory_operand" "")))]
746   ""
747   "")
748
749 (define_insn "subsi3_h8300"
750   [(set (match_operand:SI 0 "register_operand" "=r")
751         (minus:SI (match_operand:SI 1 "register_operand" "0")
752                   (match_operand:SI 2 "register_operand" "r")))]
753   "TARGET_H8300"
754   "sub.w        %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
755   [(set_attr "type" "arith")
756    (set_attr "length" "6")
757    (set_attr "cc" "clobber")])
758
759 ;; Specialized version using adds/subs.  This must come before
760 ;; the more general patterns below.  This may not be needed
761 ;; due to instruction canonicalization.
762 (define_insn ""
763   [(set (match_operand:SI 0 "register_operand" "=ra")
764         (minus:SI (match_operand:SI 1 "general_operand" "0")
765                   (match_operand:SI 2 "adds_subs_operand" "i")))]
766   "TARGET_H8300H"
767   "*
768 {
769   operands[2] = GEN_INT (-INTVAL (operands[2]));
770   return output_adds_subs (operands);
771 }"
772   [(set_attr "type" "arith")
773    (set_attr "length" "4")
774    (set_attr "cc" "none_0hit")])
775
776 (define_insn "subsi3_h8300h"
777   [(set (match_operand:SI 0 "register_operand" "=ra,ra")
778         (minus:SI (match_operand:SI 1 "general_operand" "0,0")
779                   (match_operand:SI 2 "nonmemory_operand" "ra,i")))]
780   "TARGET_H8300H"
781   "@
782    sub.l        %S2,%S0
783    sub.l        %S2,%S0"
784   [(set_attr "type" "arith")
785    (set_attr "length" "2,6")
786    (set_attr "cc" "set_zn_c0,set_zn_c0")])
787 \f
788 ;; ----------------------------------------------------------------------
789 ;; MULTIPLY INSTRUCTIONS
790 ;; ----------------------------------------------------------------------
791
792 ;; Note that the h8/300 can only handle umulqihi3.
793
794 (define_insn "mulqihi3"
795   [(set (match_operand:HI 0 "register_operand" "=r")
796         (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%0"))
797                  (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
798   "TARGET_H8300H"
799   "mulxs.b      %X2,%T0"
800   [(set_attr "type" "multi")
801    (set_attr "length" "4")
802    (set_attr "cc" "set_zn_c0")])
803
804 (define_insn "mulhisi3"
805   [(set (match_operand:SI 0 "register_operand" "=r")
806         (mult:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "%0"))
807                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
808   "TARGET_H8300H"
809   "mulxs.w      %T2,%S0"
810   [(set_attr "type" "multi")
811    (set_attr "length" "4")
812    (set_attr "cc" "set_zn_c0")])
813
814 (define_insn "umulqihi3"
815   [(set (match_operand:HI 0 "register_operand" "=r")
816         (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%0"))
817                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
818   ""
819   "mulxu        %X2,%T0"
820   [(set_attr "type" "multi")
821    (set_attr "length" "2")
822    (set_attr "cc" "none_0hit")])
823
824 (define_insn "umulhisi3"
825   [(set (match_operand:SI 0 "register_operand" "=r")
826         (mult:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "%0"))
827                  (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
828   "TARGET_H8300H"
829   "mulxu.w      %T2,%S0"
830   [(set_attr "type" "multi")
831    (set_attr "length" "2")
832    (set_attr "cc" "none_0hit")])
833
834 ;; ----------------------------------------------------------------------
835 ;; DIVIDE INSTRUCTIONS
836 ;; ----------------------------------------------------------------------
837
838 (define_insn "udivqi3"
839   [(set (match_operand:QI 0 "register_operand" "=r")
840         (udiv:QI (match_operand:HI 1 "general_operand" "0")
841                  (match_operand:QI 2 "register_operand" "r")))]
842   ""
843   "divxu        %X2,%T0"
844   [(set_attr "type" "multi")
845    (set_attr "length" "2")
846    (set_attr "cc" "clobber")])
847
848 ;; ??? Will divxu always work here?
849
850 (define_insn "divqi3"
851   [(set (match_operand:QI 0 "register_operand" "=r")
852         (div:QI (match_operand:HI 1 "general_operand" "0")
853                 (match_operand:QI 2 "register_operand" "r")))]
854   ""
855   "divxu        %X2,%T0"
856   [(set_attr "type" "multi")
857    (set_attr "length" "2")
858    (set_attr "cc" "clobber")])
859
860 (define_insn "udivhi3"
861   [(set (match_operand:HI 0 "register_operand" "=r")
862         (udiv:HI (match_operand:SI 1 "general_operand" "0")
863                  (match_operand:HI 2 "register_operand" "r")))]
864   "TARGET_H8300H"
865   "divxu.w      %T2,%S0"
866   [(set_attr "type" "multi")
867    (set_attr "length" "2")
868    (set_attr "cc" "clobber")])
869
870 (define_insn "divhi3"
871   [(set (match_operand:HI 0 "register_operand" "=r")
872         (div:HI (match_operand:SI 1 "general_operand" "0")
873                 (match_operand:HI 2 "register_operand" "r")))]
874   "TARGET_H8300H"
875   "divxs.w      %T2,%S0"
876   [(set_attr "type" "multi")
877    (set_attr "length" "4")
878    (set_attr "cc" "clobber")])
879
880 ;; ----------------------------------------------------------------------
881 ;; MOD INSTRUCTIONS
882 ;; ----------------------------------------------------------------------
883
884 (define_insn "umodqi3"
885   [(set (match_operand:QI 0 "register_operand" "=r")
886         (umod:QI (match_operand:HI 1 "general_operand" "0")
887                  (match_operand:QI 2 "register_operand" "r")))]
888   ""
889   "divxu        %X2,%T0\;mov %t0,%s0"
890   [(set_attr "type" "multi")
891    (set_attr "length" "4")
892    (set_attr "cc" "clobber")])
893
894 (define_insn "modqi3"
895   [(set (match_operand:QI 0 "register_operand" "=r")
896         (mod:QI (match_operand:HI 1 "general_operand" "0")
897                 (match_operand:QI 2 "register_operand" "r")))]
898   "TARGET_H8300H"
899   "divxs.b      %X2,%T0\;mov %t0,%s0"
900   [(set_attr "type" "multi")
901    (set_attr "length" "6")
902    (set_attr "cc" "clobber")])
903
904 (define_insn "umodhi3"
905   [(set (match_operand:HI 0 "register_operand" "=r")
906         (umod:HI (match_operand:SI 1 "general_operand" "0")
907                  (match_operand:HI 2 "register_operand" "r")))]
908   "TARGET_H8300H"
909   "divxu.w      %T2,%S0\;mov %e0,%f0"
910   [(set_attr "type" "multi")
911    (set_attr "length" "4")
912    (set_attr "cc" "clobber")])
913
914 (define_insn "modhi3"
915   [(set (match_operand:HI 0 "register_operand" "=r")
916         (mod:HI (match_operand:SI 1 "general_operand" "0")
917                 (match_operand:HI 2 "register_operand" "r")))]
918   "TARGET_H8300H"
919   "divxs.w      %T2,%S0\;mov %e0,%f0"
920   [(set_attr "type" "multi")
921    (set_attr "length" "6")
922    (set_attr "cc" "clobber")])
923 \f
924 ;; ----------------------------------------------------------------------
925 ;; AND INSTRUCTIONS
926 ;; ----------------------------------------------------------------------
927
928 (define_insn "andqi3_internal"
929   [(set (match_operand:QI 0 "bit_operand" "=r,U")
930         (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
931                 (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
932   "register_operand (operands[0], QImode) || o_operand (operands[2], QImode)"
933   "@
934    and  %X2,%X0
935    bclr %W2,%R0"
936   [(set_attr "type" "arith")
937    (set_attr "length" "2,4")
938    (set_attr "cc" "set,none_0hit")])
939
940 (define_expand "andqi3"
941   [(set (match_operand:QI 0 "bit_operand" "=r,U")
942         (and:QI (match_operand:QI 1 "bit_operand" "%0,0")
943                 (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
944   ""
945   "
946 {
947   if (fix_bit_operand (operands, 'O', AND))
948     DONE;
949 }")
950
951 (define_insn "andhi3"
952   [(set (match_operand:HI 0 "register_operand" "=r,r")
953         (and:HI (match_operand:HI 1 "register_operand" "%0,0")
954                 (match_operand:HI 2 "nonmemory_operand" "J,rn")))]
955   ""
956   "*
957 {
958   if (GET_CODE (operands[2]) == CONST_INT)
959     {
960       int i = INTVAL (operands[2]);
961
962       if ((i & 0x00ff) != 0x00ff) 
963         output_asm_insn (\"and  %s2,%s0\", operands);
964       if ((i & 0xff00) != 0xff00) 
965         output_asm_insn (\"and  %t2,%t0\", operands);
966       return \"\";
967     }
968   if (TARGET_H8300H)
969     return \"and.w %T2,%T0\";
970   return \"and  %s2,%s0\;and    %t2,%t0;\";
971 }"
972   [(set_attr "type" "arith,multi")
973    (set_attr "length" "2,4")
974    (set_attr "cc" "clobber,clobber")])
975
976 (define_insn "andsi3"
977   [(set (match_operand:SI 0 "register_operand" "=r,r")
978         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
979                 (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
980   ""
981   "*
982 {
983   if (GET_CODE (operands[2]) == CONST_INT)
984     {
985       int i = INTVAL (operands[2]);
986
987       /* ??? If we used e0..e7, then we could sub.w eX,eX to
988          clear the high word if (i & 0xffff0000) == 0.  */
989
990       /* The h8300h can't do byte-wise operations on the
991          upper 16bits of 32bit registers.  However, if
992          those bits aren't going to change, then we can
993          work on the low-order bits.  */
994       if (TARGET_H8300H
995           && (i & 0xffff0000) != 0xffff0000)
996         return \"and.l  %S2,%S0\";
997
998       if ((i & 0x000000ff) != 0x000000ff) 
999         output_asm_insn (\"and  %w2,%w0\", operands);
1000       if ((i & 0x0000ff00) != 0x0000ff00) 
1001         output_asm_insn (\"and  %x2,%x0\", operands);
1002       if ((i & 0x00ff0000) != 0x00ff0000) 
1003         output_asm_insn (\"and  %y2,%y0\", operands);
1004       if ((i & 0xff000000) != 0xff000000) 
1005         output_asm_insn (\"and  %z2,%z0\", operands);
1006       return \"\";
1007     }
1008   if (TARGET_H8300H)
1009     return \"and.l      %S2,%S0\";
1010   return \"and  %w2,%w0\;and    %x2,%x0\;and    %y2,%y0\;and    %z2,%z0\;\";
1011 }"
1012   [(set_attr "type" "arith,multi")
1013    (set_attr "length" "2,8")
1014    (set_attr "cc" "clobber,clobber")])
1015
1016 ;; ----------------------------------------------------------------------
1017 ;; OR INSTRUCTIONS
1018 ;; ----------------------------------------------------------------------
1019
1020 (define_insn "iorqi3_internal"
1021   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1022         (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1023                 (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
1024   "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
1025   "@
1026    or   %X2,%X0
1027    bset %V2,%R0"
1028   [(set_attr "type" "arith")
1029    (set_attr "length" "2,4")
1030    (set_attr "cc" "set,none_0hit")])
1031
1032 (define_expand "iorqi3"
1033   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1034         (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
1035                 (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
1036   ""
1037   "
1038 {
1039   if (fix_bit_operand (operands, 'P', IOR))
1040     DONE;
1041 }")
1042
1043 (define_insn "iorhi3"
1044   [(set (match_operand:HI 0 "general_operand" "=r,r")
1045         (ior:HI (match_operand:HI 1 "general_operand" "%0,0")
1046                 (match_operand:HI 2 "general_operand" "J,rn")))]
1047   ""
1048   "*
1049 {
1050   if (GET_CODE (operands[2]) == CONST_INT)
1051     {
1052       int i = INTVAL (operands[2]);
1053
1054       if ((i & 0x00ff) != 0) 
1055         output_asm_insn (\"or   %s2,%s0\", operands);
1056       if ((i & 0xff00) != 0) 
1057         output_asm_insn (\"or   %t2,%t0\", operands);
1058       return \"\";
1059     }
1060   if (TARGET_H8300H)
1061     return \"or.w       %T2,%T0\";
1062   return \"or   %s2,%s0\;or     %t2,%t0; %2 or2\";
1063 }"
1064   [(set_attr "type" "arith,multi")
1065    (set_attr "length" "2,4")
1066    (set_attr "cc" "clobber,clobber")])
1067
1068 (define_insn "iorsi3"
1069   [(set (match_operand:SI 0 "register_operand" "=r,r")
1070         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1071                 (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
1072   ""
1073   "*
1074 {
1075   if (GET_CODE (operands[2]) == CONST_INT)
1076     {
1077       int i = INTVAL (operands[2]);
1078
1079       /* The h8300h can't do byte-wise operations on the
1080          upper 16bits of 32bit registers.  However, if
1081          those bits aren't going to change, then we can
1082          work on the low-order bits.  */
1083       if (TARGET_H8300H
1084           && (i & 0xffff0000) != 0x00000000)
1085         return \"or.l   %S2,%S0\";
1086         
1087       if ((i & 0x000000ff) != 0) 
1088         output_asm_insn (\"or   %w2,%w0\", operands);
1089       if ((i & 0x0000ff00) != 0) 
1090         output_asm_insn (\"or   %x2,%x0\", operands);
1091       if ((i & 0x00ff0000) != 0) 
1092         output_asm_insn (\"or   %y2,%y0\", operands);
1093       if ((i & 0xff000000) != 0) 
1094         output_asm_insn (\"or   %z2,%z0\", operands);
1095       return \"\";
1096     }
1097   if (TARGET_H8300H)
1098     return \"or.l       %S2,%S0\";
1099   return \"or   %w2,%w0\;or     %x2,%x0\;or     %y2,%y0\;or     %z2,%z0\;\";
1100 }"
1101   [(set_attr "type" "arith,multi")
1102    (set_attr "length" "2,8")
1103    (set_attr "cc" "clobber,clobber")])
1104
1105 ;; ----------------------------------------------------------------------
1106 ;; XOR INSTRUCTIONS
1107 ;; ----------------------------------------------------------------------
1108
1109 (define_insn "xorqi3_internal"
1110   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1111         (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1112                 (match_operand:QI 2 "nonmemory_operand" "rn,P")))]
1113   "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)"
1114   "@
1115    xor  %X2,%X0
1116    bnot %V2,%R0"
1117   [(set_attr "type" "arith")
1118    (set_attr "length" "2,4")
1119    (set_attr "cc" "set,none_0hit")])
1120
1121 (define_expand "xorqi3"
1122   [(set (match_operand:QI 0 "bit_operand" "=r,U")
1123         (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
1124                 (match_operand:QI 2 "nonmemory_operand" "rn,O")))]
1125   ""
1126   "
1127 {
1128   if (fix_bit_operand (operands, 'O', XOR))
1129     DONE;
1130 }")
1131
1132 (define_insn "xorhi3"
1133   [(set (match_operand:HI 0 "register_operand" "=r,r")
1134         (xor:HI (match_operand:HI 1 "general_operand" "%0,0")
1135                 (match_operand:HI 2 "nonmemory_operand" "J,rn")))]
1136   ""
1137   "*
1138 {
1139   if (GET_CODE (operands[2]) == CONST_INT)
1140     {
1141       int i = INTVAL (operands[2]);
1142
1143       if ((i & 0x00ff) != 0) 
1144         output_asm_insn (\"xor  %s2,%s0\", operands);
1145       if ((i & 0xff00) != 0) 
1146         output_asm_insn (\"xor  %t2,%t0\", operands);
1147       return \"\";
1148     }
1149   if (TARGET_H8300H)
1150     return \"xor.w      %T2,%T0\";
1151   return \"xor  %s2,%s0\;xor    %t2,%t0\";
1152 }"
1153   [(set_attr "type" "arith,multi")
1154    (set_attr "length" "2,4")
1155    (set_attr "cc" "clobber,clobber")])
1156
1157 (define_insn "xorsi3"
1158   [(set (match_operand:SI 0 "register_operand" "=r,r")
1159         (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
1160                 (match_operand:SI 2 "nonmemory_operand" "J,rn")))]
1161   ""
1162   "*
1163 {
1164   if (GET_CODE (operands[2]) == CONST_INT)
1165     {
1166       int i = INTVAL (operands[2]);
1167
1168       /* The h8300h can't do byte-wise operations on the
1169          upper 16bits of 32bit registers.  However, if
1170          those bits aren't going to change, then we can
1171          work on the low-order bits.  */
1172       if (TARGET_H8300H
1173           && (i & 0xffff0000) != 0x00000000)
1174         return \"xor.l  %S2,%S0\";
1175
1176       if ((i & 0x000000ff) != 0) 
1177         output_asm_insn (\"xor  %w2,%w0\", operands);
1178       if ((i & 0x0000ff00) != 0) 
1179         output_asm_insn (\"xor  %x2,%x0\", operands);
1180       if ((i & 0x00ff0000) != 0) 
1181         output_asm_insn (\"xor  %y2,%y0\", operands);
1182       if ((i & 0xff000000) != 0) 
1183         output_asm_insn (\"xor  %z2,%z0\", operands);
1184       return \"\";
1185     }
1186   if (TARGET_H8300H)
1187     return \"xor.l      %S2,%S0\";
1188   return \"xor  %w2,%w0\;xor    %x2,%x0\;xor    %y2,%y0\;xor    %z2,%z0\;\";
1189 }"
1190   [(set_attr "type" "arith,multi")
1191    (set_attr "length" "2,8")
1192    (set_attr "cc" "clobber,clobber")])
1193 \f
1194 ;; ----------------------------------------------------------------------
1195 ;; NEGATION INSTRUCTIONS
1196 ;; ----------------------------------------------------------------------
1197
1198 (define_insn "negqi2"
1199   [(set (match_operand:QI 0 "register_operand" "=r")
1200         (neg:QI (match_operand:QI 1 "general_operand" "0")))]
1201   ""
1202   "neg  %X0"
1203   [(set_attr "type" "arith")
1204    (set_attr "length" "2")
1205    (set_attr "cc" "set_zn_c0")])
1206
1207 (define_expand "neghi2"
1208   [(set (match_operand:HI 0 "register_operand" "=r")
1209         (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1210   ""
1211   "
1212 {
1213   if (TARGET_H8300)
1214     {
1215       emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
1216       DONE;
1217     }
1218 }")
1219
1220 (define_expand "neghi2_h8300"
1221   [(set (match_dup 2)
1222         (not:HI (match_operand:HI 1 "register_operand" "r")))
1223    (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
1224    (set (match_operand:HI 0 "register_operand" "=r")
1225         (match_dup 2))]
1226   ""
1227   "{ operands[2] = gen_reg_rtx (HImode); }")
1228
1229 (define_insn "neghi2_h8300h"
1230   [(set (match_operand:HI 0 "register_operand" "=r")
1231         (neg:HI (match_operand:HI 1 "general_operand" "0")))]
1232   "TARGET_H8300H"
1233   "neg  %T0"
1234   [(set_attr "type" "arith")
1235    (set_attr "length" "2")
1236    (set_attr "cc" "set_zn_c0")])
1237
1238 (define_expand "negsi2"
1239   [(set (match_operand:SI 0 "register_operand" "=r")
1240         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1241   ""
1242   "
1243 {
1244   if (TARGET_H8300)
1245     {
1246       emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
1247       DONE;
1248     }
1249 }")
1250
1251 (define_expand "negsi2_h8300"
1252   [(set (match_dup 2)
1253         (not:SI (match_operand:SI 1 "register_operand" "r")))
1254    (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
1255    (set (match_operand:SI 0 "register_operand" "=r")
1256         (match_dup 2))]
1257   ""
1258   "{ operands[2] = gen_reg_rtx(SImode); }")
1259
1260 (define_insn "negsi2_h8300h"
1261   [(set (match_operand:SI 0 "register_operand" "=r")
1262         (neg:SI (match_operand:SI 1 "general_operand" "0")))]
1263   "TARGET_H8300H"
1264   "neg  %S0"
1265   [(set_attr "type" "arith")
1266    (set_attr "length" "2")
1267    (set_attr "cc" "set_zn_c0")])
1268
1269 ;; ----------------------------------------------------------------------
1270 ;; NOT INSTRUCTIONS
1271 ;; ----------------------------------------------------------------------
1272
1273 (define_insn "one_cmplqi2"
1274   [(set (match_operand:QI 0 "register_operand" "=r")
1275         (not:QI (match_operand:QI 1 "general_operand" "0")))]
1276   ""
1277   "not  %X0"
1278   [(set_attr "type" "arith")
1279    (set_attr "length" "2")
1280    (set_attr "cc" "set")])
1281
1282 (define_insn "one_cmplhi2"
1283   [(set (match_operand:HI 0 "register_operand" "=r")
1284         (not:HI (match_operand:HI 1 "general_operand" "0")))]
1285   ""
1286   "*
1287 {
1288   if (TARGET_H8300)
1289     return \"not        %s0\;not        %t0\";
1290   else
1291     return \"not        %T0\";
1292 }"
1293   [(set_attr "type" "arith")
1294    (set_attr "cc" "clobber")
1295    (set (attr "length")
1296         (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
1297                       (const_int 8)
1298                       (const_int 2)))])
1299
1300 (define_insn "one_cmplsi2"
1301   [(set (match_operand:SI 0 "register_operand" "=r")
1302         (not:SI (match_operand:SI 1 "general_operand" "0")))]
1303   ""
1304   "*
1305 {
1306   if (TARGET_H8300)
1307     return \"not        %w0\;not        %x0\;not        %y0\;not        %z0\";
1308   else
1309     return \"not        %S0\";
1310 }"
1311   [(set_attr "type" "arith")
1312    (set_attr "cc" "clobber")
1313    (set (attr "length")
1314         (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
1315                       (const_int 8)
1316                       (const_int 2)))])
1317                         
1318 \f
1319 ;; ----------------------------------------------------------------------
1320 ;; JUMP INSTRUCTIONS
1321 ;; ----------------------------------------------------------------------
1322
1323 ;; Conditional jump instructions
1324
1325 (define_expand "ble"
1326   [(set (pc)
1327         (if_then_else (le (cc0)
1328                           (const_int 0))
1329                       (label_ref (match_operand 0 "" ""))
1330                       (pc)))]
1331   ""
1332   "")
1333
1334 (define_expand "bleu"
1335   [(set (pc)
1336         (if_then_else (leu (cc0)
1337                            (const_int 0))
1338                       (label_ref (match_operand 0 "" ""))
1339                       (pc)))]
1340   ""
1341   "")
1342
1343 (define_expand "bge"
1344   [(set (pc)
1345         (if_then_else (ge (cc0)
1346                           (const_int 0))
1347                       (label_ref (match_operand 0 "" ""))
1348                       (pc)))]
1349   ""
1350   "")
1351
1352 (define_expand "bgeu"
1353   [(set (pc)
1354         (if_then_else (geu (cc0)
1355                            (const_int 0))
1356                       (label_ref (match_operand 0 "" ""))
1357                       (pc)))]
1358   ""
1359   "")
1360
1361 (define_expand "blt"
1362   [(set (pc)
1363         (if_then_else (lt (cc0)
1364                           (const_int 0))
1365                       (label_ref (match_operand 0 "" ""))
1366                       (pc)))]
1367   ""
1368   "")
1369
1370 (define_expand "bltu"
1371   [(set (pc)
1372         (if_then_else (ltu (cc0)
1373                            (const_int 0))
1374                       (label_ref (match_operand 0 "" ""))
1375                       (pc)))]
1376   ""
1377   "")
1378
1379 (define_expand "bgt"
1380   [(set (pc)
1381         (if_then_else (gt (cc0)
1382                           (const_int 0))
1383                       (label_ref (match_operand 0 "" ""))
1384                       (pc)))]
1385   ""
1386   "")
1387
1388 (define_expand "bgtu"
1389   [(set (pc)
1390         (if_then_else (gtu (cc0)
1391                            (const_int 0))
1392                       (label_ref (match_operand 0 "" ""))
1393                       (pc)))]
1394   ""
1395   "")
1396
1397 (define_expand "beq"
1398   [(set (pc)
1399         (if_then_else (eq (cc0)
1400                           (const_int 0))
1401                       (label_ref (match_operand 0 "" ""))
1402                       (pc)))]
1403   ""
1404   "")
1405
1406 (define_expand "bne"
1407   [(set (pc)
1408         (if_then_else (ne (cc0)
1409                           (const_int 0))
1410                       (label_ref (match_operand 0 "" ""))
1411                       (pc)))]
1412   ""
1413   "")
1414
1415 (define_insn "branch_true"
1416   [(set (pc)
1417         (if_then_else (match_operator 1 "comparison_operator"
1418                                       [(cc0) (const_int 0)])
1419                       (label_ref (match_operand 0 "" ""))
1420                       (pc)))]
1421   ""
1422   "*
1423 {
1424   /* If we erroneously deleted a compare insn (which can happen if we need
1425      CC bits set that aren't), emit the compare.  */
1426   if (restore_compare_p (operands[1]))
1427     return 0;
1428
1429   if (get_attr_length (insn) == 2) 
1430     return \"b%j1       %l0\";
1431   else if (get_attr_length (insn) == 4) 
1432     return \"b%j1       %l0:16\";
1433   else
1434     return \"b%k1       %L0\;jmp        @%l0\;%L0:\";
1435 }" 
1436  [(set_attr "type" "branch")
1437    (set_attr "cc" "none")])
1438
1439 (define_insn "branch_false"
1440   [(set (pc)
1441         (if_then_else (match_operator 1 "comparison_operator"
1442                                       [(cc0) (const_int 0)])
1443                       (pc)
1444                       (label_ref (match_operand 0 "" ""))))]
1445   ""
1446   "*
1447 {
1448   /* If we erroneously deleted a compare insn (which can happen if we need
1449      CC bits set that aren't), emit the compare.  */
1450   if (restore_compare_p (operands[1]))
1451     return 0;
1452
1453   if (get_attr_length (insn) == 2) 
1454     return \"b%k1       %l0\";
1455   else if (get_attr_length (insn) == 4) 
1456     return \"b%k1       %l0:16\";
1457   else
1458     return \"b%j1       %L0\;jmp        @%l0\;%L0:\";
1459 }"
1460   [(set_attr "type" "branch")
1461    (set_attr "cc" "none")])
1462
1463 ;; Unconditional and other jump instructions.
1464
1465 (define_insn "jump"
1466   [(set (pc)
1467         (label_ref (match_operand 0 "" "")))]
1468   ""
1469   "*
1470 {
1471   if (get_attr_length (insn) == 2)
1472     return \"bra        %l0\";
1473   else if (get_attr_length (insn) == 4)
1474     return \"bra        %l0:16\";
1475   else
1476     return \"jmp        @%l0\";
1477 }"
1478   [(set_attr "type" "branch")
1479    (set_attr "cc" "none")])
1480
1481 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1482
1483 (define_expand "tablejump"
1484   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
1485               (use (label_ref (match_operand 1 "" "")))])]
1486   ""
1487   "")
1488
1489 (define_insn "tablejump_h8300"
1490   [(set (pc) (match_operand:HI 0 "register_operand" "r"))
1491    (use (label_ref (match_operand 1 "" "")))]
1492   "TARGET_H8300"
1493   "jmp  @%0"
1494   [(set_attr "type" "branch")
1495    (set_attr "cc" "none")
1496    (set_attr "length" "2")])
1497
1498 (define_insn "tablejump_h8300h"
1499   [(set (pc) (match_operand:SI 0 "register_operand" "r"))
1500    (use (label_ref (match_operand 1 "" "")))]
1501   "TARGET_H8300H"
1502   "jmp  @%0"
1503   [(set_attr "type" "branch")
1504    (set_attr "cc" "none")
1505    (set_attr "length" "2")])
1506
1507 ;; This is a define expand, because pointers may be either 16 or 32 bits.
1508
1509 (define_expand "indirect_jump"
1510   [(set (pc) (match_operand 0 "jump_address_operand" "Vr"))]
1511   ""
1512   "")
1513
1514 (define_insn "indirect_jump_h8300"
1515   [(set (pc) (match_operand:HI 0 "jump_address_operand" "V,r"))]
1516   "TARGET_H8300"
1517   "@
1518    jmp  @%0
1519    jmp  @%0"
1520   [(set_attr "type" "branch")
1521    (set_attr "cc" "none")
1522    (set_attr "length" "2")])
1523
1524 (define_insn "indirect_jump_h8300h"
1525   [(set (pc) (match_operand:SI 0 "jump_address_operand" "V,r"))]
1526   "TARGET_H8300H"
1527   "@
1528    jmp @%0
1529    jmp @%0"
1530   [(set_attr "type" "branch")
1531    (set_attr "cc" "none")
1532    (set_attr "length" "2")])
1533
1534 ;; Call subroutine with no return value.
1535
1536 ;; ??? Even though we use HImode here, this works for the 300h.
1537
1538 (define_insn "call"
1539   [(call (match_operand:QI 0 "call_insn_operand" "or")
1540          (match_operand:HI 1 "general_operand" "g"))]
1541   ""
1542   "*
1543 {
1544   if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
1545       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
1546     return \"jsr\\t\@%0:8\";
1547   else
1548     return \"jsr\\t%0\";
1549 }"
1550   [(set_attr "type" "call")
1551    (set_attr "cc" "clobber")
1552    (set (attr "length")
1553      (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1554                    (const_int 4)
1555                    (const_int 8)))])
1556
1557 ;; Call subroutine, returning value in operand 0
1558 ;; (which must be a hard register).
1559
1560 ;; ??? Even though we use HImode here, this works on the 300h.
1561
1562 (define_insn "call_value"
1563   [(set (match_operand 0 "" "=r")
1564         (call (match_operand:QI 1 "call_insn_operand" "or")
1565               (match_operand:HI 2 "general_operand" "g")))]
1566   ""
1567   "*
1568 {
1569   if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
1570       && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
1571     return \"jsr\\t\@%1:8\";
1572   else
1573     return \"jsr\\t%1\";
1574 }"
1575   [(set_attr "type" "call")
1576    (set_attr "cc" "clobber")
1577    (set (attr "length")
1578      (if_then_else (match_operand:QI 0 "small_call_insn_operand" "")
1579                    (const_int 4)
1580                    (const_int 8)))])
1581
1582 (define_insn "nop"
1583   [(const_int 0)]
1584   ""
1585   "nop"
1586   [(set_attr "type" "multi")
1587    (set_attr "cc" "none")
1588    (set_attr "length" "2")])
1589 \f
1590 ;; ----------------------------------------------------------------------
1591 ;; EXTEND INSTRUCTIONS
1592 ;; ----------------------------------------------------------------------
1593
1594 (define_insn "zero_extendqihi2"
1595   [(set (match_operand:HI 0 "register_operand" "=r,r")
1596         (zero_extend:HI (match_operand:QI 1 "general_operand" "0,g")))]
1597   ""
1598   "*
1599 {
1600   if (which_alternative==0)
1601     return \"mov.b      #0,%t0\";
1602
1603   if (TARGET_H8300)
1604     return \"mov.b      %R1,%s0\;mov.b  #0,%t0\";
1605   else
1606     {
1607       /* ??? See how often this gets optimized.  */
1608       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
1609         return \"extu.w %T0\";
1610       else
1611         return \"mov.b  %R1,%s0\;extu.w %T0\";
1612     }
1613 }"
1614   [(set_attr "type" "multi")
1615 ;; ??? This length is wrong for one case.
1616    (set_attr "length" "4")
1617    (set_attr "cc" "clobber")])
1618
1619 (define_insn "zero_extendhisi2"
1620   [(set (match_operand:SI 0 "register_operand" "=r")
1621         (zero_extend:SI (match_operand:HI 1 "general_operand" "g")))]
1622   "TARGET_H8300H"
1623   "*
1624 {
1625   /* ??? See how often this gets optimized.  */
1626   if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
1627     return \"extu.l     %S0\";
1628   else
1629     return \"mov.w      %T1,%T0\;extu.l %S0\";
1630 }"
1631   [(set_attr "type" "multi")
1632 ;; ??? This length is wrong for one case.
1633    (set_attr "length" "4")
1634    (set_attr "cc" "clobber")])
1635
1636 (define_insn "extendqihi2"
1637   [(set (match_operand:HI 0 "register_operand" "=r")
1638         (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))]
1639   ""
1640   "*
1641 {
1642   if (TARGET_H8300)
1643     {
1644       /* ??? See how often this gets optimized.  */
1645       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
1646         return \"bld    #7,%s0\;subx    %t0,%t0\";
1647       else
1648         return \"mov.b  %R1,%s0\;bld    #7,%s0\;subx    %t0,%t0\";
1649     }
1650   else
1651     {
1652       /* ??? See how often this gets optimized.  */
1653       if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
1654         return \"exts.w %T0\";
1655       else
1656         return \"mov.b  %R1,%s0\;exts.w %T0\";
1657     }
1658 }"
1659   [(set_attr "type" "multi")
1660 ;; ??? Length is wrong in some cases.
1661    (set_attr "length" "6")
1662    (set_attr "cc" "clobber")])
1663
1664 (define_expand "extendhisi2"
1665   [(set (match_operand:SI 0 "register_operand" "")
1666         (sign_extend:SI (match_operand:HI 1 "general_operand" "")))]
1667   ""
1668   "
1669 {
1670   if (TARGET_H8300)
1671     emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1]));
1672   else
1673     emit_insn (gen_extendhisi2_h8300h (operands[0], operands[1]));
1674   DONE;
1675 }")
1676
1677 (define_expand "extendhisi2_h8300"
1678   [(set (reg:HI 1) (match_operand:HI 1 "general_operand" ""))
1679    (set (reg:SI 0) (sign_extend:SI (reg:HI 1)))
1680    (set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))]
1681   "TARGET_H8300"
1682   "")
1683
1684 (define_expand "extendhisi2_h8300h"
1685   [(set (match_operand:SI 0 "register_operand" "")
1686         (sign_extend:SI (match_operand:HI 1 "general_operand" "")))]
1687   "TARGET_H8300H"
1688   "")
1689
1690 (define_insn "extendhisi2_h8300_internal"
1691   [(set (match_operand:SI 0 "register_operand" "=r")
1692         (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))]
1693   "TARGET_H8300"
1694   "mov.w        %T1,%f0\;bld    #7,%x0\;subx    %y0,%y0\;subx   %z0,%z0"
1695   [(set_attr "length" "10")
1696    (set_attr "cc" "clobber")])
1697
1698 (define_insn "extendhisi2_h8300h_internal"
1699   [(set (match_operand:SI 0 "register_operand" "=r")
1700         (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))]
1701   "TARGET_H8300H"
1702   "*
1703 {
1704   /* ??? See how often this gets optimized.  */
1705   if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0])))
1706     return \"exts.l     %S0\";
1707   else
1708     return \"mov.w      %T1,%T0\;exts.l %S0\";
1709 }"
1710   [(set_attr "length" "10")
1711    (set_attr "cc" "clobber")])
1712 \f
1713 ;; ----------------------------------------------------------------------
1714 ;; SHIFTS
1715 ;; ----------------------------------------------------------------------
1716 ;;
1717 ;; We make some attempt to provide real efficient shifting.  One example is
1718 ;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
1719 ;; reg and moving 0 into the former reg.
1720 ;;
1721 ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
1722 ;; this in both rtl and at insn emit time.  Ideally, we'd use rtl as that would
1723 ;; give the optimizer more cracks at the code.  However, we wish to do things
1724 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
1725 ;; There is rtl to handle this (rotate + and), but the h8/300 doesn't handle
1726 ;; 16 bit rotates.  Also, if we emit complicated rtl, combine may not be able
1727 ;; to detect cases it can optimize.
1728 ;;
1729 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
1730 ;; easier "do it at insn emit time" route.
1731
1732 ;; QI BIT SHIFTS
1733
1734 (define_expand "ashlqi3"
1735   [(set (match_operand:QI 0 "register_operand" "")
1736         (ashift:QI (match_operand:QI 1 "register_operand" "")
1737                    (match_operand:QI 2 "nonmemory_operand" "")))]
1738   ""
1739   "if (expand_a_shift (QImode, ASHIFT, operands)) DONE;else FAIL;")
1740
1741 (define_expand "ashrqi3"
1742   [(set (match_operand:QI 0 "register_operand" "")
1743         (ashiftrt:QI (match_operand:QI 1 "register_operand" "")
1744                      (match_operand:QI 2 "nonmemory_operand" "")))]
1745   ""
1746   "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE;else FAIL;")
1747
1748 (define_expand "lshrqi3"
1749   [(set (match_operand:QI 0 "register_operand" "")
1750         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
1751                      (match_operand:QI 2 "nonmemory_operand" "")))]
1752   ""
1753   "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE;else FAIL;")
1754
1755 ;; WARNING: The constraints on the scratch register say one is not needed
1756 ;; for constant shifts of 1,2,3,4.  Emit_a_shift() must know this.
1757
1758 (define_insn "shiftbyn_QI"
1759   [(set (match_operand:QI 0 "register_operand" "=r,r")
1760         (match_operator:QI 3 "nshift_operator" 
1761                         [ (match_operand:QI 1 "register_operand" "0,0")
1762                           (match_operand:QI 2 "nonmemory_operand" "IKM,rn")]))
1763    (clobber (match_scratch:QI 4 "=X,&r"))]
1764   ""
1765   "* return emit_a_shift (insn, operands);"
1766   [(set_attr "type" "arith")
1767    (set_attr "length" "20")
1768 ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
1769 ;; However, for cases that loop or are done in pieces, cc does not contain
1770 ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1771    (set_attr "cc" "clobber")])
1772
1773 ;; HI BIT SHIFTS
1774
1775 (define_expand "ashlhi3"
1776   [(set (match_operand:HI 0 "register_operand" "")
1777         (ashift:HI (match_operand:HI 1 "nonmemory_operand" "")
1778                    (match_operand:QI 2 "nonmemory_operand" "")))]
1779   ""
1780   "if (expand_a_shift (HImode, ASHIFT, operands)) DONE;else FAIL;")
1781
1782 (define_expand "lshrhi3"
1783   [(set (match_operand:HI 0 "register_operand" "")
1784         (lshiftrt:HI (match_operand:HI 1 "general_operand_src" "")
1785                      (match_operand:QI 2 "nonmemory_operand" "")))]
1786   ""
1787   "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;")
1788
1789 (define_expand "ashrhi3"
1790   [(set (match_operand:HI 0 "register_operand" "")
1791         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1792                      (match_operand:QI 2 "nonmemory_operand" "")))]
1793   ""
1794   "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE;else FAIL;")
1795
1796 ;; WARNING: The constraints on the scratch register say one is not needed
1797 ;; for constant shifts of 1,2,3,4.  Emit_a_shift() must know this.
1798
1799 (define_insn "shiftbyn_HI"
1800   [(set (match_operand:HI 0 "register_operand" "=r,r")
1801         (match_operator:HI 3 "nshift_operator" 
1802                         [ (match_operand:HI 1 "register_operand" "0,0")
1803                           (match_operand:QI 2 "nonmemory_operand" "IKM,rn")]))
1804    (clobber (match_scratch:QI 4 "=X,&r"))]
1805   ""
1806   "* return emit_a_shift (insn, operands);"
1807   [(set_attr "type" "arith")
1808    (set_attr "length" "20")
1809 ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
1810 ;; However, for cases that loop or are done in pieces, cc does not contain
1811 ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1812    (set_attr "cc" "clobber")])
1813
1814 ;;  SI BIT SHIFTS
1815
1816 (define_expand "ashlsi3"
1817   [(set (match_operand:SI 0 "register_operand" "")
1818         (ashift:SI
1819          (match_operand:SI 1 "general_operand_src" "")
1820          (match_operand:QI 2 "nonmemory_operand" "")))]
1821   ""
1822   "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;")
1823
1824 (define_expand "lshrsi3"
1825   [(set (match_operand:SI 0 "register_operand" "")
1826         (lshiftrt:SI
1827          (match_operand:SI 1 "general_operand_src" "")
1828          (match_operand:QI 2 "nonmemory_operand" "")))]
1829   ""
1830   "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;")
1831
1832 (define_expand "ashrsi3"
1833   [(set (match_operand:SI 0 "register_operand" "")
1834         (ashiftrt:SI
1835          (match_operand:SI 1 "general_operand_src" "")
1836          (match_operand:QI 2 "nonmemory_operand" "")))]
1837   ""
1838   "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;")
1839
1840 ;; WARNING: The constraints on the scratch register say one is not needed
1841 ;; for constant shifts of 1,2.  Emit_a_shift() must know this.
1842
1843 (define_insn "shiftbyn_SI"
1844   [(set (match_operand:SI 0 "register_operand" "=r,r")
1845         (match_operator:SI 3 "nshift_operator" 
1846                         [ (match_operand:SI 1 "register_operand" "0,0")
1847                           (match_operand:QI 2 "nonmemory_operand" "IK,rn")]))
1848    (clobber (match_scratch:QI 4 "=X,&r"))]
1849   ""
1850   "* return emit_a_shift (insn, operands);"
1851   [(set_attr "type" "arith")
1852    (set_attr "length" "20")
1853 ;; ??? We'd like to indicate that cc is set here, and it is for simple shifts.
1854 ;; However, for cases that loop or are done in pieces, cc does not contain
1855 ;; what we want.  Emit_a_shift is free to tweak cc_status as desired.
1856    (set_attr "cc" "clobber")])
1857 \f
1858 ;; -----------------------------------------------------------------
1859 ;; BIT FIELDS
1860 ;; -----------------------------------------------------------------
1861 ;; The H8/300 has given 1/8th of its opcode space to bitfield
1862 ;; instructions so let's use them as well as we can.
1863
1864 ;; BCC and BCS patterns.
1865
1866 (define_insn "bcs_qiqi"
1867   [(set (pc)
1868         (if_then_else 
1869          (match_operator 1 "eq_operator"
1870                          [(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur")
1871                                            (const_int 1)
1872                                            (match_operand:HI 3 "immediate_operand" "i"))
1873                           (const_int 0)])
1874          (label_ref (match_operand 0 "" ""))
1875          (pc)))]
1876   ""
1877   "*
1878 {
1879   /* The length of this insn includes the bld insn below.  We
1880      compute the length of the branch without the bld so we
1881      can easily choose the right branch length.  */
1882   int branch_length = get_attr_length (insn);
1883
1884   if (! register_operand (operands[2], QImode))
1885     branch_length -= 4;
1886   else
1887     branch_length -= 2;
1888
1889   output_asm_insn(\"bld %Z3,%Y2\", operands);
1890   if (branch_length == 2) 
1891     return \"%d1        %l0\";
1892   else if (branch_length == 4) 
1893     return \"%d1        %l0:16\";
1894   else
1895     return \"%g1        %L0\;jmp        @%l0\;%L0:\";
1896 }" 
1897   [(set_attr "type" "bcs")
1898    (set_attr "cc" "clobber")])
1899
1900 (define_insn "bcs_hihi"
1901   [(set (pc)
1902         (if_then_else 
1903          (match_operator 1 "eq_operator"
1904                          [(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur")
1905                                            (const_int 1)
1906                                            (match_operand:HI 3 "immediate_operand" "i"))
1907                           (const_int 0)])
1908          (label_ref (match_operand 0 "" ""))
1909          (pc)))]
1910   ""
1911   "*
1912 {
1913   /* The length of this insn includes the bld insn below.  We
1914      compute the length of the branch without the bld so we
1915      can easily choose the right branch length.  */
1916   int branch_length = get_attr_length (insn);
1917
1918   if (! register_operand (operands[2], QImode))
1919     branch_length -= 4;
1920   else
1921     branch_length -= 2;
1922
1923   output_asm_insn(\"bld %Z3,%Y2\", operands);
1924   if (branch_length == 2) 
1925     return \"%d1        %l0\";
1926   else if (branch_length == 4) 
1927     return \"%d1        %l0:16\";
1928   else
1929     return \"%g1        %L0\;jmp        @%l0\;%L0:\";
1930 }" 
1931   [(set_attr "type" "bcs")
1932    (set_attr "cc" "clobber")])
1933
1934 (define_insn "bcs_hiqi"
1935   [(set (pc)
1936         (if_then_else 
1937          (match_operator 1 "eq_operator"
1938                          [(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur")
1939                                            (const_int 1)
1940                                            (match_operand:HI 3 "immediate_operand" "i"))
1941                           (const_int 0)])
1942          (label_ref (match_operand 0 "" ""))
1943          (pc)))]
1944   ""
1945   "*
1946 {
1947   /* The length of this insn includes the bld insn below.  We
1948      compute the length of the branch without the bld so we
1949      can easily choose the right branch length.  */
1950   int branch_length = get_attr_length (insn);
1951
1952   if (! register_operand (operands[2], QImode))
1953     branch_length -= 4;
1954   else
1955     branch_length -= 2;
1956
1957   output_asm_insn(\"bld %Z3,%Y2\", operands);
1958   if (branch_length == 2) 
1959     return \"%d1        %l0\";
1960   else if (branch_length == 4) 
1961     return \"%d1        %l0:16\";
1962   else
1963     return \"%g1        %L0\;jmp        @%l0\;%L0:\";
1964 }" 
1965   [(set_attr "type" "bcs")
1966    (set_attr "cc" "clobber")])
1967
1968 ;; BLD and BST patterns
1969
1970 (define_insn "extract_1"
1971   [(set (match_operand:HI 0 "register_operand" "=&r")
1972         (zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
1973                          (const_int 1)
1974                          (match_operand:HI 2 "immediate_operand" "i")))]
1975   ""
1976   "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0")
1977
1978 (define_insn "extract_1_hi"
1979   [(set (match_operand:HI 0 "register_operand" "=&r")
1980         (zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
1981                          (const_int 1)
1982                          (match_operand:HI 2 "immediate_operand" "i")))]
1983   ""
1984   "sub.w        %0,%0\;bld      %Z2,%Y1\;bst    #0,%X0")
1985
1986 (define_insn "insert_1"
1987   [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur")
1988                          (const_int 1)
1989                          (match_operand:HI 1 "immediate_operand" "i"))
1990         (zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur")
1991                          (const_int 1)
1992                          (const_int 0)))]
1993   ""
1994   "bld  #0,%R2\;bst     %Z1,%Y0 ; i1")
1995
1996 ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
1997 ;; in combine.c, but there is no problem with writing it this way so we do.
1998 (define_insn "extract_insert_1"
1999   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur")
2000                          (const_int 1)
2001                          (match_operand:HI 1 "immediate_operand" "i"))
2002         (lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur")
2003                      (match_operand:HI 3 "immediate_operand" "i")))]
2004  ""
2005  "bld   %Z3,%Y2\;bst    %Z1,%Y0; ei1")
2006
2007 ;; BAND, BOR, and BXOR patterns
2008
2009 (define_insn "bitlogical_1"
2010   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2011         (match_operator:HI 4 "bit_operator"
2012            [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
2013                              (const_int 1)
2014                              (match_operand:HI 2 "immediate_operand" "i"))
2015             (match_operand:HI 3 "bit_operand" "0")]))]
2016   ""
2017   "bld  %Z2,%Y1\;%b4    #0,%R0\;bst     #0,%R0; bl1")
2018
2019 (define_insn "bitlogical_1_hi"
2020   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2021         (match_operator:HI 4 "bit_operator"
2022            [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
2023                              (const_int 1)
2024                              (match_operand:HI 2 "immediate_operand" "i"))
2025             (match_operand:HI 3 "bit_operand" "0")]))]
2026   ""
2027   "bld  %Z2,%Y1\;%b4    #0,%R0\;bst     #0,%R0; bl2")
2028
2029 (define_insn "bitlogical_2"
2030   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2031         (match_operator:HI 5 "bit_operator"
2032            [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur")
2033                              (const_int 1)
2034                              (match_operand:HI 2 "immediate_operand" "i"))
2035             (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur")
2036                              (const_int 1)
2037                              (match_operand:HI 4 "immediate_operand" "i"))]))]
2038   ""
2039   "bld  %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%R0; bl3")
2040
2041 (define_insn "bitlogical_2_hi"
2042   [(set (match_operand:HI 0 "bit_operand" "=Ur")
2043         (match_operator:HI 5 "bit_operator"
2044            [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur")
2045                              (const_int 1)
2046                              (match_operand:HI 2 "immediate_operand" "i"))
2047             (zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur")
2048                              (const_int 1)
2049                              (match_operand:HI 4 "immediate_operand" "i"))]))]
2050   ""
2051   "bld  %Z2,%Y1\;%b5    %Z4,%Y3\;bst    #0,%R0; bl3")
2052
2053 ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
2054 ;; in combine.c, but there is no problem with writing it this way so we do.
2055 (define_insn "bitlogical_3"
2056   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur")
2057                          (const_int 1)
2058                          (match_operand:HI 1 "immediate_operand" "i"))
2059         (match_operator:QI 6 "bit_operator"
2060            [(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur")
2061                          (match_operand:HI 3 "immediate_operand" "i"))
2062             (lshiftrt:QI (match_operand:QI 4 "bit_operand" "Ur")
2063                          (match_operand:HI 5 "immediate_operand" "i"))]))]
2064   ""
2065   "bld  %Z3,%Y2\;%b6    %Z5,%Y4\;bst    %Z1,%Y0; bl5")
2066                                                      
2067 ;; This is how combine canonicalizes this pattern.  This is perhaps a bug
2068 ;; in combine.c, but there is no problem with writing it this way so we do.
2069 (define_insn "bitnot_1"
2070   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur")
2071                          (const_int 1)
2072                          (match_operand:HI 1 "immediate_operand" "i"))
2073         (lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0")
2074                              (match_operand:HI 3 "immediate_operand" "i"))
2075                      (match_operand:HI 4 "immediate_operand" "1")))]
2076   "GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT
2077    && exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])"
2078   "bnot %Z1,%Y0")
2079
2080 ;; ??? Implement BIAND, BIOR, BIXOR
2081
2082 ;; ??? Implement BILD, BIST
2083
2084 ;; ??? Apparently general_operand for the 1st and 2nd operands is useful,
2085 ;; but I don't know why.  --Jim
2086
2087 (define_expand "insv"
2088   [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur")
2089                          (match_operand:HI 1 "general_operand" "g")
2090                          (match_operand:HI 2 "general_operand" "g"))
2091         (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur")
2092                          (const_int 1)
2093                          (const_int 0)))]
2094 ;; ??? This should have word mode which is SImode for the h8/300h.
2095   "TARGET_H8300"
2096   "
2097 {
2098   if (INTVAL (operands[1]) != 1)
2099     FAIL;
2100
2101   /* ??? HACK ???
2102      This INSV pattern is wrong.  It should use HImode for operand 3.
2103      Also, the zero_extract around operand 3 is superfluous and should be
2104      deleted.  Fixing this is more work than we care to do for the moment,
2105      because it means most of the above patterns would need to be rewritten,
2106      and we also need more combine.c patches to make this work.
2107
2108      So, for now, we work around this bug by simply not accepting any bitfield
2109      inserts that have a position greater than fits in QImode.  */
2110
2111   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 8)
2112     FAIL;
2113
2114   /* The bit_operand predicate accepts any memory during RTL generation, but
2115      only 'U' memory afterwards, so if this is a MEM operand, we must force
2116      it to be valid for 'U' by reloading the address.  */
2117
2118   if (GET_CODE (operands[0]) == MEM && ! EXTRA_CONSTRAINT (operands[0], 'U'))
2119     {
2120       rtx mem;
2121       mem = gen_rtx (MEM, GET_MODE (operands[0]),
2122                      copy_to_mode_reg (Pmode, XEXP (operands[0], 0)));
2123       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]);
2124       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]);
2125       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]);
2126       operands[0] = mem;
2127     }
2128
2129   /* Likewise for operands[3].  */
2130
2131   if (GET_CODE (operands[3]) == MEM && ! EXTRA_CONSTRAINT (operands[3], 'U'))
2132     {
2133       rtx mem;
2134       mem = gen_rtx (MEM, GET_MODE (operands[3]),
2135                      copy_to_mode_reg (Pmode, XEXP (operands[3], 0)));
2136       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[3]);
2137       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[3]);
2138       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]);
2139       operands[3] = mem;
2140     }
2141 }")
2142
2143 ;; ??? Apparently general_operand for the 2nd and 3rd operands is useful,
2144 ;; but I don't know why.  --Jim
2145
2146 (define_expand "extzv"
2147   [(set (match_operand:HI 0 "register_operand" "") 
2148         (zero_extract:HI (match_operand:QI 1 "bit_operand" "")
2149                          (match_operand:HI 2 "general_operand" "g")
2150                          (match_operand:HI 3 "general_operand" "g")))]
2151 ;; ??? This should have word mode which is SImode for the h8/300h.
2152   "TARGET_H8300"
2153   "
2154 {
2155   if (INTVAL (operands[2]) != 1)
2156     FAIL;
2157
2158   /* The bit_operand predicate accepts any memory during RTL generation, but
2159      only 'U' memory afterwards, so if this is a MEM operand, we must force
2160      it to be valid for 'U' by reloading the address.  */
2161
2162   if (GET_CODE (operands[1]) == MEM && ! EXTRA_CONSTRAINT (operands[1], 'U'))
2163     {
2164       rtx mem;
2165       mem = gen_rtx (MEM, GET_MODE (operands[1]),
2166                      copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
2167       RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]);
2168       MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]);
2169       MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]);
2170       operands[1] = mem;
2171     }
2172 }")
2173 \f
2174 ;; -----------------------------------------------------------------
2175 ;; STACK POINTER MANIPULATIONS
2176 ;; -----------------------------------------------------------------
2177
2178 ;; This pattern is needed because there is no way on the H8/300
2179 ;; to add a 16 bit immediate value to the stack pointer in one 
2180 ;; instruction, which could leave an invalid instruction if interrupted
2181 ;; half way through.  Here we add to the stack pointer from a
2182 ;; register.
2183
2184 (define_insn "stack_pointer_manip"
2185   [(set (match_operand:HI 0 "register_operand" "=&ra")
2186         (plus:HI (match_operand:HI 1 "general_operand_src" "g")
2187                  (match_operand:HI 2 "register_operand" "ra")))]
2188   "TARGET_H8300"
2189   "mov.w        %T1,%T0\;add.w  %T2,%T0"
2190   [(set_attr "type" "arith")
2191    (set_attr "length" "6")
2192    (set_attr "cc" "set_zn_c0")])
2193
2194
2195 ;; -------------------------------------------
2196 ;; BLK moves
2197 ;; -------------------------------------------
2198
2199 (define_expand "movstrhi"
2200   [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" ""))
2201                    (mem:BLK (match_operand:BLK 1 "general_operand" "")))
2202              (use (match_operand:HI 2 "general_operand" ""))
2203              (use (match_operand:HI 3 "immediate_operand" ""))
2204              (clobber (match_dup 3))
2205   ])]
2206   ""
2207   "
2208 {
2209         rtx src_ptr = copy_to_mode_reg (Pmode, XEXP(operands[1], 0));
2210         rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP(operands[0], 0));
2211         
2212         int max = GET_CODE (operands[2]) == CONST_INT
2213           ? MIN (INTVAL (operands[2]), INTVAL (operands[3])) : 1;
2214         enum machine_mode mode = max >= 2 ? HImode : QImode;
2215         rtx tmpreg = gen_reg_rtx (mode);
2216         rtx increment = mode == QImode ? const1_rtx : const2_rtx;
2217         rtx length = operands[2];
2218         rtx label = gen_label_rtx ();
2219         rtx end_src_ptr = gen_reg_rtx (Pmode);
2220
2221 /*      emit_move_insn (length, gen_rtx(MINUS, HImode, length, increment));*/
2222         FAIL;
2223         if (Pmode == HImode)
2224           emit_insn (gen_addhi3 (end_src_ptr, src_ptr, length));
2225         else
2226           emit_insn (gen_addsi3 (end_src_ptr, src_ptr, length));
2227
2228         emit_label (label);
2229         emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr));
2230         emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg);
2231         emit_insn (gen_rtx (SET, VOIDmode, src_ptr,
2232                             gen_rtx (PLUS, Pmode, src_ptr, increment)));
2233         emit_insn (gen_rtx (SET, VOIDmode, dst_ptr,
2234                             gen_rtx (PLUS, Pmode, dst_ptr, increment)));
2235
2236         emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
2237                             gen_rtx (COMPARE, Pmode, src_ptr, end_src_ptr)));
2238         emit_jump_insn (gen_bne (label));
2239
2240         DONE;   
2241 }")
2242 \f
2243 ;; ----------------------------------------------
2244 ;; Peepholes go at the end.
2245 ;; ----------------------------------------------
2246
2247 ;; Notice when two byte moves in a row could be a word move.
2248
2249 (define_peephole
2250   [(set (match_operand:QI 0 "register_operand" "=r")
2251         (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
2252                          (match_operand:HI 2 "immediate_operand" "n"))))
2253    (set (match_operand:QI 3 "register_operand" "=r")
2254         (mem:QI (plus:HI (match_dup 1)
2255                          (match_operand:HI 4 "immediate_operand" "n"))))]
2256   "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
2257   "mov.w        @(%u4,%T1),%T0"
2258   [(set_attr "length" "6")
2259    (set_attr "cc" "set")])
2260
2261 (define_peephole
2262   [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra")
2263                          (match_operand:HI 2 "immediate_operand" "n")))
2264         (match_operand:QI 0 "register_operand" "r"))
2265    (set (mem:QI (plus:HI (match_dup 1)
2266                          (match_operand:HI 4 "immediate_operand" "n")))
2267         (match_operand:QI 3 "register_operand" "r"))]
2268   "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])"
2269   "mov.w        %T0,@(%u4,%T1)"
2270   [(set_attr "length" "6")
2271    (set_attr "cc" "set")])
2272
2273 ;; Notice a move which could be post incremented.
2274
2275 (define_peephole 
2276   [(set (match_operand:QI 0 "register_operand" "")
2277         (mem:QI (match_operand:HI 1 "register_operand" "")))
2278    (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
2279   "REGNO(operands[1]) != REGNO(operands[0])"
2280   "mov.b        @%T1+,%X0"
2281   [(set_attr "length" "2")
2282    (set_attr "cc" "set")])
2283
2284 (define_peephole 
2285   [(set (match_operand:HI 0 "register_operand" "")
2286         (mem:HI (match_operand:HI 1 "register_operand" "")))
2287    (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))]
2288   "REGNO(operands[1]) != REGNO(operands[0])"
2289   "mov.w        @%T1+,%T0"
2290   [(set_attr "length" "2")
2291    (set_attr "cc" "set")])
2292
2293 ;; Notice a move which could be predecremented.
2294
2295 (define_peephole 
2296   [(set (match_operand:HI 1 "register_operand" "")
2297         (plus:HI (match_dup 1) (const_int -1)))
2298    (set (mem:QI (match_dup 1))
2299                 (match_operand:QI 0 "register_operand" ""))]
2300   "REGNO(operands[1]) != REGNO(operands[0])"
2301   "mov.b        %X0,@-%T1"
2302   [(set_attr "length" "2")
2303    (set_attr "cc" "set")])
2304
2305 (define_peephole 
2306   [(set (match_operand:HI 1 "register_operand" "")
2307         (plus:HI (match_dup 1) (const_int -1)))
2308    (set (mem:HI (match_dup 1))
2309                 (match_operand:HI 0 "register_operand" ""))]
2310   "REGNO(operands[1]) != REGNO(operands[0])"
2311   "mov.w        %T0,@-%T1"
2312   [(set_attr "length" "2")
2313    (set_attr "cc" "set")])
2314
2315 ;(define_insn ""
2316 ;  [(set (match_operand:HI 0 "register_operand" "=r")
2317 ;       (MEM:HI (match_operand:HI 1 "register_operand" "r")))
2318 ;   (set (match_operand:HI 3 "register_operand" "=r")
2319 ;       (zero_extract:HI (match_dup 0)
2320 ;                        (const_int 1)
2321 ;                        (match_operand:HI 2 "general_operand" "g")))
2322 ;   (set (MEM:HI (match_dup 1) (match_dup 3)))]
2323 ;  ""
2324 ;  "bld #0,%3l\;bst     %Z2,%0%Y1"
2325 ;  [(set_attr "type" "multi")
2326 ;   (set_attr "length" "4")
2327 ;   (set_attr "cc" "clobber")])
2328
2329 (define_insn "fancybset1"
2330   [(set (match_operand:QI 0 "bit_operand" "=Ur")
2331         (ior:QI (subreg:QI 
2332                  (ashift:HI (const_int 1)
2333                             (subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0)
2334                 (match_dup 0)))]
2335   ""
2336   "bset %X1,%R0")       
2337
2338 (define_insn "fancybset"
2339   [(set (match_operand:QI 0 "bit_operand" "=Ur")
2340         (ior:QI (subreg:QI 
2341                  (ashift:HI (const_int 1)
2342                             (match_operand:HI 1 "nonmemory_operand" "ri") ) 0)
2343                 (match_operand:QI 2 "general_operand" "Ur")))]
2344   ""
2345   "mov.b        %R2,%R0\;bset   %X1,%R0")       
2346
2347 (define_insn "fancybclr4"
2348   [(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
2349         (and:QI 
2350          (subreg:QI 
2351           (rotate:HI (const_int -2)
2352                      (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0)
2353          (match_operand:QI 1 "general_operand" "0,Ur")))
2354    (clobber (match_scratch:HI 3 "=X,&r"))]
2355   ""
2356   "@
2357    bclr %X2,%R0; l1
2358    mov.b        %R1,%X3\;mov.b  %3,%0\;bclr     %X2,%R0; l3")
2359
2360 (define_insn "fancybclr5"
2361   [(set (match_operand:QI 0 "general_operand" "=Ur,Ur")
2362         (and:QI 
2363          (subreg:QI 
2364           (rotate:HI (const_int -2)
2365                      (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0)
2366          (match_operand:QI 1 "general_operand" "0,Ur")))
2367    (clobber (match_scratch:HI 3 "=X,&r"))]
2368   ""
2369   "@
2370    bclr %X2,%R0; l1
2371    mov.b        %R1,%X3\;mov.b  %3,%0\;bclr     %X2,%R0;l2")
2372
2373 (define_insn "fancybclr2"
2374   [(set (match_operand:QI 0 "general_operand" "=U,r")
2375         (and:QI 
2376          (subreg:QI 
2377           (rotate:HI (const_int -2)
2378                      (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0)
2379          (match_operand:QI 1 "general_operand" "0,0")))]
2380   ""
2381   "bclr %X2,%R0")
2382
2383 (define_insn "fancybclr3"
2384   [(set (match_operand:QI 0 "general_operand" "=U,r")
2385         (and:QI 
2386          (subreg:QI 
2387           (rotate:HI (const_int -2)
2388                      (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0)
2389          (match_operand:QI 1 "general_operand" "0,0")))]
2390   ""
2391   "bclr %X2,%R0")
2392
2393 (define_insn "fancybclr"
2394   [(set (match_operand:QI 0 "general_operand" "=r")
2395         (and:QI (not:QI (match_operand:QI 1 "general_operand" "0"))
2396                 (match_operand:QI 2 "general_operand" "r")))]
2397   ""
2398   "not  %X0\;and        %X2,%X0")
2399
2400 (define_insn "fancybsetp3"
2401   [(set (match_operand:QI 0 "bit_operand" "=Ur")
2402         (ior:QI (subreg:QI (ashift:HI (const_int 1)
2403                                       (match_operand:QI 1 "register_operand" "r")) 0)
2404                 (match_operand:QI 2 "bit_operand" "0")))]
2405   ""
2406   "bset %X1,%R0")
2407
2408 (define_insn "fancybsetp2"
2409   [(set (match_operand:QI 0 "general_operand" "=r,U")
2410         (ior:QI (subreg:QI (ashift:HI (const_int 1)
2411                                       (match_operand:QI 1 "register_operand" "r,r")) 0)
2412                 (match_operand:QI 2 "general_operand" "U,r")))]
2413   ""
2414   "mov.b        %R2,%R0\;bset   %X1,%R0")
2415         
2416 (define_insn "fancybnot"
2417   [(set (match_operand:QI 0 "bit_operand" "=Ur")
2418         (xor:QI (subreg:QI (ashift:HI (const_int 1)
2419                                       (match_operand:QI 1 "register_operand" "r")) 0)
2420                 (match_operand:QI 2 "bit_operand" "0")))]
2421
2422   ""
2423   "bnot %X1,%R0")
2424
2425 (define_insn "fancy_btst"
2426   [(set (pc)
2427         (if_then_else (eq (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur"))
2428                                            (const_int 1)
2429                                            (match_operand:HI 2 "nonmemory_operand" "rn"))
2430                           (const_int 0))
2431                       (label_ref (match_operand 0 "" ""))
2432                       (pc)))]
2433   ""
2434   "*
2435 {
2436   if (get_attr_length (insn) == 2)
2437     return \"btst       %X2,%R1\;beq    %l0\";
2438   else if (get_attr_length (insn) == 4)
2439     return \"btst       %X2,%R1\;beq    %l0:16\";
2440   else
2441     return \"btst       %X2,%R1\;bne    %L1\;jmp        @%l0\;%L1:\";
2442 }"
2443   [(set_attr "type" "branch")
2444    (set_attr "cc" "clobber")])
2445
2446 (define_insn "fancy_btst1"
2447   [(set (pc)
2448         (if_then_else (ne (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur"))
2449                                            (const_int 1)
2450                                            (match_operand:HI 2 "nonmemory_operand" "rn"))
2451                           (const_int 0))
2452                       (label_ref (match_operand 0 "" ""))
2453                       (pc)))]
2454   ""
2455   "*
2456 {
2457   if (get_attr_length (insn) == 2)
2458     return \"btst       %X2,%R1\;bne    %l0\";
2459   else if (get_attr_length (insn) == 4)
2460     return \"btst       %X2,%R1\;bne    %l0:16\";
2461   else
2462     return \"btst       %X2,%R1\;beq    %L1\;jmp        @%l0\;%L1:\";
2463 }"
2464   [(set_attr "type" "branch")
2465    (set_attr "cc" "clobber")])
2466
2467 (define_insn "pxor"
2468   [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=r,U")
2469                          (const_int 1)
2470                          (match_operand 1 "immediate_operand" "n,n"))
2471         (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U"))
2472                         (const_int 1)))]
2473   ""
2474   "bld  #0,%R2\;bist    %1,%0"
2475   [(set_attr "type" "arith")
2476    (set_attr "length" "4")
2477    (set_attr "cc" "clobber")])