avr.md (*reload_insi): Change predicate #1 to const_int_operand.
[platform/upstream/gcc.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 ; *reload_insi
406   [(match_scratch:QI 2 "d")
407    (set (match_operand:SI 0 "l_register_operand" "")
408         (match_operand:SI 1 "const_int_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 "const_int_operand" "n"))
420    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
421   "reload_completed"
422   {
423     return output_reload_insisf (insn, operands, operands[2], NULL);
424   }
425   [(set_attr "length" "8")
426    (set_attr "cc" "clobber")])
427
428
429 (define_insn "*movsi"
430   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
431         (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
432   "(register_operand (operands[0],SImode)
433     || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
434   {
435     return output_movsisf (insn, operands, NULL_RTX, NULL);
436   }
437   [(set_attr "length" "4,4,8,9,4,10")
438    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
439
440 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
441 ;; move floating point numbers (32 bit)
442
443 (define_expand "movsf"
444   [(set (match_operand:SF 0 "nonimmediate_operand" "")
445         (match_operand:SF 1 "general_operand"  ""))]
446   ""
447   "
448 {
449   /* One of the ops has to be in a register.  */
450   if (!register_operand (operand1, SFmode)
451       && !register_operand (operand0, SFmode))
452     {
453       operands[1] = copy_to_mode_reg (SFmode, operand1);
454     }
455 }")
456
457 (define_insn "*movsf"
458   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
459         (match_operand:SF 1 "general_operand"       "r,G,Qm,rG,F,F"))]
460   "register_operand (operands[0], SFmode)
461    || register_operand (operands[1], SFmode)
462    || operands[1] == CONST0_RTX (SFmode)"
463   {
464     return output_movsisf (insn, operands, NULL_RTX, NULL);
465   }
466   [(set_attr "length" "4,4,8,9,4,10")
467    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
468
469 (define_peephole2 ; *reload_insf
470   [(match_scratch:QI 2 "d")
471    (set (match_operand:SF 0 "l_register_operand" "")
472         (match_operand:SF 1 "const_double_operand" ""))
473    (match_dup 2)]
474   "operands[1] != CONST0_RTX (SFmode)"
475   [(parallel [(set (match_dup 0) 
476                    (match_dup 1))
477               (clobber (match_dup 2))])]
478   "")
479
480 ;; '*' because it is not used in rtl generation.
481 (define_insn "*reload_insf"
482   [(set (match_operand:SF 0 "register_operand" "=r")
483         (match_operand:SF 1 "const_double_operand" "F"))
484    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
485   "reload_completed"
486   {
487     return output_reload_insisf (insn, operands, operands[2], NULL);
488   }
489   [(set_attr "length" "8")
490    (set_attr "cc" "clobber")])
491
492 ;;=========================================================================
493 ;; move string (like memcpy)
494 ;; implement as RTL loop
495
496 (define_expand "movmemhi"
497   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
498           (match_operand:BLK 1 "memory_operand" ""))
499           (use (match_operand:HI 2 "const_int_operand" ""))
500           (use (match_operand:HI 3 "const_int_operand" ""))])]
501   ""
502   "{
503   int prob;
504   HOST_WIDE_INT count;
505   enum machine_mode mode;
506   rtx label = gen_label_rtx ();
507   rtx loop_reg;
508   rtx jump;
509
510   /* Copy pointers into new psuedos - they will be changed.  */
511   rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
512   rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
513
514   /* Create rtx for tmp register - we use this as scratch.  */
515   rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
516
517   if (GET_CODE (operands[2]) != CONST_INT)
518     FAIL;
519
520   count = INTVAL (operands[2]);
521   if (count <= 0)
522     FAIL;
523
524   /* Work out branch probability for latter use.  */
525   prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
526
527   /* See if constant fit 8 bits.  */
528   mode = (count < 0x100) ? QImode : HImode;
529   /* Create loop counter register.  */
530   loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
531
532   /* Now create RTL code for move loop.  */
533   /* Label at top of loop.  */
534   emit_label (label);
535
536   /* Move one byte into scratch and inc pointer.  */
537   emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
538   emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
539
540   /* Move to mem and inc pointer.  */
541   emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
542   emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
543
544   /* Decrement count.  */
545   emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
546
547   /* Compare with zero and jump if not equal. */
548   emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
549                            label);
550   /* Set jump probability based on loop count.  */
551   jump = get_last_insn ();
552   add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
553   DONE;
554 }")
555
556 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
557 ;; memset (%0, %2, %1)
558
559 (define_expand "setmemhi"
560   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
561                    (match_operand 2 "const_int_operand" ""))
562               (use (match_operand:HI 1 "const_int_operand" ""))
563               (use (match_operand:HI 3 "const_int_operand" "n"))
564               (clobber (match_scratch:HI 4 ""))
565               (clobber (match_dup 5))])]
566   ""
567   "{
568   rtx addr0;
569   int cnt8;
570   enum machine_mode mode;
571
572   /* If value to set is not zero, use the library routine.  */
573   if (operands[2] != const0_rtx)
574     FAIL;
575
576   if (GET_CODE (operands[1]) != CONST_INT)
577     FAIL;
578
579   cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
580   mode = cnt8 ? QImode : HImode;
581   operands[5] = gen_rtx_SCRATCH (mode);
582   operands[1] = copy_to_mode_reg (mode,
583                                   gen_int_mode (INTVAL (operands[1]), mode));
584   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
585   operands[0] = gen_rtx_MEM (BLKmode, addr0);
586 }")
587
588 (define_insn "*clrmemqi"
589   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
590         (const_int 0))
591    (use (match_operand:QI 1 "register_operand" "r"))
592    (use (match_operand:QI 2 "const_int_operand" "n"))
593    (clobber (match_scratch:HI 3 "=0"))
594    (clobber (match_scratch:QI 4 "=&1"))]
595   ""
596   "st %a0+,__zero_reg__
597         dec %1
598         brne .-6"
599   [(set_attr "length" "3")
600    (set_attr "cc" "clobber")])
601
602 (define_insn "*clrmemhi"
603   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
604         (const_int 0))
605    (use (match_operand:HI 1 "register_operand" "!w,d"))
606    (use (match_operand:HI 2 "const_int_operand" "n,n"))
607    (clobber (match_scratch:HI 3 "=0,0"))
608    (clobber (match_scratch:HI 4 "=&1,&1"))]
609   ""
610   "*{
611      if (which_alternative==0)
612        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
613                AS2 (sbiw,%A1,1) CR_TAB
614                AS1 (brne,.-6));
615      else
616        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
617                AS2 (subi,%A1,1) CR_TAB
618                AS2 (sbci,%B1,0) CR_TAB
619                AS1 (brne,.-8));
620 }"
621   [(set_attr "length" "3,4")
622    (set_attr "cc" "clobber,clobber")])
623
624 (define_expand "strlenhi"
625     [(set (match_dup 4)
626           (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
627                       (match_operand:QI 2 "const_int_operand" "")
628                       (match_operand:HI 3 "immediate_operand" "")]
629                      UNSPEC_STRLEN))
630      (set (match_dup 4) (plus:HI (match_dup 4)
631                                  (const_int -1)))
632      (set (match_operand:HI 0 "register_operand" "")
633           (minus:HI (match_dup 4)
634                     (match_dup 5)))]
635    ""
636    "{
637   rtx addr;
638   if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
639     FAIL;
640   addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
641   operands[1] = gen_rtx_MEM (BLKmode, addr); 
642   operands[5] = addr;
643   operands[4] = gen_reg_rtx (HImode);
644 }")
645
646 (define_insn "*strlenhi"
647   [(set (match_operand:HI 0 "register_operand" "=e")
648         (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
649                     (const_int 0)
650                     (match_operand:HI 2 "immediate_operand" "i")]
651                    UNSPEC_STRLEN))]
652   ""
653   "ld __tmp_reg__,%a0+
654         tst __tmp_reg__
655         brne .-6"
656   [(set_attr "length" "3")
657    (set_attr "cc" "clobber")])
658
659 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
660 ; add bytes
661
662 (define_insn "addqi3"
663   [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
664         (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
665                  (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
666   ""
667   "@
668         add %0,%2
669         subi %0,lo8(-(%2))
670         inc %0
671         dec %0"
672   [(set_attr "length" "1,1,1,1")
673    (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
674
675
676 (define_expand "addhi3"
677   [(set (match_operand:HI 0 "register_operand" "")
678         (plus:HI (match_operand:HI 1 "register_operand" "")
679                  (match_operand:HI 2 "nonmemory_operand" "")))]
680   ""
681   "
682 {
683   if (GET_CODE (operands[2]) == CONST_INT)
684     {
685       short tmp = INTVAL (operands[2]);
686       operands[2] = GEN_INT(tmp);
687     }
688 }")
689
690
691 (define_insn "*addhi3_zero_extend"
692   [(set (match_operand:HI 0 "register_operand" "=r")
693         (plus:HI (zero_extend:HI
694                   (match_operand:QI 1 "register_operand" "r"))
695                  (match_operand:HI 2 "register_operand" "0")))]
696   ""
697   "add %A0,%1
698         adc %B0,__zero_reg__"
699   [(set_attr "length" "2")
700    (set_attr "cc" "set_n")])
701
702 (define_insn "*addhi3_zero_extend1"
703   [(set (match_operand:HI 0 "register_operand" "=r")
704         (plus:HI (match_operand:HI 1 "register_operand" "%0")
705                  (zero_extend:HI
706                   (match_operand:QI 2 "register_operand" "r"))))]
707   ""
708   "add %A0,%2
709         adc %B0,__zero_reg__"
710   [(set_attr "length" "2")
711    (set_attr "cc" "set_n")])
712
713 (define_insn "*addhi3_sp_R_pc2"
714   [(set (match_operand:HI 1 "stack_register_operand" "=q")
715         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
716                  (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
717   "AVR_2_BYTE_PC"
718   "*{
719       if (CONST_INT_P (operands[0]))
720         {
721           switch(INTVAL (operands[0]))
722             {
723             case -6: 
724               return \"rcall .\" CR_TAB 
725                      \"rcall .\" CR_TAB 
726                      \"rcall .\";
727             case -5: 
728               return \"rcall .\" CR_TAB 
729                      \"rcall .\" CR_TAB 
730                      \"push __tmp_reg__\";
731             case -4: 
732               return \"rcall .\" CR_TAB 
733                      \"rcall .\";
734             case -3: 
735               return \"rcall .\" CR_TAB 
736                      \"push __tmp_reg__\";
737             case -2: 
738               return \"rcall .\";
739             case -1: 
740               return \"push __tmp_reg__\";
741             case 0: 
742               return \"\";
743             case 1: 
744               return \"pop __tmp_reg__\";
745             case 2: 
746               return \"pop __tmp_reg__\" CR_TAB 
747                      \"pop __tmp_reg__\";
748             case 3: 
749               return \"pop __tmp_reg__\" CR_TAB 
750                      \"pop __tmp_reg__\" CR_TAB 
751                      \"pop __tmp_reg__\";
752             case 4: 
753               return \"pop __tmp_reg__\" CR_TAB 
754                      \"pop __tmp_reg__\" CR_TAB 
755                      \"pop __tmp_reg__\" CR_TAB 
756                      \"pop __tmp_reg__\";
757             case 5: 
758               return \"pop __tmp_reg__\" CR_TAB 
759                      \"pop __tmp_reg__\" CR_TAB 
760                      \"pop __tmp_reg__\" CR_TAB 
761                      \"pop __tmp_reg__\" CR_TAB 
762                      \"pop __tmp_reg__\";
763             }
764         }
765       return \"bug\";
766     }"
767   [(set (attr "length") 
768         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
769                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
770                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
771                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
772                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
773                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
774                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
775                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
776                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
777                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
778                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
779                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
780                (const_int 0)))])
781
782 (define_insn "*addhi3_sp_R_pc3"
783   [(set (match_operand:HI 1 "stack_register_operand" "=q")
784         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
785                  (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
786   "AVR_3_BYTE_PC"
787   "*{
788       if (CONST_INT_P (operands[0]))
789         {
790           switch(INTVAL (operands[0]))
791             {
792             case -6: 
793               return \"rcall .\" CR_TAB 
794                      \"rcall .\";
795             case -5: 
796               return \"rcall .\" CR_TAB 
797                      \"push __tmp_reg__\" CR_TAB 
798                      \"push __tmp_reg__\";
799             case -4: 
800               return \"rcall .\" CR_TAB 
801                      \"push __tmp_reg__\";
802             case -3: 
803               return \"rcall .\";
804             case -2: 
805               return \"push __tmp_reg__\" CR_TAB 
806                      \"push __tmp_reg__\";
807             case -1: 
808               return \"push __tmp_reg__\";
809             case 0: 
810               return \"\";
811             case 1: 
812               return \"pop __tmp_reg__\";
813             case 2: 
814               return \"pop __tmp_reg__\" CR_TAB 
815                      \"pop __tmp_reg__\";
816             case 3: 
817               return \"pop __tmp_reg__\" CR_TAB 
818                      \"pop __tmp_reg__\" CR_TAB 
819                      \"pop __tmp_reg__\";
820             case 4: 
821               return \"pop __tmp_reg__\" CR_TAB 
822                      \"pop __tmp_reg__\" CR_TAB 
823                      \"pop __tmp_reg__\" CR_TAB 
824                      \"pop __tmp_reg__\";
825             case 5: 
826               return \"pop __tmp_reg__\" CR_TAB 
827                      \"pop __tmp_reg__\" CR_TAB 
828                      \"pop __tmp_reg__\" CR_TAB 
829                      \"pop __tmp_reg__\" CR_TAB 
830                      \"pop __tmp_reg__\";
831             }
832         }
833       return \"bug\";
834     }"
835   [(set (attr "length") 
836         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
837                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
838                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
839                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
840                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
841                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
842                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
843                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
844                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
845                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
846                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
847                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
848                (const_int 0)))])
849
850 (define_insn "*addhi3"
851   [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
852         (plus:HI
853          (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
854          (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
855   ""
856   "@
857         add %A0,%A2\;adc %B0,%B2
858         adiw %A0,%2
859         sbiw %A0,%n2
860         subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
861         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
862         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
863   [(set_attr "length" "2,1,1,2,3,3")
864    (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
865
866 (define_insn "addsi3"
867   [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
868           (plus:SI
869            (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
870            (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
871   ""
872   "@
873         add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
874         adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
875         sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
876         subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
877         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
878         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
879   [(set_attr "length" "4,3,3,4,5,5")
880    (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
881
882 (define_insn "*addsi3_zero_extend"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (plus:SI (zero_extend:SI
885                   (match_operand:QI 1 "register_operand" "r"))
886                  (match_operand:SI 2 "register_operand" "0")))]
887   ""
888   "add %A0,%1
889         adc %B0,__zero_reg__
890         adc %C0,__zero_reg__
891         adc %D0,__zero_reg__"
892   [(set_attr "length" "4")
893    (set_attr "cc" "set_n")])
894
895 ;-----------------------------------------------------------------------------
896 ; sub bytes
897 (define_insn "subqi3"
898   [(set (match_operand:QI 0 "register_operand" "=r,d")
899         (minus:QI (match_operand:QI 1 "register_operand" "0,0")
900                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
901   ""
902   "@
903         sub %0,%2
904         subi %0,lo8(%2)"
905   [(set_attr "length" "1,1")
906    (set_attr "cc" "set_czn,set_czn")])
907
908 (define_insn "subhi3"
909   [(set (match_operand:HI 0 "register_operand" "=r,d")
910         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
911                   (match_operand:HI 2 "nonmemory_operand" "r,i")))]
912   ""
913   "@
914         sub %A0,%A2\;sbc %B0,%B2
915         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
916   [(set_attr "length" "2,2")
917    (set_attr "cc" "set_czn,set_czn")])
918
919 (define_insn "*subhi3_zero_extend1"
920   [(set (match_operand:HI 0 "register_operand" "=r")
921         (minus:HI (match_operand:HI 1 "register_operand" "0")
922                   (zero_extend:HI
923                    (match_operand:QI 2 "register_operand" "r"))))]
924   ""
925   "sub %A0,%2
926         sbc %B0,__zero_reg__"
927   [(set_attr "length" "2")
928    (set_attr "cc" "set_n")])
929
930 (define_insn "subsi3"
931   [(set (match_operand:SI 0 "register_operand" "=r,d")
932         (minus:SI (match_operand:SI 1 "register_operand" "0,0")
933                  (match_operand:SI 2 "nonmemory_operand" "r,i")))]
934   ""
935   "@
936         sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
937         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
938   [(set_attr "length" "4,4")
939    (set_attr "cc" "set_czn,set_czn")])
940
941 (define_insn "*subsi3_zero_extend"
942   [(set (match_operand:SI 0 "register_operand" "=r")
943         (minus:SI (match_operand:SI 1 "register_operand" "0")
944                   (zero_extend:SI
945                    (match_operand:QI 2 "register_operand" "r"))))]
946   ""
947   "sub %A0,%2
948         sbc %B0,__zero_reg__
949         sbc %C0,__zero_reg__
950         sbc %D0,__zero_reg__"
951   [(set_attr "length" "4")
952    (set_attr "cc" "set_n")])
953
954 ;******************************************************************************
955 ; mul
956
957 (define_expand "mulqi3"
958   [(set (match_operand:QI 0 "register_operand" "")
959         (mult:QI (match_operand:QI 1 "register_operand" "")
960                  (match_operand:QI 2 "register_operand" "")))]
961   ""
962   "{
963   if (!AVR_HAVE_MUL)
964     {
965       emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
966       DONE;
967     }
968 }")
969
970 (define_insn "*mulqi3_enh"
971   [(set (match_operand:QI 0 "register_operand" "=r")
972         (mult:QI (match_operand:QI 1 "register_operand" "r")
973                  (match_operand:QI 2 "register_operand" "r")))]
974   "AVR_HAVE_MUL"
975   "mul %1,%2
976         mov %0,r0
977         clr r1"
978   [(set_attr "length" "3")
979    (set_attr "cc" "clobber")])
980
981 (define_expand "mulqi3_call"
982   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
983    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
984    (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
985               (clobber (reg:QI 22))])
986    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
987   ""
988   "")
989
990 (define_insn "*mulqi3_call"
991   [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
992    (clobber (reg:QI 22))]
993   "!AVR_HAVE_MUL"
994   "%~call __mulqi3"
995   [(set_attr "type" "xcall")
996    (set_attr "cc" "clobber")])
997
998 (define_insn "mulqihi3"
999   [(set (match_operand:HI 0 "register_operand" "=r")
1000         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1001                  (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
1002   "AVR_HAVE_MUL"
1003   "muls %1,%2
1004         movw %0,r0
1005         clr r1"
1006   [(set_attr "length" "3")
1007    (set_attr "cc" "clobber")])
1008
1009 (define_insn "umulqihi3"
1010   [(set (match_operand:HI 0 "register_operand" "=r")
1011         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1012                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1013   "AVR_HAVE_MUL"
1014   "mul %1,%2
1015         movw %0,r0
1016         clr r1"
1017   [(set_attr "length" "3")
1018    (set_attr "cc" "clobber")])
1019
1020 (define_expand "mulhi3"
1021   [(set (match_operand:HI 0 "register_operand" "")
1022         (mult:HI (match_operand:HI 1 "register_operand" "")
1023                  (match_operand:HI 2 "register_operand" "")))]
1024   ""
1025   "
1026 {
1027   if (!AVR_HAVE_MUL)
1028     {
1029       emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1030       DONE;
1031     }
1032 }")
1033
1034 (define_insn "*mulhi3_enh"
1035   [(set (match_operand:HI 0 "register_operand" "=&r")
1036         (mult:HI (match_operand:HI 1 "register_operand" "r")
1037                  (match_operand:HI 2 "register_operand" "r")))]
1038   "AVR_HAVE_MUL"
1039   "mul %A1,%A2
1040         movw %0,r0
1041         mul %A1,%B2
1042         add %B0,r0
1043         mul %B1,%A2
1044         add %B0,r0
1045         clr r1"
1046   [(set_attr "length" "7")
1047    (set_attr "cc" "clobber")])
1048
1049 (define_expand "mulhi3_call"
1050   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1051    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1052    (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1053               (clobber (reg:HI 22))
1054               (clobber (reg:QI 21))])
1055    (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1056   ""
1057   "")
1058
1059 (define_insn "*mulhi3_call"
1060   [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1061    (clobber (reg:HI 22))
1062    (clobber (reg:QI 21))]
1063   "!AVR_HAVE_MUL"
1064   "%~call __mulhi3"
1065   [(set_attr "type" "xcall")
1066    (set_attr "cc" "clobber")])
1067
1068 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
1069 ;; All call-used registers clobbered otherwise - normal library call.
1070 (define_expand "mulsi3"
1071   [(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
1072    (set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
1073    (parallel [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1074               (clobber (reg:HI 26))
1075               (clobber (reg:HI 30))])
1076    (set (match_operand:SI 0 "register_operand" "") (reg:SI 22))]
1077   "AVR_HAVE_MUL"
1078   "")
1079
1080 (define_insn "*mulsi3_call"
1081   [(set (reg:SI 22) (mult:SI (reg:SI 22) (reg:SI 18)))
1082    (clobber (reg:HI 26))
1083    (clobber (reg:HI 30))]
1084   "AVR_HAVE_MUL"
1085   "%~call __mulsi3"
1086   [(set_attr "type" "xcall")
1087    (set_attr "cc" "clobber")])
1088
1089 (define_expand "mulhisi3"
1090   [(set (reg:HI 18)
1091         (match_operand:HI 1 "register_operand" ""))
1092    (set (reg:HI 20)
1093         (match_operand:HI 2 "register_operand" ""))
1094    (set (reg:SI 22) 
1095         (mult:SI (sign_extend:SI (reg:HI 18))
1096                  (sign_extend:SI (reg:HI 20))))
1097    (set (match_operand:SI 0 "register_operand" "") 
1098         (reg:SI 22))]
1099   "AVR_HAVE_MUL"
1100   "")
1101
1102 (define_expand "umulhisi3"
1103   [(set (reg:HI 18)
1104         (match_operand:HI 1 "register_operand" ""))
1105    (set (reg:HI 20)
1106         (match_operand:HI 2 "register_operand" ""))
1107    (set (reg:SI 22) 
1108         (mult:SI (zero_extend:SI (reg:HI 18))
1109                  (zero_extend:SI (reg:HI 20))))
1110    (set (match_operand:SI 0 "register_operand" "") 
1111         (reg:SI 22))]
1112   "AVR_HAVE_MUL"
1113   "")
1114
1115 (define_insn "*mulhisi3_call"
1116   [(set (reg:SI 22) 
1117         (mult:SI (sign_extend:SI (reg:HI 18))
1118                  (sign_extend:SI (reg:HI 20))))]
1119   "AVR_HAVE_MUL"
1120   "%~call __mulhisi3"
1121   [(set_attr "type" "xcall")
1122    (set_attr "cc" "clobber")])
1123
1124 (define_insn "*umulhisi3_call"
1125   [(set (reg:SI 22) 
1126         (mult:SI (zero_extend:SI (reg:HI 18))
1127                  (zero_extend:SI (reg:HI 20))))]
1128   "AVR_HAVE_MUL"
1129   "%~call __umulhisi3"
1130   [(set_attr "type" "xcall")
1131    (set_attr "cc" "clobber")])
1132
1133 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1134 ; divmod
1135
1136 ;; Generate libgcc.S calls ourselves, because:
1137 ;;  - we know exactly which registers are clobbered (for QI and HI
1138 ;;    modes, some of the call-used registers are preserved)
1139 ;;  - we get both the quotient and the remainder at no extra cost
1140 ;;  - we split the patterns only after the first CSE passes because
1141 ;;    CSE has problems to operate on hard regs.
1142 ;; 
1143 (define_insn_and_split "divmodqi4"
1144   [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1145                    (div:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1146                            (match_operand:QI 2 "pseudo_register_operand" "")))
1147               (set (match_operand:QI 3 "pseudo_register_operand" "") 
1148                    (mod:QI (match_dup 1) (match_dup 2)))
1149               (clobber (reg:QI 22)) 
1150               (clobber (reg:QI 23)) 
1151               (clobber (reg:QI 24)) 
1152               (clobber (reg:QI 25))])]
1153   ""
1154   "this divmodqi4 pattern should have been splitted;"
1155   ""
1156   [(set (reg:QI 24) (match_dup 1))
1157    (set (reg:QI 22) (match_dup 2))
1158    (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1159               (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1160               (clobber (reg:QI 22))
1161               (clobber (reg:QI 23))])
1162    (set (match_dup 0) (reg:QI 24))
1163    (set (match_dup 3) (reg:QI 25))]
1164   "")
1165
1166 (define_insn "*divmodqi4_call"
1167   [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1168    (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1169    (clobber (reg:QI 22))
1170    (clobber (reg:QI 23))]
1171   ""
1172   "%~call __divmodqi4"
1173   [(set_attr "type" "xcall")
1174    (set_attr "cc" "clobber")])
1175
1176 (define_insn_and_split "udivmodqi4"
1177  [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1178                   (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1179                            (match_operand:QI 2 "pseudo_register_operand" "")))
1180              (set (match_operand:QI 3 "pseudo_register_operand" "") 
1181                   (umod:QI (match_dup 1) (match_dup 2)))
1182              (clobber (reg:QI 22))
1183              (clobber (reg:QI 23))
1184              (clobber (reg:QI 24))
1185              (clobber (reg:QI 25))])]
1186   ""
1187   "this udivmodqi4 pattern should have been splitted;"
1188   "" 
1189   [(set (reg:QI 24) (match_dup 1))
1190    (set (reg:QI 22) (match_dup 2))
1191    (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1192               (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1193               (clobber (reg:QI 23))])
1194    (set (match_dup 0) (reg:QI 24))
1195    (set (match_dup 3) (reg:QI 25))]
1196   "")
1197
1198 (define_insn "*udivmodqi4_call"
1199   [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1200    (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1201    (clobber (reg:QI 23))]
1202   ""
1203   "%~call __udivmodqi4"
1204   [(set_attr "type" "xcall")
1205    (set_attr "cc" "clobber")])
1206
1207 (define_insn_and_split "divmodhi4"
1208   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1209                    (div:HI (match_operand:HI 1 "pseudo_register_operand" "") 
1210                            (match_operand:HI 2 "pseudo_register_operand" "")))
1211               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1212                    (mod:HI (match_dup 1) (match_dup 2)))
1213               (clobber (reg:QI 21))
1214               (clobber (reg:HI 22))
1215               (clobber (reg:HI 24))
1216               (clobber (reg:HI 26))])]
1217   ""
1218   "this should have been splitted;"
1219   ""
1220   [(set (reg:HI 24) (match_dup 1))
1221    (set (reg:HI 22) (match_dup 2))
1222    (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1223               (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1224               (clobber (reg:HI 26))
1225               (clobber (reg:QI 21))])
1226    (set (match_dup 0) (reg:HI 22))
1227    (set (match_dup 3) (reg:HI 24))]
1228   "") 
1229
1230 (define_insn "*divmodhi4_call"
1231   [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1232    (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1233    (clobber (reg:HI 26))
1234    (clobber (reg:QI 21))]
1235   ""
1236   "%~call __divmodhi4"
1237   [(set_attr "type" "xcall")
1238    (set_attr "cc" "clobber")])
1239
1240 (define_insn_and_split "udivmodhi4"
1241   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1242                    (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1243                             (match_operand:HI 2 "pseudo_register_operand" "")))
1244               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1245                    (umod:HI (match_dup 1) (match_dup 2)))
1246               (clobber (reg:QI 21))
1247               (clobber (reg:HI 22))
1248               (clobber (reg:HI 24))
1249               (clobber (reg:HI 26))])]
1250   ""
1251   "this udivmodhi4 pattern should have been splitted.;"
1252   ""
1253   [(set (reg:HI 24) (match_dup 1))
1254    (set (reg:HI 22) (match_dup 2))
1255    (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1256               (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1257               (clobber (reg:HI 26))
1258               (clobber (reg:QI 21))])
1259    (set (match_dup 0) (reg:HI 22))
1260    (set (match_dup 3) (reg:HI 24))]
1261   "")
1262
1263 (define_insn "*udivmodhi4_call"
1264   [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1265    (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1266    (clobber (reg:HI 26))
1267    (clobber (reg:QI 21))]
1268   ""
1269   "%~call __udivmodhi4"
1270   [(set_attr "type" "xcall")
1271    (set_attr "cc" "clobber")])
1272
1273 (define_insn_and_split "divmodsi4"
1274   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1275                    (div:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1276                            (match_operand:SI 2 "pseudo_register_operand" "")))
1277               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1278                    (mod:SI (match_dup 1) (match_dup 2)))
1279               (clobber (reg:SI 18))
1280               (clobber (reg:SI 22))
1281               (clobber (reg:HI 26))
1282               (clobber (reg:HI 30))])]
1283   ""
1284   "this divmodsi4 pattern should have been splitted;" 
1285   ""
1286   [(set (reg:SI 22) (match_dup 1))
1287    (set (reg:SI 18) (match_dup 2))
1288    (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1289               (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1290               (clobber (reg:HI 26))
1291               (clobber (reg:HI 30))])
1292    (set (match_dup 0) (reg:SI 18))
1293    (set (match_dup 3) (reg:SI 22))]
1294   "")
1295
1296 (define_insn "*divmodsi4_call"
1297   [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1298    (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1299    (clobber (reg:HI 26))
1300    (clobber (reg:HI 30))]
1301   ""
1302   "%~call __divmodsi4"
1303   [(set_attr "type" "xcall")
1304    (set_attr "cc" "clobber")])
1305
1306 (define_insn_and_split "udivmodsi4"
1307   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1308                    (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1309                            (match_operand:SI 2 "pseudo_register_operand" "")))
1310               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1311                    (umod:SI (match_dup 1) (match_dup 2)))
1312               (clobber (reg:SI 18))
1313               (clobber (reg:SI 22))
1314               (clobber (reg:HI 26))
1315               (clobber (reg:HI 30))])]
1316   ""
1317   "this udivmodsi4 pattern should have been splitted;"
1318   ""
1319   [(set (reg:SI 22) (match_dup 1))
1320    (set (reg:SI 18) (match_dup 2))
1321    (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1322               (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1323               (clobber (reg:HI 26))
1324               (clobber (reg:HI 30))])
1325    (set (match_dup 0) (reg:SI 18))
1326    (set (match_dup 3) (reg:SI 22))]
1327   "")
1328
1329 (define_insn "*udivmodsi4_call"
1330   [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1331    (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1332    (clobber (reg:HI 26))
1333    (clobber (reg:HI 30))]
1334   ""
1335   "%~call __udivmodsi4"
1336   [(set_attr "type" "xcall")
1337    (set_attr "cc" "clobber")])
1338
1339 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1340 ; and
1341
1342 (define_insn "andqi3"
1343   [(set (match_operand:QI 0 "register_operand" "=r,d")
1344         (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1345                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1346   ""
1347   "@
1348         and %0,%2
1349         andi %0,lo8(%2)"
1350   [(set_attr "length" "1,1")
1351    (set_attr "cc" "set_zn,set_zn")])
1352
1353 (define_insn "andhi3"
1354   [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1355           (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1356                   (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1357    (clobber (match_scratch:QI 3 "=X,X,&d"))]
1358   ""
1359 {
1360   if (which_alternative==0)
1361     return ("and %A0,%A2" CR_TAB
1362             "and %B0,%B2");
1363   else if (which_alternative==1)
1364     {
1365       if (GET_CODE (operands[2]) == CONST_INT)
1366         {
1367           int mask = INTVAL (operands[2]);
1368           if ((mask & 0xff) != 0xff)
1369             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1370           if ((mask & 0xff00) != 0xff00)
1371             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1372           return "";
1373         }
1374         return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1375                 AS2 (andi,%B0,hi8(%2)));
1376      }
1377   return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1378           "and %A0,%3"         CR_TAB
1379           AS1 (clr,%B0));
1380 }
1381   [(set_attr "length" "2,2,3")
1382    (set_attr "cc" "set_n,clobber,set_n")])
1383
1384 (define_insn "andsi3"
1385   [(set (match_operand:SI 0 "register_operand" "=r,d")
1386         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1387                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1388   ""
1389 {
1390   if (which_alternative==0)
1391     return ("and %0,%2"   CR_TAB
1392             "and %B0,%B2" CR_TAB
1393             "and %C0,%C2" CR_TAB
1394             "and %D0,%D2");
1395   else if (which_alternative==1)
1396     {
1397       if (GET_CODE (operands[2]) == CONST_INT)
1398         {
1399           HOST_WIDE_INT mask = INTVAL (operands[2]);
1400           if ((mask & 0xff) != 0xff)
1401             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1402           if ((mask & 0xff00) != 0xff00)
1403             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1404           if ((mask & 0xff0000L) != 0xff0000L)
1405             output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1406           if ((mask & 0xff000000L) != 0xff000000L)
1407             output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1408           return "";
1409         }
1410       return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1411               AS2 (andi, %B0,hi8(%2)) CR_TAB
1412               AS2 (andi, %C0,hlo8(%2)) CR_TAB
1413               AS2 (andi, %D0,hhi8(%2)));
1414     }
1415   return "bug";
1416 }
1417   [(set_attr "length" "4,4")
1418    (set_attr "cc" "set_n,clobber")])
1419
1420 (define_peephole2 ; andi
1421   [(set (match_operand:QI 0 "d_register_operand" "")
1422         (and:QI (match_dup 0)
1423                 (match_operand:QI 1 "const_int_operand" "")))
1424    (set (match_dup 0)
1425         (and:QI (match_dup 0)
1426                 (match_operand:QI 2 "const_int_operand" "")))]
1427   ""
1428   [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1429   {
1430     operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
1431   })
1432
1433 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1434 ;; ior
1435
1436 (define_insn "iorqi3"
1437   [(set (match_operand:QI 0 "register_operand" "=r,d")
1438         (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1439                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1440   ""
1441   "@
1442         or %0,%2
1443         ori %0,lo8(%2)"
1444   [(set_attr "length" "1,1")
1445    (set_attr "cc" "set_zn,set_zn")])
1446
1447 (define_insn "iorhi3"
1448   [(set (match_operand:HI 0 "register_operand" "=r,d")
1449         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1450                 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1451   ""
1452 {
1453   if (which_alternative==0)
1454     return ("or %A0,%A2" CR_TAB
1455             "or %B0,%B2");
1456   if (GET_CODE (operands[2]) == CONST_INT)
1457      {
1458         int mask = INTVAL (operands[2]);
1459         if (mask & 0xff)
1460           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1461         if (mask & 0xff00)
1462           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1463         return "";
1464       }
1465    return (AS2 (ori,%0,lo8(%2)) CR_TAB
1466            AS2 (ori,%B0,hi8(%2)));
1467 }
1468   [(set_attr "length" "2,2")
1469    (set_attr "cc" "set_n,clobber")])
1470
1471 (define_insn "*iorhi3_clobber"
1472   [(set (match_operand:HI 0 "register_operand" "=r,r")
1473         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1474                 (match_operand:HI 2 "immediate_operand" "M,i")))
1475    (clobber (match_scratch:QI 3 "=&d,&d"))]
1476   ""
1477   "@
1478         ldi %3,lo8(%2)\;or %A0,%3
1479         ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
1480   [(set_attr "length" "2,4")
1481    (set_attr "cc" "clobber,set_n")])
1482
1483 (define_insn "iorsi3"
1484   [(set (match_operand:SI 0 "register_operand"        "=r,d")
1485         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1486                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1487   ""
1488 {
1489   if (which_alternative==0)
1490     return ("or %0,%2"   CR_TAB
1491             "or %B0,%B2" CR_TAB
1492             "or %C0,%C2" CR_TAB
1493             "or %D0,%D2");
1494   if (GET_CODE (operands[2]) == CONST_INT)
1495      {
1496         HOST_WIDE_INT mask = INTVAL (operands[2]);
1497         if (mask & 0xff)
1498           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
1499         if (mask & 0xff00)
1500           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
1501         if (mask & 0xff0000L)
1502           output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
1503         if (mask & 0xff000000L)
1504           output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
1505         return "";
1506       }
1507   return (AS2 (ori, %A0,lo8(%2))  CR_TAB
1508           AS2 (ori, %B0,hi8(%2)) CR_TAB
1509           AS2 (ori, %C0,hlo8(%2)) CR_TAB
1510           AS2 (ori, %D0,hhi8(%2)));
1511 }
1512   [(set_attr "length" "4,4")
1513    (set_attr "cc" "set_n,clobber")])
1514
1515 (define_insn "*iorsi3_clobber"
1516   [(set (match_operand:SI 0 "register_operand"        "=r,r")
1517         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
1518                 (match_operand:SI 2 "immediate_operand" "M,i")))
1519    (clobber (match_scratch:QI 3 "=&d,&d"))]
1520   ""
1521   "@
1522         ldi %3,lo8(%2)\;or %A0,%3
1523         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"
1524   [(set_attr "length" "2,8")
1525    (set_attr "cc" "clobber,set_n")])
1526
1527 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1528 ;; xor
1529
1530 (define_insn "xorqi3"
1531   [(set (match_operand:QI 0 "register_operand" "=r")
1532         (xor:QI (match_operand:QI 1 "register_operand" "%0")
1533                 (match_operand:QI 2 "register_operand" "r")))]
1534   ""
1535   "eor %0,%2"
1536   [(set_attr "length" "1")
1537    (set_attr "cc" "set_zn")])
1538
1539 (define_insn "xorhi3"
1540   [(set (match_operand:HI 0 "register_operand" "=r")
1541         (xor:HI (match_operand:HI 1 "register_operand" "%0")
1542                 (match_operand:HI 2 "register_operand" "r")))]
1543   ""
1544   "eor %0,%2
1545         eor %B0,%B2"
1546   [(set_attr "length" "2")
1547    (set_attr "cc" "set_n")])
1548
1549 (define_insn "xorsi3"
1550   [(set (match_operand:SI 0 "register_operand" "=r")
1551         (xor:SI (match_operand:SI 1 "register_operand" "%0")
1552                 (match_operand:SI 2 "register_operand" "r")))]
1553   ""
1554   "eor %0,%2
1555         eor %B0,%B2
1556         eor %C0,%C2
1557         eor %D0,%D2"
1558   [(set_attr "length" "4")
1559    (set_attr "cc" "set_n")])
1560
1561 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
1562 ;; swap
1563
1564 (define_expand "rotlqi3"
1565   [(set (match_operand:QI 0 "register_operand" "")
1566         (rotate:QI (match_operand:QI 1 "register_operand" "")
1567                    (match_operand:QI 2 "const_int_operand" "")))]
1568   ""
1569   "
1570 {
1571   if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
1572     FAIL;
1573 }")
1574
1575 (define_insn "rotlqi3_4"
1576   [(set (match_operand:QI 0 "register_operand" "=r")
1577         (rotate:QI (match_operand:QI 1 "register_operand" "0")
1578                    (const_int 4)))]
1579   ""
1580   "swap %0"
1581   [(set_attr "length" "1")
1582    (set_attr "cc" "none")])
1583
1584 ;; Split all rotates of HI,SI and DImode registers where rotation is by
1585 ;; a whole number of bytes.  The split creates the appropriate moves and
1586 ;; considers all overlap situations.  DImode is split before reload.
1587
1588 ;; HImode does not need scratch.  Use attribute for this constraint.
1589 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
1590
1591 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
1592 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
1593
1594 (define_expand "rotl<mode>3"
1595   [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
1596                    (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
1597                                 (match_operand:VOID 2 "const_int_operand" "")))
1598                 (clobber (match_dup 3))])]
1599   ""
1600   "
1601 {
1602   if (CONST_INT_P (operands[2]) && 0 == (INTVAL (operands[2]) % 8))
1603   {
1604   if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
1605     operands[3] = gen_reg_rtx (<rotsmode>mode);
1606   else
1607     operands[3] = gen_reg_rtx (QImode);
1608   }
1609   else
1610     FAIL;
1611 }")
1612
1613
1614 ;; Overlapping non-HImode registers often (but not always) need a scratch.
1615 ;; The best we can do is use early clobber alternative "#&r" so that
1616 ;; completely non-overlapping operands dont get a scratch but # so register
1617 ;; allocation does not prefer non-overlapping.
1618
1619
1620 ; Split word aligned rotates using scratch that is mode dependent.
1621 (define_insn_and_split "*rotw<mode>"
1622   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1623         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1624                      (match_operand 2 "immediate_operand" "n,n,n")))
1625    (clobber (match_operand:<rotsmode> 3 "register_operand"  "=<rotx>" ))]
1626   "(CONST_INT_P (operands[2]) &&
1627      (0 == (INTVAL (operands[2]) % 16) && AVR_HAVE_MOVW))"
1628   "#"
1629   "&& (reload_completed || <MODE>mode == DImode)"
1630   [(const_int 0)]
1631   "avr_rotate_bytes (operands);
1632   DONE;"
1633 )
1634
1635
1636 ; Split byte aligned rotates using scratch that is always QI mode.
1637 (define_insn_and_split "*rotb<mode>"
1638   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
1639         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
1640                      (match_operand 2 "immediate_operand" "n,n,n")))
1641    (clobber (match_operand:QI 3 "register_operand" "=<rotx>" ))]
1642   "(CONST_INT_P (operands[2]) &&
1643      (8 == (INTVAL (operands[2]) % 16)
1644         || (!AVR_HAVE_MOVW && 0 == (INTVAL (operands[2]) % 16))))"
1645   "#"
1646   "&& (reload_completed || <MODE>mode == DImode)"
1647   [(const_int 0)]
1648   "avr_rotate_bytes (operands);
1649   DONE;"
1650 )
1651
1652
1653 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
1654 ;; arithmetic shift left
1655
1656 (define_expand "ashlqi3"
1657   [(set (match_operand:QI 0 "register_operand"            "")
1658         (ashift:QI (match_operand:QI 1 "register_operand" "")
1659                    (match_operand:QI 2 "general_operand"  "")))]
1660   ""
1661   "")
1662
1663 (define_split ; ashlqi3_const4
1664   [(set (match_operand:QI 0 "d_register_operand" "")
1665         (ashift:QI (match_dup 0)
1666                    (const_int 4)))]
1667   ""
1668   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1669    (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
1670   "")
1671
1672 (define_split ; ashlqi3_const5
1673   [(set (match_operand:QI 0 "d_register_operand" "")
1674         (ashift:QI (match_dup 0)
1675                    (const_int 5)))]
1676   ""
1677   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1678    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1679    (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
1680   "")
1681
1682 (define_split ; ashlqi3_const6
1683   [(set (match_operand:QI 0 "d_register_operand" "")
1684         (ashift:QI (match_dup 0)
1685                    (const_int 6)))]
1686   ""
1687   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1688    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1689    (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
1690   "")
1691
1692 (define_insn "*ashlqi3"
1693   [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
1694         (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1695                    (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1696   ""
1697   "* return ashlqi3_out (insn, operands, NULL);"
1698   [(set_attr "length" "5,0,1,2,4,6,9")
1699    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1700
1701 (define_insn "ashlhi3"
1702   [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
1703         (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1704                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1705   ""
1706   "* return ashlhi3_out (insn, operands, NULL);"
1707   [(set_attr "length" "6,0,2,2,4,10,10")
1708    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1709
1710 (define_insn "ashlsi3"
1711   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
1712         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1713                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1714   ""
1715   "* return ashlsi3_out (insn, operands, NULL);"
1716   [(set_attr "length" "8,0,4,4,8,10,12")
1717    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
1718
1719 ;; Optimize if a scratch register from LD_REGS happens to be available.
1720
1721 (define_peephole2 ; ashlqi3_l_const4
1722   [(set (match_operand:QI 0 "l_register_operand" "")
1723         (ashift:QI (match_dup 0)
1724                    (const_int 4)))
1725    (match_scratch:QI 1 "d")]
1726   ""
1727   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1728    (set (match_dup 1) (const_int -16))
1729    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1730   "")
1731
1732 (define_peephole2 ; ashlqi3_l_const5
1733   [(set (match_operand:QI 0 "l_register_operand" "")
1734         (ashift:QI (match_dup 0)
1735                    (const_int 5)))
1736    (match_scratch:QI 1 "d")]
1737   ""
1738   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1739    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
1740    (set (match_dup 1) (const_int -32))
1741    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1742   "")
1743
1744 (define_peephole2 ; ashlqi3_l_const6
1745   [(set (match_operand:QI 0 "l_register_operand" "")
1746         (ashift:QI (match_dup 0)
1747                    (const_int 6)))
1748    (match_scratch:QI 1 "d")]
1749   ""
1750   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1751    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
1752    (set (match_dup 1) (const_int -64))
1753    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1754   "")
1755
1756 (define_peephole2
1757   [(match_scratch:QI 3 "d")
1758    (set (match_operand:HI 0 "register_operand" "")
1759         (ashift:HI (match_operand:HI 1 "register_operand" "")
1760                    (match_operand:QI 2 "const_int_operand" "")))]
1761   ""
1762   [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
1763               (clobber (match_dup 3))])]
1764   "")
1765
1766 (define_insn "*ashlhi3_const"
1767   [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
1768         (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1769                    (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1770    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1771   "reload_completed"
1772   "* return ashlhi3_out (insn, operands, NULL);"
1773   [(set_attr "length" "0,2,2,4,10")
1774    (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
1775
1776 (define_peephole2
1777   [(match_scratch:QI 3 "d")
1778    (set (match_operand:SI 0 "register_operand" "")
1779         (ashift:SI (match_operand:SI 1 "register_operand" "")
1780                    (match_operand:QI 2 "const_int_operand" "")))]
1781   ""
1782   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
1783               (clobber (match_dup 3))])]
1784   "")
1785
1786 (define_insn "*ashlsi3_const"
1787   [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
1788         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1789                    (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1790    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1791   "reload_completed"
1792   "* return ashlsi3_out (insn, operands, NULL);"
1793   [(set_attr "length" "0,4,4,10")
1794    (set_attr "cc" "none,set_n,clobber,clobber")])
1795
1796 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1797 ;; arithmetic shift right
1798
1799 (define_insn "ashrqi3"
1800   [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
1801         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
1802                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
1803   ""
1804   "* return ashrqi3_out (insn, operands, NULL);"
1805   [(set_attr "length" "5,0,1,2,5,9")
1806    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
1807
1808 (define_insn "ashrhi3"
1809   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1810         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1811                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1812   ""
1813   "* return ashrhi3_out (insn, operands, NULL);"
1814   [(set_attr "length" "6,0,2,4,4,10,10")
1815    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1816
1817 (define_insn "ashrsi3"
1818   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1819         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1820                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1821   ""
1822   "* return ashrsi3_out (insn, operands, NULL);"
1823   [(set_attr "length" "8,0,4,6,8,10,12")
1824    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
1825
1826 ;; Optimize if a scratch register from LD_REGS happens to be available.
1827
1828 (define_peephole2
1829   [(match_scratch:QI 3 "d")
1830    (set (match_operand:HI 0 "register_operand" "")
1831         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
1832                      (match_operand:QI 2 "const_int_operand" "")))]
1833   ""
1834   [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
1835               (clobber (match_dup 3))])]
1836   "")
1837
1838 (define_insn "*ashrhi3_const"
1839   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1840         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1841                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1842    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1843   "reload_completed"
1844   "* return ashrhi3_out (insn, operands, NULL);"
1845   [(set_attr "length" "0,2,4,4,10")
1846    (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
1847
1848 (define_peephole2
1849   [(match_scratch:QI 3 "d")
1850    (set (match_operand:SI 0 "register_operand" "")
1851         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
1852                      (match_operand:QI 2 "const_int_operand" "")))]
1853   ""
1854   [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
1855               (clobber (match_dup 3))])]
1856   "")
1857
1858 (define_insn "*ashrsi3_const"
1859   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
1860         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
1861                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
1862    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
1863   "reload_completed"
1864   "* return ashrsi3_out (insn, operands, NULL);"
1865   [(set_attr "length" "0,4,4,10")
1866    (set_attr "cc" "none,clobber,set_n,clobber")])
1867
1868 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
1869 ;; logical shift right
1870
1871 (define_expand "lshrqi3"
1872   [(set (match_operand:QI 0 "register_operand"              "")
1873         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
1874                      (match_operand:QI 2 "general_operand"  "")))]
1875   ""
1876   "")
1877
1878 (define_split   ; lshrqi3_const4
1879   [(set (match_operand:QI 0 "d_register_operand" "")
1880         (lshiftrt:QI (match_dup 0)
1881                      (const_int 4)))]
1882   ""
1883   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1884    (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
1885   "")
1886
1887 (define_split   ; lshrqi3_const5
1888   [(set (match_operand:QI 0 "d_register_operand" "")
1889         (lshiftrt:QI (match_dup 0)
1890                      (const_int 5)))]
1891   ""
1892   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1893    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1894    (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
1895   "")
1896
1897 (define_split   ; lshrqi3_const6
1898   [(set (match_operand:QI 0 "d_register_operand" "")
1899         (lshiftrt:QI (match_dup 0)
1900                      (const_int 6)))]
1901   ""
1902   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1903    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1904    (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
1905   "")
1906
1907 (define_insn "*lshrqi3"
1908   [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
1909         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
1910                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
1911   ""
1912   "* return lshrqi3_out (insn, operands, NULL);"
1913   [(set_attr "length" "5,0,1,2,4,6,9")
1914    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
1915
1916 (define_insn "lshrhi3"
1917   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
1918         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
1919                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1920   ""
1921   "* return lshrhi3_out (insn, operands, NULL);"
1922   [(set_attr "length" "6,0,2,2,4,10,10")
1923    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1924
1925 (define_insn "lshrsi3"
1926   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
1927         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
1928                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
1929   ""
1930   "* return lshrsi3_out (insn, operands, NULL);"
1931   [(set_attr "length" "8,0,4,4,8,10,12")
1932    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
1933
1934 ;; Optimize if a scratch register from LD_REGS happens to be available.
1935
1936 (define_peephole2 ; lshrqi3_l_const4
1937   [(set (match_operand:QI 0 "l_register_operand" "")
1938         (lshiftrt:QI (match_dup 0)
1939                      (const_int 4)))
1940    (match_scratch:QI 1 "d")]
1941   ""
1942   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1943    (set (match_dup 1) (const_int 15))
1944    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1945   "")
1946
1947 (define_peephole2 ; lshrqi3_l_const5
1948   [(set (match_operand:QI 0 "l_register_operand" "")
1949         (lshiftrt:QI (match_dup 0)
1950                      (const_int 5)))
1951    (match_scratch:QI 1 "d")]
1952   ""
1953   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1954    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
1955    (set (match_dup 1) (const_int 7))
1956    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1957   "")
1958
1959 (define_peephole2 ; lshrqi3_l_const6
1960   [(set (match_operand:QI 0 "l_register_operand" "")
1961         (lshiftrt:QI (match_dup 0)
1962                      (const_int 6)))
1963    (match_scratch:QI 1 "d")]
1964   ""
1965   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
1966    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
1967    (set (match_dup 1) (const_int 3))
1968    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1969   "")
1970
1971 (define_peephole2
1972   [(match_scratch:QI 3 "d")
1973    (set (match_operand:HI 0 "register_operand" "")
1974         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
1975                      (match_operand:QI 2 "const_int_operand" "")))]
1976   ""
1977   [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
1978               (clobber (match_dup 3))])]
1979   "")
1980
1981 (define_insn "*lshrhi3_const"
1982   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
1983         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
1984                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
1985    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
1986   "reload_completed"
1987   "* return lshrhi3_out (insn, operands, NULL);"
1988   [(set_attr "length" "0,2,2,4,10")
1989    (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
1990
1991 (define_peephole2
1992   [(match_scratch:QI 3 "d")
1993    (set (match_operand:SI 0 "register_operand" "")
1994         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
1995                      (match_operand:QI 2 "const_int_operand" "")))]
1996   ""
1997   [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
1998               (clobber (match_dup 3))])]
1999   "")
2000
2001 (define_insn "*lshrsi3_const"
2002   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
2003         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
2004                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2005    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2006   "reload_completed"
2007   "* return lshrsi3_out (insn, operands, NULL);"
2008   [(set_attr "length" "0,4,4,10")
2009    (set_attr "cc" "none,clobber,clobber,clobber")])
2010
2011 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2012 ;; abs
2013
2014 (define_insn "absqi2"
2015   [(set (match_operand:QI 0 "register_operand" "=r")
2016         (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2017   ""
2018   "sbrc %0,7
2019         neg %0"
2020   [(set_attr "length" "2")
2021    (set_attr "cc" "clobber")])
2022
2023
2024 (define_insn "abssf2"
2025   [(set (match_operand:SF 0 "register_operand" "=d,r")
2026         (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2027   ""
2028   "@
2029         andi %D0,0x7f
2030         clt\;bld %D0,7"
2031   [(set_attr "length" "1,2")
2032    (set_attr "cc" "set_n,clobber")])
2033
2034 ;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
2035 ;; neg
2036
2037 (define_insn "negqi2"
2038   [(set (match_operand:QI 0 "register_operand" "=r")
2039         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2040   ""
2041   "neg %0"
2042   [(set_attr "length" "1")
2043    (set_attr "cc" "set_zn")])
2044
2045 (define_insn "neghi2"
2046   [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
2047         (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2048   ""
2049   "@
2050         com %B0\;neg %A0\;sbci %B0,lo8(-1)
2051         com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2052         clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2053   [(set_attr "length" "3,4,4")
2054    (set_attr "cc" "set_czn,set_n,set_czn")])
2055
2056 (define_insn "negsi2"
2057   [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
2058         (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2059   ""
2060   "@
2061         com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2062         com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2063         clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2064   [(set_attr_alternative "length"
2065                          [(const_int 7)
2066                           (const_int 8)
2067                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2068                                         (const_int 7)
2069                                         (const_int 8))])
2070    (set_attr "cc" "set_czn,set_n,set_czn")])
2071
2072 (define_insn "negsf2"
2073   [(set (match_operand:SF 0 "register_operand" "=d,r")
2074         (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2075   ""
2076   "@
2077         subi %D0,0x80
2078         bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2079   [(set_attr "length" "1,4")
2080    (set_attr "cc" "set_n,set_n")])
2081
2082 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2083 ;; not
2084
2085 (define_insn "one_cmplqi2"
2086   [(set (match_operand:QI 0 "register_operand" "=r")
2087         (not:QI (match_operand:QI 1 "register_operand" "0")))]
2088   ""
2089   "com %0"
2090   [(set_attr "length" "1")
2091    (set_attr "cc" "set_czn")])
2092
2093 (define_insn "one_cmplhi2"
2094   [(set (match_operand:HI 0 "register_operand" "=r")
2095         (not:HI (match_operand:HI 1 "register_operand" "0")))]
2096   ""
2097   "com %0
2098         com %B0"
2099   [(set_attr "length" "2")
2100    (set_attr "cc" "set_n")])
2101
2102 (define_insn "one_cmplsi2"
2103   [(set (match_operand:SI 0 "register_operand" "=r")
2104         (not:SI (match_operand:SI 1 "register_operand" "0")))]
2105   ""
2106   "com %0
2107         com %B0
2108         com %C0
2109         com %D0"
2110   [(set_attr "length" "4")
2111    (set_attr "cc" "set_n")])
2112
2113 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2114 ;; sign extend
2115
2116 (define_insn "extendqihi2"
2117   [(set (match_operand:HI 0 "register_operand" "=r,r")
2118         (sign_extend:HI (match_operand:QI 1 "register_operand" "0,*r")))]
2119   ""
2120   "@
2121         clr %B0\;sbrc %0,7\;com %B0
2122         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2123   [(set_attr "length" "3,4")
2124    (set_attr "cc" "set_n,set_n")])
2125
2126 (define_insn "extendqisi2"
2127   [(set (match_operand:SI 0 "register_operand" "=r,r")
2128         (sign_extend:SI (match_operand:QI 1 "register_operand" "0,*r")))]
2129   ""
2130   "@
2131         clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2132         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2133   [(set_attr "length" "5,6")
2134    (set_attr "cc" "set_n,set_n")])
2135
2136 (define_insn "extendhisi2"
2137   [(set (match_operand:SI 0 "register_operand"               "=r,&r")
2138         (sign_extend:SI (match_operand:HI 1 "register_operand" "0,*r")))]
2139   ""
2140   "@
2141         clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2142         {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2143   [(set_attr_alternative "length"
2144                          [(const_int 4)
2145                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2146                                         (const_int 5)
2147                                         (const_int 6))])
2148    (set_attr "cc" "set_n,set_n")])
2149
2150 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2151 ;; zero extend
2152
2153 (define_insn_and_split "zero_extendqihi2"
2154   [(set (match_operand:HI 0 "register_operand" "=r")
2155         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
2156   ""
2157   "#"
2158   "reload_completed"
2159   [(set (match_dup 2) (match_dup 1))
2160    (set (match_dup 3) (const_int 0))]
2161 {
2162   unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2163   unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2164
2165   operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2166   operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2167 })
2168
2169 (define_insn_and_split "zero_extendqisi2"
2170   [(set (match_operand:SI 0 "register_operand" "=r")
2171         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
2172   ""
2173   "#"
2174   "reload_completed"
2175   [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2176    (set (match_dup 3) (const_int 0))]
2177 {
2178   unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2179   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2180
2181   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2182   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2183 })
2184
2185 (define_insn_and_split "zero_extendhisi2"
2186   [(set (match_operand:SI 0 "register_operand" "=r")
2187         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
2188   ""
2189   "#"
2190   "reload_completed"
2191   [(set (match_dup 2) (match_dup 1))
2192    (set (match_dup 3) (const_int 0))]
2193 {
2194   unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2195   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2196
2197   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2198   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2199 })
2200
2201 (define_insn_and_split "zero_extendqidi2"
2202   [(set (match_operand:DI 0 "register_operand" "=r")
2203         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2204   ""
2205   "#"
2206   "reload_completed"
2207   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2208    (set (match_dup 3) (const_int 0))]
2209 {
2210   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2211   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2212
2213   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2214   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2215 })
2216
2217 (define_insn_and_split "zero_extendhidi2"
2218   [(set (match_operand:DI 0 "register_operand" "=r")
2219         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2220   ""
2221   "#"
2222   "reload_completed"
2223   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2224    (set (match_dup 3) (const_int 0))]
2225 {
2226   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2227   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2228
2229   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2230   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2231 })
2232
2233 (define_insn_and_split "zero_extendsidi2"
2234   [(set (match_operand:DI 0 "register_operand" "=r")
2235         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2236   ""
2237   "#"
2238   "reload_completed"
2239   [(set (match_dup 2) (match_dup 1))
2240    (set (match_dup 3) (const_int 0))]
2241 {
2242   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2243   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2244
2245   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2246   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2247 })
2248
2249 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2250 ;; compare
2251
2252 ; Optimize negated tests into reverse compare if overflow is undefined.
2253 (define_insn "*negated_tstqi"
2254   [(set (cc0)
2255         (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2256                  (const_int 0)))]
2257   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2258   "cp __zero_reg__,%0"
2259   [(set_attr "cc" "compare")
2260    (set_attr "length" "1")])
2261
2262 (define_insn "*reversed_tstqi"
2263   [(set (cc0)
2264         (compare (const_int 0)
2265                  (match_operand:QI 0 "register_operand" "r")))]
2266   ""
2267   "cp __zero_reg__,%0"
2268 [(set_attr "cc" "compare")
2269  (set_attr "length" "2")])
2270
2271 (define_insn "*negated_tsthi"
2272   [(set (cc0)
2273         (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2274                  (const_int 0)))]
2275   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2276   "cp __zero_reg__,%A0
2277         cpc __zero_reg__,%B0"
2278 [(set_attr "cc" "compare")
2279  (set_attr "length" "2")])
2280
2281 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2282 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2283 (define_insn "*reversed_tsthi"
2284   [(set (cc0)
2285         (compare (const_int 0)
2286                  (match_operand:HI 0 "register_operand" "r")))
2287    (clobber (match_scratch:QI 1 "=X"))]
2288   ""
2289   "cp __zero_reg__,%A0
2290         cpc __zero_reg__,%B0"
2291 [(set_attr "cc" "compare")
2292  (set_attr "length" "2")])
2293
2294 (define_insn "*negated_tstsi"
2295   [(set (cc0)
2296         (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2297                  (const_int 0)))]
2298   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2299   "cp __zero_reg__,%A0
2300         cpc __zero_reg__,%B0
2301         cpc __zero_reg__,%C0
2302         cpc __zero_reg__,%D0"
2303   [(set_attr "cc" "compare")
2304    (set_attr "length" "4")])
2305
2306 (define_insn "*reversed_tstsi"
2307   [(set (cc0)
2308         (compare (const_int 0)
2309                  (match_operand:SI 0 "register_operand" "r")))
2310    (clobber (match_scratch:QI 1 "=X"))]
2311   ""
2312   "cp __zero_reg__,%A0
2313         cpc __zero_reg__,%B0
2314         cpc __zero_reg__,%C0
2315         cpc __zero_reg__,%D0"
2316   [(set_attr "cc" "compare")
2317    (set_attr "length" "4")])
2318
2319
2320 (define_insn "*cmpqi"
2321   [(set (cc0)
2322         (compare (match_operand:QI 0 "register_operand"  "r,r,d")
2323                  (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
2324   ""
2325   "@
2326         tst %0
2327         cp %0,%1
2328         cpi %0,lo8(%1)"
2329   [(set_attr "cc" "compare,compare,compare")
2330    (set_attr "length" "1,1,1")])
2331
2332 (define_insn "*cmpqi_sign_extend"
2333   [(set (cc0)
2334         (compare (sign_extend:HI
2335                   (match_operand:QI 0 "register_operand"  "d"))
2336                  (match_operand:HI 1 "const_int_operand" "n")))]
2337   "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
2338   "cpi %0,lo8(%1)"
2339   [(set_attr "cc" "compare")
2340    (set_attr "length" "1")])
2341
2342 (define_insn "*cmphi"
2343   [(set (cc0)
2344         (compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
2345                  (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
2346    (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
2347   ""
2348   "*{
2349   switch (which_alternative)
2350     {
2351     case 0: case 1:
2352       return out_tsthi (insn, operands[0], NULL);
2353
2354     case 2:
2355       return (AS2 (cp,%A0,%A1) CR_TAB
2356               AS2 (cpc,%B0,%B1));
2357     case 3:
2358       if (reg_unused_after (insn, operands[0])
2359           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2360           && test_hard_reg_class (ADDW_REGS, operands[0]))
2361         return AS2 (sbiw,%0,%1);
2362        else
2363         return (AS2 (cpi,%0,%1) CR_TAB
2364                 AS2 (cpc,%B0,__zero_reg__));
2365     case 4:
2366       if (reg_unused_after (insn, operands[0]))
2367         return (AS2 (subi,%0,lo8(%1))  CR_TAB
2368                 AS2 (sbci,%B0,hi8(%1)));
2369       else
2370         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
2371                 AS2 (cpi, %A0,lo8(%1)) CR_TAB
2372                 AS2 (cpc, %B0,%2));
2373    case 5:
2374       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2375               AS2 (cp, %A0,%2) CR_TAB
2376               AS2 (cpc, %B0,__zero_reg__));
2377
2378    case 6:
2379       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2380               AS2 (cp, %A0,%2)       CR_TAB
2381               AS2 (ldi, %2,hi8(%1)) CR_TAB
2382               AS2 (cpc, %B0,%2));
2383     }
2384   return \"bug\";
2385 }" 
2386   [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
2387    (set_attr "length" "1,2,2,2,3,3,4")])
2388
2389
2390 (define_insn "*cmpsi"
2391   [(set (cc0)
2392         (compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
2393                  (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
2394    (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
2395   ""
2396   "*{
2397   switch (which_alternative)
2398     {
2399     case 0:
2400       return out_tstsi (insn, operands[0], NULL);
2401
2402     case 1:
2403       return (AS2 (cp,%A0,%A1) CR_TAB
2404               AS2 (cpc,%B0,%B1) CR_TAB
2405               AS2 (cpc,%C0,%C1) CR_TAB
2406               AS2 (cpc,%D0,%D1));
2407     case 2:
2408       if (reg_unused_after (insn, operands[0])
2409           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2410           && test_hard_reg_class (ADDW_REGS, operands[0]))
2411         return (AS2 (sbiw,%0,%1) CR_TAB
2412                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2413                 AS2 (cpc,%D0,__zero_reg__));
2414       else
2415         return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
2416                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2417                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2418                 AS2 (cpc,%D0,__zero_reg__));
2419     case 3:
2420       if (reg_unused_after (insn, operands[0]))
2421         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
2422                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
2423                 AS2 (sbci,%C0,hlo8(%1))  CR_TAB
2424                 AS2 (sbci,%D0,hhi8(%1)));
2425       else
2426        return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
2427                AS2 (ldi, %2,hi8(%1))  CR_TAB
2428                AS2 (cpc, %B0,%2)       CR_TAB
2429                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2430                AS2 (cpc, %C0,%2)       CR_TAB
2431                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2432                AS2 (cpc, %D0,%2));
2433     case 4:
2434         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
2435                 AS2 (cp,%A0,%2)            CR_TAB
2436                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2437                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2438                 AS2 (cpc,%D0,__zero_reg__));
2439     case 5:
2440        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
2441                AS2 (cp, %A0,%2)        CR_TAB
2442                AS2 (ldi, %2,hi8(%1))  CR_TAB
2443                AS2 (cpc, %B0,%2)       CR_TAB
2444                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2445                AS2 (cpc, %C0,%2)       CR_TAB
2446                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2447                AS2 (cpc, %D0,%2));
2448     }
2449   return \"bug\";
2450 }"
2451   [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
2452    (set_attr "length" "4,4,4,7,5,8")])
2453
2454
2455 ;; ----------------------------------------------------------------------
2456 ;; JUMP INSTRUCTIONS
2457 ;; ----------------------------------------------------------------------
2458 ;; Conditional jump instructions
2459
2460 (define_expand "cbranchsi4"
2461   [(parallel [(set (cc0)
2462                    (compare (match_operand:SI 1 "register_operand" "")
2463                             (match_operand:SI 2 "nonmemory_operand" "")))
2464               (clobber (match_scratch:QI 4 ""))])
2465    (set (pc)
2466         (if_then_else
2467               (match_operator 0 "ordered_comparison_operator" [(cc0)
2468                                                                (const_int 0)])
2469               (label_ref (match_operand 3 "" ""))
2470               (pc)))]
2471  "")
2472
2473 (define_expand "cbranchhi4"
2474   [(parallel [(set (cc0)
2475                    (compare (match_operand:HI 1 "register_operand" "")
2476                             (match_operand:HI 2 "nonmemory_operand" "")))
2477               (clobber (match_scratch:QI 4 ""))])
2478    (set (pc)
2479         (if_then_else
2480               (match_operator 0 "ordered_comparison_operator" [(cc0)
2481                                                                (const_int 0)])
2482               (label_ref (match_operand 3 "" ""))
2483               (pc)))]
2484  "")
2485
2486 (define_expand "cbranchqi4"
2487   [(set (cc0)
2488         (compare (match_operand:QI 1 "register_operand" "")
2489                  (match_operand:QI 2 "nonmemory_operand" "")))
2490    (set (pc)
2491         (if_then_else
2492               (match_operator 0 "ordered_comparison_operator" [(cc0)
2493                                                                (const_int 0)])
2494               (label_ref (match_operand 3 "" ""))
2495               (pc)))]
2496  "")
2497
2498
2499 ;; Test a single bit in a QI/HI/SImode register.
2500 ;; Combine will create zero extract patterns for single bit tests.
2501 ;; permit any mode in source pattern by using VOIDmode.
2502
2503 (define_insn "*sbrx_branch<mode>"
2504   [(set (pc)
2505         (if_then_else
2506          (match_operator 0 "eqne_operator"
2507                          [(zero_extract:QIDI
2508                            (match_operand:VOID 1 "register_operand" "r")
2509                            (const_int 1)
2510                            (match_operand 2 "const_int_operand" "n"))
2511                           (const_int 0)])
2512          (label_ref (match_operand 3 "" ""))
2513          (pc)))]
2514   ""
2515   "* return avr_out_sbxx_branch (insn, operands);"
2516   [(set (attr "length")
2517         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2518                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2519                       (const_int 2)
2520                       (if_then_else (eq_attr "mcu_mega" "no")
2521                                     (const_int 2)
2522                                     (const_int 4))))
2523    (set_attr "cc" "clobber")])
2524
2525 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
2526 ;; or for old peepholes.
2527 ;; Fixme - bitwise Mask will not work for DImode
2528
2529 (define_insn "*sbrx_and_branch<mode>"
2530   [(set (pc)
2531         (if_then_else
2532          (match_operator 0 "eqne_operator"
2533                          [(and:QISI
2534                            (match_operand:QISI 1 "register_operand" "r")
2535                            (match_operand:QISI 2 "single_one_operand" "n"))
2536                           (const_int 0)])
2537          (label_ref (match_operand 3 "" ""))
2538          (pc)))]
2539   ""
2540 {
2541     HOST_WIDE_INT bitnumber;
2542     bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
2543     operands[2] = GEN_INT (bitnumber);
2544     return avr_out_sbxx_branch (insn, operands);
2545 }
2546   [(set (attr "length")
2547         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2548                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
2549                       (const_int 2)
2550                       (if_then_else (eq_attr "mcu_mega" "no")
2551                                     (const_int 2)
2552                                     (const_int 4))))
2553    (set_attr "cc" "clobber")])
2554
2555 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
2556 (define_peephole2
2557   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2558                        (const_int 0)))
2559    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2560                            (label_ref (match_operand 1 "" ""))
2561                            (pc)))]
2562   ""
2563   [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
2564                                                 (const_int 1)
2565                                                 (const_int 7))
2566                                (const_int 0))
2567                            (label_ref (match_dup 1))
2568                            (pc)))]
2569   "")
2570
2571 (define_peephole2
2572   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
2573                        (const_int 0)))
2574    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2575                            (label_ref (match_operand 1 "" ""))
2576                            (pc)))]
2577   ""
2578   [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
2579                                                 (const_int 1)
2580                                                 (const_int 7))
2581                                (const_int 0))
2582                            (label_ref (match_dup 1))
2583                            (pc)))]
2584   "")
2585
2586 (define_peephole2
2587   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2588                                   (const_int 0)))
2589               (clobber (match_operand:HI 2 ""))])
2590    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2591                            (label_ref (match_operand 1 "" ""))
2592                            (pc)))]
2593   ""
2594   [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
2595                                (const_int 0))
2596                            (label_ref (match_dup 1))
2597                            (pc)))]
2598   "")
2599
2600 (define_peephole2
2601   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
2602                                   (const_int 0)))
2603               (clobber (match_operand:HI 2 ""))])
2604    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2605                            (label_ref (match_operand 1 "" ""))
2606                            (pc)))]
2607   ""
2608   [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
2609                                (const_int 0))
2610                            (label_ref (match_dup 1))
2611                            (pc)))]
2612   "")
2613
2614 (define_peephole2
2615   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2616                                   (const_int 0)))
2617               (clobber (match_operand:SI 2 ""))])
2618    (set (pc) (if_then_else (ge (cc0) (const_int 0))
2619                            (label_ref (match_operand 1 "" ""))
2620                            (pc)))]
2621   ""
2622   [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
2623                                (const_int 0))
2624                            (label_ref (match_dup 1))
2625                            (pc)))]
2626   "operands[2] = GEN_INT (-2147483647 - 1);")
2627
2628 (define_peephole2
2629   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
2630                                   (const_int 0)))
2631               (clobber (match_operand:SI 2 ""))])
2632    (set (pc) (if_then_else (lt (cc0) (const_int 0))
2633                            (label_ref (match_operand 1 "" ""))
2634                            (pc)))]
2635   ""
2636   [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
2637                                (const_int 0))
2638                            (label_ref (match_dup 1))
2639                            (pc)))]
2640   "operands[2] = GEN_INT (-2147483647 - 1);")
2641
2642 ;; ************************************************************************
2643 ;; Implementation of conditional jumps here.
2644 ;;  Compare with 0 (test) jumps
2645 ;; ************************************************************************
2646
2647 (define_insn "branch"
2648   [(set (pc)
2649         (if_then_else (match_operator 1 "simple_comparison_operator"
2650                         [(cc0)
2651                          (const_int 0)])
2652                       (label_ref (match_operand 0 "" ""))
2653                       (pc)))]
2654   ""
2655   "*
2656    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2657   [(set_attr "type" "branch")
2658    (set_attr "cc" "clobber")])
2659
2660 ;; ****************************************************************
2661 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
2662 ;; Convert them all to proper jumps.
2663 ;; ****************************************************************/
2664
2665 (define_insn "difficult_branch"
2666   [(set (pc)
2667         (if_then_else (match_operator 1 "difficult_comparison_operator"
2668                         [(cc0)
2669                          (const_int 0)])
2670                       (label_ref (match_operand 0 "" ""))
2671                       (pc)))]
2672   ""
2673   "*
2674    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
2675   [(set_attr "type" "branch1")
2676    (set_attr "cc" "clobber")])
2677
2678 ;; revers branch
2679
2680 (define_insn "rvbranch"
2681   [(set (pc)
2682         (if_then_else (match_operator 1 "simple_comparison_operator" 
2683                         [(cc0)
2684                          (const_int 0)])
2685                       (pc)
2686                       (label_ref (match_operand 0 "" ""))))]
2687   ""
2688   "*
2689    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2690   [(set_attr "type" "branch1")
2691    (set_attr "cc" "clobber")])
2692
2693 (define_insn "difficult_rvbranch"
2694   [(set (pc)
2695         (if_then_else (match_operator 1 "difficult_comparison_operator" 
2696                         [(cc0)
2697                          (const_int 0)])
2698                       (pc)
2699                       (label_ref (match_operand 0 "" ""))))]
2700   ""
2701   "*
2702    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
2703   [(set_attr "type" "branch")
2704    (set_attr "cc" "clobber")])
2705
2706 ;; **************************************************************************
2707 ;; Unconditional and other jump instructions.
2708
2709 (define_insn "jump"
2710   [(set (pc)
2711         (label_ref (match_operand 0 "" "")))]
2712   ""
2713   "*{
2714   if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
2715     return AS1 (jmp,%x0);
2716   return AS1 (rjmp,%x0);
2717 }"
2718   [(set (attr "length")
2719         (if_then_else (match_operand 0 "symbol_ref_operand" "") 
2720                 (if_then_else (eq_attr "mcu_mega" "no")
2721                               (const_int 1)
2722                               (const_int 2))
2723                 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
2724                                    (le (minus (pc) (match_dup 0)) (const_int 2047)))
2725                               (const_int 1)
2726                               (const_int 2))))
2727    (set_attr "cc" "none")])
2728
2729 ;; call
2730
2731 (define_expand "call"
2732   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
2733                    (match_operand:HI 1 "general_operand" ""))
2734              (use (const_int 0))])]
2735   ;; Operand 1 not used on the AVR.
2736   ;; Operand 2 is 1 for tail-call, 0 otherwise.
2737   ""
2738   "")
2739
2740 (define_expand "sibcall"
2741   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
2742                    (match_operand:HI 1 "general_operand" ""))
2743              (use (const_int 1))])]
2744   ;; Operand 1 not used on the AVR.
2745   ;; Operand 2 is 1 for tail-call, 0 otherwise.
2746   ""
2747   "")
2748
2749 ;; call value
2750
2751 (define_expand "call_value"
2752   [(parallel[(set (match_operand 0 "register_operand" "")
2753                   (call (match_operand:HI 1 "call_insn_operand" "")
2754                         (match_operand:HI 2 "general_operand" "")))
2755              (use (const_int 0))])]
2756   ;; Operand 2 not used on the AVR.
2757   ;; Operand 3 is 1 for tail-call, 0 otherwise.
2758   ""
2759   "")
2760
2761 (define_expand "sibcall_value"
2762   [(parallel[(set (match_operand 0 "register_operand" "")
2763                   (call (match_operand:HI 1 "call_insn_operand" "")
2764                         (match_operand:HI 2 "general_operand" "")))
2765              (use (const_int 1))])]
2766   ;; Operand 2 not used on the AVR.
2767   ;; Operand 3 is 1 for tail-call, 0 otherwise.
2768   ""
2769   "")
2770
2771 (define_insn "*call_insn"
2772   [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
2773                    (match_operand:HI 1 "general_operand"           "X,X,X,X"))
2774              (use (match_operand:HI 2 "const_int_operand"          "L,L,P,P"))])]
2775   ;; Operand 1 not used on the AVR.
2776   ;; Operand 2 is 1 for tail-call, 0 otherwise.
2777   ""
2778   "@
2779     %!icall
2780     %~call %x0
2781     %!ijmp
2782     %~jmp %x0"
2783   [(set_attr "cc" "clobber")
2784    (set_attr_alternative "length"
2785                          [(const_int 1)
2786                           (if_then_else (eq_attr "mcu_mega" "yes")
2787                                         (const_int 2)
2788                                         (const_int 1))
2789                           (const_int 1)
2790                           (if_then_else (eq_attr "mcu_mega" "yes")
2791                                         (const_int 2)
2792                                         (const_int 1))])])
2793
2794 (define_insn "*call_value_insn"
2795   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
2796                   (call (mem:HI (match_operand:HI 1 "nonmemory_operand"  "z,s,z,s"))
2797                         (match_operand:HI 2 "general_operand"            "X,X,X,X")))
2798              (use (match_operand:HI 3 "const_int_operand"                "L,L,P,P"))])]
2799   ;; Operand 2 not used on the AVR.
2800   ;; Operand 3 is 1 for tail-call, 0 otherwise.
2801   ""
2802   "@
2803     %!icall
2804     %~call %x1
2805     %!ijmp
2806     %~jmp %x1"
2807   [(set_attr "cc" "clobber")
2808    (set_attr_alternative "length"
2809                          [(const_int 1)
2810                           (if_then_else (eq_attr "mcu_mega" "yes")
2811                                         (const_int 2)
2812                                         (const_int 1))
2813                           (const_int 1)
2814                           (if_then_else (eq_attr "mcu_mega" "yes")
2815                                         (const_int 2)
2816                                         (const_int 1))])])
2817
2818 (define_insn "nop"
2819   [(const_int 0)]
2820   ""
2821   "nop"
2822   [(set_attr "cc" "none")
2823    (set_attr "length" "1")])
2824
2825 ; indirect jump
2826
2827 (define_expand "indirect_jump"
2828   [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
2829   ""
2830   " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
2831     {
2832       operands[0] = copy_to_mode_reg(HImode, operand0);
2833     }"
2834 )
2835
2836 ; indirect jump
2837 (define_insn "*jcindirect_jump"
2838   [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
2839   ""
2840   "%~jmp %x0"
2841   [(set_attr "length" "2")
2842    (set_attr "cc" "none")])
2843
2844 ;;
2845 (define_insn "*njcindirect_jump"
2846   [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
2847   "!AVR_HAVE_EIJMP_EICALL"
2848   "@
2849         ijmp
2850         push %A0\;push %B0\;ret"
2851   [(set_attr "length" "1,3")
2852    (set_attr "cc" "none,none")])
2853
2854 (define_insn "*indirect_jump_avr6"
2855   [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
2856   "AVR_HAVE_EIJMP_EICALL"
2857   "eijmp"
2858   [(set_attr "length" "1")
2859    (set_attr "cc" "none")])
2860
2861 ;; table jump
2862
2863 ;; Table made from "rjmp" instructions for <=8K devices.
2864 (define_insn "*tablejump_rjmp"
2865   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
2866                         UNSPEC_INDEX_JMP))
2867    (use (label_ref (match_operand 1 "" "")))
2868    (clobber (match_dup 0))]
2869   "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
2870   "@
2871         ijmp
2872         push %A0\;push %B0\;ret"
2873   [(set_attr "length" "1,3")
2874    (set_attr "cc" "none,none")])
2875
2876 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
2877 (define_insn "*tablejump_lib"
2878   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2879                         UNSPEC_INDEX_JMP))
2880    (use (label_ref (match_operand 1 "" "")))
2881    (clobber (match_dup 0))]
2882   "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
2883   "%~jmp __tablejump2__"
2884   [(set_attr "length" "2")
2885    (set_attr "cc" "clobber")])
2886
2887 (define_insn "*tablejump_enh"
2888   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2889                         UNSPEC_INDEX_JMP))
2890    (use (label_ref (match_operand 1 "" "")))
2891    (clobber (match_dup 0))]
2892   "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
2893   "lsl r30
2894         rol r31
2895         lpm __tmp_reg__,Z+
2896         lpm r31,Z
2897         mov r30,__tmp_reg__
2898         %!ijmp"
2899   [(set_attr "length" "6")
2900    (set_attr "cc" "clobber")])
2901
2902 (define_insn "*tablejump"
2903   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
2904                         UNSPEC_INDEX_JMP))
2905    (use (label_ref (match_operand 1 "" "")))
2906    (clobber (match_dup 0))]
2907   "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
2908   "lsl r30
2909         rol r31
2910         lpm
2911         inc r30
2912         push r0
2913         lpm
2914         push r0
2915         ret"
2916   [(set_attr "length" "8")
2917    (set_attr "cc" "clobber")])
2918
2919 (define_expand "casesi"
2920   [(set (match_dup 6)
2921         (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
2922                   (match_operand:HI 1 "register_operand" "")))
2923    (parallel [(set (cc0)
2924                    (compare (match_dup 6)
2925                             (match_operand:HI 2 "register_operand" "")))
2926               (clobber (match_scratch:QI 9 ""))])
2927    
2928    (set (pc)
2929         (if_then_else (gtu (cc0)
2930                            (const_int 0))
2931                       (label_ref (match_operand 4 "" ""))
2932                       (pc)))
2933
2934    (set (match_dup 6)
2935         (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
2936
2937    (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
2938               (use (label_ref (match_dup 3)))
2939               (clobber (match_dup 6))])]
2940   ""
2941   "
2942 {
2943   operands[6] = gen_reg_rtx (HImode);
2944 }")
2945
2946
2947 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2948 ;; This instruction sets Z flag
2949
2950 (define_insn "sez"
2951   [(set (cc0) (const_int 0))]
2952   ""
2953   "sez"
2954   [(set_attr "length" "1")
2955    (set_attr "cc" "compare")])
2956
2957 ;; Clear/set/test a single bit in I/O address space.
2958
2959 (define_insn "*cbi"
2960   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2961         (and:QI (mem:QI (match_dup 0))
2962                 (match_operand:QI 1 "single_zero_operand" "n")))]
2963   "(optimize > 0)"
2964 {
2965   operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
2966   return AS2 (cbi,%m0-0x20,%2);
2967 }
2968   [(set_attr "length" "1")
2969    (set_attr "cc" "none")])
2970
2971 (define_insn "*sbi"
2972   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
2973         (ior:QI (mem:QI (match_dup 0))
2974                 (match_operand:QI 1 "single_one_operand" "n")))]
2975   "(optimize > 0)"
2976 {
2977   operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
2978   return AS2 (sbi,%m0-0x20,%2);
2979 }
2980   [(set_attr "length" "1")
2981    (set_attr "cc" "none")])
2982
2983 ;; Lower half of the I/O space - use sbic/sbis directly.
2984 (define_insn "*sbix_branch"
2985   [(set (pc)
2986         (if_then_else
2987          (match_operator 0 "eqne_operator"
2988                          [(zero_extract:HI
2989                            (mem:QI (match_operand 1 "low_io_address_operand" "n"))
2990                            (const_int 1)
2991                            (match_operand 2 "const_int_operand" "n"))
2992                           (const_int 0)])
2993          (label_ref (match_operand 3 "" ""))
2994          (pc)))]
2995   "(optimize > 0)"
2996   "* return avr_out_sbxx_branch (insn, operands);"
2997   [(set (attr "length")
2998         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
2999                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
3000                       (const_int 2)
3001                       (if_then_else (eq_attr "mcu_mega" "no")
3002                                     (const_int 2)
3003                                     (const_int 4))))
3004    (set_attr "cc" "clobber")])
3005
3006 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3007 (define_insn "*sbix_branch_bit7"
3008   [(set (pc)
3009         (if_then_else
3010          (match_operator 0 "gelt_operator"
3011                          [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3012                           (const_int 0)])
3013          (label_ref (match_operand 2 "" ""))
3014          (pc)))]
3015   "(optimize > 0)"
3016 {
3017   operands[3] = operands[2];
3018   operands[2] = GEN_INT (7);
3019   return avr_out_sbxx_branch (insn, operands);
3020 }
3021   [(set (attr "length")
3022         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3023                            (le (minus (pc) (match_dup 2)) (const_int 2046)))
3024                       (const_int 2)
3025                       (if_then_else (eq_attr "mcu_mega" "no")
3026                                     (const_int 2)
3027                                     (const_int 4))))
3028    (set_attr "cc" "clobber")])
3029
3030 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3031 (define_insn "*sbix_branch_tmp"
3032   [(set (pc)
3033         (if_then_else
3034          (match_operator 0 "eqne_operator"
3035                          [(zero_extract:HI
3036                            (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3037                            (const_int 1)
3038                            (match_operand 2 "const_int_operand" "n"))
3039                           (const_int 0)])
3040          (label_ref (match_operand 3 "" ""))
3041          (pc)))]
3042   "(optimize > 0)"
3043   "* return avr_out_sbxx_branch (insn, operands);"
3044   [(set (attr "length")
3045         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3046                            (le (minus (pc) (match_dup 3)) (const_int 2045)))
3047                       (const_int 3)
3048                       (if_then_else (eq_attr "mcu_mega" "no")
3049                                     (const_int 3)
3050                                     (const_int 5))))
3051    (set_attr "cc" "clobber")])
3052
3053 (define_insn "*sbix_branch_tmp_bit7"
3054   [(set (pc)
3055         (if_then_else
3056          (match_operator 0 "gelt_operator"
3057                          [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3058                           (const_int 0)])
3059          (label_ref (match_operand 2 "" ""))
3060          (pc)))]
3061   "(optimize > 0)"
3062 {
3063   operands[3] = operands[2];
3064   operands[2] = GEN_INT (7);
3065   return avr_out_sbxx_branch (insn, operands);
3066 }
3067   [(set (attr "length")
3068         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3069                            (le (minus (pc) (match_dup 2)) (const_int 2045)))
3070                       (const_int 3)
3071                       (if_then_else (eq_attr "mcu_mega" "no")
3072                                     (const_int 3)
3073                                     (const_int 5))))
3074    (set_attr "cc" "clobber")])
3075
3076 ;; ************************* Peepholes ********************************
3077
3078 (define_peephole
3079   [(set (match_operand:SI 0 "d_register_operand" "")
3080         (plus:SI (match_dup 0)
3081                  (const_int -1)))
3082    (parallel
3083     [(set (cc0)
3084           (compare (match_dup 0)
3085                    (const_int -1)))
3086      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3087    (set (pc)
3088         (if_then_else (ne (cc0) (const_int 0))
3089                       (label_ref (match_operand 2 "" ""))
3090                       (pc)))]
3091   ""
3092   "*
3093 {
3094   CC_STATUS_INIT;
3095   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3096     output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3097                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3098                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3099   else
3100     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3101                      AS2 (sbc,%B0,__zero_reg__) CR_TAB
3102                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3103                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3104   switch (avr_jump_mode (operands[2],insn))
3105   {
3106     case 1:
3107       return AS1 (brcc,%2);
3108     case 2:
3109       return (AS1 (brcs,.+2) CR_TAB
3110               AS1 (rjmp,%2));
3111   }
3112   return (AS1 (brcs,.+4) CR_TAB
3113           AS1 (jmp,%2));
3114 }")
3115
3116 (define_peephole
3117   [(set (match_operand:HI 0 "d_register_operand" "")
3118         (plus:HI (match_dup 0)
3119                  (const_int -1)))
3120    (parallel
3121     [(set (cc0)
3122           (compare (match_dup 0)
3123                    (const_int 65535)))
3124      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3125    (set (pc)
3126         (if_then_else (ne (cc0) (const_int 0))
3127                       (label_ref (match_operand 2 "" ""))
3128                       (pc)))]
3129   ""
3130   "*
3131 {
3132   CC_STATUS_INIT;
3133   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3134     output_asm_insn (AS2 (sbiw,%0,1), operands);
3135   else
3136     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3137                      AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3138   switch (avr_jump_mode (operands[2],insn))
3139   {
3140     case 1:
3141       return AS1 (brcc,%2);
3142     case 2:
3143       return (AS1 (brcs,.+2) CR_TAB
3144               AS1 (rjmp,%2));
3145   }
3146   return (AS1 (brcs,.+4) CR_TAB
3147           AS1 (jmp,%2));
3148 }")
3149
3150 (define_peephole
3151   [(set (match_operand:QI 0 "d_register_operand" "")
3152         (plus:QI (match_dup 0)
3153                  (const_int -1)))
3154    (set (cc0)
3155         (compare (match_dup 0)
3156                  (const_int -1)))
3157    (set (pc)
3158         (if_then_else (ne (cc0) (const_int 0))
3159                       (label_ref (match_operand 1 "" ""))
3160                       (pc)))]
3161   ""
3162   "*
3163 {
3164   CC_STATUS_INIT;
3165   cc_status.value1 = operands[0];
3166   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3167   output_asm_insn (AS2 (subi,%A0,1), operands);
3168   switch (avr_jump_mode (operands[1],insn))
3169   {
3170     case 1:
3171       return AS1 (brcc,%1);
3172     case 2:
3173       return (AS1 (brcs,.+2) CR_TAB
3174               AS1 (rjmp,%1));
3175   }
3176   return (AS1 (brcs,.+4) CR_TAB
3177           AS1 (jmp,%1));
3178 }")
3179
3180 (define_peephole
3181   [(set (cc0)
3182         (compare (match_operand:QI 0 "register_operand" "")
3183                  (const_int 0)))
3184    (set (pc)
3185         (if_then_else (eq (cc0) (const_int 0))
3186                       (label_ref (match_operand 1 "" ""))
3187                       (pc)))]
3188   "jump_over_one_insn_p (insn, operands[1])"
3189   "cpse %0,__zero_reg__")
3190
3191 (define_peephole
3192   [(set (cc0)
3193         (compare (match_operand:QI 0 "register_operand" "")
3194                  (match_operand:QI 1 "register_operand" "")))
3195    (set (pc)
3196         (if_then_else (eq (cc0) (const_int 0))
3197                       (label_ref (match_operand 2 "" ""))
3198                       (pc)))]
3199   "jump_over_one_insn_p (insn, operands[2])"
3200   "cpse %0,%1")
3201
3202 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3203 ;;prologue/epilogue support instructions
3204
3205 (define_insn "popqi"
3206   [(set (match_operand:QI 0 "register_operand" "=r")
3207         (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
3208   ""
3209   "pop %0"
3210   [(set_attr "cc" "none")
3211    (set_attr "length" "1")])
3212
3213 ;; Enable Interrupts
3214 (define_insn "enable_interrupt"
3215   [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
3216   ""
3217   "sei"
3218   [(set_attr "length" "1")
3219    (set_attr "cc" "none")])
3220
3221 ;; Disable Interrupts
3222 (define_insn "disable_interrupt"
3223   [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
3224   ""
3225   "cli"
3226   [(set_attr "length" "1")
3227    (set_attr "cc" "none")])
3228
3229 ;;  Library prologue saves
3230 (define_insn "call_prologue_saves"
3231   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3232    (match_operand:HI 0 "immediate_operand" "")
3233    (set (reg:HI REG_SP) (minus:HI 
3234                            (reg:HI REG_SP)
3235                            (match_operand:HI 1 "immediate_operand" "")))
3236    (use (reg:HI REG_X))
3237    (clobber (reg:HI REG_Z))]
3238   ""
3239   "ldi r30,lo8(gs(1f))
3240         ldi r31,hi8(gs(1f))
3241         %~jmp __prologue_saves__+((18 - %0) * 2)
3242 1:"
3243   [(set_attr_alternative "length"
3244                          [(if_then_else (eq_attr "mcu_mega" "yes")
3245                                         (const_int 6)
3246                                         (const_int 5))])
3247   (set_attr "cc" "clobber")
3248   ])
3249   
3250 ;  epilogue  restores using library
3251 (define_insn "epilogue_restores"
3252   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3253    (set (reg:HI REG_Y ) (plus:HI 
3254                            (reg:HI REG_Y)
3255                            (match_operand:HI 0 "immediate_operand" ""))) 
3256    (set (reg:HI REG_SP) (reg:HI REG_Y))
3257    (clobber  (reg:QI REG_Z))]
3258   ""
3259   "ldi r30, lo8(%0)
3260         %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3261   [(set_attr_alternative "length"
3262                          [(if_then_else (eq_attr "mcu_mega" "yes")
3263                                         (const_int 3)
3264                                         (const_int 2))])
3265   (set_attr "cc" "clobber")
3266   ])
3267   
3268 ; return
3269 (define_insn "return"
3270   [(return)]
3271   "reload_completed && avr_simple_epilogue ()"
3272   "ret"
3273   [(set_attr "cc" "none")
3274    (set_attr "length" "1")])
3275
3276 (define_insn "return_from_epilogue"
3277   [(return)]
3278   "(reload_completed 
3279     && cfun->machine 
3280     && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3281     && !cfun->machine->is_naked)"
3282   "ret"
3283   [(set_attr "cc" "none")
3284    (set_attr "length" "1")])
3285
3286 (define_insn "return_from_interrupt_epilogue"
3287   [(return)]
3288   "(reload_completed 
3289     && cfun->machine 
3290     && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3291     && !cfun->machine->is_naked)"
3292   "reti"
3293   [(set_attr "cc" "none")
3294    (set_attr "length" "1")])
3295
3296 (define_insn "return_from_naked_epilogue"
3297   [(return)]
3298   "(reload_completed 
3299     && cfun->machine 
3300     && cfun->machine->is_naked)"
3301   ""
3302   [(set_attr "cc" "none")
3303    (set_attr "length" "0")])
3304
3305 (define_expand "prologue"
3306   [(const_int 0)]
3307   ""
3308   "
3309   {
3310     expand_prologue (); 
3311     DONE;
3312   }")
3313
3314 (define_expand "epilogue"
3315   [(const_int 0)]
3316   ""
3317   {
3318     expand_epilogue (false /* sibcall_p */);
3319     DONE;
3320   })
3321
3322 (define_expand "sibcall_epilogue"
3323   [(const_int 0)]
3324   ""
3325   {
3326     expand_epilogue (true /* sibcall_p */);
3327     DONE;
3328   })
3329
3330 ;; Some instructions resp. instruction sequences available
3331 ;; via builtins.
3332
3333 (define_insn "delay_cycles_1"
3334   [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
3335                      (const_int 1)]
3336                     UNSPECV_DELAY_CYCLES)
3337    (clobber (match_scratch:QI 1 "=&d"))]
3338   ""
3339   "ldi %1,lo8(%0)
3340         1: dec %1
3341         brne 1b"
3342   [(set_attr "length" "3")
3343    (set_attr "cc" "clobber")])
3344
3345 (define_insn "delay_cycles_2"
3346   [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
3347                      (const_int 2)]
3348                     UNSPECV_DELAY_CYCLES)
3349    (clobber (match_scratch:HI 1 "=&w"))]
3350   ""
3351   "ldi %A1,lo8(%0)
3352         ldi %B1,hi8(%0)
3353         1: sbiw %A1,1
3354         brne 1b"
3355   [(set_attr "length" "4")
3356    (set_attr "cc" "clobber")])
3357
3358 (define_insn "delay_cycles_3"
3359   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3360                      (const_int 3)]
3361                     UNSPECV_DELAY_CYCLES)
3362    (clobber (match_scratch:QI 1 "=&d"))
3363    (clobber (match_scratch:QI 2 "=&d"))
3364    (clobber (match_scratch:QI 3 "=&d"))]
3365   ""
3366   "ldi %1,lo8(%0)
3367         ldi %2,hi8(%0)
3368         ldi %3,hlo8(%0)
3369         1: subi %1,1
3370         sbci %2,0
3371         sbci %3,0
3372         brne 1b"
3373   [(set_attr "length" "7")
3374    (set_attr "cc" "clobber")])
3375
3376 (define_insn "delay_cycles_4"
3377   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3378                      (const_int 4)]
3379                     UNSPECV_DELAY_CYCLES)
3380    (clobber (match_scratch:QI 1 "=&d"))
3381    (clobber (match_scratch:QI 2 "=&d"))
3382    (clobber (match_scratch:QI 3 "=&d"))
3383    (clobber (match_scratch:QI 4 "=&d"))]
3384   ""
3385   "ldi %1,lo8(%0)
3386         ldi %2,hi8(%0)
3387         ldi %3,hlo8(%0)
3388         ldi %4,hhi8(%0)
3389         1: subi %1,1
3390         sbci %2,0
3391         sbci %3,0
3392         sbci %4,0
3393         brne 1b"
3394   [(set_attr "length" "9")
3395    (set_attr "cc" "clobber")])
3396
3397 ;; CPU instructions
3398
3399 ;; NOP taking 1 or 2 Ticks 
3400 (define_insn "nopv"
3401   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")] 
3402                     UNSPECV_NOP)]
3403   ""
3404   "@
3405         nop
3406         rjmp ."
3407   [(set_attr "length" "1")
3408    (set_attr "cc" "none")])
3409
3410 ;; SLEEP
3411 (define_insn "sleep"
3412   [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
3413   ""
3414   "sleep"
3415   [(set_attr "length" "1")
3416    (set_attr "cc" "none")])
3417  
3418 ;; WDR
3419 (define_insn "wdr"
3420   [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
3421   ""
3422   "wdr"
3423   [(set_attr "length" "1")
3424    (set_attr "cc" "none")])
3425   
3426 ;; FMUL
3427 (define_expand "fmul"
3428   [(set (reg:QI 24)
3429         (match_operand:QI 1 "register_operand" ""))
3430    (set (reg:QI 25)
3431         (match_operand:QI 2 "register_operand" ""))
3432    (parallel [(set (reg:HI 22)
3433                    (unspec:HI [(reg:QI 24)
3434                                (reg:QI 25)] UNSPEC_FMUL))
3435               (clobber (reg:HI 24))])
3436    (set (match_operand:HI 0 "register_operand" "")
3437         (reg:HI 22))]
3438   ""
3439   {
3440     if (AVR_HAVE_MUL)
3441       {
3442         emit_insn (gen_fmul_insn (operand0, operand1, operand2));
3443         DONE;
3444       }
3445   })
3446
3447 (define_insn "fmul_insn"
3448   [(set (match_operand:HI 0 "register_operand" "=r")
3449         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
3450                     (match_operand:QI 2 "register_operand" "a")]
3451                    UNSPEC_FMUL))]
3452   "AVR_HAVE_MUL"
3453   "fmul %1,%2
3454         movw %0,r0
3455         clr __zero_reg__"
3456   [(set_attr "length" "3")
3457    (set_attr "cc" "clobber")])
3458
3459 (define_insn "*fmul.call"
3460   [(set (reg:HI 22)
3461         (unspec:HI [(reg:QI 24)
3462                     (reg:QI 25)] UNSPEC_FMUL))
3463    (clobber (reg:HI 24))]
3464   "!AVR_HAVE_MUL"
3465   "%~call __fmul"
3466   [(set_attr "type" "xcall")
3467    (set_attr "cc" "clobber")])
3468
3469 ;; FMULS
3470 (define_expand "fmuls"
3471   [(set (reg:QI 24)
3472         (match_operand:QI 1 "register_operand" ""))
3473    (set (reg:QI 25)
3474         (match_operand:QI 2 "register_operand" ""))
3475    (parallel [(set (reg:HI 22)
3476                    (unspec:HI [(reg:QI 24)
3477                                (reg:QI 25)] UNSPEC_FMULS))
3478               (clobber (reg:HI 24))])
3479    (set (match_operand:HI 0 "register_operand" "")
3480         (reg:HI 22))]
3481   ""
3482   {
3483     if (AVR_HAVE_MUL)
3484       {
3485         emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
3486         DONE;
3487       }
3488   })
3489
3490 (define_insn "fmuls_insn"
3491   [(set (match_operand:HI 0 "register_operand" "=r")
3492         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
3493                     (match_operand:QI 2 "register_operand" "a")]
3494                    UNSPEC_FMULS))]
3495   "AVR_HAVE_MUL"
3496   "fmuls %1,%2
3497         movw %0,r0
3498         clr __zero_reg__"
3499   [(set_attr "length" "3")
3500    (set_attr "cc" "clobber")])
3501
3502 (define_insn "*fmuls.call"
3503   [(set (reg:HI 22)
3504         (unspec:HI [(reg:QI 24)
3505                     (reg:QI 25)] UNSPEC_FMULS))
3506    (clobber (reg:HI 24))]
3507   "!AVR_HAVE_MUL"
3508   "%~call __fmuls"
3509   [(set_attr "type" "xcall")
3510    (set_attr "cc" "clobber")])
3511
3512 ;; FMULSU
3513 (define_expand "fmulsu"
3514   [(set (reg:QI 24)
3515         (match_operand:QI 1 "register_operand" ""))
3516    (set (reg:QI 25)
3517         (match_operand:QI 2 "register_operand" ""))
3518    (parallel [(set (reg:HI 22)
3519                    (unspec:HI [(reg:QI 24)
3520                                (reg:QI 25)] UNSPEC_FMULSU))
3521               (clobber (reg:HI 24))])
3522    (set (match_operand:HI 0 "register_operand" "")
3523         (reg:HI 22))]
3524   ""
3525   {
3526     if (AVR_HAVE_MUL)
3527       {
3528         emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
3529         DONE;
3530       }
3531   })
3532
3533 (define_insn "fmulsu_insn"
3534   [(set (match_operand:HI 0 "register_operand" "=r")
3535         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
3536                     (match_operand:QI 2 "register_operand" "a")]
3537                    UNSPEC_FMULSU))]
3538   "AVR_HAVE_MUL"
3539   "fmulsu %1,%2
3540         movw %0,r0
3541         clr __zero_reg__"
3542   [(set_attr "length" "3")
3543    (set_attr "cc" "clobber")])
3544
3545 (define_insn "*fmulsu.call"
3546   [(set (reg:HI 22)
3547         (unspec:HI [(reg:QI 24)
3548                     (reg:QI 25)] UNSPEC_FMULSU))
3549    (clobber (reg:HI 24))]
3550   "!AVR_HAVE_MUL"
3551   "%~call __fmulsu"
3552   [(set_attr "type" "xcall")
3553    (set_attr "cc" "clobber")])
3554
3555 \f
3556 ;; Some combiner patterns dealing with bits.
3557 ;; See PR42210
3558
3559 ;; Move bit $3.0 into bit $0.$4
3560 (define_insn "*movbitqi.1-6.a"
3561   [(set (match_operand:QI 0 "register_operand"                               "=r")
3562         (ior:QI (and:QI (match_operand:QI 1 "register_operand"                "0")
3563                         (match_operand:QI 2 "single_zero_operand"             "n"))
3564                 (and:QI (ashift:QI (match_operand:QI 3 "register_operand"     "r")
3565                                    (match_operand:QI 4 "const_0_to_7_operand" "n"))
3566                         (match_operand:QI 5 "single_one_operand"              "n"))))]
3567   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
3568    && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
3569   "bst %3,0\;bld %0,%4"
3570   [(set_attr "length" "2")
3571    (set_attr "cc" "none")])
3572
3573 ;; Move bit $3.0 into bit $0.$4
3574 ;; Variation of above. Unfortunately, there is no canonicalized representation
3575 ;; of moving around bits.  So what we see here depends on how user writes down
3576 ;; bit manipulations.
3577 (define_insn "*movbitqi.1-6.b"
3578   [(set (match_operand:QI 0 "register_operand"                            "=r")
3579         (ior:QI (and:QI (match_operand:QI 1 "register_operand"             "0")
3580                         (match_operand:QI 2 "single_zero_operand"          "n"))
3581                 (ashift:QI (and:QI (match_operand:QI 3 "register_operand"  "r")
3582                                    (const_int 1))
3583                            (match_operand:QI 4 "const_0_to_7_operand"      "n"))))]
3584   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
3585   "bst %3,0\;bld %0,%4"
3586   [(set_attr "length" "2")
3587    (set_attr "cc" "none")])
3588
3589 ;; Move bit $3.0 into bit $0.0.
3590 ;; For bit 0, combiner generates slightly different pattern.
3591 (define_insn "*movbitqi.0"
3592   [(set (match_operand:QI 0 "register_operand"                     "=r")
3593         (ior:QI (and:QI (match_operand:QI 1 "register_operand"      "0")
3594                         (match_operand:QI 2 "single_zero_operand"   "n"))
3595                 (and:QI (match_operand:QI 3 "register_operand"      "r")
3596                         (const_int 1))))]
3597   "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
3598   "bst %3,0\;bld %0,0"
3599   [(set_attr "length" "2")
3600    (set_attr "cc" "none")])
3601
3602 ;; Move bit $2.0 into bit $0.7.
3603 ;; For bit 7, combiner generates slightly different pattern
3604 (define_insn "*movbitqi.7"
3605   [(set (match_operand:QI 0 "register_operand"                      "=r")
3606         (ior:QI (and:QI (match_operand:QI 1 "register_operand"       "0")
3607                         (const_int 127))
3608                 (ashift:QI (match_operand:QI 2 "register_operand"    "r")
3609                            (const_int 7))))]
3610   ""
3611   "bst %2,0\;bld %0,7"
3612   [(set_attr "length" "2")
3613    (set_attr "cc" "none")])
3614
3615 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
3616 ;; and input/output match.  We provide a special pattern for this, because
3617 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
3618 ;; operation on I/O is atomic.
3619 (define_insn "*insv.io"
3620   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
3621                          (const_int 1)
3622                          (match_operand:QI 1 "const_0_to_7_operand"        "n,n,n"))
3623         (match_operand:QI 2 "nonmemory_operand"                            "L,P,r"))]
3624   ""
3625   "@
3626         cbi %m0-0x20,%1
3627         sbi %m0-0x20,%1
3628         sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
3629   [(set_attr "length" "1,1,4")
3630    (set_attr "cc" "none")])
3631
3632 (define_insn "*insv.not.io"
3633   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3634                          (const_int 1)
3635                          (match_operand:QI 1 "const_0_to_7_operand"        "n"))
3636         (not:QI (match_operand:QI 2 "register_operand"                     "r")))]
3637   ""
3638   "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
3639   [(set_attr "length" "4")
3640    (set_attr "cc" "none")])
3641
3642 ;; The insv expander.
3643 ;; We only support 1-bit inserts
3644 (define_expand "insv"
3645   [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
3646                          (match_operand:QI 1 "const1_operand" "")        ; width
3647                          (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
3648         (match_operand:QI 3 "nonmemory_operand" ""))]
3649   "optimize"
3650   "")
3651
3652 ;; Insert bit $2.0 into $0.$1
3653 (define_insn "*insv.reg"
3654   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r,d,d,l,l")
3655                          (const_int 1)
3656                          (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
3657         (match_operand:QI 2 "nonmemory_operand"                     "r,L,P,L,P"))]
3658   ""
3659   "@
3660         bst %2,0\;bld %0,%1
3661         andi %0,lo8(~(1<<%1))
3662         ori %0,lo8(1<<%1)
3663         clt\;bld %0,%1
3664         set\;bld %0,%1"
3665   [(set_attr "length" "2,1,1,2,2")
3666    (set_attr "cc" "none,set_zn,set_zn,none,none")])
3667
3668 \f
3669 ;; Some combine patterns that try to fix bad code when a value is composed
3670 ;; from byte parts like in PR27663.
3671 ;; The patterns give some release but the code still is not optimal,
3672 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
3673 ;; That switch obfuscates things here and in many other places.
3674
3675 (define_insn_and_split "*ior<mode>qi.byte0"
3676   [(set (match_operand:HISI 0 "register_operand"                 "=r")
3677         (ior:HISI
3678          (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
3679          (match_operand:HISI 2 "register_operand"                 "0")))]
3680   ""
3681   "#"
3682   "reload_completed"
3683   [(set (match_dup 3)
3684         (ior:QI (match_dup 3)
3685                 (match_dup 1)))]
3686   {
3687     operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
3688   })
3689
3690 (define_insn_and_split "*ior<mode>qi.byte1-3"
3691   [(set (match_operand:HISI 0 "register_operand"                              "=r")
3692         (ior:HISI
3693          (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
3694                       (match_operand:QI 2 "const_8_16_24_operand"              "n"))
3695          (match_operand:HISI 3 "register_operand"                              "0")))]
3696   "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3697   "#"
3698   "&& reload_completed"
3699   [(set (match_dup 4)
3700         (ior:QI (match_dup 4)
3701                 (match_dup 1)))]
3702   {
3703     int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
3704     operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
3705   })
3706
3707 (define_expand "extzv"
3708   [(set (match_operand:QI 0 "register_operand" "")
3709         (zero_extract:QI (match_operand:QI 1 "register_operand"  "")
3710                          (match_operand:QI 2 "const1_operand" "")
3711                          (match_operand:QI 3 "const_0_to_7_operand" "")))]
3712   ""
3713   "")
3714
3715 (define_insn "*extzv"
3716   [(set (match_operand:QI 0 "register_operand"                   "=*d,*d,*d,*d,r")
3717         (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,0,r")
3718                          (const_int 1)
3719                          (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
3720   ""
3721   "@
3722         andi %0,1
3723         mov %0,%1\;andi %0,1
3724         lsr %0\;andi %0,1
3725         swap %0\;andi %0,1
3726         bst %1,%2\;clr %0\;bld %0,0"
3727   [(set_attr "length" "1,2,2,2,3")
3728    (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
3729
3730 (define_insn_and_split "*extzv.qihi1"
3731   [(set (match_operand:HI 0 "register_operand"                     "=r")
3732         (zero_extract:HI (match_operand:QI 1 "register_operand"     "r")
3733                          (const_int 1)
3734                          (match_operand:QI 2 "const_0_to_7_operand" "n")))]
3735   ""
3736   "#"
3737   ""
3738   [(set (match_dup 3)
3739         (zero_extract:QI (match_dup 1)
3740                          (const_int 1)
3741                          (match_dup 2)))
3742    (set (match_dup 4)
3743         (const_int 0))]
3744   {
3745     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3746     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3747   })
3748
3749 (define_insn_and_split "*extzv.qihi2"
3750   [(set (match_operand:HI 0 "register_operand"                      "=r")
3751         (zero_extend:HI 
3752          (zero_extract:QI (match_operand:QI 1 "register_operand"     "r")
3753                           (const_int 1)
3754                           (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
3755   ""
3756   "#"
3757   ""
3758   [(set (match_dup 3)
3759         (zero_extract:QI (match_dup 1)
3760                          (const_int 1)
3761                          (match_dup 2)))
3762    (set (match_dup 4)
3763         (const_int 0))]
3764   {
3765     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3766     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3767   })