OSDN Git Service

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