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