OSDN Git Service

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