OSDN Git Service

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