OSDN Git Service

9b6b69217d583c1d22a62f6618016dc2cbec71f1
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.md
1 ;; -*- Mode: Scheme -*-
2 ;;   Machine description for GNU compiler,
3 ;;   for ATMEL AVR micro controllers.
4 ;;   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
5 ;;   2009 Free Software Foundation, Inc.
6 ;;   Contributed by Denis Chertykov (chertykov@gmail.com)
7
8 ;; This file is part of GCC.
9
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
14
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
23
24 ;; Special characters after '%':
25 ;;  A  No effect (add 0).
26 ;;  B  Add 1 to REG number, MEM address or CONST_INT.
27 ;;  C  Add 2.
28 ;;  D  Add 3.
29 ;;  j  Branch condition.
30 ;;  k  Reverse branch condition.
31 ;;..m..Constant Direct Data memory address.
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 ;;..x..Constant Direct Program memory address.
36 ;;  ~  Output 'r' if not AVR_HAVE_JMP_CALL.
37 ;;  !  Output 'e' if AVR_HAVE_EIJMP_EICALL.
38
39 ;; UNSPEC usage:
40 ;;  0  Length of a string, see "strlenhi".
41 ;;  1  Jump by register pair Z or by table addressed by Z, see "casesi".
42
43 (define_constants
44   [(REG_X       26)
45    (REG_Y       28)
46    (REG_Z       30)
47    (REG_W       24)
48    (REG_SP      32)
49    (TMP_REGNO   0)      ; temporary register r0
50    (ZERO_REGNO  1)      ; zero register r1
51    
52    (SREG_ADDR   0x5F)
53    (RAMPZ_ADDR  0x5B)
54    
55    (UNSPEC_STRLEN       0)
56    (UNSPEC_INDEX_JMP    1)
57    (UNSPEC_SEI          2)
58    (UNSPEC_CLI          3)
59
60    (UNSPECV_PROLOGUE_SAVES      0)
61    (UNSPECV_EPILOGUE_RESTORES   1)
62    (UNSPECV_WRITE_SP_IRQ_ON     2)
63    (UNSPECV_WRITE_SP_IRQ_OFF    3)
64    (UNSPECV_GOTO_RECEIVER       4)])
65
66 (include "predicates.md")
67 (include "constraints.md")
68   
69 ;; Condition code settings.
70 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
71   (const_string "none"))
72
73 (define_attr "type" "branch,branch1,arith,xcall"
74   (const_string "arith"))
75
76 (define_attr "mcu_have_movw" "yes,no"
77   (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
78                        (const_string "yes")
79                        (const_string "no"))))
80
81 (define_attr "mcu_mega" "yes,no"
82   (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
83                        (const_string "yes")
84                        (const_string "no"))))
85   
86
87 ;; The size of instructions in bytes.
88 ;; XXX may depend from "cc"
89
90 (define_attr "length" ""
91   (cond [(eq_attr "type" "branch")
92          (if_then_else (and (ge (minus (pc) (match_dup 0))
93                                 (const_int -63))
94                             (le (minus (pc) (match_dup 0))
95                                 (const_int 62)))
96                        (const_int 1)
97                        (if_then_else (and (ge (minus (pc) (match_dup 0))
98                                               (const_int -2045))
99                                           (le (minus (pc) (match_dup 0))
100                                               (const_int 2045)))
101                                      (const_int 2)
102                                      (const_int 3)))
103          (eq_attr "type" "branch1")
104          (if_then_else (and (ge (minus (pc) (match_dup 0))
105                                 (const_int -62))
106                             (le (minus (pc) (match_dup 0))
107                                 (const_int 61)))
108                        (const_int 2)
109                        (if_then_else (and (ge (minus (pc) (match_dup 0))
110                                               (const_int -2044))
111                                           (le (minus (pc) (match_dup 0))
112                                               (const_int 2043)))
113                                      (const_int 3)
114                                      (const_int 4)))
115          (eq_attr "type" "xcall")
116          (if_then_else (eq_attr "mcu_mega" "no")
117                        (const_int 1)
118                        (const_int 2))]
119         (const_int 2)))
120
121 ;; Define mode iterator
122 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
123 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
124 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
125 (define_mode_iterator HISI [(HI "") (SI "")])
126
127 ;;========================================================================
128 ;; The following is used by nonlocal_goto and setjmp.
129 ;; The receiver pattern will create no instructions since internally
130 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
131 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
132 ;; The 'null' receiver also avoids  problems with optimisation
133 ;; not recognising incoming jmp and removing code that resets frame_pointer.
134 ;; The code derived from builtins.c.
135
136 (define_expand "nonlocal_goto_receiver"
137   [(set (reg:HI REG_Y) 
138         (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
139   ""
140   {
141     emit_move_insn (virtual_stack_vars_rtx, 
142                     gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, 
143                                   gen_int_mode (STARTING_FRAME_OFFSET,
144                                                 Pmode)));
145   /* This might change the hard frame pointer in ways that aren't
146     apparent to early optimization passes, so force a clobber.  */
147     emit_clobber (hard_frame_pointer_rtx);
148     DONE;
149   })
150   
151
152 ;; Defining nonlocal_goto_receiver means we must also define this.
153 ;; even though its function is identical to that in builtins.c
154
155 (define_expand "nonlocal_goto"
156   [
157   (use (match_operand 0 "general_operand"))
158   (use (match_operand 1 "general_operand"))
159   (use (match_operand 2 "general_operand"))
160   (use (match_operand 3 "general_operand"))
161   ]
162   ""
163 {
164   rtx r_label = copy_to_reg (operands[1]);
165   rtx r_fp = operands[3];
166   rtx r_sp = operands[2];
167
168   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
169
170   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
171
172   emit_move_insn (hard_frame_pointer_rtx, r_fp);
173   emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
174
175   emit_use (hard_frame_pointer_rtx);
176   emit_use (stack_pointer_rtx);
177
178   emit_indirect_jump (r_label);
179  
180   DONE;
181 })
182
183
184 (define_insn "*pushqi"
185   [(set (mem:QI (post_dec (reg:HI REG_SP)))
186         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
187   ""
188   "@
189         push %0
190         push __zero_reg__"
191   [(set_attr "length" "1,1")])
192
193
194 (define_insn "*pushhi"
195   [(set (mem:HI (post_dec (reg:HI REG_SP)))
196         (match_operand:HI 0 "reg_or_0_operand" "r,L"))]
197   ""
198   "@
199         push %B0\;push %A0
200         push __zero_reg__\;push __zero_reg__"
201   [(set_attr "length" "2,2")])
202
203 (define_insn "*pushsi"
204   [(set (mem:SI (post_dec (reg:HI REG_SP)))
205         (match_operand:SI 0 "reg_or_0_operand" "r,L"))]
206   ""
207   "@
208         push %D0\;push %C0\;push %B0\;push %A0
209         push __zero_reg__\;push __zero_reg__\;push __zero_reg__\;push __zero_reg__"
210   [(set_attr "length" "4,4")])
211
212 (define_insn "*pushsf"
213   [(set (mem:SF (post_dec (reg:HI REG_SP)))
214         (match_operand:SF 0 "register_operand" "r"))]
215   ""
216   "push %D0
217         push %C0
218         push %B0
219         push %A0"
220   [(set_attr "length" "4")])
221
222 ;;========================================================================
223 ;; move byte
224 ;; The last alternative (any immediate constant to any register) is
225 ;; very expensive.  It should be optimized by peephole2 if a scratch
226 ;; register is available, but then that register could just as well be
227 ;; allocated for the variable we are loading.  But, most of NO_LD_REGS
228 ;; are call-saved registers, and most of LD_REGS are call-used registers,
229 ;; so this may still be a win for registers live across function calls.
230
231 (define_expand "movqi"
232   [(set (match_operand:QI 0 "nonimmediate_operand" "")
233         (match_operand:QI 1 "general_operand" ""))]
234   ""
235   "/* One of the ops has to be in a register.  */
236    if (!register_operand(operand0, QImode)
237        && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
238        operands[1] = copy_to_mode_reg(QImode, operand1);
239   ")
240
241 (define_insn "*movqi"
242   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
243         (match_operand:QI 1 "general_operand"       "rL,i,rL,Qm,r,q,i"))]
244   "(register_operand (operands[0],QImode)
245     || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
246   "* return output_movqi (insn, operands, NULL);"
247   [(set_attr "length" "1,1,5,5,1,1,4")
248    (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
249
250 ;; This is used in peephole2 to optimize loading immediate constants
251 ;; if a scratch register from LD_REGS happens to be available.
252
253 (define_insn "*reload_inqi"
254   [(set (match_operand:QI 0 "register_operand" "=l")
255         (match_operand:QI 1 "immediate_operand" "i"))
256    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
257   "reload_completed"
258   "ldi %2,lo8(%1)
259         mov %0,%2"
260   [(set_attr "length" "2")
261    (set_attr "cc" "none")])
262
263 (define_peephole2
264   [(match_scratch:QI 2 "d")
265    (set (match_operand:QI 0 "l_register_operand" "")
266         (match_operand:QI 1 "immediate_operand" ""))]
267   "(operands[1] != const0_rtx
268     && operands[1] != const1_rtx
269     && operands[1] != constm1_rtx)"
270   [(parallel [(set (match_dup 0) (match_dup 1))
271               (clobber (match_dup 2))])]
272   "")
273
274 ;;============================================================================
275 ;; move word (16 bit)
276
277 (define_expand "movhi"
278   [(set (match_operand:HI 0 "nonimmediate_operand" "")
279         (match_operand:HI 1 "general_operand"       ""))]
280   ""
281   "
282 {
283    /* One of the ops has to be in a register.  */
284   if (!register_operand(operand0, HImode)
285       && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
286     {
287       operands[1] = copy_to_mode_reg(HImode, operand1);
288     }
289 }")
290
291 (define_insn "*movhi_sp"
292   [(set (match_operand:HI 0 "register_operand" "=q,r")
293         (match_operand:HI 1 "register_operand"  "r,q"))]
294   "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
295     || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
296   "* return output_movhi (insn, operands, NULL);"
297   [(set_attr "length" "5,2")
298    (set_attr "cc" "none,none")])
299
300 (define_insn "movhi_sp_r_irq_off"
301   [(set (match_operand:HI 0 "stack_register_operand" "=q")
302         (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
303                             UNSPECV_WRITE_SP_IRQ_OFF))]
304   ""
305   "out __SP_H__, %B1
306         out __SP_L__, %A1"
307   [(set_attr "length" "2")
308    (set_attr "cc" "none")])
309
310 (define_insn "movhi_sp_r_irq_on"
311   [(set (match_operand:HI 0 "stack_register_operand" "=q")
312         (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
313                             UNSPECV_WRITE_SP_IRQ_ON))]
314   ""
315   "cli
316         out __SP_H__, %B1
317         sei
318         out __SP_L__, %A1"
319   [(set_attr "length" "4")
320    (set_attr "cc" "none")])
321
322 (define_peephole2
323   [(match_scratch:QI 2 "d")
324    (set (match_operand:HI 0 "l_register_operand" "")
325         (match_operand:HI 1 "immediate_operand" ""))]
326   "(operands[1] != const0_rtx 
327     && operands[1] != constm1_rtx)"
328   [(parallel [(set (match_dup 0) (match_dup 1))
329               (clobber (match_dup 2))])]
330   "")
331
332 ;; '*' because it is not used in rtl generation, only in above peephole
333 (define_insn "*reload_inhi"
334   [(set (match_operand:HI 0 "register_operand" "=r")
335         (match_operand:HI 1 "immediate_operand" "i"))
336    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
337   "reload_completed"
338   "* return output_reload_inhi (insn, operands, NULL);"
339   [(set_attr "length" "4")
340    (set_attr "cc" "none")])
341
342 (define_insn "*movhi"
343   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
344         (match_operand:HI 1 "general_operand"       "rL,m,rL,i,i,r,q"))]
345   "(register_operand (operands[0],HImode)
346     || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
347   "* return output_movhi (insn, operands, NULL);"
348   [(set_attr "length" "2,6,7,2,6,5,2")
349    (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
350
351 (define_peephole2 ; movw
352   [(set (match_operand:QI 0 "even_register_operand" "")
353         (match_operand:QI 1 "even_register_operand" ""))
354    (set (match_operand:QI 2 "odd_register_operand" "")
355         (match_operand:QI 3 "odd_register_operand" ""))]
356   "(AVR_HAVE_MOVW
357     && REGNO (operands[0]) == REGNO (operands[2]) - 1
358     && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
359   [(set (match_dup 4) (match_dup 5))]
360   {
361     operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
362     operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
363   })
364
365 (define_peephole2 ; movw_r
366   [(set (match_operand:QI 0 "odd_register_operand" "")
367         (match_operand:QI 1 "odd_register_operand" ""))
368    (set (match_operand:QI 2 "even_register_operand" "")
369         (match_operand:QI 3 "even_register_operand" ""))]
370   "(AVR_HAVE_MOVW
371     && REGNO (operands[2]) == REGNO (operands[0]) - 1
372     && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
373   [(set (match_dup 4) (match_dup 5))]
374   {
375     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
376     operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
377   })
378
379 ;;==========================================================================
380 ;; move double word (32 bit)
381
382 (define_expand "movsi"
383   [(set (match_operand:SI 0 "nonimmediate_operand" "")
384         (match_operand:SI 1 "general_operand"  ""))]
385   ""
386   "
387 {
388   /* One of the ops has to be in a register.  */
389   if (!register_operand (operand0, SImode)
390       && !(register_operand (operand1, SImode) || const0_rtx == operand1))
391     {
392       operands[1] = copy_to_mode_reg (SImode, operand1);
393     }
394 }")
395
396
397
398 (define_peephole2 ; movsi_lreg_const
399   [(match_scratch:QI 2 "d")
400    (set (match_operand:SI 0 "l_register_operand" "")
401         (match_operand:SI 1 "immediate_operand" ""))
402    (match_dup 2)]
403   "(operands[1] != const0_rtx
404     && operands[1] != constm1_rtx)"
405   [(parallel [(set (match_dup 0) (match_dup 1))
406               (clobber (match_dup 2))])]
407   "")
408
409 ;; '*' because it is not used in rtl generation.
410 (define_insn "*reload_insi"
411   [(set (match_operand:SI 0 "register_operand" "=r")
412         (match_operand:SI 1 "immediate_operand" "i"))
413    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
414   "reload_completed"
415   "* return output_reload_insisf (insn, operands, NULL);"
416   [(set_attr "length" "8")
417    (set_attr "cc" "none")])
418
419
420 (define_insn "*movsi"
421   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
422         (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
423   "(register_operand (operands[0],SImode)
424     || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
425   "* return output_movsisf (insn, operands, NULL);"
426   [(set_attr "length" "4,4,8,9,4,10")
427    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
428
429 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
430 ;; move floating point numbers (32 bit)
431
432 (define_expand "movsf"
433   [(set (match_operand:SF 0 "nonimmediate_operand" "")
434         (match_operand:SF 1 "general_operand"  ""))]
435   ""
436   "
437 {
438   /* One of the ops has to be in a register.  */
439   if (!register_operand (operand1, SFmode)
440       && !register_operand (operand0, SFmode))
441     {
442       operands[1] = copy_to_mode_reg (SFmode, operand1);
443     }
444 }")
445
446 (define_insn "*movsf"
447   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
448         (match_operand:SF 1 "general_operand"       "r,G,Qm,r,F,F"))]
449   "register_operand (operands[0], SFmode)
450    || register_operand (operands[1], SFmode)"
451   "* return output_movsisf (insn, operands, NULL);"
452   [(set_attr "length" "4,4,8,9,4,10")
453    (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")])
454
455 ;;=========================================================================
456 ;; move string (like memcpy)
457 ;; implement as RTL loop
458
459 (define_expand "movmemhi"
460   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
461           (match_operand:BLK 1 "memory_operand" ""))
462           (use (match_operand:HI 2 "const_int_operand" ""))
463           (use (match_operand:HI 3 "const_int_operand" ""))])]
464   ""
465   "{
466   int prob;
467   HOST_WIDE_INT count;
468   enum machine_mode mode;
469   rtx label = gen_label_rtx ();
470   rtx loop_reg;
471   rtx jump;
472
473   /* Copy pointers into new psuedos - they will be changed.  */
474   rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
475   rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
476
477   /* Create rtx for tmp register - we use this as scratch.  */
478   rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
479
480   if (GET_CODE (operands[2]) != CONST_INT)
481     FAIL;
482
483   count = INTVAL (operands[2]);
484   if (count <= 0)
485     FAIL;
486
487   /* Work out branch probability for latter use.  */
488   prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
489
490   /* See if constant fit 8 bits.  */
491   mode = (count < 0x100) ? QImode : HImode;
492   /* Create loop counter register.  */
493   loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
494
495   /* Now create RTL code for move loop.  */
496   /* Label at top of loop.  */
497   emit_label (label);
498
499   /* Move one byte into scratch and inc pointer.  */
500   emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
501   emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
502
503   /* Move to mem and inc pointer.  */
504   emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
505   emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
506
507   /* Decrement count.  */
508   emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
509
510   /* Compare with zero and jump if not equal. */
511   emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
512                            label);
513   /* Set jump probability based on loop count.  */
514   jump = get_last_insn ();
515   add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
516   DONE;
517 }")
518
519 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
520 ;; memset (%0, %2, %1)
521
522 (define_expand "setmemhi"
523   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
524                    (match_operand 2 "const_int_operand" ""))
525               (use (match_operand:HI 1 "const_int_operand" ""))
526               (use (match_operand:HI 3 "const_int_operand" "n"))
527               (clobber (match_scratch:HI 4 ""))
528               (clobber (match_dup 5))])]
529   ""
530   "{
531   rtx addr0;
532   int cnt8;
533   enum machine_mode mode;
534
535   /* If value to set is not zero, use the library routine.  */
536   if (operands[2] != const0_rtx)
537     FAIL;
538
539   if (GET_CODE (operands[1]) != CONST_INT)
540     FAIL;
541
542   cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
543   mode = cnt8 ? QImode : HImode;
544   operands[5] = gen_rtx_SCRATCH (mode);
545   operands[1] = copy_to_mode_reg (mode,
546                                   gen_int_mode (INTVAL (operands[1]), mode));
547   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
548   operands[0] = gen_rtx_MEM (BLKmode, addr0);
549 }")
550
551 (define_insn "*clrmemqi"
552   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
553         (const_int 0))
554    (use (match_operand:QI 1 "register_operand" "r"))
555    (use (match_operand:QI 2 "const_int_operand" "n"))
556    (clobber (match_scratch:HI 3 "=0"))
557    (clobber (match_scratch:QI 4 "=&1"))]
558   ""
559   "st %a0+,__zero_reg__
560         dec %1
561         brne .-6"
562   [(set_attr "length" "3")
563    (set_attr "cc" "clobber")])
564
565 (define_insn "*clrmemhi"
566   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
567         (const_int 0))
568    (use (match_operand:HI 1 "register_operand" "!w,d"))
569    (use (match_operand:HI 2 "const_int_operand" "n,n"))
570    (clobber (match_scratch:HI 3 "=0,0"))
571    (clobber (match_scratch:HI 4 "=&1,&1"))]
572   ""
573   "*{
574      if (which_alternative==0)
575        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
576                AS2 (sbiw,%A1,1) CR_TAB
577                AS1 (brne,.-6));
578      else
579        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
580                AS2 (subi,%A1,1) CR_TAB
581                AS2 (sbci,%B1,0) CR_TAB
582                AS1 (brne,.-8));
583 }"
584   [(set_attr "length" "3,4")
585    (set_attr "cc" "clobber,clobber")])
586
587 (define_expand "strlenhi"
588     [(set (match_dup 4)
589           (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
590                       (match_operand:QI 2 "const_int_operand" "")
591                       (match_operand:HI 3 "immediate_operand" "")]
592                      UNSPEC_STRLEN))
593      (set (match_dup 4) (plus:HI (match_dup 4)
594                                  (const_int -1)))
595      (set (match_operand:HI 0 "register_operand" "")
596           (minus:HI (match_dup 4)
597                     (match_dup 5)))]
598    ""
599    "{
600   rtx addr;
601   if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
602     FAIL;
603   addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
604   operands[1] = gen_rtx_MEM (BLKmode, addr); 
605   operands[5] = addr;
606   operands[4] = gen_reg_rtx (HImode);
607 }")
608
609 (define_insn "*strlenhi"
610   [(set (match_operand:HI 0 "register_operand" "=e")
611         (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
612                     (const_int 0)
613                     (match_operand:HI 2 "immediate_operand" "i")]
614                    UNSPEC_STRLEN))]
615   ""
616   "ld __tmp_reg__,%a0+
617         tst __tmp_reg__
618         brne .-6"
619   [(set_attr "length" "3")
620    (set_attr "cc" "clobber")])
621
622 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
623 ; add bytes
624
625 (define_insn "addqi3"
626   [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
627         (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
628                  (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
629   ""
630   "@
631         add %0,%2
632         subi %0,lo8(-(%2))
633         inc %0
634         dec %0"
635   [(set_attr "length" "1,1,1,1")
636    (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
637
638
639 (define_expand "addhi3"
640   [(set (match_operand:HI 0 "register_operand" "")
641         (plus:HI (match_operand:HI 1 "register_operand" "")
642                  (match_operand:HI 2 "nonmemory_operand" "")))]
643   ""
644   "
645 {
646   if (GET_CODE (operands[2]) == CONST_INT)
647     {
648       short tmp = INTVAL (operands[2]);
649       operands[2] = GEN_INT(tmp);
650     }
651 }")
652
653
654 (define_insn "*addhi3_zero_extend"
655   [(set (match_operand:HI 0 "register_operand" "=r")
656         (plus:HI (zero_extend:HI
657                   (match_operand:QI 1 "register_operand" "r"))
658                  (match_operand:HI 2 "register_operand" "0")))]
659   ""
660   "add %A0,%1
661         adc %B0,__zero_reg__"
662   [(set_attr "length" "2")
663    (set_attr "cc" "set_n")])
664
665 (define_insn "*addhi3_zero_extend1"
666   [(set (match_operand:HI 0 "register_operand" "=r")
667         (plus:HI (match_operand:HI 1 "register_operand" "%0")
668                  (zero_extend:HI
669                   (match_operand:QI 2 "register_operand" "r"))))]
670   ""
671   "add %A0,%2
672         adc %B0,__zero_reg__"
673   [(set_attr "length" "2")
674    (set_attr "cc" "set_n")])
675
676 (define_insn "*addhi3_sp_R_pc2"
677   [(set (match_operand:HI 1 "stack_register_operand" "=q")
678         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
679                  (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
680   "AVR_2_BYTE_PC"
681   "*{
682       if (CONST_INT_P (operands[0]))
683         {
684           switch(INTVAL (operands[0]))
685             {
686             case -6: 
687               return \"rcall .\" CR_TAB 
688                      \"rcall .\" CR_TAB 
689                      \"rcall .\";
690             case -5: 
691               return \"rcall .\" CR_TAB 
692                      \"rcall .\" CR_TAB 
693                      \"push __tmp_reg__\";
694             case -4: 
695               return \"rcall .\" CR_TAB 
696                      \"rcall .\";
697             case -3: 
698               return \"rcall .\" CR_TAB 
699                      \"push __tmp_reg__\";
700             case -2: 
701               return \"rcall .\";
702             case -1: 
703               return \"push __tmp_reg__\";
704             case 0: 
705               return \"\";
706             case 1: 
707               return \"pop __tmp_reg__\";
708             case 2: 
709               return \"pop __tmp_reg__\" CR_TAB 
710                      \"pop __tmp_reg__\";
711             case 3: 
712               return \"pop __tmp_reg__\" CR_TAB 
713                      \"pop __tmp_reg__\" CR_TAB 
714                      \"pop __tmp_reg__\";
715             case 4: 
716               return \"pop __tmp_reg__\" CR_TAB 
717                      \"pop __tmp_reg__\" CR_TAB 
718                      \"pop __tmp_reg__\" CR_TAB 
719                      \"pop __tmp_reg__\";
720             case 5: 
721               return \"pop __tmp_reg__\" CR_TAB 
722                      \"pop __tmp_reg__\" CR_TAB 
723                      \"pop __tmp_reg__\" CR_TAB 
724                      \"pop __tmp_reg__\" CR_TAB 
725                      \"pop __tmp_reg__\";
726             }
727         }
728       return \"bug\";
729     }"
730   [(set (attr "length") 
731         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
732                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
733                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
734                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
735                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
736                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
737                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
738                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
739                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
740                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
741                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
742                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
743                (const_int 0)))])
744
745 (define_insn "*addhi3_sp_R_pc3"
746   [(set (match_operand:HI 1 "stack_register_operand" "=q")
747         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
748                  (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
749   "AVR_3_BYTE_PC"
750   "*{
751       if (CONST_INT_P (operands[0]))
752         {
753           switch(INTVAL (operands[0]))
754             {
755             case -6: 
756               return \"rcall .\" CR_TAB 
757                      \"rcall .\";
758             case -5: 
759               return \"rcall .\" CR_TAB 
760                      \"push __tmp_reg__\" CR_TAB 
761                      \"push __tmp_reg__\";
762             case -4: 
763               return \"rcall .\" CR_TAB 
764                      \"push __tmp_reg__\";
765             case -3: 
766               return \"rcall .\";
767             case -2: 
768               return \"push __tmp_reg__\" CR_TAB 
769                      \"push __tmp_reg__\";
770             case -1: 
771               return \"push __tmp_reg__\";
772             case 0: 
773               return \"\";
774             case 1: 
775               return \"pop __tmp_reg__\";
776             case 2: 
777               return \"pop __tmp_reg__\" CR_TAB 
778                      \"pop __tmp_reg__\";
779             case 3: 
780               return \"pop __tmp_reg__\" CR_TAB 
781                      \"pop __tmp_reg__\" CR_TAB 
782                      \"pop __tmp_reg__\";
783             case 4: 
784               return \"pop __tmp_reg__\" CR_TAB 
785                      \"pop __tmp_reg__\" CR_TAB 
786                      \"pop __tmp_reg__\" CR_TAB 
787                      \"pop __tmp_reg__\";
788             case 5: 
789               return \"pop __tmp_reg__\" CR_TAB 
790                      \"pop __tmp_reg__\" CR_TAB 
791                      \"pop __tmp_reg__\" CR_TAB 
792                      \"pop __tmp_reg__\" CR_TAB 
793                      \"pop __tmp_reg__\";
794             }
795         }
796       return \"bug\";
797     }"
798   [(set (attr "length") 
799         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
800                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
801                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
802                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
803                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
804                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
805                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
806                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
807                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
808                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
809                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
810                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
811                (const_int 0)))])
812
813 (define_insn "*addhi3"
814   [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
815         (plus:HI
816          (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
817          (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
818   ""
819   "@
820         add %A0,%A2\;adc %B0,%B2
821         adiw %A0,%2
822         sbiw %A0,%n2
823         subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
824         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
825         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
826   [(set_attr "length" "2,1,1,2,3,3")
827    (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
828
829 (define_insn "addsi3"
830   [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
831           (plus:SI
832            (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
833            (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
834   ""
835   "@
836         add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
837         adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
838         sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
839         subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
840         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
841         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
842   [(set_attr "length" "4,3,3,4,5,5")
843    (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
844
845 (define_insn "*addsi3_zero_extend"
846   [(set (match_operand:SI 0 "register_operand" "=r")
847         (plus:SI (zero_extend:SI
848                   (match_operand:QI 1 "register_operand" "r"))
849                  (match_operand:SI 2 "register_operand" "0")))]
850   ""
851   "add %A0,%1
852         adc %B0,__zero_reg__
853         adc %C0,__zero_reg__
854         adc %D0,__zero_reg__"
855   [(set_attr "length" "4")
856    (set_attr "cc" "set_n")])
857
858 ;-----------------------------------------------------------------------------
859 ; sub bytes
860 (define_insn "subqi3"
861   [(set (match_operand:QI 0 "register_operand" "=r,d")
862         (minus:QI (match_operand:QI 1 "register_operand" "0,0")
863                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
864   ""
865   "@
866         sub %0,%2
867         subi %0,lo8(%2)"
868   [(set_attr "length" "1,1")
869    (set_attr "cc" "set_czn,set_czn")])
870
871 (define_insn "subhi3"
872   [(set (match_operand:HI 0 "register_operand" "=r,d")
873         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
874                   (match_operand:HI 2 "nonmemory_operand" "r,i")))]
875   ""
876   "@
877         sub %A0,%A2\;sbc %B0,%B2
878         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
879   [(set_attr "length" "2,2")
880    (set_attr "cc" "set_czn,set_czn")])
881
882 (define_insn "*subhi3_zero_extend1"
883   [(set (match_operand:HI 0 "register_operand" "=r")
884         (minus:HI (match_operand:HI 1 "register_operand" "0")
885                   (zero_extend:HI
886                    (match_operand:QI 2 "register_operand" "r"))))]
887   ""
888   "sub %A0,%2
889         sbc %B0,__zero_reg__"
890   [(set_attr "length" "2")
891    (set_attr "cc" "set_n")])
892
893 (define_insn "subsi3"
894   [(set (match_operand:SI 0 "register_operand" "=r,d")
895         (minus:SI (match_operand:SI 1 "register_operand" "0,0")
896                  (match_operand:SI 2 "nonmemory_operand" "r,i")))]
897   ""
898   "@
899         sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
900         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
901   [(set_attr "length" "4,4")
902    (set_attr "cc" "set_czn,set_czn")])
903
904 (define_insn "*subsi3_zero_extend"
905   [(set (match_operand:SI 0 "register_operand" "=r")
906         (minus:SI (match_operand:SI 1 "register_operand" "0")
907                   (zero_extend:SI
908                    (match_operand:QI 2 "register_operand" "r"))))]
909   ""
910   "sub %A0,%2
911         sbc %B0,__zero_reg__
912         sbc %C0,__zero_reg__
913         sbc %D0,__zero_reg__"
914   [(set_attr "length" "4")
915    (set_attr "cc" "set_n")])
916
917 ;******************************************************************************
918 ; mul
919
920 (define_expand "mulqi3"
921   [(set (match_operand:QI 0 "register_operand" "")
922         (mult:QI (match_operand:QI 1 "register_operand" "")
923                  (match_operand:QI 2 "register_operand" "")))]
924   ""
925   "{
926   if (!AVR_HAVE_MUL)
927     {
928       emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
929       DONE;
930     }
931 }")
932
933 (define_insn "*mulqi3_enh"
934   [(set (match_operand:QI 0 "register_operand" "=r")
935         (mult:QI (match_operand:QI 1 "register_operand" "r")
936                  (match_operand:QI 2 "register_operand" "r")))]
937   "AVR_HAVE_MUL"
938   "mul %1,%2
939         mov %0,r0
940         clr r1"
941   [(set_attr "length" "3")
942    (set_attr "cc" "clobber")])
943
944 (define_expand "mulqi3_call"
945   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
946    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
947    (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
948               (clobber (reg:QI 22))])
949    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
950   ""
951   "")
952
953 (define_insn "*mulqi3_call"
954   [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
955    (clobber (reg:QI 22))]
956   "!AVR_HAVE_MUL"
957   "%~call __mulqi3"
958   [(set_attr "type" "xcall")
959    (set_attr "cc" "clobber")])
960
961 (define_insn "mulqihi3"
962   [(set (match_operand:HI 0 "register_operand" "=r")
963         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
964                  (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
965   "AVR_HAVE_MUL"
966   "muls %1,%2
967         movw %0,r0
968         clr r1"
969   [(set_attr "length" "3")
970    (set_attr "cc" "clobber")])
971
972 (define_insn "umulqihi3"
973   [(set (match_operand:HI 0 "register_operand" "=r")
974         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
975                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
976   "AVR_HAVE_MUL"
977   "mul %1,%2
978         movw %0,r0
979         clr r1"
980   [(set_attr "length" "3")
981    (set_attr "cc" "clobber")])
982
983 (define_expand "mulhi3"
984   [(set (match_operand:HI 0 "register_operand" "")
985         (mult:HI (match_operand:HI 1 "register_operand" "")
986                  (match_operand:HI 2 "register_operand" "")))]
987   ""
988   "
989 {
990   if (!AVR_HAVE_MUL)
991     {
992       emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
993       DONE;
994     }
995 }")
996
997 (define_insn "*mulhi3_enh"
998   [(set (match_operand:HI 0 "register_operand" "=&r")
999         (mult:HI (match_operand:HI 1 "register_operand" "r")
1000                  (match_operand:HI 2 "register_operand" "r")))]
1001   "AVR_HAVE_MUL"
1002   "mul %A1,%A2
1003         movw %0,r0
1004         mul %A1,%B2
1005         add %B0,r0
1006         mul %B1,%A2
1007         add %B0,r0
1008         clr r1"
1009   [(set_attr "length" "7")
1010    (set_attr "cc" "clobber")])
1011
1012 (define_expand "mulhi3_call"
1013   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1014    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1015    (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1016               (clobber (reg:HI 22))
1017               (clobber (reg:QI 21))])
1018    (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1019   ""
1020   "")
1021
1022 (define_insn "*mulhi3_call"
1023   [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1024    (clobber (reg:HI 22))
1025    (clobber (reg:QI 21))]
1026   "!AVR_HAVE_MUL"
1027   "%~call __mulhi3"
1028   [(set_attr "type" "xcall")
1029    (set_attr "cc" "clobber")])
1030
1031 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
1032 ;; All call-used registers clobbered otherwise - normal library call.
1033 (define_expand "mulsi3"
1034   [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
1035    (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
1036    (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1037               (clobber (reg:HI 26))
1038               (clobber (reg:HI 30))])
1039    (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
1040   "AVR_HAVE_MUL"
1041   "")
1042
1043 (define_insn "*mulsi3_call"
1044   [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1045    (clobber (reg:HI 26))
1046    (clobber (reg:HI 30))]
1047   "AVR_HAVE_MUL"
1048   "%~call __mulsi3"
1049   [(set_attr "type" "xcall")
1050    (set_attr "cc" "clobber")])
1051
1052 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1053 ; divmod
1054
1055 ;; Generate libgcc.S calls ourselves, because:
1056 ;;  - we know exactly which registers are clobbered (for QI and HI
1057 ;;    modes, some of the call-used registers are preserved)
1058 ;;  - we get both the quotient and the remainder at no extra cost
1059 ;;  - we split the patterns only after the first CSE passes because
1060 ;;    CSE has problems to operate on hard regs.
1061 ;; 
1062 (define_insn_and_split "divmodqi4"
1063   [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1064                    (div:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1065                            (match_operand:QI 2 "pseudo_register_operand" "")))
1066               (set (match_operand:QI 3 "pseudo_register_operand" "") 
1067                    (mod:QI (match_dup 1) (match_dup 2)))
1068               (clobber (reg:QI 22)) 
1069               (clobber (reg:QI 23)) 
1070               (clobber (reg:QI 24)) 
1071               (clobber (reg:QI 25))])]
1072   ""
1073   "this divmodqi4 pattern should have been splitted;"
1074   ""
1075   [(set (reg:QI 24) (match_dup 1))
1076    (set (reg:QI 22) (match_dup 2))
1077    (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1078               (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1079               (clobber (reg:QI 22))
1080               (clobber (reg:QI 23))])
1081    (set (match_dup 0) (reg:QI 24))
1082    (set (match_dup 3) (reg:QI 25))]
1083   "")
1084
1085 (define_insn "*divmodqi4_call"
1086   [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1087    (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1088    (clobber (reg:QI 22))
1089    (clobber (reg:QI 23))]
1090   ""
1091   "%~call __divmodqi4"
1092   [(set_attr "type" "xcall")
1093    (set_attr "cc" "clobber")])
1094
1095 (define_insn_and_split "udivmodqi4"
1096  [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1097                   (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1098                            (match_operand:QI 2 "pseudo_register_operand" "")))
1099              (set (match_operand:QI 3 "pseudo_register_operand" "") 
1100                   (umod:QI (match_dup 1) (match_dup 2)))
1101              (clobber (reg:QI 22))
1102              (clobber (reg:QI 23))
1103              (clobber (reg:QI 24))
1104              (clobber (reg:QI 25))])]
1105   ""
1106   "this udivmodqi4 pattern should have been splitted;"
1107   "" 
1108   [(set (reg:QI 24) (match_dup 1))
1109    (set (reg:QI 22) (match_dup 2))
1110    (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1111               (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1112               (clobber (reg:QI 23))])
1113    (set (match_dup 0) (reg:QI 24))
1114    (set (match_dup 3) (reg:QI 25))]
1115   "")
1116
1117 (define_insn "*udivmodqi4_call"
1118   [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1119    (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1120    (clobber (reg:QI 23))]
1121   ""
1122   "%~call __udivmodqi4"
1123   [(set_attr "type" "xcall")
1124    (set_attr "cc" "clobber")])
1125
1126 (define_insn_and_split "divmodhi4"
1127   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1128                    (div:HI (match_operand:HI 1 "pseudo_register_operand" "") 
1129                            (match_operand:HI 2 "pseudo_register_operand" "")))
1130               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1131                    (mod:HI (match_dup 1) (match_dup 2)))
1132               (clobber (reg:QI 21))
1133               (clobber (reg:HI 22))
1134               (clobber (reg:HI 24))
1135               (clobber (reg:HI 26))])]
1136   ""
1137   "this should have been splitted;"
1138   ""
1139   [(set (reg:HI 24) (match_dup 1))
1140    (set (reg:HI 22) (match_dup 2))
1141    (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1142               (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1143               (clobber (reg:HI 26))
1144               (clobber (reg:QI 21))])
1145    (set (match_dup 0) (reg:HI 22))
1146    (set (match_dup 3) (reg:HI 24))]
1147   "") 
1148
1149 (define_insn "*divmodhi4_call"
1150   [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1151    (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1152    (clobber (reg:HI 26))
1153    (clobber (reg:QI 21))]
1154   ""
1155   "%~call __divmodhi4"
1156   [(set_attr "type" "xcall")
1157    (set_attr "cc" "clobber")])
1158
1159 (define_insn_and_split "udivmodhi4"
1160   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1161                    (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1162                             (match_operand:HI 2 "pseudo_register_operand" "")))
1163               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1164                    (umod:HI (match_dup 1) (match_dup 2)))
1165               (clobber (reg:QI 21))
1166               (clobber (reg:HI 22))
1167               (clobber (reg:HI 24))
1168               (clobber (reg:HI 26))])]
1169   ""
1170   "this udivmodhi4 pattern should have been splitted.;"
1171   ""
1172   [(set (reg:HI 24) (match_dup 1))
1173    (set (reg:HI 22) (match_dup 2))
1174    (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1175               (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1176               (clobber (reg:HI 26))
1177               (clobber (reg:QI 21))])
1178    (set (match_dup 0) (reg:HI 22))
1179    (set (match_dup 3) (reg:HI 24))]
1180   "")
1181
1182 (define_insn "*udivmodhi4_call"
1183   [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1184    (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1185    (clobber (reg:HI 26))
1186    (clobber (reg:QI 21))]
1187   ""
1188   "%~call __udivmodhi4"
1189   [(set_attr "type" "xcall")
1190    (set_attr "cc" "clobber")])
1191
1192 (define_insn_and_split "divmodsi4"
1193   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1194                    (div:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1195                            (match_operand:SI 2 "pseudo_register_operand" "")))
1196               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1197                    (mod:SI (match_dup 1) (match_dup 2)))
1198               (clobber (reg:SI 18))
1199               (clobber (reg:SI 22))
1200               (clobber (reg:HI 26))
1201               (clobber (reg:HI 30))])]
1202   ""
1203   "this divmodsi4 pattern should have been splitted;" 
1204   ""
1205   [(set (reg:SI 22) (match_dup 1))
1206    (set (reg:SI 18) (match_dup 2))
1207    (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1208               (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1209               (clobber (reg:HI 26))
1210               (clobber (reg:HI 30))])
1211    (set (match_dup 0) (reg:SI 18))
1212    (set (match_dup 3) (reg:SI 22))]
1213   "")
1214
1215 (define_insn "*divmodsi4_call"
1216   [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1217    (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1218    (clobber (reg:HI 26))
1219    (clobber (reg:HI 30))]
1220   ""
1221   "%~call __divmodsi4"
1222   [(set_attr "type" "xcall")
1223    (set_attr "cc" "clobber")])
1224
1225 (define_insn_and_split "udivmodsi4"
1226   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1227                    (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1228                            (match_operand:SI 2 "pseudo_register_operand" "")))
1229               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1230                    (umod:SI (match_dup 1) (match_dup 2)))
1231               (clobber (reg:SI 18))
1232               (clobber (reg:SI 22))
1233               (clobber (reg:HI 26))
1234               (clobber (reg:HI 30))])]
1235   ""
1236   "this udivmodsi4 pattern should have been splitted;"
1237   ""
1238   [(set (reg:SI 22) (match_dup 1))
1239    (set (reg:SI 18) (match_dup 2))
1240    (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1241               (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1242               (clobber (reg:HI 26))
1243               (clobber (reg:HI 30))])
1244    (set (match_dup 0) (reg:SI 18))
1245    (set (match_dup 3) (reg:SI 22))]
1246   "")
1247
1248 (define_insn "*udivmodsi4_call"
1249   [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1250    (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1251    (clobber (reg:HI 26))
1252    (clobber (reg:HI 30))]
1253   ""
1254   "%~call __udivmodsi4"
1255   [(set_attr "type" "xcall")
1256    (set_attr "cc" "clobber")])
1257
1258 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1259 ; and
1260
1261 (define_insn "andqi3"
1262   [(set (match_operand:QI 0 "register_operand" "=r,d")
1263         (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1264                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1265   ""
1266   "@
1267         and %0,%2
1268         andi %0,lo8(%2)"
1269   [(set_attr "length" "1,1")
1270    (set_attr "cc" "set_zn,set_zn")])
1271
1272 (define_insn "andhi3"
1273   [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1274           (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1275                   (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1276    (clobber (match_scratch:QI 3 "=X,X,&d"))]
1277   ""
1278 {
1279   if (which_alternative==0)
1280     return ("and %A0,%A2" CR_TAB
1281             "and %B0,%B2");
1282   else if (which_alternative==1)
1283     {
1284       if (GET_CODE (operands[2]) == CONST_INT)
1285         {
1286           int mask = INTVAL (operands[2]);
1287           if ((mask & 0xff) != 0xff)
1288             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1289           if ((mask & 0xff00) != 0xff00)
1290             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1291           return "";
1292         }
1293         return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1294                 AS2 (andi,%B0,hi8(%2)));
1295      }
1296   return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1297           "and %A0,%3"         CR_TAB
1298           AS1 (clr,%B0));
1299 }
1300   [(set_attr "length" "2,2,3")
1301    (set_attr "cc" "set_n,clobber,set_n")])
1302
1303 (define_insn "andsi3"
1304   [(set (match_operand:SI 0 "register_operand" "=r,d")
1305         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1306                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1307   ""
1308 {
1309   if (which_alternative==0)
1310     return ("and %0,%2"   CR_TAB
1311             "and %B0,%B2" CR_TAB
1312             "and %C0,%C2" CR_TAB
1313             "and %D0,%D2");
1314   else if (which_alternative==1)
1315     {
1316       if (GET_CODE (operands[2]) == CONST_INT)
1317         {
1318           HOST_WIDE_INT mask = INTVAL (operands[2]);
1319           if ((mask & 0xff) != 0xff)
1320             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1321           if ((mask & 0xff00) != 0xff00)
1322             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1323           if ((mask & 0xff0000L) != 0xff0000L)
1324             output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1325           if ((mask & 0xff000000L) != 0xff000000L)
1326             output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1327           return "";
1328         }
1329       return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1330               AS2 (andi, %B0,hi8(%2)) CR_TAB
1331               AS2 (andi, %C0,hlo8(%2)) CR_TAB
1332               AS2 (andi, %D0,hhi8(%2)));
1333     }
1334   return "bug";
1335 }
1336   [(set_attr "length" "4,4")
1337    (set_attr "cc" "set_n,clobber")])
1338
1339 (define_peephole2 ; andi
1340   [(set (match_operand:QI 0 "d_register_operand" "")
1341         (and:QI (match_dup 0)
1342                 (match_operand:QI 1 "const_int_operand" "")))
1343    (set (match_dup 0)
1344         (and:QI (match_dup 0)
1345                 (match_operand:QI 2 "const_int_operand" "")))]
1346   ""
1347   [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1348   {
1349     operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
1350   })
1351
1352 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1353 ;; ior
1354
1355 (define_insn "iorqi3"
1356   [(set (match_operand:QI 0 "register_operand" "=r,d")
1357         (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1358                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1359   ""
1360   "@
1361         or %0,%2
1362         ori %0,lo8(%2)"
1363   [(set_attr "length" "1,1")
1364    (set_attr "cc" "set_zn,set_zn")])
1365
1366 (define_insn "iorhi3"
1367   [(set (match_operand:HI 0 "register_operand" "=r,d")
1368         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1369                 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1370   ""
1371 {
1372   if (which_alternative==0)
1373     return ("or %A0,%A2" CR_TAB
1374             "or %B0,%B2");
1375   if (GET_CODE (operands[2]) == CONST_INT)
1376      {
1377         int mask = INTVAL (operands[2]);
1378         if (mask & 0xff)
1379           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1380         if (mask & 0xff00)
1381           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1382         return "";
1383       }
1384    return (AS2 (ori,%0,lo8(%2)) CR_TAB
1385            AS2 (ori,%B0,hi8(%2)));
1386 }
1387   [(set_attr "length" "2,2")
1388    (set_attr "cc" "set_n,clobber")])
1389
1390 (define_insn "*iorhi3_clobber"
1391   [(set (match_operand:HI 0 "register_operand" "=r,r")
1392         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1393                 (match_operand:HI 2 "immediate_operand" "M,i")))
1394    (clobber (match_scratch:QI 3 "=&d,&d"))]
1395   ""
1396   "@
1397         ldi %3,lo8(%2)\;or %A0,%3
1398         ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1399   [(set_attr "length" "2,4")
1400    (set_attr "cc" "clobber,set_n")])
1401
1402 (define_insn "iorsi3"
1403   [(set (match_operand:SI 0 "register_operand"        "=r,d")
1404         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1405                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1406   ""
1407 {
1408   if (which_alternative==0)
1409     return ("or %0,%2"   CR_TAB
1410             "or %B0,%B2" CR_TAB
1411             "or %C0,%C2" CR_TAB
1412             "or %D0,%D2");
1413   if (GET_CODE (operands[2]) == CONST_INT)
1414      {
1415         HOST_WIDE_INT mask = INTVAL (operands[2]);
1416         if (mask & 0xff)
1417           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1418         if (mask & 0xff00)
1419           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1420         if (mask & 0xff0000L)
1421           output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1422         if (mask & 0xff000000L)
1423           output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1424         return "";
1425       }
1426   return (AS2 (ori, %A0,lo8(%2))  CR_TAB
1427           AS2 (ori, %B0,hi8(%2)) CR_TAB
1428           AS2 (ori, %C0,hlo8(%2)) CR_TAB
1429           AS2 (ori, %D0,hhi8(%2)));
1430 }
1431   [(set_attr "length" "4,4")
1432    (set_attr "cc" "set_n,clobber")])
1433
1434 (define_insn "*iorsi3_clobber"
1435   [(set (match_operand:SI 0 "register_operand"        "=r,r")
1436         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1437                 (match_operand:SI 2 "immediate_operand" "M,i")))
1438    (clobber (match_scratch:QI 3 "=&d,&d"))]
1439   ""
1440   "@
1441         ldi %3,lo8(%2)\;or %A0,%3
1442         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"
1443   [(set_attr "length" "2,8")
1444    (set_attr "cc" "clobber,set_n")])
1445
1446 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1447 ;; xor
1448
1449 (define_insn "xorqi3"
1450   [(set (match_operand:QI 0 "register_operand" "=r")
1451         (xor:QI (match_operand:QI 1 "register_operand" "%0")
1452                 (match_operand:QI 2 "register_operand" "r")))]
1453   ""
1454   "eor %0,%2"
1455   [(set_attr "length" "1")
1456    (set_attr "cc" "set_zn")])
1457
1458 (define_insn "xorhi3"
1459   [(set (match_operand:HI 0 "register_operand" "=r")
1460         (xor:HI (match_operand:HI 1 "register_operand" "%0")
1461                 (match_operand:HI 2 "register_operand" "r")))]
1462   ""
1463   "eor %0,%2
1464         eor %B0,%B2"
1465   [(set_attr "length" "2")
1466    (set_attr "cc" "set_n")])
1467
1468 (define_insn "xorsi3"
1469   [(set (match_operand:SI 0 "register_operand" "=r")
1470         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1471                 (match_operand:SI 2 "register_operand" "r")))]
1472   ""
1473   "eor %0,%2
1474         eor %B0,%B2
1475         eor %C0,%C2
1476         eor %D0,%D2"
1477   [(set_attr "length" "4")
1478    (set_attr "cc" "set_n")])
1479
1480 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
1481 ;; swap
1482
1483 (define_expand "rotlqi3"
1484   [(set (match_operand:QI 0 "register_operand" "")
1485         (rotate:QI (match_operand:QI 1 "register_operand" "")
1486                    (match_operand:QI 2 "const_int_operand" "")))]
1487   ""
1488   "
1489 {
1490   if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
1491     FAIL;
1492 }")
1493
1494 (define_insn "*rotlqi3_4"
1495   [(set (match_operand:QI 0 "register_operand" "=r")
1496         (rotate:QI (match_operand:QI 1 "register_operand" "0")
1497                    (const_int 4)))]
1498   ""
1499   "swap %0"
1500   [(set_attr "length" "1")
1501    (set_attr "cc" "none")])
1502
1503 ;; Split all rotates of HI,SI and DImode registers where rotation is by
1504 ;; a whole number of bytes.  The split creates the appropriate moves and
1505 ;; considers all overlap situations.  DImode is split before reload.
1506
1507 ;; HImode does not need scratch.  Use attribute for this constraint.
1508 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
1509
1510 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
1511 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
1512
1513 (define_expand "rotl<mode>3"
1514   [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
1515                    (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
1516                                 (match_operand:VOID 2 "const_int_operand" "")))
1517                 (clobber (match_operand 3 ""))])]
1518   ""
1519   "
1520 {
1521   if (CONST_INT_P (operands[2]) && 0 == (INTVAL (operands[2]) % 8))
1522   {
1523   if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
1524     operands[3] = gen_reg_rtx (<rotsmode>mode);
1525   else
1526     operands[3] = gen_reg_rtx (QImode);
1527   }
1528   else
1529     FAIL;
1530 }")
1531
1532
1533 ;; Overlapping non-HImode registers often (but not always) need a scratch.
1534 ;; The best we can do is use early clobber alternative "#&r" so that
1535 ;; completely non-overlapping operands dont get a scratch but # so register
1536 ;; allocation does not prefer non-overlapping.
1537
1538
1539 ; Split word aligned rotates using scratch that is mode dependent.
1540 (define_insn_and_split "*rotw<mode>"
1541   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1542         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1543                      (match_operand 2 "immediate_operand" "n,n,n")))
1544    (clobber (match_operand:<rotsmode> 3 "register_operand"  "=<rotx>" ))]
1545   "(CONST_INT_P (operands[2]) &&
1546      (0 == (INTVAL (operands[2]) % 16) && AVR_HAVE_MOVW))"
1547   "#"
1548   "&& (reload_completed || <MODE>mode == DImode)"
1549   [(const_int 0)]
1550   "avr_rotate_bytes (operands);
1551   DONE;"
1552 )
1553
1554
1555 ; Split byte aligned rotates using scratch that is always QI mode.
1556 (define_insn_and_split "*rotb<mode>"
1557   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1558         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1559                      (match_operand 2 "immediate_operand" "n,n,n")))
1560    (clobber (match_operand:QI 3 "register_operand" "=<rotx>" ))]
1561   "(CONST_INT_P (operands[2]) &&
1562      (8 == (INTVAL (operands[2]) % 16)
1563         || (!AVR_HAVE_MOVW && 0 == (INTVAL (operands[2]) % 16))))"
1564   "#"
1565   "&& (reload_completed || <MODE>mode == DImode)"
1566   [(const_int 0)]
1567   "avr_rotate_bytes (operands);
1568   DONE;"
1569 )
1570
1571
1572 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1573 ;; arithmetic shift left
1574
1575 (define_expand "ashlqi3"
1576   [(set (match_operand:QI 0 "register_operand"            "")
1577         (ashift:QI (match_operand:QI 1 "register_operand" "")
1578                    (match_operand:QI 2 "general_operand"  "")))]
1579   ""
1580   "")
1581
1582 (define_split ; ashlqi3_const4
1583   [(set (match_operand:QI 0 "d_register_operand" "")
1584         (ashift:QI (match_dup 0)
1585                    (const_int 4)))]
1586   ""
1587   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1588    (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
1589   "")
1590
1591 (define_split ; ashlqi3_const5
1592   [(set (match_operand:QI 0 "d_register_operand" "")
1593         (ashift:QI (match_dup 0)
1594                    (const_int 5)))]
1595   ""
1596   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1597    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1598    (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
1599   "")
1600
1601 (define_split ; ashlqi3_const6
1602   [(set (match_operand:QI 0 "d_register_operand" "")
1603         (ashift:QI (match_dup 0)
1604                    (const_int 6)))]
1605   ""
1606   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1607    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1608    (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
1609   "")
1610
1611 (define_insn "*ashlqi3"
1612   [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
1613         (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1614                    (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1615   ""
1616   "* return ashlqi3_out (insn, operands, NULL);"
1617   [(set_attr "length" "5,0,1,2,4,6,9")
1618    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1619
1620 (define_insn "ashlhi3"
1621   [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
1622         (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1623                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1624   ""
1625   "* return ashlhi3_out (insn, operands, NULL);"
1626   [(set_attr "length" "6,0,2,2,4,10,10")
1627    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1628
1629 (define_insn "ashlsi3"
1630   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
1631         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1632                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1633   ""
1634   "* return ashlsi3_out (insn, operands, NULL);"
1635   [(set_attr "length" "8,0,4,4,8,10,12")
1636    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1637
1638 ;; Optimize if a scratch register from LD_REGS happens to be available.
1639
1640 (define_peephole2 ; ashlqi3_l_const4
1641   [(set (match_operand:QI 0 "l_register_operand" "")
1642         (ashift:QI (match_dup 0)
1643                    (const_int 4)))
1644    (match_scratch:QI 1 "d")]
1645   ""
1646   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1647    (set (match_dup 1) (const_int -16))
1648    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1649   "")
1650
1651 (define_peephole2 ; ashlqi3_l_const5
1652   [(set (match_operand:QI 0 "l_register_operand" "")
1653         (ashift:QI (match_dup 0)
1654                    (const_int 5)))
1655    (match_scratch:QI 1 "d")]
1656   ""
1657   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1658    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1659    (set (match_dup 1) (const_int -32))
1660    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1661   "")
1662
1663 (define_peephole2 ; ashlqi3_l_const6
1664   [(set (match_operand:QI 0 "l_register_operand" "")
1665         (ashift:QI (match_dup 0)
1666                    (const_int 6)))
1667    (match_scratch:QI 1 "d")]
1668   ""
1669   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1670    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1671    (set (match_dup 1) (const_int -64))
1672    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1673   "")
1674
1675 (define_peephole2
1676   [(match_scratch:QI 3 "d")
1677    (set (match_operand:HI 0 "register_operand" "")
1678         (ashift:HI (match_operand:HI 1 "register_operand" "")
1679                    (match_operand:QI 2 "const_int_operand" "")))]
1680   ""
1681   [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1682               (clobber (match_dup 3))])]
1683   "")
1684
1685 (define_insn "*ashlhi3_const"
1686   [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
1687         (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1688                    (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1689    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1690   "reload_completed"
1691   "* return ashlhi3_out (insn, operands, NULL);"
1692   [(set_attr "length" "0,2,2,4,10")
1693    (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1694
1695 (define_peephole2
1696   [(match_scratch:QI 3 "d")
1697    (set (match_operand:SI 0 "register_operand" "")
1698         (ashift:SI (match_operand:SI 1 "register_operand" "")
1699                    (match_operand:QI 2 "const_int_operand" "")))]
1700   ""
1701   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1702               (clobber (match_dup 3))])]
1703   "")
1704
1705 (define_insn "*ashlsi3_const"
1706   [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
1707         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1708                    (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1709    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1710   "reload_completed"
1711   "* return ashlsi3_out (insn, operands, NULL);"
1712   [(set_attr "length" "0,4,4,10")
1713    (set_attr "cc" "none,set_n,clobber,clobber")])
1714
1715 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1716 ;; arithmetic shift right
1717
1718 (define_insn "ashrqi3"
1719   [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1720         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1721                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
1722   ""
1723   "* return ashrqi3_out (insn, operands, NULL);"
1724   [(set_attr "length" "5,0,1,2,5,9")
1725    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1726
1727 (define_insn "ashrhi3"
1728   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1729         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1730                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1731   ""
1732   "* return ashrhi3_out (insn, operands, NULL);"
1733   [(set_attr "length" "6,0,2,4,4,10,10")
1734    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1735
1736 (define_insn "ashrsi3"
1737   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1738         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1739                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1740   ""
1741   "* return ashrsi3_out (insn, operands, NULL);"
1742   [(set_attr "length" "8,0,4,6,8,10,12")
1743    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1744
1745 ;; Optimize if a scratch register from LD_REGS happens to be available.
1746
1747 (define_peephole2
1748   [(match_scratch:QI 3 "d")
1749    (set (match_operand:HI 0 "register_operand" "")
1750         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1751                      (match_operand:QI 2 "const_int_operand" "")))]
1752   ""
1753   [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1754               (clobber (match_dup 3))])]
1755   "")
1756
1757 (define_insn "*ashrhi3_const"
1758   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1759         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1760                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1761    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1762   "reload_completed"
1763   "* return ashrhi3_out (insn, operands, NULL);"
1764   [(set_attr "length" "0,2,4,4,10")
1765    (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1766
1767 (define_peephole2
1768   [(match_scratch:QI 3 "d")
1769    (set (match_operand:SI 0 "register_operand" "")
1770         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1771                      (match_operand:QI 2 "const_int_operand" "")))]
1772   ""
1773   [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1774               (clobber (match_dup 3))])]
1775   "")
1776
1777 (define_insn "*ashrsi3_const"
1778   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1779         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1780                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1781    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1782   "reload_completed"
1783   "* return ashrsi3_out (insn, operands, NULL);"
1784   [(set_attr "length" "0,4,4,10")
1785    (set_attr "cc" "none,clobber,set_n,clobber")])
1786
1787 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1788 ;; logical shift right
1789
1790 (define_expand "lshrqi3"
1791   [(set (match_operand:QI 0 "register_operand"              "")
1792         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
1793                      (match_operand:QI 2 "general_operand"  "")))]
1794   ""
1795   "")
1796
1797 (define_split   ; lshrqi3_const4
1798   [(set (match_operand:QI 0 "d_register_operand" "")
1799         (lshiftrt:QI (match_dup 0)
1800                      (const_int 4)))]
1801   ""
1802   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1803    (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
1804   "")
1805
1806 (define_split   ; lshrqi3_const5
1807   [(set (match_operand:QI 0 "d_register_operand" "")
1808         (lshiftrt:QI (match_dup 0)
1809                      (const_int 5)))]
1810   ""
1811   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1812    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1813    (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
1814   "")
1815
1816 (define_split   ; lshrqi3_const6
1817   [(set (match_operand:QI 0 "d_register_operand" "")
1818         (lshiftrt:QI (match_dup 0)
1819                      (const_int 6)))]
1820   ""
1821   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1822    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1823    (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
1824   "")
1825
1826 (define_insn "*lshrqi3"
1827   [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
1828         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1829                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1830   ""
1831   "* return lshrqi3_out (insn, operands, NULL);"
1832   [(set_attr "length" "5,0,1,2,4,6,9")
1833    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1834
1835 (define_insn "lshrhi3"
1836   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1837         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1838                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1839   ""
1840   "* return lshrhi3_out (insn, operands, NULL);"
1841   [(set_attr "length" "6,0,2,2,4,10,10")
1842    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1843
1844 (define_insn "lshrsi3"
1845   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1846         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1847                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1848   ""
1849   "* return lshrsi3_out (insn, operands, NULL);"
1850   [(set_attr "length" "8,0,4,4,8,10,12")
1851    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1852
1853 ;; Optimize if a scratch register from LD_REGS happens to be available.
1854
1855 (define_peephole2 ; lshrqi3_l_const4
1856   [(set (match_operand:QI 0 "l_register_operand" "")
1857         (lshiftrt:QI (match_dup 0)
1858                      (const_int 4)))
1859    (match_scratch:QI 1 "d")]
1860   ""
1861   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1862    (set (match_dup 1) (const_int 15))
1863    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1864   "")
1865
1866 (define_peephole2 ; lshrqi3_l_const5
1867   [(set (match_operand:QI 0 "l_register_operand" "")
1868         (lshiftrt:QI (match_dup 0)
1869                      (const_int 5)))
1870    (match_scratch:QI 1 "d")]
1871   ""
1872   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1873    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1874    (set (match_dup 1) (const_int 7))
1875    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1876   "")
1877
1878 (define_peephole2 ; lshrqi3_l_const6
1879   [(set (match_operand:QI 0 "l_register_operand" "")
1880         (lshiftrt:QI (match_dup 0)
1881                      (const_int 6)))
1882    (match_scratch:QI 1 "d")]
1883   ""
1884   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1885    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1886    (set (match_dup 1) (const_int 3))
1887    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1888   "")
1889
1890 (define_peephole2
1891   [(match_scratch:QI 3 "d")
1892    (set (match_operand:HI 0 "register_operand" "")
1893         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1894                      (match_operand:QI 2 "const_int_operand" "")))]
1895   ""
1896   [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1897               (clobber (match_dup 3))])]
1898   "")
1899
1900 (define_insn "*lshrhi3_const"
1901   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1902         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1903                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1904    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1905   "reload_completed"
1906   "* return lshrhi3_out (insn, operands, NULL);"
1907   [(set_attr "length" "0,2,2,4,10")
1908    (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1909
1910 (define_peephole2
1911   [(match_scratch:QI 3 "d")
1912    (set (match_operand:SI 0 "register_operand" "")
1913         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1914                      (match_operand:QI 2 "const_int_operand" "")))]
1915   ""
1916   [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1917               (clobber (match_dup 3))])]
1918   "")
1919
1920 (define_insn "*lshrsi3_const"
1921   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1922         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1923                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1924    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1925   "reload_completed"
1926   "* return lshrsi3_out (insn, operands, NULL);"
1927   [(set_attr "length" "0,4,4,10")
1928    (set_attr "cc" "none,clobber,clobber,clobber")])
1929
1930 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
1931 ;; abs
1932
1933 (define_insn "absqi2"
1934   [(set (match_operand:QI 0 "register_operand" "=r")
1935         (abs:QI (match_operand:QI 1 "register_operand" "0")))]
1936   ""
1937   "sbrc %0,7
1938         neg %0"
1939   [(set_attr "length" "2")
1940    (set_attr "cc" "clobber")])
1941
1942
1943 (define_insn "abssf2"
1944   [(set (match_operand:SF 0 "register_operand" "=d,r")
1945         (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
1946   ""
1947   "@
1948         andi %D0,0x7f
1949         clt\;bld %D0,7"
1950   [(set_attr "length" "1,2")
1951    (set_attr "cc" "set_n,clobber")])
1952
1953 ;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
1954 ;; neg
1955
1956 (define_insn "negqi2"
1957   [(set (match_operand:QI 0 "register_operand" "=r")
1958         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
1959   ""
1960   "neg %0"
1961   [(set_attr "length" "1")
1962    (set_attr "cc" "set_zn")])
1963
1964 (define_insn "neghi2"
1965   [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
1966         (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
1967   ""
1968   "@
1969         com %B0\;neg %A0\;sbci %B0,lo8(-1)
1970         com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
1971         clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
1972   [(set_attr "length" "3,4,4")
1973    (set_attr "cc" "set_czn,set_n,set_czn")])
1974
1975 (define_insn "negsi2"
1976   [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
1977         (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
1978   ""
1979   "@
1980         com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
1981         com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
1982         clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
1983   [(set_attr_alternative "length"
1984                          [(const_int 7)
1985                           (const_int 8)
1986                           (if_then_else (eq_attr "mcu_have_movw" "yes")
1987                                         (const_int 7)
1988                                         (const_int 8))])
1989    (set_attr "cc" "set_czn,set_n,set_czn")])
1990
1991 (define_insn "negsf2"
1992   [(set (match_operand:SF 0 "register_operand" "=d,r")
1993         (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
1994   ""
1995   "@
1996         subi %D0,0x80
1997         bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
1998   [(set_attr "length" "1,4")
1999    (set_attr "cc" "set_n,set_n")])
2000
2001 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2002 ;; not
2003
2004 (define_insn "one_cmplqi2"
2005   [(set (match_operand:QI 0 "register_operand" "=r")
2006         (not:QI (match_operand:QI 1 "register_operand" "0")))]
2007   ""
2008   "com %0"
2009   [(set_attr "length" "1")
2010    (set_attr "cc" "set_czn")])
2011
2012 (define_insn "one_cmplhi2"
2013   [(set (match_operand:HI 0 "register_operand" "=r")
2014         (not:HI (match_operand:HI 1 "register_operand" "0")))]
2015   ""
2016   "com %0
2017         com %B0"
2018   [(set_attr "length" "2")
2019    (set_attr "cc" "set_n")])
2020
2021 (define_insn "one_cmplsi2"
2022   [(set (match_operand:SI 0 "register_operand" "=r")
2023         (not:SI (match_operand:SI 1 "register_operand" "0")))]
2024   ""
2025   "com %0
2026         com %B0
2027         com %C0
2028         com %D0"
2029   [(set_attr "length" "4")
2030    (set_attr "cc" "set_n")])
2031
2032 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2033 ;; sign extend
2034
2035 (define_insn "extendqihi2"
2036   [(set (match_operand:HI 0 "register_operand" "=r,r")
2037         (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
2038   ""
2039   "@
2040         clr %B0\;sbrc %0,7\;com %B0
2041         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2042   [(set_attr "length" "3,4")
2043    (set_attr "cc" "set_n,set_n")])
2044
2045 (define_insn "extendqisi2"
2046   [(set (match_operand:SI 0 "register_operand" "=r,r")
2047         (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
2048   ""
2049   "@
2050         clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2051         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2052   [(set_attr "length" "5,6")
2053    (set_attr "cc" "set_n,set_n")])
2054
2055 (define_insn "extendhisi2"
2056   [(set (match_operand:SI 0 "register_operand"               "=r,&r")
2057         (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
2058   ""
2059   "@
2060         clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2061         {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2062   [(set_attr_alternative "length"
2063                          [(const_int 4)
2064                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2065                                         (const_int 5)
2066                                         (const_int 6))])
2067    (set_attr "cc" "set_n,set_n")])
2068
2069 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2070 ;; zero extend
2071
2072 (define_insn_and_split "zero_extendqihi2"
2073   [(set (match_operand:HI 0 "register_operand" "=r")
2074         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2075   ""
2076   "#"
2077   "reload_completed"
2078   [(set (match_dup 2) (match_dup 1))
2079    (set (match_dup 3) (const_int 0))]
2080   "unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2081    unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2082    
2083    operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2084    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2085   ")
2086
2087 (define_insn_and_split "zero_extendqisi2"
2088   [(set (match_operand:SI 0 "register_operand" "=r")
2089         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2090   ""
2091   "#"
2092   "reload_completed"
2093   [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2094    (set (match_dup 3) (const_int 0))]
2095   "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2096    unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2097    
2098    operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2099    operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2100   ")
2101
2102 (define_insn_and_split "zero_extendhisi2"
2103   [(set (match_operand:SI 0 "register_operand" "=r")
2104         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2105   ""
2106   "#"
2107   "reload_completed"
2108   [(set (match_dup 2) (match_dup 1))
2109    (set (match_dup 3) (const_int 0))]
2110   "unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2111    unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2112    
2113    operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2114    operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2115   ")
2116
2117 (define_insn_and_split "zero_extendqidi2"
2118   [(set (match_operand:DI 0 "register_operand" "=r")
2119         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2120   ""
2121   "#"
2122   "reload_completed"
2123   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2124    (set (match_dup 3) (const_int 0))]
2125   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2126    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2127    
2128    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2129    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2130   ")
2131
2132 (define_insn_and_split "zero_extendhidi2"
2133   [(set (match_operand:DI 0 "register_operand" "=r")
2134         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2135   ""
2136   "#"
2137   "reload_completed"
2138   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2139    (set (match_dup 3) (const_int 0))]
2140   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2141    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2142    
2143    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2144    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2145   ")
2146
2147 (define_insn_and_split "zero_extendsidi2"
2148   [(set (match_operand:DI 0 "register_operand" "=r")
2149         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2150   ""
2151   "#"
2152   "reload_completed"
2153   [(set (match_dup 2) (match_dup 1))
2154    (set (match_dup 3) (const_int 0))]
2155   "unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2156    unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2157    
2158    operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2159    operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2160   ")
2161
2162 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2163 ;; compare
2164
2165 ; Optimize negated tests into reverse compare if overflow is undefined.
2166 (define_insn "*negated_tstqi"
2167   [(set (cc0)
2168         (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2169                  (const_int 0)))]
2170   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2171   "cp __zero_reg__,%0"
2172   [(set_attr "cc" "compare")
2173    (set_attr "length" "1")])
2174
2175 (define_insn "*reversed_tstqi"
2176   [(set (cc0)
2177         (compare (const_int 0)
2178                  (match_operand:QI 0 "register_operand" "r")))]
2179   ""
2180   "cp __zero_reg__,%0"
2181 [(set_attr "cc" "compare")
2182  (set_attr "length" "2")])
2183
2184 (define_insn "*negated_tsthi"
2185   [(set (cc0)
2186         (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2187                  (const_int 0)))]
2188   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2189   "cp __zero_reg__,%A0
2190         cpc __zero_reg__,%B0"
2191 [(set_attr "cc" "compare")
2192  (set_attr "length" "2")])
2193
2194 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2195 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2196 (define_insn "*reversed_tsthi"
2197   [(set (cc0)
2198         (compare (const_int 0)
2199                  (match_operand:HI 0 "register_operand" "r")))
2200    (clobber (match_scratch:QI 1 "=X"))]
2201   ""
2202   "cp __zero_reg__,%A0
2203         cpc __zero_reg__,%B0"
2204 [(set_attr "cc" "compare")
2205  (set_attr "length" "2")])
2206
2207 (define_insn "*negated_tstsi"
2208   [(set (cc0)
2209         (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2210                  (const_int 0)))]
2211   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2212   "cp __zero_reg__,%A0
2213         cpc __zero_reg__,%B0
2214         cpc __zero_reg__,%C0
2215         cpc __zero_reg__,%D0"
2216   [(set_attr "cc" "compare")
2217    (set_attr "length" "4")])
2218
2219 (define_insn "*reversed_tstsi"
2220   [(set (cc0)
2221         (compare (const_int 0)
2222                  (match_operand:SI 0 "register_operand" "r")))
2223    (clobber (match_scratch:QI 1 "=X"))]
2224   ""
2225   "cp __zero_reg__,%A0
2226         cpc __zero_reg__,%B0
2227         cpc __zero_reg__,%C0
2228         cpc __zero_reg__,%D0"
2229   [(set_attr "cc" "compare")
2230    (set_attr "length" "4")])
2231
2232
2233 (define_insn "*cmpqi"
2234   [(set (cc0)
2235         (compare (match_operand:QI 0 "register_operand"  "r,r,d")
2236                  (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
2237   ""
2238   "@
2239         tst %0
2240         cp %0,%1
2241         cpi %0,lo8(%1)"
2242   [(set_attr "cc" "compare,compare,compare")
2243    (set_attr "length" "1,1,1")])
2244
2245 (define_insn "*cmpqi_sign_extend"
2246   [(set (cc0)
2247         (compare (sign_extend:HI
2248                   (match_operand:QI 0 "register_operand"  "d"))
2249                  (match_operand:HI 1 "const_int_operand" "n")))]
2250   "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
2251   "cpi %0,lo8(%1)"
2252   [(set_attr "cc" "compare")
2253    (set_attr "length" "1")])
2254
2255 (define_insn "*cmphi"
2256   [(set (cc0)
2257         (compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
2258                  (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
2259    (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
2260   ""
2261   "*{
2262   switch (which_alternative)
2263     {
2264     case 0: case 1:
2265       return out_tsthi (insn, operands[0], NULL);
2266
2267     case 2:
2268       return (AS2 (cp,%A0,%A1) CR_TAB
2269               AS2 (cpc,%B0,%B1));
2270     case 3:
2271       if (reg_unused_after (insn, operands[0])
2272           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2273           && test_hard_reg_class (ADDW_REGS, operands[0]))
2274         return AS2 (sbiw,%0,%1);
2275        else
2276         return (AS2 (cpi,%0,%1) CR_TAB
2277                 AS2 (cpc,%B0,__zero_reg__));
2278     case 4:
2279       if (reg_unused_after (insn, operands[0]))
2280         return (AS2 (subi,%0,lo8(%1))  CR_TAB
2281                 AS2 (sbci,%B0,hi8(%1)));
2282       else
2283         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
2284                 AS2 (cpi, %A0,lo8(%1)) CR_TAB
2285                 AS2 (cpc, %B0,%2));
2286    case 5:
2287       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2288               AS2 (cp, %A0,%2) CR_TAB
2289               AS2 (cpc, %B0,__zero_reg__));
2290
2291    case 6:
2292       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2293               AS2 (cp, %A0,%2)       CR_TAB
2294               AS2 (ldi, %2,hi8(%1)) CR_TAB
2295               AS2 (cpc, %B0,%2));
2296     }
2297   return \"bug\";
2298 }" 
2299   [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
2300    (set_attr "length" "1,2,2,2,3,3,4")])
2301
2302
2303 (define_insn "*cmpsi"
2304   [(set (cc0)
2305         (compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
2306                  (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
2307    (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
2308   ""
2309   "*{
2310   switch (which_alternative)
2311     {
2312     case 0:
2313       return out_tstsi (insn, operands[0], NULL);
2314
2315     case 1:
2316       return (AS2 (cp,%A0,%A1) CR_TAB
2317               AS2 (cpc,%B0,%B1) CR_TAB
2318               AS2 (cpc,%C0,%C1) CR_TAB
2319               AS2 (cpc,%D0,%D1));
2320     case 2:
2321       if (reg_unused_after (insn, operands[0])
2322           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2323           && test_hard_reg_class (ADDW_REGS, operands[0]))
2324         return (AS2 (sbiw,%0,%1) CR_TAB
2325                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2326                 AS2 (cpc,%D0,__zero_reg__));
2327       else
2328         return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
2329                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2330                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2331                 AS2 (cpc,%D0,__zero_reg__));
2332     case 3:
2333       if (reg_unused_after (insn, operands[0]))
2334         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
2335                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
2336                 AS2 (sbci,%C0,hlo8(%1))  CR_TAB
2337                 AS2 (sbci,%D0,hhi8(%1)));
2338       else
2339        return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
2340                AS2 (ldi, %2,hi8(%1))  CR_TAB
2341                AS2 (cpc, %B0,%2)       CR_TAB
2342                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2343                AS2 (cpc, %C0,%2)       CR_TAB
2344                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2345                AS2 (cpc, %D0,%2));
2346     case 4:
2347         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
2348                 AS2 (cp,%A0,%2)            CR_TAB
2349                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2350                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2351                 AS2 (cpc,%D0,__zero_reg__));
2352     case 5:
2353        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
2354                AS2 (cp, %A0,%2)        CR_TAB
2355                AS2 (ldi, %2,hi8(%1))  CR_TAB
2356                AS2 (cpc, %B0,%2)       CR_TAB
2357                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2358                AS2 (cpc, %C0,%2)       CR_TAB
2359                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2360                AS2 (cpc, %D0,%2));
2361     }
2362   return \"bug\";
2363 }"
2364   [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
2365    (set_attr "length" "4,4,4,7,5,8")])
2366
2367
2368 ;; ----------------------------------------------------------------------
2369 ;; JUMP INSTRUCTIONS
2370 ;; ----------------------------------------------------------------------
2371 ;; Conditional jump instructions
2372
2373 (define_expand "cbranchsi4"
2374   [(parallel [(set (cc0)
2375                    (compare (match_operand:SI 1 "register_operand" "")
2376                             (match_operand:SI 2 "nonmemory_operand" "")))
2377               (clobber (match_scratch:QI 4 ""))])
2378    (set (pc)
2379         (if_then_else
2380               (match_operator 0 "ordered_comparison_operator" [(cc0)
2381                                                                (const_int 0)])
2382               (label_ref (match_operand 3 "" ""))
2383               (pc)))]
2384  "")
2385
2386 (define_expand "cbranchhi4"
2387   [(parallel [(set (cc0)
2388                    (compare (match_operand:HI 1 "register_operand" "")
2389                             (match_operand:HI 2 "nonmemory_operand" "")))
2390               (clobber (match_scratch:QI 4 ""))])
2391    (set (pc)
2392         (if_then_else
2393               (match_operator 0 "ordered_comparison_operator" [(cc0)
2394                                                                (const_int 0)])
2395               (label_ref (match_operand 3 "" ""))
2396               (pc)))]
2397  "")
2398
2399 (define_expand "cbranchqi4"
2400   [(set (cc0)
2401         (compare (match_operand:QI 1 "register_operand" "")
2402                  (match_operand:QI 2 "nonmemory_operand" "")))
2403    (set (pc)
2404         (if_then_else
2405               (match_operator 0 "ordered_comparison_operator" [(cc0)
2406                                                                (const_int 0)])
2407               (label_ref (match_operand 3 "" ""))
2408               (pc)))]
2409  "")
2410
2411
2412 ;; Test a single bit in a QI/HI/SImode register.
2413 ;; Combine will create zero extract patterns for single bit tests.
2414 ;; permit any mode in source pattern by using VOIDmode.
2415
2416 (define_insn "*sbrx_branch<mode>"
2417   [(set (pc)
2418         (if_then_else
2419          (match_operator 0 "eqne_operator"
2420                          [(zero_extract:QIDI
2421                            (match_operand:VOID 1 "register_operand" "r")
2422                            (const_int 1)
2423                            (match_operand 2 "const_int_operand" "n"))
2424                           (const_int 0)])
2425          (label_ref (match_operand 3 "" ""))
2426          (pc)))]
2427   ""
2428   "* return avr_out_sbxx_branch (insn, operands);"
2429   [(set (attr "length")
2430         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2431                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2432                       (const_int 2)
2433                       (if_then_else (eq_attr "mcu_mega" "no")
2434                                     (const_int 2)
2435                                     (const_int 4))))
2436    (set_attr "cc" "clobber")])
2437
2438 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
2439 ;; or for old peepholes.
2440 ;; Fixme - bitwise Mask will not work for DImode
2441
2442 (define_insn "*sbrx_and_branch<mode>"
2443   [(set (pc)
2444         (if_then_else
2445          (match_operator 0 "eqne_operator"
2446                          [(and:QISI
2447                            (match_operand:QISI 1 "register_operand" "r")
2448                            (match_operand:QISI 2 "single_one_operand" "n"))
2449                           (const_int 0)])
2450          (label_ref (match_operand 3 "" ""))
2451          (pc)))]
2452   ""
2453 {
2454     HOST_WIDE_INT bitnumber;
2455     bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
2456     operands[2] = GEN_INT (bitnumber);
2457     return avr_out_sbxx_branch (insn, operands);
2458 }
2459   [(set (attr "length")
2460         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2461                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2462                       (const_int 2)
2463                       (if_then_else (eq_attr "mcu_mega" "no")
2464                                     (const_int 2)
2465                                     (const_int 4))))
2466    (set_attr "cc" "clobber")])
2467
2468 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
2469 (define_peephole2
2470   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2471                        (const_int 0)))
2472    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2473                            (label_ref (match_operand 1 "" ""))
2474                            (pc)))]
2475   ""
2476   [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
2477                                                 (const_int 1)
2478                                                 (const_int 7))
2479                                (const_int 0))
2480                            (label_ref (match_dup 1))
2481                            (pc)))]
2482   "")
2483
2484 (define_peephole2
2485   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2486                        (const_int 0)))
2487    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2488                            (label_ref (match_operand 1 "" ""))
2489                            (pc)))]
2490   ""
2491   [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
2492                                                 (const_int 1)
2493                                                 (const_int 7))
2494                                (const_int 0))
2495                            (label_ref (match_dup 1))
2496                            (pc)))]
2497   "")
2498
2499 (define_peephole2
2500   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2501                                   (const_int 0)))
2502               (clobber (match_operand:HI 2 ""))])
2503    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2504                            (label_ref (match_operand 1 "" ""))
2505                            (pc)))]
2506   ""
2507   [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
2508                                (const_int 0))
2509                            (label_ref (match_dup 1))
2510                            (pc)))]
2511   "")
2512
2513 (define_peephole2
2514   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2515                                   (const_int 0)))
2516               (clobber (match_operand:HI 2 ""))])
2517    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2518                            (label_ref (match_operand 1 "" ""))
2519                            (pc)))]
2520   ""
2521   [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
2522                                (const_int 0))
2523                            (label_ref (match_dup 1))
2524                            (pc)))]
2525   "")
2526
2527 (define_peephole2
2528   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2529                                   (const_int 0)))
2530               (clobber (match_operand:SI 2 ""))])
2531    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2532                            (label_ref (match_operand 1 "" ""))
2533                            (pc)))]
2534   ""
2535   [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
2536                                (const_int 0))
2537                            (label_ref (match_dup 1))
2538                            (pc)))]
2539   "operands[2] = GEN_INT (-2147483647 - 1);")
2540
2541 (define_peephole2
2542   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2543                                   (const_int 0)))
2544               (clobber (match_operand:SI 2 ""))])
2545    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2546                            (label_ref (match_operand 1 "" ""))
2547                            (pc)))]
2548   ""
2549   [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
2550                                (const_int 0))
2551                            (label_ref (match_dup 1))
2552                            (pc)))]
2553   "operands[2] = GEN_INT (-2147483647 - 1);")
2554
2555 ;; ************************************************************************
2556 ;; Implementation of conditional jumps here.
2557 ;;  Compare with 0 (test) jumps
2558 ;; ************************************************************************
2559
2560 (define_insn "branch"
2561   [(set (pc)
2562         (if_then_else (match_operator 1 "simple_comparison_operator"
2563                         [(cc0)
2564                          (const_int 0)])
2565                       (label_ref (match_operand 0 "" ""))
2566                       (pc)))]
2567   ""
2568   "*
2569    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2570   [(set_attr "type" "branch")
2571    (set_attr "cc" "clobber")])
2572
2573 ;; ****************************************************************
2574 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
2575 ;; Convert them all to proper jumps.
2576 ;; ****************************************************************/
2577
2578 (define_insn "difficult_branch"
2579   [(set (pc)
2580         (if_then_else (match_operator 1 "difficult_comparison_operator"
2581                         [(cc0)
2582                          (const_int 0)])
2583                       (label_ref (match_operand 0 "" ""))
2584                       (pc)))]
2585   ""
2586   "*
2587    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2588   [(set_attr "type" "branch1")
2589    (set_attr "cc" "clobber")])
2590
2591 ;; revers branch
2592
2593 (define_insn "rvbranch"
2594   [(set (pc)
2595         (if_then_else (match_operator 1 "simple_comparison_operator" 
2596                         [(cc0)
2597                          (const_int 0)])
2598                       (pc)
2599                       (label_ref (match_operand 0 "" ""))))]
2600   ""
2601   "*
2602    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2603   [(set_attr "type" "branch1")
2604    (set_attr "cc" "clobber")])
2605
2606 (define_insn "difficult_rvbranch"
2607   [(set (pc)
2608         (if_then_else (match_operator 1 "difficult_comparison_operator" 
2609                         [(cc0)
2610                          (const_int 0)])
2611                       (pc)
2612                       (label_ref (match_operand 0 "" ""))))]
2613   ""
2614   "*
2615    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2616   [(set_attr "type" "branch")
2617    (set_attr "cc" "clobber")])
2618
2619 ;; **************************************************************************
2620 ;; Unconditional and other jump instructions.
2621
2622 (define_insn "jump"
2623   [(set (pc)
2624         (label_ref (match_operand 0 "" "")))]
2625   ""
2626   "*{
2627   if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
2628     return AS1 (jmp,%x0);
2629   return AS1 (rjmp,%x0);
2630 }"
2631   [(set (attr "length")
2632         (if_then_else (match_operand 0 "symbol_ref_operand" "") 
2633                 (if_then_else (eq_attr "mcu_mega" "no")
2634                               (const_int 1)
2635                               (const_int 2))
2636                 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2637                                    (le (minus (pc) (match_dup 0)) (const_int 2047)))
2638                               (const_int 1)
2639                               (const_int 2))))
2640    (set_attr "cc" "none")])
2641
2642 ;; call
2643
2644 (define_expand "call"
2645   [(call (match_operand:HI 0 "call_insn_operand" "")
2646          (match_operand:HI 1 "general_operand" ""))]
2647   ;; Operand 1 not used on the AVR.
2648   ""
2649   "")
2650
2651 ;; call value
2652
2653 (define_expand "call_value"
2654   [(set (match_operand 0 "register_operand" "")
2655         (call (match_operand:HI 1 "call_insn_operand" "")
2656               (match_operand:HI 2 "general_operand" "")))]
2657   ;; Operand 2 not used on the AVR.
2658   ""
2659   "")
2660
2661 (define_insn "call_insn"
2662   [(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "!z,*r,s,n"))
2663          (match_operand:HI 1 "general_operand" "X,X,X,X"))]
2664 ;; We don't need in saving Z register because r30,r31 is a call used registers
2665   ;; Operand 1 not used on the AVR.
2666   "(register_operand (operands[0], HImode) || CONSTANT_P (operands[0]))"
2667   "*{
2668   if (which_alternative==0)
2669      return \"%!icall\";
2670   else if (which_alternative==1)
2671     {
2672       if (AVR_HAVE_MOVW)
2673         return (AS2 (movw, r30, %0) CR_TAB
2674                \"%!icall\");
2675       else
2676         return (AS2 (mov, r30, %A0) CR_TAB
2677                 AS2 (mov, r31, %B0) CR_TAB
2678                 \"%!icall\");
2679     }
2680   else if (which_alternative==2)
2681     return AS1(%~call,%x0);
2682   return (AS2 (ldi,r30,lo8(%0)) CR_TAB
2683           AS2 (ldi,r31,hi8(%0)) CR_TAB
2684           \"%!icall\");
2685 }"
2686   [(set_attr "cc" "clobber,clobber,clobber,clobber")
2687    (set_attr_alternative "length"
2688                          [(const_int 1)
2689                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2690                                         (const_int 2)
2691                                         (const_int 3))
2692                           (if_then_else (eq_attr "mcu_mega" "yes")
2693                                         (const_int 2)
2694                                         (const_int 1))
2695                           (const_int 3)])])
2696
2697 (define_insn "call_value_insn"
2698   [(set (match_operand 0 "register_operand" "=r,r,r,r")
2699         (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "!z,*r,s,n"))
2700 ;; We don't need in saving Z register because r30,r31 is a call used registers
2701               (match_operand:HI 2 "general_operand" "X,X,X,X")))]
2702   ;; Operand 2 not used on the AVR.
2703   "(register_operand (operands[0], VOIDmode) || CONSTANT_P (operands[0]))"
2704   "*{
2705   if (which_alternative==0)
2706      return \"%!icall\";
2707   else if (which_alternative==1)
2708     {
2709       if (AVR_HAVE_MOVW)
2710         return (AS2 (movw, r30, %1) CR_TAB
2711                 \"%!icall\");
2712       else
2713         return (AS2 (mov, r30, %A1) CR_TAB
2714                 AS2 (mov, r31, %B1) CR_TAB
2715                 \"%!icall\");
2716     }
2717   else if (which_alternative==2)
2718     return AS1(%~call,%x1);
2719   return (AS2 (ldi, r30, lo8(%1)) CR_TAB
2720           AS2 (ldi, r31, hi8(%1)) CR_TAB
2721           \"%!icall\");
2722 }"
2723   [(set_attr "cc" "clobber,clobber,clobber,clobber")
2724    (set_attr_alternative "length"
2725                          [(const_int 1)
2726                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2727                                         (const_int 2)
2728                                         (const_int 3))
2729                           (if_then_else (eq_attr "mcu_mega" "yes")
2730                                         (const_int 2)
2731                                         (const_int 1))
2732                           (const_int 3)])])
2733
2734 (define_insn "nop"
2735   [(const_int 0)]
2736   ""
2737   "nop"
2738   [(set_attr "cc" "none")
2739    (set_attr "length" "1")])
2740
2741 ; indirect jump
2742
2743 (define_expand "indirect_jump"
2744   [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
2745   ""
2746   " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
2747     {
2748       operands[0] = copy_to_mode_reg(HImode, operand0);
2749     }"
2750 )
2751
2752 ; indirect jump
2753 (define_insn "*jcindirect_jump"
2754   [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
2755   ""
2756   "@
2757         %~jmp %x0"
2758   [(set_attr "length" "2")
2759    (set_attr "cc" "none")])
2760
2761 ;;
2762 (define_insn "*njcindirect_jump"
2763   [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2764   "!AVR_HAVE_EIJMP_EICALL"
2765   "@
2766         ijmp
2767         push %A0\;push %B0\;ret"
2768   [(set_attr "length" "1,3")
2769    (set_attr "cc" "none,none")])
2770
2771 (define_insn "*indirect_jump_avr6"
2772   [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
2773   "AVR_HAVE_EIJMP_EICALL"
2774   "eijmp"
2775   [(set_attr "length" "1")
2776    (set_attr "cc" "none")])
2777
2778 ;; table jump
2779
2780 ;; Table made from "rjmp" instructions for <=8K devices.
2781 (define_insn "*tablejump_rjmp"
2782   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2783                         UNSPEC_INDEX_JMP))
2784    (use (label_ref (match_operand 1 "" "")))
2785    (clobber (match_dup 0))]
2786   "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
2787   "@
2788         ijmp
2789         push %A0\;push %B0\;ret"
2790   [(set_attr "length" "1,3")
2791    (set_attr "cc" "none,none")])
2792
2793 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2794 (define_insn "*tablejump_lib"
2795   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2796                         UNSPEC_INDEX_JMP))
2797    (use (label_ref (match_operand 1 "" "")))
2798    (clobber (match_dup 0))]
2799   "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
2800   "%~jmp __tablejump2__"
2801   [(set_attr "length" "2")
2802    (set_attr "cc" "clobber")])
2803
2804 (define_insn "*tablejump_enh"
2805   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2806                         UNSPEC_INDEX_JMP))
2807    (use (label_ref (match_operand 1 "" "")))
2808    (clobber (match_dup 0))]
2809   "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
2810   "lsl r30
2811         rol r31
2812         lpm __tmp_reg__,Z+
2813         lpm r31,Z
2814         mov r30,__tmp_reg__
2815         %!ijmp"
2816   [(set_attr "length" "6")
2817    (set_attr "cc" "clobber")])
2818
2819 (define_insn "*tablejump"
2820   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2821                         UNSPEC_INDEX_JMP))
2822    (use (label_ref (match_operand 1 "" "")))
2823    (clobber (match_dup 0))]
2824   "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
2825   "lsl r30
2826         rol r31
2827         lpm
2828         inc r30
2829         push r0
2830         lpm
2831         push r0
2832         ret"
2833   [(set_attr "length" "8")
2834    (set_attr "cc" "clobber")])
2835
2836 (define_expand "casesi"
2837   [(set (match_dup 6)
2838         (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2839                   (match_operand:HI 1 "register_operand" "")))
2840    (parallel [(set (cc0)
2841                    (compare (match_dup 6)
2842                             (match_operand:HI 2 "register_operand" "")))
2843               (clobber (match_scratch:QI 9 ""))])
2844    
2845    (set (pc)
2846         (if_then_else (gtu (cc0)
2847                            (const_int 0))
2848                       (label_ref (match_operand 4 "" ""))
2849                       (pc)))
2850
2851    (set (match_dup 6)
2852         (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2853
2854    (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2855               (use (label_ref (match_dup 3)))
2856               (clobber (match_dup 6))])]
2857   ""
2858   "
2859 {
2860   operands[6] = gen_reg_rtx (HImode);
2861 }")
2862
2863
2864 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2865 ;; This instruction sets Z flag
2866
2867 (define_insn "sez"
2868   [(set (cc0) (const_int 0))]
2869   ""
2870   "sez"
2871   [(set_attr "length" "1")
2872    (set_attr "cc" "compare")])
2873
2874 ;; Clear/set/test a single bit in I/O address space.
2875
2876 (define_insn "*cbi"
2877   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2878         (and:QI (mem:QI (match_dup 0))
2879                 (match_operand:QI 1 "single_zero_operand" "n")))]
2880   "(optimize > 0)"
2881 {
2882   operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2883   return AS2 (cbi,%m0-0x20,%2);
2884 }
2885   [(set_attr "length" "1")
2886    (set_attr "cc" "none")])
2887
2888 (define_insn "*sbi"
2889   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2890         (ior:QI (mem:QI (match_dup 0))
2891                 (match_operand:QI 1 "single_one_operand" "n")))]
2892   "(optimize > 0)"
2893 {
2894   operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2895   return AS2 (sbi,%m0-0x20,%2);
2896 }
2897   [(set_attr "length" "1")
2898    (set_attr "cc" "none")])
2899
2900 ;; Lower half of the I/O space - use sbic/sbis directly.
2901 (define_insn "*sbix_branch"
2902   [(set (pc)
2903         (if_then_else
2904          (match_operator 0 "eqne_operator"
2905                          [(zero_extract:HI
2906                            (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2907                            (const_int 1)
2908                            (match_operand 2 "const_int_operand" "n"))
2909                           (const_int 0)])
2910          (label_ref (match_operand 3 "" ""))
2911          (pc)))]
2912   "(optimize > 0)"
2913   "* return avr_out_sbxx_branch (insn, operands);"
2914   [(set (attr "length")
2915         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2916                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2917                       (const_int 2)
2918                       (if_then_else (eq_attr "mcu_mega" "no")
2919                                     (const_int 2)
2920                                     (const_int 4))))
2921    (set_attr "cc" "clobber")])
2922
2923 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
2924 (define_insn "*sbix_branch_bit7"
2925   [(set (pc)
2926         (if_then_else
2927          (match_operator 0 "gelt_operator"
2928                          [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
2929                           (const_int 0)])
2930          (label_ref (match_operand 2 "" ""))
2931          (pc)))]
2932   "(optimize > 0)"
2933 {
2934   operands[3] = operands[2];
2935   operands[2] = GEN_INT (7);
2936   return avr_out_sbxx_branch (insn, operands);
2937 }
2938   [(set (attr "length")
2939         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2940                            (le (minus (pc) (match_dup 2)) (const_int 2046)))
2941                       (const_int 2)
2942                       (if_then_else (eq_attr "mcu_mega" "no")
2943                                     (const_int 2)
2944                                     (const_int 4))))
2945    (set_attr "cc" "clobber")])
2946
2947 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
2948 (define_insn "*sbix_branch_tmp"
2949   [(set (pc)
2950         (if_then_else
2951          (match_operator 0 "eqne_operator"
2952                          [(zero_extract:HI
2953                            (mem:QI (match_operand 1 "high_io_address_operand" "n"))
2954                            (const_int 1)
2955                            (match_operand 2 "const_int_operand" "n"))
2956                           (const_int 0)])
2957          (label_ref (match_operand 3 "" ""))
2958          (pc)))]
2959   "(optimize > 0)"
2960   "* return avr_out_sbxx_branch (insn, operands);"
2961   [(set (attr "length")
2962         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2963                            (le (minus (pc) (match_dup 3)) (const_int 2045)))
2964                       (const_int 3)
2965                       (if_then_else (eq_attr "mcu_mega" "no")
2966                                     (const_int 3)
2967                                     (const_int 5))))
2968    (set_attr "cc" "clobber")])
2969
2970 (define_insn "*sbix_branch_tmp_bit7"
2971   [(set (pc)
2972         (if_then_else
2973          (match_operator 0 "gelt_operator"
2974                          [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
2975                           (const_int 0)])
2976          (label_ref (match_operand 2 "" ""))
2977          (pc)))]
2978   "(optimize > 0)"
2979 {
2980   operands[3] = operands[2];
2981   operands[2] = GEN_INT (7);
2982   return avr_out_sbxx_branch (insn, operands);
2983 }
2984   [(set (attr "length")
2985         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
2986                            (le (minus (pc) (match_dup 2)) (const_int 2045)))
2987                       (const_int 3)
2988                       (if_then_else (eq_attr "mcu_mega" "no")
2989                                     (const_int 3)
2990                                     (const_int 5))))
2991    (set_attr "cc" "clobber")])
2992
2993 ;; ************************* Peepholes ********************************
2994
2995 (define_peephole
2996   [(set (match_operand:SI 0 "d_register_operand" "")
2997         (plus:SI (match_dup 0)
2998                  (const_int -1)))
2999    (parallel
3000     [(set (cc0)
3001           (compare (match_dup 0)
3002                    (const_int -1)))
3003      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3004    (set (pc)
3005         (if_then_else (ne (cc0) (const_int 0))
3006                       (label_ref (match_operand 2 "" ""))
3007                       (pc)))]
3008   ""
3009   "*
3010 {
3011   CC_STATUS_INIT;
3012   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3013     output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3014                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3015                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3016   else
3017     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3018                      AS2 (sbc,%B0,__zero_reg__) CR_TAB
3019                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3020                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3021   switch (avr_jump_mode (operands[2],insn))
3022   {
3023     case 1:
3024       return AS1 (brcc,%2);
3025     case 2:
3026       return (AS1 (brcs,.+2) CR_TAB
3027               AS1 (rjmp,%2));
3028   }
3029   return (AS1 (brcs,.+4) CR_TAB
3030           AS1 (jmp,%2));
3031 }")
3032
3033 (define_peephole
3034   [(set (match_operand:HI 0 "d_register_operand" "")
3035         (plus:HI (match_dup 0)
3036                  (const_int -1)))
3037    (parallel
3038     [(set (cc0)
3039           (compare (match_dup 0)
3040                    (const_int 65535)))
3041      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3042    (set (pc)
3043         (if_then_else (ne (cc0) (const_int 0))
3044                       (label_ref (match_operand 2 "" ""))
3045                       (pc)))]
3046   ""
3047   "*
3048 {
3049   CC_STATUS_INIT;
3050   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3051     output_asm_insn (AS2 (sbiw,%0,1), operands);
3052   else
3053     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3054                      AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3055   switch (avr_jump_mode (operands[2],insn))
3056   {
3057     case 1:
3058       return AS1 (brcc,%2);
3059     case 2:
3060       return (AS1 (brcs,.+2) CR_TAB
3061               AS1 (rjmp,%2));
3062   }
3063   return (AS1 (brcs,.+4) CR_TAB
3064           AS1 (jmp,%2));
3065 }")
3066
3067 (define_peephole
3068   [(set (match_operand:QI 0 "d_register_operand" "")
3069         (plus:QI (match_dup 0)
3070                  (const_int -1)))
3071    (set (cc0)
3072         (compare (match_dup 0)
3073                  (const_int -1)))
3074    (set (pc)
3075         (if_then_else (ne (cc0) (const_int 0))
3076                       (label_ref (match_operand 1 "" ""))
3077                       (pc)))]
3078   ""
3079   "*
3080 {
3081   CC_STATUS_INIT;
3082   cc_status.value1 = operands[0];
3083   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3084   output_asm_insn (AS2 (subi,%A0,1), operands);
3085   switch (avr_jump_mode (operands[1],insn))
3086   {
3087     case 1:
3088       return AS1 (brcc,%1);
3089     case 2:
3090       return (AS1 (brcs,.+2) CR_TAB
3091               AS1 (rjmp,%1));
3092   }
3093   return (AS1 (brcs,.+4) CR_TAB
3094           AS1 (jmp,%1));
3095 }")
3096
3097 (define_peephole
3098   [(set (cc0)
3099         (compare (match_operand:QI 0 "register_operand" "")
3100                  (const_int 0)))
3101    (set (pc)
3102         (if_then_else (eq (cc0) (const_int 0))
3103                       (label_ref (match_operand 1 "" ""))
3104                       (pc)))]
3105   "jump_over_one_insn_p (insn, operands[1])"
3106   "cpse %0,__zero_reg__")
3107
3108 (define_peephole
3109   [(set (cc0)
3110         (compare (match_operand:QI 0 "register_operand" "")
3111                  (match_operand:QI 1 "register_operand" "")))
3112    (set (pc)
3113         (if_then_else (eq (cc0) (const_int 0))
3114                       (label_ref (match_operand 2 "" ""))
3115                       (pc)))]
3116   "jump_over_one_insn_p (insn, operands[2])"
3117   "cpse %0,%1")
3118
3119 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3120 ;;prologue/epilogue support instructions
3121
3122 (define_insn "popqi"
3123   [(set (match_operand:QI 0 "register_operand" "=r")
3124         (mem:QI (post_inc (reg:HI REG_SP))))]
3125   ""
3126   "pop %0"
3127   [(set_attr "cc" "none")
3128    (set_attr "length" "1")])
3129
3130 (define_insn "pophi"
3131   [(set (match_operand:HI 0 "register_operand" "=r")
3132         (mem:HI (post_inc (reg:HI REG_SP))))]
3133   ""
3134   "pop %A0\;pop %B0"
3135   [(set_attr "cc" "none")
3136    (set_attr "length" "2")])
3137
3138 ;; Enable Interrupts
3139 (define_insn "enable_interrupt"
3140   [(unspec [(const_int 0)] UNSPEC_SEI)]
3141   ""
3142   "sei"
3143   [(set_attr "length" "1")
3144   (set_attr "cc" "none")
3145   ])
3146
3147 ;; Disable Interrupts
3148 (define_insn "disable_interrupt"
3149   [(unspec [(const_int 0)] UNSPEC_CLI)]
3150   ""
3151   "cli"
3152   [(set_attr "length" "1")
3153   (set_attr "cc" "none")
3154   ])
3155
3156 ;;  Library prologue saves
3157 (define_insn "call_prologue_saves"
3158   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3159    (match_operand:HI 0 "immediate_operand" "")
3160    (set (reg:HI REG_SP) (minus:HI 
3161                            (reg:HI REG_SP)
3162                            (match_operand:HI 1 "immediate_operand" "")))
3163    (use (reg:HI REG_X))
3164    (clobber (reg:HI REG_Z))]
3165   ""
3166   "ldi r30,lo8(gs(1f))
3167         ldi r31,hi8(gs(1f))
3168         %~jmp __prologue_saves__+((18 - %0) * 2)
3169 1:"
3170   [(set_attr_alternative "length"
3171                          [(if_then_else (eq_attr "mcu_mega" "yes")
3172                                         (const_int 6)
3173                                         (const_int 5))])
3174   (set_attr "cc" "clobber")
3175   ])
3176   
3177 ;  epilogue  restores using library
3178 (define_insn "epilogue_restores"
3179   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3180    (set (reg:HI REG_Y ) (plus:HI 
3181                            (reg:HI REG_Y)
3182                            (match_operand:HI 0 "immediate_operand" ""))) 
3183    (set (reg:HI REG_SP) (reg:HI REG_Y))
3184    (clobber  (reg:QI REG_Z))]
3185   ""
3186   "ldi r30, lo8(%0)
3187         %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3188   [(set_attr_alternative "length"
3189                          [(if_then_else (eq_attr "mcu_mega" "yes")
3190                                         (const_int 3)
3191                                         (const_int 2))])
3192   (set_attr "cc" "clobber")
3193   ])
3194   
3195 ; return
3196 (define_insn "return"
3197   [(return)]
3198   "reload_completed && avr_simple_epilogue ()"
3199   "ret"
3200   [(set_attr "cc" "none")
3201    (set_attr "length" "1")])
3202
3203 (define_insn "return_from_epilogue"
3204   [(return)]
3205   "(reload_completed 
3206     && cfun->machine 
3207     && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3208     && !cfun->machine->is_naked)"
3209   "ret"
3210   [(set_attr "cc" "none")
3211    (set_attr "length" "1")])
3212
3213 (define_insn "return_from_interrupt_epilogue"
3214   [(return)]
3215   "(reload_completed 
3216     && cfun->machine 
3217     && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3218     && !cfun->machine->is_naked)"
3219   "reti"
3220   [(set_attr "cc" "none")
3221    (set_attr "length" "1")])
3222
3223 (define_insn "return_from_naked_epilogue"
3224   [(return)]
3225   "(reload_completed 
3226     && cfun->machine 
3227     && cfun->machine->is_naked)"
3228   ""
3229   [(set_attr "cc" "none")
3230    (set_attr "length" "0")])
3231
3232 (define_expand "prologue"
3233   [(const_int 0)]
3234   ""
3235   "
3236   {
3237     expand_prologue (); 
3238     DONE;
3239   }")
3240
3241 (define_expand "epilogue"
3242   [(const_int 0)]
3243   ""
3244   "
3245   {
3246     expand_epilogue (); 
3247     DONE;
3248   }")