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