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