OSDN Git Service

PR target/49881
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.md
1 ;;   Machine description for GNU compiler,
2 ;;   for ATMEL AVR micro controllers.
3 ;;   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;;   2009, 2010 Free Software Foundation, Inc.
5 ;;   Contributed by Denis Chertykov (chertykov@gmail.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;; Special characters after '%':
24 ;;  A  No effect (add 0).
25 ;;  B  Add 1 to REG number, MEM address or CONST_INT.
26 ;;  C  Add 2.
27 ;;  D  Add 3.
28 ;;  j  Branch condition.
29 ;;  k  Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;;  o  Displacement for (mem (plus (reg) (const_int))) operands.
32 ;;  p  POST_INC or PRE_DEC address as a pointer (X, Y, Z)
33 ;;  r  POST_INC or PRE_DEC address as a register (r26, r28, r30)
34 ;;..x..Constant Direct Program memory address.
35 ;;  ~  Output 'r' if not AVR_HAVE_JMP_CALL.
36 ;;  !  Output 'e' if AVR_HAVE_EIJMP_EICALL.
37
38
39 (define_constants
40   [(REG_X       26)
41    (REG_Y       28)
42    (REG_Z       30)
43    (REG_W       24)
44    (REG_SP      32)
45    (TMP_REGNO   0)      ; temporary register r0
46    (ZERO_REGNO  1)      ; zero register r1
47    
48    (SREG_ADDR   0x5F)
49    (RAMPZ_ADDR  0x5B)
50    ])
51
52 (define_c_enum "unspec"
53   [UNSPEC_STRLEN
54    UNSPEC_INDEX_JMP
55    UNSPEC_FMUL
56    UNSPEC_FMULS
57    UNSPEC_FMULSU
58    UNSPEC_COPYSIGN
59    ])
60
61 (define_c_enum "unspecv"
62   [UNSPECV_PROLOGUE_SAVES
63    UNSPECV_EPILOGUE_RESTORES
64    UNSPECV_WRITE_SP_IRQ_ON
65    UNSPECV_WRITE_SP_IRQ_OFF
66    UNSPECV_GOTO_RECEIVER
67    UNSPECV_ENABLE_IRQS
68    UNSPECV_NOP
69    UNSPECV_SLEEP
70    UNSPECV_WDR
71    UNSPECV_DELAY_CYCLES
72    ])
73     
74
75 (include "predicates.md")
76 (include "constraints.md")
77   
78 ;; Condition code settings.
79 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
80   (const_string "none"))
81
82 (define_attr "type" "branch,branch1,arith,xcall"
83   (const_string "arith"))
84
85 (define_attr "mcu_have_movw" "yes,no"
86   (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
87                        (const_string "yes")
88                        (const_string "no"))))
89
90 (define_attr "mcu_mega" "yes,no"
91   (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
92                        (const_string "yes")
93                        (const_string "no"))))
94   
95
96 ;; The size of instructions in bytes.
97 ;; XXX may depend from "cc"
98
99 (define_attr "length" ""
100   (cond [(eq_attr "type" "branch")
101          (if_then_else (and (ge (minus (pc) (match_dup 0))
102                                 (const_int -63))
103                             (le (minus (pc) (match_dup 0))
104                                 (const_int 62)))
105                        (const_int 1)
106                        (if_then_else (and (ge (minus (pc) (match_dup 0))
107                                               (const_int -2045))
108                                           (le (minus (pc) (match_dup 0))
109                                               (const_int 2045)))
110                                      (const_int 2)
111                                      (const_int 3)))
112          (eq_attr "type" "branch1")
113          (if_then_else (and (ge (minus (pc) (match_dup 0))
114                                 (const_int -62))
115                             (le (minus (pc) (match_dup 0))
116                                 (const_int 61)))
117                        (const_int 2)
118                        (if_then_else (and (ge (minus (pc) (match_dup 0))
119                                               (const_int -2044))
120                                           (le (minus (pc) (match_dup 0))
121                                               (const_int 2043)))
122                                      (const_int 3)
123                                      (const_int 4)))
124          (eq_attr "type" "xcall")
125          (if_then_else (eq_attr "mcu_mega" "no")
126                        (const_int 1)
127                        (const_int 2))]
128         (const_int 2)))
129
130 ;; Define mode iterators
131 (define_mode_iterator QIHI  [(QI "") (HI "")])
132 (define_mode_iterator QIHI2 [(QI "") (HI "")])
133 (define_mode_iterator QISI [(QI "") (HI "") (SI "")])
134 (define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
135 (define_mode_iterator HIDI [(HI "") (SI "") (DI "")])
136 (define_mode_iterator HISI [(HI "") (SI "")])
137
138 ;; Define code iterators
139 ;; Define two incarnations so that we can build the cross product.
140 (define_code_iterator any_extend  [sign_extend zero_extend])
141 (define_code_iterator any_extend2 [sign_extend zero_extend])
142
143 ;; Define code attributes
144 (define_code_attr extend_prefix
145   [(sign_extend "s")
146    (zero_extend "u")])
147
148
149 ;;========================================================================
150 ;; The following is used by nonlocal_goto and setjmp.
151 ;; The receiver pattern will create no instructions since internally
152 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
153 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
154 ;; The 'null' receiver also avoids  problems with optimisation
155 ;; not recognising incoming jmp and removing code that resets frame_pointer.
156 ;; The code derived from builtins.c.
157
158 (define_expand "nonlocal_goto_receiver"
159   [(set (reg:HI REG_Y) 
160         (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
161   ""
162   {
163     emit_move_insn (virtual_stack_vars_rtx, 
164                     gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, 
165                                   gen_int_mode (STARTING_FRAME_OFFSET,
166                                                 Pmode)));
167   /* This might change the hard frame pointer in ways that aren't
168     apparent to early optimization passes, so force a clobber.  */
169     emit_clobber (hard_frame_pointer_rtx);
170     DONE;
171   })
172   
173
174 ;; Defining nonlocal_goto_receiver means we must also define this.
175 ;; even though its function is identical to that in builtins.c
176
177 (define_expand "nonlocal_goto"
178   [
179   (use (match_operand 0 "general_operand"))
180   (use (match_operand 1 "general_operand"))
181   (use (match_operand 2 "general_operand"))
182   (use (match_operand 3 "general_operand"))
183   ]
184   ""
185 {
186   rtx r_label = copy_to_reg (operands[1]);
187   rtx r_fp = operands[3];
188   rtx r_sp = operands[2];
189
190   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
191
192   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
193
194   emit_move_insn (hard_frame_pointer_rtx, r_fp);
195   emit_stack_restore (SAVE_NONLOCAL, r_sp);
196
197   emit_use (hard_frame_pointer_rtx);
198   emit_use (stack_pointer_rtx);
199
200   emit_indirect_jump (r_label);
201  
202   DONE;
203 })
204
205 (define_insn "pushqi1"
206   [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
207         (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
208   ""
209   "@
210         push %0
211         push __zero_reg__"
212   [(set_attr "length" "1,1")])
213
214 ;; All modes for a multi-byte push.  We must include complex modes here too,
215 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
216 (define_mode_iterator MPUSH
217   [(CQI "")
218    (HI "") (CHI "")
219    (SI "") (CSI "")
220    (DI "") (CDI "")
221    (SF "") (SC "")])
222
223 (define_expand "push<mode>1"
224   [(match_operand:MPUSH 0 "" "")]
225   ""
226 {
227   int i;
228   for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
229     {
230       rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
231       if (part != const0_rtx)
232         part = force_reg (QImode, part);
233       emit_insn (gen_pushqi1 (part));
234     }
235   DONE;
236 })
237
238 ;;========================================================================
239 ;; move byte
240 ;; The last alternative (any immediate constant to any register) is
241 ;; very expensive.  It should be optimized by peephole2 if a scratch
242 ;; register is available, but then that register could just as well be
243 ;; allocated for the variable we are loading.  But, most of NO_LD_REGS
244 ;; are call-saved registers, and most of LD_REGS are call-used registers,
245 ;; so this may still be a win for registers live across function calls.
246
247 (define_expand "movqi"
248   [(set (match_operand:QI 0 "nonimmediate_operand" "")
249         (match_operand:QI 1 "general_operand" ""))]
250   ""
251   "/* One of the ops has to be in a register.  */
252    if (!register_operand(operand0, QImode)
253        && ! (register_operand(operand1, QImode) || const0_rtx == operand1))
254        operands[1] = copy_to_mode_reg(QImode, operand1);
255   ")
256
257 (define_insn "*movqi"
258   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r")
259         (match_operand:QI 1 "general_operand"       "rL,i,rL,Qm,r,q,i"))]
260   "(register_operand (operands[0],QImode)
261     || register_operand (operands[1], QImode) || const0_rtx == operands[1])"
262   "* return output_movqi (insn, operands, NULL);"
263   [(set_attr "length" "1,1,5,5,1,1,4")
264    (set_attr "cc" "none,none,clobber,clobber,none,none,clobber")])
265
266 ;; This is used in peephole2 to optimize loading immediate constants
267 ;; if a scratch register from LD_REGS happens to be available.
268
269 (define_insn "*reload_inqi"
270   [(set (match_operand:QI 0 "register_operand" "=l")
271         (match_operand:QI 1 "immediate_operand" "i"))
272    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
273   "reload_completed"
274   "ldi %2,lo8(%1)
275         mov %0,%2"
276   [(set_attr "length" "2")
277    (set_attr "cc" "none")])
278
279 (define_peephole2
280   [(match_scratch:QI 2 "d")
281    (set (match_operand:QI 0 "l_register_operand" "")
282         (match_operand:QI 1 "immediate_operand" ""))]
283   "(operands[1] != const0_rtx
284     && operands[1] != const1_rtx
285     && operands[1] != constm1_rtx)"
286   [(parallel [(set (match_dup 0) (match_dup 1))
287               (clobber (match_dup 2))])]
288   "")
289
290 ;;============================================================================
291 ;; move word (16 bit)
292
293 (define_expand "movhi"
294   [(set (match_operand:HI 0 "nonimmediate_operand" "")
295         (match_operand:HI 1 "general_operand"       ""))]
296   ""
297   "
298 {
299    /* One of the ops has to be in a register.  */
300   if (!register_operand(operand0, HImode)
301       && !(register_operand(operand1, HImode) || const0_rtx == operands[1]))
302     {
303       operands[1] = copy_to_mode_reg(HImode, operand1);
304     }
305 }")
306
307 (define_insn "*movhi_sp"
308   [(set (match_operand:HI 0 "register_operand" "=q,r")
309         (match_operand:HI 1 "register_operand"  "r,q"))]
310   "((stack_register_operand(operands[0], HImode) && register_operand (operands[1], HImode))
311     || (register_operand (operands[0], HImode) && stack_register_operand(operands[1], HImode)))"
312   "* return output_movhi (insn, operands, NULL);"
313   [(set_attr "length" "5,2")
314    (set_attr "cc" "none,none")])
315
316 (define_insn "movhi_sp_r_irq_off"
317   [(set (match_operand:HI 0 "stack_register_operand" "=q")
318         (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
319                             UNSPECV_WRITE_SP_IRQ_OFF))]
320   ""
321   "out __SP_H__, %B1
322         out __SP_L__, %A1"
323   [(set_attr "length" "2")
324    (set_attr "cc" "none")])
325
326 (define_insn "movhi_sp_r_irq_on"
327   [(set (match_operand:HI 0 "stack_register_operand" "=q")
328         (unspec_volatile:HI [(match_operand:HI 1 "register_operand"  "r")] 
329                             UNSPECV_WRITE_SP_IRQ_ON))]
330   ""
331   "cli
332         out __SP_H__, %B1
333         sei
334         out __SP_L__, %A1"
335   [(set_attr "length" "4")
336    (set_attr "cc" "none")])
337
338 (define_peephole2
339   [(match_scratch:QI 2 "d")
340    (set (match_operand:HI 0 "l_register_operand" "")
341         (match_operand:HI 1 "immediate_operand" ""))]
342   "(operands[1] != const0_rtx 
343     && operands[1] != constm1_rtx)"
344   [(parallel [(set (match_dup 0) (match_dup 1))
345               (clobber (match_dup 2))])]
346   "")
347
348 ;; '*' because it is not used in rtl generation, only in above peephole
349 (define_insn "*reload_inhi"
350   [(set (match_operand:HI 0 "register_operand" "=r")
351         (match_operand:HI 1 "immediate_operand" "i"))
352    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
353   "reload_completed"
354   "* return output_reload_inhi (insn, operands, NULL);"
355   [(set_attr "length" "4")
356    (set_attr "cc" "none")])
357
358 (define_insn "*movhi"
359   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,d,*r,q,r")
360         (match_operand:HI 1 "general_operand"       "rL,m,rL,i,i,r,q"))]
361   "(register_operand (operands[0],HImode)
362     || register_operand (operands[1],HImode) || const0_rtx == operands[1])"
363   "* return output_movhi (insn, operands, NULL);"
364   [(set_attr "length" "2,6,7,2,6,5,2")
365    (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")])
366
367 (define_peephole2 ; movw
368   [(set (match_operand:QI 0 "even_register_operand" "")
369         (match_operand:QI 1 "even_register_operand" ""))
370    (set (match_operand:QI 2 "odd_register_operand" "")
371         (match_operand:QI 3 "odd_register_operand" ""))]
372   "(AVR_HAVE_MOVW
373     && REGNO (operands[0]) == REGNO (operands[2]) - 1
374     && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
375   [(set (match_dup 4) (match_dup 5))]
376   {
377     operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
378     operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
379   })
380
381 (define_peephole2 ; movw_r
382   [(set (match_operand:QI 0 "odd_register_operand" "")
383         (match_operand:QI 1 "odd_register_operand" ""))
384    (set (match_operand:QI 2 "even_register_operand" "")
385         (match_operand:QI 3 "even_register_operand" ""))]
386   "(AVR_HAVE_MOVW
387     && REGNO (operands[2]) == REGNO (operands[0]) - 1
388     && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
389   [(set (match_dup 4) (match_dup 5))]
390   {
391     operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
392     operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
393   })
394
395 ;;==========================================================================
396 ;; move double word (32 bit)
397
398 (define_expand "movsi"
399   [(set (match_operand:SI 0 "nonimmediate_operand" "")
400         (match_operand:SI 1 "general_operand"  ""))]
401   ""
402   "
403 {
404   /* One of the ops has to be in a register.  */
405   if (!register_operand (operand0, SImode)
406       && !(register_operand (operand1, SImode) || const0_rtx == operand1))
407     {
408       operands[1] = copy_to_mode_reg (SImode, operand1);
409     }
410 }")
411
412
413
414 (define_peephole2 ; *reload_insi
415   [(match_scratch:QI 2 "d")
416    (set (match_operand:SI 0 "l_register_operand" "")
417         (match_operand:SI 1 "const_int_operand" ""))
418    (match_dup 2)]
419   "(operands[1] != const0_rtx
420     && operands[1] != constm1_rtx)"
421   [(parallel [(set (match_dup 0) (match_dup 1))
422               (clobber (match_dup 2))])]
423   "")
424
425 ;; '*' because it is not used in rtl generation.
426 (define_insn "*reload_insi"
427   [(set (match_operand:SI 0 "register_operand" "=r")
428         (match_operand:SI 1 "const_int_operand" "n"))
429    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
430   "reload_completed"
431   {
432     return output_reload_insisf (insn, operands, operands[2], NULL);
433   }
434   [(set_attr "length" "8")
435    (set_attr "cc" "clobber")])
436
437
438 (define_insn "*movsi"
439   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
440         (match_operand:SI 1 "general_operand"       "r,L,Qm,rL,i,i"))]
441   "(register_operand (operands[0],SImode)
442     || register_operand (operands[1],SImode) || const0_rtx == operands[1])"
443   {
444     return output_movsisf (insn, operands, NULL_RTX, NULL);
445   }
446   [(set_attr "length" "4,4,8,9,4,10")
447    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
448
449 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
450 ;; move floating point numbers (32 bit)
451
452 (define_expand "movsf"
453   [(set (match_operand:SF 0 "nonimmediate_operand" "")
454         (match_operand:SF 1 "general_operand"  ""))]
455   ""
456   "
457 {
458   /* One of the ops has to be in a register.  */
459   if (!register_operand (operand1, SFmode)
460       && !register_operand (operand0, SFmode))
461     {
462       operands[1] = copy_to_mode_reg (SFmode, operand1);
463     }
464 }")
465
466 (define_insn "*movsf"
467   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,Qm,!d,r")
468         (match_operand:SF 1 "general_operand"       "r,G,Qm,rG,F,F"))]
469   "register_operand (operands[0], SFmode)
470    || register_operand (operands[1], SFmode)
471    || operands[1] == CONST0_RTX (SFmode)"
472   {
473     return output_movsisf (insn, operands, NULL_RTX, NULL);
474   }
475   [(set_attr "length" "4,4,8,9,4,10")
476    (set_attr "cc" "none,set_zn,clobber,clobber,clobber,clobber")])
477
478 (define_peephole2 ; *reload_insf
479   [(match_scratch:QI 2 "d")
480    (set (match_operand:SF 0 "l_register_operand" "")
481         (match_operand:SF 1 "const_double_operand" ""))
482    (match_dup 2)]
483   "operands[1] != CONST0_RTX (SFmode)"
484   [(parallel [(set (match_dup 0) 
485                    (match_dup 1))
486               (clobber (match_dup 2))])]
487   "")
488
489 ;; '*' because it is not used in rtl generation.
490 (define_insn "*reload_insf"
491   [(set (match_operand:SF 0 "register_operand" "=r")
492         (match_operand:SF 1 "const_double_operand" "F"))
493    (clobber (match_operand:QI 2 "register_operand" "=&d"))]
494   "reload_completed"
495   {
496     return output_reload_insisf (insn, operands, operands[2], NULL);
497   }
498   [(set_attr "length" "8")
499    (set_attr "cc" "clobber")])
500
501 ;;=========================================================================
502 ;; move string (like memcpy)
503 ;; implement as RTL loop
504
505 (define_expand "movmemhi"
506   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
507           (match_operand:BLK 1 "memory_operand" ""))
508           (use (match_operand:HI 2 "const_int_operand" ""))
509           (use (match_operand:HI 3 "const_int_operand" ""))])]
510   ""
511   "{
512   int prob;
513   HOST_WIDE_INT count;
514   enum machine_mode mode;
515   rtx label = gen_label_rtx ();
516   rtx loop_reg;
517   rtx jump;
518
519   /* Copy pointers into new psuedos - they will be changed.  */
520   rtx addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
521   rtx addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
522
523   /* Create rtx for tmp register - we use this as scratch.  */
524   rtx tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
525
526   if (GET_CODE (operands[2]) != CONST_INT)
527     FAIL;
528
529   count = INTVAL (operands[2]);
530   if (count <= 0)
531     FAIL;
532
533   /* Work out branch probability for latter use.  */
534   prob = REG_BR_PROB_BASE - REG_BR_PROB_BASE / count;
535
536   /* See if constant fit 8 bits.  */
537   mode = (count < 0x100) ? QImode : HImode;
538   /* Create loop counter register.  */
539   loop_reg = copy_to_mode_reg (mode, gen_int_mode (count, mode));
540
541   /* Now create RTL code for move loop.  */
542   /* Label at top of loop.  */
543   emit_label (label);
544
545   /* Move one byte into scratch and inc pointer.  */
546   emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, addr1));
547   emit_move_insn (addr1, gen_rtx_PLUS (Pmode, addr1, const1_rtx));
548
549   /* Move to mem and inc pointer.  */
550   emit_move_insn (gen_rtx_MEM (QImode, addr0), tmp_reg_rtx);
551   emit_move_insn (addr0, gen_rtx_PLUS (Pmode, addr0, const1_rtx));
552
553   /* Decrement count.  */
554   emit_move_insn (loop_reg, gen_rtx_PLUS (mode, loop_reg, constm1_rtx));
555
556   /* Compare with zero and jump if not equal. */
557   emit_cmp_and_jump_insns (loop_reg, const0_rtx, NE, NULL_RTX, mode, 1,
558                            label);
559   /* Set jump probability based on loop count.  */
560   jump = get_last_insn ();
561   add_reg_note (jump, REG_BR_PROB, GEN_INT (prob));
562   DONE;
563 }")
564
565 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
566 ;; memset (%0, %2, %1)
567
568 (define_expand "setmemhi"
569   [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
570                    (match_operand 2 "const_int_operand" ""))
571               (use (match_operand:HI 1 "const_int_operand" ""))
572               (use (match_operand:HI 3 "const_int_operand" "n"))
573               (clobber (match_scratch:HI 4 ""))
574               (clobber (match_dup 5))])]
575   ""
576   "{
577   rtx addr0;
578   int cnt8;
579   enum machine_mode mode;
580
581   /* If value to set is not zero, use the library routine.  */
582   if (operands[2] != const0_rtx)
583     FAIL;
584
585   if (GET_CODE (operands[1]) != CONST_INT)
586     FAIL;
587
588   cnt8 = byte_immediate_operand (operands[1], GET_MODE (operands[1]));
589   mode = cnt8 ? QImode : HImode;
590   operands[5] = gen_rtx_SCRATCH (mode);
591   operands[1] = copy_to_mode_reg (mode,
592                                   gen_int_mode (INTVAL (operands[1]), mode));
593   addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
594   operands[0] = gen_rtx_MEM (BLKmode, addr0);
595 }")
596
597 (define_insn "*clrmemqi"
598   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
599         (const_int 0))
600    (use (match_operand:QI 1 "register_operand" "r"))
601    (use (match_operand:QI 2 "const_int_operand" "n"))
602    (clobber (match_scratch:HI 3 "=0"))
603    (clobber (match_scratch:QI 4 "=&1"))]
604   ""
605   "st %a0+,__zero_reg__
606         dec %1
607         brne .-6"
608   [(set_attr "length" "3")
609    (set_attr "cc" "clobber")])
610
611 (define_insn "*clrmemhi"
612   [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
613         (const_int 0))
614    (use (match_operand:HI 1 "register_operand" "!w,d"))
615    (use (match_operand:HI 2 "const_int_operand" "n,n"))
616    (clobber (match_scratch:HI 3 "=0,0"))
617    (clobber (match_scratch:HI 4 "=&1,&1"))]
618   ""
619   "*{
620      if (which_alternative==0)
621        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
622                AS2 (sbiw,%A1,1) CR_TAB
623                AS1 (brne,.-6));
624      else
625        return (AS2 (st,%a0+,__zero_reg__) CR_TAB
626                AS2 (subi,%A1,1) CR_TAB
627                AS2 (sbci,%B1,0) CR_TAB
628                AS1 (brne,.-8));
629 }"
630   [(set_attr "length" "3,4")
631    (set_attr "cc" "clobber,clobber")])
632
633 (define_expand "strlenhi"
634     [(set (match_dup 4)
635           (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
636                       (match_operand:QI 2 "const_int_operand" "")
637                       (match_operand:HI 3 "immediate_operand" "")]
638                      UNSPEC_STRLEN))
639      (set (match_dup 4) (plus:HI (match_dup 4)
640                                  (const_int -1)))
641      (set (match_operand:HI 0 "register_operand" "")
642           (minus:HI (match_dup 4)
643                     (match_dup 5)))]
644    ""
645    "{
646   rtx addr;
647   if (! (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
648     FAIL;
649   addr = copy_to_mode_reg (Pmode, XEXP (operands[1],0));
650   operands[1] = gen_rtx_MEM (BLKmode, addr); 
651   operands[5] = addr;
652   operands[4] = gen_reg_rtx (HImode);
653 }")
654
655 (define_insn "*strlenhi"
656   [(set (match_operand:HI 0 "register_operand" "=e")
657         (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
658                     (const_int 0)
659                     (match_operand:HI 2 "immediate_operand" "i")]
660                    UNSPEC_STRLEN))]
661   ""
662   "ld __tmp_reg__,%a0+
663         tst __tmp_reg__
664         brne .-6"
665   [(set_attr "length" "3")
666    (set_attr "cc" "clobber")])
667
668 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
669 ; add bytes
670
671 (define_insn "addqi3"
672   [(set (match_operand:QI 0 "register_operand" "=r,d,r,r")
673         (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0")
674                  (match_operand:QI 2 "nonmemory_operand" "r,i,P,N")))]
675   ""
676   "@
677         add %0,%2
678         subi %0,lo8(-(%2))
679         inc %0
680         dec %0"
681   [(set_attr "length" "1,1,1,1")
682    (set_attr "cc" "set_czn,set_czn,set_zn,set_zn")])
683
684
685 (define_expand "addhi3"
686   [(set (match_operand:HI 0 "register_operand" "")
687         (plus:HI (match_operand:HI 1 "register_operand" "")
688                  (match_operand:HI 2 "nonmemory_operand" "")))]
689   ""
690   "
691 {
692   if (GET_CODE (operands[2]) == CONST_INT)
693     {
694       short tmp = INTVAL (operands[2]);
695       operands[2] = GEN_INT(tmp);
696     }
697 }")
698
699
700 (define_insn "*addhi3_zero_extend"
701   [(set (match_operand:HI 0 "register_operand" "=r")
702         (plus:HI (zero_extend:HI
703                   (match_operand:QI 1 "register_operand" "r"))
704                  (match_operand:HI 2 "register_operand" "0")))]
705   ""
706   "add %A0,%1
707         adc %B0,__zero_reg__"
708   [(set_attr "length" "2")
709    (set_attr "cc" "set_n")])
710
711 (define_insn "*addhi3_zero_extend1"
712   [(set (match_operand:HI 0 "register_operand" "=r")
713         (plus:HI (match_operand:HI 1 "register_operand" "%0")
714                  (zero_extend:HI
715                   (match_operand:QI 2 "register_operand" "r"))))]
716   ""
717   "add %A0,%2
718         adc %B0,__zero_reg__"
719   [(set_attr "length" "2")
720    (set_attr "cc" "set_n")])
721
722 (define_insn "*addhi3_sp_R_pc2"
723   [(set (match_operand:HI 1 "stack_register_operand" "=q")
724         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
725                  (match_operand:HI 0 "avr_sp_immediate_operand" "R")))]
726   "AVR_2_BYTE_PC"
727   "*{
728       if (CONST_INT_P (operands[0]))
729         {
730           switch(INTVAL (operands[0]))
731             {
732             case -6: 
733               return \"rcall .\" CR_TAB 
734                      \"rcall .\" CR_TAB 
735                      \"rcall .\";
736             case -5: 
737               return \"rcall .\" CR_TAB 
738                      \"rcall .\" CR_TAB 
739                      \"push __tmp_reg__\";
740             case -4: 
741               return \"rcall .\" CR_TAB 
742                      \"rcall .\";
743             case -3: 
744               return \"rcall .\" CR_TAB 
745                      \"push __tmp_reg__\";
746             case -2: 
747               return \"rcall .\";
748             case -1: 
749               return \"push __tmp_reg__\";
750             case 0: 
751               return \"\";
752             case 1: 
753               return \"pop __tmp_reg__\";
754             case 2: 
755               return \"pop __tmp_reg__\" CR_TAB 
756                      \"pop __tmp_reg__\";
757             case 3: 
758               return \"pop __tmp_reg__\" CR_TAB 
759                      \"pop __tmp_reg__\" CR_TAB 
760                      \"pop __tmp_reg__\";
761             case 4: 
762               return \"pop __tmp_reg__\" CR_TAB 
763                      \"pop __tmp_reg__\" CR_TAB 
764                      \"pop __tmp_reg__\" CR_TAB 
765                      \"pop __tmp_reg__\";
766             case 5: 
767               return \"pop __tmp_reg__\" CR_TAB 
768                      \"pop __tmp_reg__\" CR_TAB 
769                      \"pop __tmp_reg__\" CR_TAB 
770                      \"pop __tmp_reg__\" CR_TAB 
771                      \"pop __tmp_reg__\";
772             }
773         }
774       return \"bug\";
775     }"
776   [(set (attr "length") 
777         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
778                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
779                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
780                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
781                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
782                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
783                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
784                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
785                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
786                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
787                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
788                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
789                (const_int 0)))])
790
791 (define_insn "*addhi3_sp_R_pc3"
792   [(set (match_operand:HI 1 "stack_register_operand" "=q")
793         (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
794                  (match_operand:QI 0 "avr_sp_immediate_operand" "R")))]
795   "AVR_3_BYTE_PC"
796   "*{
797       if (CONST_INT_P (operands[0]))
798         {
799           switch(INTVAL (operands[0]))
800             {
801             case -6: 
802               return \"rcall .\" CR_TAB 
803                      \"rcall .\";
804             case -5: 
805               return \"rcall .\" CR_TAB 
806                      \"push __tmp_reg__\" CR_TAB 
807                      \"push __tmp_reg__\";
808             case -4: 
809               return \"rcall .\" CR_TAB 
810                      \"push __tmp_reg__\";
811             case -3: 
812               return \"rcall .\";
813             case -2: 
814               return \"push __tmp_reg__\" CR_TAB 
815                      \"push __tmp_reg__\";
816             case -1: 
817               return \"push __tmp_reg__\";
818             case 0: 
819               return \"\";
820             case 1: 
821               return \"pop __tmp_reg__\";
822             case 2: 
823               return \"pop __tmp_reg__\" CR_TAB 
824                      \"pop __tmp_reg__\";
825             case 3: 
826               return \"pop __tmp_reg__\" CR_TAB 
827                      \"pop __tmp_reg__\" CR_TAB 
828                      \"pop __tmp_reg__\";
829             case 4: 
830               return \"pop __tmp_reg__\" CR_TAB 
831                      \"pop __tmp_reg__\" CR_TAB 
832                      \"pop __tmp_reg__\" CR_TAB 
833                      \"pop __tmp_reg__\";
834             case 5: 
835               return \"pop __tmp_reg__\" CR_TAB 
836                      \"pop __tmp_reg__\" CR_TAB 
837                      \"pop __tmp_reg__\" CR_TAB 
838                      \"pop __tmp_reg__\" CR_TAB 
839                      \"pop __tmp_reg__\";
840             }
841         }
842       return \"bug\";
843     }"
844   [(set (attr "length") 
845         (cond [(eq (const_int -6) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
846                (eq (const_int -5) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
847                (eq (const_int -4) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
848                (eq (const_int -3) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
849                (eq (const_int -2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
850                (eq (const_int -1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
851                (eq (const_int  0) (symbol_ref "INTVAL (operands[0])")) (const_int 0)
852                (eq (const_int  1) (symbol_ref "INTVAL (operands[0])")) (const_int 1)
853                (eq (const_int  2) (symbol_ref "INTVAL (operands[0])")) (const_int 2)
854                (eq (const_int  3) (symbol_ref "INTVAL (operands[0])")) (const_int 3)
855                (eq (const_int  4) (symbol_ref "INTVAL (operands[0])")) (const_int 4)
856                (eq (const_int  5) (symbol_ref "INTVAL (operands[0])")) (const_int 5)]
857                (const_int 0)))])
858
859 (define_insn "*addhi3"
860   [(set (match_operand:HI 0 "register_operand" "=r,!w,!w,d,r,r")
861         (plus:HI
862          (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0")
863          (match_operand:HI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
864   ""
865   "@
866         add %A0,%A2\;adc %B0,%B2
867         adiw %A0,%2
868         sbiw %A0,%n2
869         subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))
870         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__
871         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__"
872   [(set_attr "length" "2,1,1,2,3,3")
873    (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")])
874
875 (define_insn "addsi3"
876   [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,r,r")
877           (plus:SI
878            (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
879            (match_operand:SI 2 "nonmemory_operand" "r,I,J,i,P,N")))]
880   ""
881   "@
882         add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2
883         adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
884         sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__
885         subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))
886         sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
887         sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
888   [(set_attr "length" "4,3,3,4,5,5")
889    (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n")])
890
891 (define_insn "*addsi3_zero_extend"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (plus:SI (zero_extend:SI
894                   (match_operand:QI 1 "register_operand" "r"))
895                  (match_operand:SI 2 "register_operand" "0")))]
896   ""
897   "add %A0,%1
898         adc %B0,__zero_reg__
899         adc %C0,__zero_reg__
900         adc %D0,__zero_reg__"
901   [(set_attr "length" "4")
902    (set_attr "cc" "set_n")])
903
904 ;-----------------------------------------------------------------------------
905 ; sub bytes
906 (define_insn "subqi3"
907   [(set (match_operand:QI 0 "register_operand" "=r,d")
908         (minus:QI (match_operand:QI 1 "register_operand" "0,0")
909                   (match_operand:QI 2 "nonmemory_operand" "r,i")))]
910   ""
911   "@
912         sub %0,%2
913         subi %0,lo8(%2)"
914   [(set_attr "length" "1,1")
915    (set_attr "cc" "set_czn,set_czn")])
916
917 (define_insn "subhi3"
918   [(set (match_operand:HI 0 "register_operand" "=r,d")
919         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
920                   (match_operand:HI 2 "nonmemory_operand" "r,i")))]
921   ""
922   "@
923         sub %A0,%A2\;sbc %B0,%B2
924         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
925   [(set_attr "length" "2,2")
926    (set_attr "cc" "set_czn,set_czn")])
927
928 (define_insn "*subhi3_zero_extend1"
929   [(set (match_operand:HI 0 "register_operand" "=r")
930         (minus:HI (match_operand:HI 1 "register_operand" "0")
931                   (zero_extend:HI
932                    (match_operand:QI 2 "register_operand" "r"))))]
933   ""
934   "sub %A0,%2
935         sbc %B0,__zero_reg__"
936   [(set_attr "length" "2")
937    (set_attr "cc" "set_n")])
938
939 (define_insn "subsi3"
940   [(set (match_operand:SI 0 "register_operand" "=r,d")
941         (minus:SI (match_operand:SI 1 "register_operand" "0,0")
942                  (match_operand:SI 2 "nonmemory_operand" "r,i")))]
943   ""
944   "@
945         sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2
946         subi %A0,lo8(%2)\;sbci %B0,hi8(%2)\;sbci %C0,hlo8(%2)\;sbci %D0,hhi8(%2)"
947   [(set_attr "length" "4,4")
948    (set_attr "cc" "set_czn,set_czn")])
949
950 (define_insn "*subsi3_zero_extend"
951   [(set (match_operand:SI 0 "register_operand" "=r")
952         (minus:SI (match_operand:SI 1 "register_operand" "0")
953                   (zero_extend:SI
954                    (match_operand:QI 2 "register_operand" "r"))))]
955   ""
956   "sub %A0,%2
957         sbc %B0,__zero_reg__
958         sbc %C0,__zero_reg__
959         sbc %D0,__zero_reg__"
960   [(set_attr "length" "4")
961    (set_attr "cc" "set_n")])
962
963 ;******************************************************************************
964 ; mul
965
966 (define_expand "mulqi3"
967   [(set (match_operand:QI 0 "register_operand" "")
968         (mult:QI (match_operand:QI 1 "register_operand" "")
969                  (match_operand:QI 2 "register_operand" "")))]
970   ""
971   "{
972   if (!AVR_HAVE_MUL)
973     {
974       emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
975       DONE;
976     }
977 }")
978
979 (define_insn "*mulqi3_enh"
980   [(set (match_operand:QI 0 "register_operand" "=r")
981         (mult:QI (match_operand:QI 1 "register_operand" "r")
982                  (match_operand:QI 2 "register_operand" "r")))]
983   "AVR_HAVE_MUL"
984   "mul %1,%2
985         mov %0,r0
986         clr r1"
987   [(set_attr "length" "3")
988    (set_attr "cc" "clobber")])
989
990 (define_expand "mulqi3_call"
991   [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
992    (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
993    (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
994               (clobber (reg:QI 22))])
995    (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
996   ""
997   "")
998
999 (define_insn "*mulqi3_call"
1000   [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1001    (clobber (reg:QI 22))]
1002   "!AVR_HAVE_MUL"
1003   "%~call __mulqi3"
1004   [(set_attr "type" "xcall")
1005    (set_attr "cc" "clobber")])
1006
1007 (define_insn "mulqihi3"
1008   [(set (match_operand:HI 0 "register_operand" "=r")
1009         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1010                  (sign_extend:HI (match_operand:QI 2 "register_operand" "d"))))]
1011   "AVR_HAVE_MUL"
1012   "muls %1,%2
1013         movw %0,r0
1014         clr r1"
1015   [(set_attr "length" "3")
1016    (set_attr "cc" "clobber")])
1017
1018 (define_insn "umulqihi3"
1019   [(set (match_operand:HI 0 "register_operand" "=r")
1020         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1021                  (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1022   "AVR_HAVE_MUL"
1023   "mul %1,%2
1024         movw %0,r0
1025         clr r1"
1026   [(set_attr "length" "3")
1027    (set_attr "cc" "clobber")])
1028
1029 (define_insn "usmulqihi3"
1030   [(set (match_operand:HI 0 "register_operand"                         "=r")
1031         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1032                  (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1033   "AVR_HAVE_MUL"
1034   "mulsu %2,%1
1035         movw %0,r0
1036         clr __zero_reg__"
1037   [(set_attr "length" "3")
1038    (set_attr "cc" "clobber")])
1039
1040 ;; Above insn is not canonicalized by insn combine, so here is a version with
1041 ;; operands swapped.
1042
1043 (define_insn "*sumulqihi3"
1044   [(set (match_operand:HI 0 "register_operand"                         "=r")
1045         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1046                  (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1047   "AVR_HAVE_MUL"
1048   "mulsu %1,%2
1049         movw %0,r0
1050         clr __zero_reg__"
1051   [(set_attr "length" "3")
1052    (set_attr "cc" "clobber")])
1053
1054 ;; One-extend operand 1
1055
1056 (define_insn "*osmulqihi3"
1057   [(set (match_operand:HI 0 "register_operand"                                        "=&r")
1058         (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1059                  (sign_extend:HI (match_operand:QI 2 "register_operand"                 "a"))))]
1060   "AVR_HAVE_MUL"
1061   "mulsu %2,%1
1062         movw %0,r0
1063         sub %B0,%2
1064         clr __zero_reg__"
1065   [(set_attr "length" "4")
1066    (set_attr "cc" "clobber")])
1067
1068 (define_insn "*oumulqihi3"
1069   [(set (match_operand:HI 0 "register_operand"                                        "=&r")
1070         (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1071                  (zero_extend:HI (match_operand:QI 2 "register_operand"                 "r"))))]
1072   "AVR_HAVE_MUL"
1073   "mul %2,%1
1074         movw %0,r0
1075         sub %B0,%2
1076         clr __zero_reg__"
1077   [(set_attr "length" "4")
1078    (set_attr "cc" "clobber")])
1079
1080
1081 ;******************************************************************************
1082 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1083 ;******************************************************************************
1084
1085 (define_insn_and_split "*muluqihi3.uconst"
1086   [(set (match_operand:HI 0 "register_operand"                         "=r")
1087         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1088                  (match_operand:HI 2 "u8_operand"                       "M")))
1089    (clobber (match_scratch:QI 3                                       "=&d"))]
1090   "AVR_HAVE_MUL"
1091   "#"
1092   "&& reload_completed"
1093   [(set (match_dup 3)
1094         (match_dup 2))
1095    ; umulqihi3
1096    (set (match_dup 0)
1097         (mult:HI (zero_extend:HI (match_dup 1))
1098                  (zero_extend:HI (match_dup 3))))]
1099   {
1100     operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1101   })
1102
1103 (define_insn_and_split "*muluqihi3.sconst"
1104   [(set (match_operand:HI 0 "register_operand"                         "=r")
1105         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1106                  (match_operand:HI 2 "s8_operand"                       "n")))
1107    (clobber (match_scratch:QI 3                                       "=&a"))]
1108   "AVR_HAVE_MUL"
1109   "#"
1110   "&& reload_completed"
1111   [(set (match_dup 3)
1112         (match_dup 2))
1113    ; usmulqihi3
1114    (set (match_dup 0)
1115         (mult:HI (zero_extend:HI (match_dup 1))
1116                  (sign_extend:HI (match_dup 3))))]
1117   {
1118     operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1119   })
1120
1121 (define_insn_and_split "*mulsqihi3.sconst"
1122   [(set (match_operand:HI 0 "register_operand"                         "=r")
1123         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1124                  (match_operand:HI 2 "s8_operand"                       "n")))
1125    (clobber (match_scratch:QI 3                                       "=&d"))]
1126   "AVR_HAVE_MUL"
1127   "#"
1128   "&& reload_completed"
1129   [(set (match_dup 3)
1130         (match_dup 2))
1131    ; mulqihi3
1132    (set (match_dup 0)
1133         (mult:HI (sign_extend:HI (match_dup 1))
1134                  (sign_extend:HI (match_dup 3))))]
1135   {
1136     operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1137   })
1138
1139 (define_insn_and_split "*mulsqihi3.uconst"
1140   [(set (match_operand:HI 0 "register_operand"                         "=r")
1141         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1142                  (match_operand:HI 2 "u8_operand"                       "M")))
1143    (clobber (match_scratch:QI 3                                       "=&a"))]
1144   "AVR_HAVE_MUL"
1145   "#"
1146   "&& reload_completed"
1147   [(set (match_dup 3)
1148         (match_dup 2))
1149    ; usmulqihi3
1150    (set (match_dup 0)
1151         (mult:HI (zero_extend:HI (match_dup 3))
1152                  (sign_extend:HI (match_dup 1))))]
1153   {
1154     operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1155   })
1156
1157 (define_insn_and_split "*mulsqihi3.oconst"
1158   [(set (match_operand:HI 0 "register_operand"                        "=&r")
1159         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1160                  (match_operand:HI 2 "o8_operand"                       "n")))
1161    (clobber (match_scratch:QI 3                                       "=&a"))]
1162   "AVR_HAVE_MUL"
1163   "#"
1164   "&& reload_completed"
1165   [(set (match_dup 3)
1166         (match_dup 2))
1167    ; *osmulqihi3
1168    (set (match_dup 0)
1169         (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1170                  (sign_extend:HI (match_dup 1))))]
1171   {
1172     operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1173   })
1174
1175 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1176 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1177 ;; at that time.  Fix that.
1178
1179 (define_insn_and_split "*ashifthi3.signx.const"
1180   [(set (match_operand:HI 0 "register_operand"                           "=r")
1181         (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1182                    (match_operand:HI 2 "const_2_to_6_operand"             "I")))
1183    (clobber (match_scratch:QI 3                                         "=&d"))]
1184   "AVR_HAVE_MUL"
1185   "#"
1186   "&& reload_completed"
1187   [(set (match_dup 3)
1188         (match_dup 2))
1189    ; mulqihi3
1190    (set (match_dup 0)
1191         (mult:HI (sign_extend:HI (match_dup 1))
1192                  (sign_extend:HI (match_dup 3))))]
1193   {
1194     operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1195   })
1196
1197 (define_insn_and_split "*ashifthi3.signx.const7"
1198   [(set (match_operand:HI 0 "register_operand"                           "=r")
1199         (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1200                    (const_int 7)))
1201    (clobber (match_scratch:QI 2                                         "=&a"))]
1202   "AVR_HAVE_MUL"
1203   "#"
1204   "&& reload_completed"
1205   [(set (match_dup 2)
1206         (match_dup 3))
1207    ; usmulqihi3
1208    (set (match_dup 0)
1209         (mult:HI (zero_extend:HI (match_dup 2))
1210                  (sign_extend:HI (match_dup 1))))]
1211   {
1212     operands[3] = gen_int_mode (1 << 7, QImode);
1213   })
1214
1215 (define_insn_and_split "*ashifthi3.zerox.const"
1216   [(set (match_operand:HI 0 "register_operand"                           "=r")
1217         (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1218                    (match_operand:HI 2 "const_2_to_7_operand"             "I")))
1219    (clobber (match_scratch:QI 3                                         "=&d"))]
1220   "AVR_HAVE_MUL"
1221   "#"
1222   "&& reload_completed"
1223   [(set (match_dup 3)
1224         (match_dup 2))
1225    ; umulqihi3
1226    (set (match_dup 0)
1227         (mult:HI (zero_extend:HI (match_dup 1))
1228                  (zero_extend:HI (match_dup 3))))]
1229   {
1230     operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1231   })
1232
1233 ;******************************************************************************
1234 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1235 ;******************************************************************************
1236
1237 (define_insn "mulsqihi3"
1238   [(set (match_operand:HI 0 "register_operand"                        "=&r")
1239         (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1240                  (match_operand:HI 2 "register_operand"                 "a")))]
1241   "AVR_HAVE_MUL"
1242   "mulsu %1,%A2
1243         movw %0,r0
1244         mul %1,%B2
1245         add %B0,r0
1246         clr __zero_reg__"
1247   [(set_attr "length" "5")
1248    (set_attr "cc" "clobber")])
1249
1250 (define_insn "muluqihi3"
1251   [(set (match_operand:HI 0 "register_operand"                        "=&r")
1252         (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1253                  (match_operand:HI 2 "register_operand"                 "r")))]
1254   "AVR_HAVE_MUL"
1255   "mul %1,%A2
1256         movw %0,r0
1257         mul %1,%B2
1258         add %B0,r0
1259         clr __zero_reg__"
1260   [(set_attr "length" "5")
1261    (set_attr "cc" "clobber")])
1262
1263 ;; one-extend operand 1
1264
1265 (define_insn "muloqihi3"
1266   [(set (match_operand:HI 0 "register_operand"                                        "=&r")
1267         (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1268                  (match_operand:HI 2 "register_operand"                                 "r")))]
1269   "AVR_HAVE_MUL"
1270   "mul %1,%A2
1271         movw %0,r0
1272         mul %1,%B2
1273         add %B0,r0
1274         sub %B0,%A2
1275         clr __zero_reg__"
1276   [(set_attr "length" "6")
1277    (set_attr "cc" "clobber")])
1278
1279 ;******************************************************************************
1280
1281 (define_expand "mulhi3"
1282   [(set (match_operand:HI 0 "register_operand" "")
1283         (mult:HI (match_operand:HI 1 "register_operand" "")
1284                  (match_operand:HI 2 "register_or_s9_operand" "")))]
1285   ""
1286   {
1287     if (!AVR_HAVE_MUL)
1288       {
1289         if (!register_operand (operands[2], HImode))
1290           operands[2] = force_reg (HImode, operands[2]);
1291
1292         emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
1293         DONE;
1294       }
1295
1296     /* For small constants we can do better by extending them on the fly.
1297        The constant can be loaded in one instruction and the widening
1298        multiplication is shorter.  First try the unsigned variant because it
1299        allows constraint "d" instead of "a" for the signed version.  */
1300
1301     if (s9_operand (operands[2], HImode))
1302       {
1303         rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
1304
1305         if (u8_operand (operands[2], HImode))
1306           {
1307             emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
1308           } 
1309         else if (s8_operand (operands[2], HImode))
1310           {
1311             emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
1312           }
1313         else
1314           {
1315             emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
1316           }
1317
1318         DONE;
1319       }
1320
1321     if (!register_operand (operands[2], HImode))
1322       operands[2] = force_reg (HImode, operands[2]);
1323   })
1324
1325 (define_insn "*mulhi3_enh"
1326   [(set (match_operand:HI 0 "register_operand" "=&r")
1327         (mult:HI (match_operand:HI 1 "register_operand" "r")
1328                  (match_operand:HI 2 "register_operand" "r")))]
1329   "AVR_HAVE_MUL"
1330   "mul %A1,%A2
1331         movw %0,r0
1332         mul %A1,%B2
1333         add %B0,r0
1334         mul %B1,%A2
1335         add %B0,r0
1336         clr r1"
1337   [(set_attr "length" "7")
1338    (set_attr "cc" "clobber")])
1339
1340 (define_expand "mulhi3_call"
1341   [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
1342    (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
1343    (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1344               (clobber (reg:HI 22))
1345               (clobber (reg:QI 21))])
1346    (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
1347   ""
1348   "")
1349
1350 (define_insn "*mulhi3_call"
1351   [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
1352    (clobber (reg:HI 22))
1353    (clobber (reg:QI 21))]
1354   "!AVR_HAVE_MUL"
1355   "%~call __mulhi3"
1356   [(set_attr "type" "xcall")
1357    (set_attr "cc" "clobber")])
1358
1359 ;; Operand 2 (reg:SI 18) not clobbered on the enhanced core.
1360 ;; All call-used registers clobbered otherwise - normal library call.
1361 ;;    To support widening multiplicatioon with constant we postpone
1362 ;; expanding to the implicit library call until post combine and
1363 ;; prior to register allocation.  Clobber all hard registers that
1364 ;; might be used by the (widening) multiply until it is split and
1365 ;; it's final register footprint is worked out.
1366
1367 (define_expand "mulsi3"
1368   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1369                    (mult:SI (match_operand:SI 1 "register_operand" "")
1370                             (match_operand:SI 2 "nonmemory_operand" "")))
1371               (clobber (reg:HI 26))
1372               (clobber (reg:DI 18))])]
1373   "AVR_HAVE_MUL"
1374   {
1375     if (u16_operand (operands[2], SImode))
1376       {
1377         operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1378         emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1379         DONE;
1380       }
1381
1382     if (o16_operand (operands[2], SImode))
1383       {
1384         operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1385         emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1386         DONE;
1387       }
1388   })
1389
1390 (define_insn_and_split "*mulsi3"
1391   [(set (match_operand:SI 0 "pseudo_register_operand"                      "=r")
1392         (mult:SI (match_operand:SI 1 "pseudo_register_operand"              "r")
1393                  (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
1394    (clobber (reg:HI 26))
1395    (clobber (reg:DI 18))]
1396   "AVR_HAVE_MUL && !reload_completed"
1397   { gcc_unreachable(); }
1398   "&& 1"
1399   [(set (reg:SI 18)
1400         (match_dup 1))
1401    (set (reg:SI 22) 
1402         (match_dup 2))
1403    (parallel [(set (reg:SI 22)
1404                    (mult:SI (reg:SI 22)
1405                             (reg:SI 18)))
1406               (clobber (reg:HI 26))])
1407    (set (match_dup 0)
1408         (reg:SI 22))]
1409   {
1410     if (u16_operand (operands[2], SImode))
1411       {
1412         operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1413         emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
1414         DONE;
1415       }
1416
1417     if (o16_operand (operands[2], SImode))
1418       {
1419         operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1420         emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
1421         DONE;
1422       }
1423   })
1424
1425 ;; "muluqisi3"
1426 ;; "muluhisi3"
1427 (define_insn_and_split "mulu<mode>si3"
1428   [(set (match_operand:SI 0 "pseudo_register_operand"                           "=r")
1429         (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1430                  (match_operand:SI 2 "pseudo_register_or_const_int_operand"      "rn")))
1431    (clobber (reg:HI 26))
1432    (clobber (reg:DI 18))]
1433   "AVR_HAVE_MUL && !reload_completed"
1434   { gcc_unreachable(); }
1435   "&& 1"
1436   [(set (reg:HI 26)
1437         (match_dup 1))
1438    (set (reg:SI 18)
1439         (match_dup 2))
1440    (set (reg:SI 22)
1441         (mult:SI (zero_extend:SI (reg:HI 26))
1442                  (reg:SI 18)))
1443    (set (match_dup 0)
1444         (reg:SI 22))]
1445   {
1446     /* Do the QI -> HI extension explicitely before the multiplication.  */
1447     /* Do the HI -> SI extension implicitely and after the multiplication.  */
1448        
1449     if (QImode == <MODE>mode)
1450       operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
1451
1452     if (u16_operand (operands[2], SImode))
1453       {
1454         operands[1] = force_reg (HImode, operands[1]);
1455         operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1456         emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
1457         DONE;
1458       }
1459   })
1460
1461 ;; "mulsqisi3"
1462 ;; "mulshisi3"
1463 (define_insn_and_split "muls<mode>si3"
1464   [(set (match_operand:SI 0 "pseudo_register_operand"                           "=r")
1465         (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
1466                  (match_operand:SI 2 "pseudo_register_or_const_int_operand"      "rn")))
1467    (clobber (reg:HI 26))
1468    (clobber (reg:DI 18))]
1469   "AVR_HAVE_MUL && !reload_completed"
1470   { gcc_unreachable(); }
1471   "&& 1"
1472   [(set (reg:HI 26)
1473         (match_dup 1))
1474    (set (reg:SI 18)
1475         (match_dup 2))
1476    (set (reg:SI 22)
1477         (mult:SI (sign_extend:SI (reg:HI 26))
1478                  (reg:SI 18)))
1479    (set (match_dup 0)
1480         (reg:SI 22))]
1481   {
1482     /* Do the QI -> HI extension explicitely before the multiplication.  */
1483     /* Do the HI -> SI extension implicitely and after the multiplication.  */
1484        
1485     if (QImode == <MODE>mode)
1486       operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
1487
1488     if (u16_operand (operands[2], SImode)
1489         || s16_operand (operands[2], SImode))
1490       {
1491         rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
1492
1493         operands[1] = force_reg (HImode, operands[1]);
1494
1495         if (u16_operand (operands[2], SImode))
1496           emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
1497         else
1498           emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
1499
1500         DONE;
1501       }
1502   })
1503
1504 ;; One-extend operand 1
1505
1506 (define_insn_and_split "mulohisi3"
1507   [(set (match_operand:SI 0 "pseudo_register_operand"                          "=r")
1508         (mult:SI (not:SI (zero_extend:SI 
1509                           (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
1510                  (match_operand:SI 2 "pseudo_register_or_const_int_operand"     "rn")))
1511    (clobber (reg:HI 26))
1512    (clobber (reg:DI 18))]
1513   "AVR_HAVE_MUL && !reload_completed"
1514   { gcc_unreachable(); }
1515   "&& 1"
1516   [(set (reg:HI 26)
1517         (match_dup 1))
1518    (set (reg:SI 18)
1519         (match_dup 2))
1520    (set (reg:SI 22)
1521         (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1522                  (reg:SI 18)))
1523    (set (match_dup 0)
1524         (reg:SI 22))]
1525   "")
1526
1527 (define_expand "mulhisi3"
1528   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1529                    (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
1530                             (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1531               (clobber (reg:HI 26))
1532               (clobber (reg:DI 18))])]
1533   "AVR_HAVE_MUL"
1534   "")
1535
1536 (define_expand "umulhisi3"
1537   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1538                    (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1539                             (zero_extend:SI (match_operand:HI 2 "register_operand" ""))))
1540               (clobber (reg:HI 26))
1541               (clobber (reg:DI 18))])]
1542   "AVR_HAVE_MUL"
1543   "")
1544
1545 (define_expand "usmulhisi3"
1546   [(parallel [(set (match_operand:SI 0 "register_operand" "")
1547                    (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
1548                             (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
1549               (clobber (reg:HI 26))
1550               (clobber (reg:DI 18))])]
1551   "AVR_HAVE_MUL"
1552   "")
1553
1554 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
1555 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
1556 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
1557 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
1558 (define_insn_and_split
1559   "*<any_extend:extend_prefix><any_extend2:extend_prefix>mul<QIHI:mode><QIHI2:mode>si3"
1560   [(set (match_operand:SI 0 "pseudo_register_operand"                            "=r")
1561         (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand"   "r"))
1562                  (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
1563    (clobber (reg:HI 26))
1564    (clobber (reg:DI 18))]
1565   "AVR_HAVE_MUL && !reload_completed"
1566   { gcc_unreachable(); }
1567   "&& 1"
1568   [(set (reg:HI 18)
1569         (match_dup 1))
1570    (set (reg:HI 26)
1571         (match_dup 2))
1572    (set (reg:SI 22)
1573         (mult:SI (match_dup 3)
1574                  (match_dup 4)))
1575    (set (match_dup 0)
1576         (reg:SI 22))]
1577   {
1578     rtx xop1 = operands[1];
1579     rtx xop2 = operands[2];
1580
1581     /* Do the QI -> HI extension explicitely before the multiplication.  */
1582     /* Do the HI -> SI extension implicitely and after the multiplication.  */
1583        
1584     if (QImode == <QIHI:MODE>mode)
1585       xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
1586
1587     if (QImode == <QIHI2:MODE>mode)
1588       xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
1589
1590     if (<any_extend:CODE> == <any_extend2:CODE>
1591         || <any_extend:CODE> == ZERO_EXTEND)
1592       {
1593         operands[1] = xop1;
1594         operands[2] = xop2;
1595         operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
1596         operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
1597       }
1598     else
1599       {
1600         /* <any_extend:CODE>  = SIGN_EXTEND */
1601         /* <any_extend2:CODE> = ZERO_EXTEND */
1602
1603         operands[1] = xop2;
1604         operands[2] = xop1;
1605         operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
1606         operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
1607       }
1608   })
1609
1610 (define_insn "*mulsi3_call"
1611   [(set (reg:SI 22)
1612         (mult:SI (reg:SI 22)
1613                  (reg:SI 18)))
1614    (clobber (reg:HI 26))]
1615   "AVR_HAVE_MUL"
1616   "%~call __mulsi3"
1617   [(set_attr "type" "xcall")
1618    (set_attr "cc" "clobber")])
1619
1620 (define_insn "*mulhisi3_call"
1621   [(set (reg:SI 22)
1622         (mult:SI (sign_extend:SI (reg:HI 18))
1623                  (sign_extend:SI (reg:HI 26))))]
1624   "AVR_HAVE_MUL"
1625   "%~call __mulhisi3"
1626   [(set_attr "type" "xcall")
1627    (set_attr "cc" "clobber")])
1628
1629 (define_insn "*umulhisi3_call"
1630   [(set (reg:SI 22)
1631         (mult:SI (zero_extend:SI (reg:HI 18))
1632                  (zero_extend:SI (reg:HI 26))))]
1633   "AVR_HAVE_MUL"
1634   "%~call __umulhisi3"
1635   [(set_attr "type" "xcall")
1636    (set_attr "cc" "clobber")])
1637
1638 (define_insn "*usmulhisi3_call"
1639   [(set (reg:SI 22)
1640         (mult:SI (zero_extend:SI (reg:HI 18))
1641                  (sign_extend:SI (reg:HI 26))))]
1642   "AVR_HAVE_MUL"
1643   "%~call __usmulhisi3"
1644   [(set_attr "type" "xcall")
1645    (set_attr "cc" "clobber")])
1646
1647 (define_insn "*muluhisi3_call"
1648   [(set (reg:SI 22)
1649         (mult:SI (zero_extend:SI (reg:HI 26))
1650                  (reg:SI 18)))]
1651   "AVR_HAVE_MUL"
1652   "%~call __muluhisi3"
1653   [(set_attr "type" "xcall")
1654    (set_attr "cc" "clobber")])
1655
1656 (define_insn "*mulshisi3_call"
1657   [(set (reg:SI 22)
1658         (mult:SI (sign_extend:SI (reg:HI 26))
1659                  (reg:SI 18)))]
1660   "AVR_HAVE_MUL"
1661   "%~call __mulshisi3"
1662   [(set_attr "type" "xcall")
1663    (set_attr "cc" "clobber")])
1664
1665 (define_insn "*mulohisi3_call"
1666   [(set (reg:SI 22)
1667         (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
1668                  (reg:SI 18)))]
1669   "AVR_HAVE_MUL"
1670   "%~call __mulohisi3"
1671   [(set_attr "type" "xcall")
1672    (set_attr "cc" "clobber")])
1673
1674 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
1675 ; divmod
1676
1677 ;; Generate libgcc.S calls ourselves, because:
1678 ;;  - we know exactly which registers are clobbered (for QI and HI
1679 ;;    modes, some of the call-used registers are preserved)
1680 ;;  - we get both the quotient and the remainder at no extra cost
1681 ;;  - we split the patterns only after the first CSE passes because
1682 ;;    CSE has problems to operate on hard regs.
1683 ;; 
1684 (define_insn_and_split "divmodqi4"
1685   [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1686                    (div:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1687                            (match_operand:QI 2 "pseudo_register_operand" "")))
1688               (set (match_operand:QI 3 "pseudo_register_operand" "") 
1689                    (mod:QI (match_dup 1) (match_dup 2)))
1690               (clobber (reg:QI 22)) 
1691               (clobber (reg:QI 23)) 
1692               (clobber (reg:QI 24)) 
1693               (clobber (reg:QI 25))])]
1694   ""
1695   "this divmodqi4 pattern should have been splitted;"
1696   ""
1697   [(set (reg:QI 24) (match_dup 1))
1698    (set (reg:QI 22) (match_dup 2))
1699    (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1700               (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1701               (clobber (reg:QI 22))
1702               (clobber (reg:QI 23))])
1703    (set (match_dup 0) (reg:QI 24))
1704    (set (match_dup 3) (reg:QI 25))]
1705   "")
1706
1707 (define_insn "*divmodqi4_call"
1708   [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
1709    (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
1710    (clobber (reg:QI 22))
1711    (clobber (reg:QI 23))]
1712   ""
1713   "%~call __divmodqi4"
1714   [(set_attr "type" "xcall")
1715    (set_attr "cc" "clobber")])
1716
1717 (define_insn_and_split "udivmodqi4"
1718  [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "") 
1719                   (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "") 
1720                            (match_operand:QI 2 "pseudo_register_operand" "")))
1721              (set (match_operand:QI 3 "pseudo_register_operand" "") 
1722                   (umod:QI (match_dup 1) (match_dup 2)))
1723              (clobber (reg:QI 22))
1724              (clobber (reg:QI 23))
1725              (clobber (reg:QI 24))
1726              (clobber (reg:QI 25))])]
1727   ""
1728   "this udivmodqi4 pattern should have been splitted;"
1729   "" 
1730   [(set (reg:QI 24) (match_dup 1))
1731    (set (reg:QI 22) (match_dup 2))
1732    (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1733               (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1734               (clobber (reg:QI 23))])
1735    (set (match_dup 0) (reg:QI 24))
1736    (set (match_dup 3) (reg:QI 25))]
1737   "")
1738
1739 (define_insn "*udivmodqi4_call"
1740   [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
1741    (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
1742    (clobber (reg:QI 23))]
1743   ""
1744   "%~call __udivmodqi4"
1745   [(set_attr "type" "xcall")
1746    (set_attr "cc" "clobber")])
1747
1748 (define_insn_and_split "divmodhi4"
1749   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1750                    (div:HI (match_operand:HI 1 "pseudo_register_operand" "") 
1751                            (match_operand:HI 2 "pseudo_register_operand" "")))
1752               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1753                    (mod:HI (match_dup 1) (match_dup 2)))
1754               (clobber (reg:QI 21))
1755               (clobber (reg:HI 22))
1756               (clobber (reg:HI 24))
1757               (clobber (reg:HI 26))])]
1758   ""
1759   "this should have been splitted;"
1760   ""
1761   [(set (reg:HI 24) (match_dup 1))
1762    (set (reg:HI 22) (match_dup 2))
1763    (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1764               (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1765               (clobber (reg:HI 26))
1766               (clobber (reg:QI 21))])
1767    (set (match_dup 0) (reg:HI 22))
1768    (set (match_dup 3) (reg:HI 24))]
1769   "") 
1770
1771 (define_insn "*divmodhi4_call"
1772   [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
1773    (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
1774    (clobber (reg:HI 26))
1775    (clobber (reg:QI 21))]
1776   ""
1777   "%~call __divmodhi4"
1778   [(set_attr "type" "xcall")
1779    (set_attr "cc" "clobber")])
1780
1781 (define_insn_and_split "udivmodhi4"
1782   [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "") 
1783                    (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
1784                             (match_operand:HI 2 "pseudo_register_operand" "")))
1785               (set (match_operand:HI 3 "pseudo_register_operand" "") 
1786                    (umod:HI (match_dup 1) (match_dup 2)))
1787               (clobber (reg:QI 21))
1788               (clobber (reg:HI 22))
1789               (clobber (reg:HI 24))
1790               (clobber (reg:HI 26))])]
1791   ""
1792   "this udivmodhi4 pattern should have been splitted.;"
1793   ""
1794   [(set (reg:HI 24) (match_dup 1))
1795    (set (reg:HI 22) (match_dup 2))
1796    (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1797               (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1798               (clobber (reg:HI 26))
1799               (clobber (reg:QI 21))])
1800    (set (match_dup 0) (reg:HI 22))
1801    (set (match_dup 3) (reg:HI 24))]
1802   "")
1803
1804 (define_insn "*udivmodhi4_call"
1805   [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
1806    (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
1807    (clobber (reg:HI 26))
1808    (clobber (reg:QI 21))]
1809   ""
1810   "%~call __udivmodhi4"
1811   [(set_attr "type" "xcall")
1812    (set_attr "cc" "clobber")])
1813
1814 (define_insn_and_split "divmodsi4"
1815   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1816                    (div:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1817                            (match_operand:SI 2 "pseudo_register_operand" "")))
1818               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1819                    (mod:SI (match_dup 1) (match_dup 2)))
1820               (clobber (reg:SI 18))
1821               (clobber (reg:SI 22))
1822               (clobber (reg:HI 26))
1823               (clobber (reg:HI 30))])]
1824   ""
1825   "this divmodsi4 pattern should have been splitted;" 
1826   ""
1827   [(set (reg:SI 22) (match_dup 1))
1828    (set (reg:SI 18) (match_dup 2))
1829    (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1830               (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1831               (clobber (reg:HI 26))
1832               (clobber (reg:HI 30))])
1833    (set (match_dup 0) (reg:SI 18))
1834    (set (match_dup 3) (reg:SI 22))]
1835   "")
1836
1837 (define_insn "*divmodsi4_call"
1838   [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
1839    (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
1840    (clobber (reg:HI 26))
1841    (clobber (reg:HI 30))]
1842   ""
1843   "%~call __divmodsi4"
1844   [(set_attr "type" "xcall")
1845    (set_attr "cc" "clobber")])
1846
1847 (define_insn_and_split "udivmodsi4"
1848   [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "") 
1849                    (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "") 
1850                            (match_operand:SI 2 "pseudo_register_operand" "")))
1851               (set (match_operand:SI 3 "pseudo_register_operand" "") 
1852                    (umod:SI (match_dup 1) (match_dup 2)))
1853               (clobber (reg:SI 18))
1854               (clobber (reg:SI 22))
1855               (clobber (reg:HI 26))
1856               (clobber (reg:HI 30))])]
1857   ""
1858   "this udivmodsi4 pattern should have been splitted;"
1859   ""
1860   [(set (reg:SI 22) (match_dup 1))
1861    (set (reg:SI 18) (match_dup 2))
1862    (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1863               (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1864               (clobber (reg:HI 26))
1865               (clobber (reg:HI 30))])
1866    (set (match_dup 0) (reg:SI 18))
1867    (set (match_dup 3) (reg:SI 22))]
1868   "")
1869
1870 (define_insn "*udivmodsi4_call"
1871   [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
1872    (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
1873    (clobber (reg:HI 26))
1874    (clobber (reg:HI 30))]
1875   ""
1876   "%~call __udivmodsi4"
1877   [(set_attr "type" "xcall")
1878    (set_attr "cc" "clobber")])
1879
1880 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1881 ; and
1882
1883 (define_insn "andqi3"
1884   [(set (match_operand:QI 0 "register_operand" "=r,d")
1885         (and:QI (match_operand:QI 1 "register_operand" "%0,0")
1886                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1887   ""
1888   "@
1889         and %0,%2
1890         andi %0,lo8(%2)"
1891   [(set_attr "length" "1,1")
1892    (set_attr "cc" "set_zn,set_zn")])
1893
1894 (define_insn "andhi3"
1895   [(set (match_operand:HI 0 "register_operand" "=r,d,r")
1896           (and:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1897                   (match_operand:HI 2 "nonmemory_operand" "r,i,M")))
1898    (clobber (match_scratch:QI 3 "=X,X,&d"))]
1899   ""
1900 {
1901   if (which_alternative==0)
1902     return ("and %A0,%A2" CR_TAB
1903             "and %B0,%B2");
1904   else if (which_alternative==1)
1905     {
1906       if (GET_CODE (operands[2]) == CONST_INT)
1907         {
1908           int mask = INTVAL (operands[2]);
1909           if ((mask & 0xff) != 0xff)
1910             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1911           if ((mask & 0xff00) != 0xff00)
1912             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1913           return "";
1914         }
1915         return (AS2 (andi,%A0,lo8(%2)) CR_TAB
1916                 AS2 (andi,%B0,hi8(%2)));
1917      }
1918   return (AS2 (ldi,%3,lo8(%2)) CR_TAB
1919           "and %A0,%3"         CR_TAB
1920           AS1 (clr,%B0));
1921 }
1922   [(set_attr "length" "2,2,3")
1923    (set_attr "cc" "set_n,clobber,set_n")])
1924
1925 (define_insn "andsi3"
1926   [(set (match_operand:SI 0 "register_operand" "=r,d")
1927         (and:SI (match_operand:SI 1 "register_operand" "%0,0")
1928                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
1929   ""
1930 {
1931   if (which_alternative==0)
1932     return ("and %0,%2"   CR_TAB
1933             "and %B0,%B2" CR_TAB
1934             "and %C0,%C2" CR_TAB
1935             "and %D0,%D2");
1936   else if (which_alternative==1)
1937     {
1938       if (GET_CODE (operands[2]) == CONST_INT)
1939         {
1940           HOST_WIDE_INT mask = INTVAL (operands[2]);
1941           if ((mask & 0xff) != 0xff)
1942             output_asm_insn (AS2 (andi,%A0,lo8(%2)), operands);
1943           if ((mask & 0xff00) != 0xff00)
1944             output_asm_insn (AS2 (andi,%B0,hi8(%2)), operands);
1945           if ((mask & 0xff0000L) != 0xff0000L)
1946             output_asm_insn (AS2 (andi,%C0,hlo8(%2)), operands);
1947           if ((mask & 0xff000000L) != 0xff000000L)
1948             output_asm_insn (AS2 (andi,%D0,hhi8(%2)), operands);
1949           return "";
1950         }
1951       return (AS2 (andi, %A0,lo8(%2))  CR_TAB
1952               AS2 (andi, %B0,hi8(%2)) CR_TAB
1953               AS2 (andi, %C0,hlo8(%2)) CR_TAB
1954               AS2 (andi, %D0,hhi8(%2)));
1955     }
1956   return "bug";
1957 }
1958   [(set_attr "length" "4,4")
1959    (set_attr "cc" "set_n,clobber")])
1960
1961 (define_peephole2 ; andi
1962   [(set (match_operand:QI 0 "d_register_operand" "")
1963         (and:QI (match_dup 0)
1964                 (match_operand:QI 1 "const_int_operand" "")))
1965    (set (match_dup 0)
1966         (and:QI (match_dup 0)
1967                 (match_operand:QI 2 "const_int_operand" "")))]
1968   ""
1969   [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
1970   {
1971     operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
1972   })
1973
1974 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1975 ;; ior
1976
1977 (define_insn "iorqi3"
1978   [(set (match_operand:QI 0 "register_operand" "=r,d")
1979         (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
1980                 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1981   ""
1982   "@
1983         or %0,%2
1984         ori %0,lo8(%2)"
1985   [(set_attr "length" "1,1")
1986    (set_attr "cc" "set_zn,set_zn")])
1987
1988 (define_insn "iorhi3"
1989   [(set (match_operand:HI 0 "register_operand" "=r,d")
1990         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
1991                 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1992   ""
1993 {
1994   if (which_alternative==0)
1995     return ("or %A0,%A2" CR_TAB
1996             "or %B0,%B2");
1997   if (GET_CODE (operands[2]) == CONST_INT)
1998      {
1999         int mask = INTVAL (operands[2]);
2000         if (mask & 0xff)
2001           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2002         if (mask & 0xff00)
2003           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2004         return "";
2005       }
2006    return (AS2 (ori,%0,lo8(%2)) CR_TAB
2007            AS2 (ori,%B0,hi8(%2)));
2008 }
2009   [(set_attr "length" "2,2")
2010    (set_attr "cc" "set_n,clobber")])
2011
2012 (define_insn "*iorhi3_clobber"
2013   [(set (match_operand:HI 0 "register_operand" "=r,r")
2014         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
2015                 (match_operand:HI 2 "immediate_operand" "M,i")))
2016    (clobber (match_scratch:QI 3 "=&d,&d"))]
2017   ""
2018   "@
2019         ldi %3,lo8(%2)\;or %A0,%3
2020         ldi %3,lo8(%2)\;or %A0,%3\;ldi %3,hi8(%2)\;or %B0,%3"
2021   [(set_attr "length" "2,4")
2022    (set_attr "cc" "clobber,set_n")])
2023
2024 (define_insn "iorsi3"
2025   [(set (match_operand:SI 0 "register_operand"        "=r,d")
2026         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2027                 (match_operand:SI 2 "nonmemory_operand" "r,i")))]
2028   ""
2029 {
2030   if (which_alternative==0)
2031     return ("or %0,%2"   CR_TAB
2032             "or %B0,%B2" CR_TAB
2033             "or %C0,%C2" CR_TAB
2034             "or %D0,%D2");
2035   if (GET_CODE (operands[2]) == CONST_INT)
2036      {
2037         HOST_WIDE_INT mask = INTVAL (operands[2]);
2038         if (mask & 0xff)
2039           output_asm_insn (AS2 (ori,%A0,lo8(%2)), operands);
2040         if (mask & 0xff00)
2041           output_asm_insn (AS2 (ori,%B0,hi8(%2)), operands);
2042         if (mask & 0xff0000L)
2043           output_asm_insn (AS2 (ori,%C0,hlo8(%2)), operands);
2044         if (mask & 0xff000000L)
2045           output_asm_insn (AS2 (ori,%D0,hhi8(%2)), operands);
2046         return "";
2047       }
2048   return (AS2 (ori, %A0,lo8(%2))  CR_TAB
2049           AS2 (ori, %B0,hi8(%2)) CR_TAB
2050           AS2 (ori, %C0,hlo8(%2)) CR_TAB
2051           AS2 (ori, %D0,hhi8(%2)));
2052 }
2053   [(set_attr "length" "4,4")
2054    (set_attr "cc" "set_n,clobber")])
2055
2056 (define_insn "*iorsi3_clobber"
2057   [(set (match_operand:SI 0 "register_operand"        "=r,r")
2058         (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
2059                 (match_operand:SI 2 "immediate_operand" "M,i")))
2060    (clobber (match_scratch:QI 3 "=&d,&d"))]
2061   ""
2062   "@
2063         ldi %3,lo8(%2)\;or %A0,%3
2064         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"
2065   [(set_attr "length" "2,8")
2066    (set_attr "cc" "clobber,set_n")])
2067
2068 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2069 ;; xor
2070
2071 (define_insn "xorqi3"
2072   [(set (match_operand:QI 0 "register_operand" "=r")
2073         (xor:QI (match_operand:QI 1 "register_operand" "%0")
2074                 (match_operand:QI 2 "register_operand" "r")))]
2075   ""
2076   "eor %0,%2"
2077   [(set_attr "length" "1")
2078    (set_attr "cc" "set_zn")])
2079
2080 (define_insn "xorhi3"
2081   [(set (match_operand:HI 0 "register_operand" "=r")
2082         (xor:HI (match_operand:HI 1 "register_operand" "%0")
2083                 (match_operand:HI 2 "register_operand" "r")))]
2084   ""
2085   "eor %0,%2
2086         eor %B0,%B2"
2087   [(set_attr "length" "2")
2088    (set_attr "cc" "set_n")])
2089
2090 (define_insn "xorsi3"
2091   [(set (match_operand:SI 0 "register_operand" "=r")
2092         (xor:SI (match_operand:SI 1 "register_operand" "%0")
2093                 (match_operand:SI 2 "register_operand" "r")))]
2094   ""
2095   "eor %0,%2
2096         eor %B0,%B2
2097         eor %C0,%C2
2098         eor %D0,%D2"
2099   [(set_attr "length" "4")
2100    (set_attr "cc" "set_n")])
2101
2102 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
2103 ;; swap
2104
2105 (define_expand "rotlqi3"
2106   [(set (match_operand:QI 0 "register_operand" "")
2107         (rotate:QI (match_operand:QI 1 "register_operand" "")
2108                    (match_operand:QI 2 "const_int_operand" "")))]
2109   ""
2110   "
2111 {
2112   if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
2113     FAIL;
2114 }")
2115
2116 (define_insn "rotlqi3_4"
2117   [(set (match_operand:QI 0 "register_operand" "=r")
2118         (rotate:QI (match_operand:QI 1 "register_operand" "0")
2119                    (const_int 4)))]
2120   ""
2121   "swap %0"
2122   [(set_attr "length" "1")
2123    (set_attr "cc" "none")])
2124
2125 ;; Split all rotates of HI,SI and DImode registers where rotation is by
2126 ;; a whole number of bytes.  The split creates the appropriate moves and
2127 ;; considers all overlap situations.  DImode is split before reload.
2128
2129 ;; HImode does not need scratch.  Use attribute for this constraint.
2130 ;; Use QI scratch for DI mode as this is often split into byte sized operands.
2131
2132 (define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
2133 (define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
2134
2135 (define_expand "rotl<mode>3"
2136   [(parallel [(set (match_operand:HIDI 0 "register_operand" "")
2137                    (rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
2138                                 (match_operand:VOID 2 "const_int_operand" "")))
2139                 (clobber (match_dup 3))])]
2140   ""
2141   {
2142     if (CONST_INT_P (operands[2])
2143         && 0 == INTVAL (operands[2]) % 8)
2144       {
2145         if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
2146           operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
2147         else
2148           operands[3] = gen_rtx_SCRATCH (QImode);
2149       }
2150     else
2151       FAIL;
2152   })
2153
2154
2155 ;; Overlapping non-HImode registers often (but not always) need a scratch.
2156 ;; The best we can do is use early clobber alternative "#&r" so that
2157 ;; completely non-overlapping operands dont get a scratch but # so register
2158 ;; allocation does not prefer non-overlapping.
2159
2160
2161 ; Split word aligned rotates using scratch that is mode dependent.
2162 (define_insn_and_split "*rotw<mode>"
2163   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2164         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2165                      (match_operand 2 "const_int_operand" "n,n,n")))
2166    (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
2167   "AVR_HAVE_MOVW
2168    && CONST_INT_P (operands[2])
2169    && 0 == INTVAL (operands[2]) % 16"
2170   "#"
2171   "&& (reload_completed || <MODE>mode == DImode)"
2172   [(const_int 0)]
2173   {
2174     avr_rotate_bytes (operands);
2175     DONE;
2176   })
2177
2178
2179 ; Split byte aligned rotates using scratch that is always QI mode.
2180 (define_insn_and_split "*rotb<mode>"
2181   [(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
2182         (rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
2183                      (match_operand 2 "const_int_operand" "n,n,n")))
2184    (clobber (match_scratch:QI 3 "=<rotx>"))]
2185   "CONST_INT_P (operands[2])
2186    && (8 == INTVAL (operands[2]) % 16
2187        || (!AVR_HAVE_MOVW
2188            && 0 == INTVAL (operands[2]) % 16))"
2189   "#"
2190   "&& (reload_completed || <MODE>mode == DImode)"
2191   [(const_int 0)]
2192   {
2193     avr_rotate_bytes (operands);
2194     DONE;
2195   })
2196
2197
2198 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
2199 ;; arithmetic shift left
2200
2201 (define_expand "ashlqi3"
2202   [(set (match_operand:QI 0 "register_operand"            "")
2203         (ashift:QI (match_operand:QI 1 "register_operand" "")
2204                    (match_operand:QI 2 "general_operand"  "")))]
2205   ""
2206   "")
2207
2208 (define_split ; ashlqi3_const4
2209   [(set (match_operand:QI 0 "d_register_operand" "")
2210         (ashift:QI (match_dup 0)
2211                    (const_int 4)))]
2212   ""
2213   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2214    (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
2215   "")
2216
2217 (define_split ; ashlqi3_const5
2218   [(set (match_operand:QI 0 "d_register_operand" "")
2219         (ashift:QI (match_dup 0)
2220                    (const_int 5)))]
2221   ""
2222   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2223    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2224    (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
2225   "")
2226
2227 (define_split ; ashlqi3_const6
2228   [(set (match_operand:QI 0 "d_register_operand" "")
2229         (ashift:QI (match_dup 0)
2230                    (const_int 6)))]
2231   ""
2232   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2233    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2234    (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
2235   "")
2236
2237 (define_insn "*ashlqi3"
2238   [(set (match_operand:QI 0 "register_operand"           "=r,r,r,r,!d,r,r")
2239         (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2240                    (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
2241   ""
2242   "* return ashlqi3_out (insn, operands, NULL);"
2243   [(set_attr "length" "5,0,1,2,4,6,9")
2244    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2245
2246 (define_insn "ashlhi3"
2247   [(set (match_operand:HI 0 "register_operand"           "=r,r,r,r,r,r,r")
2248         (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2249                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2250   ""
2251   "* return ashlhi3_out (insn, operands, NULL);"
2252   [(set_attr "length" "6,0,2,2,4,10,10")
2253    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2254
2255 (define_insn "ashlsi3"
2256   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
2257         (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2258                    (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2259   ""
2260   "* return ashlsi3_out (insn, operands, NULL);"
2261   [(set_attr "length" "8,0,4,4,8,10,12")
2262    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
2263
2264 ;; Optimize if a scratch register from LD_REGS happens to be available.
2265
2266 (define_peephole2 ; ashlqi3_l_const4
2267   [(set (match_operand:QI 0 "l_register_operand" "")
2268         (ashift:QI (match_dup 0)
2269                    (const_int 4)))
2270    (match_scratch:QI 1 "d")]
2271   ""
2272   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2273    (set (match_dup 1) (const_int -16))
2274    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2275   "")
2276
2277 (define_peephole2 ; ashlqi3_l_const5
2278   [(set (match_operand:QI 0 "l_register_operand" "")
2279         (ashift:QI (match_dup 0)
2280                    (const_int 5)))
2281    (match_scratch:QI 1 "d")]
2282   ""
2283   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2284    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
2285    (set (match_dup 1) (const_int -32))
2286    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2287   "")
2288
2289 (define_peephole2 ; ashlqi3_l_const6
2290   [(set (match_operand:QI 0 "l_register_operand" "")
2291         (ashift:QI (match_dup 0)
2292                    (const_int 6)))
2293    (match_scratch:QI 1 "d")]
2294   ""
2295   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2296    (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
2297    (set (match_dup 1) (const_int -64))
2298    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2299   "")
2300
2301 (define_peephole2
2302   [(match_scratch:QI 3 "d")
2303    (set (match_operand:HI 0 "register_operand" "")
2304         (ashift:HI (match_operand:HI 1 "register_operand" "")
2305                    (match_operand:QI 2 "const_int_operand" "")))]
2306   ""
2307   [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
2308               (clobber (match_dup 3))])]
2309   "")
2310
2311 (define_insn "*ashlhi3_const"
2312   [(set (match_operand:HI 0 "register_operand"            "=r,r,r,r,r")
2313         (ashift:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
2314                    (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2315    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2316   "reload_completed"
2317   "* return ashlhi3_out (insn, operands, NULL);"
2318   [(set_attr "length" "0,2,2,4,10")
2319    (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
2320
2321 (define_peephole2
2322   [(match_scratch:QI 3 "d")
2323    (set (match_operand:SI 0 "register_operand" "")
2324         (ashift:SI (match_operand:SI 1 "register_operand" "")
2325                    (match_operand:QI 2 "const_int_operand" "")))]
2326   ""
2327   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
2328               (clobber (match_dup 3))])]
2329   "")
2330
2331 (define_insn "*ashlsi3_const"
2332   [(set (match_operand:SI 0 "register_operand"            "=r,r,r,r")
2333         (ashift:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
2334                    (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2335    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2336   "reload_completed"
2337   "* return ashlsi3_out (insn, operands, NULL);"
2338   [(set_attr "length" "0,4,4,10")
2339    (set_attr "cc" "none,set_n,clobber,clobber")])
2340
2341 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2342 ;; arithmetic shift right
2343
2344 (define_insn "ashrqi3"
2345   [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r")
2346         (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0")
2347                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,Qm")))]
2348   ""
2349   "* return ashrqi3_out (insn, operands, NULL);"
2350   [(set_attr "length" "5,0,1,2,5,9")
2351    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")])
2352
2353 (define_insn "ashrhi3"
2354   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
2355         (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2356                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2357   ""
2358   "* return ashrhi3_out (insn, operands, NULL);"
2359   [(set_attr "length" "6,0,2,4,4,10,10")
2360    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2361
2362 (define_insn "ashrsi3"
2363   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
2364         (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2365                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2366   ""
2367   "* return ashrsi3_out (insn, operands, NULL);"
2368   [(set_attr "length" "8,0,4,6,8,10,12")
2369    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
2370
2371 ;; Optimize if a scratch register from LD_REGS happens to be available.
2372
2373 (define_peephole2
2374   [(match_scratch:QI 3 "d")
2375    (set (match_operand:HI 0 "register_operand" "")
2376         (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
2377                      (match_operand:QI 2 "const_int_operand" "")))]
2378   ""
2379   [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
2380               (clobber (match_dup 3))])]
2381   "")
2382
2383 (define_insn "*ashrhi3_const"
2384   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
2385         (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
2386                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2387    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2388   "reload_completed"
2389   "* return ashrhi3_out (insn, operands, NULL);"
2390   [(set_attr "length" "0,2,4,4,10")
2391    (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
2392
2393 (define_peephole2
2394   [(match_scratch:QI 3 "d")
2395    (set (match_operand:SI 0 "register_operand" "")
2396         (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
2397                      (match_operand:QI 2 "const_int_operand" "")))]
2398   ""
2399   [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
2400               (clobber (match_dup 3))])]
2401   "")
2402
2403 (define_insn "*ashrsi3_const"
2404   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
2405         (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
2406                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2407    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2408   "reload_completed"
2409   "* return ashrsi3_out (insn, operands, NULL);"
2410   [(set_attr "length" "0,4,4,10")
2411    (set_attr "cc" "none,clobber,set_n,clobber")])
2412
2413 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
2414 ;; logical shift right
2415
2416 (define_expand "lshrqi3"
2417   [(set (match_operand:QI 0 "register_operand"              "")
2418         (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
2419                      (match_operand:QI 2 "general_operand"  "")))]
2420   ""
2421   "")
2422
2423 (define_split   ; lshrqi3_const4
2424   [(set (match_operand:QI 0 "d_register_operand" "")
2425         (lshiftrt:QI (match_dup 0)
2426                      (const_int 4)))]
2427   ""
2428   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2429    (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
2430   "")
2431
2432 (define_split   ; lshrqi3_const5
2433   [(set (match_operand:QI 0 "d_register_operand" "")
2434         (lshiftrt:QI (match_dup 0)
2435                      (const_int 5)))]
2436   ""
2437   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2438    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2439    (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
2440   "")
2441
2442 (define_split   ; lshrqi3_const6
2443   [(set (match_operand:QI 0 "d_register_operand" "")
2444         (lshiftrt:QI (match_dup 0)
2445                      (const_int 6)))]
2446   ""
2447   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2448    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2449    (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
2450   "")
2451
2452 (define_insn "*lshrqi3"
2453   [(set (match_operand:QI 0 "register_operand"             "=r,r,r,r,!d,r,r")
2454         (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0")
2455                      (match_operand:QI 2 "general_operand"  "r,L,P,K,n,n,Qm")))]
2456   ""
2457   "* return lshrqi3_out (insn, operands, NULL);"
2458   [(set_attr "length" "5,0,1,2,4,6,9")
2459    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
2460
2461 (define_insn "lshrhi3"
2462   [(set (match_operand:HI 0 "register_operand"             "=r,r,r,r,r,r,r")
2463         (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
2464                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2465   ""
2466   "* return lshrhi3_out (insn, operands, NULL);"
2467   [(set_attr "length" "6,0,2,2,4,10,10")
2468    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2469
2470 (define_insn "lshrsi3"
2471   [(set (match_operand:SI 0 "register_operand"             "=r,r,r,r,r,r,r")
2472         (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
2473                      (match_operand:QI 2 "general_operand"  "r,L,P,O,K,n,Qm")))]
2474   ""
2475   "* return lshrsi3_out (insn, operands, NULL);"
2476   [(set_attr "length" "8,0,4,4,8,10,12")
2477    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
2478
2479 ;; Optimize if a scratch register from LD_REGS happens to be available.
2480
2481 (define_peephole2 ; lshrqi3_l_const4
2482   [(set (match_operand:QI 0 "l_register_operand" "")
2483         (lshiftrt:QI (match_dup 0)
2484                      (const_int 4)))
2485    (match_scratch:QI 1 "d")]
2486   ""
2487   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2488    (set (match_dup 1) (const_int 15))
2489    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2490   "")
2491
2492 (define_peephole2 ; lshrqi3_l_const5
2493   [(set (match_operand:QI 0 "l_register_operand" "")
2494         (lshiftrt:QI (match_dup 0)
2495                      (const_int 5)))
2496    (match_scratch:QI 1 "d")]
2497   ""
2498   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2499    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
2500    (set (match_dup 1) (const_int 7))
2501    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2502   "")
2503
2504 (define_peephole2 ; lshrqi3_l_const6
2505   [(set (match_operand:QI 0 "l_register_operand" "")
2506         (lshiftrt:QI (match_dup 0)
2507                      (const_int 6)))
2508    (match_scratch:QI 1 "d")]
2509   ""
2510   [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
2511    (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
2512    (set (match_dup 1) (const_int 3))
2513    (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2514   "")
2515
2516 (define_peephole2
2517   [(match_scratch:QI 3 "d")
2518    (set (match_operand:HI 0 "register_operand" "")
2519         (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
2520                      (match_operand:QI 2 "const_int_operand" "")))]
2521   ""
2522   [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
2523               (clobber (match_dup 3))])]
2524   "")
2525
2526 (define_insn "*lshrhi3_const"
2527   [(set (match_operand:HI 0 "register_operand"              "=r,r,r,r,r")
2528         (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0,r,0,0")
2529                      (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
2530    (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
2531   "reload_completed"
2532   "* return lshrhi3_out (insn, operands, NULL);"
2533   [(set_attr "length" "0,2,2,4,10")
2534    (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
2535
2536 (define_peephole2
2537   [(match_scratch:QI 3 "d")
2538    (set (match_operand:SI 0 "register_operand" "")
2539         (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2540                      (match_operand:QI 2 "const_int_operand" "")))]
2541   ""
2542   [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
2543               (clobber (match_dup 3))])]
2544   "")
2545
2546 (define_insn "*lshrsi3_const"
2547   [(set (match_operand:SI 0 "register_operand"              "=r,r,r,r")
2548         (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0,r,0")
2549                      (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
2550    (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
2551   "reload_completed"
2552   "* return lshrsi3_out (insn, operands, NULL);"
2553   [(set_attr "length" "0,4,4,10")
2554    (set_attr "cc" "none,clobber,clobber,clobber")])
2555
2556 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
2557 ;; abs
2558
2559 (define_insn "absqi2"
2560   [(set (match_operand:QI 0 "register_operand" "=r")
2561         (abs:QI (match_operand:QI 1 "register_operand" "0")))]
2562   ""
2563   "sbrc %0,7
2564         neg %0"
2565   [(set_attr "length" "2")
2566    (set_attr "cc" "clobber")])
2567
2568
2569 (define_insn "abssf2"
2570   [(set (match_operand:SF 0 "register_operand" "=d,r")
2571         (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
2572   ""
2573   "@
2574         andi %D0,0x7f
2575         clt\;bld %D0,7"
2576   [(set_attr "length" "1,2")
2577    (set_attr "cc" "set_n,clobber")])
2578
2579 ;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
2580 ;; neg
2581
2582 (define_insn "negqi2"
2583   [(set (match_operand:QI 0 "register_operand" "=r")
2584         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
2585   ""
2586   "neg %0"
2587   [(set_attr "length" "1")
2588    (set_attr "cc" "set_zn")])
2589
2590 (define_insn "neghi2"
2591   [(set (match_operand:HI 0 "register_operand"       "=!d,r,&r")
2592         (neg:HI (match_operand:HI 1 "register_operand" "0,0,r")))]
2593   ""
2594   "@
2595         com %B0\;neg %A0\;sbci %B0,lo8(-1)
2596         com %B0\;neg %A0\;sbc %B0,__zero_reg__\;inc %B0
2597         clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
2598   [(set_attr "length" "3,4,4")
2599    (set_attr "cc" "set_czn,set_n,set_czn")])
2600
2601 (define_insn "negsi2"
2602   [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
2603         (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
2604   ""
2605   "@
2606         com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
2607         com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
2608         clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
2609   [(set_attr_alternative "length"
2610                          [(const_int 7)
2611                           (const_int 8)
2612                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2613                                         (const_int 7)
2614                                         (const_int 8))])
2615    (set_attr "cc" "set_czn,set_n,set_czn")])
2616
2617 (define_insn "negsf2"
2618   [(set (match_operand:SF 0 "register_operand" "=d,r")
2619         (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
2620   ""
2621   "@
2622         subi %D0,0x80
2623         bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
2624   [(set_attr "length" "1,4")
2625    (set_attr "cc" "set_n,set_n")])
2626
2627 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2628 ;; not
2629
2630 (define_insn "one_cmplqi2"
2631   [(set (match_operand:QI 0 "register_operand" "=r")
2632         (not:QI (match_operand:QI 1 "register_operand" "0")))]
2633   ""
2634   "com %0"
2635   [(set_attr "length" "1")
2636    (set_attr "cc" "set_czn")])
2637
2638 (define_insn "one_cmplhi2"
2639   [(set (match_operand:HI 0 "register_operand" "=r")
2640         (not:HI (match_operand:HI 1 "register_operand" "0")))]
2641   ""
2642   "com %0
2643         com %B0"
2644   [(set_attr "length" "2")
2645    (set_attr "cc" "set_n")])
2646
2647 (define_insn "one_cmplsi2"
2648   [(set (match_operand:SI 0 "register_operand" "=r")
2649         (not:SI (match_operand:SI 1 "register_operand" "0")))]
2650   ""
2651   "com %0
2652         com %B0
2653         com %C0
2654         com %D0"
2655   [(set_attr "length" "4")
2656    (set_attr "cc" "set_n")])
2657
2658 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2659 ;; sign extend
2660
2661 ;; We keep combiner from inserting hard registers into the input of sign- and
2662 ;; zero-extends.  A hard register in the input operand is not wanted because
2663 ;; 32-bit multiply patterns clobber some hard registers and extends with a
2664 ;; hard register that overlaps these clobbers won't be combined to a widening
2665 ;; multiplication.  There is no need for combine to propagate hard registers,
2666 ;; register allocation can do it just as well.
2667
2668 (define_insn "extendqihi2"
2669   [(set (match_operand:HI 0 "register_operand" "=r,r")
2670         (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2671   ""
2672   "@
2673         clr %B0\;sbrc %0,7\;com %B0
2674         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
2675   [(set_attr "length" "3,4")
2676    (set_attr "cc" "set_n,set_n")])
2677
2678 (define_insn "extendqisi2"
2679   [(set (match_operand:SI 0 "register_operand" "=r,r")
2680         (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
2681   ""
2682   "@
2683         clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
2684         mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
2685   [(set_attr "length" "5,6")
2686    (set_attr "cc" "set_n,set_n")])
2687
2688 (define_insn "extendhisi2"
2689   [(set (match_operand:SI 0 "register_operand"                               "=r,r")
2690         (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
2691   ""
2692   "@
2693         clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
2694         {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
2695   [(set_attr_alternative "length"
2696                          [(const_int 4)
2697                           (if_then_else (eq_attr "mcu_have_movw" "yes")
2698                                         (const_int 5)
2699                                         (const_int 6))])
2700    (set_attr "cc" "set_n,set_n")])
2701
2702 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
2703 ;; zero extend
2704
2705 (define_insn_and_split "zero_extendqihi2"
2706   [(set (match_operand:HI 0 "register_operand" "=r")
2707         (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2708   ""
2709   "#"
2710   "reload_completed"
2711   [(set (match_dup 2) (match_dup 1))
2712    (set (match_dup 3) (const_int 0))]
2713 {
2714   unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
2715   unsigned int high_off = subreg_highpart_offset (QImode, HImode);
2716
2717   operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
2718   operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
2719 })
2720
2721 (define_insn_and_split "zero_extendqisi2"
2722   [(set (match_operand:SI 0 "register_operand" "=r")
2723         (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
2724   ""
2725   "#"
2726   "reload_completed"
2727   [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
2728    (set (match_dup 3) (const_int 0))]
2729 {
2730   unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2731   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2732
2733   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2734   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2735 })
2736
2737 (define_insn_and_split "zero_extendhisi2"
2738   [(set (match_operand:SI 0 "register_operand"                               "=r")
2739         (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
2740   ""
2741   "#"
2742   "reload_completed"
2743   [(set (match_dup 2) (match_dup 1))
2744    (set (match_dup 3) (const_int 0))]
2745 {
2746   unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
2747   unsigned int high_off = subreg_highpart_offset (HImode, SImode);
2748
2749   operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
2750   operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
2751 })
2752
2753 (define_insn_and_split "zero_extendqidi2"
2754   [(set (match_operand:DI 0 "register_operand" "=r")
2755         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
2756   ""
2757   "#"
2758   "reload_completed"
2759   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2760    (set (match_dup 3) (const_int 0))]
2761 {
2762   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2763   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2764
2765   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2766   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2767 })
2768
2769 (define_insn_and_split "zero_extendhidi2"
2770   [(set (match_operand:DI 0 "register_operand" "=r")
2771         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
2772   ""
2773   "#"
2774   "reload_completed"
2775   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
2776    (set (match_dup 3) (const_int 0))]
2777 {
2778   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2779   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2780
2781   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2782   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2783 })
2784
2785 (define_insn_and_split "zero_extendsidi2"
2786   [(set (match_operand:DI 0 "register_operand" "=r")
2787         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2788   ""
2789   "#"
2790   "reload_completed"
2791   [(set (match_dup 2) (match_dup 1))
2792    (set (match_dup 3) (const_int 0))]
2793 {
2794   unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
2795   unsigned int high_off = subreg_highpart_offset (SImode, DImode);
2796
2797   operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
2798   operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
2799 })
2800
2801 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
2802 ;; compare
2803
2804 ; Optimize negated tests into reverse compare if overflow is undefined.
2805 (define_insn "*negated_tstqi"
2806   [(set (cc0)
2807         (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
2808                  (const_int 0)))]
2809   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2810   "cp __zero_reg__,%0"
2811   [(set_attr "cc" "compare")
2812    (set_attr "length" "1")])
2813
2814 (define_insn "*reversed_tstqi"
2815   [(set (cc0)
2816         (compare (const_int 0)
2817                  (match_operand:QI 0 "register_operand" "r")))]
2818   ""
2819   "cp __zero_reg__,%0"
2820 [(set_attr "cc" "compare")
2821  (set_attr "length" "2")])
2822
2823 (define_insn "*negated_tsthi"
2824   [(set (cc0)
2825         (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
2826                  (const_int 0)))]
2827   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2828   "cp __zero_reg__,%A0
2829         cpc __zero_reg__,%B0"
2830 [(set_attr "cc" "compare")
2831  (set_attr "length" "2")])
2832
2833 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
2834 ;; though it is unused, because this pattern is synthesized by avr_reorg.
2835 (define_insn "*reversed_tsthi"
2836   [(set (cc0)
2837         (compare (const_int 0)
2838                  (match_operand:HI 0 "register_operand" "r")))
2839    (clobber (match_scratch:QI 1 "=X"))]
2840   ""
2841   "cp __zero_reg__,%A0
2842         cpc __zero_reg__,%B0"
2843 [(set_attr "cc" "compare")
2844  (set_attr "length" "2")])
2845
2846 (define_insn "*negated_tstsi"
2847   [(set (cc0)
2848         (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
2849                  (const_int 0)))]
2850   "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
2851   "cp __zero_reg__,%A0
2852         cpc __zero_reg__,%B0
2853         cpc __zero_reg__,%C0
2854         cpc __zero_reg__,%D0"
2855   [(set_attr "cc" "compare")
2856    (set_attr "length" "4")])
2857
2858 (define_insn "*reversed_tstsi"
2859   [(set (cc0)
2860         (compare (const_int 0)
2861                  (match_operand:SI 0 "register_operand" "r")))
2862    (clobber (match_scratch:QI 1 "=X"))]
2863   ""
2864   "cp __zero_reg__,%A0
2865         cpc __zero_reg__,%B0
2866         cpc __zero_reg__,%C0
2867         cpc __zero_reg__,%D0"
2868   [(set_attr "cc" "compare")
2869    (set_attr "length" "4")])
2870
2871
2872 (define_insn "*cmpqi"
2873   [(set (cc0)
2874         (compare (match_operand:QI 0 "register_operand"  "r,r,d")
2875                  (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
2876   ""
2877   "@
2878         tst %0
2879         cp %0,%1
2880         cpi %0,lo8(%1)"
2881   [(set_attr "cc" "compare,compare,compare")
2882    (set_attr "length" "1,1,1")])
2883
2884 (define_insn "*cmpqi_sign_extend"
2885   [(set (cc0)
2886         (compare (sign_extend:HI
2887                   (match_operand:QI 0 "register_operand"  "d"))
2888                  (match_operand:HI 1 "const_int_operand" "n")))]
2889   "INTVAL (operands[1]) >= -128 && INTVAL (operands[1]) <= 127"
2890   "cpi %0,lo8(%1)"
2891   [(set_attr "cc" "compare")
2892    (set_attr "length" "1")])
2893
2894 (define_insn "*cmphi"
2895   [(set (cc0)
2896         (compare (match_operand:HI 0 "register_operand"  "!w,r,r,d,d,r,r")
2897                  (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
2898    (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
2899   ""
2900   "*{
2901   switch (which_alternative)
2902     {
2903     case 0: case 1:
2904       return out_tsthi (insn, operands[0], NULL);
2905
2906     case 2:
2907       return (AS2 (cp,%A0,%A1) CR_TAB
2908               AS2 (cpc,%B0,%B1));
2909     case 3:
2910       if (reg_unused_after (insn, operands[0])
2911           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2912           && test_hard_reg_class (ADDW_REGS, operands[0]))
2913         return AS2 (sbiw,%0,%1);
2914        else
2915         return (AS2 (cpi,%0,%1) CR_TAB
2916                 AS2 (cpc,%B0,__zero_reg__));
2917     case 4:
2918       if (reg_unused_after (insn, operands[0]))
2919         return (AS2 (subi,%0,lo8(%1))  CR_TAB
2920                 AS2 (sbci,%B0,hi8(%1)));
2921       else
2922         return (AS2 (ldi, %2,hi8(%1))  CR_TAB
2923                 AS2 (cpi, %A0,lo8(%1)) CR_TAB
2924                 AS2 (cpc, %B0,%2));
2925    case 5:
2926       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2927               AS2 (cp, %A0,%2) CR_TAB
2928               AS2 (cpc, %B0,__zero_reg__));
2929
2930    case 6:
2931       return (AS2 (ldi, %2,lo8(%1))  CR_TAB
2932               AS2 (cp, %A0,%2)       CR_TAB
2933               AS2 (ldi, %2,hi8(%1)) CR_TAB
2934               AS2 (cpc, %B0,%2));
2935     }
2936   return \"bug\";
2937 }" 
2938   [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
2939    (set_attr "length" "1,2,2,2,3,3,4")])
2940
2941
2942 (define_insn "*cmpsi"
2943   [(set (cc0)
2944         (compare (match_operand:SI 0 "register_operand"  "r,r,d,d,r,r")
2945                  (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
2946    (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
2947   ""
2948   "*{
2949   switch (which_alternative)
2950     {
2951     case 0:
2952       return out_tstsi (insn, operands[0], NULL);
2953
2954     case 1:
2955       return (AS2 (cp,%A0,%A1) CR_TAB
2956               AS2 (cpc,%B0,%B1) CR_TAB
2957               AS2 (cpc,%C0,%C1) CR_TAB
2958               AS2 (cpc,%D0,%D1));
2959     case 2:
2960       if (reg_unused_after (insn, operands[0])
2961           && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
2962           && test_hard_reg_class (ADDW_REGS, operands[0]))
2963         return (AS2 (sbiw,%0,%1) CR_TAB
2964                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2965                 AS2 (cpc,%D0,__zero_reg__));
2966       else
2967         return (AS2 (cpi,%A0,lo8(%1))  CR_TAB
2968                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2969                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2970                 AS2 (cpc,%D0,__zero_reg__));
2971     case 3:
2972       if (reg_unused_after (insn, operands[0]))
2973         return (AS2 (subi,%A0,lo8(%1))  CR_TAB
2974                 AS2 (sbci,%B0,hi8(%1))  CR_TAB
2975                 AS2 (sbci,%C0,hlo8(%1))  CR_TAB
2976                 AS2 (sbci,%D0,hhi8(%1)));
2977       else
2978        return (AS2 (cpi, %A0,lo8(%1))   CR_TAB
2979                AS2 (ldi, %2,hi8(%1))  CR_TAB
2980                AS2 (cpc, %B0,%2)       CR_TAB
2981                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2982                AS2 (cpc, %C0,%2)       CR_TAB
2983                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2984                AS2 (cpc, %D0,%2));
2985     case 4:
2986         return (AS2 (ldi,%2,lo8(%1))        CR_TAB
2987                 AS2 (cp,%A0,%2)            CR_TAB
2988                 AS2 (cpc,%B0,__zero_reg__) CR_TAB
2989                 AS2 (cpc,%C0,__zero_reg__) CR_TAB
2990                 AS2 (cpc,%D0,__zero_reg__));
2991     case 5:
2992        return (AS2 (ldi, %2,lo8(%1))   CR_TAB
2993                AS2 (cp, %A0,%2)        CR_TAB
2994                AS2 (ldi, %2,hi8(%1))  CR_TAB
2995                AS2 (cpc, %B0,%2)       CR_TAB
2996                AS2 (ldi, %2,hlo8(%1))  CR_TAB
2997                AS2 (cpc, %C0,%2)       CR_TAB
2998                AS2 (ldi, %2,hhi8(%1)) CR_TAB
2999                AS2 (cpc, %D0,%2));
3000     }
3001   return \"bug\";
3002 }"
3003   [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
3004    (set_attr "length" "4,4,4,7,5,8")])
3005
3006
3007 ;; ----------------------------------------------------------------------
3008 ;; JUMP INSTRUCTIONS
3009 ;; ----------------------------------------------------------------------
3010 ;; Conditional jump instructions
3011
3012 (define_expand "cbranchsi4"
3013   [(parallel [(set (cc0)
3014                    (compare (match_operand:SI 1 "register_operand" "")
3015                             (match_operand:SI 2 "nonmemory_operand" "")))
3016               (clobber (match_scratch:QI 4 ""))])
3017    (set (pc)
3018         (if_then_else
3019               (match_operator 0 "ordered_comparison_operator" [(cc0)
3020                                                                (const_int 0)])
3021               (label_ref (match_operand 3 "" ""))
3022               (pc)))]
3023  "")
3024
3025 (define_expand "cbranchhi4"
3026   [(parallel [(set (cc0)
3027                    (compare (match_operand:HI 1 "register_operand" "")
3028                             (match_operand:HI 2 "nonmemory_operand" "")))
3029               (clobber (match_scratch:QI 4 ""))])
3030    (set (pc)
3031         (if_then_else
3032               (match_operator 0 "ordered_comparison_operator" [(cc0)
3033                                                                (const_int 0)])
3034               (label_ref (match_operand 3 "" ""))
3035               (pc)))]
3036  "")
3037
3038 (define_expand "cbranchqi4"
3039   [(set (cc0)
3040         (compare (match_operand:QI 1 "register_operand" "")
3041                  (match_operand:QI 2 "nonmemory_operand" "")))
3042    (set (pc)
3043         (if_then_else
3044               (match_operator 0 "ordered_comparison_operator" [(cc0)
3045                                                                (const_int 0)])
3046               (label_ref (match_operand 3 "" ""))
3047               (pc)))]
3048  "")
3049
3050
3051 ;; Test a single bit in a QI/HI/SImode register.
3052 ;; Combine will create zero extract patterns for single bit tests.
3053 ;; permit any mode in source pattern by using VOIDmode.
3054
3055 (define_insn "*sbrx_branch<mode>"
3056   [(set (pc)
3057         (if_then_else
3058          (match_operator 0 "eqne_operator"
3059                          [(zero_extract:QIDI
3060                            (match_operand:VOID 1 "register_operand" "r")
3061                            (const_int 1)
3062                            (match_operand 2 "const_int_operand" "n"))
3063                           (const_int 0)])
3064          (label_ref (match_operand 3 "" ""))
3065          (pc)))]
3066   ""
3067   "* return avr_out_sbxx_branch (insn, operands);"
3068   [(set (attr "length")
3069         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3070                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
3071                       (const_int 2)
3072                       (if_then_else (eq_attr "mcu_mega" "no")
3073                                     (const_int 2)
3074                                     (const_int 4))))
3075    (set_attr "cc" "clobber")])
3076
3077 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
3078 ;; or for old peepholes.
3079 ;; Fixme - bitwise Mask will not work for DImode
3080
3081 (define_insn "*sbrx_and_branch<mode>"
3082   [(set (pc)
3083         (if_then_else
3084          (match_operator 0 "eqne_operator"
3085                          [(and:QISI
3086                            (match_operand:QISI 1 "register_operand" "r")
3087                            (match_operand:QISI 2 "single_one_operand" "n"))
3088                           (const_int 0)])
3089          (label_ref (match_operand 3 "" ""))
3090          (pc)))]
3091   ""
3092 {
3093     HOST_WIDE_INT bitnumber;
3094     bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
3095     operands[2] = GEN_INT (bitnumber);
3096     return avr_out_sbxx_branch (insn, operands);
3097 }
3098   [(set (attr "length")
3099         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3100                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
3101                       (const_int 2)
3102                       (if_then_else (eq_attr "mcu_mega" "no")
3103                                     (const_int 2)
3104                                     (const_int 4))))
3105    (set_attr "cc" "clobber")])
3106
3107 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
3108 (define_peephole2
3109   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3110                        (const_int 0)))
3111    (set (pc) (if_then_else (ge (cc0) (const_int 0))
3112                            (label_ref (match_operand 1 "" ""))
3113                            (pc)))]
3114   ""
3115   [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
3116                                                 (const_int 1)
3117                                                 (const_int 7))
3118                                (const_int 0))
3119                            (label_ref (match_dup 1))
3120                            (pc)))]
3121   "")
3122
3123 (define_peephole2
3124   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
3125                        (const_int 0)))
3126    (set (pc) (if_then_else (lt (cc0) (const_int 0))
3127                            (label_ref (match_operand 1 "" ""))
3128                            (pc)))]
3129   ""
3130   [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
3131                                                 (const_int 1)
3132                                                 (const_int 7))
3133                                (const_int 0))
3134                            (label_ref (match_dup 1))
3135                            (pc)))]
3136   "")
3137
3138 (define_peephole2
3139   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3140                                   (const_int 0)))
3141               (clobber (match_operand:HI 2 ""))])
3142    (set (pc) (if_then_else (ge (cc0) (const_int 0))
3143                            (label_ref (match_operand 1 "" ""))
3144                            (pc)))]
3145   ""
3146   [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
3147                                (const_int 0))
3148                            (label_ref (match_dup 1))
3149                            (pc)))]
3150   "")
3151
3152 (define_peephole2
3153   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
3154                                   (const_int 0)))
3155               (clobber (match_operand:HI 2 ""))])
3156    (set (pc) (if_then_else (lt (cc0) (const_int 0))
3157                            (label_ref (match_operand 1 "" ""))
3158                            (pc)))]
3159   ""
3160   [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
3161                                (const_int 0))
3162                            (label_ref (match_dup 1))
3163                            (pc)))]
3164   "")
3165
3166 (define_peephole2
3167   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3168                                   (const_int 0)))
3169               (clobber (match_operand:SI 2 ""))])
3170    (set (pc) (if_then_else (ge (cc0) (const_int 0))
3171                            (label_ref (match_operand 1 "" ""))
3172                            (pc)))]
3173   ""
3174   [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
3175                                (const_int 0))
3176                            (label_ref (match_dup 1))
3177                            (pc)))]
3178   "operands[2] = GEN_INT (-2147483647 - 1);")
3179
3180 (define_peephole2
3181   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
3182                                   (const_int 0)))
3183               (clobber (match_operand:SI 2 ""))])
3184    (set (pc) (if_then_else (lt (cc0) (const_int 0))
3185                            (label_ref (match_operand 1 "" ""))
3186                            (pc)))]
3187   ""
3188   [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
3189                                (const_int 0))
3190                            (label_ref (match_dup 1))
3191                            (pc)))]
3192   "operands[2] = GEN_INT (-2147483647 - 1);")
3193
3194 ;; ************************************************************************
3195 ;; Implementation of conditional jumps here.
3196 ;;  Compare with 0 (test) jumps
3197 ;; ************************************************************************
3198
3199 (define_insn "branch"
3200   [(set (pc)
3201         (if_then_else (match_operator 1 "simple_comparison_operator"
3202                         [(cc0)
3203                          (const_int 0)])
3204                       (label_ref (match_operand 0 "" ""))
3205                       (pc)))]
3206   ""
3207   "*
3208    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3209   [(set_attr "type" "branch")
3210    (set_attr "cc" "clobber")])
3211
3212 ;; ****************************************************************
3213 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
3214 ;; Convert them all to proper jumps.
3215 ;; ****************************************************************/
3216
3217 (define_insn "difficult_branch"
3218   [(set (pc)
3219         (if_then_else (match_operator 1 "difficult_comparison_operator"
3220                         [(cc0)
3221                          (const_int 0)])
3222                       (label_ref (match_operand 0 "" ""))
3223                       (pc)))]
3224   ""
3225   "*
3226    return ret_cond_branch (operands[1], avr_jump_mode (operands[0],insn), 0);"
3227   [(set_attr "type" "branch1")
3228    (set_attr "cc" "clobber")])
3229
3230 ;; revers branch
3231
3232 (define_insn "rvbranch"
3233   [(set (pc)
3234         (if_then_else (match_operator 1 "simple_comparison_operator" 
3235                         [(cc0)
3236                          (const_int 0)])
3237                       (pc)
3238                       (label_ref (match_operand 0 "" ""))))]
3239   ""
3240   "*
3241    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3242   [(set_attr "type" "branch1")
3243    (set_attr "cc" "clobber")])
3244
3245 (define_insn "difficult_rvbranch"
3246   [(set (pc)
3247         (if_then_else (match_operator 1 "difficult_comparison_operator" 
3248                         [(cc0)
3249                          (const_int 0)])
3250                       (pc)
3251                       (label_ref (match_operand 0 "" ""))))]
3252   ""
3253   "*
3254    return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);"
3255   [(set_attr "type" "branch")
3256    (set_attr "cc" "clobber")])
3257
3258 ;; **************************************************************************
3259 ;; Unconditional and other jump instructions.
3260
3261 (define_insn "jump"
3262   [(set (pc)
3263         (label_ref (match_operand 0 "" "")))]
3264   ""
3265   "*{
3266   if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
3267     return AS1 (jmp,%x0);
3268   return AS1 (rjmp,%x0);
3269 }"
3270   [(set (attr "length")
3271         (if_then_else (match_operand 0 "symbol_ref_operand" "") 
3272                 (if_then_else (eq_attr "mcu_mega" "no")
3273                               (const_int 1)
3274                               (const_int 2))
3275                 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
3276                                    (le (minus (pc) (match_dup 0)) (const_int 2047)))
3277                               (const_int 1)
3278                               (const_int 2))))
3279    (set_attr "cc" "none")])
3280
3281 ;; call
3282
3283 (define_expand "call"
3284   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3285                    (match_operand:HI 1 "general_operand" ""))
3286              (use (const_int 0))])]
3287   ;; Operand 1 not used on the AVR.
3288   ;; Operand 2 is 1 for tail-call, 0 otherwise.
3289   ""
3290   "")
3291
3292 (define_expand "sibcall"
3293   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
3294                    (match_operand:HI 1 "general_operand" ""))
3295              (use (const_int 1))])]
3296   ;; Operand 1 not used on the AVR.
3297   ;; Operand 2 is 1 for tail-call, 0 otherwise.
3298   ""
3299   "")
3300
3301 ;; call value
3302
3303 (define_expand "call_value"
3304   [(parallel[(set (match_operand 0 "register_operand" "")
3305                   (call (match_operand:HI 1 "call_insn_operand" "")
3306                         (match_operand:HI 2 "general_operand" "")))
3307              (use (const_int 0))])]
3308   ;; Operand 2 not used on the AVR.
3309   ;; Operand 3 is 1 for tail-call, 0 otherwise.
3310   ""
3311   "")
3312
3313 (define_expand "sibcall_value"
3314   [(parallel[(set (match_operand 0 "register_operand" "")
3315                   (call (match_operand:HI 1 "call_insn_operand" "")
3316                         (match_operand:HI 2 "general_operand" "")))
3317              (use (const_int 1))])]
3318   ;; Operand 2 not used on the AVR.
3319   ;; Operand 3 is 1 for tail-call, 0 otherwise.
3320   ""
3321   "")
3322
3323 (define_insn "*call_insn"
3324   [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
3325                    (match_operand:HI 1 "general_operand"           "X,X,X,X"))
3326              (use (match_operand:HI 2 "const_int_operand"          "L,L,P,P"))])]
3327   ;; Operand 1 not used on the AVR.
3328   ;; Operand 2 is 1 for tail-call, 0 otherwise.
3329   ""
3330   "@
3331     %!icall
3332     %~call %x0
3333     %!ijmp
3334     %~jmp %x0"
3335   [(set_attr "cc" "clobber")
3336    (set_attr_alternative "length"
3337                          [(const_int 1)
3338                           (if_then_else (eq_attr "mcu_mega" "yes")
3339                                         (const_int 2)
3340                                         (const_int 1))
3341                           (const_int 1)
3342                           (if_then_else (eq_attr "mcu_mega" "yes")
3343                                         (const_int 2)
3344                                         (const_int 1))])])
3345
3346 (define_insn "*call_value_insn"
3347   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
3348                   (call (mem:HI (match_operand:HI 1 "nonmemory_operand"  "z,s,z,s"))
3349                         (match_operand:HI 2 "general_operand"            "X,X,X,X")))
3350              (use (match_operand:HI 3 "const_int_operand"                "L,L,P,P"))])]
3351   ;; Operand 2 not used on the AVR.
3352   ;; Operand 3 is 1 for tail-call, 0 otherwise.
3353   ""
3354   "@
3355     %!icall
3356     %~call %x1
3357     %!ijmp
3358     %~jmp %x1"
3359   [(set_attr "cc" "clobber")
3360    (set_attr_alternative "length"
3361                          [(const_int 1)
3362                           (if_then_else (eq_attr "mcu_mega" "yes")
3363                                         (const_int 2)
3364                                         (const_int 1))
3365                           (const_int 1)
3366                           (if_then_else (eq_attr "mcu_mega" "yes")
3367                                         (const_int 2)
3368                                         (const_int 1))])])
3369
3370 (define_insn "nop"
3371   [(const_int 0)]
3372   ""
3373   "nop"
3374   [(set_attr "cc" "none")
3375    (set_attr "length" "1")])
3376
3377 ; indirect jump
3378
3379 (define_expand "indirect_jump"
3380   [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
3381   ""
3382   " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
3383     {
3384       operands[0] = copy_to_mode_reg(HImode, operand0);
3385     }"
3386 )
3387
3388 ; indirect jump
3389 (define_insn "*jcindirect_jump"
3390   [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
3391   ""
3392   "%~jmp %x0"
3393   [(set_attr "length" "2")
3394    (set_attr "cc" "none")])
3395
3396 ;;
3397 (define_insn "*njcindirect_jump"
3398   [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
3399   "!AVR_HAVE_EIJMP_EICALL"
3400   "@
3401         ijmp
3402         push %A0\;push %B0\;ret"
3403   [(set_attr "length" "1,3")
3404    (set_attr "cc" "none,none")])
3405
3406 (define_insn "*indirect_jump_avr6"
3407   [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
3408   "AVR_HAVE_EIJMP_EICALL"
3409   "eijmp"
3410   [(set_attr "length" "1")
3411    (set_attr "cc" "none")])
3412
3413 ;; table jump
3414
3415 ;; Table made from "rjmp" instructions for <=8K devices.
3416 (define_insn "*tablejump_rjmp"
3417   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
3418                         UNSPEC_INDEX_JMP))
3419    (use (label_ref (match_operand 1 "" "")))
3420    (clobber (match_dup 0))]
3421   "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)"
3422   "@
3423         ijmp
3424         push %A0\;push %B0\;ret"
3425   [(set_attr "length" "1,3")
3426    (set_attr "cc" "none,none")])
3427
3428 ;; Not a prologue, but similar idea - move the common piece of code to libgcc.
3429 (define_insn "*tablejump_lib"
3430   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3431                         UNSPEC_INDEX_JMP))
3432    (use (label_ref (match_operand 1 "" "")))
3433    (clobber (match_dup 0))]
3434   "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES"
3435   "%~jmp __tablejump2__"
3436   [(set_attr "length" "2")
3437    (set_attr "cc" "clobber")])
3438
3439 (define_insn "*tablejump_enh"
3440   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3441                         UNSPEC_INDEX_JMP))
3442    (use (label_ref (match_operand 1 "" "")))
3443    (clobber (match_dup 0))]
3444   "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX"
3445   "lsl r30
3446         rol r31
3447         lpm __tmp_reg__,Z+
3448         lpm r31,Z
3449         mov r30,__tmp_reg__
3450         %!ijmp"
3451   [(set_attr "length" "6")
3452    (set_attr "cc" "clobber")])
3453
3454 (define_insn "*tablejump"
3455   [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
3456                         UNSPEC_INDEX_JMP))
3457    (use (label_ref (match_operand 1 "" "")))
3458    (clobber (match_dup 0))]
3459   "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL"
3460   "lsl r30
3461         rol r31
3462         lpm
3463         inc r30
3464         push r0
3465         lpm
3466         push r0
3467         ret"
3468   [(set_attr "length" "8")
3469    (set_attr "cc" "clobber")])
3470
3471 (define_expand "casesi"
3472   [(set (match_dup 6)
3473         (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
3474                   (match_operand:HI 1 "register_operand" "")))
3475    (parallel [(set (cc0)
3476                    (compare (match_dup 6)
3477                             (match_operand:HI 2 "register_operand" "")))
3478               (clobber (match_scratch:QI 9 ""))])
3479    
3480    (set (pc)
3481         (if_then_else (gtu (cc0)
3482                            (const_int 0))
3483                       (label_ref (match_operand 4 "" ""))
3484                       (pc)))
3485
3486    (set (match_dup 6)
3487         (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
3488
3489    (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
3490               (use (label_ref (match_dup 3)))
3491               (clobber (match_dup 6))])]
3492   ""
3493   "
3494 {
3495   operands[6] = gen_reg_rtx (HImode);
3496 }")
3497
3498
3499 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3500 ;; This instruction sets Z flag
3501
3502 (define_insn "sez"
3503   [(set (cc0) (const_int 0))]
3504   ""
3505   "sez"
3506   [(set_attr "length" "1")
3507    (set_attr "cc" "compare")])
3508
3509 ;; Clear/set/test a single bit in I/O address space.
3510
3511 (define_insn "*cbi"
3512   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3513         (and:QI (mem:QI (match_dup 0))
3514                 (match_operand:QI 1 "single_zero_operand" "n")))]
3515   "(optimize > 0)"
3516 {
3517   operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
3518   return AS2 (cbi,%m0-0x20,%2);
3519 }
3520   [(set_attr "length" "1")
3521    (set_attr "cc" "none")])
3522
3523 (define_insn "*sbi"
3524   [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
3525         (ior:QI (mem:QI (match_dup 0))
3526                 (match_operand:QI 1 "single_one_operand" "n")))]
3527   "(optimize > 0)"
3528 {
3529   operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
3530   return AS2 (sbi,%m0-0x20,%2);
3531 }
3532   [(set_attr "length" "1")
3533    (set_attr "cc" "none")])
3534
3535 ;; Lower half of the I/O space - use sbic/sbis directly.
3536 (define_insn "*sbix_branch"
3537   [(set (pc)
3538         (if_then_else
3539          (match_operator 0 "eqne_operator"
3540                          [(zero_extract:HI
3541                            (mem:QI (match_operand 1 "low_io_address_operand" "n"))
3542                            (const_int 1)
3543                            (match_operand 2 "const_int_operand" "n"))
3544                           (const_int 0)])
3545          (label_ref (match_operand 3 "" ""))
3546          (pc)))]
3547   "(optimize > 0)"
3548   "* return avr_out_sbxx_branch (insn, operands);"
3549   [(set (attr "length")
3550         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3551                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
3552                       (const_int 2)
3553                       (if_then_else (eq_attr "mcu_mega" "no")
3554                                     (const_int 2)
3555                                     (const_int 4))))
3556    (set_attr "cc" "clobber")])
3557
3558 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
3559 (define_insn "*sbix_branch_bit7"
3560   [(set (pc)
3561         (if_then_else
3562          (match_operator 0 "gelt_operator"
3563                          [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
3564                           (const_int 0)])
3565          (label_ref (match_operand 2 "" ""))
3566          (pc)))]
3567   "(optimize > 0)"
3568 {
3569   operands[3] = operands[2];
3570   operands[2] = GEN_INT (7);
3571   return avr_out_sbxx_branch (insn, operands);
3572 }
3573   [(set (attr "length")
3574         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3575                            (le (minus (pc) (match_dup 2)) (const_int 2046)))
3576                       (const_int 2)
3577                       (if_then_else (eq_attr "mcu_mega" "no")
3578                                     (const_int 2)
3579                                     (const_int 4))))
3580    (set_attr "cc" "clobber")])
3581
3582 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
3583 (define_insn "*sbix_branch_tmp"
3584   [(set (pc)
3585         (if_then_else
3586          (match_operator 0 "eqne_operator"
3587                          [(zero_extract:HI
3588                            (mem:QI (match_operand 1 "high_io_address_operand" "n"))
3589                            (const_int 1)
3590                            (match_operand 2 "const_int_operand" "n"))
3591                           (const_int 0)])
3592          (label_ref (match_operand 3 "" ""))
3593          (pc)))]
3594   "(optimize > 0)"
3595   "* return avr_out_sbxx_branch (insn, operands);"
3596   [(set (attr "length")
3597         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
3598                            (le (minus (pc) (match_dup 3)) (const_int 2045)))
3599                       (const_int 3)
3600                       (if_then_else (eq_attr "mcu_mega" "no")
3601                                     (const_int 3)
3602                                     (const_int 5))))
3603    (set_attr "cc" "clobber")])
3604
3605 (define_insn "*sbix_branch_tmp_bit7"
3606   [(set (pc)
3607         (if_then_else
3608          (match_operator 0 "gelt_operator"
3609                          [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
3610                           (const_int 0)])
3611          (label_ref (match_operand 2 "" ""))
3612          (pc)))]
3613   "(optimize > 0)"
3614 {
3615   operands[3] = operands[2];
3616   operands[2] = GEN_INT (7);
3617   return avr_out_sbxx_branch (insn, operands);
3618 }
3619   [(set (attr "length")
3620         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
3621                            (le (minus (pc) (match_dup 2)) (const_int 2045)))
3622                       (const_int 3)
3623                       (if_then_else (eq_attr "mcu_mega" "no")
3624                                     (const_int 3)
3625                                     (const_int 5))))
3626    (set_attr "cc" "clobber")])
3627
3628 ;; ************************* Peepholes ********************************
3629
3630 (define_peephole
3631   [(set (match_operand:SI 0 "d_register_operand" "")
3632         (plus:SI (match_dup 0)
3633                  (const_int -1)))
3634    (parallel
3635     [(set (cc0)
3636           (compare (match_dup 0)
3637                    (const_int -1)))
3638      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3639    (set (pc)
3640         (if_then_else (ne (cc0) (const_int 0))
3641                       (label_ref (match_operand 2 "" ""))
3642                       (pc)))]
3643   ""
3644   "*
3645 {
3646   CC_STATUS_INIT;
3647   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3648     output_asm_insn (AS2 (sbiw,%0,1) CR_TAB
3649                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3650                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3651   else
3652     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3653                      AS2 (sbc,%B0,__zero_reg__) CR_TAB
3654                      AS2 (sbc,%C0,__zero_reg__) CR_TAB
3655                      AS2 (sbc,%D0,__zero_reg__) \"\\n\", operands);
3656   switch (avr_jump_mode (operands[2],insn))
3657   {
3658     case 1:
3659       return AS1 (brcc,%2);
3660     case 2:
3661       return (AS1 (brcs,.+2) CR_TAB
3662               AS1 (rjmp,%2));
3663   }
3664   return (AS1 (brcs,.+4) CR_TAB
3665           AS1 (jmp,%2));
3666 }")
3667
3668 (define_peephole
3669   [(set (match_operand:HI 0 "d_register_operand" "")
3670         (plus:HI (match_dup 0)
3671                  (const_int -1)))
3672    (parallel
3673     [(set (cc0)
3674           (compare (match_dup 0)
3675                    (const_int 65535)))
3676      (clobber (match_operand:QI 1 "d_register_operand" ""))])
3677    (set (pc)
3678         (if_then_else (ne (cc0) (const_int 0))
3679                       (label_ref (match_operand 2 "" ""))
3680                       (pc)))]
3681   ""
3682   "*
3683 {
3684   CC_STATUS_INIT;
3685   if (test_hard_reg_class (ADDW_REGS, operands[0]))
3686     output_asm_insn (AS2 (sbiw,%0,1), operands);
3687   else
3688     output_asm_insn (AS2 (subi,%A0,1) CR_TAB
3689                      AS2 (sbc,%B0,__zero_reg__) \"\\n\", operands);
3690   switch (avr_jump_mode (operands[2],insn))
3691   {
3692     case 1:
3693       return AS1 (brcc,%2);
3694     case 2:
3695       return (AS1 (brcs,.+2) CR_TAB
3696               AS1 (rjmp,%2));
3697   }
3698   return (AS1 (brcs,.+4) CR_TAB
3699           AS1 (jmp,%2));
3700 }")
3701
3702 (define_peephole
3703   [(set (match_operand:QI 0 "d_register_operand" "")
3704         (plus:QI (match_dup 0)
3705                  (const_int -1)))
3706    (set (cc0)
3707         (compare (match_dup 0)
3708                  (const_int -1)))
3709    (set (pc)
3710         (if_then_else (ne (cc0) (const_int 0))
3711                       (label_ref (match_operand 1 "" ""))
3712                       (pc)))]
3713   ""
3714   "*
3715 {
3716   CC_STATUS_INIT;
3717   cc_status.value1 = operands[0];
3718   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
3719   output_asm_insn (AS2 (subi,%A0,1), operands);
3720   switch (avr_jump_mode (operands[1],insn))
3721   {
3722     case 1:
3723       return AS1 (brcc,%1);
3724     case 2:
3725       return (AS1 (brcs,.+2) CR_TAB
3726               AS1 (rjmp,%1));
3727   }
3728   return (AS1 (brcs,.+4) CR_TAB
3729           AS1 (jmp,%1));
3730 }")
3731
3732 (define_peephole
3733   [(set (cc0)
3734         (compare (match_operand:QI 0 "register_operand" "")
3735                  (const_int 0)))
3736    (set (pc)
3737         (if_then_else (eq (cc0) (const_int 0))
3738                       (label_ref (match_operand 1 "" ""))
3739                       (pc)))]
3740   "jump_over_one_insn_p (insn, operands[1])"
3741   "cpse %0,__zero_reg__")
3742
3743 (define_peephole
3744   [(set (cc0)
3745         (compare (match_operand:QI 0 "register_operand" "")
3746                  (match_operand:QI 1 "register_operand" "")))
3747    (set (pc)
3748         (if_then_else (eq (cc0) (const_int 0))
3749                       (label_ref (match_operand 2 "" ""))
3750                       (pc)))]
3751   "jump_over_one_insn_p (insn, operands[2])"
3752   "cpse %0,%1")
3753
3754 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
3755 ;;prologue/epilogue support instructions
3756
3757 (define_insn "popqi"
3758   [(set (match_operand:QI 0 "register_operand" "=r")
3759         (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
3760   ""
3761   "pop %0"
3762   [(set_attr "cc" "none")
3763    (set_attr "length" "1")])
3764
3765 ;; Enable Interrupts
3766 (define_insn "enable_interrupt"
3767   [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
3768   ""
3769   "sei"
3770   [(set_attr "length" "1")
3771    (set_attr "cc" "none")])
3772
3773 ;; Disable Interrupts
3774 (define_insn "disable_interrupt"
3775   [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
3776   ""
3777   "cli"
3778   [(set_attr "length" "1")
3779    (set_attr "cc" "none")])
3780
3781 ;;  Library prologue saves
3782 (define_insn "call_prologue_saves"
3783   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
3784    (match_operand:HI 0 "immediate_operand" "")
3785    (set (reg:HI REG_SP) (minus:HI 
3786                            (reg:HI REG_SP)
3787                            (match_operand:HI 1 "immediate_operand" "")))
3788    (use (reg:HI REG_X))
3789    (clobber (reg:HI REG_Z))]
3790   ""
3791   "ldi r30,lo8(gs(1f))
3792         ldi r31,hi8(gs(1f))
3793         %~jmp __prologue_saves__+((18 - %0) * 2)
3794 1:"
3795   [(set_attr_alternative "length"
3796                          [(if_then_else (eq_attr "mcu_mega" "yes")
3797                                         (const_int 6)
3798                                         (const_int 5))])
3799   (set_attr "cc" "clobber")
3800   ])
3801   
3802 ;  epilogue  restores using library
3803 (define_insn "epilogue_restores"
3804   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
3805    (set (reg:HI REG_Y ) (plus:HI 
3806                            (reg:HI REG_Y)
3807                            (match_operand:HI 0 "immediate_operand" ""))) 
3808    (set (reg:HI REG_SP) (reg:HI REG_Y))
3809    (clobber  (reg:QI REG_Z))]
3810   ""
3811   "ldi r30, lo8(%0)
3812         %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
3813   [(set_attr_alternative "length"
3814                          [(if_then_else (eq_attr "mcu_mega" "yes")
3815                                         (const_int 3)
3816                                         (const_int 2))])
3817   (set_attr "cc" "clobber")
3818   ])
3819   
3820 ; return
3821 (define_insn "return"
3822   [(return)]
3823   "reload_completed && avr_simple_epilogue ()"
3824   "ret"
3825   [(set_attr "cc" "none")
3826    (set_attr "length" "1")])
3827
3828 (define_insn "return_from_epilogue"
3829   [(return)]
3830   "(reload_completed 
3831     && cfun->machine 
3832     && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
3833     && !cfun->machine->is_naked)"
3834   "ret"
3835   [(set_attr "cc" "none")
3836    (set_attr "length" "1")])
3837
3838 (define_insn "return_from_interrupt_epilogue"
3839   [(return)]
3840   "(reload_completed 
3841     && cfun->machine 
3842     && (cfun->machine->is_interrupt || cfun->machine->is_signal)
3843     && !cfun->machine->is_naked)"
3844   "reti"
3845   [(set_attr "cc" "none")
3846    (set_attr "length" "1")])
3847
3848 (define_insn "return_from_naked_epilogue"
3849   [(return)]
3850   "(reload_completed 
3851     && cfun->machine 
3852     && cfun->machine->is_naked)"
3853   ""
3854   [(set_attr "cc" "none")
3855    (set_attr "length" "0")])
3856
3857 (define_expand "prologue"
3858   [(const_int 0)]
3859   ""
3860   "
3861   {
3862     expand_prologue (); 
3863     DONE;
3864   }")
3865
3866 (define_expand "epilogue"
3867   [(const_int 0)]
3868   ""
3869   {
3870     expand_epilogue (false /* sibcall_p */);
3871     DONE;
3872   })
3873
3874 (define_expand "sibcall_epilogue"
3875   [(const_int 0)]
3876   ""
3877   {
3878     expand_epilogue (true /* sibcall_p */);
3879     DONE;
3880   })
3881
3882 ;; Some instructions resp. instruction sequences available
3883 ;; via builtins.
3884
3885 (define_insn "delay_cycles_1"
3886   [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
3887                      (const_int 1)]
3888                     UNSPECV_DELAY_CYCLES)
3889    (clobber (match_scratch:QI 1 "=&d"))]
3890   ""
3891   "ldi %1,lo8(%0)
3892         1: dec %1
3893         brne 1b"
3894   [(set_attr "length" "3")
3895    (set_attr "cc" "clobber")])
3896
3897 (define_insn "delay_cycles_2"
3898   [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
3899                      (const_int 2)]
3900                     UNSPECV_DELAY_CYCLES)
3901    (clobber (match_scratch:HI 1 "=&w"))]
3902   ""
3903   "ldi %A1,lo8(%0)
3904         ldi %B1,hi8(%0)
3905         1: sbiw %A1,1
3906         brne 1b"
3907   [(set_attr "length" "4")
3908    (set_attr "cc" "clobber")])
3909
3910 (define_insn "delay_cycles_3"
3911   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3912                      (const_int 3)]
3913                     UNSPECV_DELAY_CYCLES)
3914    (clobber (match_scratch:QI 1 "=&d"))
3915    (clobber (match_scratch:QI 2 "=&d"))
3916    (clobber (match_scratch:QI 3 "=&d"))]
3917   ""
3918   "ldi %1,lo8(%0)
3919         ldi %2,hi8(%0)
3920         ldi %3,hlo8(%0)
3921         1: subi %1,1
3922         sbci %2,0
3923         sbci %3,0
3924         brne 1b"
3925   [(set_attr "length" "7")
3926    (set_attr "cc" "clobber")])
3927
3928 (define_insn "delay_cycles_4"
3929   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
3930                      (const_int 4)]
3931                     UNSPECV_DELAY_CYCLES)
3932    (clobber (match_scratch:QI 1 "=&d"))
3933    (clobber (match_scratch:QI 2 "=&d"))
3934    (clobber (match_scratch:QI 3 "=&d"))
3935    (clobber (match_scratch:QI 4 "=&d"))]
3936   ""
3937   "ldi %1,lo8(%0)
3938         ldi %2,hi8(%0)
3939         ldi %3,hlo8(%0)
3940         ldi %4,hhi8(%0)
3941         1: subi %1,1
3942         sbci %2,0
3943         sbci %3,0
3944         sbci %4,0
3945         brne 1b"
3946   [(set_attr "length" "9")
3947    (set_attr "cc" "clobber")])
3948
3949
3950 ;; Parity
3951
3952 (define_expand "parityhi2"
3953   [(set (reg:HI 24)
3954         (match_operand:HI 1 "register_operand" ""))
3955    (set (reg:HI 24)
3956         (parity:HI (reg:HI 24)))
3957    (set (match_operand:HI 0 "register_operand" "")
3958         (reg:HI 24))]
3959   ""
3960   "")
3961
3962 (define_expand "paritysi2"
3963   [(set (reg:SI 22)
3964         (match_operand:SI 1 "register_operand" ""))
3965    (set (reg:HI 24)
3966         (parity:HI (reg:SI 22)))
3967    (set (match_dup 2)
3968         (reg:HI 24))
3969    (set (match_operand:SI 0 "register_operand" "")
3970         (zero_extend:SI (match_dup 2)))]
3971   ""
3972   {
3973     operands[2] = gen_reg_rtx (HImode);
3974   })
3975
3976 (define_insn "*parityhi2.libgcc"
3977   [(set (reg:HI 24)
3978         (parity:HI (reg:HI 24)))]
3979   ""
3980   "%~call __parityhi2"
3981   [(set_attr "type" "xcall")
3982    (set_attr "cc" "clobber")])
3983
3984 (define_insn "*parityqihi2.libgcc"
3985   [(set (reg:HI 24)
3986         (parity:HI (reg:QI 24)))]
3987   ""
3988   "%~call __parityqi2"
3989   [(set_attr "type" "xcall")
3990    (set_attr "cc" "clobber")])
3991
3992 (define_insn "*paritysihi2.libgcc"
3993   [(set (reg:HI 24)
3994         (parity:HI (reg:SI 22)))]
3995   ""
3996   "%~call __paritysi2"
3997   [(set_attr "type" "xcall")
3998    (set_attr "cc" "clobber")])
3999
4000
4001 ;; Popcount
4002
4003 (define_expand "popcounthi2"
4004   [(set (reg:HI 24)
4005         (match_operand:HI 1 "register_operand" ""))
4006    (set (reg:HI 24)
4007         (popcount:HI (reg:HI 24)))
4008    (set (match_operand:HI 0 "register_operand" "")
4009         (reg:HI 24))]
4010   ""
4011   "")
4012
4013 (define_expand "popcountsi2"
4014   [(set (reg:SI 22)
4015         (match_operand:SI 1 "register_operand" ""))
4016    (set (reg:HI 24)
4017         (popcount:HI (reg:SI 22)))
4018    (set (match_dup 2)
4019         (reg:HI 24))
4020    (set (match_operand:SI 0 "register_operand" "")
4021         (zero_extend:SI (match_dup 2)))]
4022   ""
4023   {
4024     operands[2] = gen_reg_rtx (HImode);
4025   })
4026
4027 (define_insn "*popcounthi2.libgcc"
4028   [(set (reg:HI 24)
4029         (popcount:HI (reg:HI 24)))]
4030   ""
4031   "%~call __popcounthi2"
4032   [(set_attr "type" "xcall")
4033    (set_attr "cc" "clobber")])
4034
4035 (define_insn "*popcountsi2.libgcc"
4036   [(set (reg:HI 24)
4037         (popcount:HI (reg:SI 22)))]
4038   ""
4039   "%~call __popcountsi2"
4040   [(set_attr "type" "xcall")
4041    (set_attr "cc" "clobber")])
4042
4043 (define_insn "*popcountqi2.libgcc"
4044   [(set (reg:QI 24)
4045         (popcount:QI (reg:QI 24)))]
4046   ""
4047   "%~call __popcountqi2"
4048   [(set_attr "type" "xcall")
4049    (set_attr "cc" "clobber")])
4050
4051 (define_insn_and_split "*popcountqihi2.libgcc"
4052   [(set (reg:HI 24)
4053         (popcount:HI (reg:QI 24)))]
4054   ""
4055   "#"
4056   ""
4057   [(set (reg:QI 24)
4058         (popcount:QI (reg:QI 24)))
4059    (set (reg:QI 25)
4060         (const_int 0))]
4061   "")
4062
4063 ;; Count Leading Zeros
4064
4065 (define_expand "clzhi2"
4066   [(set (reg:HI 24)
4067         (match_operand:HI 1 "register_operand" ""))
4068    (parallel [(set (reg:HI 24)
4069                    (clz:HI (reg:HI 24)))
4070               (clobber (reg:QI 26))])
4071    (set (match_operand:HI 0 "register_operand" "")
4072         (reg:HI 24))]
4073   ""
4074   "")
4075
4076 (define_expand "clzsi2"
4077   [(set (reg:SI 22)
4078         (match_operand:SI 1 "register_operand" ""))
4079    (parallel [(set (reg:HI 24)
4080                    (clz:HI (reg:SI 22)))
4081               (clobber (reg:QI 26))])
4082    (set (match_dup 2)
4083         (reg:HI 24))
4084    (set (match_operand:SI 0 "register_operand" "")
4085         (zero_extend:SI (match_dup 2)))]
4086   ""
4087   {
4088     operands[2] = gen_reg_rtx (HImode);
4089   })
4090
4091 (define_insn "*clzhi2.libgcc"
4092   [(set (reg:HI 24)
4093         (clz:HI (reg:HI 24)))
4094    (clobber (reg:QI 26))]
4095   ""
4096   "%~call __clzhi2"
4097   [(set_attr "type" "xcall")
4098    (set_attr "cc" "clobber")])
4099
4100 (define_insn "*clzsihi2.libgcc"
4101   [(set (reg:HI 24)
4102         (clz:HI (reg:SI 22)))
4103    (clobber (reg:QI 26))]
4104   ""
4105   "%~call __clzsi2"
4106   [(set_attr "type" "xcall")
4107    (set_attr "cc" "clobber")])
4108
4109 ;; Count Trailing Zeros
4110
4111 (define_expand "ctzhi2"
4112   [(set (reg:HI 24)
4113         (match_operand:HI 1 "register_operand" ""))
4114    (parallel [(set (reg:HI 24)
4115                    (ctz:HI (reg:HI 24)))
4116               (clobber (reg:QI 26))])
4117    (set (match_operand:HI 0 "register_operand" "")
4118         (reg:HI 24))]
4119   ""
4120   "")
4121
4122 (define_expand "ctzsi2"
4123   [(set (reg:SI 22)
4124         (match_operand:SI 1 "register_operand" ""))
4125    (parallel [(set (reg:HI 24)
4126                    (ctz:HI (reg:SI 22)))
4127               (clobber (reg:QI 22))
4128               (clobber (reg:QI 26))])
4129    (set (match_dup 2)
4130         (reg:HI 24))
4131    (set (match_operand:SI 0 "register_operand" "")
4132         (zero_extend:SI (match_dup 2)))]
4133   ""
4134   {
4135     operands[2] = gen_reg_rtx (HImode);
4136   })
4137
4138 (define_insn "*ctzhi2.libgcc"
4139   [(set (reg:HI 24)
4140         (ctz:HI (reg:HI 24)))
4141    (clobber (reg:QI 26))]
4142   ""
4143   "%~call __ctzhi2"
4144   [(set_attr "type" "xcall")
4145    (set_attr "cc" "clobber")])
4146
4147 (define_insn "*ctzsihi2.libgcc"
4148   [(set (reg:HI 24)
4149         (ctz:HI (reg:SI 22)))
4150    (clobber (reg:QI 22))
4151    (clobber (reg:QI 26))]
4152   ""
4153   "%~call __ctzsi2"
4154   [(set_attr "type" "xcall")
4155    (set_attr "cc" "clobber")])
4156
4157 ;; Find First Set
4158
4159 (define_expand "ffshi2"
4160   [(set (reg:HI 24)
4161         (match_operand:HI 1 "register_operand" ""))
4162    (parallel [(set (reg:HI 24)
4163                    (ffs:HI (reg:HI 24)))
4164               (clobber (reg:QI 26))])
4165    (set (match_operand:HI 0 "register_operand" "")
4166         (reg:HI 24))]
4167   ""
4168   "")
4169
4170 (define_expand "ffssi2"
4171   [(set (reg:SI 22)
4172         (match_operand:SI 1 "register_operand" ""))
4173    (parallel [(set (reg:HI 24)
4174                    (ffs:HI (reg:SI 22)))
4175               (clobber (reg:QI 22))
4176               (clobber (reg:QI 26))])
4177    (set (match_dup 2)
4178         (reg:HI 24))
4179    (set (match_operand:SI 0 "register_operand" "")
4180         (zero_extend:SI (match_dup 2)))]
4181   ""
4182   {
4183     operands[2] = gen_reg_rtx (HImode);
4184   })
4185
4186 (define_insn "*ffshi2.libgcc"
4187   [(set (reg:HI 24)
4188         (ffs:HI (reg:HI 24)))
4189    (clobber (reg:QI 26))]
4190   ""
4191   "%~call __ffshi2"
4192   [(set_attr "type" "xcall")
4193    (set_attr "cc" "clobber")])
4194
4195 (define_insn "*ffssihi2.libgcc"
4196   [(set (reg:HI 24)
4197         (ffs:HI (reg:SI 22)))
4198    (clobber (reg:QI 22))
4199    (clobber (reg:QI 26))]
4200   ""
4201   "%~call __ffssi2"
4202   [(set_attr "type" "xcall")
4203    (set_attr "cc" "clobber")])
4204
4205 ;; Copysign
4206
4207 (define_insn "copysignsf3"
4208   [(set (match_operand:SF 0 "register_operand"             "=r")
4209         (unspec:SF [(match_operand:SF 1 "register_operand"  "0")
4210                     (match_operand:SF 2 "register_operand"  "r")]
4211                    UNSPEC_COPYSIGN))]
4212   ""
4213   "bst %D2,7\;bld %D0,7"
4214   [(set_attr "length" "2")
4215    (set_attr "cc" "none")])
4216   
4217 ;; Swap Bytes (change byte-endianess)
4218
4219 (define_expand "bswapsi2"
4220   [(set (reg:SI 22)
4221         (match_operand:SI 1 "register_operand" ""))
4222    (set (reg:SI 22)
4223         (bswap:SI (reg:SI 22)))
4224    (set (match_operand:SI 0 "register_operand" "")
4225         (reg:SI 22))]
4226   ""
4227   "")
4228
4229 (define_insn "*bswapsi2.libgcc"
4230   [(set (reg:SI 22)
4231         (bswap:SI (reg:SI 22)))]
4232   ""
4233   "%~call __bswapsi2"
4234   [(set_attr "type" "xcall")
4235    (set_attr "cc" "clobber")])
4236
4237
4238 ;; CPU instructions
4239
4240 ;; NOP taking 1 or 2 Ticks 
4241 (define_insn "nopv"
4242   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")] 
4243                     UNSPECV_NOP)]
4244   ""
4245   "@
4246         nop
4247         rjmp ."
4248   [(set_attr "length" "1")
4249    (set_attr "cc" "none")])
4250
4251 ;; SLEEP
4252 (define_insn "sleep"
4253   [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
4254   ""
4255   "sleep"
4256   [(set_attr "length" "1")
4257    (set_attr "cc" "none")])
4258  
4259 ;; WDR
4260 (define_insn "wdr"
4261   [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
4262   ""
4263   "wdr"
4264   [(set_attr "length" "1")
4265    (set_attr "cc" "none")])
4266   
4267 ;; FMUL
4268 (define_expand "fmul"
4269   [(set (reg:QI 24)
4270         (match_operand:QI 1 "register_operand" ""))
4271    (set (reg:QI 25)
4272         (match_operand:QI 2 "register_operand" ""))
4273    (parallel [(set (reg:HI 22)
4274                    (unspec:HI [(reg:QI 24)
4275                                (reg:QI 25)] UNSPEC_FMUL))
4276               (clobber (reg:HI 24))])
4277    (set (match_operand:HI 0 "register_operand" "")
4278         (reg:HI 22))]
4279   ""
4280   {
4281     if (AVR_HAVE_MUL)
4282       {
4283         emit_insn (gen_fmul_insn (operand0, operand1, operand2));
4284         DONE;
4285       }
4286   })
4287
4288 (define_insn "fmul_insn"
4289   [(set (match_operand:HI 0 "register_operand" "=r")
4290         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4291                     (match_operand:QI 2 "register_operand" "a")]
4292                    UNSPEC_FMUL))]
4293   "AVR_HAVE_MUL"
4294   "fmul %1,%2
4295         movw %0,r0
4296         clr __zero_reg__"
4297   [(set_attr "length" "3")
4298    (set_attr "cc" "clobber")])
4299
4300 (define_insn "*fmul.call"
4301   [(set (reg:HI 22)
4302         (unspec:HI [(reg:QI 24)
4303                     (reg:QI 25)] UNSPEC_FMUL))
4304    (clobber (reg:HI 24))]
4305   "!AVR_HAVE_MUL"
4306   "%~call __fmul"
4307   [(set_attr "type" "xcall")
4308    (set_attr "cc" "clobber")])
4309
4310 ;; FMULS
4311 (define_expand "fmuls"
4312   [(set (reg:QI 24)
4313         (match_operand:QI 1 "register_operand" ""))
4314    (set (reg:QI 25)
4315         (match_operand:QI 2 "register_operand" ""))
4316    (parallel [(set (reg:HI 22)
4317                    (unspec:HI [(reg:QI 24)
4318                                (reg:QI 25)] UNSPEC_FMULS))
4319               (clobber (reg:HI 24))])
4320    (set (match_operand:HI 0 "register_operand" "")
4321         (reg:HI 22))]
4322   ""
4323   {
4324     if (AVR_HAVE_MUL)
4325       {
4326         emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
4327         DONE;
4328       }
4329   })
4330
4331 (define_insn "fmuls_insn"
4332   [(set (match_operand:HI 0 "register_operand" "=r")
4333         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4334                     (match_operand:QI 2 "register_operand" "a")]
4335                    UNSPEC_FMULS))]
4336   "AVR_HAVE_MUL"
4337   "fmuls %1,%2
4338         movw %0,r0
4339         clr __zero_reg__"
4340   [(set_attr "length" "3")
4341    (set_attr "cc" "clobber")])
4342
4343 (define_insn "*fmuls.call"
4344   [(set (reg:HI 22)
4345         (unspec:HI [(reg:QI 24)
4346                     (reg:QI 25)] UNSPEC_FMULS))
4347    (clobber (reg:HI 24))]
4348   "!AVR_HAVE_MUL"
4349   "%~call __fmuls"
4350   [(set_attr "type" "xcall")
4351    (set_attr "cc" "clobber")])
4352
4353 ;; FMULSU
4354 (define_expand "fmulsu"
4355   [(set (reg:QI 24)
4356         (match_operand:QI 1 "register_operand" ""))
4357    (set (reg:QI 25)
4358         (match_operand:QI 2 "register_operand" ""))
4359    (parallel [(set (reg:HI 22)
4360                    (unspec:HI [(reg:QI 24)
4361                                (reg:QI 25)] UNSPEC_FMULSU))
4362               (clobber (reg:HI 24))])
4363    (set (match_operand:HI 0 "register_operand" "")
4364         (reg:HI 22))]
4365   ""
4366   {
4367     if (AVR_HAVE_MUL)
4368       {
4369         emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
4370         DONE;
4371       }
4372   })
4373
4374 (define_insn "fmulsu_insn"
4375   [(set (match_operand:HI 0 "register_operand" "=r")
4376         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
4377                     (match_operand:QI 2 "register_operand" "a")]
4378                    UNSPEC_FMULSU))]
4379   "AVR_HAVE_MUL"
4380   "fmulsu %1,%2
4381         movw %0,r0
4382         clr __zero_reg__"
4383   [(set_attr "length" "3")
4384    (set_attr "cc" "clobber")])
4385
4386 (define_insn "*fmulsu.call"
4387   [(set (reg:HI 22)
4388         (unspec:HI [(reg:QI 24)
4389                     (reg:QI 25)] UNSPEC_FMULSU))
4390    (clobber (reg:HI 24))]
4391   "!AVR_HAVE_MUL"
4392   "%~call __fmulsu"
4393   [(set_attr "type" "xcall")
4394    (set_attr "cc" "clobber")])
4395
4396 \f
4397 ;; Some combiner patterns dealing with bits.
4398 ;; See PR42210
4399
4400 ;; Move bit $3.0 into bit $0.$4
4401 (define_insn "*movbitqi.1-6.a"
4402   [(set (match_operand:QI 0 "register_operand"                               "=r")
4403         (ior:QI (and:QI (match_operand:QI 1 "register_operand"                "0")
4404                         (match_operand:QI 2 "single_zero_operand"             "n"))
4405                 (and:QI (ashift:QI (match_operand:QI 3 "register_operand"     "r")
4406                                    (match_operand:QI 4 "const_0_to_7_operand" "n"))
4407                         (match_operand:QI 5 "single_one_operand"              "n"))))]
4408   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
4409    && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
4410   "bst %3,0\;bld %0,%4"
4411   [(set_attr "length" "2")
4412    (set_attr "cc" "none")])
4413
4414 ;; Move bit $3.0 into bit $0.$4
4415 ;; Variation of above. Unfortunately, there is no canonicalized representation
4416 ;; of moving around bits.  So what we see here depends on how user writes down
4417 ;; bit manipulations.
4418 (define_insn "*movbitqi.1-6.b"
4419   [(set (match_operand:QI 0 "register_operand"                            "=r")
4420         (ior:QI (and:QI (match_operand:QI 1 "register_operand"             "0")
4421                         (match_operand:QI 2 "single_zero_operand"          "n"))
4422                 (ashift:QI (and:QI (match_operand:QI 3 "register_operand"  "r")
4423                                    (const_int 1))
4424                            (match_operand:QI 4 "const_0_to_7_operand"      "n"))))]
4425   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4426   "bst %3,0\;bld %0,%4"
4427   [(set_attr "length" "2")
4428    (set_attr "cc" "none")])
4429
4430 ;; Move bit $3.0 into bit $0.0.
4431 ;; For bit 0, combiner generates slightly different pattern.
4432 (define_insn "*movbitqi.0"
4433   [(set (match_operand:QI 0 "register_operand"                     "=r")
4434         (ior:QI (and:QI (match_operand:QI 1 "register_operand"      "0")
4435                         (match_operand:QI 2 "single_zero_operand"   "n"))
4436                 (and:QI (match_operand:QI 3 "register_operand"      "r")
4437                         (const_int 1))))]
4438   "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
4439   "bst %3,0\;bld %0,0"
4440   [(set_attr "length" "2")
4441    (set_attr "cc" "none")])
4442
4443 ;; Move bit $2.0 into bit $0.7.
4444 ;; For bit 7, combiner generates slightly different pattern
4445 (define_insn "*movbitqi.7"
4446   [(set (match_operand:QI 0 "register_operand"                      "=r")
4447         (ior:QI (and:QI (match_operand:QI 1 "register_operand"       "0")
4448                         (const_int 127))
4449                 (ashift:QI (match_operand:QI 2 "register_operand"    "r")
4450                            (const_int 7))))]
4451   ""
4452   "bst %2,0\;bld %0,7"
4453   [(set_attr "length" "2")
4454    (set_attr "cc" "none")])
4455
4456 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
4457 ;; and input/output match.  We provide a special pattern for this, because
4458 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
4459 ;; operation on I/O is atomic.
4460 (define_insn "*insv.io"
4461   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
4462                          (const_int 1)
4463                          (match_operand:QI 1 "const_0_to_7_operand"        "n,n,n"))
4464         (match_operand:QI 2 "nonmemory_operand"                            "L,P,r"))]
4465   ""
4466   "@
4467         cbi %m0-0x20,%1
4468         sbi %m0-0x20,%1
4469         sbrc %2,0\;sbi %m0-0x20,%1\;sbrs %2,0\;cbi %m0-0x20,%1"
4470   [(set_attr "length" "1,1,4")
4471    (set_attr "cc" "none")])
4472
4473 (define_insn "*insv.not.io"
4474   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4475                          (const_int 1)
4476                          (match_operand:QI 1 "const_0_to_7_operand"        "n"))
4477         (not:QI (match_operand:QI 2 "register_operand"                     "r")))]
4478   ""
4479   "sbrs %2,0\;sbi %m0-0x20,%1\;sbrc %2,0\;cbi %m0-0x20,%1"
4480   [(set_attr "length" "4")
4481    (set_attr "cc" "none")])
4482
4483 ;; The insv expander.
4484 ;; We only support 1-bit inserts
4485 (define_expand "insv"
4486   [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
4487                          (match_operand:QI 1 "const1_operand" "")        ; width
4488                          (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
4489         (match_operand:QI 3 "nonmemory_operand" ""))]
4490   "optimize"
4491   "")
4492
4493 ;; Insert bit $2.0 into $0.$1
4494 (define_insn "*insv.reg"
4495   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r,d,d,l,l")
4496                          (const_int 1)
4497                          (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
4498         (match_operand:QI 2 "nonmemory_operand"                     "r,L,P,L,P"))]
4499   ""
4500   "@
4501         bst %2,0\;bld %0,%1
4502         andi %0,lo8(~(1<<%1))
4503         ori %0,lo8(1<<%1)
4504         clt\;bld %0,%1
4505         set\;bld %0,%1"
4506   [(set_attr "length" "2,1,1,2,2")
4507    (set_attr "cc" "none,set_zn,set_zn,none,none")])
4508
4509 \f
4510 ;; Some combine patterns that try to fix bad code when a value is composed
4511 ;; from byte parts like in PR27663.
4512 ;; The patterns give some release but the code still is not optimal,
4513 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
4514 ;; That switch obfuscates things here and in many other places.
4515
4516 (define_insn_and_split "*ior<mode>qi.byte0"
4517   [(set (match_operand:HISI 0 "register_operand"                 "=r")
4518         (ior:HISI
4519          (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4520          (match_operand:HISI 2 "register_operand"                 "0")))]
4521   ""
4522   "#"
4523   "reload_completed"
4524   [(set (match_dup 3)
4525         (ior:QI (match_dup 3)
4526                 (match_dup 1)))]
4527   {
4528     operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
4529   })
4530
4531 (define_insn_and_split "*ior<mode>qi.byte1-3"
4532   [(set (match_operand:HISI 0 "register_operand"                              "=r")
4533         (ior:HISI
4534          (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
4535                       (match_operand:QI 2 "const_8_16_24_operand"              "n"))
4536          (match_operand:HISI 3 "register_operand"                              "0")))]
4537   "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
4538   "#"
4539   "&& reload_completed"
4540   [(set (match_dup 4)
4541         (ior:QI (match_dup 4)
4542                 (match_dup 1)))]
4543   {
4544     int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
4545     operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
4546   })
4547
4548 (define_expand "extzv"
4549   [(set (match_operand:QI 0 "register_operand" "")
4550         (zero_extract:QI (match_operand:QI 1 "register_operand"  "")
4551                          (match_operand:QI 2 "const1_operand" "")
4552                          (match_operand:QI 3 "const_0_to_7_operand" "")))]
4553   ""
4554   "")
4555
4556 (define_insn "*extzv"
4557   [(set (match_operand:QI 0 "register_operand"                   "=*d,*d,*d,*d,r")
4558         (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,0,r")
4559                          (const_int 1)
4560                          (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
4561   ""
4562   "@
4563         andi %0,1
4564         mov %0,%1\;andi %0,1
4565         lsr %0\;andi %0,1
4566         swap %0\;andi %0,1
4567         bst %1,%2\;clr %0\;bld %0,0"
4568   [(set_attr "length" "1,2,2,2,3")
4569    (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
4570
4571 (define_insn_and_split "*extzv.qihi1"
4572   [(set (match_operand:HI 0 "register_operand"                     "=r")
4573         (zero_extract:HI (match_operand:QI 1 "register_operand"     "r")
4574                          (const_int 1)
4575                          (match_operand:QI 2 "const_0_to_7_operand" "n")))]
4576   ""
4577   "#"
4578   ""
4579   [(set (match_dup 3)
4580         (zero_extract:QI (match_dup 1)
4581                          (const_int 1)
4582                          (match_dup 2)))
4583    (set (match_dup 4)
4584         (const_int 0))]
4585   {
4586     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4587     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4588   })
4589
4590 (define_insn_and_split "*extzv.qihi2"
4591   [(set (match_operand:HI 0 "register_operand"                      "=r")
4592         (zero_extend:HI 
4593          (zero_extract:QI (match_operand:QI 1 "register_operand"     "r")
4594                           (const_int 1)
4595                           (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
4596   ""
4597   "#"
4598   ""
4599   [(set (match_dup 3)
4600         (zero_extract:QI (match_dup 1)
4601                          (const_int 1)
4602                          (match_dup 2)))
4603    (set (match_dup 4)
4604         (const_int 0))]
4605   {
4606     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4607     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4608   })