OSDN Git Service

* config/avr/avr.h (AVR_HAVE_RAMPZ): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.md
1 ;; -*- Mode: Scheme -*-
2 ;;   Machine description for GNU compiler,
3 ;;   for ATMEL AVR micro controllers.
4 ;;   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
5 ;;   Free Software Foundation, Inc.
6 ;;   Contributed by Denis Chertykov (denisc@overta.ru)
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24 ;; Special characters after '%':
25 ;;  A  No effect (add 0).
26 ;;  B  Add 1 to REG number, MEM address or CONST_INT.
27 ;;  C  Add 2.
28 ;;  D  Add 3.
29 ;;  j  Branch condition.
30 ;;  k  Reverse branch condition.
31 ;;  o  Displacement for (mem (plus (reg) (const_int))) operands.
32 ;;  p  POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33 ;;  r  POST_INC or PRE_DEC address as a register (r26, r28, r30)
34 ;;  ~  Output 'r' if not AVR_MEGA.
35
36 ;; UNSPEC usage:
37 ;;  0  Length of a string, see "strlenhi".
38 ;;  1  Jump by register pair Z or by table addressed by Z, see "casesi".
39
40 (define_constants
41   [(REG_X       26)
42    (REG_Y       28)
43    (REG_Z       30)
44    (REG_W       24)
45    (REG_SP      32)
46    (TMP_REGNO   0)      ; temporary register r0
47    (ZERO_REGNO  1)      ; zero register r1
48    
49    (SREG_ADDR   0x5F)
50    (RAMPZ_ADDR  0x5B)
51    
52    (UNSPEC_STRLEN       0)
53    (UNSPEC_INDEX_JMP    1)
54    (UNSPEC_SEI          2)
55    (UNSPEC_CLI          3)
56
57    (UNSPECV_PROLOGUE_SAVES      0)
58    (UNSPECV_EPILOGUE_RESTORES   1)])
59
60 (include "predicates.md")
61 (include "constraints.md")
62   
63 ;; Condition code settings.
64 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
65   (const_string "none"))
66
67 (define_attr "type" "branch,branch1,arith,xcall"
68   (const_string "arith"))
69
70 (define_attr "mcu_have_movw" "yes,no"
71   (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
72                        (const_string "yes")
73                        (const_string "no"))))
74
75 (define_attr "mcu_mega" "yes,no"
76   (const (if_then_else (symbol_ref "AVR_MEGA")
77                        (const_string "yes")
78                        (const_string "no"))))
79   
80
81 ;; The size of instructions in bytes.
82 ;; XXX may depend from "cc"
83
84 (define_attr "length" ""
85   (cond [(eq_attr "type" "branch")
86          (if_then_else (and (ge (minus (pc) (match_dup 0))
87                                 (const_int -63))
88                             (le (minus (pc) (match_dup 0))
89                                 (const_int 62)))
90                        (const_int 1)
91                        (if_then_else (and (ge (minus (pc) (match_dup 0))
92                                               (const_int -2045))
93                                           (le (minus (pc) (match_dup 0))
94                                               (const_int 2045)))
95                                      (const_int 2)
96                                      (const_int 3)))
97          (eq_attr "type" "branch1")
98          (if_then_else (and (ge (minus (pc) (match_dup 0))
99                                 (const_int -62))
100                             (le (minus (pc) (match_dup 0))
101                                 (const_int 61)))
102                        (const_int 2)
103                        (if_then_else (and (ge (minus (pc) (match_dup 0))
104                                               (const_int -2044))
105                                           (le (minus (pc) (match_dup 0))
106                                               (const_int 2043)))
107                                      (const_int 3)
108                                      (const_int 4)))
109          (eq_attr "type" "xcall")
110          (if_then_else (eq_attr "mcu_mega" "no")
111                        (const_int 1)
112                        (const_int 2))]
113         (const_int 2)))
114
115 (define_insn "*pushqi"
116   [(set (mem:QI (post_dec (reg:HI REG_SP)))
117         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
118   ""
119   "@
120         push %0
121         push __zero_reg__"
122   [(set_attr "length" "1,1")])
123
124
125 (define_insn "*pushhi"
126   [(set (mem:HI (post_dec (reg:HI REG_SP)))
127         (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
128   ""
129   "@
130         push %B0\;push %A0
131         push __zero_reg__\;push __zero_reg__"
132   [(set_attr "length" "2,2")])
133
134 (define_insn "*pushsi"
135   [(set (mem:SI (post_dec (reg:HI REG_SP)))
136         (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
137   ""
138   "@
139         push %D0\;push %C0\;push %B0\;push %A0
140         push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
141   [(set_attr "length" "4,4")])
142
143 (define_insn "*pushsf"
144   [(set (mem:SF (post_dec (reg:HI REG_SP)))
145         (match_operand:SF 0 "register_operand" "r"))]
146   ""
147   "push %D0
148         push %C0
149         push %B0
150         push %A0"
151   [(set_attr "length" "4")])
152
153 ;;========================================================================
154 ;; move byte
155 ;; The last alternative (any immediate constant to any register) is
156 ;; very expensive.  It should be optimized by peephole2 if a scratch
157 ;; register is available, but then that register could just as well be
158 ;; allocated for the variable we are loading.  But, most of NO_LD_REGS
159 ;; are call-saved registers, and most of LD_REGS are call-used registers,
160 ;; so this may still be a win for registers live across function calls.
161
162 (define_expand "movqi"
163   [(set (match_operand:QI 0 "nonimmediate_operand" "")
164         (match_operand:QI 1 "general_operand" ""))]
165   ""
166   "/* One of the ops has to be in a register.  */
167    if (!register_operand(operand0, QImode)
168        && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
169        operands[1] = copy_to_mode_reg(QImode, operand1);
170   ")
171
172 (define_insn "*movqi"
173   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
174         (match_operand:QI 1 "general_operand"       "r,i,rL,Qm,r,q,i"))]
175   "(register_operand (operands[0],QImode)
176     || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
177   "* return output_movqi (insn, operands, NULL);"
178   [(set_attr "length" "1,1,5,5,1,1,4")
179    (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
180
181 ;; This is used in peephole2 to optimize loading immediate constants
182 ;; if a scratch register from LD_REGS happens to be available.
183
184 (define_insn "*reload_inqi"
185   [(set (match_operand:QI 0 "register_operand" "=l")
186         (match_operand:QI 1 "immediate_operand" "i"))
187    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
188   "reload_completed"
189   "ldi %2,lo8(%1)
190         mov %0,%2"
191   [(set_attr "length" "2")
192    (set_attr "cc" "none")])
193
194 (define_peephole2
195   [(match_scratch:QI 2 "d")
196    (set (match_operand:QI 0 "l_register_operand" "")
197         (match_operand:QI 1 "immediate_operand" ""))]
198   "(operands[1] != const0_rtx
199     && operands[1] != const1_rtx
200     && operands[1] != constm1_rtx)"
201   [(parallel [(set (match_dup 0) (match_dup 1))
202               (clobber (match_dup 2))])]
203   "if (!avr_peep2_scratch_safe (operands[2]))
204      FAIL;")
205
206 ;;============================================================================
207 ;; move word (16 bit)
208
209 (define_expand "movhi"
210   [(set (match_operand:HI 0 "nonimmediate_operand" "")
211         (match_operand:HI 1 "general_operand"       ""))]
212   ""
213   "
214 {
215    /* One of the ops has to be in a register.  */
216   if (!register_operand(operand0, HImode)
217       && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
218     {
219       operands[1] = copy_to_mode_reg(HImode, operand1);
220     }
221 }")
222
223 (define_insn "*movhi_sp"
224   [(set (match_operand:HI 0 "register_operand" "=q,r")
225         (match_operand:HI 1 "register_operand"  "r,q"))]
226   "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
227     || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
228   "* return output_movhi (insn, operands, NULL);"
229   [(set_attr "length" "5,2")
230    (set_attr "cc" "none,none")])
231
232 (define_peephole2
233   [(match_scratch:QI 2 "d")
234    (set (match_operand:HI 0 "l_register_operand" "")
235         (match_operand:HI 1 "immediate_operand" ""))]
236   "(operands[1] != const0_rtx 
237     && operands[1] != constm1_rtx)"
238   [(parallel [(set (match_dup 0) (match_dup 1))
239               (clobber (match_dup 2))])]
240   "if (!avr_peep2_scratch_safe (operands[2]))
241      FAIL;")
242
243 ;; '*' because it is not used in rtl generation, only in above peephole
244 (define_insn "*reload_inhi"
245   [(set (match_operand:HI 0 "register_operand" "=r")
246         (match_operand:HI 1 "immediate_operand" "i"))
247    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
248   "reload_completed"
249   "* return output_reload_inhi (insn, operands, NULL);"
250   [(set_attr "length" "4")
251    (set_attr "cc" "none")])
252
253 (define_insn "*movhi"
254   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
255         (match_operand:HI 1 "general_operand"       "r,m,rL,i,i,r,q"))]
256   "(register_operand (operands[0],HImode)
257     || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
258   "* return output_movhi (insn, operands, NULL);"
259   [(set_attr "length" "2,6,7,2,6,5,2")
260    (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
261
262 (define_peephole2 ; movw
263   [(set (match_operand:QI 0 "even_register_operand" "")
264         (match_operand:QI 1 "even_register_operand" ""))
265    (set (match_operand:QI 2 "odd_register_operand" "")
266         (match_operand:QI 3 "odd_register_operand" ""))]
267   "(AVR_HAVE_MOVW
268     && REGNO (operands[0]) == REGNO (operands[2]) - 1
269     && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
270   [(set (match_dup 4) (match_dup 5))]
271   {
272     operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
273     operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
274   })
275
276 (define_peephole2 ; movw_r
277   [(set (match_operand:QI 0 "odd_register_operand" "")
278         (match_operand:QI 1 "odd_register_operand" ""))
279    (set (match_operand:QI 2 "even_register_operand" "")
280         (match_operand:QI 3 "even_register_operand" ""))]
281   "(AVR_HAVE_MOVW
282     && REGNO (operands[2]) == REGNO (operands[0]) - 1
283     && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
284   [(set (match_dup 4) (match_dup 5))]
285   {
286     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
287     operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
288   })
289
290 ;;==========================================================================
291 ;; move double word (32 bit)
292
293 (define_expand "movsi"
294   [(set (match_operand:SI 0 "nonimmediate_operand" "")
295         (match_operand:SI 1 "general_operand"  ""))]
296   ""
297   "
298 {
299   /* One of the ops has to be in a register.  */
300   if (!register_operand (operand0, SImode)
301       && !(register_operand (operand1, SImode) || const0_rtx == operand1))
302     {
303       operands[1] = copy_to_mode_reg (SImode, operand1);
304     }
305 }")
306
307
308
309 (define_peephole2
310   [(match_scratch:QI 2 "d")
311    (set (match_operand:SI 0 "l_register_operand" "")
312         (match_operand:SI 1 "immediate_operand" ""))]
313   "(operands[1] != const0_rtx
314     && operands[1] != constm1_rtx)"
315   [(parallel [(set (match_dup 0) (match_dup 1))
316               (clobber (match_dup 2))])]
317   "if (!avr_peep2_scratch_safe (operands[2]))
318      FAIL;")
319
320 ;; '*' because it is not used in rtl generation.
321 (define_insn "*reload_insi"
322   [(set (match_operand:SI 0 "register_operand" "=r")
323         (match_operand:SI 1 "immediate_operand" "i"))
324    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
325   "reload_completed"
326   "* return output_reload_insisf (insn, operands, NULL);"
327   [(set_attr "length" "8")
328    (set_attr "cc" "none")])
329
330
331 (define_insn "*movsi"
332   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
333         (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
334   "(register_operand (operands[0],SImode)
335     || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
336   "* return output_movsisf (insn, operands, NULL);"
337   [(set_attr "length" "4,4,8,9,4,10")
338    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
339
340 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
341 ;; move floating point numbers (32 bit)
342
343 (define_expand "movsf"
344   [(set (match_operand:SF 0 "nonimmediate_operand" "")
345         (match_operand:SF 1 "general_operand"  ""))]
346   ""
347   "
348 {
349   /* One of the ops has to be in a register.  */
350   if (!register_operand (operand1, SFmode)
351       && !register_operand (operand0, SFmode))
352     {
353       operands[1] = copy_to_mode_reg (SFmode, operand1);
354     }
355 }")
356
357 (define_insn "*movsf"
358   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
359         (match_operand:SF 1 "general_operand"       "r,G,Qm,r,F,F"))]
360   "register_operand (operands[0], SFmode)
361    || register_operand (operands[1], SFmode)"
362   "* return output_movsisf (insn, operands, NULL);"
363   [(set_attr "length" "4,4,8,9,4,10")
364    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
365
366 ;;=========================================================================
367 ;; move string (like memcpy)
368 ;; implement as RTL loop
369
370 (define_expand "movmemhi"
371   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
372           (match_operand:BLK 1 "memory_operand" ""))
373           (use (match_operand:HI 2 "const_int_operand" ""))
374           (use (match_operand:HI 3 "const_int_operand" ""))])]
375   ""
376   "{
377   int prob;
378   HOST_WIDE_INT count;
379   enum machine_mode mode;
380   rtx label = gen_label_rtx ();
381   rtx loop_reg;
382   rtx jump;
383
384   /* Copy pointers into new psuedos - they will be changed.  */
385   rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
386   rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
387
388   /* Create rtx for tmp register - we use this as scratch.  */
389   rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
390
391   if (GET_CODE (operands[2]) != CONST_INT)
392     FAIL;
393
394   count = INTVAL (operands[2]);
395   if (count <= 0)
396     FAIL;
397
398   /* Work out branch probability for latter use.  */
399   prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
400
401   /* See if constant fit 8 bits.  */
402   mode = (count < 0x100) ? QImode : HImode;
403   /* Create loop counter register.  */
404   loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
405
406   /* Now create RTL code for move loop.  */
407   /* Label at top of loop.  */
408   emit_label (label);
409
410   /* Move one byte into scratch and inc pointer.  */
411   emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
412   emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
413
414   /* Move to mem and inc pointer.  */
415   emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
416   emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
417
418   /* Decrement count.  */
419   emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
420
421   /* Compare with zero and jump if not equal. */
422   emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
423                            label);
424   /* Set jump probability based on loop count.  */
425   jump = get_last_insn ();
426   REG_NOTES (jump) = gen_rtx_EXPR_LIST (REG_BR_PROB,
427                     GEN_INT (prob),
428                     REG_NOTES (jump));
429   DONE;
430 }")
431
432 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
433 ;; memset (%0, %2, %1)
434
435 (define_expand "setmemhi"
436   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
437                    (match_operand 2 "const_int_operand" ""))
438               (use (match_operand:HI 1 "const_int_operand" ""))
439               (use (match_operand:HI 3 "const_int_operand" "n"))
440               (clobber (match_scratch:HI 4 ""))
441               (clobber (match_dup 5))])]
442   ""
443   "{
444   rtx addr0;
445   int cnt8;
446   enum machine_mode mode;
447
448   /* If value to set is not zero, use the library routine.  */
449   if (operands[2] != const0_rtx)
450     FAIL;
451
452   if (GET_CODE (operands[1]) != CONST_INT)
453     FAIL;
454
455   cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
456   mode = cnt8 ? QImode : HImode;
457   operands[5] = gen_rtx_SCRATCH (mode);
458   operands[1] = copy_to_mode_reg (mode,
459                                   gen_int_mode (INTVAL (operands[1]), mode));
460   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
461   operands[0] = gen_rtx_MEM (BLKmode, addr0);
462 }")
463
464 (define_insn "*clrmemqi"
465   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
466         (const_int 0))
467    (use (match_operand:QI 1 "register_operand" "r"))
468    (use (match_operand:QI 2 "const_int_operand" "n"))
469    (clobber (match_scratch:HI 3 "=0"))
470    (clobber (match_scratch:QI 4 "=&1"))]
471   ""
472   "st %a0+,__zero_reg__
473         dec %1
474         brne .-6"
475   [(set_attr "length" "3")
476    (set_attr "cc" "clobber")])
477
478 (define_insn "*clrmemhi"
479   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
480         (const_int 0))
481    (use (match_operand:HI 1 "register_operand" "!w,d"))
482    (use (match_operand:HI 2 "const_int_operand" "n,n"))
483    (clobber (match_scratch:HI 3 "=0,0"))
484    (clobber (match_scratch:HI 4 "=&1,&1"))]
485   ""
486   "*{
487      if (which_alternative==0)
488        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
489                AS2 (sbiw,%A1,1) CR_TAB
490                AS1 (brne,.-6));
491      else
492        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
493                AS2 (subi,%A1,1) CR_TAB
494                AS2 (sbci,%B1,0) CR_TAB
495                AS1 (brne,.-8));
496 }"
497   [(set_attr "length" "3,4")
498    (set_attr "cc" "clobber,clobber")])
499
500 (define_expand "strlenhi"
501     [(set (match_dup 4)
502           (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
503                       (match_operand:QI 2 "const_int_operand" "")
504                       (match_operand:HI 3 "immediate_operand" "")]
505                      UNSPEC_STRLEN))
506      (set (match_dup 4) (plus:HI (match_dup 4)
507                                  (const_int -1)))
508      (set (match_operand:HI 0 "register_operand" "")
509           (minus:HI (match_dup 4)
510                     (match_dup 5)))]
511    ""
512    "{
513   rtx addr;
514   if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
515     FAIL;
516   addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
517   operands[1] = gen_rtx_MEM (BLKmode, addr); 
518   operands[5] = addr;
519   operands[4] = gen_reg_rtx (HImode);
520 }")
521
522 (define_insn "*strlenhi"
523   [(set (match_operand:HI 0 "register_operand" "=e")
524         (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
525                     (const_int 0)
526                     (match_operand:HI 2 "immediate_operand" "i")]
527                    UNSPEC_STRLEN))]
528   ""
529   "ld __tmp_reg__,%a0+
530         tst __tmp_reg__
531         brne .-6"
532   [(set_attr "length" "3")
533    (set_attr "cc" "clobber")])
534
535 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
536 ; add bytes
537
538 (define_insn "addqi3"
539   [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
540         (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
541                  (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
542   ""
543   "@
544         add %0,%2
545         subi %0,lo8(-(%2))
546         inc %0
547         dec %0"
548   [(set_attr "length" "1,1,1,1")
549    (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
550
551
552 (define_expand "addhi3"
553   [(set (match_operand:HI 0 "register_operand" "")
554         (plus:HI (match_operand:HI 1 "register_operand" "")
555                  (match_operand:HI 2 "nonmemory_operand" "")))]
556   ""
557   "
558 {
559   if (GET_CODE (operands[2]) == CONST_INT)
560     {
561       short tmp = INTVAL (operands[2]);
562       operands[2] = GEN_INT(tmp);
563     }
564 }")
565
566
567 (define_insn "*addhi3_zero_extend"
568   [(set (match_operand:HI 0 "register_operand" "=r")
569         (plus:HI (zero_extend:HI
570                   (match_operand:QI 1 "register_operand" "r"))
571                  (match_operand:HI 2 "register_operand" "0")))]
572   ""
573   "add %A0,%1
574         adc %B0,__zero_reg__"
575   [(set_attr "length" "2")
576    (set_attr "cc" "set_n")])
577
578 (define_insn "*addhi3_zero_extend1"
579   [(set (match_operand:HI 0 "register_operand" "=r")
580         (plus:HI (match_operand:HI 1 "register_operand" "%0")
581                  (zero_extend:HI
582                   (match_operand:QI 2 "register_operand" "r"))))]
583   ""
584   "add %A0,%2
585         adc %B0,__zero_reg__"
586   [(set_attr "length" "2")
587    (set_attr "cc" "set_n")])
588
589 (define_insn "*addhi3_zero_extend2"
590   [(set (match_operand:HI 0 "register_operand" "=r")
591         (plus:HI
592          (zero_extend:HI (match_operand:QI 1 "register_operand" "%0"))
593          (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
594   ""
595   "add %0,%2
596         mov %B0,__zero_reg__
597         adc %B0,__zero_reg__"
598   [(set_attr "length" "3")
599    (set_attr "cc" "set_n")])
600
601 (define_insn "*addhi3_sp_R_pc2"
602   [(set (match_operand:HI 1 "stack_register_operand" "=q")
603         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
604                  (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
605   "AVR_2_BYTE_PC"
606   "*{
607       if (CONST_INT_P (operands[0]))
608         {
609           switch(INTVAL (operands[0]))
610             {
611             case -6: 
612               return \"rcall .\" CR_TAB 
613                      \"rcall .\" CR_TAB 
614                      \"rcall .\";
615             case -5: 
616               return \"rcall .\" CR_TAB 
617                      \"rcall .\" CR_TAB 
618                      \"push __tmp_reg__\";
619             case -4: 
620               return \"rcall .\" CR_TAB 
621                      \"rcall .\";
622             case -3: 
623               return \"rcall .\" CR_TAB 
624                      \"push __tmp_reg__\";
625             case -2: 
626               return \"rcall .\";
627             case -1: 
628               return \"push __tmp_reg__\";
629             case 0: 
630               return \"\";
631             case 1: 
632               return \"pop __tmp_reg__\";
633             case 2: 
634               return \"pop __tmp_reg__\" CR_TAB 
635                      \"pop __tmp_reg__\";
636             case 3: 
637               return \"pop __tmp_reg__\" CR_TAB 
638                      \"pop __tmp_reg__\" CR_TAB 
639                      \"pop __tmp_reg__\";
640             case 4: 
641               return \"pop __tmp_reg__\" CR_TAB 
642                      \"pop __tmp_reg__\" CR_TAB 
643                      \"pop __tmp_reg__\" CR_TAB 
644                      \"pop __tmp_reg__\";
645             case 5: 
646               return \"pop __tmp_reg__\" CR_TAB 
647                      \"pop __tmp_reg__\" CR_TAB 
648                      \"pop __tmp_reg__\" CR_TAB 
649                      \"pop __tmp_reg__\" CR_TAB 
650                      \"pop __tmp_reg__\";
651             }
652         }
653       return \"bug\";
654     }"
655   [(set (attr "length") 
656         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
657                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
658                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
659                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
660                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
661                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
662                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
663                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
664                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
665                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
666                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
667                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
668                (const_int 0)))])
669
670 (define_insn "*addhi3_sp_R_pc3"
671   [(set (match_operand:HI 1 "stack_register_operand" "=q")
672         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
673                  (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
674   "AVR_3_BYTE_PC"
675   "*{
676       if (CONST_INT_P (operands[0]))
677         {
678           switch(INTVAL (operands[0]))
679             {
680             case -6: 
681               return \"rcall .\" CR_TAB 
682                      \"rcall .\";
683             case -5: 
684               return \"rcall .\" CR_TAB 
685                      \"push __tmp_reg__\" CR_TAB 
686                      \"push __tmp_reg__\";
687             case -4: 
688               return \"rcall .\" CR_TAB 
689                      \"push __tmp_reg__\";
690             case -3: 
691               return \"rcall .\";
692             case -2: 
693               return \"push __tmp_reg__\" CR_TAB 
694                      \"push __tmp_reg__\";
695             case -1: 
696               return \"push __tmp_reg__\";
697             case 0: 
698               return \"\";
699             case 1: 
700               return \"pop __tmp_reg__\";
701             case 2: 
702               return \"pop __tmp_reg__\" CR_TAB 
703                      \"pop __tmp_reg__\";
704             case 3: 
705               return \"pop __tmp_reg__\" CR_TAB 
706                      \"pop __tmp_reg__\" CR_TAB 
707                      \"pop __tmp_reg__\";
708             case 4: 
709               return \"pop __tmp_reg__\" CR_TAB 
710                      \"pop __tmp_reg__\" CR_TAB 
711                      \"pop __tmp_reg__\" CR_TAB 
712                      \"pop __tmp_reg__\";
713             case 5: 
714               return \"pop __tmp_reg__\" CR_TAB 
715                      \"pop __tmp_reg__\" CR_TAB 
716                      \"pop __tmp_reg__\" CR_TAB 
717                      \"pop __tmp_reg__\" CR_TAB 
718                      \"pop __tmp_reg__\";
719             }
720         }
721       return \"bug\";
722     }"
723   [(set (attr "length") 
724         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
725                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
726                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
727                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
728                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
729                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
730                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
731                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
732                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
733                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
734                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
735                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
736                (const_int 0)))])
737
738 (define_insn "*addhi3"
739   [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
740         (plus:HI
741          (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
742          (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
743   ""
744   "@
745         add %A0,%A2\;adc %B0,%B2
746         adiw %A0,%2
747         sbiw %A0,%n2
748         subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
749         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
750         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
751   [(set_attr "length" "2,1,1,2,3,3")
752    (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
753
754 (define_insn "addsi3"
755   [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
756           (plus:SI
757            (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
758            (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
759   ""
760   "@
761         add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
762         adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
763         sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
764         subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
765         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
766         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
767   [(set_attr "length" "4,3,3,4,5,5")
768    (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
769
770 (define_insn "*addsi3_zero_extend"
771   [(set (match_operand:SI 0 "register_operand" "=r")
772         (plus:SI (zero_extend:SI
773                   (match_operand:QI 1 "register_operand" "r"))
774                  (match_operand:SI 2 "register_operand" "0")))]
775   ""
776   "add %A0,%1
777         adc %B0,__zero_reg__
778         adc %C0,__zero_reg__
779         adc %D0,__zero_reg__"
780   [(set_attr "length" "4")
781    (set_attr "cc" "set_n")])
782
783 ;-----------------------------------------------------------------------------
784 ; sub bytes
785 (define_insn "subqi3"
786   [(set (match_operand:QI 0 "register_operand" "=r,d")
787         (minus:QI (match_operand:QI 1 "register_operand" "0,0")
788                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
789   ""
790   "@
791         sub %0,%2
792         subi %0,lo8(%2)"
793   [(set_attr "length" "1,1")
794    (set_attr "cc" "set_czn,set_czn")])
795
796 (define_insn "subhi3"
797   [(set (match_operand:HI 0 "register_operand" "=r,d")
798         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
799                   (match_operand:HI 2 "nonmemory_operand" "r,i")))]
800   ""
801   "@
802         sub %A0,%A2\;sbc %B0,%B2
803         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
804   [(set_attr "length" "2,2")
805    (set_attr "cc" "set_czn,set_czn")])
806
807 (define_insn "*subhi3_zero_extend1"
808   [(set (match_operand:HI 0 "register_operand" "=r")
809         (minus:HI (match_operand:HI 1 "register_operand" "0")
810                   (zero_extend:HI
811                    (match_operand:QI 2 "register_operand" "r"))))]
812   ""
813   "sub %A0,%2
814         sbc %B0,__zero_reg__"
815   [(set_attr "length" "2")
816    (set_attr "cc" "set_n")])
817
818 (define_insn "subsi3"
819   [(set (match_operand:SI 0 "register_operand" "=r,d")
820         (minus:SI (match_operand:SI 1 "register_operand" "0,0")
821                  (match_operand:SI 2 "nonmemory_operand" "r,i")))]
822   ""
823   "@
824         sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
825         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
826   [(set_attr "length" "4,4")
827    (set_attr "cc" "set_czn,set_czn")])
828
829 (define_insn "*subsi3_zero_extend"
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (minus:SI (match_operand:SI 1 "register_operand" "0")
832                   (zero_extend:SI
833                    (match_operand:QI 2 "register_operand" "r"))))]
834   ""
835   "sub %A0,%2
836         sbc %B0,__zero_reg__
837         sbc %C0,__zero_reg__
838         sbc %D0,__zero_reg__"
839   [(set_attr "length" "4")
840    (set_attr "cc" "set_n")])
841
842 ;******************************************************************************
843 ; mul
844
845 (define_expand "mulqi3"
846   [(set (match_operand:QI 0 "register_operand" "")
847         (mult:QI (match_operand:QI 1 "register_operand" "")
848                  (match_operand:QI 2 "register_operand" "")))]
849   ""
850   "{
851   if (!AVR_HAVE_MUL)
852     {
853       emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
854       DONE;
855     }
856 }")
857
858 (define_insn "*mulqi3_enh"
859   [(set (match_operand:QI 0 "register_operand" "=r")
860         (mult:QI (match_operand:QI 1 "register_operand" "r")
861                  (match_operand:QI 2 "register_operand" "r")))]
862   "AVR_HAVE_MUL"
863   "mul %1,%2
864         mov %0,r0
865         clr r1"
866   [(set_attr "length" "3")
867    (set_attr "cc" "clobber")])
868
869 (define_expand "mulqi3_call"
870   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
871    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
872    (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
873               (clobber (reg:QI 22))])
874    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
875   ""
876   "")
877
878 (define_insn "*mulqi3_call"
879   [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
880    (clobber (reg:QI 22))]
881   "!AVR_HAVE_MUL"
882   "%~call __mulqi3"
883   [(set_attr "type" "xcall")
884    (set_attr "cc" "clobber")])
885
886 (define_insn "mulqihi3"
887   [(set (match_operand:HI 0 "register_operand" "=r")
888         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
889                  (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
890   "AVR_HAVE_MUL"
891   "muls %1,%2
892         movw %0,r0
893         clr r1"
894   [(set_attr "length" "3")
895    (set_attr "cc" "clobber")])
896
897 (define_insn "umulqihi3"
898   [(set (match_operand:HI 0 "register_operand" "=r")
899         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
900                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
901   "AVR_HAVE_MUL"
902   "mul %1,%2
903         movw %0,r0
904         clr r1"
905   [(set_attr "length" "3")
906    (set_attr "cc" "clobber")])
907
908 (define_expand "mulhi3"
909   [(set (match_operand:HI 0 "register_operand" "")
910         (mult:HI (match_operand:HI 1 "register_operand" "")
911                  (match_operand:HI 2 "register_operand" "")))]
912   ""
913   "
914 {
915   if (!AVR_HAVE_MUL)
916     {
917       emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
918       DONE;
919     }
920 }")
921
922 (define_insn "*mulhi3_enh"
923   [(set (match_operand:HI 0 "register_operand" "=&r")
924         (mult:HI (match_operand:HI 1 "register_operand" "r")
925                  (match_operand:HI 2 "register_operand" "r")))]
926   "AVR_HAVE_MUL"
927   "mul %A1,%A2
928         movw %0,r0
929         mul %A1,%B2
930         add %B0,r0
931         mul %B1,%A2
932         add %B0,r0
933         clr r1"
934   [(set_attr "length" "7")
935    (set_attr "cc" "clobber")])
936
937 (define_expand "mulhi3_call"
938   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
939    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
940    (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
941               (clobber (reg:HI 22))
942               (clobber (reg:QI 21))])
943    (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
944   ""
945   "")
946
947 (define_insn "*mulhi3_call"
948   [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
949    (clobber (reg:HI 22))
950    (clobber (reg:QI 21))]
951   "!AVR_HAVE_MUL"
952   "%~call __mulhi3"
953   [(set_attr "type" "xcall")
954    (set_attr "cc" "clobber")])
955
956 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
957 ;; All call-used registers clobbered otherwise - normal library call.
958 (define_expand "mulsi3"
959   [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
960    (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
961    (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
962               (clobber (reg:HI 26))
963               (clobber (reg:HI 30))])
964    (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
965   "AVR_HAVE_MUL"
966   "")
967
968 (define_insn "*mulsi3_call"
969   [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
970    (clobber (reg:HI 26))
971    (clobber (reg:HI 30))]
972   "AVR_HAVE_MUL"
973   "%~call __mulsi3"
974   [(set_attr "type" "xcall")
975    (set_attr "cc" "clobber")])
976
977 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
978 ; divmod
979
980 ;; Generate libgcc.S calls ourselves, because:
981 ;;  - we know exactly which registers are clobbered (for QI and HI
982 ;;    modes, some of the call-used registers are preserved)
983 ;;  - we get both the quotient and the remainder at no extra cost
984
985 (define_expand "divmodqi4"
986   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
987    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
988    (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
989               (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
990               (clobber (reg:QI 22))
991               (clobber (reg:QI 23))])
992    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
993    (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
994   ""
995   "")
996
997 (define_insn "*divmodqi4_call"
998   [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
999    (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1000    (clobber (reg:QI 22))
1001    (clobber (reg:QI 23))]
1002   ""
1003   "%~call __divmodqi4"
1004   [(set_attr "type" "xcall")
1005    (set_attr "cc" "clobber")])
1006
1007 (define_expand "udivmodqi4"
1008   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1009    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1010    (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1011               (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1012               (clobber (reg:QI 23))])
1013    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
1014    (set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
1015   ""
1016   "")
1017
1018 (define_insn "*udivmodqi4_call"
1019   [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1020    (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1021    (clobber (reg:QI 23))]
1022   ""
1023   "%~call __udivmodqi4"
1024   [(set_attr "type" "xcall")
1025    (set_attr "cc" "clobber")])
1026
1027 (define_expand "divmodhi4"
1028   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1029    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1030    (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1031               (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1032               (clobber (reg:HI 26))
1033               (clobber (reg:QI 21))])
1034    (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
1035    (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
1036   ""
1037   "")
1038
1039 (define_insn "*divmodhi4_call"
1040   [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1041    (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1042    (clobber (reg:HI 26))
1043    (clobber (reg:QI 21))]
1044   ""
1045   "%~call __divmodhi4"
1046   [(set_attr "type" "xcall")
1047    (set_attr "cc" "clobber")])
1048
1049 (define_expand "udivmodhi4"
1050   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1051    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1052    (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1053               (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1054               (clobber (reg:HI 26))
1055               (clobber (reg:QI 21))])
1056    (set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
1057    (set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
1058   ""
1059   "")
1060
1061 (define_insn "*udivmodhi4_call"
1062   [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1063    (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1064    (clobber (reg:HI 26))
1065    (clobber (reg:QI 21))]
1066   ""
1067   "%~call __udivmodhi4"
1068   [(set_attr "type" "xcall")
1069    (set_attr "cc" "clobber")])
1070
1071 (define_expand "divmodsi4"
1072   [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
1073    (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
1074    (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1075               (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1076               (clobber (reg:HI 26))
1077               (clobber (reg:HI 30))])
1078    (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
1079    (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
1080   ""
1081   "")
1082
1083 (define_insn "*divmodsi4_call"
1084   [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1085    (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1086    (clobber (reg:HI 26))
1087    (clobber (reg:HI 30))]
1088   ""
1089   "%~call __divmodsi4"
1090   [(set_attr "type" "xcall")
1091    (set_attr "cc" "clobber")])
1092
1093 (define_expand "udivmodsi4"
1094   [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
1095    (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
1096    (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1097               (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1098               (clobber (reg:HI 26))
1099               (clobber (reg:HI 30))])
1100    (set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
1101    (set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
1102   ""
1103   "")
1104
1105 (define_insn "*udivmodsi4_call"
1106   [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1107    (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1108    (clobber (reg:HI 26))
1109    (clobber (reg:HI 30))]
1110   ""
1111   "%~call __udivmodsi4"
1112   [(set_attr "type" "xcall")
1113    (set_attr "cc" "clobber")])
1114
1115 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1116 ; and
1117
1118 (define_insn "andqi3"
1119   [(set (match_operand:QI 0 "register_operand" "=r,d")
1120         (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1121                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1122   ""
1123   "@
1124         and %0,%2
1125         andi %0,lo8(%2)"
1126   [(set_attr "length" "1,1")
1127    (set_attr "cc" "set_zn,set_zn")])
1128
1129 (define_insn "andhi3"
1130   [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1131           (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1132                   (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1133    (clobber (match_scratch:QI 3 "=X,X,&d"))]
1134   ""
1135   "*{
1136   if (which_alternative==0)
1137     return (AS2 (and,%A0,%A2) CR_TAB
1138             AS2 (and,%B0,%B2));
1139   else if (which_alternative==1)
1140     {
1141       if (GET_CODE (operands[2]) == CONST_INT)
1142         {
1143           int mask = INTVAL (operands[2]);
1144           if ((mask & 0xff) != 0xff)
1145             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1146           if ((mask & 0xff00) != 0xff00)
1147             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1148           return \"\";
1149         }
1150         return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1151                 AS2 (andi,%B0,hi8(%2)));
1152      }
1153   return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1154           AS2 (and,%A0,%3)     CR_TAB
1155           AS1 (clr,%B0));
1156 }"
1157   [(set_attr "length" "2,2,3")
1158    (set_attr "cc" "set_n,clobber,set_n")])
1159
1160 (define_insn "andsi3"
1161   [(set (match_operand:SI 0 "register_operand" "=r,d")
1162         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1163                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1164   ""
1165   "*{
1166   if (which_alternative==0)
1167     return (AS2 (and, %0,%2)   CR_TAB
1168             AS2 (and, %B0,%B2) CR_TAB
1169             AS2 (and, %C0,%C2) CR_TAB
1170             AS2 (and, %D0,%D2));
1171   else if (which_alternative==1)
1172     {
1173       if (GET_CODE (operands[2]) == CONST_INT)
1174         {
1175           HOST_WIDE_INT mask = INTVAL (operands[2]);
1176           if ((mask & 0xff) != 0xff)
1177             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1178           if ((mask & 0xff00) != 0xff00)
1179             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1180           if ((mask & 0xff0000L) != 0xff0000L)
1181             output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1182           if ((mask & 0xff000000L) != 0xff000000L)
1183             output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1184           return \"\";
1185         }
1186       return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1187               AS2 (andi, %B0,hi8(%2)) CR_TAB
1188               AS2 (andi, %C0,hlo8(%2)) CR_TAB
1189               AS2 (andi, %D0,hhi8(%2)));
1190     }
1191   return \"bug\";
1192 }"
1193   [(set_attr "length" "4,4")
1194    (set_attr "cc" "set_n,set_n")])
1195
1196 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1197 ;; ior
1198
1199 (define_insn "iorqi3"
1200   [(set (match_operand:QI 0 "register_operand" "=r,d")
1201         (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1202                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1203   ""
1204   "@
1205         or %0,%2
1206         ori %0,lo8(%2)"
1207   [(set_attr "length" "1,1")
1208    (set_attr "cc" "set_zn,set_zn")])
1209
1210 (define_insn "iorhi3"
1211   [(set (match_operand:HI 0 "register_operand" "=r,d")
1212         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1213                 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1214   ""
1215   "*{
1216   if (which_alternative==0)
1217     return (AS2 (or,%A0,%A2) CR_TAB
1218             AS2 (or,%B0,%B2));
1219   if (GET_CODE (operands[2]) == CONST_INT)
1220      {
1221         int mask = INTVAL (operands[2]);
1222         if (mask & 0xff)
1223           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1224         if (mask & 0xff00)
1225           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1226         return \"\";
1227       }
1228    return (AS2 (ori,%0,lo8(%2)) CR_TAB
1229            AS2 (ori,%B0,hi8(%2)));
1230 }"  
1231   [(set_attr "length" "2,2")
1232    (set_attr "cc" "set_n,clobber")])
1233
1234 (define_insn "*iorhi3_clobber"
1235   [(set (match_operand:HI 0 "register_operand" "=r,r")
1236         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1237                 (match_operand:HI 2 "immediate_operand" "M,i")))
1238    (clobber (match_scratch:QI 3 "=&d,&d"))]
1239   ""
1240   "@
1241         ldi %3,lo8(%2)\;or %A0,%3
1242         ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1243   [(set_attr "length" "2,4")
1244    (set_attr "cc" "clobber,set_n")])
1245
1246 (define_insn "iorsi3"
1247   [(set (match_operand:SI 0 "register_operand"        "=r,d")
1248         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1249                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1250   ""
1251   "*{
1252   if (which_alternative==0)
1253     return (AS2 (or, %0,%2)   CR_TAB
1254             AS2 (or, %B0,%B2) CR_TAB
1255             AS2 (or, %C0,%C2) CR_TAB
1256             AS2 (or, %D0,%D2));
1257   if (GET_CODE (operands[2]) == CONST_INT)
1258      {
1259         HOST_WIDE_INT mask = INTVAL (operands[2]);
1260         if (mask & 0xff)
1261           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1262         if (mask & 0xff00)
1263           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1264         if (mask & 0xff0000L)
1265           output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1266         if (mask & 0xff000000L)
1267           output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1268         return \"\";
1269       }
1270   return (AS2 (ori, %A0,lo8(%2))  CR_TAB
1271           AS2 (ori, %B0,hi8(%2)) CR_TAB
1272           AS2 (ori, %C0,hlo8(%2)) CR_TAB
1273           AS2 (ori, %D0,hhi8(%2)));
1274 }"
1275   [(set_attr "length" "4,4")
1276    (set_attr "cc" "set_n,clobber")])
1277
1278 (define_insn "*iorsi3_clobber"
1279   [(set (match_operand:SI 0 "register_operand"        "=r,r")
1280         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1281                 (match_operand:SI 2 "immediate_operand" "M,i")))
1282    (clobber (match_scratch:QI 3 "=&d,&d"))]
1283   ""
1284   "@
1285         ldi %3,lo8(%2)\;or %A0,%3
1286         ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3\;ldi %3,hlo8(%2)\;or %C0,%3\;ldi %3,hhi8(%2)\;or %D0,%3"
1287   [(set_attr "length" "2,8")
1288    (set_attr "cc" "clobber,set_n")])
1289
1290 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1291 ;; xor
1292
1293 (define_insn "xorqi3"
1294   [(set (match_operand:QI 0 "register_operand" "=r")
1295         (xor:QI (match_operand:QI 1 "register_operand" "%0")
1296                 (match_operand:QI 2 "register_operand" "r")))]
1297   ""
1298   "eor %0,%2"
1299   [(set_attr "length" "1")
1300    (set_attr "cc" "set_zn")])
1301
1302 (define_insn "xorhi3"
1303   [(set (match_operand:HI 0 "register_operand" "=r")
1304         (xor:HI (match_operand:HI 1 "register_operand" "%0")
1305                 (match_operand:HI 2 "register_operand" "r")))]
1306   ""
1307   "eor %0,%2
1308         eor %B0,%B2"
1309   [(set_attr "length" "2")
1310    (set_attr "cc" "set_n")])
1311
1312 (define_insn "xorsi3"
1313   [(set (match_operand:SI 0 "register_operand" "=r")
1314         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1315                 (match_operand:SI 2 "register_operand" "r")))]
1316   ""
1317   "eor %0,%2
1318         eor %B0,%B2
1319         eor %C0,%C2
1320         eor %D0,%D2"
1321   [(set_attr "length" "4")
1322    (set_attr "cc" "set_n")])
1323
1324 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1325 ;; arithmetic shift left
1326
1327 (define_insn "ashlqi3"
1328   [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
1329         (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1330                    (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1331   ""
1332   "* return ashlqi3_out (insn, operands, NULL);"
1333   [(set_attr "length" "5,0,1,2,4,6,9")
1334    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1335
1336 (define_insn "ashlhi3"
1337   [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
1338         (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1339                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1340   ""
1341   "* return ashlhi3_out (insn, operands, NULL);"
1342   [(set_attr "length" "6,0,2,2,4,10,10")
1343    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1344
1345 (define_insn "ashlsi3"
1346   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
1347         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1348                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1349   ""
1350   "* return ashlsi3_out (insn, operands, NULL);"
1351   [(set_attr "length" "8,0,4,4,8,10,12")
1352    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1353
1354 ;; Optimize if a scratch register from LD_REGS happens to be available.
1355
1356 (define_peephole2
1357   [(match_scratch:QI 3 "d")
1358    (set (match_operand:HI 0 "register_operand" "")
1359         (ashift:HI (match_operand:HI 1 "register_operand" "")
1360                    (match_operand:QI 2 "const_int_operand" "")))]
1361   ""
1362   [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1363               (clobber (match_dup 3))])]
1364   "if (!avr_peep2_scratch_safe (operands[3]))
1365      FAIL;")
1366
1367 (define_insn "*ashlhi3_const"
1368   [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
1369         (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1370                    (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1371    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1372   "reload_completed"
1373   "* return ashlhi3_out (insn, operands, NULL);"
1374   [(set_attr "length" "0,2,2,4,10")
1375    (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1376
1377 (define_peephole2
1378   [(match_scratch:QI 3 "d")
1379    (set (match_operand:SI 0 "register_operand" "")
1380         (ashift:SI (match_operand:SI 1 "register_operand" "")
1381                    (match_operand:QI 2 "const_int_operand" "")))]
1382   ""
1383   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1384               (clobber (match_dup 3))])]
1385   "if (!avr_peep2_scratch_safe (operands[3]))
1386      FAIL;")
1387
1388 (define_insn "*ashlsi3_const"
1389   [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
1390         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1391                    (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1392    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1393   "reload_completed"
1394   "* return ashlsi3_out (insn, operands, NULL);"
1395   [(set_attr "length" "0,4,4,10")
1396    (set_attr "cc" "none,set_n,clobber,clobber")])
1397
1398 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1399 ;; arithmetic shift right
1400
1401 (define_insn "ashrqi3"
1402   [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1403         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1404                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
1405   ""
1406   "* return ashrqi3_out (insn, operands, NULL);"
1407   [(set_attr "length" "5,0,1,2,5,9")
1408    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1409
1410 (define_insn "ashrhi3"
1411   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1412         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1413                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1414   ""
1415   "* return ashrhi3_out (insn, operands, NULL);"
1416   [(set_attr "length" "6,0,2,4,4,10,10")
1417    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1418
1419 (define_insn "ashrsi3"
1420   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1421         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1422                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1423   ""
1424   "* return ashrsi3_out (insn, operands, NULL);"
1425   [(set_attr "length" "8,0,4,6,8,10,12")
1426    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1427
1428 ;; Optimize if a scratch register from LD_REGS happens to be available.
1429
1430 (define_peephole2
1431   [(match_scratch:QI 3 "d")
1432    (set (match_operand:HI 0 "register_operand" "")
1433         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1434                      (match_operand:QI 2 "const_int_operand" "")))]
1435   ""
1436   [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1437               (clobber (match_dup 3))])]
1438   "if (!avr_peep2_scratch_safe (operands[3]))
1439      FAIL;")
1440
1441 (define_insn "*ashrhi3_const"
1442   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1443         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1444                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1445    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1446   "reload_completed"
1447   "* return ashrhi3_out (insn, operands, NULL);"
1448   [(set_attr "length" "0,2,4,4,10")
1449    (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1450
1451 (define_peephole2
1452   [(match_scratch:QI 3 "d")
1453    (set (match_operand:SI 0 "register_operand" "")
1454         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1455                      (match_operand:QI 2 "const_int_operand" "")))]
1456   ""
1457   [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1458               (clobber (match_dup 3))])]
1459   "if (!avr_peep2_scratch_safe (operands[3]))
1460      FAIL;")
1461
1462 (define_insn "*ashrsi3_const"
1463   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1464         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1465                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1466    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1467   "reload_completed"
1468   "* return ashrsi3_out (insn, operands, NULL);"
1469   [(set_attr "length" "0,4,4,10")
1470    (set_attr "cc" "none,clobber,set_n,clobber")])
1471
1472 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1473 ;; logical shift right
1474
1475 (define_insn "lshrqi3"
1476   [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
1477         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1478                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1479   ""
1480   "* return lshrqi3_out (insn, operands, NULL);"
1481   [(set_attr "length" "5,0,1,2,4,6,9")
1482    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1483
1484 (define_insn "lshrhi3"
1485   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1486         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1487                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1488   ""
1489   "* return lshrhi3_out (insn, operands, NULL);"
1490   [(set_attr "length" "6,0,2,2,4,10,10")
1491    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1492
1493 (define_insn "lshrsi3"
1494   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1495         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1496                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1497   ""
1498   "* return lshrsi3_out (insn, operands, NULL);"
1499   [(set_attr "length" "8,0,4,4,8,10,12")
1500    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1501
1502 ;; Optimize if a scratch register from LD_REGS happens to be available.
1503
1504 (define_peephole2
1505   [(match_scratch:QI 3 "d")
1506    (set (match_operand:HI 0 "register_operand" "")
1507         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1508                      (match_operand:QI 2 "const_int_operand" "")))]
1509   ""
1510   [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1511               (clobber (match_dup 3))])]
1512   "if (!avr_peep2_scratch_safe (operands[3]))
1513      FAIL;")
1514
1515 (define_insn "*lshrhi3_const"
1516   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1517         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1518                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1519    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1520   "reload_completed"
1521   "* return lshrhi3_out (insn, operands, NULL);"
1522   [(set_attr "length" "0,2,2,4,10")
1523    (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1524
1525 (define_peephole2
1526   [(match_scratch:QI 3 "d")
1527    (set (match_operand:SI 0 "register_operand" "")
1528         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1529                      (match_operand:QI 2 "const_int_operand" "")))]
1530   ""
1531   [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1532               (clobber (match_dup 3))])]
1533   "if (!avr_peep2_scratch_safe (operands[3]))
1534      FAIL;")
1535
1536 (define_insn "*lshrsi3_const"
1537   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1538         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1539                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1540    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1541   "reload_completed"
1542   "* return lshrsi3_out (insn, operands, NULL);"
1543   [(set_attr "length" "0,4,4,10")
1544    (set_attr "cc" "none,clobber,clobber,clobber")])
1545
1546 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1547 ;; abs
1548
1549 (define_insn "absqi2"
1550   [(set (match_operand:QI 0 "register_operand" "=r")
1551         (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1552   ""
1553   "sbrc %0,7
1554         neg %0"
1555   [(set_attr "length" "2")
1556    (set_attr "cc" "clobber")])
1557
1558
1559 (define_insn "abssf2"
1560   [(set (match_operand:SF 0 "register_operand" "=d,r")
1561         (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1562   ""
1563   "@
1564         andi %D0,0x7f
1565         clt\;bld %D0,7"
1566   [(set_attr "length" "1,2")
1567    (set_attr "cc" "set_n,clobber")])
1568
1569 ;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
1570 ;; neg
1571
1572 (define_insn "negqi2"
1573   [(set (match_operand:QI 0 "register_operand" "=r")
1574         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1575   ""
1576   "neg %0"
1577   [(set_attr "length" "1")
1578    (set_attr "cc" "set_zn")])
1579
1580 (define_insn "neghi2"
1581   [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
1582         (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1583   ""
1584   "@
1585         com %B0\;neg %A0\;sbci %B0,lo8(-1)
1586         com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1587         clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1588   [(set_attr "length" "3,4,4")
1589    (set_attr "cc" "set_czn,set_n,set_czn")])
1590
1591 (define_insn "negsi2"
1592   [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
1593         (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1594   ""
1595   "@
1596         com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1597         com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1598         clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1599   [(set_attr_alternative "length"
1600                          [(const_int 7)
1601                           (const_int 8)
1602                           (if_then_else (eq_attr "mcu_have_movw" "yes")
1603                                         (const_int 7)
1604                                         (const_int 8))])
1605    (set_attr "cc" "set_czn,set_n,set_czn")])
1606
1607 (define_insn "negsf2"
1608   [(set (match_operand:SF 0 "register_operand" "=d,r")
1609         (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1610   ""
1611   "@
1612         subi %D0,0x80
1613         bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1614   [(set_attr "length" "1,4")
1615    (set_attr "cc" "set_n,set_n")])
1616
1617 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1618 ;; not
1619
1620 (define_insn "one_cmplqi2"
1621   [(set (match_operand:QI 0 "register_operand" "=r")
1622         (not:QI (match_operand:QI 1 "register_operand" "0")))]
1623   ""
1624   "com %0"
1625   [(set_attr "length" "1")
1626    (set_attr "cc" "set_czn")])
1627
1628 (define_insn "one_cmplhi2"
1629   [(set (match_operand:HI 0 "register_operand" "=r")
1630         (not:HI (match_operand:HI 1 "register_operand" "0")))]
1631   ""
1632   "com %0
1633         com %B0"
1634   [(set_attr "length" "2")
1635    (set_attr "cc" "set_n")])
1636
1637 (define_insn "one_cmplsi2"
1638   [(set (match_operand:SI 0 "register_operand" "=r")
1639         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1640   ""
1641   "com %0
1642         com %B0
1643         com %C0
1644         com %D0"
1645   [(set_attr "length" "4")
1646    (set_attr "cc" "set_n")])
1647
1648 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1649 ;; sign extend
1650
1651 (define_insn "extendqihi2"
1652   [(set (match_operand:HI 0 "register_operand" "=r,r")
1653         (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
1654   ""
1655   "@
1656         clr %B0\;sbrc %0,7\;com %B0
1657         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
1658   [(set_attr "length" "3,4")
1659    (set_attr "cc" "set_n,set_n")])
1660
1661 (define_insn "extendqisi2"
1662   [(set (match_operand:SI 0 "register_operand" "=r,r")
1663         (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
1664   ""
1665   "@
1666         clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
1667         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
1668   [(set_attr "length" "5,6")
1669    (set_attr "cc" "set_n,set_n")])
1670
1671 (define_insn "extendhisi2"
1672   [(set (match_operand:SI 0 "register_operand"               "=r,&r")
1673         (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
1674   ""
1675   "@
1676         clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
1677         {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
1678   [(set_attr_alternative "length"
1679                          [(const_int 4)
1680                           (if_then_else (eq_attr "mcu_have_movw" "yes")
1681                                         (const_int 5)
1682                                         (const_int 6))])
1683    (set_attr "cc" "set_n,set_n")])
1684
1685 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
1686 ;; zero extend
1687
1688 (define_insn_and_split "zero_extendqihi2"
1689   [(set (match_operand:HI 0 "register_operand" "=r")
1690         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1691   ""
1692   "#"
1693   "reload_completed"
1694   [(set (match_dup 2) (match_dup 1))
1695    (set (match_dup 3) (const_int 0))]
1696   "unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
1697    unsigned int high_off = subreg_highpart_offset (QImode, HImode);
1698    
1699    operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
1700    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
1701   ")
1702
1703 (define_insn_and_split "zero_extendqisi2"
1704   [(set (match_operand:SI 0 "register_operand" "=r")
1705         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1706   ""
1707   "#"
1708   "reload_completed"
1709   [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
1710    (set (match_dup 3) (const_int 0))]
1711   "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
1712    unsigned int high_off = subreg_highpart_offset (HImode, SImode);
1713    
1714    operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
1715    operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
1716   ")
1717
1718 (define_insn_and_split "zero_extendhisi2"
1719   [(set (match_operand:SI 0 "register_operand" "=r")
1720         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1721   ""
1722   "#"
1723   "reload_completed"
1724   [(set (match_dup 2) (match_dup 1))
1725    (set (match_dup 3) (const_int 0))]
1726   "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
1727    unsigned int high_off = subreg_highpart_offset (HImode, SImode);
1728    
1729    operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
1730    operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
1731   ")
1732
1733 (define_insn_and_split "zero_extendqidi2"
1734   [(set (match_operand:DI 0 "register_operand" "=r")
1735         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1736   ""
1737   "#"
1738   "reload_completed"
1739   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
1740    (set (match_dup 3) (const_int 0))]
1741   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
1742    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
1743    
1744    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
1745    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
1746   ")
1747
1748 (define_insn_and_split "zero_extendhidi2"
1749   [(set (match_operand:DI 0 "register_operand" "=r")
1750         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1751   ""
1752   "#"
1753   "reload_completed"
1754   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
1755    (set (match_dup 3) (const_int 0))]
1756   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
1757    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
1758    
1759    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
1760    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
1761   ")
1762
1763 (define_insn_and_split "zero_extendsidi2"
1764   [(set (match_operand:DI 0 "register_operand" "=r")
1765         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1766   ""
1767   "#"
1768   "reload_completed"
1769   [(set (match_dup 2) (match_dup 1))
1770    (set (match_dup 3) (const_int 0))]
1771   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
1772    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
1773    
1774    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
1775    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
1776   ")
1777
1778 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
1779 ;; compare
1780
1781 (define_insn "tstqi"
1782   [(set (cc0)
1783         (match_operand:QI 0 "register_operand" "r"))]
1784   ""
1785   "tst %0"
1786   [(set_attr "cc" "compare")
1787    (set_attr "length" "1")])
1788
1789 (define_insn "*negated_tstqi"
1790   [(set (cc0)
1791         (neg:QI (match_operand:QI 0 "register_operand" "r")))]
1792   ""
1793   "cp __zero_reg__,%0"
1794   [(set_attr "cc" "compare")
1795    (set_attr "length" "1")])
1796
1797 (define_insn "tsthi"
1798   [(set (cc0)
1799         (match_operand:HI 0 "register_operand" "!w,r"))]
1800   ""
1801   "* return out_tsthi (insn,NULL);"
1802 [(set_attr "cc" "compare,compare")
1803  (set_attr "length" "1,2")])
1804
1805 (define_insn "*negated_tsthi"
1806   [(set (cc0)
1807         (neg:HI (match_operand:HI 0 "register_operand" "r")))]
1808   ""
1809   "cp __zero_reg__,%A0
1810         cpc __zero_reg__,%B0"
1811 [(set_attr "cc" "compare")
1812  (set_attr "length" "2")])
1813
1814 (define_insn "tstsi"
1815   [(set (cc0)
1816         (match_operand:SI 0 "register_operand" "r"))]
1817   ""
1818   "* return out_tstsi (insn,NULL);"
1819   [(set_attr "cc" "compare")
1820    (set_attr "length" "4")])
1821
1822 (define_insn "*negated_tstsi"
1823   [(set (cc0)
1824         (neg:SI (match_operand:SI 0 "register_operand" "r")))]
1825   ""
1826   "cp __zero_reg__,%A0
1827         cpc __zero_reg__,%B0
1828         cpc __zero_reg__,%C0
1829         cpc __zero_reg__,%D0"
1830   [(set_attr "cc" "compare")
1831    (set_attr "length" "4")])
1832
1833
1834 (define_insn "cmpqi"
1835   [(set (cc0)
1836         (compare (match_operand:QI 0 "register_operand"  "r,d")
1837                  (match_operand:QI 1 "nonmemory_operand" "r,i")))]
1838   ""
1839   "@
1840         cp %0,%1
1841         cpi %0,lo8(%1)"
1842   [(set_attr "cc" "compare,compare")
1843    (set_attr "length" "1,1")])
1844
1845 (define_insn "*cmpqi_sign_extend"
1846   [(set (cc0)
1847         (compare (sign_extend:HI
1848                   (match_operand:QI 0 "register_operand"  "d"))
1849                  (match_operand:HI 1 "const_int_operand" "n")))]
1850   "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
1851   "cpi %0,lo8(%1)"
1852   [(set_attr "cc" "compare")
1853    (set_attr "length" "1")])
1854
1855 (define_insn "cmphi"
1856   [(set (cc0)
1857         (compare (match_operand:HI 0 "register_operand"  "r,d,d,r,r")
1858                  (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
1859    (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1860   ""
1861   "*{
1862   switch (which_alternative)
1863     {
1864     case 0:
1865       return (AS2 (cp,%A0,%A1) CR_TAB
1866               AS2 (cpc,%B0,%B1));
1867     case 1:
1868       if (reg_unused_after (insn, operands[0])
1869           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1870           && test_hard_reg_class (ADDW_REGS, operands[0]))
1871         return AS2 (sbiw,%0,%1);
1872        else
1873         return (AS2 (cpi,%0,%1) CR_TAB
1874                 AS2 (cpc,%B0,__zero_reg__));
1875     case 2:
1876       if (reg_unused_after (insn, operands[0]))
1877         return (AS2 (subi,%0,lo8(%1))  CR_TAB
1878                 AS2 (sbci,%B0,hi8(%1)));
1879       else
1880         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
1881                 AS2 (cpi, %A0,lo8(%1)) CR_TAB
1882                 AS2 (cpc, %B0,%2));
1883    case 3:
1884       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
1885               AS2 (cp, %A0,%2) CR_TAB
1886               AS2 (cpc, %B0,__zero_reg__));
1887
1888    case 4:
1889       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
1890               AS2 (cp, %A0,%2)       CR_TAB
1891               AS2 (ldi, %2,hi8(%1)) CR_TAB
1892               AS2 (cpc, %B0,%2));
1893     }
1894   return \"bug\";
1895 }" 
1896   [(set_attr "cc" "compare,compare,compare,compare,compare")
1897    (set_attr "length" "2,2,3,3,4")])
1898
1899
1900 (define_insn "cmpsi"
1901   [(set (cc0)
1902         (compare (match_operand:SI 0 "register_operand"  "r,d,d,r,r")
1903                  (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
1904    (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
1905   ""
1906   "*{
1907   switch (which_alternative)
1908     {
1909     case 0:
1910       return (AS2 (cp,%A0,%A1) CR_TAB
1911               AS2 (cpc,%B0,%B1) CR_TAB
1912               AS2 (cpc,%C0,%C1) CR_TAB
1913               AS2 (cpc,%D0,%D1));
1914     case 1:
1915       if (reg_unused_after (insn, operands[0])
1916           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
1917           && test_hard_reg_class (ADDW_REGS, operands[0]))
1918         return (AS2 (sbiw,%0,%1) CR_TAB
1919                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1920                 AS2 (cpc,%D0,__zero_reg__));
1921       else
1922         return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
1923                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1924                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1925                 AS2 (cpc,%D0,__zero_reg__));
1926     case 2:
1927       if (reg_unused_after (insn, operands[0]))
1928         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
1929                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
1930                 AS2 (sbci,%C0,hlo8(%1))  CR_TAB
1931                 AS2 (sbci,%D0,hhi8(%1)));
1932       else
1933        return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
1934                AS2 (ldi, %2,hi8(%1))  CR_TAB
1935                AS2 (cpc, %B0,%2)       CR_TAB
1936                AS2 (ldi, %2,hlo8(%1))  CR_TAB
1937                AS2 (cpc, %C0,%2)       CR_TAB
1938                AS2 (ldi, %2,hhi8(%1)) CR_TAB
1939                AS2 (cpc, %D0,%2));
1940     case 3:
1941         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
1942                 AS2 (cp,%A0,%2)            CR_TAB
1943                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
1944                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
1945                 AS2 (cpc,%D0,__zero_reg__));
1946     case 4:
1947        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
1948                AS2 (cp, %A0,%2)        CR_TAB
1949                AS2 (ldi, %2,hi8(%1))  CR_TAB
1950                AS2 (cpc, %B0,%2)       CR_TAB
1951                AS2 (ldi, %2,hlo8(%1))  CR_TAB
1952                AS2 (cpc, %C0,%2)       CR_TAB
1953                AS2 (ldi, %2,hhi8(%1)) CR_TAB
1954                AS2 (cpc, %D0,%2));
1955     }
1956   return \"bug\";
1957 }"
1958   [(set_attr "cc" "compare,compare,compare,compare,compare")
1959    (set_attr "length" "4,4,7,5,8")])
1960
1961 ;; ----------------------------------------------------------------------
1962 ;; JUMP INSTRUCTIONS
1963 ;; ----------------------------------------------------------------------
1964 ;; Conditional jump instructions
1965
1966 (define_expand "beq"
1967   [(set (pc)
1968         (if_then_else (eq (cc0) (const_int 0))
1969                       (label_ref (match_operand 0 "" ""))
1970                       (pc)))]
1971   ""
1972   "")
1973
1974 (define_expand "bne"
1975   [(set (pc)
1976         (if_then_else (ne (cc0) (const_int 0))
1977                       (label_ref (match_operand 0 "" ""))
1978                       (pc)))]
1979   ""
1980   "")
1981
1982 (define_expand "bge"
1983   [(set (pc)
1984         (if_then_else (ge (cc0) (const_int 0))
1985                       (label_ref (match_operand 0 "" ""))
1986                       (pc)))]
1987   ""
1988   "")
1989
1990 (define_expand "bgeu"
1991   [(set (pc)
1992         (if_then_else (geu (cc0) (const_int 0))
1993                       (label_ref (match_operand 0 "" ""))
1994                       (pc)))]
1995   ""
1996   "")
1997
1998 (define_expand "blt"
1999   [(set (pc)
2000         (if_then_else (lt (cc0) (const_int 0))
2001                       (label_ref (match_operand 0 "" ""))
2002                       (pc)))]
2003   ""
2004   "")
2005
2006 (define_expand "bltu"
2007   [(set (pc)
2008         (if_then_else (ltu (cc0) (const_int 0))
2009                       (label_ref (match_operand 0 "" ""))
2010                       (pc)))]
2011   ""
2012   "")
2013
2014
2015
2016 /****************************************************************
2017  AVR not have following conditional jumps: LE,LEU,GT,GTU.
2018  Convert them all to proper jumps.
2019 *****************************************************************/
2020
2021 (define_expand "ble"
2022   [(set (pc)
2023         (if_then_else (le (cc0) (const_int 0))
2024                       (label_ref (match_operand 0 "" ""))
2025                       (pc)))]
2026   ""
2027   "")
2028
2029 (define_expand "bleu"
2030   [(set (pc)
2031         (if_then_else (leu (cc0) (const_int 0))
2032                       (label_ref (match_operand 0 "" ""))
2033                       (pc)))]
2034   ""
2035   "")
2036
2037 (define_expand "bgt"
2038   [(set (pc)
2039         (if_then_else (gt (cc0) (const_int 0))
2040                       (label_ref (match_operand 0 "" ""))
2041                       (pc)))]
2042   ""
2043   "")
2044
2045 (define_expand "bgtu"
2046   [(set (pc)
2047         (if_then_else (gtu (cc0) (const_int 0))
2048                       (label_ref (match_operand 0 "" ""))
2049                       (pc)))]
2050   ""
2051   "")
2052
2053 ;; Test a single bit in a QI/HI/SImode register.
2054 (define_insn "*sbrx_branch"
2055   [(set (pc)
2056         (if_then_else
2057          (match_operator 0 "eqne_operator"
2058                          [(zero_extract
2059                            (match_operand:QI 1 "register_operand" "r")
2060                            (const_int 1)
2061                            (match_operand 2 "const_int_operand" "n"))
2062                           (const_int 0)])
2063          (label_ref (match_operand 3 "" ""))
2064          (pc)))]
2065   ""
2066   "* return avr_out_sbxx_branch (insn, operands);"
2067   [(set (attr "length")
2068         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2069                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2070                       (const_int 2)
2071                       (if_then_else (eq_attr "mcu_mega" "no")
2072                                     (const_int 2)
2073                                     (const_int 4))))
2074    (set_attr "cc" "clobber")])
2075
2076 (define_insn "*sbrx_and_branchhi"
2077   [(set (pc)
2078         (if_then_else
2079          (match_operator 0 "eqne_operator"
2080                          [(and:HI
2081                            (match_operand:HI 1 "register_operand" "r")
2082                            (match_operand:HI 2 "single_one_operand" "n"))
2083                           (const_int 0)])
2084          (label_ref (match_operand 3 "" ""))
2085          (pc)))]
2086   ""
2087   "* return avr_out_sbxx_branch (insn, operands);"
2088   [(set (attr "length")
2089         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2090                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2091                       (const_int 2)
2092                       (if_then_else (eq_attr "mcu_mega" "no")
2093                                     (const_int 2)
2094                                     (const_int 4))))
2095    (set_attr "cc" "clobber")])
2096
2097 (define_insn "*sbrx_and_branchsi"
2098   [(set (pc)
2099         (if_then_else
2100          (match_operator 0 "eqne_operator"
2101                          [(and:SI
2102                            (match_operand:SI 1 "register_operand" "r")
2103                            (match_operand:SI 2 "single_one_operand" "n"))
2104                           (const_int 0)])
2105          (label_ref (match_operand 3 "" ""))
2106          (pc)))]
2107   ""
2108   "* return avr_out_sbxx_branch (insn, operands);"
2109   [(set (attr "length")
2110         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2111                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2112                       (const_int 2)
2113                       (if_then_else (eq_attr "mcu_mega" "no")
2114                                     (const_int 2)
2115                                     (const_int 4))))
2116    (set_attr "cc" "clobber")])
2117
2118 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
2119 (define_peephole2
2120   [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2121    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2122                            (label_ref (match_operand 1 "" ""))
2123                            (pc)))]
2124   ""
2125   [(set (pc) (if_then_else (eq (zero_extract (match_dup 0)
2126                                              (const_int 1)
2127                                              (const_int 7))
2128                                (const_int 0))
2129                            (label_ref (match_dup 1))
2130                            (pc)))]
2131   "")
2132
2133 (define_peephole2
2134   [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2135    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2136                            (label_ref (match_operand 1 "" ""))
2137                            (pc)))]
2138   ""
2139   [(set (pc) (if_then_else (ne (zero_extract (match_dup 0)
2140                                              (const_int 1)
2141                                              (const_int 7))
2142                                (const_int 0))
2143                            (label_ref (match_dup 1))
2144                            (pc)))]
2145   "")
2146
2147 (define_peephole2
2148   [(set (cc0) (match_operand:HI 0 "register_operand" ""))
2149    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2150                            (label_ref (match_operand 1 "" ""))
2151                            (pc)))]
2152   ""
2153   [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
2154                                (const_int 0))
2155                            (label_ref (match_dup 1))
2156                            (pc)))]
2157   "")
2158
2159 (define_peephole2
2160   [(set (cc0) (match_operand:HI 0 "register_operand" ""))
2161    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2162                            (label_ref (match_operand 1 "" ""))
2163                            (pc)))]
2164   ""
2165   [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
2166                                (const_int 0))
2167                            (label_ref (match_dup 1))
2168                            (pc)))]
2169   "")
2170
2171 (define_peephole2
2172   [(set (cc0) (match_operand:SI 0 "register_operand" ""))
2173    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2174                            (label_ref (match_operand 1 "" ""))
2175                            (pc)))]
2176   ""
2177   [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
2178                                (const_int 0))
2179                            (label_ref (match_dup 1))
2180                            (pc)))]
2181   "operands[2] = GEN_INT (-2147483647 - 1);")
2182
2183 (define_peephole2
2184   [(set (cc0) (match_operand:SI 0 "register_operand" ""))
2185    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2186                            (label_ref (match_operand 1 "" ""))
2187                            (pc)))]
2188   ""
2189   [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
2190                                (const_int 0))
2191                            (label_ref (match_dup 1))
2192                            (pc)))]
2193   "operands[2] = GEN_INT (-2147483647 - 1);")
2194
2195 ;; ************************************************************************
2196 ;; Implementation of conditional jumps here.
2197 ;;  Compare with 0 (test) jumps
2198 ;; ************************************************************************
2199
2200 (define_insn "branch"
2201   [(set (pc)
2202         (if_then_else (match_operator 1 "simple_comparison_operator"
2203                         [(cc0)
2204                          (const_int 0)])
2205                       (label_ref (match_operand 0 "" ""))
2206                       (pc)))]
2207   ""
2208   "*
2209    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2210   [(set_attr "type" "branch")
2211    (set_attr "cc" "clobber")])
2212
2213 (define_insn "difficult_branch"
2214   [(set (pc)
2215         (if_then_else (match_operator 1 "difficult_comparison_operator"
2216                         [(cc0)
2217                          (const_int 0)])
2218                       (label_ref (match_operand 0 "" ""))
2219                       (pc)))]
2220   ""
2221   "*
2222    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2223   [(set_attr "type" "branch1")
2224    (set_attr "cc" "clobber")])
2225
2226 ;; revers branch
2227
2228 (define_insn "rvbranch"
2229   [(set (pc)
2230         (if_then_else (match_operator 1 "simple_comparison_operator" 
2231                         [(cc0)
2232                          (const_int 0)])
2233                       (pc)
2234                       (label_ref (match_operand 0 "" ""))))]
2235   ""
2236   "*
2237    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2238   [(set_attr "type" "branch1")
2239    (set_attr "cc" "clobber")])
2240
2241 (define_insn "difficult_rvbranch"
2242   [(set (pc)
2243         (if_then_else (match_operator 1 "difficult_comparison_operator" 
2244                         [(cc0)
2245                          (const_int 0)])
2246                       (pc)
2247                       (label_ref (match_operand 0 "" ""))))]
2248   ""
2249   "*
2250    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2251   [(set_attr "type" "branch")
2252    (set_attr "cc" "clobber")])
2253
2254 ;; **************************************************************************
2255 ;; Unconditional and other jump instructions.
2256
2257 (define_insn "jump"
2258   [(set (pc)
2259         (label_ref (match_operand 0 "" "")))]
2260   ""
2261   "*{
2262   if (AVR_MEGA && get_attr_length (insn) != 1)
2263     return AS1 (jmp,%0);
2264   return AS1 (rjmp,%0);
2265 }"
2266   [(set (attr "length")
2267         (if_then_else (match_operand 0 "symbol_ref_operand" "") 
2268                 (if_then_else (eq_attr "mcu_mega" "no")
2269                               (const_int 1)
2270                               (const_int 2))
2271                 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2272                                    (le (minus (pc) (match_dup 0)) (const_int 2047)))
2273                               (const_int 1)
2274                               (const_int 2))))
2275    (set_attr "cc" "none")])
2276
2277 ;; call
2278
2279 (define_expand "call"
2280   [(call (match_operand:HI 0 "call_insn_operand" "")
2281          (match_operand:HI 1 "general_operand" ""))]
2282   ;; Operand 1 not used on the AVR.
2283   ""
2284   "")
2285
2286 ;; call value
2287
2288 (define_expand "call_value"
2289   [(set (match_operand 0 "register_operand" "")
2290         (call (match_operand:HI 1 "call_insn_operand" "")
2291               (match_operand:HI 2 "general_operand" "")))]
2292   ;; Operand 2 not used on the AVR.
2293   ""
2294   "")
2295
2296 (define_insn "call_insn"
2297   [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2298          (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2299 ;; We don't need in saving Z register because r30,r31 is a call used registers
2300   ;; Operand 1 not used on the AVR.
2301   "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2302   "*{
2303   if (which_alternative==0)
2304      return \"icall\";
2305   else if (which_alternative==1)
2306     {
2307       if (AVR_HAVE_MOVW)
2308         return (AS2 (movw, r30, %0) CR_TAB
2309                 \"icall\");
2310       else
2311         return (AS2 (mov, r30, %A0) CR_TAB
2312                 AS2 (mov, r31, %B0) CR_TAB
2313                 \"icall\");
2314     }
2315   else if (which_alternative==2)
2316     return AS1(%~call,%c0);
2317   return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2318           AS2 (ldi,r31,hi8(%0)) CR_TAB
2319           \"icall\");
2320 }"
2321   [(set_attr "cc" "clobber,clobber,clobber,clobber")
2322    (set_attr_alternative "length"
2323                          [(const_int 1)
2324                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2325                                         (const_int 2)
2326                                         (const_int 3))
2327                           (if_then_else (eq_attr "mcu_mega" "yes")
2328                                         (const_int 2)
2329                                         (const_int 1))
2330                           (const_int 3)])])
2331
2332 (define_insn "call_value_insn"
2333   [(set (match_operand 0 "register_operand" "=r,r,r,r")
2334         (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2335 ;; We don't need in saving Z register because r30,r31 is a call used registers
2336               (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2337   ;; Operand 2 not used on the AVR.
2338   "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2339   "*{
2340   if (which_alternative==0)
2341      return \"icall\";
2342   else if (which_alternative==1)
2343     {
2344       if (AVR_HAVE_MOVW)
2345         return (AS2 (movw, r30, %1) CR_TAB
2346                 \"icall\");
2347       else
2348         return (AS2 (mov, r30, %A1) CR_TAB
2349                 AS2 (mov, r31, %B1) CR_TAB
2350                 \"icall\");
2351     }
2352   else if (which_alternative==2)
2353     return AS1(%~call,%c1);
2354   return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2355           AS2 (ldi, r31, hi8(%1)) CR_TAB
2356           \"icall\");
2357 }"
2358   [(set_attr "cc" "clobber,clobber,clobber,clobber")
2359    (set_attr_alternative "length"
2360                          [(const_int 1)
2361                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2362                                         (const_int 2)
2363                                         (const_int 3))
2364                           (if_then_else (eq_attr "mcu_mega" "yes")
2365                                         (const_int 2)
2366                                         (const_int 1))
2367                           (const_int 3)])])
2368
2369 (define_insn "nop"
2370   [(const_int 0)]
2371   ""
2372   "nop"
2373   [(set_attr "cc" "none")
2374    (set_attr "length" "1")])
2375
2376 ; indirect jump
2377 (define_insn "indirect_jump"
2378   [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2379   ""
2380   "@
2381         ijmp
2382         push %A0\;push %B0\;ret"
2383   [(set_attr "length" "1,3")
2384    (set_attr "cc" "none,none")])
2385
2386 ;; table jump
2387
2388 ;; Table made from "rjmp" instructions for <=8K devices.
2389 (define_insn "*tablejump_rjmp"
2390   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2391                         UNSPEC_INDEX_JMP))
2392    (use (label_ref (match_operand 1 "" "")))
2393    (clobber (match_dup 0))]
2394   "!AVR_MEGA"
2395   "@
2396         ijmp
2397         push %A0\;push %B0\;ret"
2398   [(set_attr "length" "1,3")
2399    (set_attr "cc" "none,none")])
2400
2401 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2402 (define_insn "*tablejump_lib"
2403   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2404                         UNSPEC_INDEX_JMP))
2405    (use (label_ref (match_operand 1 "" "")))
2406    (clobber (match_dup 0))]
2407   "AVR_MEGA && TARGET_CALL_PROLOGUES"
2408   "jmp __tablejump2__"
2409   [(set_attr "length" "2")
2410    (set_attr "cc" "clobber")])
2411
2412 (define_insn "*tablejump_enh"
2413   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2414                         UNSPEC_INDEX_JMP))
2415    (use (label_ref (match_operand 1 "" "")))
2416    (clobber (match_dup 0))]
2417   "AVR_MEGA && AVR_HAVE_LPMX"
2418   "lsl r30
2419         rol r31
2420         lpm __tmp_reg__,Z+
2421         lpm r31,Z
2422         mov r30,__tmp_reg__
2423         ijmp"
2424   [(set_attr "length" "6")
2425    (set_attr "cc" "clobber")])
2426
2427 (define_insn "*tablejump"
2428   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2429                         UNSPEC_INDEX_JMP))
2430    (use (label_ref (match_operand 1 "" "")))
2431    (clobber (match_dup 0))]
2432   "AVR_MEGA"
2433   "lsl r30
2434         rol r31
2435         lpm
2436         inc r30
2437         push r0
2438         lpm
2439         push r0
2440         ret"
2441   [(set_attr "length" "8")
2442    (set_attr "cc" "clobber")])
2443
2444 (define_expand "casesi"
2445   [(set (match_dup 6)
2446         (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2447                   (match_operand:HI 1 "register_operand" "")))
2448    (parallel [(set (cc0)
2449                    (compare (match_dup 6)
2450                             (match_operand:HI 2 "register_operand" "")))
2451               (clobber (match_scratch:QI 9 ""))])
2452    
2453    (set (pc)
2454         (if_then_else (gtu (cc0)
2455                            (const_int 0))
2456                       (label_ref (match_operand 4 "" ""))
2457                       (pc)))
2458
2459    (set (match_dup 6)
2460         (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2461
2462    (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2463               (use (label_ref (match_dup 3)))
2464               (clobber (match_dup 6))])]
2465   ""
2466   "
2467 {
2468   operands[6] = gen_reg_rtx (HImode);
2469 }")
2470
2471
2472 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2473 ;; This instruction sets Z flag
2474
2475 (define_insn "sez"
2476   [(set (cc0) (const_int 0))]
2477   ""
2478   "sez"
2479   [(set_attr "length" "1")
2480    (set_attr "cc" "compare")])
2481
2482 ;; Clear/set/test a single bit in I/O address space.
2483
2484 (define_insn "*cbi"
2485   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2486         (and:QI (mem:QI (match_dup 0))
2487                 (match_operand:QI 1 "single_zero_operand" "n")))]
2488   "(optimize > 0)"
2489 {
2490   operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2491   return AS2 (cbi,%0-0x20,%2);
2492 }
2493   [(set_attr "length" "1")
2494    (set_attr "cc" "none")])
2495
2496 (define_insn "*sbi"
2497   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2498         (ior:QI (mem:QI (match_dup 0))
2499                 (match_operand:QI 1 "single_one_operand" "n")))]
2500   "(optimize > 0)"
2501 {
2502   operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2503   return AS2 (sbi,%0-0x20,%2);
2504 }
2505   [(set_attr "length" "1")
2506    (set_attr "cc" "none")])
2507
2508 ;; Lower half of the I/O space - use sbic/sbis directly.
2509 (define_insn "*sbix_branch"
2510   [(set (pc)
2511         (if_then_else
2512          (match_operator 0 "eqne_operator"
2513                          [(zero_extract
2514                            (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2515                            (const_int 1)
2516                            (match_operand 2 "const_int_operand" "n"))
2517                           (const_int 0)])
2518          (label_ref (match_operand 3 "" ""))
2519          (pc)))]
2520   "(optimize > 0)"
2521   "* return avr_out_sbxx_branch (insn, operands);"
2522   [(set (attr "length")
2523         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2524                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2525                       (const_int 2)
2526                       (if_then_else (eq_attr "mcu_mega" "no")
2527                                     (const_int 2)
2528                                     (const_int 4))))
2529    (set_attr "cc" "clobber")])
2530
2531 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2532 (define_insn "*sbix_branch_bit7"
2533   [(set (pc)
2534         (if_then_else
2535          (match_operator 0 "gelt_operator"
2536                          [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2537                           (const_int 0)])
2538          (label_ref (match_operand 2 "" ""))
2539          (pc)))]
2540   "(optimize > 0)"
2541 {
2542   operands[3] = operands[2];
2543   operands[2] = GEN_INT (7);
2544   return avr_out_sbxx_branch (insn, operands);
2545 }
2546   [(set (attr "length")
2547         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2548                            (le (minus (pc) (match_dup 2)) (const_int 2046)))
2549                       (const_int 2)
2550                       (if_then_else (eq_attr "mcu_mega" "no")
2551                                     (const_int 2)
2552                                     (const_int 4))))
2553    (set_attr "cc" "clobber")])
2554
2555 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2556 (define_insn "*sbix_branch_tmp"
2557   [(set (pc)
2558         (if_then_else
2559          (match_operator 0 "eqne_operator"
2560                          [(zero_extract
2561                            (mem:QI (match_operand 1 "high_io_address_operand" "n"))
2562                            (const_int 1)
2563                            (match_operand 2 "const_int_operand" "n"))
2564                           (const_int 0)])
2565          (label_ref (match_operand 3 "" ""))
2566          (pc)))]
2567   "(optimize > 0)"
2568   "* return avr_out_sbxx_branch (insn, operands);"
2569   [(set (attr "length")
2570         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2571                            (le (minus (pc) (match_dup 3)) (const_int 2045)))
2572                       (const_int 3)
2573                       (if_then_else (eq_attr "mcu_mega" "no")
2574                                     (const_int 3)
2575                                     (const_int 5))))
2576    (set_attr "cc" "clobber")])
2577
2578 (define_insn "*sbix_branch_tmp_bit7"
2579   [(set (pc)
2580         (if_then_else
2581          (match_operator 0 "gelt_operator"
2582                          [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
2583                           (const_int 0)])
2584          (label_ref (match_operand 2 "" ""))
2585          (pc)))]
2586   "(optimize > 0)"
2587 {
2588   operands[3] = operands[2];
2589   operands[2] = GEN_INT (7);
2590   return avr_out_sbxx_branch (insn, operands);
2591 }
2592   [(set (attr "length")
2593         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2594                            (le (minus (pc) (match_dup 2)) (const_int 2045)))
2595                       (const_int 3)
2596                       (if_then_else (eq_attr "mcu_mega" "no")
2597                                     (const_int 3)
2598                                     (const_int 5))))
2599    (set_attr "cc" "clobber")])
2600
2601 ;; ************************* Peepholes ********************************
2602
2603 (define_peephole
2604   [(set (match_operand:SI 0 "d_register_operand" "")
2605         (plus:SI (match_dup 0)
2606                  (const_int -1)))
2607    (parallel
2608     [(set (cc0)
2609           (compare (match_dup 0)
2610                    (const_int -1)))
2611      (clobber (match_operand:QI 1 "d_register_operand" ""))])
2612    (set (pc)
2613         (if_then_else (ne (cc0) (const_int 0))
2614                       (label_ref (match_operand 2 "" ""))
2615                       (pc)))]
2616   ""
2617   "*
2618 {
2619   CC_STATUS_INIT;
2620   if (test_hard_reg_class (ADDW_REGS, operands[0]))
2621     output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
2622                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
2623                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2624   else
2625     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2626                      AS2 (sbc,%B0,__zero_reg__) CR_TAB
2627                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
2628                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
2629   switch (avr_jump_mode (operands[2],insn))
2630   {
2631     case 1:
2632       return AS1 (brcc,%2);
2633     case 2:
2634       return (AS1 (brcs,.+2) CR_TAB
2635               AS1 (rjmp,%2));
2636   }
2637   return (AS1 (brcs,.+4) CR_TAB
2638           AS1 (jmp,%2));
2639 }")
2640
2641 (define_peephole
2642   [(set (match_operand:HI 0 "d_register_operand" "")
2643         (plus:HI (match_dup 0)
2644                  (const_int -1)))
2645    (parallel
2646     [(set (cc0)
2647           (compare (match_dup 0)
2648                    (const_int 65535)))
2649      (clobber (match_operand:QI 1 "d_register_operand" ""))])
2650    (set (pc)
2651         (if_then_else (ne (cc0) (const_int 0))
2652                       (label_ref (match_operand 2 "" ""))
2653                       (pc)))]
2654   ""
2655   "*
2656 {
2657   CC_STATUS_INIT;
2658   if (test_hard_reg_class (ADDW_REGS, operands[0]))
2659     output_asm_insn (AS2 (sbiw,%0,1), operands);
2660   else
2661     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
2662                      AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
2663   switch (avr_jump_mode (operands[2],insn))
2664   {
2665     case 1:
2666       return AS1 (brcc,%2);
2667     case 2:
2668       return (AS1 (brcs,.+2) CR_TAB
2669               AS1 (rjmp,%2));
2670   }
2671   return (AS1 (brcs,.+4) CR_TAB
2672           AS1 (jmp,%2));
2673 }")
2674
2675 (define_peephole
2676   [(set (match_operand:QI 0 "d_register_operand" "")
2677         (plus:QI (match_dup 0)
2678                  (const_int -1)))
2679    (set (cc0)
2680         (compare (match_dup 0)
2681                  (const_int -1)))
2682    (set (pc)
2683         (if_then_else (ne (cc0) (const_int 0))
2684                       (label_ref (match_operand 1 "" ""))
2685                       (pc)))]
2686   ""
2687   "*
2688 {
2689   CC_STATUS_INIT;
2690   cc_status.value1 = operands[0];
2691   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2692   output_asm_insn (AS2 (subi,%A0,1), operands);
2693   switch (avr_jump_mode (operands[1],insn))
2694   {
2695     case 1:
2696       return AS1 (brcc,%1);
2697     case 2:
2698       return (AS1 (brcs,.+2) CR_TAB
2699               AS1 (rjmp,%1));
2700   }
2701   return (AS1 (brcs,.+4) CR_TAB
2702           AS1 (jmp,%1));
2703 }")
2704
2705 (define_peephole
2706   [(set (cc0) (match_operand:QI 0 "register_operand" ""))
2707    (set (pc)
2708         (if_then_else (eq (cc0) (const_int 0))
2709                       (label_ref (match_operand 1 "" ""))
2710                       (pc)))]
2711   "jump_over_one_insn_p (insn, operands[1])"
2712   "cpse %0,__zero_reg__")
2713
2714 (define_peephole
2715   [(set (cc0)
2716         (compare (match_operand:QI 0 "register_operand" "")
2717                  (match_operand:QI 1 "register_operand" "")))
2718    (set (pc)
2719         (if_then_else (eq (cc0) (const_int 0))
2720                       (label_ref (match_operand 2 "" ""))
2721                       (pc)))]
2722   "jump_over_one_insn_p (insn, operands[2])"
2723   "cpse %0,%1")
2724
2725 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
2726 ;;prologue/epilogue support instructions
2727
2728 (define_insn "popqi"
2729   [(set (match_operand:QI 0 "register_operand" "=r")
2730         (mem:QI (post_inc (reg:HI REG_SP))))]
2731   ""
2732   "pop %0"
2733   [(set_attr "cc" "none")
2734    (set_attr "length" "1")])
2735
2736 (define_insn "pophi"
2737   [(set (match_operand:HI 0 "register_operand" "=r")
2738         (mem:HI (post_inc (reg:HI REG_SP))))]
2739   ""
2740   "pop %A0\;pop %B0"
2741   [(set_attr "cc" "none")
2742    (set_attr "length" "2")])
2743
2744 ;; Enable Interrupts
2745 (define_insn "enable_interrupt"
2746   [(unspec [(const_int 0)] UNSPEC_SEI)]
2747   ""
2748   "sei"
2749   [(set_attr "length" "1")
2750   (set_attr "cc" "none")
2751   ])
2752
2753 ;; Disable Interrupts
2754 (define_insn "disable_interrupt"
2755   [(unspec [(const_int 0)] UNSPEC_CLI)]
2756   ""
2757   "cli"
2758   [(set_attr "length" "1")
2759   (set_attr "cc" "none")
2760   ])
2761
2762 ;;  Library prologue saves
2763 (define_insn "call_prologue_saves"
2764   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
2765    (match_operand:HI 0 "immediate_operand" "")
2766    (set (reg:HI REG_SP) (minus:HI 
2767                            (reg:HI REG_SP)
2768                            (match_operand:HI 1 "immediate_operand" "")))
2769    (use (reg:HI REG_X))
2770    (clobber (reg:HI REG_Z))]
2771   ""
2772   "ldi r30,pm_lo8(1f)
2773         ldi r31,pm_hi8(1f)
2774         %~jmp __prologue_saves__+((18 - %0) * 2)
2775 1:"
2776   [(set_attr_alternative "length"
2777                          [(if_then_else (eq_attr "mcu_mega" "yes")
2778                                         (const_int 6)
2779                                         (const_int 5))])
2780   (set_attr "cc" "clobber")
2781   ])
2782   
2783 ;  epilogue  restores using library
2784 (define_insn "epilogue_restores"
2785   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
2786    (set (reg:HI REG_Y ) (plus:HI 
2787                            (reg:HI REG_Y)
2788                            (match_operand:HI 0 "immediate_operand" ""))) 
2789    (set (reg:HI REG_SP) (reg:HI REG_Y))
2790    (clobber  (reg:QI REG_Z))]
2791   ""
2792   "ldi r30, lo8(%0)
2793         %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
2794   [(set_attr_alternative "length"
2795                          [(if_then_else (eq_attr "mcu_mega" "yes")
2796                                         (const_int 3)
2797                                         (const_int 2))])
2798   (set_attr "cc" "clobber")
2799   ])
2800   
2801 ; return
2802 (define_insn "return"
2803   [(return)]
2804   "reload_completed && avr_simple_epilogue ()"
2805   "ret"
2806   [(set_attr "cc" "none")
2807    (set_attr "length" "1")])
2808
2809 (define_insn "return_from_epilogue"
2810   [(return)]
2811   "(reload_completed 
2812     && cfun->machine 
2813     && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
2814     && !cfun->machine->is_naked)"
2815   "ret"
2816   [(set_attr "cc" "none")
2817    (set_attr "length" "1")])
2818
2819 (define_insn "return_from_interrupt_epilogue"
2820   [(return)]
2821   "(reload_completed 
2822     && cfun->machine 
2823     && (cfun->machine->is_interrupt || cfun->machine->is_signal)
2824     && !cfun->machine->is_naked)"
2825   "reti"
2826   [(set_attr "cc" "none")
2827    (set_attr "length" "1")])
2828
2829 (define_insn "return_from_naked_epilogue"
2830   [(return)]
2831   "(reload_completed 
2832     && cfun->machine 
2833     && cfun->machine->is_naked)"
2834   ""
2835   [(set_attr "cc" "none")
2836    (set_attr "length" "0")])
2837
2838 (define_expand "prologue"
2839   [(const_int 0)]
2840   ""
2841   "
2842   {
2843     expand_prologue (); 
2844     DONE;
2845   }")
2846
2847 (define_expand "epilogue"
2848   [(const_int 0)]
2849   ""
2850   "
2851   {
2852     expand_epilogue (); 
2853     DONE;
2854   }")