qimode_for_vec_perm
[official-gcc.git] / gcc / config / avr / avr.md
blob14f9298f30541f774ad70883cb2bd4c110ba93d6
1 ;;   Machine description for GNU compiler,
2 ;;   for ATMEL AVR micro controllers.
3 ;;   Copyright (C) 1998-2017 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    && (!AVR_HAVE_MOVW
3372        || const0_rtx == operands[1])"
3373   [(set (match_dup 2) (match_dup 3))
3374    (set (match_dup 4) (match_dup 5))]
3375   {
3376     operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3377     operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
3378     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3379     operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3380   })
3382 ;; Split andhi3, andpsi3, andsi3.
3383 ;; Split iorhi3, iorpsi3, iorsi3.
3384 ;; Split xorhi3, xorpsi3, xorsi3.
3385 (define_split
3386   [(parallel [(set (match_operand:HISI 0 "register_operand")
3387                    (bitop:HISI (match_dup 0)
3388                                (match_operand:HISI 1 "register_operand")))
3389               (clobber (scratch:QI))])]
3390   "optimize
3391    && reload_completed"
3392   [(const_int 1)]
3393   {
3394     for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
3395       {
3396         rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
3397         rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
3398         emit_insn (gen_<code>qi3 (dst, dst, src));
3399       }
3400     DONE;
3401   })
3404 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3405 ;; swap
3407 (define_expand "rotlqi3"
3408   [(set (match_operand:QI 0 "register_operand" "")
3409         (rotate:QI (match_operand:QI 1 "register_operand" "")
3410                    (match_operand:QI 2 "const_0_to_7_operand" "")))]
3411   ""
3412   {
3413     if (!CONST_INT_P (operands[2]))
3414       FAIL;
3416     operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3417   })
3419 ;; Expander used by __builtin_avr_swap
3420 (define_expand "rotlqi3_4"
3421   [(set (match_operand:QI 0 "register_operand" "")
3422         (rotate:QI (match_operand:QI 1 "register_operand" "")
3423                    (const_int 4)))])
3425 (define_insn "*rotlqi3"
3426   [(set (match_operand:QI 0 "register_operand"               "=r,r,r  ,r  ,r  ,r  ,r  ,r")
3427         (rotate:QI (match_operand:QI 1 "register_operand"     "0,0,0  ,0  ,0  ,0  ,0  ,0")
3428                    (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3429   ""
3430   "@
3431         lsl %0\;adc %0,__zero_reg__
3432         lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3433         swap %0\;bst %0,0\;ror %0\;bld %0,7
3434         swap %0
3435         swap %0\;lsl %0\;adc %0,__zero_reg__
3436         swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3437         bst %0,0\;ror %0\;bld %0,7
3438         " ; empty
3439   [(set_attr "length" "2,4,4,1,3,5,3,0")
3440    (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3442 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3443 ;; a whole number of bytes.  The split creates the appropriate moves and
3444 ;; considers all overlap situations.
3446 ;; HImode does not need scratch.  Use attribute for this constraint.
3448 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3449 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3451 ;; "rotlhi3"
3452 ;; "rotlpsi3"
3453 ;; "rotlsi3"
3454 (define_expand "rotl<mode>3"
3455   [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3456                    (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3457                                 (match_operand:HISI 2 "const_int_operand" "")))
3458               (clobber (match_dup 3))])]
3459   ""
3460   {
3461     int offset;
3463     if (!CONST_INT_P (operands[2]))
3464       FAIL;
3466     offset = INTVAL (operands[2]);
3468     if (0 == offset % 8)
3469       {
3470         if (AVR_HAVE_MOVW && 0 == offset % 16)
3471           operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3472         else
3473           operands[3] = gen_rtx_SCRATCH (QImode);
3474       }
3475     else if (offset == 1
3476              || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3477       {
3478         /*; Support rotate left/right by 1  */
3480         emit_move_insn (operands[0],
3481                         gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3482         DONE;
3483       }
3484     else
3485       FAIL;
3486   })
3488 (define_insn "*rotlhi2.1"
3489   [(set (match_operand:HI 0 "register_operand"           "=r")
3490         (rotate:HI (match_operand:HI 1 "register_operand" "0")
3491                    (const_int 1)))]
3492   ""
3493   "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3494   [(set_attr "length" "3")
3495    (set_attr "cc" "clobber")])
3497 (define_insn "*rotlhi2.15"
3498   [(set (match_operand:HI 0 "register_operand"           "=r")
3499         (rotate:HI (match_operand:HI 1 "register_operand" "0")
3500                    (const_int 15)))]
3501   ""
3502   "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3503   [(set_attr "length" "4")
3504    (set_attr "cc" "clobber")])
3506 (define_insn "*rotlpsi2.1"
3507   [(set (match_operand:PSI 0 "register_operand"            "=r")
3508         (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3509                     (const_int 1)))]
3510   ""
3511   "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3512   [(set_attr "length" "4")
3513    (set_attr "cc" "clobber")])
3515 (define_insn "*rotlpsi2.23"
3516   [(set (match_operand:PSI 0 "register_operand"            "=r")
3517         (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3518                     (const_int 23)))]
3519   ""
3520   "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3521   [(set_attr "length" "5")
3522    (set_attr "cc" "clobber")])
3524 (define_insn "*rotlsi2.1"
3525   [(set (match_operand:SI 0 "register_operand"           "=r")
3526         (rotate:SI (match_operand:SI 1 "register_operand" "0")
3527                    (const_int 1)))]
3528   ""
3529   "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3530   [(set_attr "length" "5")
3531    (set_attr "cc" "clobber")])
3533 (define_insn "*rotlsi2.31"
3534   [(set (match_operand:SI 0 "register_operand"           "=r")
3535         (rotate:SI (match_operand:SI 1 "register_operand" "0")
3536                    (const_int 31)))]
3537   ""
3538   "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3539   [(set_attr "length" "6")
3540    (set_attr "cc" "clobber")])
3542 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3543 ;; The best we can do is use early clobber alternative "#&r" so that
3544 ;; completely non-overlapping operands dont get a scratch but # so register
3545 ;; allocation does not prefer non-overlapping.
3548 ;; Split word aligned rotates using scratch that is mode dependent.
3550 ;; "*rotwhi"
3551 ;; "*rotwsi"
3552 (define_insn_and_split "*rotw<mode>"
3553   [(set (match_operand:HISI 0 "register_operand"             "=r,r,#&r")
3554         (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3555                      (match_operand 2 "const_int_operand"     "n,n,n")))
3556    (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3557   "AVR_HAVE_MOVW
3558    && CONST_INT_P (operands[2])
3559    && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3560    && 0 == INTVAL (operands[2]) % 16"
3561   "#"
3562   "&& reload_completed"
3563   [(const_int 0)]
3564   {
3565     avr_rotate_bytes (operands);
3566     DONE;
3567   })
3570 ;; Split byte aligned rotates using scratch that is always QI mode.
3572 ;; "*rotbhi"
3573 ;; "*rotbpsi"
3574 ;; "*rotbsi"
3575 (define_insn_and_split "*rotb<mode>"
3576   [(set (match_operand:HISI 0 "register_operand"             "=r,r,#&r")
3577         (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3578                      (match_operand 2 "const_int_operand"     "n,n,n")))
3579    (clobber (match_scratch:QI 3 "=<rotx>"))]
3580   "CONST_INT_P (operands[2])
3581    && (8 == INTVAL (operands[2]) % 16
3582        || ((!AVR_HAVE_MOVW
3583             || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3584            && 0 == INTVAL (operands[2]) % 16))"
3585   "#"
3586   "&& reload_completed"
3587   [(const_int 0)]
3588   {
3589     avr_rotate_bytes (operands);
3590     DONE;
3591   })
3594 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3595 ;; arithmetic shift left
3597 ;; "ashlqi3"
3598 ;; "ashlqq3"  "ashluqq3"
3599 (define_expand "ashl<mode>3"
3600   [(set (match_operand:ALL1 0 "register_operand" "")
3601         (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3602                      (match_operand:QI 2 "nop_general_operand" "")))])
3604 (define_split ; ashlqi3_const4
3605   [(set (match_operand:ALL1 0 "d_register_operand" "")
3606         (ashift:ALL1 (match_dup 0)
3607                      (const_int 4)))]
3608   ""
3609   [(set (match_dup 1)
3610         (rotate:QI (match_dup 1)
3611                    (const_int 4)))
3612    (set (match_dup 1)
3613         (and:QI (match_dup 1)
3614                 (const_int -16)))]
3615   {
3616     operands[1] = avr_to_int_mode (operands[0]);
3617   })
3619 (define_split ; ashlqi3_const5
3620   [(set (match_operand:ALL1 0 "d_register_operand" "")
3621         (ashift:ALL1 (match_dup 0)
3622                      (const_int 5)))]
3623   ""
3624   [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3625    (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3626    (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3627   {
3628     operands[1] = avr_to_int_mode (operands[0]);
3629   })
3631 (define_split ; ashlqi3_const6
3632   [(set (match_operand:ALL1 0 "d_register_operand" "")
3633         (ashift:ALL1 (match_dup 0)
3634                      (const_int 6)))]
3635   ""
3636   [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3637    (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3638    (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3639   {
3640     operands[1] = avr_to_int_mode (operands[0]);
3641   })
3643 ;; "*ashlqi3"
3644 ;; "*ashlqq3"  "*ashluqq3"
3645 (define_insn "*ashl<mode>3"
3646   [(set (match_operand:ALL1 0 "register_operand"              "=r,r,r,r,!d,r,r")
3647         (ashift:ALL1 (match_operand:ALL1 1 "register_operand"  "0,0,0,0,0 ,0,0")
3648                      (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3649   ""
3650   {
3651     return ashlqi3_out (insn, operands, NULL);
3652   }
3653   [(set_attr "length" "5,0,1,2,4,6,9")
3654    (set_attr "adjust_len" "ashlqi")
3655    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3657 (define_insn "ashl<mode>3"
3658   [(set (match_operand:ALL2 0 "register_operand"              "=r,r,r,r,r,r,r")
3659         (ashift:ALL2 (match_operand:ALL2 1 "register_operand"  "0,0,0,r,0,0,0")
3660                      (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3661   ""
3662   {
3663     return ashlhi3_out (insn, operands, NULL);
3664   }
3665   [(set_attr "length" "6,0,2,2,4,10,10")
3666    (set_attr "adjust_len" "ashlhi")
3667    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3670 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3671 ;; like char1 = char2 << char3.  Only the low-byte is needed in that situation.
3673 ;; "*ashluqihiqi3"
3674 ;; "*ashlsqihiqi3"
3675 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3676   [(set (match_operand:QI 0 "register_operand"                                     "=r")
3677         (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3678                               (match_operand:QI 2 "register_operand"                "r"))
3679                    0))]
3680   ""
3681   "#"
3682   ""
3683   [(set (match_dup 0)
3684         (ashift:QI (match_dup 1)
3685                    (match_dup 2)))])
3687 ;; ??? Combiner does not recognize that it could split the following insn;
3688 ;;     presumably because he has no register handy?
3690 ;; "*ashluqihiqi3.mem"
3691 ;; "*ashlsqihiqi3.mem"
3692 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3693   [(set (match_operand:QI 0 "memory_operand" "=m")
3694         (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3695                               (match_operand:QI 2 "register_operand" "r"))
3696                    0))]
3697   "!reload_completed"
3698   { gcc_unreachable(); }
3699   "&& 1"
3700   [(set (match_dup 3)
3701         (ashift:QI (match_dup 1)
3702                    (match_dup 2)))
3703    (set (match_dup 0)
3704         (match_dup 3))]
3705   {
3706     operands[3] = gen_reg_rtx (QImode);
3707   })
3709 ;; Similar.
3711 (define_insn_and_split "*ashlhiqi3"
3712   [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3713         (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3714                               (match_operand:QI 2 "register_operand" "r")) 0))]
3715   "!reload_completed"
3716   { gcc_unreachable(); }
3717   "&& 1"
3718   [(set (match_dup 4)
3719         (ashift:QI (match_dup 3)
3720                    (match_dup 2)))
3721    (set (match_dup 0)
3722         (match_dup 4))]
3723   {
3724     operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3725     operands[4] = gen_reg_rtx (QImode);
3726   })
3728 ;; High part of 16-bit shift is unused after the instruction:
3729 ;; No need to compute it, map to 8-bit shift.
3731 (define_peephole2
3732   [(set (match_operand:HI 0 "register_operand" "")
3733         (ashift:HI (match_dup 0)
3734                    (match_operand:QI 1 "register_operand" "")))]
3735   ""
3736   [(set (match_dup 2)
3737         (ashift:QI (match_dup 2)
3738                    (match_dup 1)))
3739    (clobber (match_dup 3))]
3740   {
3741     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3743     if (!peep2_reg_dead_p (1, operands[3]))
3744       FAIL;
3746     operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3747   })
3750 ;; "ashlsi3"
3751 ;; "ashlsq3"  "ashlusq3"
3752 ;; "ashlsa3"  "ashlusa3"
3753 (define_insn "ashl<mode>3"
3754   [(set (match_operand:ALL4 0 "register_operand"                "=r,r,r,r,r,r,r")
3755         (ashift:ALL4 (match_operand:ALL4 1 "register_operand"    "0,0,0,r,0,0,0")
3756                      (match_operand:QI 2 "nop_general_operand"   "r,L,P,O,K,n,Qm")))]
3757   ""
3758   {
3759     return ashlsi3_out (insn, operands, NULL);
3760   }
3761   [(set_attr "length" "8,0,4,4,8,10,12")
3762    (set_attr "adjust_len" "ashlsi")
3763    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3765 ;; Optimize if a scratch register from LD_REGS happens to be available.
3767 (define_peephole2 ; ashlqi3_l_const4
3768   [(set (match_operand:ALL1 0 "l_register_operand" "")
3769         (ashift:ALL1 (match_dup 0)
3770                      (const_int 4)))
3771    (match_scratch:QI 1 "d")]
3772   ""
3773   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3774    (set (match_dup 1) (const_int -16))
3775    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3776   {
3777     operands[2] = avr_to_int_mode (operands[0]);
3778   })
3780 (define_peephole2 ; ashlqi3_l_const5
3781   [(set (match_operand:ALL1 0 "l_register_operand" "")
3782         (ashift:ALL1 (match_dup 0)
3783                      (const_int 5)))
3784    (match_scratch:QI 1 "d")]
3785   ""
3786   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3787    (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3788    (set (match_dup 1) (const_int -32))
3789    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3790   {
3791     operands[2] = avr_to_int_mode (operands[0]);
3792   })
3794 (define_peephole2 ; ashlqi3_l_const6
3795   [(set (match_operand:ALL1 0 "l_register_operand" "")
3796         (ashift:ALL1 (match_dup 0)
3797                      (const_int 6)))
3798    (match_scratch:QI 1 "d")]
3799   ""
3800   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3801    (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3802    (set (match_dup 1) (const_int -64))
3803    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3804   {
3805     operands[2] = avr_to_int_mode (operands[0]);
3806   })
3808 (define_peephole2
3809   [(match_scratch:QI 3 "d")
3810    (set (match_operand:ALL2 0 "register_operand" "")
3811         (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3812                      (match_operand:QI 2 "const_int_operand" "")))]
3813   ""
3814   [(parallel [(set (match_dup 0)
3815                    (ashift:ALL2 (match_dup 1)
3816                                 (match_dup 2)))
3817               (clobber (match_dup 3))])])
3819 ;; "*ashlhi3_const"
3820 ;; "*ashlhq3_const"  "*ashluhq3_const"
3821 ;; "*ashlha3_const"  "*ashluha3_const"
3822 (define_insn "*ashl<mode>3_const"
3823   [(set (match_operand:ALL2 0 "register_operand"              "=r,r,r,r,r")
3824         (ashift:ALL2 (match_operand:ALL2 1 "register_operand"  "0,0,r,0,0")
3825                      (match_operand:QI 2 "const_int_operand"   "L,P,O,K,n")))
3826    (clobber (match_scratch:QI 3                               "=X,X,X,X,&d"))]
3827   "reload_completed"
3828   {
3829     return ashlhi3_out (insn, operands, NULL);
3830   }
3831   [(set_attr "length" "0,2,2,4,10")
3832    (set_attr "adjust_len" "ashlhi")
3833    (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3835 (define_peephole2
3836   [(match_scratch:QI 3 "d")
3837    (set (match_operand:ALL4 0 "register_operand" "")
3838         (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3839                      (match_operand:QI 2 "const_int_operand" "")))]
3840   ""
3841   [(parallel [(set (match_dup 0)
3842                    (ashift:ALL4 (match_dup 1)
3843                                 (match_dup 2)))
3844               (clobber (match_dup 3))])])
3846 ;; "*ashlsi3_const"
3847 ;; "*ashlsq3_const"  "*ashlusq3_const"
3848 ;; "*ashlsa3_const"  "*ashlusa3_const"
3849 (define_insn "*ashl<mode>3_const"
3850   [(set (match_operand:ALL4 0 "register_operand"              "=r,r,r,r")
3851         (ashift:ALL4 (match_operand:ALL4 1 "register_operand"  "0,0,r,0")
3852                      (match_operand:QI 2 "const_int_operand"   "L,P,O,n")))
3853    (clobber (match_scratch:QI 3                               "=X,X,X,&d"))]
3854   "reload_completed"
3855   {
3856     return ashlsi3_out (insn, operands, NULL);
3857   }
3858   [(set_attr "length" "0,4,4,10")
3859    (set_attr "adjust_len" "ashlsi")
3860    (set_attr "cc" "none,set_n,clobber,clobber")])
3862 (define_expand "ashlpsi3"
3863   [(parallel [(set (match_operand:PSI 0 "register_operand"             "")
3864                    (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3865                                (match_operand:QI 2 "nonmemory_operand" "")))
3866               (clobber (scratch:QI))])]
3867   ""
3868   {
3869     if (AVR_HAVE_MUL
3870         && CONST_INT_P (operands[2]))
3871       {
3872         if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3873           {
3874             rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3875             emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3876             DONE;
3877           }
3878         else if (optimize_insn_for_speed_p ()
3879                  && INTVAL (operands[2]) != 16
3880                  && IN_RANGE (INTVAL (operands[2]), 9, 22))
3881           {
3882             rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3883             emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3884             DONE;
3885           }
3886       }
3887   })
3889 (define_insn "*ashlpsi3"
3890   [(set (match_operand:PSI 0 "register_operand"             "=r,r,r,r")
3891         (ashift:PSI (match_operand:PSI 1 "register_operand"  "0,0,r,0")
3892                     (match_operand:QI 2 "nonmemory_operand"  "r,P,O,n")))
3893    (clobber (match_scratch:QI 3                             "=X,X,X,&d"))]
3894   ""
3895   {
3896     return avr_out_ashlpsi3 (insn, operands, NULL);
3897   }
3898   [(set_attr "adjust_len" "ashlpsi")
3899    (set_attr "cc" "clobber")])
3901 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3902 ;; arithmetic shift right
3904 ;; "ashrqi3"
3905 ;; "ashrqq3"  "ashruqq3"
3906 (define_insn "ashr<mode>3"
3907   [(set (match_operand:ALL1 0 "register_operand"                  "=r,r,r,r,r          ,r      ,r")
3908         (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand"    "0,0,0,0,0          ,0      ,0")
3909                        (match_operand:QI 2 "nop_general_operand"   "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3910   ""
3911   {
3912     return ashrqi3_out (insn, operands, NULL);
3913   }
3914   [(set_attr "length" "5,0,1,2,5,4,9")
3915    (set_attr "adjust_len" "ashrqi")
3916    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3918 ;; "ashrhi3"
3919 ;; "ashrhq3"  "ashruhq3"
3920 ;; "ashrha3"  "ashruha3"
3921 (define_insn "ashr<mode>3"
3922   [(set (match_operand:ALL2 0 "register_operand"                "=r,r,r,r,r,r,r")
3923         (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand"  "0,0,0,r,0,0,0")
3924                        (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3925   ""
3926   {
3927     return ashrhi3_out (insn, operands, NULL);
3928   }
3929   [(set_attr "length" "6,0,2,4,4,10,10")
3930    (set_attr "adjust_len" "ashrhi")
3931    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3933 (define_insn "ashrpsi3"
3934   [(set (match_operand:PSI 0 "register_operand"                 "=r,r,r,r,r")
3935         (ashiftrt:PSI (match_operand:PSI 1 "register_operand"    "0,0,0,r,0")
3936                       (match_operand:QI 2 "nonmemory_operand"    "r,P,K,O,n")))
3937    (clobber (match_scratch:QI 3                                 "=X,X,X,X,&d"))]
3938   ""
3939   {
3940     return avr_out_ashrpsi3 (insn, operands, NULL);
3941   }
3942   [(set_attr "adjust_len" "ashrpsi")
3943    (set_attr "cc" "clobber")])
3945 ;; "ashrsi3"
3946 ;; "ashrsq3"  "ashrusq3"
3947 ;; "ashrsa3"  "ashrusa3"
3948 (define_insn "ashr<mode>3"
3949   [(set (match_operand:ALL4 0 "register_operand"                  "=r,r,r,r,r,r,r")
3950         (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand"    "0,0,0,r,0,0,0")
3951                        (match_operand:QI 2 "nop_general_operand"   "r,L,P,O,K,n,Qm")))]
3952   ""
3953   {
3954     return ashrsi3_out (insn, operands, NULL);
3955   }
3956   [(set_attr "length" "8,0,4,6,8,10,12")
3957    (set_attr "adjust_len" "ashrsi")
3958    (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3960 ;; Optimize if a scratch register from LD_REGS happens to be available.
3962 (define_peephole2
3963   [(match_scratch:QI 3 "d")
3964    (set (match_operand:ALL2 0 "register_operand" "")
3965         (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3966                        (match_operand:QI 2 "const_int_operand" "")))]
3967   ""
3968   [(parallel [(set (match_dup 0)
3969                    (ashiftrt:ALL2 (match_dup 1)
3970                                   (match_dup 2)))
3971               (clobber (match_dup 3))])])
3973 ;; "*ashrhi3_const"
3974 ;; "*ashrhq3_const"  "*ashruhq3_const"
3975 ;; "*ashrha3_const"  "*ashruha3_const"
3976 (define_insn "*ashr<mode>3_const"
3977   [(set (match_operand:ALL2 0 "register_operand"                "=r,r,r,r,r")
3978         (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand"  "0,0,r,0,0")
3979                        (match_operand:QI 2 "const_int_operand"   "L,P,O,K,n")))
3980    (clobber (match_scratch:QI 3                                 "=X,X,X,X,&d"))]
3981   "reload_completed"
3982   {
3983     return ashrhi3_out (insn, operands, NULL);
3984   }
3985   [(set_attr "length" "0,2,4,4,10")
3986    (set_attr "adjust_len" "ashrhi")
3987    (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3989 (define_peephole2
3990   [(match_scratch:QI 3 "d")
3991    (set (match_operand:ALL4 0 "register_operand" "")
3992         (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3993                        (match_operand:QI 2 "const_int_operand" "")))]
3994   ""
3995   [(parallel [(set (match_dup 0)
3996                    (ashiftrt:ALL4 (match_dup 1)
3997                                   (match_dup 2)))
3998               (clobber (match_dup 3))])])
4000 ;; "*ashrsi3_const"
4001 ;; "*ashrsq3_const"  "*ashrusq3_const"
4002 ;; "*ashrsa3_const"  "*ashrusa3_const"
4003 (define_insn "*ashr<mode>3_const"
4004   [(set (match_operand:ALL4 0 "register_operand"                "=r,r,r,r")
4005         (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand"  "0,0,r,0")
4006                        (match_operand:QI 2 "const_int_operand"   "L,P,O,n")))
4007    (clobber (match_scratch:QI 3                                 "=X,X,X,&d"))]
4008   "reload_completed"
4009   {
4010     return ashrsi3_out (insn, operands, NULL);
4011   }
4012   [(set_attr "length" "0,4,4,10")
4013    (set_attr "adjust_len" "ashrsi")
4014    (set_attr "cc" "none,clobber,set_n,clobber")])
4016 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
4017 ;; logical shift right
4019 ;; "lshrqi3"
4020 ;; "lshrqq3" "lshruqq3"
4021 (define_expand "lshr<mode>3"
4022   [(set (match_operand:ALL1 0 "register_operand" "")
4023         (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
4024                        (match_operand:QI 2 "nop_general_operand" "")))])
4026 (define_split   ; lshrqi3_const4
4027   [(set (match_operand:ALL1 0 "d_register_operand" "")
4028         (lshiftrt:ALL1 (match_dup 0)
4029                        (const_int 4)))]
4030   ""
4031   [(set (match_dup 1)
4032         (rotate:QI (match_dup 1)
4033                    (const_int 4)))
4034    (set (match_dup 1)
4035         (and:QI (match_dup 1)
4036                 (const_int 15)))]
4037   {
4038     operands[1] = avr_to_int_mode (operands[0]);
4039   })
4041 (define_split   ; lshrqi3_const5
4042   [(set (match_operand:ALL1 0 "d_register_operand" "")
4043         (lshiftrt:ALL1 (match_dup 0)
4044                        (const_int 5)))]
4045   ""
4046   [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4047    (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
4048    (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
4049   {
4050     operands[1] = avr_to_int_mode (operands[0]);
4051   })
4053 (define_split   ; lshrqi3_const6
4054   [(set (match_operand:QI 0 "d_register_operand" "")
4055         (lshiftrt:QI (match_dup 0)
4056                      (const_int 6)))]
4057   ""
4058   [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4059    (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
4060    (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
4061   {
4062     operands[1] = avr_to_int_mode (operands[0]);
4063   })
4065 ;; "*lshrqi3"
4066 ;; "*lshrqq3"
4067 ;; "*lshruqq3"
4068 (define_insn "*lshr<mode>3"
4069   [(set (match_operand:ALL1 0 "register_operand"                  "=r,r,r,r,!d,r,r")
4070         (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand"    "0,0,0,0,0 ,0,0")
4071                        (match_operand:QI 2 "nop_general_operand"   "r,L,P,K,n ,n,Qm")))]
4072   ""
4073   {
4074     return lshrqi3_out (insn, operands, NULL);
4075   }
4076   [(set_attr "length" "5,0,1,2,4,6,9")
4077    (set_attr "adjust_len" "lshrqi")
4078    (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
4080 ;; "lshrhi3"
4081 ;; "lshrhq3"  "lshruhq3"
4082 ;; "lshrha3"  "lshruha3"
4083 (define_insn "lshr<mode>3"
4084   [(set (match_operand:ALL2 0 "register_operand"                "=r,r,r,r,r,r,r")
4085         (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand"    "0,0,0,r,0,0,0")
4086                        (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4087   ""
4088   {
4089     return lshrhi3_out (insn, operands, NULL);
4090   }
4091   [(set_attr "length" "6,0,2,2,4,10,10")
4092    (set_attr "adjust_len" "lshrhi")
4093    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4095 (define_insn "lshrpsi3"
4096   [(set (match_operand:PSI 0 "register_operand"                 "=r,r,r,r,r")
4097         (lshiftrt:PSI (match_operand:PSI 1 "register_operand"    "0,0,r,0,0")
4098                       (match_operand:QI 2 "nonmemory_operand"    "r,P,O,K,n")))
4099    (clobber (match_scratch:QI 3                                 "=X,X,X,X,&d"))]
4100   ""
4101   {
4102     return avr_out_lshrpsi3 (insn, operands, NULL);
4103   }
4104   [(set_attr "adjust_len" "lshrpsi")
4105    (set_attr "cc" "clobber")])
4107 ;; "lshrsi3"
4108 ;; "lshrsq3"  "lshrusq3"
4109 ;; "lshrsa3"  "lshrusa3"
4110 (define_insn "lshr<mode>3"
4111   [(set (match_operand:ALL4 0 "register_operand"                  "=r,r,r,r,r,r,r")
4112         (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand"    "0,0,0,r,0,0,0")
4113                        (match_operand:QI 2 "nop_general_operand"   "r,L,P,O,K,n,Qm")))]
4114   ""
4115   {
4116     return lshrsi3_out (insn, operands, NULL);
4117   }
4118   [(set_attr "length" "8,0,4,4,8,10,12")
4119    (set_attr "adjust_len" "lshrsi")
4120    (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4122 ;; Optimize if a scratch register from LD_REGS happens to be available.
4124 (define_peephole2 ; lshrqi3_l_const4
4125   [(set (match_operand:ALL1 0 "l_register_operand" "")
4126         (lshiftrt:ALL1 (match_dup 0)
4127                        (const_int 4)))
4128    (match_scratch:QI 1 "d")]
4129   ""
4130   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4131    (set (match_dup 1) (const_int 15))
4132    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4133   {
4134     operands[2] = avr_to_int_mode (operands[0]);
4135   })
4137 (define_peephole2 ; lshrqi3_l_const5
4138   [(set (match_operand:ALL1 0 "l_register_operand" "")
4139         (lshiftrt:ALL1 (match_dup 0)
4140                        (const_int 5)))
4141    (match_scratch:QI 1 "d")]
4142   ""
4143   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4144    (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
4145    (set (match_dup 1) (const_int 7))
4146    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4147   {
4148     operands[2] = avr_to_int_mode (operands[0]);
4149   })
4151 (define_peephole2 ; lshrqi3_l_const6
4152   [(set (match_operand:ALL1 0 "l_register_operand" "")
4153         (lshiftrt:ALL1 (match_dup 0)
4154                        (const_int 6)))
4155    (match_scratch:QI 1 "d")]
4156   ""
4157   [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4158    (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
4159    (set (match_dup 1) (const_int 3))
4160    (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4161   {
4162     operands[2] = avr_to_int_mode (operands[0]);
4163   })
4165 (define_peephole2
4166   [(match_scratch:QI 3 "d")
4167    (set (match_operand:ALL2 0 "register_operand" "")
4168         (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
4169                        (match_operand:QI 2 "const_int_operand" "")))]
4170   ""
4171   [(parallel [(set (match_dup 0)
4172                    (lshiftrt:ALL2 (match_dup 1)
4173                                   (match_dup 2)))
4174               (clobber (match_dup 3))])])
4176 ;; "*lshrhi3_const"
4177 ;; "*lshrhq3_const"  "*lshruhq3_const"
4178 ;; "*lshrha3_const"  "*lshruha3_const"
4179 (define_insn "*lshr<mode>3_const"
4180   [(set (match_operand:ALL2 0 "register_operand"                "=r,r,r,r,r")
4181         (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand"  "0,0,r,0,0")
4182                        (match_operand:QI 2 "const_int_operand"   "L,P,O,K,n")))
4183    (clobber (match_scratch:QI 3                                 "=X,X,X,X,&d"))]
4184   "reload_completed"
4185   {
4186     return lshrhi3_out (insn, operands, NULL);
4187   }
4188   [(set_attr "length" "0,2,2,4,10")
4189    (set_attr "adjust_len" "lshrhi")
4190    (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
4192 (define_peephole2
4193   [(match_scratch:QI 3 "d")
4194    (set (match_operand:ALL4 0 "register_operand" "")
4195         (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
4196                        (match_operand:QI 2 "const_int_operand" "")))]
4197   ""
4198   [(parallel [(set (match_dup 0)
4199                    (lshiftrt:ALL4 (match_dup 1)
4200                                   (match_dup 2)))
4201               (clobber (match_dup 3))])])
4203 ;; "*lshrsi3_const"
4204 ;; "*lshrsq3_const"  "*lshrusq3_const"
4205 ;; "*lshrsa3_const"  "*lshrusa3_const"
4206 (define_insn "*lshr<mode>3_const"
4207   [(set (match_operand:ALL4 0 "register_operand"               "=r,r,r,r")
4208         (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4209                        (match_operand:QI 2 "const_int_operand"  "L,P,O,n")))
4210    (clobber (match_scratch:QI 3                                "=X,X,X,&d"))]
4211   "reload_completed"
4212   {
4213     return lshrsi3_out (insn, operands, NULL);
4214   }
4215   [(set_attr "length" "0,4,4,10")
4216    (set_attr "adjust_len" "lshrsi")
4217    (set_attr "cc" "none,clobber,clobber,clobber")])
4219 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
4220 ;; abs
4222 (define_insn "absqi2"
4223   [(set (match_operand:QI 0 "register_operand" "=r")
4224         (abs:QI (match_operand:QI 1 "register_operand" "0")))]
4225   ""
4226   "sbrc %0,7
4227         neg %0"
4228   [(set_attr "length" "2")
4229    (set_attr "cc" "clobber")])
4232 (define_insn "abssf2"
4233   [(set (match_operand:SF 0 "register_operand" "=d,r")
4234         (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4235   ""
4236   "@
4237         andi %D0,0x7f
4238         clt\;bld %D0,7"
4239   [(set_attr "length" "1,2")
4240    (set_attr "cc" "set_n,clobber")])
4242 ;; 0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x  0 - x
4243 ;; neg
4245 (define_insn "negqi2"
4246   [(set (match_operand:QI 0 "register_operand" "=r")
4247         (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4248   ""
4249   "neg %0"
4250   [(set_attr "length" "1")
4251    (set_attr "cc" "set_vzn")])
4253 (define_insn "*negqihi2"
4254   [(set (match_operand:HI 0 "register_operand"                        "=r")
4255         (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4256   ""
4257   "clr %B0\;neg %A0\;brge .+2\;com %B0"
4258   [(set_attr "length" "4")
4259    (set_attr "cc" "set_n")])
4261 (define_insn "neghi2"
4262   [(set (match_operand:HI 0 "register_operand"        "=r,&r")
4263         (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4264   ""
4265   "@
4266         neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4267         clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4268   [(set_attr "length" "3,4")
4269    (set_attr "cc" "set_czn")])
4271 (define_insn "negpsi2"
4272   [(set (match_operand:PSI 0 "register_operand"        "=!d,r,&r")
4273         (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4274   ""
4275   "@
4276         com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4277         com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4278         clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4279   [(set_attr "length" "5,6,6")
4280    (set_attr "cc" "set_czn,set_n,set_czn")])
4282 (define_insn "negsi2"
4283   [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r,&r")
4284         (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4285   ""
4286   "@
4287         com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4288         com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4289         clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4290         clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4291   [(set_attr "length" "7,8,8,7")
4292    (set_attr "isa"    "*,*,mov,movw")
4293    (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4295 (define_insn "negsf2"
4296   [(set (match_operand:SF 0 "register_operand" "=d,r")
4297         (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4298   ""
4299   "@
4300         subi %D0,0x80
4301         bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4302   [(set_attr "length" "1,4")
4303    (set_attr "cc" "set_n,set_n")])
4305 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4306 ;; not
4308 (define_insn "one_cmplqi2"
4309   [(set (match_operand:QI 0 "register_operand" "=r")
4310         (not:QI (match_operand:QI 1 "register_operand" "0")))]
4311   ""
4312   "com %0"
4313   [(set_attr "length" "1")
4314    (set_attr "cc" "set_czn")])
4316 (define_insn "one_cmplhi2"
4317   [(set (match_operand:HI 0 "register_operand" "=r")
4318         (not:HI (match_operand:HI 1 "register_operand" "0")))]
4319   ""
4320   "com %0
4321         com %B0"
4322   [(set_attr "length" "2")
4323    (set_attr "cc" "set_n")])
4325 (define_insn "one_cmplpsi2"
4326   [(set (match_operand:PSI 0 "register_operand" "=r")
4327         (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4328   ""
4329   "com %0\;com %B0\;com %C0"
4330   [(set_attr "length" "3")
4331    (set_attr "cc" "set_n")])
4333 (define_insn "one_cmplsi2"
4334   [(set (match_operand:SI 0 "register_operand" "=r")
4335         (not:SI (match_operand:SI 1 "register_operand" "0")))]
4336   ""
4337   "com %0
4338         com %B0
4339         com %C0
4340         com %D0"
4341   [(set_attr "length" "4")
4342    (set_attr "cc" "set_n")])
4344 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4345 ;; sign extend
4347 ;; We keep combiner from inserting hard registers into the input of sign- and
4348 ;; zero-extends.  A hard register in the input operand is not wanted because
4349 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4350 ;; hard register that overlaps these clobbers won't be combined to a widening
4351 ;; multiplication.  There is no need for combine to propagate hard registers,
4352 ;; register allocation can do it just as well.
4354 (define_insn "extendqihi2"
4355   [(set (match_operand:HI 0 "register_operand" "=r,r")
4356         (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4357   ""
4358   {
4359     return avr_out_sign_extend (insn, operands, NULL);
4360   }
4361   [(set_attr "length" "3,4")
4362    (set_attr "adjust_len" "sext")
4363    (set_attr "cc" "set_n")])
4365 (define_insn "extendqipsi2"
4366   [(set (match_operand:PSI 0 "register_operand" "=r,r")
4367         (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4368   ""
4369   {
4370     return avr_out_sign_extend (insn, operands, NULL);
4371   }
4372   [(set_attr "length" "4,5")
4373    (set_attr "adjust_len" "sext")
4374    (set_attr "cc" "set_n")])
4376 (define_insn "extendqisi2"
4377   [(set (match_operand:SI 0 "register_operand" "=r,r")
4378         (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4379   ""
4380   {
4381     return avr_out_sign_extend (insn, operands, NULL);
4382   }
4383   [(set_attr "length" "5,6")
4384    (set_attr "adjust_len" "sext")
4385    (set_attr "cc" "set_n")])
4387 (define_insn "extendhipsi2"
4388   [(set (match_operand:PSI 0 "register_operand"                               "=r,r")
4389         (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4390   ""
4391   {
4392     return avr_out_sign_extend (insn, operands, NULL);
4393   }
4394   [(set_attr "length" "3,5")
4395    (set_attr "adjust_len" "sext")
4396    (set_attr "cc" "set_n")])
4398 (define_insn "extendhisi2"
4399   [(set (match_operand:SI 0 "register_operand"                               "=r,r")
4400         (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4401   ""
4402   {
4403     return avr_out_sign_extend (insn, operands, NULL);
4404   }
4405   [(set_attr "length" "4,6")
4406    (set_attr "adjust_len" "sext")
4407    (set_attr "cc" "set_n")])
4409 (define_insn "extendpsisi2"
4410   [(set (match_operand:SI 0 "register_operand"                                "=r")
4411         (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4412   ""
4413   {
4414     return avr_out_sign_extend (insn, operands, NULL);
4415   }
4416   [(set_attr "length" "3")
4417    (set_attr "adjust_len" "sext")
4418    (set_attr "cc" "set_n")])
4420 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4421 ;; zero extend
4423 (define_insn_and_split "zero_extendqihi2"
4424   [(set (match_operand:HI 0 "register_operand" "=r")
4425         (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4426   ""
4427   "#"
4428   "reload_completed"
4429   [(set (match_dup 2) (match_dup 1))
4430    (set (match_dup 3) (const_int 0))]
4431   {
4432     unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4433     unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4435     operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4436     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4437   })
4439 (define_insn_and_split "zero_extendqipsi2"
4440   [(set (match_operand:PSI 0 "register_operand" "=r")
4441         (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4442   ""
4443   "#"
4444   "reload_completed"
4445   [(set (match_dup 2) (match_dup 1))
4446    (set (match_dup 3) (const_int 0))
4447    (set (match_dup 4) (const_int 0))]
4448   {
4449     operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4450     operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4451     operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4452   })
4454 (define_insn_and_split "zero_extendqisi2"
4455   [(set (match_operand:SI 0 "register_operand" "=r")
4456         (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4457   ""
4458   "#"
4459   "reload_completed"
4460   [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4461    (set (match_dup 3) (const_int 0))]
4462   {
4463     unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4464     unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4466     operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4467     operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4468   })
4470 (define_insn_and_split "zero_extendhipsi2"
4471   [(set (match_operand:PSI 0 "register_operand"                               "=r")
4472         (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4473   ""
4474   "#"
4475   "reload_completed"
4476   [(set (match_dup 2) (match_dup 1))
4477    (set (match_dup 3) (const_int 0))]
4478   {
4479     operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4480     operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4481   })
4483 (define_insn_and_split "n_extendhipsi2"
4484   [(set (match_operand:PSI 0 "register_operand"            "=r,r,d,r")
4485         (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4486                     (match_operand:HI 2 "register_operand"  "r,r,r,r")))
4487    (clobber (match_scratch:QI 3                            "=X,X,X,&d"))]
4488   ""
4489   "#"
4490   "reload_completed"
4491   [(set (match_dup 4) (match_dup 2))
4492    (set (match_dup 3) (match_dup 6))
4493    ; no-op move in the case where no scratch is needed
4494    (set (match_dup 5) (match_dup 3))]
4495   {
4496     operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4497     operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4498     operands[6] = operands[1];
4500     if (GET_CODE (operands[3]) == SCRATCH)
4501       operands[3] = operands[5];
4502   })
4504 (define_insn_and_split "zero_extendhisi2"
4505   [(set (match_operand:SI 0 "register_operand"                               "=r")
4506         (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4507   ""
4508   "#"
4509   "reload_completed"
4510   [(set (match_dup 2) (match_dup 1))
4511    (set (match_dup 3) (const_int 0))]
4512   {
4513     unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4514     unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4516     operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4517     operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4518   })
4520 (define_insn_and_split "zero_extendpsisi2"
4521   [(set (match_operand:SI 0 "register_operand"                                "=r")
4522         (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4523   ""
4524   "#"
4525   "reload_completed"
4526   [(set (match_dup 2) (match_dup 1))
4527    (set (match_dup 3) (const_int 0))]
4528   {
4529     operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4530     operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4531   })
4533 (define_insn_and_split "zero_extendqidi2"
4534   [(set (match_operand:DI 0 "register_operand" "=r")
4535         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4536   ""
4537   "#"
4538   "reload_completed"
4539   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4540    (set (match_dup 3) (const_int 0))]
4541   {
4542     unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4543     unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4545     operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4546     operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4547   })
4549 (define_insn_and_split "zero_extendhidi2"
4550   [(set (match_operand:DI 0 "register_operand" "=r")
4551         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4552   ""
4553   "#"
4554   "reload_completed"
4555   [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4556    (set (match_dup 3) (const_int 0))]
4557   {
4558     unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4559     unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4561     operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4562     operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4563   })
4565 (define_insn_and_split "zero_extendsidi2"
4566   [(set (match_operand:DI 0 "register_operand" "=r")
4567         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4568   ""
4569   "#"
4570   "reload_completed"
4571   [(set (match_dup 2) (match_dup 1))
4572    (set (match_dup 3) (const_int 0))]
4573   {
4574     unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4575     unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4577     operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4578     operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4579   })
4581 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4582 ;; compare
4584 ; Optimize negated tests into reverse compare if overflow is undefined.
4585 (define_insn "*negated_tstqi"
4586   [(set (cc0)
4587         (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4588                  (const_int 0)))]
4589   "!flag_wrapv && !flag_trapv"
4590   "cp __zero_reg__,%0"
4591   [(set_attr "cc" "compare")
4592    (set_attr "length" "1")])
4594 (define_insn "*reversed_tstqi"
4595   [(set (cc0)
4596         (compare (const_int 0)
4597                  (match_operand:QI 0 "register_operand" "r")))]
4598   ""
4599   "cp __zero_reg__,%0"
4600 [(set_attr "cc" "compare")
4601  (set_attr "length" "2")])
4603 (define_insn "*negated_tsthi"
4604   [(set (cc0)
4605         (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4606                  (const_int 0)))]
4607   "!flag_wrapv && !flag_trapv"
4608   "cp __zero_reg__,%A0
4609         cpc __zero_reg__,%B0"
4610 [(set_attr "cc" "compare")
4611  (set_attr "length" "2")])
4613 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4614 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4615 (define_insn "*reversed_tsthi"
4616   [(set (cc0)
4617         (compare (const_int 0)
4618                  (match_operand:HI 0 "register_operand" "r")))
4619    (clobber (match_scratch:QI 1 "=X"))]
4620   ""
4621   "cp __zero_reg__,%A0
4622         cpc __zero_reg__,%B0"
4623 [(set_attr "cc" "compare")
4624  (set_attr "length" "2")])
4626 (define_insn "*negated_tstpsi"
4627   [(set (cc0)
4628         (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4629                  (const_int 0)))]
4630   "!flag_wrapv && !flag_trapv"
4631   "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4632   [(set_attr "cc" "compare")
4633    (set_attr "length" "3")])
4635 (define_insn "*reversed_tstpsi"
4636   [(set (cc0)
4637         (compare (const_int 0)
4638                  (match_operand:PSI 0 "register_operand" "r")))
4639    (clobber (match_scratch:QI 1 "=X"))]
4640   ""
4641   "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4642   [(set_attr "cc" "compare")
4643    (set_attr "length" "3")])
4645 (define_insn "*negated_tstsi"
4646   [(set (cc0)
4647         (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4648                  (const_int 0)))]
4649   "!flag_wrapv && !flag_trapv"
4650   "cp __zero_reg__,%A0
4651         cpc __zero_reg__,%B0
4652         cpc __zero_reg__,%C0
4653         cpc __zero_reg__,%D0"
4654   [(set_attr "cc" "compare")
4655    (set_attr "length" "4")])
4657 ;; "*reversed_tstsi"
4658 ;; "*reversed_tstsq" "*reversed_tstusq"
4659 ;; "*reversed_tstsa" "*reversed_tstusa"
4660 (define_insn "*reversed_tst<mode>"
4661   [(set (cc0)
4662         (compare (match_operand:ALL4 0 "const0_operand"   "Y00")
4663                  (match_operand:ALL4 1 "register_operand" "r")))
4664    (clobber (match_scratch:QI 2 "=X"))]
4665   ""
4666   "cp __zero_reg__,%A1
4667         cpc __zero_reg__,%B1
4668         cpc __zero_reg__,%C1
4669         cpc __zero_reg__,%D1"
4670   [(set_attr "cc" "compare")
4671    (set_attr "length" "4")])
4674 ;; "cmpqi3"
4675 ;; "cmpqq3" "cmpuqq3"
4676 (define_insn "cmp<mode>3"
4677   [(set (cc0)
4678         (compare (match_operand:ALL1 0 "register_operand"  "r  ,r,d")
4679                  (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4680   ""
4681   "@
4682         tst %0
4683         cp %0,%1
4684         cpi %0,lo8(%1)"
4685   [(set_attr "cc" "compare,compare,compare")
4686    (set_attr "length" "1,1,1")])
4688 (define_insn "*cmpqi_sign_extend"
4689   [(set (cc0)
4690         (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4691                  (match_operand:HI 1 "s8_operand"                       "n")))]
4692   ""
4693   "cpi %0,lo8(%1)"
4694   [(set_attr "cc" "compare")
4695    (set_attr "length" "1")])
4698 (define_insn "*cmphi.zero-extend.0"
4699   [(set (cc0)
4700         (compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
4701                  (match_operand:HI 1 "register_operand" "r")))]
4702   ""
4703   "cp %0,%A1\;cpc __zero_reg__,%B1"
4704   [(set_attr "cc" "compare")
4705    (set_attr "length" "2")])
4707 (define_insn "*cmphi.zero-extend.1"
4708   [(set (cc0)
4709         (compare (match_operand:HI 0 "register_operand" "r")
4710                  (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
4711   ""
4712   "cp %A0,%1\;cpc %B0,__zero_reg__"
4713   [(set_attr "cc" "compare")
4714    (set_attr "length" "2")])
4716 ;; "cmphi3"
4717 ;; "cmphq3" "cmpuhq3"
4718 ;; "cmpha3" "cmpuha3"
4719 (define_insn "cmp<mode>3"
4720   [(set (cc0)
4721         (compare (match_operand:ALL2 0 "register_operand"  "!w  ,r  ,r,d ,r  ,d,r")
4722                  (match_operand:ALL2 1 "nonmemory_operand"  "Y00,Y00,r,s ,s  ,M,n Ynn")))
4723    (clobber (match_scratch:QI 2                            "=X  ,X  ,X,&d,&d ,X,&d"))]
4724   ""
4725   {
4726     switch (which_alternative)
4727       {
4728       case 0:
4729       case 1:
4730         return avr_out_tsthi (insn, operands, NULL);
4732       case 2:
4733         return "cp %A0,%A1\;cpc %B0,%B1";
4735       case 3:
4736         if (<MODE>mode != HImode)
4737           break;
4738         return reg_unused_after (insn, operands[0])
4739                ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4740                : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4742       case 4:
4743         if (<MODE>mode != HImode)
4744           break;
4745         return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4746       }
4748     return avr_out_compare (insn, operands, NULL);
4749   }
4750   [(set_attr "cc" "compare")
4751    (set_attr "length" "1,2,2,3,4,2,4")
4752    (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4754 (define_insn "*cmppsi"
4755   [(set (cc0)
4756         (compare (match_operand:PSI 0 "register_operand"  "r,r,d ,r  ,d,r")
4757                  (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s  ,M,n")))
4758    (clobber (match_scratch:QI 2                          "=X,X,&d,&d ,X,&d"))]
4759   ""
4760   {
4761     switch (which_alternative)
4762       {
4763       case 0:
4764         return avr_out_tstpsi (insn, operands, NULL);
4766       case 1:
4767         return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4769       case 2:
4770         return reg_unused_after (insn, operands[0])
4771                ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4772                : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4774       case 3:
4775         return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4776       }
4778     return avr_out_compare (insn, operands, NULL);
4779   }
4780   [(set_attr "cc" "compare")
4781    (set_attr "length" "3,3,5,6,3,7")
4782    (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4784 ;; "*cmpsi"
4785 ;; "*cmpsq" "*cmpusq"
4786 ;; "*cmpsa" "*cmpusa"
4787 (define_insn "*cmp<mode>"
4788   [(set (cc0)
4789         (compare (match_operand:ALL4 0 "register_operand"  "r  ,r ,d,r ,r")
4790                  (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4791    (clobber (match_scratch:QI 2                           "=X  ,X ,X,&d,&d"))]
4792   ""
4793   {
4794     if (0 == which_alternative)
4795       return avr_out_tstsi (insn, operands, NULL);
4796     else if (1 == which_alternative)
4797       return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4799     return avr_out_compare (insn, operands, NULL);
4800   }
4801   [(set_attr "cc" "compare")
4802    (set_attr "length" "4,4,4,5,8")
4803    (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4806 ;; ----------------------------------------------------------------------
4807 ;; JUMP INSTRUCTIONS
4808 ;; ----------------------------------------------------------------------
4809 ;; Conditional jump instructions
4811 ;; "cbranchqi4"
4812 ;; "cbranchqq4"  "cbranchuqq4"
4813 (define_expand "cbranch<mode>4"
4814   [(set (cc0)
4815         (compare (match_operand:ALL1 1 "register_operand" "")
4816                  (match_operand:ALL1 2 "nonmemory_operand" "")))
4817    (set (pc)
4818         (if_then_else
4819          (match_operator 0 "ordered_comparison_operator" [(cc0)
4820                                                           (const_int 0)])
4821          (label_ref (match_operand 3 "" ""))
4822          (pc)))])
4824 ;; "cbranchhi4"  "cbranchhq4"  "cbranchuhq4"  "cbranchha4"  "cbranchuha4"
4825 ;; "cbranchsi4"  "cbranchsq4"  "cbranchusq4"  "cbranchsa4"  "cbranchusa4"
4826 ;; "cbranchpsi4"
4827 (define_expand "cbranch<mode>4"
4828   [(parallel [(set (cc0)
4829                    (compare (match_operand:ORDERED234 1 "register_operand" "")
4830                             (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4831               (clobber (match_scratch:QI 4 ""))])
4832    (set (pc)
4833         (if_then_else
4834          (match_operator 0 "ordered_comparison_operator" [(cc0)
4835                                                           (const_int 0)])
4836          (label_ref (match_operand 3 "" ""))
4837          (pc)))])
4840 ;; Test a single bit in a QI/HI/SImode register.
4841 ;; Combine will create zero extract patterns for single bit tests.
4842 ;; permit any mode in source pattern by using VOIDmode.
4844 (define_insn "*sbrx_branch<mode>"
4845   [(set (pc)
4846         (if_then_else
4847          (match_operator 0 "eqne_operator"
4848                          [(zero_extract:QIDI
4849                            (match_operand:VOID 1 "register_operand" "r")
4850                            (const_int 1)
4851                            (match_operand 2 "const_int_operand" "n"))
4852                           (const_int 0)])
4853          (label_ref (match_operand 3 "" ""))
4854          (pc)))]
4855   ""
4856   {
4857     return avr_out_sbxx_branch (insn, operands);
4858   }
4859   [(set (attr "length")
4860         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4861                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
4862                       (const_int 2)
4863                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4864                                     (const_int 2)
4865                                     (const_int 4))))
4866    (set_attr "cc" "clobber")])
4868 ;; Same test based on bitwise AND.  Keep this in case gcc changes patterns.
4869 ;; or for old peepholes.
4870 ;; Fixme - bitwise Mask will not work for DImode
4872 (define_insn "*sbrx_and_branch<mode>"
4873   [(set (pc)
4874         (if_then_else
4875          (match_operator 0 "eqne_operator"
4876                          [(and:QISI
4877                            (match_operand:QISI 1 "register_operand" "r")
4878                            (match_operand:QISI 2 "single_one_operand" "n"))
4879                           (const_int 0)])
4880          (label_ref (match_operand 3 "" ""))
4881          (pc)))]
4882   ""
4883   {
4884     HOST_WIDE_INT bitnumber;
4885     bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4886     operands[2] = GEN_INT (bitnumber);
4887     return avr_out_sbxx_branch (insn, operands);
4888   }
4889   [(set (attr "length")
4890         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4891                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
4892                       (const_int 2)
4893                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4894                                     (const_int 2)
4895                                     (const_int 4))))
4896    (set_attr "cc" "clobber")])
4898 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4899 (define_peephole2
4900   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4901                        (const_int 0)))
4902    (set (pc) (if_then_else (ge (cc0) (const_int 0))
4903                            (label_ref (match_operand 1 "" ""))
4904                            (pc)))]
4905   ""
4906   [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4907                                                 (const_int 1)
4908                                                 (const_int 7))
4909                                (const_int 0))
4910                            (label_ref (match_dup 1))
4911                            (pc)))])
4913 (define_peephole2
4914   [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4915                        (const_int 0)))
4916    (set (pc) (if_then_else (lt (cc0) (const_int 0))
4917                            (label_ref (match_operand 1 "" ""))
4918                            (pc)))]
4919   ""
4920   [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4921                                                 (const_int 1)
4922                                                 (const_int 7))
4923                                (const_int 0))
4924                            (label_ref (match_dup 1))
4925                            (pc)))])
4927 (define_peephole2
4928   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4929                                   (const_int 0)))
4930               (clobber (match_operand:HI 2 ""))])
4931    (set (pc) (if_then_else (ge (cc0) (const_int 0))
4932                            (label_ref (match_operand 1 "" ""))
4933                            (pc)))]
4934   ""
4935   [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4936                                (const_int 0))
4937                            (label_ref (match_dup 1))
4938                            (pc)))])
4940 (define_peephole2
4941   [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4942                                   (const_int 0)))
4943               (clobber (match_operand:HI 2 ""))])
4944    (set (pc) (if_then_else (lt (cc0) (const_int 0))
4945                            (label_ref (match_operand 1 "" ""))
4946                            (pc)))]
4947   ""
4948   [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4949                                (const_int 0))
4950                            (label_ref (match_dup 1))
4951                            (pc)))])
4953 (define_peephole2
4954   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4955                                   (const_int 0)))
4956               (clobber (match_operand:SI 2 ""))])
4957    (set (pc) (if_then_else (ge (cc0) (const_int 0))
4958                            (label_ref (match_operand 1 "" ""))
4959                            (pc)))]
4960   ""
4961   [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4962                                (const_int 0))
4963                            (label_ref (match_dup 1))
4964                            (pc)))]
4965   "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4967 (define_peephole2
4968   [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4969                                   (const_int 0)))
4970               (clobber (match_operand:SI 2 ""))])
4971    (set (pc) (if_then_else (lt (cc0) (const_int 0))
4972                            (label_ref (match_operand 1 "" ""))
4973                            (pc)))]
4974   ""
4975   [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4976                                (const_int 0))
4977                            (label_ref (match_dup 1))
4978                            (pc)))]
4979   "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4981 ;; ************************************************************************
4982 ;; Implementation of conditional jumps here.
4983 ;;  Compare with 0 (test) jumps
4984 ;; ************************************************************************
4986 (define_insn "branch"
4987   [(set (pc)
4988         (if_then_else (match_operator 1 "simple_comparison_operator"
4989                                       [(cc0)
4990                                        (const_int 0)])
4991                       (label_ref (match_operand 0 "" ""))
4992                       (pc)))]
4993   ""
4994   {
4995     return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4996   }
4997   [(set_attr "type" "branch")
4998    (set_attr "cc" "clobber")])
5001 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
5002 ;; or optimized in the remainder.
5004 (define_insn "branch_unspec"
5005   [(set (pc)
5006         (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
5007                                                [(cc0)
5008                                                 (const_int 0)])
5009                                (label_ref (match_operand 0 "" ""))
5010                                (pc))
5011                  ] UNSPEC_IDENTITY))]
5012   ""
5013   {
5014     return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5015   }
5016   [(set_attr "type" "branch")
5017    (set_attr "cc" "none")])
5019 ;; ****************************************************************
5020 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
5021 ;; Convert them all to proper jumps.
5022 ;; ****************************************************************/
5024 (define_insn "difficult_branch"
5025   [(set (pc)
5026         (if_then_else (match_operator 1 "difficult_comparison_operator"
5027                         [(cc0)
5028                          (const_int 0)])
5029                       (label_ref (match_operand 0 "" ""))
5030                       (pc)))]
5031   ""
5032   {
5033     return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5034   }
5035   [(set_attr "type" "branch1")
5036    (set_attr "cc" "clobber")])
5038 ;; revers branch
5040 (define_insn "rvbranch"
5041   [(set (pc)
5042         (if_then_else (match_operator 1 "simple_comparison_operator"
5043                                       [(cc0)
5044                                        (const_int 0)])
5045                       (pc)
5046                       (label_ref (match_operand 0 "" ""))))]
5047   ""
5048   {
5049     return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5050   }
5051   [(set_attr "type" "branch1")
5052    (set_attr "cc" "clobber")])
5054 (define_insn "difficult_rvbranch"
5055   [(set (pc)
5056         (if_then_else (match_operator 1 "difficult_comparison_operator"
5057                                       [(cc0)
5058                                        (const_int 0)])
5059                       (pc)
5060                       (label_ref (match_operand 0 "" ""))))]
5061   ""
5062   {
5063     return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5064   }
5065   [(set_attr "type" "branch")
5066    (set_attr "cc" "clobber")])
5068 ;; **************************************************************************
5069 ;; Unconditional and other jump instructions.
5071 (define_insn "jump"
5072   [(set (pc)
5073         (label_ref (match_operand 0 "" "")))]
5074   ""
5075   {
5076     return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
5077            ? "jmp %x0"
5078            : "rjmp %x0";
5079   }
5080   [(set (attr "length")
5081         (if_then_else (match_operand 0 "symbol_ref_operand" "") 
5082                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5083                                     (const_int 1)
5084                                     (const_int 2))
5085                       (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
5086                                          (le (minus (pc) (match_dup 0)) (const_int 2047)))
5087                                     (const_int 1)
5088                                     (const_int 2))))
5089    (set_attr "cc" "none")])
5091 ;; call
5093 ;; Operand 1 not used on the AVR.
5094 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5095 (define_expand "call"
5096   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5097                    (match_operand:HI 1 "general_operand" ""))
5098              (use (const_int 0))])])
5100 ;; Operand 1 not used on the AVR.
5101 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5102 (define_expand "sibcall"
5103   [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5104                    (match_operand:HI 1 "general_operand" ""))
5105              (use (const_int 1))])])
5107 ;; call value
5109 ;; Operand 2 not used on the AVR.
5110 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5111 (define_expand "call_value"
5112   [(parallel[(set (match_operand 0 "register_operand" "")
5113                   (call (match_operand:HI 1 "call_insn_operand" "")
5114                         (match_operand:HI 2 "general_operand" "")))
5115              (use (const_int 0))])])
5117 ;; Operand 2 not used on the AVR.
5118 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5119 (define_expand "sibcall_value"
5120   [(parallel[(set (match_operand 0 "register_operand" "")
5121                   (call (match_operand:HI 1 "call_insn_operand" "")
5122                         (match_operand:HI 2 "general_operand" "")))
5123              (use (const_int 1))])])
5125 (define_insn "call_insn"
5126   [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
5127                    (match_operand:HI 1 "general_operand"           "X,X,X,X"))
5128              (use (match_operand:HI 2 "const_int_operand"          "L,L,P,P"))])]
5129   ;; Operand 1 not used on the AVR.
5130   ;; Operand 2 is 1 for tail-call, 0 otherwise.
5131   ""
5132   "@
5133     %!icall
5134     %~call %x0
5135     %!ijmp
5136     %~jmp %x0"
5137   [(set_attr "cc" "clobber")
5138    (set_attr "length" "1,*,1,*")
5139    (set_attr "adjust_len" "*,call,*,call")])
5141 (define_insn "call_value_insn"
5142   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
5143                   (call (mem:HI (match_operand:HI 1 "nonmemory_operand"  "z,s,z,s"))
5144                         (match_operand:HI 2 "general_operand"            "X,X,X,X")))
5145              (use (match_operand:HI 3 "const_int_operand"                "L,L,P,P"))])]
5146   ;; Operand 2 not used on the AVR.
5147   ;; Operand 3 is 1 for tail-call, 0 otherwise.
5148   ""
5149   "@
5150     %!icall
5151     %~call %x1
5152     %!ijmp
5153     %~jmp %x1"
5154   [(set_attr "cc" "clobber")
5155    (set_attr "length" "1,*,1,*")
5156    (set_attr "adjust_len" "*,call,*,call")])
5158 (define_insn "nop"
5159   [(const_int 0)]
5160   ""
5161   "nop"
5162   [(set_attr "cc" "none")
5163    (set_attr "length" "1")])
5165 ; indirect jump
5167 (define_expand "indirect_jump"
5168   [(set (pc)
5169         (match_operand:HI 0 "nonmemory_operand" ""))]
5170   ""
5171   {
5172     if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
5173       {
5174         operands[0] = copy_to_mode_reg (HImode, operands[0]);
5175       }
5176   })
5178 ; indirect jump
5179 (define_insn "*indirect_jump"
5180   [(set (pc)
5181         (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
5182   ""
5183   "@
5184         rjmp %x0
5185         jmp %x0
5186         ijmp
5187         push %A0\;push %B0\;ret
5188         eijmp"
5189   [(set_attr "length" "1,2,1,3,1")
5190    (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
5191    (set_attr "cc" "none")])
5193 ;; table jump
5194 ;; For entries in jump table see avr_output_addr_vec.
5196 ;; Table made from
5197 ;;    "rjmp .L<n>"   instructions for <= 8K devices
5198 ;;    ".word gs(.L<n>)" addresses for >  8K devices
5199 (define_insn "*tablejump"
5200   [(set (pc)
5201         (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
5202                    UNSPEC_INDEX_JMP))
5203    (use (label_ref (match_operand 1 "" "")))
5204    (clobber (match_dup 0))
5205    (clobber (const_int 0))]
5206   "!AVR_HAVE_EIJMP_EICALL"
5207   "@
5208         ijmp
5209         push %A0\;push %B0\;ret
5210         jmp __tablejump2__"
5211   [(set_attr "length" "1,3,2")
5212    (set_attr "isa" "rjmp,rjmp,jmp")
5213    (set_attr "cc" "none,none,clobber")])
5215 (define_insn "*tablejump.3byte-pc"
5216   [(set (pc)
5217         (unspec:HI [(reg:HI REG_Z)]
5218                    UNSPEC_INDEX_JMP))
5219    (use (label_ref (match_operand 0 "" "")))
5220    (clobber (reg:HI REG_Z))
5221    (clobber (reg:QI 24))]
5222   "AVR_HAVE_EIJMP_EICALL"
5223   "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
5224   [(set_attr "length" "6")
5225    (set_attr "isa" "eijmp")
5226    (set_attr "cc" "clobber")])
5229 ;; FIXME: casesi comes up with an SImode switch value $0 which
5230 ;;   is quite some overhead because most code would use HI or
5231 ;;   even QI.  We add an AVR specific pass .avr-casesi which
5232 ;;   tries to recover from the superfluous extension to SImode.
5234 ;;   Using "tablejump" could be a way out, but this also does
5235 ;;   not perform in a satisfying manner as the middle end will
5236 ;;   already multiply the table index by 2.  Note that this
5237 ;;   multiplication is performed by libgcc's __tablejump2__.
5238 ;;   The multiplication there, however, runs *after* the table
5239 ;;   start (a byte address) has been added, not before it like
5240 ;;   "tablejump" will do.
5242 ;;   The preferred solution would be to let the middle ends pass
5243 ;;   down information on the index as an additional casesi operand.
5245 ;;   If this expander is changed, you'll likely have to go through
5246 ;;   "casesi_<mode>_sequence" (used to recog + extract casesi
5247 ;;   sequences in pass .avr-casesi) and propagate all adjustments
5248 ;;   also to that pattern and the code of the extra pass.
5249   
5250 (define_expand "casesi"
5251   [(parallel [(set (match_dup 5)
5252                    (plus:SI (match_operand:SI 0 "register_operand")
5253                             (match_operand:SI 1 "const_int_operand")))
5254               (clobber (scratch:QI))])
5255    (parallel [(set (cc0)
5256                    (compare (match_dup 5)
5257                             (match_operand:SI 2 "const_int_operand")))
5258               (clobber (scratch:QI))])
5260    (set (pc)
5261         (if_then_else (gtu (cc0)
5262                            (const_int 0))
5263                       (label_ref (match_operand 4))
5264                       (pc)))
5266    (set (match_dup 7)
5267         (match_dup 6))
5269    (parallel [(set (pc)
5270                    (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5271               (use (label_ref (match_dup 3)))
5272               (clobber (match_dup 7))
5273               (clobber (match_dup 8))])]
5274   ""
5275   {
5276     operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
5277     operands[5] = gen_reg_rtx (SImode);
5278     operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
5280     if (AVR_HAVE_EIJMP_EICALL)
5281       {
5282         operands[7] = gen_rtx_REG (HImode, REG_Z);
5283         operands[8] = all_regs_rtx[24];
5284       }
5285     else
5286       {
5287         operands[6] = gen_rtx_PLUS (HImode, operands[6],
5288                                     gen_rtx_LABEL_REF (VOIDmode, operands[3]));
5289         operands[7] = gen_reg_rtx (HImode);
5290         operands[8] = const0_rtx;
5291       }
5292   })
5295 ;; This insn is used only for easy operand extraction.
5296 ;; The elements must match an extension to SImode plus
5297 ;; a sequence generated by casesi above.
5299 ;; "casesi_qi_sequence"
5300 ;; "casesi_hi_sequence"
5301 (define_insn "casesi_<mode>_sequence"
5302   [(set (match_operand:SI 0 "register_operand")
5303         (match_operator:SI 9 "extend_operator"
5304                            [(match_operand:QIHI 10 "register_operand")]))
5306    ;; What follows is a matcher for code from casesi.
5307    ;; We keep the same operand numbering (except for $9 and $10
5308    ;; which don't appear in casesi).
5309    (parallel [(set (match_operand:SI 5 "register_operand")
5310                    (plus:SI (match_dup 0)
5311                             (match_operand:SI 1 "const_int_operand")))
5312               (clobber (scratch:QI))])
5313    (parallel [(set (cc0)
5314                    (compare (match_dup 5)
5315                             (match_operand:SI 2 "const_int_operand")))
5316               (clobber (scratch:QI))])
5318    (set (pc)
5319         (if_then_else (gtu (cc0)
5320                            (const_int 0))
5321                       (label_ref (match_operand 4))
5322                       (pc)))
5324    (set (match_operand:HI 7 "register_operand")
5325         (match_operand:HI 6))
5327    (parallel [(set (pc)
5328                    (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5329               (use (label_ref (match_operand 3)))
5330               (clobber (match_dup 7))
5331               (clobber (match_operand:QI 8))])]
5332   "optimize
5333    && avr_casei_sequence_check_operands (operands)"
5334   { gcc_unreachable(); }
5335   )
5338 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5339 ;; This instruction sets Z flag
5341 (define_insn "sez"
5342   [(set (cc0) (const_int 0))]
5343   ""
5344   "sez"
5345   [(set_attr "length" "1")
5346    (set_attr "cc" "compare")])
5348 ;; Clear/set/test a single bit in I/O address space.
5350 (define_insn "*cbi"
5351   [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5352         (and:QI (mem:QI (match_dup 0))
5353                 (match_operand:QI 1 "single_zero_operand" "n")))]
5354   ""
5355   {
5356     operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5357     return "cbi %i0,%2";
5358   }
5359   [(set_attr "length" "1")
5360    (set_attr "cc" "none")])
5362 (define_insn "*sbi"
5363   [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5364         (ior:QI (mem:QI (match_dup 0))
5365                 (match_operand:QI 1 "single_one_operand" "n")))]
5366   ""
5367   {
5368     operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5369     return "sbi %i0,%2";
5370   }
5371   [(set_attr "length" "1")
5372    (set_attr "cc" "none")])
5374 ;; Lower half of the I/O space - use sbic/sbis directly.
5375 (define_insn "*sbix_branch"
5376   [(set (pc)
5377         (if_then_else
5378          (match_operator 0 "eqne_operator"
5379                          [(zero_extract:QIHI
5380                            (mem:QI (match_operand 1 "low_io_address_operand" "i"))
5381                            (const_int 1)
5382                            (match_operand 2 "const_int_operand" "n"))
5383                           (const_int 0)])
5384          (label_ref (match_operand 3 "" ""))
5385          (pc)))]
5386   ""
5387   {
5388     return avr_out_sbxx_branch (insn, operands);
5389   }
5390   [(set (attr "length")
5391         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5392                            (le (minus (pc) (match_dup 3)) (const_int 2046)))
5393                       (const_int 2)
5394                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5395                                     (const_int 2)
5396                                     (const_int 4))))
5397    (set_attr "cc" "clobber")])
5399 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5400 (define_insn "*sbix_branch_bit7"
5401   [(set (pc)
5402         (if_then_else
5403          (match_operator 0 "gelt_operator"
5404                          [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
5405                           (const_int 0)])
5406          (label_ref (match_operand 2 "" ""))
5407          (pc)))]
5408   ""
5409   {
5410     operands[3] = operands[2];
5411     operands[2] = GEN_INT (7);
5412     return avr_out_sbxx_branch (insn, operands);
5413   }
5414   [(set (attr "length")
5415         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5416                            (le (minus (pc) (match_dup 2)) (const_int 2046)))
5417                       (const_int 2)
5418                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5419                                     (const_int 2)
5420                                     (const_int 4))))
5421    (set_attr "cc" "clobber")])
5423 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5424 (define_insn "*sbix_branch_tmp"
5425   [(set (pc)
5426         (if_then_else
5427          (match_operator 0 "eqne_operator"
5428                          [(zero_extract:QIHI
5429                            (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5430                            (const_int 1)
5431                            (match_operand 2 "const_int_operand" "n"))
5432                           (const_int 0)])
5433          (label_ref (match_operand 3 "" ""))
5434          (pc)))]
5435   ""
5436   {
5437     return avr_out_sbxx_branch (insn, operands);
5438   }
5439   [(set (attr "length")
5440         (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5441                            (le (minus (pc) (match_dup 3)) (const_int 2045)))
5442                       (const_int 3)
5443                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5444                                     (const_int 3)
5445                                     (const_int 5))))
5446    (set_attr "cc" "clobber")])
5448 (define_insn "*sbix_branch_tmp_bit7"
5449   [(set (pc)
5450         (if_then_else
5451          (match_operator 0 "gelt_operator"
5452                          [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5453                           (const_int 0)])
5454          (label_ref (match_operand 2 "" ""))
5455          (pc)))]
5456   ""
5457   {
5458     operands[3] = operands[2];
5459     operands[2] = GEN_INT (7);
5460     return avr_out_sbxx_branch (insn, operands);
5461   }
5462   [(set (attr "length")
5463         (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5464                            (le (minus (pc) (match_dup 2)) (const_int 2045)))
5465                       (const_int 3)
5466                       (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5467                                     (const_int 3)
5468                                     (const_int 5))))
5469    (set_attr "cc" "clobber")])
5471 ;; ************************* Peepholes ********************************
5473 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5474   [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5475                    (plus:SI (match_dup 0)
5476                             (const_int -1)))
5477               (clobber (scratch:QI))])
5478    (parallel [(set (cc0)
5479                    (compare (match_dup 0)
5480                             (const_int -1)))
5481               (clobber (match_operand:QI 1 "d_register_operand" ""))])
5482    (set (pc)
5483         (if_then_else (eqne (cc0)
5484                             (const_int 0))
5485                       (label_ref (match_operand 2 "" ""))
5486                       (pc)))]
5487   ""
5488   {
5489     const char *op;
5490     int jump_mode;
5491     CC_STATUS_INIT;
5492     if (test_hard_reg_class (ADDW_REGS, operands[0]))
5493       output_asm_insn ("sbiw %0,1" CR_TAB
5494                        "sbc %C0,__zero_reg__" CR_TAB
5495                        "sbc %D0,__zero_reg__", operands);
5496     else
5497       output_asm_insn ("subi %A0,1" CR_TAB
5498                        "sbc %B0,__zero_reg__" CR_TAB
5499                        "sbc %C0,__zero_reg__" CR_TAB
5500                        "sbc %D0,__zero_reg__", operands);
5502     jump_mode = avr_jump_mode (operands[2], insn);
5503     op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5504     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5506     switch (jump_mode)
5507       {
5508       case 1: return "%1 %2";
5509       case 2: return "%1 .+2\;rjmp %2";
5510       case 3: return "%1 .+4\;jmp %2";
5511       }
5513     gcc_unreachable();
5514     return "";
5515   })
5517 (define_peephole ; "*dec-and-branchhi!=-1"
5518   [(set (match_operand:HI 0 "d_register_operand" "")
5519         (plus:HI (match_dup 0)
5520                  (const_int -1)))
5521    (parallel [(set (cc0)
5522                    (compare (match_dup 0)
5523                             (const_int -1)))
5524               (clobber (match_operand:QI 1 "d_register_operand" ""))])
5525    (set (pc)
5526         (if_then_else (eqne (cc0)
5527                             (const_int 0))
5528                       (label_ref (match_operand 2 "" ""))
5529                       (pc)))]
5530   ""
5531   {
5532     const char *op;
5533     int jump_mode;
5534     CC_STATUS_INIT;
5535     if (test_hard_reg_class (ADDW_REGS, operands[0]))
5536       output_asm_insn ("sbiw %0,1", operands);
5537     else
5538       output_asm_insn ("subi %A0,1" CR_TAB
5539                        "sbc %B0,__zero_reg__", operands);
5541     jump_mode = avr_jump_mode (operands[2], insn);
5542     op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5543     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5545     switch (jump_mode)
5546       {
5547       case 1: return "%1 %2";
5548       case 2: return "%1 .+2\;rjmp %2";
5549       case 3: return "%1 .+4\;jmp %2";
5550       }
5552     gcc_unreachable();
5553     return "";
5554   })
5556 ;; Same as above but with clobber flavour of addhi3
5557 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5558   [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5559                    (plus:HI (match_dup 0)
5560                             (const_int -1)))
5561               (clobber (scratch:QI))])
5562    (parallel [(set (cc0)
5563                    (compare (match_dup 0)
5564                             (const_int -1)))
5565               (clobber (match_operand:QI 1 "d_register_operand" ""))])
5566    (set (pc)
5567         (if_then_else (eqne (cc0)
5568                             (const_int 0))
5569                       (label_ref (match_operand 2 "" ""))
5570                       (pc)))]
5571   ""
5572   {
5573     const char *op;
5574     int jump_mode;
5575     CC_STATUS_INIT;
5576     if (test_hard_reg_class (ADDW_REGS, operands[0]))
5577       output_asm_insn ("sbiw %0,1", operands);
5578     else
5579       output_asm_insn ("subi %A0,1" CR_TAB
5580                        "sbc %B0,__zero_reg__", operands);
5582     jump_mode = avr_jump_mode (operands[2], insn);
5583     op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5584     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5586     switch (jump_mode)
5587       {
5588       case 1: return "%1 %2";
5589       case 2: return "%1 .+2\;rjmp %2";
5590       case 3: return "%1 .+4\;jmp %2";
5591       }
5593     gcc_unreachable();
5594     return "";
5595   })
5597 ;; Same as above but with clobber flavour of addhi3
5598 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5599   [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5600                    (plus:HI (match_dup 0)
5601                             (const_int -1)))
5602               (clobber (match_operand:QI 3 "d_register_operand" ""))])
5603    (parallel [(set (cc0)
5604                    (compare (match_dup 0)
5605                             (const_int -1)))
5606               (clobber (match_operand:QI 1 "d_register_operand" ""))])
5607    (set (pc)
5608         (if_then_else (eqne (cc0)
5609                             (const_int 0))
5610                       (label_ref (match_operand 2 "" ""))
5611                       (pc)))]
5612   ""
5613   {
5614     const char *op;
5615     int jump_mode;
5616     CC_STATUS_INIT;
5617     output_asm_insn ("ldi %3,1"   CR_TAB
5618                      "sub %A0,%3" CR_TAB
5619                      "sbc %B0,__zero_reg__", operands);
5621     jump_mode = avr_jump_mode (operands[2], insn);
5622     op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5623     operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5625     switch (jump_mode)
5626       {
5627       case 1: return "%1 %2";
5628       case 2: return "%1 .+2\;rjmp %2";
5629       case 3: return "%1 .+4\;jmp %2";
5630       }
5632     gcc_unreachable();
5633     return "";
5634   })
5636 (define_peephole ; "*dec-and-branchqi!=-1"
5637   [(set (match_operand:QI 0 "d_register_operand" "")
5638         (plus:QI (match_dup 0)
5639                  (const_int -1)))
5640    (set (cc0)
5641         (compare (match_dup 0)
5642                  (const_int -1)))
5643    (set (pc)
5644         (if_then_else (eqne (cc0)
5645                             (const_int 0))
5646                       (label_ref (match_operand 1 "" ""))
5647                       (pc)))]
5648   ""
5649   {
5650     const char *op;
5651     int jump_mode;
5652     CC_STATUS_INIT;
5653     cc_status.value1 = operands[0];
5654     cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5656     output_asm_insn ("subi %A0,1", operands);
5658     jump_mode = avr_jump_mode (operands[1], insn);
5659     op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5660     operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5662     switch (jump_mode)
5663       {
5664       case 1: return "%0 %1";
5665       case 2: return "%0 .+2\;rjmp %1";
5666       case 3: return "%0 .+4\;jmp %1";
5667       }
5669     gcc_unreachable();
5670     return "";
5671   })
5674 (define_peephole ; "*cpse.eq"
5675   [(set (cc0)
5676         (compare (match_operand:ALL1 1 "register_operand" "r,r")
5677                  (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5678    (set (pc)
5679         (if_then_else (eq (cc0)
5680                           (const_int 0))
5681                       (label_ref (match_operand 0 "" ""))
5682                       (pc)))]
5683   "jump_over_one_insn_p (insn, operands[0])"
5684   "@
5685         cpse %1,%2
5686         cpse %1,__zero_reg__")
5688 ;; This peephole avoids code like
5690 ;;     TST   Rn     ; cmpqi3
5691 ;;     BREQ  .+2    ; branch
5692 ;;     RJMP  .Lm
5694 ;; Notice that the peephole is always shorter than cmpqi + branch.
5695 ;; The reason to write it as peephole is that sequences like
5697 ;;     AND   Rm, Rn
5698 ;;     BRNE  .La
5700 ;; shall not be superseeded.  With a respective combine pattern
5701 ;; the latter sequence would be
5703 ;;     AND   Rm, Rn
5704 ;;     CPSE  Rm, __zero_reg__
5705 ;;     RJMP  .La
5707 ;; and thus longer and slower and not easy to be rolled back.
5709 (define_peephole ; "*cpse.ne"
5710   [(set (cc0)
5711         (compare (match_operand:ALL1 1 "register_operand" "")
5712                  (match_operand:ALL1 2 "reg_or_0_operand" "")))
5713    (set (pc)
5714         (if_then_else (ne (cc0)
5715                           (const_int 0))
5716                       (label_ref (match_operand 0 "" ""))
5717                       (pc)))]
5718   "!AVR_HAVE_JMP_CALL
5719    || !TARGET_SKIP_BUG"
5720   {
5721     if (operands[2] == CONST0_RTX (<MODE>mode))
5722       operands[2] = zero_reg_rtx;
5724     return 3 == avr_jump_mode (operands[0], insn)
5725       ? "cpse %1,%2\;jmp %0"
5726       : "cpse %1,%2\;rjmp %0";
5727   })
5729 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5730 ;;prologue/epilogue support instructions
5732 (define_insn "popqi"
5733   [(set (match_operand:QI 0 "register_operand" "=r")
5734         (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5735   ""
5736   "pop %0"
5737   [(set_attr "cc" "none")
5738    (set_attr "length" "1")])
5740 ;; Enable Interrupts
5741 (define_expand "enable_interrupt"
5742   [(clobber (const_int 0))]
5743   ""
5744   {
5745     rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5746     MEM_VOLATILE_P (mem) = 1;
5747     emit_insn (gen_cli_sei (const1_rtx, mem));
5748     DONE;
5749   })
5751 ;; Disable Interrupts
5752 (define_expand "disable_interrupt"
5753   [(clobber (const_int 0))]
5754   ""
5755   {
5756     rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5757     MEM_VOLATILE_P (mem) = 1;
5758     emit_insn (gen_cli_sei (const0_rtx, mem));
5759     DONE;
5760   })
5762 (define_insn "cli_sei"
5763   [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5764                     UNSPECV_ENABLE_IRQS)
5765    (set (match_operand:BLK 1 "" "")
5766         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5767   ""
5768   "@
5769         cli
5770         sei"
5771   [(set_attr "length" "1")
5772    (set_attr "cc" "none")])
5774 ;;  Library prologue saves
5775 (define_insn "call_prologue_saves"
5776   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5777    (match_operand:HI 0 "immediate_operand" "i,i")
5778    (set (reg:HI REG_SP)
5779         (minus:HI (reg:HI REG_SP)
5780                   (match_operand:HI 1 "immediate_operand" "i,i")))
5781    (use (reg:HI REG_X))
5782    (clobber (reg:HI REG_Z))]
5783   ""
5784   "ldi r30,lo8(gs(1f))
5785         ldi r31,hi8(gs(1f))
5786         %~jmp __prologue_saves__+((18 - %0) * 2)
5788   [(set_attr "length" "5,6")
5789    (set_attr "cc" "clobber")
5790    (set_attr "isa" "rjmp,jmp")])
5792 ;  epilogue  restores using library
5793 (define_insn "epilogue_restores"
5794   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5795    (set (reg:HI REG_Y)
5796         (plus:HI (reg:HI REG_Y)
5797                  (match_operand:HI 0 "immediate_operand" "i,i")))
5798    (set (reg:HI REG_SP)
5799         (plus:HI (reg:HI REG_Y)
5800                  (match_dup 0)))
5801    (clobber (reg:QI REG_Z))]
5802   ""
5803   "ldi r30, lo8(%0)
5804         %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5805   [(set_attr "length" "2,3")
5806    (set_attr "cc" "clobber")
5807    (set_attr "isa" "rjmp,jmp")])
5810 ;; $0 = Chunk: 1 = Prologue,  2 = Epilogue
5811 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
5812 (define_expand "gasisr"
5813   [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
5814                                 (match_operand:QI 1 "const_int_operand")]
5815                                UNSPECV_GASISR)
5816               (set (reg:HI REG_SP)
5817                    (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5818               (set (match_dup 2)
5819                    (unspec_volatile:BLK [(match_dup 2)]
5820                                         UNSPECV_MEMORY_BARRIER))])]
5821   "avr_gasisr_prologues"
5822   {
5823     operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5824     MEM_VOLATILE_P (operands[2]) = 1;
5825   })
5827 (define_insn "*gasisr"
5828   [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
5829                      (match_operand:QI 1 "const_int_operand" "n,n")]
5830                     UNSPECV_GASISR)
5831    (set (reg:HI REG_SP)
5832         (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5833    (set (match_operand:BLK 2)
5834         (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))]
5835   "avr_gasisr_prologues"
5836   "__gcc_isr %0"
5837   [(set_attr "length" "6,5")
5838    (set_attr "cc" "clobber")])
5841 ; return
5842 (define_insn "return"
5843   [(return)]
5844   "reload_completed && avr_simple_epilogue ()"
5845   "ret"
5846   [(set_attr "cc" "none")
5847    (set_attr "length" "1")])
5849 (define_insn "return_from_epilogue"
5850   [(return)]
5851   "reload_completed
5852    && cfun->machine
5853    && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5854    && !cfun->machine->is_naked"
5855   "ret"
5856   [(set_attr "cc" "none")
5857    (set_attr "length" "1")])
5859 (define_insn "return_from_interrupt_epilogue"
5860   [(return)]
5861   "reload_completed
5862    && cfun->machine
5863    && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5864    && !cfun->machine->is_naked"
5865   "reti"
5866   [(set_attr "cc" "none")
5867    (set_attr "length" "1")])
5869 (define_insn "return_from_naked_epilogue"
5870   [(return)]
5871   "reload_completed
5872    && cfun->machine
5873    && cfun->machine->is_naked"
5874   ""
5875   [(set_attr "cc" "none")
5876    (set_attr "length" "0")])
5878 (define_expand "prologue"
5879   [(const_int 0)]
5880   ""
5881   {
5882     avr_expand_prologue ();
5883     DONE;
5884   })
5886 (define_expand "epilogue"
5887   [(const_int 0)]
5888   ""
5889   {
5890     avr_expand_epilogue (false /* sibcall_p */);
5891     DONE;
5892   })
5894 (define_expand "sibcall_epilogue"
5895   [(const_int 0)]
5896   ""
5897   {
5898     avr_expand_epilogue (true /* sibcall_p */);
5899     DONE;
5900   })
5902 ;; Some instructions resp. instruction sequences available
5903 ;; via builtins.
5905 (define_insn "delay_cycles_1"
5906   [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5907                      (const_int 1)]
5908                     UNSPECV_DELAY_CYCLES)
5909    (set (match_operand:BLK 1 "" "")
5910         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5911    (clobber (match_scratch:QI 2 "=&d"))]
5912   ""
5913   "ldi %2,lo8(%0)
5914 1:      dec %2
5915         brne 1b"
5916   [(set_attr "length" "3")
5917    (set_attr "cc" "clobber")])
5919 (define_insn "delay_cycles_2"
5920   [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
5921                      (const_int 2)]
5922                     UNSPECV_DELAY_CYCLES)
5923    (set (match_operand:BLK 1 "" "")
5924         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5925    (clobber (match_scratch:HI 2 "=&w,&d"))]
5926   ""
5927   "@
5928         ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1:    sbiw %A2,1\;brne 1b
5929         ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1:    subi %A2,1\;sbci %B2,0\;brne 1b"
5930   [(set_attr "length" "4,5")
5931    (set_attr "isa" "no_tiny,tiny")
5932    (set_attr "cc" "clobber")])
5934 (define_insn "delay_cycles_3"
5935   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5936                      (const_int 3)]
5937                     UNSPECV_DELAY_CYCLES)
5938    (set (match_operand:BLK 1 "" "")
5939         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5940    (clobber (match_scratch:QI 2 "=&d"))
5941    (clobber (match_scratch:QI 3 "=&d"))
5942    (clobber (match_scratch:QI 4 "=&d"))]
5943   ""
5944   "ldi %2,lo8(%0)
5945         ldi %3,hi8(%0)
5946         ldi %4,hlo8(%0)
5947 1:      subi %2,1
5948         sbci %3,0
5949         sbci %4,0
5950         brne 1b"
5951   [(set_attr "length" "7")
5952    (set_attr "cc" "clobber")])
5954 (define_insn "delay_cycles_4"
5955   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5956                      (const_int 4)]
5957                     UNSPECV_DELAY_CYCLES)
5958    (set (match_operand:BLK 1 "" "")
5959         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5960    (clobber (match_scratch:QI 2 "=&d"))
5961    (clobber (match_scratch:QI 3 "=&d"))
5962    (clobber (match_scratch:QI 4 "=&d"))
5963    (clobber (match_scratch:QI 5 "=&d"))]
5964   ""
5965   "ldi %2,lo8(%0)
5966         ldi %3,hi8(%0)
5967         ldi %4,hlo8(%0)
5968         ldi %5,hhi8(%0)
5969 1:      subi %2,1
5970         sbci %3,0
5971         sbci %4,0
5972         sbci %5,0
5973         brne 1b"
5974   [(set_attr "length" "9")
5975    (set_attr "cc" "clobber")])
5978 ;; __builtin_avr_insert_bits
5980 (define_insn "insert_bits"
5981   [(set (match_operand:QI 0 "register_operand"              "=r  ,d  ,r")
5982         (unspec:QI [(match_operand:SI 1 "const_int_operand"  "C0f,Cxf,C0f")
5983                     (match_operand:QI 2 "register_operand"   "r  ,r  ,r")
5984                     (match_operand:QI 3 "nonmemory_operand"  "n  ,0  ,0")]
5985                    UNSPEC_INSERT_BITS))]
5986   ""
5987   {
5988     return avr_out_insert_bits (operands, NULL);
5989   }
5990   [(set_attr "adjust_len" "insert_bits")
5991    (set_attr "cc" "clobber")])
5994 ;; __builtin_avr_flash_segment
5996 ;; Just a helper for the next "official" expander.
5998 (define_expand "flash_segment1"
5999   [(set (match_operand:QI 0 "register_operand" "")
6000         (subreg:QI (match_operand:PSI 1 "register_operand" "")
6001                    2))
6002    (set (cc0)
6003         (compare (match_dup 0)
6004                  (const_int 0)))
6005    (set (pc)
6006         (if_then_else (ge (cc0)
6007                           (const_int 0))
6008                       (label_ref (match_operand 2 "" ""))
6009                       (pc)))
6010    (set (match_dup 0)
6011         (const_int -1))])
6013 (define_expand "flash_segment"
6014   [(parallel [(match_operand:QI 0 "register_operand" "")
6015               (match_operand:PSI 1 "register_operand" "")])]
6016   ""
6017   {
6018     rtx label = gen_label_rtx ();
6019     emit (gen_flash_segment1 (operands[0], operands[1], label));
6020     emit_label (label);
6021     DONE;
6022   })
6024 ;; Actually, it's too late now to work out address spaces known at compiletime.
6025 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
6026 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
6027 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
6029 (define_insn_and_split "*split.flash_segment"
6030   [(set (match_operand:QI 0 "register_operand"                        "=d")
6031         (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
6032                                (match_operand:HI 2 "register_operand"  "r"))
6033                    2))]
6034   ""
6035   { gcc_unreachable(); }
6036   ""
6037   [(set (match_dup 0)
6038         (match_dup 1))])
6041 ;; Parity
6043 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
6044 ;; better 8-bit parity recognition.
6046 (define_expand "parityhi2"
6047   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6048                    (parity:HI (match_operand:HI 1 "register_operand" "")))
6049               (clobber (reg:HI 24))])])
6051 (define_insn_and_split "*parityhi2"
6052   [(set (match_operand:HI 0 "register_operand"           "=r")
6053         (parity:HI (match_operand:HI 1 "register_operand" "r")))
6054    (clobber (reg:HI 24))]
6055   "!reload_completed"
6056   { gcc_unreachable(); }
6057   "&& 1"
6058   [(set (reg:HI 24)
6059         (match_dup 1))
6060    (set (reg:HI 24)
6061         (parity:HI (reg:HI 24)))
6062    (set (match_dup 0)
6063         (reg:HI 24))])
6065 (define_insn_and_split "*parityqihi2"
6066   [(set (match_operand:HI 0 "register_operand"           "=r")
6067         (parity:HI (match_operand:QI 1 "register_operand" "r")))
6068    (clobber (reg:HI 24))]
6069   "!reload_completed"
6070   { gcc_unreachable(); }
6071   "&& 1"
6072   [(set (reg:QI 24)
6073         (match_dup 1))
6074    (set (reg:HI 24)
6075         (zero_extend:HI (parity:QI (reg:QI 24))))
6076    (set (match_dup 0)
6077         (reg:HI 24))])
6079 (define_expand "paritysi2"
6080   [(set (reg:SI 22)
6081         (match_operand:SI 1 "register_operand" ""))
6082    (set (reg:HI 24)
6083         (truncate:HI (parity:SI (reg:SI 22))))
6084    (set (match_dup 2)
6085         (reg:HI 24))
6086    (set (match_operand:SI 0 "register_operand" "")
6087         (zero_extend:SI (match_dup 2)))]
6088   ""
6089   {
6090     operands[2] = gen_reg_rtx (HImode);
6091   })
6093 (define_insn "*parityhi2.libgcc"
6094   [(set (reg:HI 24)
6095         (parity:HI (reg:HI 24)))]
6096   ""
6097   "%~call __parityhi2"
6098   [(set_attr "type" "xcall")
6099    (set_attr "cc" "clobber")])
6101 (define_insn "*parityqihi2.libgcc"
6102   [(set (reg:HI 24)
6103         (zero_extend:HI (parity:QI (reg:QI 24))))]
6104   ""
6105   "%~call __parityqi2"
6106   [(set_attr "type" "xcall")
6107    (set_attr "cc" "clobber")])
6109 (define_insn "*paritysihi2.libgcc"
6110   [(set (reg:HI 24)
6111         (truncate:HI (parity:SI (reg:SI 22))))]
6112   ""
6113   "%~call __paritysi2"
6114   [(set_attr "type" "xcall")
6115    (set_attr "cc" "clobber")])
6118 ;; Popcount
6120 (define_expand "popcounthi2"
6121   [(set (reg:HI 24)
6122         (match_operand:HI 1 "register_operand" ""))
6123    (set (reg:HI 24)
6124         (popcount:HI (reg:HI 24)))
6125    (set (match_operand:HI 0 "register_operand" "")
6126         (reg:HI 24))]
6127   ""
6128   "")
6130 (define_expand "popcountsi2"
6131   [(set (reg:SI 22)
6132         (match_operand:SI 1 "register_operand" ""))
6133    (set (reg:HI 24)
6134         (truncate:HI (popcount:SI (reg:SI 22))))
6135    (set (match_dup 2)
6136         (reg:HI 24))
6137    (set (match_operand:SI 0 "register_operand" "")
6138         (zero_extend:SI (match_dup 2)))]
6139   ""
6140   {
6141     operands[2] = gen_reg_rtx (HImode);
6142   })
6144 (define_insn "*popcounthi2.libgcc"
6145   [(set (reg:HI 24)
6146         (popcount:HI (reg:HI 24)))]
6147   ""
6148   "%~call __popcounthi2"
6149   [(set_attr "type" "xcall")
6150    (set_attr "cc" "clobber")])
6152 (define_insn "*popcountsi2.libgcc"
6153   [(set (reg:HI 24)
6154         (truncate:HI (popcount:SI (reg:SI 22))))]
6155   ""
6156   "%~call __popcountsi2"
6157   [(set_attr "type" "xcall")
6158    (set_attr "cc" "clobber")])
6160 (define_insn "*popcountqi2.libgcc"
6161   [(set (reg:QI 24)
6162         (popcount:QI (reg:QI 24)))]
6163   ""
6164   "%~call __popcountqi2"
6165   [(set_attr "type" "xcall")
6166    (set_attr "cc" "clobber")])
6168 (define_insn_and_split "*popcountqihi2.libgcc"
6169   [(set (reg:HI 24)
6170         (zero_extend:HI (popcount:QI (reg:QI 24))))]
6171   ""
6172   "#"
6173   ""
6174   [(set (reg:QI 24)
6175         (popcount:QI (reg:QI 24)))
6176    (set (reg:QI 25)
6177         (const_int 0))])
6179 ;; Count Leading Zeros
6181 (define_expand "clzhi2"
6182   [(set (reg:HI 24)
6183         (match_operand:HI 1 "register_operand" ""))
6184    (parallel [(set (reg:HI 24)
6185                    (clz:HI (reg:HI 24)))
6186               (clobber (reg:QI 26))])
6187    (set (match_operand:HI 0 "register_operand" "")
6188         (reg:HI 24))])
6190 (define_expand "clzsi2"
6191   [(set (reg:SI 22)
6192         (match_operand:SI 1 "register_operand" ""))
6193    (parallel [(set (reg:HI 24)
6194                    (truncate:HI (clz:SI (reg:SI 22))))
6195               (clobber (reg:QI 26))])
6196    (set (match_dup 2)
6197         (reg:HI 24))
6198    (set (match_operand:SI 0 "register_operand" "")
6199         (zero_extend:SI (match_dup 2)))]
6200   ""
6201   {
6202     operands[2] = gen_reg_rtx (HImode);
6203   })
6205 (define_insn "*clzhi2.libgcc"
6206   [(set (reg:HI 24)
6207         (clz:HI (reg:HI 24)))
6208    (clobber (reg:QI 26))]
6209   ""
6210   "%~call __clzhi2"
6211   [(set_attr "type" "xcall")
6212    (set_attr "cc" "clobber")])
6214 (define_insn "*clzsihi2.libgcc"
6215   [(set (reg:HI 24)
6216         (truncate:HI (clz:SI (reg:SI 22))))
6217    (clobber (reg:QI 26))]
6218   ""
6219   "%~call __clzsi2"
6220   [(set_attr "type" "xcall")
6221    (set_attr "cc" "clobber")])
6223 ;; Count Trailing Zeros
6225 (define_expand "ctzhi2"
6226   [(set (reg:HI 24)
6227         (match_operand:HI 1 "register_operand" ""))
6228    (parallel [(set (reg:HI 24)
6229                    (ctz:HI (reg:HI 24)))
6230               (clobber (reg:QI 26))])
6231    (set (match_operand:HI 0 "register_operand" "")
6232         (reg:HI 24))])
6234 (define_expand "ctzsi2"
6235   [(set (reg:SI 22)
6236         (match_operand:SI 1 "register_operand" ""))
6237    (parallel [(set (reg:HI 24)
6238                    (truncate:HI (ctz:SI (reg:SI 22))))
6239               (clobber (reg:QI 22))
6240               (clobber (reg:QI 26))])
6241    (set (match_dup 2)
6242         (reg:HI 24))
6243    (set (match_operand:SI 0 "register_operand" "")
6244         (zero_extend:SI (match_dup 2)))]
6245   ""
6246   {
6247     operands[2] = gen_reg_rtx (HImode);
6248   })
6250 (define_insn "*ctzhi2.libgcc"
6251   [(set (reg:HI 24)
6252         (ctz:HI (reg:HI 24)))
6253    (clobber (reg:QI 26))]
6254   ""
6255   "%~call __ctzhi2"
6256   [(set_attr "type" "xcall")
6257    (set_attr "cc" "clobber")])
6259 (define_insn "*ctzsihi2.libgcc"
6260   [(set (reg:HI 24)
6261         (truncate:HI (ctz:SI (reg:SI 22))))
6262    (clobber (reg:QI 22))
6263    (clobber (reg:QI 26))]
6264   ""
6265   "%~call __ctzsi2"
6266   [(set_attr "type" "xcall")
6267    (set_attr "cc" "clobber")])
6269 ;; Find First Set
6271 (define_expand "ffshi2"
6272   [(set (reg:HI 24)
6273         (match_operand:HI 1 "register_operand" ""))
6274    (parallel [(set (reg:HI 24)
6275                    (ffs:HI (reg:HI 24)))
6276               (clobber (reg:QI 26))])
6277    (set (match_operand:HI 0 "register_operand" "")
6278         (reg:HI 24))])
6280 (define_expand "ffssi2"
6281   [(set (reg:SI 22)
6282         (match_operand:SI 1 "register_operand" ""))
6283    (parallel [(set (reg:HI 24)
6284                    (truncate:HI (ffs:SI (reg:SI 22))))
6285               (clobber (reg:QI 22))
6286               (clobber (reg:QI 26))])
6287    (set (match_dup 2)
6288         (reg:HI 24))
6289    (set (match_operand:SI 0 "register_operand" "")
6290         (zero_extend:SI (match_dup 2)))]
6291   ""
6292   {
6293     operands[2] = gen_reg_rtx (HImode);
6294   })
6296 (define_insn "*ffshi2.libgcc"
6297   [(set (reg:HI 24)
6298         (ffs:HI (reg:HI 24)))
6299    (clobber (reg:QI 26))]
6300   ""
6301   "%~call __ffshi2"
6302   [(set_attr "type" "xcall")
6303    (set_attr "cc" "clobber")])
6305 (define_insn "*ffssihi2.libgcc"
6306   [(set (reg:HI 24)
6307         (truncate:HI (ffs:SI (reg:SI 22))))
6308    (clobber (reg:QI 22))
6309    (clobber (reg:QI 26))]
6310   ""
6311   "%~call __ffssi2"
6312   [(set_attr "type" "xcall")
6313    (set_attr "cc" "clobber")])
6315 ;; Copysign
6317 (define_insn "copysignsf3"
6318   [(set (match_operand:SF 0 "register_operand"             "=r")
6319         (unspec:SF [(match_operand:SF 1 "register_operand"  "0")
6320                     (match_operand:SF 2 "register_operand"  "r")]
6321                    UNSPEC_COPYSIGN))]
6322   ""
6323   "bst %D2,7\;bld %D0,7"
6324   [(set_attr "length" "2")
6325    (set_attr "cc" "none")])
6327 ;; Swap Bytes (change byte-endianness)
6329 (define_expand "bswapsi2"
6330   [(set (reg:SI 22)
6331         (match_operand:SI 1 "register_operand" ""))
6332    (set (reg:SI 22)
6333         (bswap:SI (reg:SI 22)))
6334    (set (match_operand:SI 0 "register_operand" "")
6335         (reg:SI 22))])
6337 (define_insn "*bswapsi2.libgcc"
6338   [(set (reg:SI 22)
6339         (bswap:SI (reg:SI 22)))]
6340   ""
6341   "%~call __bswapsi2"
6342   [(set_attr "type" "xcall")
6343    (set_attr "cc" "clobber")])
6346 ;; CPU instructions
6348 ;; NOP taking 1 or 2 Ticks
6349 (define_expand "nopv"
6350   [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
6351                                UNSPECV_NOP)
6352               (set (match_dup 1)
6353                    (unspec_volatile:BLK [(match_dup 1)]
6354                                         UNSPECV_MEMORY_BARRIER))])]
6355   ""
6356   {
6357     operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6358     MEM_VOLATILE_P (operands[1]) = 1;
6359   })
6361 (define_insn "*nopv"
6362   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6363                     UNSPECV_NOP)
6364    (set (match_operand:BLK 1 "" "")
6365         (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6366   ""
6367   "@
6368         nop
6369         rjmp ."
6370   [(set_attr "length" "1")
6371    (set_attr "cc" "none")])
6373 ;; SLEEP
6374 (define_expand "sleep"
6375   [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6376               (set (match_dup 0)
6377                    (unspec_volatile:BLK [(match_dup 0)]
6378                                         UNSPECV_MEMORY_BARRIER))])]
6379   ""
6380   {
6381     operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6382     MEM_VOLATILE_P (operands[0]) = 1;
6383   })
6385 (define_insn "*sleep"
6386   [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6387    (set (match_operand:BLK 0 "" "")
6388         (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6389   ""
6390   "sleep"
6391   [(set_attr "length" "1")
6392    (set_attr "cc" "none")])
6394 ;; WDR
6395 (define_expand "wdr"
6396   [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6397               (set (match_dup 0)
6398                    (unspec_volatile:BLK [(match_dup 0)]
6399                                         UNSPECV_MEMORY_BARRIER))])]
6400   ""
6401   {
6402     operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6403     MEM_VOLATILE_P (operands[0]) = 1;
6404   })
6406 (define_insn "*wdr"
6407   [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6408    (set (match_operand:BLK 0 "" "")
6409         (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6410   ""
6411   "wdr"
6412   [(set_attr "length" "1")
6413    (set_attr "cc" "none")])
6415 ;; FMUL
6416 (define_expand "fmul"
6417   [(set (reg:QI 24)
6418         (match_operand:QI 1 "register_operand" ""))
6419    (set (reg:QI 25)
6420         (match_operand:QI 2 "register_operand" ""))
6421    (parallel [(set (reg:HI 22)
6422                    (unspec:HI [(reg:QI 24)
6423                                (reg:QI 25)] UNSPEC_FMUL))
6424               (clobber (reg:HI 24))])
6425    (set (match_operand:HI 0 "register_operand" "")
6426         (reg:HI 22))]
6427   ""
6428   {
6429     if (AVR_HAVE_MUL)
6430       {
6431         emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6432         DONE;
6433       }
6434     avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6435   })
6437 (define_insn "fmul_insn"
6438   [(set (match_operand:HI 0 "register_operand" "=r")
6439         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6440                     (match_operand:QI 2 "register_operand" "a")]
6441                    UNSPEC_FMUL))]
6442   "AVR_HAVE_MUL"
6443   "fmul %1,%2
6444         movw %0,r0
6445         clr __zero_reg__"
6446   [(set_attr "length" "3")
6447    (set_attr "cc" "clobber")])
6449 (define_insn "*fmul.call"
6450   [(set (reg:HI 22)
6451         (unspec:HI [(reg:QI 24)
6452                     (reg:QI 25)] UNSPEC_FMUL))
6453    (clobber (reg:HI 24))]
6454   "!AVR_HAVE_MUL"
6455   "%~call __fmul"
6456   [(set_attr "type" "xcall")
6457    (set_attr "cc" "clobber")])
6459 ;; FMULS
6460 (define_expand "fmuls"
6461   [(set (reg:QI 24)
6462         (match_operand:QI 1 "register_operand" ""))
6463    (set (reg:QI 25)
6464         (match_operand:QI 2 "register_operand" ""))
6465    (parallel [(set (reg:HI 22)
6466                    (unspec:HI [(reg:QI 24)
6467                                (reg:QI 25)] UNSPEC_FMULS))
6468               (clobber (reg:HI 24))])
6469    (set (match_operand:HI 0 "register_operand" "")
6470         (reg:HI 22))]
6471   ""
6472   {
6473     if (AVR_HAVE_MUL)
6474       {
6475         emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6476         DONE;
6477       }
6478     avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6479   })
6481 (define_insn "fmuls_insn"
6482   [(set (match_operand:HI 0 "register_operand" "=r")
6483         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6484                     (match_operand:QI 2 "register_operand" "a")]
6485                    UNSPEC_FMULS))]
6486   "AVR_HAVE_MUL"
6487   "fmuls %1,%2
6488         movw %0,r0
6489         clr __zero_reg__"
6490   [(set_attr "length" "3")
6491    (set_attr "cc" "clobber")])
6493 (define_insn "*fmuls.call"
6494   [(set (reg:HI 22)
6495         (unspec:HI [(reg:QI 24)
6496                     (reg:QI 25)] UNSPEC_FMULS))
6497    (clobber (reg:HI 24))]
6498   "!AVR_HAVE_MUL"
6499   "%~call __fmuls"
6500   [(set_attr "type" "xcall")
6501    (set_attr "cc" "clobber")])
6503 ;; FMULSU
6504 (define_expand "fmulsu"
6505   [(set (reg:QI 24)
6506         (match_operand:QI 1 "register_operand" ""))
6507    (set (reg:QI 25)
6508         (match_operand:QI 2 "register_operand" ""))
6509    (parallel [(set (reg:HI 22)
6510                    (unspec:HI [(reg:QI 24)
6511                                (reg:QI 25)] UNSPEC_FMULSU))
6512               (clobber (reg:HI 24))])
6513    (set (match_operand:HI 0 "register_operand" "")
6514         (reg:HI 22))]
6515   ""
6516   {
6517     if (AVR_HAVE_MUL)
6518       {
6519         emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6520         DONE;
6521       }
6522     avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6523   })
6525 (define_insn "fmulsu_insn"
6526   [(set (match_operand:HI 0 "register_operand" "=r")
6527         (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6528                     (match_operand:QI 2 "register_operand" "a")]
6529                    UNSPEC_FMULSU))]
6530   "AVR_HAVE_MUL"
6531   "fmulsu %1,%2
6532         movw %0,r0
6533         clr __zero_reg__"
6534   [(set_attr "length" "3")
6535    (set_attr "cc" "clobber")])
6537 (define_insn "*fmulsu.call"
6538   [(set (reg:HI 22)
6539         (unspec:HI [(reg:QI 24)
6540                     (reg:QI 25)] UNSPEC_FMULSU))
6541    (clobber (reg:HI 24))]
6542   "!AVR_HAVE_MUL"
6543   "%~call __fmulsu"
6544   [(set_attr "type" "xcall")
6545    (set_attr "cc" "clobber")])
6548 ;; Some combiner patterns dealing with bits.
6549 ;; See PR42210
6551 ;; Move bit $3.0 into bit $0.$4
6552 (define_insn "*movbitqi.1-6.a"
6553   [(set (match_operand:QI 0 "register_operand"                               "=r")
6554         (ior:QI (and:QI (match_operand:QI 1 "register_operand"                "0")
6555                         (match_operand:QI 2 "single_zero_operand"             "n"))
6556                 (and:QI (ashift:QI (match_operand:QI 3 "register_operand"     "r")
6557                                    (match_operand:QI 4 "const_0_to_7_operand" "n"))
6558                         (match_operand:QI 5 "single_one_operand"              "n"))))]
6559   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6560    && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6561   "bst %3,0\;bld %0,%4"
6562   [(set_attr "length" "2")
6563    (set_attr "cc" "none")])
6565 ;; Move bit $3.0 into bit $0.$4
6566 ;; Variation of above. Unfortunately, there is no canonicalized representation
6567 ;; of moving around bits.  So what we see here depends on how user writes down
6568 ;; bit manipulations.
6569 (define_insn "*movbitqi.1-6.b"
6570   [(set (match_operand:QI 0 "register_operand"                            "=r")
6571         (ior:QI (and:QI (match_operand:QI 1 "register_operand"             "0")
6572                         (match_operand:QI 2 "single_zero_operand"          "n"))
6573                 (ashift:QI (and:QI (match_operand:QI 3 "register_operand"  "r")
6574                                    (const_int 1))
6575                            (match_operand:QI 4 "const_0_to_7_operand"      "n"))))]
6576   "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6577   "bst %3,0\;bld %0,%4"
6578   [(set_attr "length" "2")
6579    (set_attr "cc" "none")])
6581 ;; Move bit $3.0 into bit $0.0.
6582 ;; For bit 0, combiner generates slightly different pattern.
6583 (define_insn "*movbitqi.0"
6584   [(set (match_operand:QI 0 "register_operand"                     "=r")
6585         (ior:QI (and:QI (match_operand:QI 1 "register_operand"      "0")
6586                         (match_operand:QI 2 "single_zero_operand"   "n"))
6587                 (and:QI (match_operand:QI 3 "register_operand"      "r")
6588                         (const_int 1))))]
6589   "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6590   "bst %3,0\;bld %0,0"
6591   [(set_attr "length" "2")
6592    (set_attr "cc" "none")])
6594 ;; Move bit $2.0 into bit $0.7.
6595 ;; For bit 7, combiner generates slightly different pattern
6596 (define_insn "*movbitqi.7"
6597   [(set (match_operand:QI 0 "register_operand"                      "=r")
6598         (ior:QI (and:QI (match_operand:QI 1 "register_operand"       "0")
6599                         (const_int 127))
6600                 (ashift:QI (match_operand:QI 2 "register_operand"    "r")
6601                            (const_int 7))))]
6602   ""
6603   "bst %2,0\;bld %0,7"
6604   [(set_attr "length" "2")
6605    (set_attr "cc" "none")])
6607 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6608 ;; and input/output match.  We provide a special pattern for this, because
6609 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6610 ;; operation on I/O is atomic.
6611 (define_insn "*insv.io"
6612   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
6613                          (const_int 1)
6614                          (match_operand:QI 1 "const_0_to_7_operand"        "n,n,n"))
6615         (match_operand:QI 2 "nonmemory_operand"                            "L,P,r"))]
6616   ""
6617   "@
6618         cbi %i0,%1
6619         sbi %i0,%1
6620         sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6621   [(set_attr "length" "1,1,4")
6622    (set_attr "cc" "none")])
6624 (define_insn "*insv.not.io"
6625   [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
6626                          (const_int 1)
6627                          (match_operand:QI 1 "const_0_to_7_operand"        "n"))
6628         (not:QI (match_operand:QI 2 "register_operand"                     "r")))]
6629   ""
6630   "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6631   [(set_attr "length" "4")
6632    (set_attr "cc" "none")])
6634 ;; The insv expander.
6635 ;; We only support 1-bit inserts
6636 (define_expand "insv"
6637   [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6638                          (match_operand:QI 1 "const1_operand" "")        ; width
6639                          (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6640         (match_operand:QI 3 "nonmemory_operand" ""))]
6641   "optimize")
6643 ;; Some more patterns to support moving around one bit which can be accomplished
6644 ;; by BST + BLD in most situations.  Unfortunately, there is no canonical
6645 ;; representation, and we just implement some more cases that are not too
6646 ;; complicated.
6648 ;; Insert bit $2.0 into $0.$1
6649 (define_insn "*insv.reg"
6650   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r,d,d,l,l")
6651                          (const_int 1)
6652                          (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6653         (match_operand:QI 2 "nonmemory_operand"                     "r,L,P,L,P"))]
6654   ""
6655   "@
6656         bst %2,0\;bld %0,%1
6657         andi %0,lo8(~(1<<%1))
6658         ori %0,lo8(1<<%1)
6659         clt\;bld %0,%1
6660         set\;bld %0,%1"
6661   [(set_attr "length" "2,1,1,2,2")
6662    (set_attr "cc" "none,set_zn,set_zn,none,none")])
6664 ;; Insert bit $2.$3 into $0.$1
6665 (define_insn "*insv.extract"
6666   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r")
6667                          (const_int 1)
6668                          (match_operand:QI 1 "const_0_to_7_operand" "n"))
6669         (any_extract:QI (match_operand:QI 2 "register_operand"      "r")
6670                         (const_int 1)
6671                         (match_operand:QI 3 "const_0_to_7_operand"  "n")))]
6672   ""
6673   "bst %2,%3\;bld %0,%1"
6674   [(set_attr "length" "2")
6675    (set_attr "cc" "none")])
6677 ;; Insert bit $2.$3 into $0.$1
6678 (define_insn "*insv.shiftrt"
6679   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r")
6680                          (const_int 1)
6681                          (match_operand:QI 1 "const_0_to_7_operand" "n"))
6682         (any_shiftrt:QI (match_operand:QI 2 "register_operand"      "r")
6683                         (match_operand:QI 3 "const_0_to_7_operand"  "n")))]
6684   ""
6685   "bst %2,%3\;bld %0,%1"
6686   [(set_attr "length" "2")
6687    (set_attr "cc" "none")])
6689 ;; Same, but with a NOT inverting the source bit.
6690 ;; Insert bit ~$2.$3 into $0.$1
6691 (define_insn "*insv.not-shiftrt"
6692   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"           "+r")
6693                          (const_int 1)
6694                          (match_operand:QI 1 "const_0_to_7_operand"        "n"))
6695         (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand"     "r")
6696                                 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
6697   ""
6698   {
6699     return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6700   }
6701   [(set_attr "adjust_len" "insv_notbit")
6702    (set_attr "cc" "clobber")])
6704 ;; Insert bit ~$2.0 into $0.$1
6705 (define_insn "*insv.xor1-bit.0"
6706   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r")
6707                          (const_int 1)
6708                          (match_operand:QI 1 "const_0_to_7_operand" "n"))
6709         (xor:QI (match_operand:QI 2 "register_operand"              "r")
6710                 (const_int 1)))]
6711   ""
6712   {
6713     return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6714   }
6715   [(set_attr "adjust_len" "insv_notbit_0")
6716    (set_attr "cc" "clobber")])
6718 ;; Insert bit ~$2.0 into $0.$1
6719 (define_insn "*insv.not-bit.0"
6720   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r")
6721                          (const_int 1)
6722                          (match_operand:QI 1 "const_0_to_7_operand" "n"))
6723         (not:QI (match_operand:QI 2 "register_operand"              "r")))]
6724   ""
6725   {
6726     return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6727   }
6728   [(set_attr "adjust_len" "insv_notbit_0")
6729    (set_attr "cc" "clobber")])
6731 ;; Insert bit ~$2.7 into $0.$1
6732 (define_insn "*insv.not-bit.7"
6733   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"    "+r")
6734                          (const_int 1)
6735                          (match_operand:QI 1 "const_0_to_7_operand" "n"))
6736         (ge:QI (match_operand:QI 2 "register_operand"               "r")
6737                (const_int 0)))]
6738   ""
6739   {
6740     return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
6741   }
6742   [(set_attr "adjust_len" "insv_notbit_7")
6743    (set_attr "cc" "clobber")])
6745 ;; Insert bit ~$2.$3 into $0.$1
6746 (define_insn "*insv.xor-extract"
6747   [(set (zero_extract:QI (match_operand:QI 0 "register_operand"        "+r")
6748                          (const_int 1)
6749                          (match_operand:QI 1 "const_0_to_7_operand"     "n"))
6750         (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand"  "r")
6751                                 (match_operand:QI 4 "const_int_operand" "n"))
6752                         (const_int 1)
6753                         (match_operand:QI 3 "const_0_to_7_operand"      "n")))]
6754   "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
6755   {
6756     return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6757   }
6758   [(set_attr "adjust_len" "insv_notbit")
6759    (set_attr "cc" "clobber")])
6762 ;; Some combine patterns that try to fix bad code when a value is composed
6763 ;; from byte parts like in PR27663.
6764 ;; The patterns give some release but the code still is not optimal,
6765 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6766 ;; That switch obfuscates things here and in many other places.
6768 ;; "*iorhiqi.byte0"   "*iorpsiqi.byte0"   "*iorsiqi.byte0"
6769 ;; "*xorhiqi.byte0"   "*xorpsiqi.byte0"   "*xorsiqi.byte0"
6770 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6771   [(set (match_operand:HISI 0 "register_operand"                 "=r")
6772         (xior:HISI
6773          (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6774          (match_operand:HISI 2 "register_operand"                 "0")))]
6775   ""
6776   "#"
6777   "reload_completed"
6778   [(set (match_dup 3)
6779         (xior:QI (match_dup 3)
6780                  (match_dup 1)))]
6781   {
6782     operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6783   })
6785 ;; "*iorhiqi.byte1-3"  "*iorpsiqi.byte1-3"  "*iorsiqi.byte1-3"
6786 ;; "*xorhiqi.byte1-3"  "*xorpsiqi.byte1-3"  "*xorsiqi.byte1-3"
6787 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6788   [(set (match_operand:HISI 0 "register_operand"                              "=r")
6789         (xior:HISI
6790          (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6791                       (match_operand:QI 2 "const_8_16_24_operand"              "n"))
6792          (match_operand:HISI 3 "register_operand"                              "0")))]
6793   "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6794   "#"
6795   "&& reload_completed"
6796   [(set (match_dup 4)
6797         (xior:QI (match_dup 4)
6798                  (match_dup 1)))]
6799   {
6800     int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6801     operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6802   })
6805 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
6806   [(set (match_operand:HI 0 "register_operand"                        "=r,r")
6807         (ior:HI (ashift:HI (any_extend:HI
6808                             (match_operand:QI 1 "register_operand"     "r,r"))
6809                            (const_int 8))
6810                 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))]
6811   "optimize"
6812   { gcc_unreachable(); }
6813   "&& reload_completed"
6814   [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
6815    (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
6816    (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
6817   {
6818     rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6819     rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6821     if (!reg_overlap_mentioned_p (hi, operands[2]))
6822       {
6823         emit_move_insn (hi, operands[1]);
6824         emit_move_insn (lo, operands[2]);
6825         DONE;
6826       }
6827     else if (!reg_overlap_mentioned_p (lo, operands[1]))
6828       {
6829         emit_move_insn (lo, operands[2]);
6830         emit_move_insn (hi, operands[1]);
6831         DONE;
6832       }
6834     gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
6835     gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
6836   })
6838 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
6839   [(set (match_operand:HI 0 "register_operand"                    "=r")
6840         (ior:HI (ashift:HI (any_extend:HI
6841                             (match_operand:QI 1 "register_operand" "r"))
6842                            (const_int 8))
6843                 (match_operand:HI 2 "register_operand"             "0")))]
6844   "optimize"
6845   { gcc_unreachable(); }
6846   "&& reload_completed"
6847   [(set (match_dup 3)
6848         (ior:QI (match_dup 4)
6849                 (match_dup 1)))]
6850   {
6851     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6852     operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
6853   })
6855 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
6856   [(set (match_operand:HI 0 "register_operand"                        "=r")
6857         (ior:HI (ashift:HI (match_operand:HI 1 "register_operand"      "r")
6858                            (const_int 8))
6859                 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
6860   "optimize"
6861   { gcc_unreachable(); }
6862   "&& reload_completed"
6863   [(set (match_dup 3)
6864         (match_dup 4))]
6865   {
6866     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6867     operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
6868   })
6871 (define_peephole2
6872   [(set (match_operand:QI 0 "register_operand")
6873         (const_int 0))
6874    (set (match_dup 0)
6875         (ior:QI (match_dup 0)
6876                 (match_operand:QI 1 "register_operand")))]
6877   ""
6878   [(set (match_dup 0)
6879         (match_dup 1))])
6882 (define_expand "extzv"
6883   [(set (match_operand:QI 0 "register_operand" "")
6884         (zero_extract:QI (match_operand:QI 1 "register_operand"  "")
6885                          (match_operand:QI 2 "const1_operand" "")
6886                          (match_operand:QI 3 "const_0_to_7_operand" "")))])
6888 (define_insn "*extzv"
6889   [(set (match_operand:QI 0 "register_operand"                   "=*d,*d,*d,*d,r")
6890         (zero_extract:QI (match_operand:QI 1 "register_operand"     "0,r,0,0,r")
6891                          (const_int 1)
6892                          (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6893   ""
6894   "@
6895         andi %0,1
6896         mov %0,%1\;andi %0,1
6897         lsr %0\;andi %0,1
6898         swap %0\;andi %0,1
6899         bst %1,%2\;clr %0\;bld %0,0"
6900   [(set_attr "length" "1,2,2,2,3")
6901    (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6903 (define_insn_and_split "*extzv.qihi1"
6904   [(set (match_operand:HI 0 "register_operand"                     "=r")
6905         (zero_extract:HI (match_operand:QI 1 "register_operand"     "r")
6906                          (const_int 1)
6907                          (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6908   ""
6909   "#"
6910   ""
6911   [(set (match_dup 3)
6912         (zero_extract:QI (match_dup 1)
6913                          (const_int 1)
6914                          (match_dup 2)))
6915    (set (match_dup 4)
6916         (const_int 0))]
6917   {
6918     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6919     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6920   })
6922 (define_insn_and_split "*extzv.qihi2"
6923   [(set (match_operand:HI 0 "register_operand"                      "=r")
6924         (zero_extend:HI
6925          (zero_extract:QI (match_operand:QI 1 "register_operand"     "r")
6926                           (const_int 1)
6927                           (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6928   ""
6929   "#"
6930   ""
6931   [(set (match_dup 3)
6932         (zero_extract:QI (match_dup 1)
6933                          (const_int 1)
6934                          (match_dup 2)))
6935    (set (match_dup 4)
6936         (const_int 0))]
6937   {
6938     operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6939     operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6940   })
6942 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
6943 ;; even considering rtx_costs, extzv, or a bit-test.  See PR 55181 for an example.
6944 (define_insn_and_split "*extract.subreg.bit"
6945   [(set (match_operand:QI 0 "register_operand"                                       "=r")
6946         (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
6947                                              (match_operand:QI 2 "const_int_operand"  "n"))
6948                            0)
6949                 (const_int 1)))]
6950   "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6951   { gcc_unreachable(); }
6952   "&& reload_completed"
6953   [;; "*extzv"
6954    (set (match_dup 0)
6955         (zero_extract:QI (match_dup 3)
6956                          (const_int 1)
6957                          (match_dup 4)))]
6958   {
6959     int bitno = INTVAL (operands[2]);
6960     operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
6961     operands[4] = GEN_INT (bitno % 8);
6962   })
6965 ;; Fixed-point instructions
6966 (include "avr-fixed.md")
6968 ;; Operations on 64-bit registers
6969 (include "avr-dimode.md")