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