OSDN Git Service

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