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