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