OSDN Git Service

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