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