OSDN Git Service

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