OSDN Git Service

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