OSDN Git Service

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