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