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