OSDN Git Service

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