1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2023 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)
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.
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.
62 (LPM_REGNO 0) ; implicit target register of LPM
63 (TMP_REGNO 0) ; temporary register r0
64 (ZERO_REGNO 1) ; zero register r1
68 [(TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY
69 (ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY
72 (define_c_enum "unspec"
84 (define_c_enum "unspecv"
85 [UNSPECV_PROLOGUE_SAVES
86 UNSPECV_EPILOGUE_RESTORES
91 UNSPECV_MEMORY_BARRIER
98 ;; Chunk numbers for __gcc_isr are hard-coded in GAS.
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,
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))
123 (le (minus (pc) (match_dup 0))
126 (if_then_else (and (ge (minus (pc) (match_dup 0))
128 (le (minus (pc) (match_dup 0))
132 (eq_attr "type" "branch1")
133 (if_then_else (and (ge (minus (pc) (match_dup 0))
135 (le (minus (pc) (match_dup 0))
138 (if_then_else (and (ge (minus (pc) (match_dup 0))
140 (le (minus (pc) (match_dup 0))
144 (eq_attr "type" "xcall")
145 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
150 ;; Lengths of several insns are adjusted in avr.cc:adjust_insn_length().
151 ;; Following insn attribute tells if and how the adjustment has to be
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,
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 add_set_ZN, cmp_uext, cmp_sext,
171 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
173 ;; mov : ISA has no MOVW movw : ISA has MOVW
174 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
175 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
176 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
177 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
178 ;; no_xmega: non-XMEGA core xmega : XMEGA core
179 ;; no_tiny: non-TINY core tiny : TINY core
182 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
184 (const_string "standard"))
186 (define_attr "enabled" ""
187 (cond [(eq_attr "isa" "standard")
190 (and (eq_attr "isa" "mov")
191 (match_test "!AVR_HAVE_MOVW"))
194 (and (eq_attr "isa" "movw")
195 (match_test "AVR_HAVE_MOVW"))
198 (and (eq_attr "isa" "rjmp")
199 (match_test "!AVR_HAVE_JMP_CALL"))
202 (and (eq_attr "isa" "jmp")
203 (match_test "AVR_HAVE_JMP_CALL"))
206 (and (eq_attr "isa" "ijmp")
207 (match_test "!AVR_HAVE_EIJMP_EICALL"))
210 (and (eq_attr "isa" "eijmp")
211 (match_test "AVR_HAVE_EIJMP_EICALL"))
214 (and (eq_attr "isa" "lpm")
215 (match_test "!AVR_HAVE_LPMX"))
218 (and (eq_attr "isa" "lpmx")
219 (match_test "AVR_HAVE_LPMX"))
222 (and (eq_attr "isa" "elpm")
223 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
226 (and (eq_attr "isa" "elpmx")
227 (match_test "AVR_HAVE_ELPMX"))
230 (and (eq_attr "isa" "xmega")
231 (match_test "AVR_XMEGA"))
234 (and (eq_attr "isa" "tiny")
235 (match_test "AVR_TINY"))
238 (and (eq_attr "isa" "no_xmega")
239 (match_test "!AVR_XMEGA"))
242 (and (eq_attr "isa" "no_tiny")
243 (match_test "!AVR_TINY"))
249 ;; Define mode iterators
250 (define_mode_iterator QIHI [QI HI])
251 (define_mode_iterator QIHI2 [QI HI])
252 (define_mode_iterator QISI [QI HI PSI SI])
253 (define_mode_iterator QIDI [QI HI PSI SI DI])
254 (define_mode_iterator QIPSI [QI HI PSI])
255 (define_mode_iterator HISI [HI PSI SI])
257 ;; Ordered integral and fixed-point modes of specific sizes.
258 (define_mode_iterator ALL1 [QI QQ UQQ])
259 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
260 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
261 (define_mode_iterator ALL234 [HI SI PSI
265 ;; Ordered signed integral and signed fixed-point modes of specific sizes.
266 (define_mode_iterator ALLs1 [QI QQ])
267 (define_mode_iterator ALLs2 [HI HQ HA])
268 (define_mode_iterator ALLs4 [SI SQ SA])
269 (define_mode_iterator ALLs234 [HI SI PSI
272 ;; All supported move-modes
273 (define_mode_iterator MOVMODE [QI QQ UQQ
278 ;; Supported ordered modes that are 2, 3, 4 bytes wide
279 (define_mode_iterator ORDERED234 [HI SI PSI
283 ;; Post-reload split of 3, 4 bytes wide moves.
284 (define_mode_iterator SPLIT34 [SI SF PSI
287 ;; Define code iterators
288 ;; Define two incarnations so that we can build the cartesian product.
289 (define_code_iterator any_extend [sign_extend zero_extend])
290 (define_code_iterator any_extend2 [sign_extend zero_extend])
291 (define_code_iterator any_extract [sign_extract zero_extract])
292 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
294 (define_code_iterator piaop [plus ior and])
295 (define_code_iterator bitop [xor ior and])
296 (define_code_iterator xior [xor ior])
297 (define_code_iterator eqne [eq ne])
298 (define_code_iterator gelt [ge lt])
300 (define_code_iterator ss_addsub [ss_plus ss_minus])
301 (define_code_iterator us_addsub [us_plus us_minus])
302 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
304 ;; Define code attributes
305 (define_code_attr extend_su
309 (define_code_attr extend_u
313 (define_code_attr extend_s
317 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
318 (define_code_attr mul_r_d
322 (define_code_attr abelian
323 [(ss_minus "") (us_minus "")
324 (ss_plus "%") (us_plus "%")])
326 (define_code_attr gelt_eqne
330 ;; Map RTX code to its standard insn name
331 (define_code_attr code_stdname
338 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
339 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
342 ;;========================================================================
343 ;; The following is used by nonlocal_goto and setjmp.
344 ;; The receiver pattern will create no instructions since internally
345 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
346 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
347 ;; The 'null' receiver also avoids problems with optimisation
348 ;; not recognising incoming jmp and removing code that resets frame_pointer.
349 ;; The code derived from builtins.cc.
351 (define_expand "nonlocal_goto_receiver"
353 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
356 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode);
357 emit_move_insn (virtual_stack_vars_rtx,
358 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset));
359 /* ; This might change the hard frame pointer in ways that aren't
360 ; apparent to early optimization passes, so force a clobber. */
361 emit_clobber (hard_frame_pointer_rtx);
366 ;; Defining nonlocal_goto_receiver means we must also define this
367 ;; even though its function is identical to that in builtins.cc
369 (define_expand "nonlocal_goto"
370 [(use (match_operand 0 "general_operand"))
371 (use (match_operand 1 "general_operand"))
372 (use (match_operand 2 "general_operand"))
373 (use (match_operand 3 "general_operand"))]
376 rtx r_label = copy_to_reg (operands[1]);
377 rtx r_fp = operands[3];
378 rtx r_sp = operands[2];
380 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
382 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
384 emit_move_insn (hard_frame_pointer_rtx, r_fp);
385 emit_stack_restore (SAVE_NONLOCAL, r_sp);
387 emit_use (hard_frame_pointer_rtx);
388 emit_use (stack_pointer_rtx);
390 emit_indirect_jump (r_label);
396 ;; "pushqq1" "pushuqq1"
397 (define_insn "push<mode>1"
398 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
399 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
404 [(set_attr "length" "1,1")])
406 (define_insn "pushhi1_insn"
407 [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
408 (match_operand:HI 0 "register_operand" "r"))]
411 [(set_attr "length" "2")])
413 ;; All modes for a multi-byte push. We must include complex modes here too,
414 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
415 (define_mode_iterator MPUSH
424 (define_expand "push<mode>1"
425 [(match_operand:MPUSH 0 "" "")]
428 if (MEM_P (operands[0])
429 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
431 // Avoid (subreg (mem)) for non-generic address spaces. Because
432 // of the poor addressing capabilities of these spaces it's better to
433 // load them in one chunk. And it avoids PR61443.
435 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
437 else if (REG_P (operands[0])
438 && VIRTUAL_REGISTER_P (operands[0]))
440 // Byte-wise pushing of virtual regs might result in something like
442 // (set (mem:QI (post_dec:HI (reg:HI 32 SP)))
443 // (subreg:QI (plus:HI (reg:HI 28)
444 // (const_int 17)) 0))
446 // after elimination. This cannot be handled by reload, cf. PR64452.
447 // Reload virtuals in one chunk. That way it's possible to reload
448 // above situation and finally
453 // (plus:HI (reg:HI **)
455 // (set (mem:HI (post_dec:HI (reg:HI 32 SP))
458 emit_insn (gen_pushhi1_insn (operands[0]));
462 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
464 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
465 if (part != const0_rtx)
466 part = force_reg (QImode, part);
467 emit_insn (gen_pushqi1 (part));
472 ;; Notice a special-case when adding N to SP where N results in a
473 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
475 [(set (reg:HI REG_SP)
476 (match_operand:HI 0 "register_operand" ""))]
478 && frame_pointer_needed
479 && !cfun->calls_alloca
480 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)
481 && REGNO (operands[0]) != REG_Y"
482 [(set (reg:HI REG_SP)
485 ;;========================================================================
493 (define_expand "load<mode>_libgcc"
496 (set (reg:MOVMODE 22)
497 (match_operand:MOVMODE 1 "memory_operand" ""))
498 (set (match_operand:MOVMODE 0 "register_operand" "")
500 "avr_load_libgcc_p (operands[1])"
502 operands[3] = gen_rtx_REG (HImode, REG_Z);
503 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
504 operands[1] = replace_equiv_address (operands[1], operands[3]);
505 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
513 (define_insn_and_split "load_<mode>_libgcc"
514 [(set (reg:MOVMODE 22)
515 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
516 "avr_load_libgcc_p (operands[0])
517 && REG_P (XEXP (operands[0], 0))
518 && REG_Z == REGNO (XEXP (operands[0], 0))"
520 "&& reload_completed"
521 [(parallel [(set (reg:MOVMODE 22)
523 (clobber (reg:CC REG_CC))])]
525 [(set_attr "isa" "rjmp,jmp")])
527 (define_insn "*load_<mode>_libgcc"
528 [(set (reg:MOVMODE 22)
529 (match_operand:MOVMODE 0 "memory_operand" "m,m"))
530 (clobber (reg:CC REG_CC))]
531 "avr_load_libgcc_p (operands[0])
532 && REG_P (XEXP (operands[0], 0))
533 && REG_Z == REGNO (XEXP (operands[0], 0))
536 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
537 return "%~call __load_%0";
539 [(set_attr "length" "1,2")
540 (set_attr "isa" "rjmp,jmp")])
544 ;; "xload8qq_A" "xload8uqq_A"
545 (define_insn_and_split "xload8<mode>_A"
546 [(set (match_operand:ALL1 0 "register_operand" "=r")
547 (match_operand:ALL1 1 "memory_operand" "m"))
548 (clobber (reg:HI REG_Z))]
549 "can_create_pseudo_p()
550 && !avr_xload_libgcc_p (<MODE>mode)
551 && avr_mem_memx_p (operands[1])
552 && REG_P (XEXP (operands[1], 0))"
553 { gcc_unreachable(); }
555 [(clobber (const_int 0))]
557 /* ; Split away the high part of the address. GCC's register allocator
558 ; in not able to allocate segment registers and reload the resulting
559 ; expressions. Notice that no address register can hold a PSImode. */
562 rtx addr = XEXP (operands[1], 0);
563 rtx hi8 = gen_reg_rtx (QImode);
564 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
566 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
567 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
569 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
570 set_mem_addr_space (SET_SRC (single_set (insn)),
571 MEM_ADDR_SPACE (operands[1]));
575 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
576 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
577 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
580 (define_insn_and_split "xload<mode>_A"
581 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
582 (match_operand:MOVMODE 1 "memory_operand" "m"))
583 (clobber (reg:MOVMODE 22))
584 (clobber (reg:QI 21))
585 (clobber (reg:HI REG_Z))]
586 "can_create_pseudo_p()
587 && avr_mem_memx_p (operands[1])
588 && REG_P (XEXP (operands[1], 0))"
589 { gcc_unreachable(); }
591 [(clobber (const_int 0))]
593 rtx addr = XEXP (operands[1], 0);
594 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
595 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
596 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
599 /* Split the address to R21:Z */
600 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
601 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
603 /* Load with code from libgcc */
604 insn = emit_insn (gen_xload_<mode>_libgcc ());
605 set_mem_addr_space (SET_SRC (single_set (insn)), as);
607 /* Move to destination */
608 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
613 ;; Move value from address space memx to a register
614 ;; These insns must be prior to respective generic move insn.
617 ;; "xloadqq_8" "xloaduqq_8"
618 (define_insn "xload<mode>_8"
619 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
620 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
622 "!avr_xload_libgcc_p (<MODE>mode)"
624 return avr_out_xload (insn, operands, NULL);
626 [(set_attr "length" "4,4")
627 (set_attr "adjust_len" "*,xload")
628 (set_attr "isa" "lpmx,lpm")])
630 ;; R21:Z : 24-bit source address
631 ;; R22 : 1-4 byte output
633 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
634 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
635 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
637 ;; "xload_psi_libgcc"
639 (define_insn_and_split "xload_<mode>_libgcc"
640 [(set (reg:MOVMODE 22)
641 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
643 (clobber (reg:QI 21))
644 (clobber (reg:HI REG_Z))]
645 "avr_xload_libgcc_p (<MODE>mode)"
647 "&& reload_completed"
648 [(parallel [(set (reg:MOVMODE 22)
649 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
651 (clobber (reg:CC REG_CC))])])
653 (define_insn "*xload_<mode>_libgcc"
654 [(set (reg:MOVMODE 22)
655 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
657 (clobber (reg:CC REG_CC))]
658 "avr_xload_libgcc_p (<MODE>mode)
661 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
663 output_asm_insn ("%~call __xload_%0", &x_bytes);
666 [(set_attr "type" "xcall")])
669 ;; General move expanders
671 ;; "movqi" "movqq" "movuqq"
672 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
673 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
676 (define_expand "mov<mode>"
677 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
678 (match_operand:MOVMODE 1 "general_operand" ""))]
681 rtx dest = operands[0];
682 rtx src = avr_eval_addr_attrib (operands[1]);
684 if (avr_mem_flash_p (dest))
687 if (QImode == <MODE>mode
689 && CONSTANT_ADDRESS_P (SUBREG_REG (src))
690 && can_create_pseudo_p())
692 // store_bitfield may want to store a SYMBOL_REF or CONST in a
693 // structure that's represented as PSImode. As the upper 16 bits
694 // of PSImode cannot be expressed as an HImode subreg, the rhs is
695 // decomposed into QImode (word_mode) subregs of SYMBOL_REF,
696 // CONST or LABEL_REF; cf. PR71103.
698 rtx const_addr = SUBREG_REG (src);
699 operands[1] = src = copy_rtx (src);
700 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr);
703 /* One of the operands has to be in a register. */
704 if (!register_operand (dest, <MODE>mode)
705 && !reg_or_0_operand (src, <MODE>mode))
707 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
710 if (avr_mem_memx_p (src))
712 rtx addr = XEXP (src, 0);
715 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
717 if (!avr_xload_libgcc_p (<MODE>mode))
718 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
719 ; insn-emit does not depend on the mode, it's all about operands. */
720 emit_insn (gen_xload8qi_A (dest, src));
722 emit_insn (gen_xload<mode>_A (dest, src));
727 if (avr_load_libgcc_p (src))
729 /* For the small devices, do loads per libgcc call. */
730 emit_insn (gen_load<mode>_libgcc (dest, src));
735 ;;========================================================================
737 ;; The last alternative (any immediate constant to any register) is
738 ;; very expensive. It should be optimized by peephole2 if a scratch
739 ;; register is available, but then that register could just as well be
740 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
741 ;; are call-saved registers, and most of LD_REGS are call-used registers,
742 ;; so this may still be a win for registers live across function calls.
744 (define_insn_and_split "mov<mode>_insn_split"
745 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
746 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
747 "register_operand (operands[0], <MODE>mode)
748 || reg_or_0_operand (operands[1], <MODE>mode)"
750 "&& reload_completed"
751 [(parallel [(set (match_dup 0)
753 (clobber (reg:CC REG_CC))])])
756 ;; "movqq_insn" "movuqq_insn"
757 (define_insn "mov<mode>_insn"
758 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
759 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))
760 (clobber (reg:CC REG_CC))]
761 "(register_operand (operands[0], <MODE>mode)
762 || reg_or_0_operand (operands[1], <MODE>mode))
765 return output_movqi (insn, operands, NULL);
767 [(set_attr "length" "1,1,5,5,1,1,4")
768 (set_attr "adjust_len" "mov8")])
770 ;; This is used in peephole2 to optimize loading immediate constants
771 ;; if a scratch register from LD_REGS happens to be available.
774 ;; "*reload_inqq" "*reload_inuqq"
775 (define_insn "*reload_in<mode>"
776 [(set (match_operand:ALL1 0 "register_operand" "=l")
777 (match_operand:ALL1 1 "const_operand" "i"))
778 (clobber (match_operand:QI 2 "register_operand" "=&d"))
779 (clobber (reg:CC REG_CC))]
783 [(set_attr "length" "2")])
786 [(match_scratch:QI 2 "d")
787 (parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
788 (match_operand:ALL1 1 "const_operand" ""))
789 (clobber (reg:CC REG_CC))])]
790 ; No need for a clobber reg for 0x0, 0x01 or 0xff
791 "!satisfies_constraint_Y00 (operands[1])
792 && !satisfies_constraint_Y01 (operands[1])
793 && !satisfies_constraint_Ym1 (operands[1])"
794 [(parallel [(set (match_dup 0)
796 (clobber (match_dup 2))
797 (clobber (reg:CC REG_CC))])])
799 ;;============================================================================
800 ;; move word (16 bit)
802 ;; Move register $1 to the Stack Pointer register SP.
803 ;; This insn is emit during function prologue/epilogue generation.
804 ;; $2 = 0: We know that IRQs are off
805 ;; $2 = 1: We know that IRQs are on
806 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
807 ;; $2 = -1: We don't know anything about IRQ on/off
808 ;; Always write SP via unspec, see PR50063
810 (define_insn "movhi_sp_r"
811 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
812 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
813 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
817 out %B0,%B1\;out %A0,%A1
818 cli\;out %B0,%B1\;sei\;out %A0,%A1
819 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
821 out %A0,%A1\;out %B0,%B1"
822 [(set_attr "length" "2,4,5,1,2")
823 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")])
826 [(match_scratch:QI 2 "d")
827 (parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
828 (match_operand:ALL2 1 "const_or_immediate_operand" ""))
829 (clobber (reg:CC REG_CC))])]
830 "operands[1] != CONST0_RTX (<MODE>mode)"
831 [(parallel [(set (match_dup 0)
833 (clobber (match_dup 2))
834 (clobber (reg:CC REG_CC))])])
836 ;; '*' because it is not used in rtl generation, only in above peephole
838 ;; "*reload_inhq" "*reload_inuhq"
839 ;; "*reload_inha" "*reload_inuha"
840 (define_insn "*reload_in<mode>"
841 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
842 (match_operand:ALL2 1 "immediate_operand" "i"))
843 (clobber (match_operand:QI 2 "register_operand" "=&d"))
844 (clobber (reg:CC REG_CC))]
847 return output_reload_inhi (operands, operands[2], NULL);
849 [(set_attr "length" "4")
850 (set_attr "adjust_len" "reload_in16")])
853 ;; "*movhq" "*movuhq"
854 ;; "*movha" "*movuha"
855 (define_insn_and_split "*mov<mode>_split"
856 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
857 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
858 "register_operand (operands[0], <MODE>mode)
859 || reg_or_0_operand (operands[1], <MODE>mode)"
861 "&& reload_completed"
862 [(parallel [(set (match_dup 0)
864 (clobber (reg:CC REG_CC))])])
866 (define_insn "*mov<mode>"
867 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
868 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))
869 (clobber (reg:CC REG_CC))]
870 "(register_operand (operands[0], <MODE>mode)
871 || reg_or_0_operand (operands[1], <MODE>mode))
874 return output_movhi (insn, operands, NULL);
876 [(set_attr "length" "2,2,6,7,2,6,5,2")
877 (set_attr "adjust_len" "mov16")])
879 (define_peephole2 ; movw
880 [(parallel [(set (match_operand:ALL1 0 "even_register_operand" "")
881 (match_operand:ALL1 1 "even_register_operand" ""))
882 (clobber (reg:CC REG_CC))])
883 (parallel [(set (match_operand:ALL1 2 "odd_register_operand" "")
884 (match_operand:ALL1 3 "odd_register_operand" ""))
885 (clobber (reg:CC REG_CC))])]
887 && REGNO (operands[0]) == REGNO (operands[2]) - 1
888 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
889 [(parallel [(set (match_dup 4)
891 (clobber (reg:CC REG_CC))])]
893 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
894 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
897 (define_peephole2 ; movw_r
898 [(parallel [(set (match_operand:ALL1 0 "odd_register_operand" "")
899 (match_operand:ALL1 1 "odd_register_operand" ""))
900 (clobber (reg:CC REG_CC))])
901 (parallel [(set (match_operand:ALL1 2 "even_register_operand" "")
902 (match_operand:ALL1 3 "even_register_operand" ""))
903 (clobber (reg:CC REG_CC))])]
905 && REGNO (operands[2]) == REGNO (operands[0]) - 1
906 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
907 [(parallel [(set (match_dup 4)
909 (clobber (reg:CC REG_CC))])]
911 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
912 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
915 ;; For LPM loads from AS1 we split
919 ;; Z = Z - sizeof (R)
921 ;; so that the second instruction can be optimized out.
923 (define_split ; "split-lpmx"
924 [(set (match_operand:HISI 0 "register_operand" "")
925 (match_operand:HISI 1 "memory_operand" ""))]
928 && avr_mem_flash_p (operands[1])
929 && REG_P (XEXP (operands[1], 0))
930 && !reg_overlap_mentioned_p (XEXP (operands[1], 0), operands[0])"
934 (plus:HI (match_dup 3)
937 rtx addr = XEXP (operands[1], 0);
939 operands[2] = replace_equiv_address (operands[1],
940 gen_rtx_POST_INC (Pmode, addr));
942 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
945 ;;==========================================================================
946 ;; xpointer move (24 bit)
948 (define_peephole2 ; *reload_inpsi
949 [(match_scratch:QI 2 "d")
950 (parallel [(set (match_operand:PSI 0 "l_register_operand" "")
951 (match_operand:PSI 1 "immediate_operand" ""))
952 (clobber (reg:CC REG_CC))])
954 "operands[1] != const0_rtx
955 && operands[1] != constm1_rtx"
956 [(parallel [(set (match_dup 0)
958 (clobber (match_dup 2))
959 (clobber (reg:CC REG_CC))])])
961 ;; '*' because it is not used in rtl generation.
962 (define_insn "*reload_inpsi"
963 [(set (match_operand:PSI 0 "register_operand" "=r")
964 (match_operand:PSI 1 "immediate_operand" "i"))
965 (clobber (match_operand:QI 2 "register_operand" "=&d"))
966 (clobber (reg:CC REG_CC))]
969 return avr_out_reload_inpsi (operands, operands[2], NULL);
971 [(set_attr "length" "6")
972 (set_attr "adjust_len" "reload_in24")])
974 (define_insn_and_split "*movpsi_split"
975 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
976 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
977 "register_operand (operands[0], PSImode)
978 || register_operand (operands[1], PSImode)
979 || const0_rtx == operands[1]"
981 "&& reload_completed"
982 [(parallel [(set (match_dup 0)
984 (clobber (reg:CC REG_CC))])])
986 (define_insn "*movpsi"
987 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
988 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))
989 (clobber (reg:CC REG_CC))]
990 "(register_operand (operands[0], PSImode)
991 || register_operand (operands[1], PSImode)
992 || const0_rtx == operands[1])
995 return avr_out_movpsi (insn, operands, NULL);
997 [(set_attr "length" "3,3,8,9,4,10")
998 (set_attr "adjust_len" "mov24")])
1000 ;;==========================================================================
1001 ;; move double word (32 bit)
1003 (define_peephole2 ; *reload_insi
1004 [(match_scratch:QI 2 "d")
1005 (parallel [(set (match_operand:ALL4 0 "l_register_operand" "")
1006 (match_operand:ALL4 1 "immediate_operand" ""))
1007 (clobber (reg:CC REG_CC))])
1009 "operands[1] != CONST0_RTX (<MODE>mode)"
1010 [(parallel [(set (match_dup 0)
1012 (clobber (match_dup 2))
1013 (clobber (reg:CC REG_CC))])])
1015 ;; '*' because it is not used in rtl generation.
1017 ;; "*reload_insq" "*reload_inusq"
1018 ;; "*reload_insa" "*reload_inusa"
1019 (define_insn "*reload_insi"
1020 [(set (match_operand:ALL4 0 "register_operand" "=r")
1021 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
1022 (clobber (match_operand:QI 2 "register_operand" "=&d"))
1023 (clobber (reg:CC REG_CC))]
1026 return output_reload_insisf (operands, operands[2], NULL);
1028 [(set_attr "length" "8")
1029 (set_attr "adjust_len" "reload_in32")])
1033 ;; "*movsq" "*movusq"
1034 ;; "*movsa" "*movusa"
1035 (define_insn_and_split "*mov<mode>_split"
1036 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
1037 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
1038 "register_operand (operands[0], <MODE>mode)
1039 || reg_or_0_operand (operands[1], <MODE>mode)"
1041 "&& reload_completed"
1042 [(parallel [(set (match_dup 0)
1044 (clobber (reg:CC REG_CC))])])
1046 (define_insn "*mov<mode>"
1047 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
1048 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))
1049 (clobber (reg:CC REG_CC))]
1050 "(register_operand (operands[0], <MODE>mode)
1051 || reg_or_0_operand (operands[1], <MODE>mode))
1052 && reload_completed"
1054 return output_movsisf (insn, operands, NULL);
1056 [(set_attr "length" "4,4,8,9,4,10")
1057 (set_attr "adjust_len" "mov32")])
1059 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
1060 ;; move floating point numbers (32 bit)
1062 (define_insn_and_split "*movsf_split"
1063 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
1064 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
1065 "register_operand (operands[0], SFmode)
1066 || reg_or_0_operand (operands[1], SFmode)"
1068 "&& reload_completed"
1069 [(parallel [(set (match_dup 0)
1071 (clobber (reg:CC REG_CC))])])
1073 (define_insn "*movsf"
1074 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
1075 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))
1076 (clobber (reg:CC REG_CC))]
1077 "(register_operand (operands[0], SFmode)
1078 || reg_or_0_operand (operands[1], SFmode))
1079 && reload_completed"
1081 return output_movsisf (insn, operands, NULL);
1083 [(set_attr "length" "4,4,8,9,4,10")
1084 (set_attr "adjust_len" "mov32")])
1086 (define_peephole2 ; *reload_insf
1087 [(match_scratch:QI 2 "d")
1088 (parallel [(set (match_operand:SF 0 "l_register_operand" "")
1089 (match_operand:SF 1 "const_double_operand" ""))
1090 (clobber (reg:CC REG_CC))])
1092 "operands[1] != CONST0_RTX (SFmode)"
1093 [(parallel [(set (match_dup 0)
1095 (clobber (match_dup 2))
1096 (clobber (reg:CC REG_CC))])])
1098 ;; '*' because it is not used in rtl generation.
1099 (define_insn "*reload_insf"
1100 [(set (match_operand:SF 0 "register_operand" "=r")
1101 (match_operand:SF 1 "const_double_operand" "F"))
1102 (clobber (match_operand:QI 2 "register_operand" "=&d"))
1103 (clobber (reg:CC REG_CC))]
1106 return output_reload_insisf (operands, operands[2], NULL);
1108 [(set_attr "length" "8")
1109 (set_attr "adjust_len" "reload_in32")])
1111 ;;=========================================================================
1112 ;; move string (like memcpy)
1114 (define_expand "cpymemhi"
1115 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1116 (match_operand:BLK 1 "memory_operand" ""))
1117 (use (match_operand:HI 2 "const_int_operand" ""))
1118 (use (match_operand:HI 3 "const_int_operand" ""))])]
1121 if (avr_emit_cpymemhi (operands))
1127 (define_mode_attr CPYMEM_r_d [(QI "r")
1130 ;; $0 : Address Space
1131 ;; $1, $2 : Loop register
1132 ;; R30 : source address
1133 ;; R26 : destination address
1137 (define_insn_and_split "cpymem_<mode>"
1138 [(set (mem:BLK (reg:HI REG_X))
1139 (mem:BLK (reg:HI REG_Z)))
1140 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1142 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>"))
1143 (clobber (reg:HI REG_X))
1144 (clobber (reg:HI REG_Z))
1145 (clobber (reg:QI LPM_REGNO))
1146 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
1149 "&& reload_completed"
1150 [(parallel [(set (mem:BLK (reg:HI REG_X))
1151 (mem:BLK (reg:HI REG_Z)))
1152 (unspec [(match_dup 0)]
1155 (clobber (reg:HI REG_X))
1156 (clobber (reg:HI REG_Z))
1157 (clobber (reg:QI LPM_REGNO))
1158 (clobber (match_dup 2))
1159 (clobber (reg:CC REG_CC))])])
1161 (define_insn "*cpymem_<mode>"
1162 [(set (mem:BLK (reg:HI REG_X))
1163 (mem:BLK (reg:HI REG_Z)))
1164 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1166 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>"))
1167 (clobber (reg:HI REG_X))
1168 (clobber (reg:HI REG_Z))
1169 (clobber (reg:QI LPM_REGNO))
1170 (clobber (match_operand:QIHI 2 "register_operand" "=1"))
1171 (clobber (reg:CC REG_CC))]
1174 return avr_out_cpymem (insn, operands, NULL);
1176 [(set_attr "adjust_len" "cpymem")])
1179 ;; $0 : Address Space
1180 ;; $1 : RAMPZ RAM address
1181 ;; R24 : #bytes and loop register
1182 ;; R23:Z : 24-bit source address
1183 ;; R26 : 16-bit destination address
1188 (define_insn_and_split "cpymemx_<mode>"
1189 [(set (mem:BLK (reg:HI REG_X))
1190 (mem:BLK (lo_sum:PSI (reg:QI 23)
1192 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1195 (clobber (reg:HI REG_X))
1196 (clobber (reg:HI REG_Z))
1197 (clobber (reg:QI LPM_REGNO))
1198 (clobber (reg:HI 24))
1199 (clobber (reg:QI 23))
1200 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
1203 "&& reload_completed"
1204 [(parallel [(set (mem:BLK (reg:HI REG_X))
1205 (mem:BLK (lo_sum:PSI (reg:QI 23)
1207 (unspec [(match_dup 0)]
1210 (clobber (reg:HI REG_X))
1211 (clobber (reg:HI REG_Z))
1212 (clobber (reg:QI LPM_REGNO))
1213 (clobber (reg:HI 24))
1214 (clobber (reg:QI 23))
1215 (clobber (mem:QI (match_dup 1)))
1216 (clobber (reg:CC REG_CC))])])
1218 (define_insn "*cpymemx_<mode>"
1219 [(set (mem:BLK (reg:HI REG_X))
1220 (mem:BLK (lo_sum:PSI (reg:QI 23)
1222 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1225 (clobber (reg:HI REG_X))
1226 (clobber (reg:HI REG_Z))
1227 (clobber (reg:QI LPM_REGNO))
1228 (clobber (reg:HI 24))
1229 (clobber (reg:QI 23))
1230 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))
1231 (clobber (reg:CC REG_CC))]
1233 "%~call __movmemx_<mode>"
1234 [(set_attr "type" "xcall")])
1237 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
1238 ;; memset (%0, %2, %1)
1240 (define_expand "setmemhi"
1241 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1242 (match_operand 2 "const_int_operand" ""))
1243 (use (match_operand:HI 1 "const_int_operand" ""))
1244 (use (match_operand:HI 3 "const_int_operand" ""))
1245 (clobber (match_scratch:HI 5 ""))
1246 (clobber (match_dup 4))])]
1252 /* If value to set is not zero, use the library routine. */
1253 if (operands[2] != const0_rtx)
1256 if (!CONST_INT_P (operands[1]))
1259 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1260 operands[4] = gen_rtx_SCRATCH (mode);
1261 operands[1] = copy_to_mode_reg (mode,
1262 gen_int_mode (INTVAL (operands[1]), mode));
1263 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1264 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1268 (define_insn_and_split "*clrmemqi_split"
1269 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1271 (use (match_operand:QI 1 "register_operand" "r"))
1272 (use (match_operand:QI 2 "const_int_operand" "n"))
1273 (clobber (match_scratch:HI 3 "=0"))
1274 (clobber (match_scratch:QI 4 "=&1"))]
1277 "&& reload_completed"
1278 [(parallel [(set (mem:BLK (match_dup 0))
1282 (clobber (match_dup 3))
1283 (clobber (match_dup 4))
1284 (clobber (reg:CC REG_CC))])])
1286 (define_insn "*clrmemqi"
1287 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1289 (use (match_operand:QI 1 "register_operand" "r"))
1290 (use (match_operand:QI 2 "const_int_operand" "n"))
1291 (clobber (match_scratch:HI 3 "=0"))
1292 (clobber (match_scratch:QI 4 "=&1"))
1293 (clobber (reg:CC REG_CC))]
1295 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1296 [(set_attr "length" "3")])
1299 (define_insn_and_split "*clrmemhi_split"
1300 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1302 (use (match_operand:HI 1 "register_operand" "!w,d"))
1303 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1304 (clobber (match_scratch:HI 3 "=0,0"))
1305 (clobber (match_scratch:HI 4 "=&1,&1"))]
1308 "&& reload_completed"
1309 [(parallel [(set (mem:BLK (match_dup 0))
1313 (clobber (match_dup 3))
1314 (clobber (match_dup 4))
1315 (clobber (reg:CC REG_CC))])])
1318 (define_insn "*clrmemhi"
1319 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1321 (use (match_operand:HI 1 "register_operand" "!w,d"))
1322 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1323 (clobber (match_scratch:HI 3 "=0,0"))
1324 (clobber (match_scratch:HI 4 "=&1,&1"))
1325 (clobber (reg:CC REG_CC))]
1328 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1329 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1330 [(set_attr "length" "3,4")])
1332 (define_expand "strlenhi"
1334 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1335 (match_operand:QI 2 "const_int_operand" "")
1336 (match_operand:HI 3 "immediate_operand" "")]
1339 (plus:HI (match_dup 4)
1341 (parallel [(set (match_operand:HI 0 "register_operand" "")
1342 (minus:HI (match_dup 4)
1344 (clobber (scratch:QI))])]
1348 if (operands[2] != const0_rtx)
1350 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1351 operands[1] = gen_rtx_MEM (BLKmode, addr);
1353 operands[4] = gen_reg_rtx (HImode);
1356 (define_insn_and_split "*strlenhi_split"
1357 [(set (match_operand:HI 0 "register_operand" "=e")
1358 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1360 (match_operand:HI 2 "immediate_operand" "i")]
1364 "&& reload_completed"
1367 (unspec:HI [(mem:BLK (match_dup 1))
1371 (clobber (reg:CC REG_CC))])])
1373 (define_insn "*strlenhi"
1374 [(set (match_operand:HI 0 "register_operand" "=e")
1375 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1377 (match_operand:HI 2 "immediate_operand" "i")]
1379 (clobber (reg:CC REG_CC))]
1381 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1382 [(set_attr "length" "3")])
1384 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1388 ;; "addqq3" "adduqq3"
1389 (define_insn_and_split "add<mode>3"
1390 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1391 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1392 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1395 "&& reload_completed"
1396 [(parallel [(set (match_dup 0)
1397 (plus:ALL1 (match_dup 1)
1399 (clobber (reg:CC REG_CC))])])
1401 (define_insn "*add<mode>3"
1402 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1403 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1404 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))
1405 (clobber (reg:CC REG_CC))]
1414 [(set_attr "length" "1,1,1,1,2,2")])
1417 ;; "addhq3" "adduhq3"
1418 ;; "addha3" "adduha3"
1419 (define_expand "add<mode>3"
1420 [(set (match_operand:ALL2 0 "register_operand" "")
1421 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1422 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1425 if (CONST_INT_P (operands[2]))
1427 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1429 if (can_create_pseudo_p()
1430 && !stack_register_operand (operands[0], HImode)
1431 && !stack_register_operand (operands[1], HImode)
1432 && !d_register_operand (operands[0], HImode)
1433 && !d_register_operand (operands[1], HImode))
1435 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1440 if (CONST_FIXED_P (operands[2]))
1442 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1448 (define_insn_and_split "*addhi3_zero_extend_split"
1449 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1450 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1451 (match_operand:HI 2 "register_operand" "0 ,r")))]
1454 "&& reload_completed"
1455 [(parallel [(set (match_dup 0)
1456 (plus:HI (zero_extend:HI (match_dup 1))
1458 (clobber (reg:CC REG_CC))])])
1460 (define_insn "*addhi3_zero_extend"
1461 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1462 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1463 (match_operand:HI 2 "register_operand" "0 ,r")))
1464 (clobber (reg:CC REG_CC))]
1467 add %A0,%1\;adc %B0,__zero_reg__
1468 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
1469 [(set_attr "length" "2,3")])
1471 (define_insn_and_split "*addhi3_zero_extend1_split"
1472 [(set (match_operand:HI 0 "register_operand" "=r")
1473 (plus:HI (match_operand:HI 1 "register_operand" "0")
1474 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1477 "&& reload_completed"
1478 [(parallel [(set (match_dup 0)
1479 (plus:HI (match_dup 1)
1480 (zero_extend:HI (match_dup 2))))
1481 (clobber (reg:CC REG_CC))])])
1483 (define_insn "*addhi3_zero_extend1"
1484 [(set (match_operand:HI 0 "register_operand" "=r")
1485 (plus:HI (match_operand:HI 1 "register_operand" "0")
1486 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1487 (clobber (reg:CC REG_CC))]
1489 "add %A0,%2\;adc %B0,__zero_reg__"
1490 [(set_attr "length" "2")])
1492 (define_insn_and_split "*addhi3.sign_extend1_split"
1493 [(set (match_operand:HI 0 "register_operand" "=r")
1494 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1495 (match_operand:HI 2 "register_operand" "0")))]
1498 "&& reload_completed"
1502 (sign_extend:HI (match_dup 1))
1504 (clobber (reg:CC REG_CC))])])
1507 (define_insn "*addhi3.sign_extend1"
1508 [(set (match_operand:HI 0 "register_operand" "=r")
1509 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1510 (match_operand:HI 2 "register_operand" "0")))
1511 (clobber (reg:CC REG_CC))]
1514 return reg_overlap_mentioned_p (operands[0], operands[1])
1515 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1516 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1518 [(set_attr "length" "5")])
1520 (define_insn_and_split "*addhi3_zero_extend.const_split"
1521 [(set (match_operand:HI 0 "register_operand" "=d")
1522 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1523 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
1526 "&& reload_completed"
1527 [(parallel [(set (match_dup 0)
1528 (plus:HI (zero_extend:HI (match_dup 1))
1530 (clobber (reg:CC REG_CC))])])
1532 (define_insn "*addhi3_zero_extend.const"
1533 [(set (match_operand:HI 0 "register_operand" "=d")
1534 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1535 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))
1536 (clobber (reg:CC REG_CC))]
1538 "subi %A0,%n2\;sbc %B0,%B0"
1539 [(set_attr "length" "2")])
1541 (define_insn_and_split "*usum_widenqihi3_split"
1542 [(set (match_operand:HI 0 "register_operand" "=r")
1543 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1544 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1547 "&& reload_completed"
1548 [(parallel [(set (match_dup 0)
1549 (plus:HI (zero_extend:HI (match_dup 1))
1550 (zero_extend:HI (match_dup 2))))
1551 (clobber (reg:CC REG_CC))])])
1554 (define_insn "*usum_widenqihi3"
1555 [(set (match_operand:HI 0 "register_operand" "=r")
1556 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1557 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1558 (clobber (reg:CC REG_CC))]
1560 "add %A0,%2\;clr %B0\;rol %B0"
1561 [(set_attr "length" "3")])
1563 (define_insn_and_split "*udiff_widenqihi3_split"
1564 [(set (match_operand:HI 0 "register_operand" "=r")
1565 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1566 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1569 "&& reload_completed"
1570 [(parallel [(set (match_dup 0)
1571 (minus:HI (zero_extend:HI (match_dup 1))
1572 (zero_extend:HI (match_dup 2))))
1573 (clobber (reg:CC REG_CC))])])
1575 (define_insn "*udiff_widenqihi3"
1576 [(set (match_operand:HI 0 "register_operand" "=r")
1577 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1578 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
1579 (clobber (reg:CC REG_CC))]
1581 "sub %A0,%2\;sbc %B0,%B0"
1582 [(set_attr "length" "2")])
1584 (define_insn_and_split "*addhi3_sp"
1585 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1586 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1587 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1590 return avr_out_addto_sp (operands, NULL);
1595 /* Do not attempt to split this pattern. This FAIL is necessary
1596 to prevent the splitter from matching *add<ALL2>3_split, splitting
1597 it, and then failing later because constraints don't match, as split
1598 does not look at constraints. */
1601 [(set_attr "length" "6")
1602 (set_attr "adjust_len" "addto_sp")])
1605 ;; "*addhq3" "*adduhq3"
1606 ;; "*addha3" "*adduha3"
1607 (define_insn_and_split "*add<mode>3_split"
1608 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1609 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1610 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1613 "&& reload_completed"
1614 [(parallel [(set (match_dup 0)
1615 (plus:ALL2 (match_dup 1)
1617 (clobber (reg:CC REG_CC))])])
1619 (define_insn "*add<mode>3"
1620 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1621 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1622 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))
1623 (clobber (reg:CC REG_CC))]
1626 return avr_out_plus (insn, operands);
1628 [(set_attr "length" "2")
1629 (set_attr "adjust_len" "plus")])
1631 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1632 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1633 ;; itself because that insn is special to reload.
1635 (define_peephole2 ; addhi3_clobber
1636 [(parallel [(set (match_operand:ALL2 0 "d_register_operand" "")
1637 (match_operand:ALL2 1 "const_operand" ""))
1638 (clobber (reg:CC REG_CC))])
1639 (parallel [(set (match_operand:ALL2 2 "l_register_operand" "")
1640 (plus:ALL2 (match_dup 2)
1642 (clobber (reg:CC REG_CC))])]
1643 "peep2_reg_dead_p (2, operands[0])"
1644 [(parallel [(set (match_dup 2)
1645 (plus:ALL2 (match_dup 2)
1647 (clobber (match_dup 3))
1648 (clobber (reg:CC REG_CC))])]
1650 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1653 ;; Same, but with reload to NO_LD_REGS
1654 ;; Combine *reload_inhi with *addhi3
1656 (define_peephole2 ; addhi3_clobber
1657 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1658 (match_operand:ALL2 1 "const_operand" ""))
1659 (clobber (match_operand:QI 2 "d_register_operand" ""))
1660 (clobber (reg:CC REG_CC))])
1661 (parallel [(set (match_operand:ALL2 3 "l_register_operand" "")
1662 (plus:ALL2 (match_dup 3)
1664 (clobber (reg:CC REG_CC))])]
1665 "peep2_reg_dead_p (2, operands[0])"
1666 [(parallel [(set (match_dup 3)
1667 (plus:ALL2 (match_dup 3)
1669 (clobber (match_dup 2))
1670 (clobber (reg:CC REG_CC))])])
1673 ;; "addhq3_clobber" "adduhq3_clobber"
1674 ;; "addha3_clobber" "adduha3_clobber"
1675 (define_insn_and_split "add<mode>3_clobber"
1676 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1677 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1678 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1679 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1682 "&& reload_completed"
1683 [(parallel [(set (match_dup 0)
1684 (plus:ALL2 (match_dup 1)
1686 (clobber (match_dup 3))
1687 (clobber (reg:CC REG_CC))])])
1689 (define_insn "*add<mode>3_clobber"
1690 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1691 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1692 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1693 (clobber (match_scratch:QI 3 "=X ,X ,&d"))
1694 (clobber (reg:CC REG_CC))]
1697 return avr_out_plus (insn, operands);
1699 [(set_attr "length" "4")
1700 (set_attr "adjust_len" "plus")])
1704 ;; "addsq3" "addusq3"
1705 ;; "addsa3" "addusa3"
1706 (define_insn_and_split "add<mode>3"
1707 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1708 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1709 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1710 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1713 "&& reload_completed"
1714 [(parallel [(set (match_dup 0)
1715 (plus:ALL4 (match_dup 1)
1717 (clobber (match_dup 3))
1718 (clobber (reg:CC REG_CC))])])
1720 (define_insn "*add<mode>3"
1721 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1722 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1723 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1724 (clobber (match_scratch:QI 3 "=X,X ,&d"))
1725 (clobber (reg:CC REG_CC))]
1728 return avr_out_plus (insn, operands);
1730 [(set_attr "length" "4")
1731 (set_attr "adjust_len" "plus")])
1733 (define_insn_and_split "*addpsi3_zero_extend.qi_split"
1734 [(set (match_operand:PSI 0 "register_operand" "=r")
1735 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1736 (match_operand:PSI 2 "register_operand" "0")))]
1739 "&& reload_completed"
1740 [(parallel [(set (match_dup 0)
1741 (plus:PSI (zero_extend:PSI (match_dup 1))
1743 (clobber (reg:CC REG_CC))])])
1745 (define_insn "*addpsi3_zero_extend.qi"
1746 [(set (match_operand:PSI 0 "register_operand" "=r")
1747 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1748 (match_operand:PSI 2 "register_operand" "0")))
1749 (clobber (reg:CC REG_CC))]
1751 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1752 [(set_attr "length" "3")])
1754 (define_insn_and_split "*addpsi3_zero_extend.hi_split"
1755 [(set (match_operand:PSI 0 "register_operand" "=r")
1756 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1757 (match_operand:PSI 2 "register_operand" "0")))]
1760 "&& reload_completed"
1761 [(parallel [(set (match_dup 0)
1762 (plus:PSI (zero_extend:PSI (match_dup 1))
1764 (clobber (reg:CC REG_CC))])])
1766 (define_insn "*addpsi3_zero_extend.hi"
1767 [(set (match_operand:PSI 0 "register_operand" "=r")
1768 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1769 (match_operand:PSI 2 "register_operand" "0")))
1770 (clobber (reg:CC REG_CC))]
1772 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1773 [(set_attr "length" "3")])
1775 (define_insn_and_split "*addpsi3_sign_extend.hi_split"
1776 [(set (match_operand:PSI 0 "register_operand" "=r")
1777 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1778 (match_operand:PSI 2 "register_operand" "0")))]
1781 "&& reload_completed"
1782 [(parallel [(set (match_dup 0)
1783 (plus:PSI (sign_extend:PSI (match_dup 1))
1785 (clobber (reg:CC REG_CC))])])
1787 (define_insn "*addpsi3_sign_extend.hi"
1788 [(set (match_operand:PSI 0 "register_operand" "=r")
1789 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1790 (match_operand:PSI 2 "register_operand" "0")))
1791 (clobber (reg:CC REG_CC))]
1793 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1794 [(set_attr "length" "5")])
1796 (define_insn_and_split "*addsi3_zero_extend_split"
1797 [(set (match_operand:SI 0 "register_operand" "=r")
1798 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1799 (match_operand:SI 2 "register_operand" "0")))]
1802 "&& reload_completed"
1803 [(parallel [(set (match_dup 0)
1804 (plus:SI (zero_extend:SI (match_dup 1))
1806 (clobber (reg:CC REG_CC))])])
1808 (define_insn "*addsi3_zero_extend"
1809 [(set (match_operand:SI 0 "register_operand" "=r")
1810 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1811 (match_operand:SI 2 "register_operand" "0")))
1812 (clobber (reg:CC REG_CC))]
1814 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1815 [(set_attr "length" "4")])
1817 (define_insn_and_split "*addsi3_zero_extend.hi_split"
1818 [(set (match_operand:SI 0 "register_operand" "=r")
1819 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1820 (match_operand:SI 2 "register_operand" "0")))]
1823 "&& reload_completed"
1824 [(parallel [(set (match_dup 0)
1825 (plus:SI (zero_extend:SI (match_dup 1))
1827 (clobber (reg:CC REG_CC))])])
1829 (define_insn "*addsi3_zero_extend.hi"
1830 [(set (match_operand:SI 0 "register_operand" "=r")
1831 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1832 (match_operand:SI 2 "register_operand" "0")))
1833 (clobber (reg:CC REG_CC))]
1835 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1836 [(set_attr "length" "4")])
1838 (define_insn_and_split "addpsi3"
1839 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1840 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1841 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1842 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1845 "&& reload_completed"
1846 [(parallel [(set (match_dup 0)
1847 (plus:PSI (match_dup 1)
1849 (clobber (match_dup 3 ))
1850 (clobber (reg:CC REG_CC))])])
1852 (define_insn "*addpsi3"
1853 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1854 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1855 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1856 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))
1857 (clobber (reg:CC REG_CC))]
1860 return avr_out_plus (insn, operands);
1862 [(set_attr "length" "3")
1863 (set_attr "adjust_len" "plus")])
1865 (define_insn_and_split "subpsi3"
1866 [(set (match_operand:PSI 0 "register_operand" "=r")
1867 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1868 (match_operand:PSI 2 "register_operand" "r")))]
1871 "&& reload_completed"
1872 [(parallel [(set (match_dup 0)
1873 (minus:PSI (match_dup 1)
1875 (clobber (reg:CC REG_CC))])])
1877 (define_insn "*subpsi3"
1878 [(set (match_operand:PSI 0 "register_operand" "=r")
1879 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1880 (match_operand:PSI 2 "register_operand" "r")))
1881 (clobber (reg:CC REG_CC))]
1883 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1884 [(set_attr "length" "3")])
1886 (define_insn_and_split "*subpsi3_zero_extend.qi_split"
1887 [(set (match_operand:PSI 0 "register_operand" "=r")
1888 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1889 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1892 "&& reload_completed"
1893 [(parallel [(set (match_dup 0)
1894 (minus:PSI (match_dup 1)
1895 (zero_extend:PSI (match_dup 2))))
1896 (clobber (reg:CC REG_CC))])])
1898 (define_insn "*subpsi3_zero_extend.qi"
1899 [(set (match_operand:PSI 0 "register_operand" "=r")
1900 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1901 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))
1902 (clobber (reg:CC REG_CC))]
1904 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1905 [(set_attr "length" "3")])
1907 (define_insn_and_split "*subpsi3_zero_extend.hi_split"
1908 [(set (match_operand:PSI 0 "register_operand" "=r")
1909 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1910 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1913 "&& reload_completed"
1914 [(parallel [(set (match_dup 0)
1915 (minus:PSI (match_dup 1)
1916 (zero_extend:PSI (match_dup 2))))
1917 (clobber (reg:CC REG_CC))])])
1919 (define_insn "*subpsi3_zero_extend.hi"
1920 [(set (match_operand:PSI 0 "register_operand" "=r")
1921 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1922 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
1923 (clobber (reg:CC REG_CC))]
1925 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1926 [(set_attr "length" "3")])
1928 (define_insn_and_split "*subpsi3_sign_extend.hi_split"
1929 [(set (match_operand:PSI 0 "register_operand" "=r")
1930 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1931 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1934 "&& reload_completed"
1935 [(parallel [(set (match_dup 0)
1936 (minus:PSI (match_dup 1)
1937 (sign_extend:PSI (match_dup 2))))
1938 (clobber (reg:CC REG_CC))])])
1940 (define_insn "*subpsi3_sign_extend.hi"
1941 [(set (match_operand:PSI 0 "register_operand" "=r")
1942 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1943 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
1944 (clobber (reg:CC REG_CC))]
1946 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1947 [(set_attr "length" "5")])
1949 ;-----------------------------------------------------------------------------
1953 ;; "subqq3" "subuqq3"
1954 (define_insn_and_split "sub<mode>3"
1955 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1956 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1957 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1960 "&& reload_completed"
1961 [(parallel [(set (match_dup 0)
1962 (minus:ALL1 (match_dup 1)
1964 (clobber (reg:CC REG_CC))])])
1966 (define_insn "*sub<mode>3"
1967 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1968 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1969 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))
1970 (clobber (reg:CC REG_CC))]
1979 [(set_attr "length" "1,1,1,1,2,2")])
1982 ;; "subhq3" "subuhq3"
1983 ;; "subha3" "subuha3"
1984 (define_insn_and_split "sub<mode>3"
1985 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1986 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1987 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1988 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1991 "&& reload_completed"
1992 [(parallel [(set (match_dup 0)
1993 (minus:ALL2 (match_dup 1)
1995 (clobber (match_dup 3))
1996 (clobber (reg:CC REG_CC))])])
1998 (define_insn "*sub<mode>3"
1999 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
2000 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
2001 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
2002 (clobber (match_scratch:QI 3 "=X,X ,&d"))
2003 (clobber (reg:CC REG_CC))]
2006 return avr_out_plus (insn, operands);
2008 [(set_attr "adjust_len" "plus")])
2010 (define_insn_and_split "*subhi3_zero_extend1_split"
2011 [(set (match_operand:HI 0 "register_operand" "=r")
2012 (minus:HI (match_operand:HI 1 "register_operand" "0")
2013 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2016 "&& reload_completed"
2017 [(parallel [(set (match_dup 0)
2018 (minus:HI (match_dup 1)
2019 (zero_extend:HI (match_dup 2))))
2020 (clobber (reg:CC REG_CC))])])
2022 (define_insn "*subhi3_zero_extend1"
2023 [(set (match_operand:HI 0 "register_operand" "=r")
2024 (minus:HI (match_operand:HI 1 "register_operand" "0")
2025 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2026 (clobber (reg:CC REG_CC))]
2028 "sub %A0,%2\;sbc %B0,__zero_reg__"
2029 [(set_attr "length" "2")])
2031 (define_insn_and_split "*subhi3.sign_extend2_split"
2032 [(set (match_operand:HI 0 "register_operand" "=r")
2033 (minus:HI (match_operand:HI 1 "register_operand" "0")
2034 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2037 "&& reload_completed"
2038 [(parallel [(set (match_dup 0)
2039 (minus:HI (match_dup 1)
2040 (sign_extend:HI (match_dup 2))))
2041 (clobber (reg:CC REG_CC))])])
2044 (define_insn "*subhi3.sign_extend2"
2045 [(set (match_operand:HI 0 "register_operand" "=r")
2046 (minus:HI (match_operand:HI 1 "register_operand" "0")
2047 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2048 (clobber (reg:CC REG_CC))]
2051 return reg_overlap_mentioned_p (operands[0], operands[2])
2052 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
2053 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
2055 [(set_attr "length" "5")])
2058 ;; "subsq3" "subusq3"
2059 ;; "subsa3" "subusa3"
2060 (define_insn_and_split "sub<mode>3"
2061 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
2062 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
2063 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
2064 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2067 "&& reload_completed"
2068 [(parallel [(set (match_dup 0)
2069 (minus:ALL4 (match_dup 1)
2071 (clobber (match_dup 3))
2072 (clobber (reg:CC REG_CC))])])
2074 (define_insn "*sub<mode>3"
2075 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
2076 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
2077 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
2078 (clobber (match_scratch:QI 3 "=X,X ,&d"))
2079 (clobber (reg:CC REG_CC))]
2082 return avr_out_plus (insn, operands);
2084 [(set_attr "adjust_len" "plus")])
2086 (define_insn_and_split "*subsi3_zero_extend_split"
2087 [(set (match_operand:SI 0 "register_operand" "=r")
2088 (minus:SI (match_operand:SI 1 "register_operand" "0")
2089 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
2092 "&& reload_completed"
2093 [(parallel [(set (match_dup 0)
2094 (minus:SI (match_dup 1)
2095 (zero_extend:SI (match_dup 2))))
2096 (clobber (reg:CC REG_CC))])])
2098 (define_insn "*subsi3_zero_extend"
2099 [(set (match_operand:SI 0 "register_operand" "=r")
2100 (minus:SI (match_operand:SI 1 "register_operand" "0")
2101 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))
2102 (clobber (reg:CC REG_CC))]
2104 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
2105 [(set_attr "length" "4")
2108 (define_insn_and_split "*subsi3_zero_extend.hi_split"
2109 [(set (match_operand:SI 0 "register_operand" "=r")
2110 (minus:SI (match_operand:SI 1 "register_operand" "0")
2111 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
2114 "&& reload_completed"
2115 [(parallel [(set (match_dup 0)
2116 (minus:SI (match_dup 1)
2117 (zero_extend:SI (match_dup 2))))
2118 (clobber (reg:CC REG_CC))])])
2120 (define_insn "*subsi3_zero_extend.hi"
2121 [(set (match_operand:SI 0 "register_operand" "=r")
2122 (minus:SI (match_operand:SI 1 "register_operand" "0")
2123 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))
2124 (clobber (reg:CC REG_CC))]
2126 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
2127 [(set_attr "length" "4")])
2129 ;******************************************************************************
2132 (define_expand "mulqi3"
2133 [(set (match_operand:QI 0 "register_operand" "")
2134 (mult:QI (match_operand:QI 1 "register_operand" "")
2135 (match_operand:QI 2 "register_operand" "")))]
2140 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
2145 (define_insn_and_split "*mulqi3_enh_split"
2146 [(set (match_operand:QI 0 "register_operand" "=r")
2147 (mult:QI (match_operand:QI 1 "register_operand" "r")
2148 (match_operand:QI 2 "register_operand" "r")))]
2151 "&& reload_completed"
2152 [(parallel [(set (match_dup 0)
2153 (mult:QI (match_dup 1)
2155 (clobber (reg:CC REG_CC))])])
2157 (define_insn "*mulqi3_enh"
2158 [(set (match_operand:QI 0 "register_operand" "=r")
2159 (mult:QI (match_operand:QI 1 "register_operand" "r")
2160 (match_operand:QI 2 "register_operand" "r")))
2161 (clobber (reg:CC REG_CC))]
2162 "AVR_HAVE_MUL && reload_completed"
2166 [(set_attr "length" "3")])
2168 (define_expand "mulqi3_call"
2169 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
2170 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
2171 (parallel [(set (reg:QI 24)
2172 (mult:QI (reg:QI 24) (reg:QI 22)))
2173 (clobber (reg:QI 22))])
2174 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
2177 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
2180 (define_insn_and_split "*mulqi3_call_split"
2181 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
2182 (clobber (reg:QI 22))]
2185 "&& reload_completed"
2186 [(parallel [(set (reg:QI 24)
2187 (mult:QI (reg:QI 24) (reg:QI 22)))
2188 (clobber (reg:QI 22))
2189 (clobber (reg:CC REG_CC))])])
2191 (define_insn "*mulqi3_call"
2193 (mult:QI (reg:QI 24) (reg:QI 22)))
2194 (clobber (reg:QI 22))
2195 (clobber (reg:CC REG_CC))]
2196 "!AVR_HAVE_MUL && reload_completed"
2198 [(set_attr "type" "xcall")])
2200 ;; "umulqi3_highpart"
2201 ;; "smulqi3_highpart"
2203 (define_insn_and_split "<extend_su>mulqi3_highpart"
2204 [(set (match_operand:QI 0 "register_operand" "=r")
2206 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2207 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2211 "&& reload_completed"
2212 [(parallel [(set (match_dup 0)
2214 (lshiftrt:HI (mult:HI (any_extend:HI (match_dup 1))
2215 (any_extend:HI (match_dup 2)))
2217 (clobber (reg:CC REG_CC))])])
2219 (define_insn "*<extend_su>mulqi3_highpart"
2220 [(set (match_operand:QI 0 "register_operand" "=r")
2222 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2223 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2225 (clobber (reg:CC REG_CC))]
2226 "AVR_HAVE_MUL && reload_completed"
2227 "mul<extend_s> %1,%2
2230 [(set_attr "length" "3")])
2233 ;; Used when expanding div or mod inline for some special values
2234 (define_insn_and_split "*subqi3.ashiftrt7_split"
2235 [(set (match_operand:QI 0 "register_operand" "=r")
2236 (minus:QI (match_operand:QI 1 "register_operand" "0")
2237 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
2241 "&& reload_completed"
2242 [(parallel [(set (match_dup 0)
2243 (minus:QI (match_dup 1)
2244 (ashiftrt:QI (match_dup 2)
2246 (clobber (reg:CC REG_CC))])])
2248 (define_insn "*subqi3.ashiftrt7"
2249 [(set (match_operand:QI 0 "register_operand" "=r")
2250 (minus:QI (match_operand:QI 1 "register_operand" "0")
2251 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
2253 (clobber (reg:CC REG_CC))]
2256 [(set_attr "length" "2")])
2258 (define_insn_and_split "*addqi3.lt0_split"
2259 [(set (match_operand:QI 0 "register_operand" "=r")
2260 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
2262 (match_operand:QI 2 "register_operand" "0")))]
2265 "&& reload_completed"
2266 [(parallel [(set (match_dup 0)
2267 (plus:QI (lt:QI (match_dup 1)
2270 (clobber (reg:CC REG_CC))])])
2272 (define_insn "*addqi3.lt0"
2273 [(set (match_operand:QI 0 "register_operand" "=r")
2274 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
2276 (match_operand:QI 2 "register_operand" "0")))
2277 (clobber (reg:CC REG_CC))]
2280 [(set_attr "length" "2")])
2282 (define_insn_and_split "*addhi3.lt0_split"
2283 [(set (match_operand:HI 0 "register_operand" "=w,r")
2284 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
2286 (match_operand:HI 2 "register_operand" "0,0")))
2287 (clobber (match_scratch:QI 3 "=X,&1"))]
2290 "&& reload_completed"
2291 [(parallel [(set (match_dup 0)
2292 (plus:HI (lt:HI (match_dup 1)
2295 (clobber (match_dup 3))
2296 (clobber (reg:CC REG_CC))])])
2298 (define_insn "*addhi3.lt0"
2299 [(set (match_operand:HI 0 "register_operand" "=w,r")
2300 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
2302 (match_operand:HI 2 "register_operand" "0,0")))
2303 (clobber (match_scratch:QI 3 "=X,&1"))
2304 (clobber (reg:CC REG_CC))]
2307 sbrc %1,7\;adiw %0,1
2308 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
2309 [(set_attr "length" "2,3")])
2311 (define_insn_and_split "*addpsi3.lt0_split"
2312 [(set (match_operand:PSI 0 "register_operand" "=r")
2313 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
2315 (match_operand:PSI 2 "register_operand" "0")))]
2318 "&& reload_completed"
2319 [(parallel [(set (match_dup 0)
2320 (plus:PSI (lshiftrt:PSI (match_dup 1)
2323 (clobber (reg:CC REG_CC))])])
2325 (define_insn "*addpsi3.lt0"
2326 [(set (match_operand:PSI 0 "register_operand" "=r")
2327 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
2329 (match_operand:PSI 2 "register_operand" "0")))
2330 (clobber (reg:CC REG_CC))]
2332 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
2333 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
2334 [(set_attr "length" "5")])
2336 (define_insn_and_split "*addsi3.lt0_split"
2337 [(set (match_operand:SI 0 "register_operand" "=r")
2338 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2340 (match_operand:SI 2 "register_operand" "0")))]
2343 "&& reload_completed"
2344 [(parallel [(set (match_dup 0)
2345 (plus:SI (lshiftrt:SI (match_dup 1)
2348 (clobber (reg:CC REG_CC))])])
2350 (define_insn "*addsi3.lt0"
2351 [(set (match_operand:SI 0 "register_operand" "=r")
2352 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
2354 (match_operand:SI 2 "register_operand" "0")))
2355 (clobber (reg:CC REG_CC))]
2357 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
2358 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
2359 [(set_attr "length" "6")])
2361 (define_insn_and_split "*umulqihi3.call_split"
2363 (mult:HI (zero_extend:HI (reg:QI 22))
2364 (zero_extend:HI (reg:QI 24))))
2365 (clobber (reg:QI 21))
2366 (clobber (reg:HI 22))]
2369 "&& reload_completed"
2370 [(parallel [(set (reg:HI 24)
2371 (mult:HI (zero_extend:HI (reg:QI 22))
2372 (zero_extend:HI (reg:QI 24))))
2373 (clobber (reg:QI 21))
2374 (clobber (reg:HI 22))
2375 (clobber (reg:CC REG_CC))])])
2377 (define_insn "*umulqihi3.call"
2379 (mult:HI (zero_extend:HI (reg:QI 22))
2380 (zero_extend:HI (reg:QI 24))))
2381 (clobber (reg:QI 21))
2382 (clobber (reg:HI 22))
2383 (clobber (reg:CC REG_CC))]
2384 "!AVR_HAVE_MUL && reload_completed"
2385 "%~call __umulqihi3"
2386 [(set_attr "type" "xcall")])
2391 (define_insn_and_split "<extend_u>mulqihi3_split"
2392 [(set (match_operand:HI 0 "register_operand" "=r")
2393 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2394 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
2397 "&& reload_completed"
2398 [(parallel [(set (match_dup 0)
2399 (mult:HI (any_extend:HI (match_dup 1))
2400 (any_extend:HI (match_dup 2))))
2401 (clobber (reg:CC REG_CC))])])
2403 (define_insn "<extend_u>mulqihi3"
2404 [(set (match_operand:HI 0 "register_operand" "=r")
2405 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2406 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))
2407 (clobber (reg:CC REG_CC))]
2408 "AVR_HAVE_MUL && reload_completed"
2409 "mul<extend_s> %1,%2
2412 [(set_attr "length" "3")])
2414 (define_insn_and_split "usmulqihi3"
2415 [(set (match_operand:HI 0 "register_operand" "=r")
2416 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2417 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2420 "&& reload_completed"
2421 [(parallel [(set (match_dup 0)
2422 (mult:HI (zero_extend:HI (match_dup 1))
2423 (sign_extend:HI (match_dup 2))))
2424 (clobber (reg:CC REG_CC))])])
2426 (define_insn "*usmulqihi3"
2427 [(set (match_operand:HI 0 "register_operand" "=r")
2428 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2429 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2430 (clobber (reg:CC REG_CC))]
2431 "AVR_HAVE_MUL && reload_completed"
2435 [(set_attr "length" "3")])
2437 ;; Above insn is not canonicalized by insn combine, so here is a version with
2438 ;; operands swapped.
2439 (define_insn_and_split "*sumulqihi3_split"
2440 [(set (match_operand:HI 0 "register_operand" "=r")
2441 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2442 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2445 "&& reload_completed"
2446 [(parallel [(set (match_dup 0)
2447 (mult:HI (sign_extend:HI (match_dup 1))
2448 (zero_extend:HI (match_dup 2))))
2449 (clobber (reg:CC REG_CC))])])
2451 (define_insn "*sumulqihi3"
2452 [(set (match_operand:HI 0 "register_operand" "=r")
2453 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2454 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2455 (clobber (reg:CC REG_CC))]
2456 "AVR_HAVE_MUL && reload_completed"
2460 [(set_attr "length" "3")])
2462 ;; One-extend operand 1
2464 (define_insn_and_split "*osmulqihi3_split"
2465 [(set (match_operand:HI 0 "register_operand" "=&r")
2466 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
2467 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
2470 "&& reload_completed"
2471 [(parallel [(set (match_dup 0)
2472 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
2473 (sign_extend:HI (match_dup 2))))
2474 (clobber (reg:CC REG_CC))])])
2476 (define_insn "*osmulqihi3"
2477 [(set (match_operand:HI 0 "register_operand" "=&r")
2478 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
2479 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))
2480 (clobber (reg:CC REG_CC))]
2481 "AVR_HAVE_MUL && reload_completed"
2486 [(set_attr "length" "4")])
2488 (define_insn_and_split "*oumulqihi3_split"
2489 [(set (match_operand:HI 0 "register_operand" "=&r")
2490 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2491 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
2494 "&& reload_completed"
2495 [(parallel [(set (match_dup 0)
2496 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
2497 (zero_extend:HI (match_dup 2))))
2498 (clobber (reg:CC REG_CC))])])
2500 (define_insn "*oumulqihi3"
2501 [(set (match_operand:HI 0 "register_operand" "=&r")
2502 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2503 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))
2504 (clobber (reg:CC REG_CC))]
2505 "AVR_HAVE_MUL && reload_completed"
2510 [(set_attr "length" "4")])
2512 ;******************************************************************************
2513 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
2514 ;******************************************************************************
2516 (define_insn_and_split "*maddqi4_split"
2517 [(set (match_operand:QI 0 "register_operand" "=r")
2518 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2519 (match_operand:QI 2 "register_operand" "r"))
2520 (match_operand:QI 3 "register_operand" "0")))]
2524 "&& reload_completed"
2525 [(parallel [(set (match_dup 0)
2526 (plus:QI (mult:QI (match_dup 1)
2529 (clobber (reg:CC REG_CC))])])
2531 (define_insn "*maddqi4"
2532 [(set (match_operand:QI 0 "register_operand" "=r")
2533 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2534 (match_operand:QI 2 "register_operand" "r"))
2535 (match_operand:QI 3 "register_operand" "0")))
2536 (clobber (reg:CC REG_CC))]
2537 "AVR_HAVE_MUL && reload_completed"
2541 [(set_attr "length" "4")])
2543 (define_insn_and_split "*msubqi4_split"
2544 [(set (match_operand:QI 0 "register_operand" "=r")
2545 (minus:QI (match_operand:QI 3 "register_operand" "0")
2546 (mult:QI (match_operand:QI 1 "register_operand" "r")
2547 (match_operand:QI 2 "register_operand" "r"))))]
2550 "&& reload_completed"
2551 [(parallel [(set (match_dup 0)
2552 (minus:QI (match_dup 3)
2553 (mult:QI (match_dup 1)
2555 (clobber (reg:CC REG_CC))])])
2557 (define_insn "*msubqi4"
2558 [(set (match_operand:QI 0 "register_operand" "=r")
2559 (minus:QI (match_operand:QI 3 "register_operand" "0")
2560 (mult:QI (match_operand:QI 1 "register_operand" "r")
2561 (match_operand:QI 2 "register_operand" "r"))))
2562 (clobber (reg:CC REG_CC))]
2563 "AVR_HAVE_MUL && reload_completed"
2567 [(set_attr "length" "4")])
2569 (define_insn_and_split "*maddqi4.const"
2570 [(set (match_operand:QI 0 "register_operand" "=r")
2571 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
2572 (match_operand:QI 2 "const_int_operand" "n"))
2573 (match_operand:QI 3 "register_operand" "0")))
2574 (clobber (match_scratch:QI 4 "=&d"))]
2577 "&& reload_completed"
2582 (plus:QI (mult:QI (match_dup 1)
2586 (define_insn_and_split "*msubqi4.const"
2587 [(set (match_operand:QI 0 "register_operand" "=r")
2588 (minus:QI (match_operand:QI 3 "register_operand" "0")
2589 (mult:QI (match_operand:QI 1 "register_operand" "r")
2590 (match_operand:QI 2 "const_int_operand" "n"))))
2591 (clobber (match_scratch:QI 4 "=&d"))]
2594 "&& reload_completed"
2599 (minus:QI (match_dup 3)
2600 (mult:QI (match_dup 1)
2604 ;******************************************************************************
2605 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
2606 ;******************************************************************************
2608 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
2611 ;; int foo (unsigned char z)
2613 ;; extern int aInt[];
2614 ;; return aInt[3*z+2];
2617 ;; because the constant +4 then is added explicitely instead of consuming it
2618 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
2619 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
2620 ;; The implementational effort is the same so we are fine with that approach.
2625 (define_insn_and_split "*<extend_u>maddqihi4_split"
2626 [(set (match_operand:HI 0 "register_operand" "=r")
2627 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2628 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2629 (match_operand:HI 3 "register_operand" "0")))]
2633 "&& reload_completed"
2634 [(parallel [(set (match_dup 0)
2635 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2636 (any_extend:HI (match_dup 2)))
2638 (clobber (reg:CC REG_CC))])])
2640 (define_insn "*<extend_u>maddqihi4"
2641 [(set (match_operand:HI 0 "register_operand" "=r")
2642 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2643 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
2644 (match_operand:HI 3 "register_operand" "0")))
2645 (clobber (reg:CC REG_CC))]
2646 "AVR_HAVE_MUL && reload_completed"
2647 "mul<extend_s> %1,%2
2651 [(set_attr "length" "4")])
2655 (define_insn_and_split "*<extend_u>msubqihi4_split"
2656 [(set (match_operand:HI 0 "register_operand" "=r")
2657 (minus:HI (match_operand:HI 3 "register_operand" "0")
2658 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2659 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
2662 "&& reload_completed"
2663 [(parallel [(set (match_dup 0)
2664 (minus:HI (match_dup 3)
2665 (mult:HI (any_extend:HI (match_dup 1))
2666 (any_extend:HI (match_dup 2)))))
2667 (clobber (reg:CC REG_CC))])])
2669 (define_insn "*<extend_u>msubqihi4"
2670 [(set (match_operand:HI 0 "register_operand" "=r")
2671 (minus:HI (match_operand:HI 3 "register_operand" "0")
2672 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2673 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))
2674 (clobber (reg:CC REG_CC))]
2675 "AVR_HAVE_MUL && reload_completed"
2676 "mul<extend_s> %1,%2
2680 [(set_attr "length" "4")])
2684 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split"
2685 [(set (match_operand:HI 0 "register_operand" "=r")
2686 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2687 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
2688 (match_operand:HI 3 "register_operand" "0")))]
2691 && <any_extend:CODE> != <any_extend2:CODE>"
2693 "&& reload_completed"
2694 [(parallel [(set (match_dup 0)
2695 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2696 (any_extend2:HI (match_dup 2)))
2698 (clobber (reg:CC REG_CC))])])
2700 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
2701 [(set (match_operand:HI 0 "register_operand" "=r")
2702 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2703 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
2704 (match_operand:HI 3 "register_operand" "0")))
2705 (clobber (reg:CC REG_CC))]
2708 && <any_extend:CODE> != <any_extend2:CODE>"
2710 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
2711 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
2713 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
2715 [(set_attr "length" "4")])
2719 (define_insn_and_split "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4_split"
2720 [(set (match_operand:HI 0 "register_operand" "=r")
2721 (minus:HI (match_operand:HI 3 "register_operand" "0")
2722 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2723 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
2726 && <any_extend:CODE> != <any_extend2:CODE>"
2728 "&& reload_completed"
2729 [(parallel [(set (match_dup 0)
2730 (minus:HI (match_dup 3)
2731 (mult:HI (any_extend:HI (match_dup 1))
2732 (any_extend2:HI (match_dup 2)))))
2733 (clobber (reg:CC REG_CC))])])
2735 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
2736 [(set (match_operand:HI 0 "register_operand" "=r")
2737 (minus:HI (match_operand:HI 3 "register_operand" "0")
2738 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
2739 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))
2740 (clobber (reg:CC REG_CC))]
2743 && <any_extend:CODE> != <any_extend2:CODE>"
2745 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
2746 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
2748 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
2750 [(set_attr "length" "4")])
2752 ;; Handle small constants
2754 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
2755 ;; This is shorter, faster than MUL and has lower register pressure.
2757 (define_insn_and_split "*umaddqihi4.2"
2758 [(set (match_operand:HI 0 "register_operand" "=r")
2759 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2761 (match_operand:HI 2 "register_operand" "r")))]
2763 && !reg_overlap_mentioned_p (operands[0], operands[1])"
2764 { gcc_unreachable(); }
2768 ; *addhi3_zero_extend
2770 (plus:HI (zero_extend:HI (match_dup 1))
2772 ; *addhi3_zero_extend
2774 (plus:HI (zero_extend:HI (match_dup 1))
2777 ;; "umaddqihi4.uconst"
2778 ;; "maddqihi4.sconst"
2779 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
2780 [(set (match_operand:HI 0 "register_operand" "=r")
2781 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2782 (match_operand:HI 2 "<extend_su>8_operand" "n"))
2783 (match_operand:HI 3 "register_operand" "0")))
2784 (clobber (match_scratch:QI 4 "=&d"))]
2787 "&& reload_completed"
2790 ; *umaddqihi4 resp. *maddqihi4
2792 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
2793 (any_extend:HI (match_dup 4)))
2796 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2799 ;; "*umsubqihi4.uconst"
2800 ;; "*msubqihi4.sconst"
2801 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
2802 [(set (match_operand:HI 0 "register_operand" "=r")
2803 (minus:HI (match_operand:HI 3 "register_operand" "0")
2804 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2805 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
2806 (clobber (match_scratch:QI 4 "=&d"))]
2809 "&& reload_completed"
2812 ; *umsubqihi4 resp. *msubqihi4
2814 (minus:HI (match_dup 3)
2815 (mult:HI (any_extend:HI (match_dup 1))
2816 (any_extend:HI (match_dup 4)))))]
2818 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2821 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
2822 ;; for MULT with power of 2 and skips trying MULT insn above.
2824 (define_insn_and_split "*umsubqihi4.uconst.ashift"
2825 [(set (match_operand:HI 0 "register_operand" "=r")
2826 (minus:HI (match_operand:HI 3 "register_operand" "0")
2827 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2828 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
2829 (clobber (match_scratch:QI 4 "=&d"))]
2832 "&& reload_completed"
2837 (minus:HI (match_dup 3)
2838 (mult:HI (zero_extend:HI (match_dup 1))
2839 (zero_extend:HI (match_dup 4)))))]
2841 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2844 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
2845 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
2846 ;; because this would require an extra pattern for just one value.
2848 (define_insn_and_split "*msubqihi4.sconst.ashift"
2849 [(set (match_operand:HI 0 "register_operand" "=r")
2850 (minus:HI (match_operand:HI 3 "register_operand" "0")
2851 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2852 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
2853 (clobber (match_scratch:QI 4 "=&d"))]
2856 "&& reload_completed"
2861 (minus:HI (match_dup 3)
2862 (mult:HI (sign_extend:HI (match_dup 1))
2863 (sign_extend:HI (match_dup 4)))))]
2865 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2868 ;; For signed/unsigned combinations that require narrow constraint "a"
2869 ;; just provide a pattern if signed/unsigned combination is actually needed.
2871 (define_insn_and_split "*sumaddqihi4.uconst"
2872 [(set (match_operand:HI 0 "register_operand" "=r")
2873 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2874 (match_operand:HI 2 "u8_operand" "M"))
2875 (match_operand:HI 3 "register_operand" "0")))
2876 (clobber (match_scratch:QI 4 "=&a"))]
2878 && !s8_operand (operands[2], VOIDmode)"
2880 "&& reload_completed"
2885 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
2886 (zero_extend:HI (match_dup 4)))
2889 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2892 (define_insn_and_split "*sumsubqihi4.uconst"
2893 [(set (match_operand:HI 0 "register_operand" "=r")
2894 (minus:HI (match_operand:HI 3 "register_operand" "0")
2895 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2896 (match_operand:HI 2 "u8_operand" "M"))))
2897 (clobber (match_scratch:QI 4 "=&a"))]
2899 && !s8_operand (operands[2], VOIDmode)"
2901 "&& reload_completed"
2906 (minus:HI (match_dup 3)
2907 (mult:HI (sign_extend:HI (match_dup 1))
2908 (zero_extend:HI (match_dup 4)))))]
2910 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2913 ;******************************************************************************
2914 ; mul HI: $1 = sign/zero-extend, $2 = small constant
2915 ;******************************************************************************
2917 ;; "*muluqihi3.uconst"
2918 ;; "*mulsqihi3.sconst"
2919 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
2920 [(set (match_operand:HI 0 "register_operand" "=r")
2921 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2922 (match_operand:HI 2 "<extend_su>8_operand" "n")))
2923 (clobber (match_scratch:QI 3 "=&d"))]
2926 "&& reload_completed"
2929 ; umulqihi3 resp. mulqihi3
2931 (mult:HI (any_extend:HI (match_dup 1))
2932 (any_extend:HI (match_dup 3))))]
2934 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2937 (define_insn_and_split "*muluqihi3.sconst"
2938 [(set (match_operand:HI 0 "register_operand" "=r")
2939 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2940 (match_operand:HI 2 "s8_operand" "n")))
2941 (clobber (match_scratch:QI 3 "=&a"))]
2944 "&& reload_completed"
2949 (mult:HI (zero_extend:HI (match_dup 1))
2950 (sign_extend:HI (match_dup 3))))]
2952 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2955 (define_insn_and_split "*mulsqihi3.uconst"
2956 [(set (match_operand:HI 0 "register_operand" "=r")
2957 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2958 (match_operand:HI 2 "u8_operand" "M")))
2959 (clobber (match_scratch:QI 3 "=&a"))]
2962 "&& reload_completed"
2967 (mult:HI (zero_extend:HI (match_dup 3))
2968 (sign_extend:HI (match_dup 1))))]
2970 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2973 (define_insn_and_split "*mulsqihi3.oconst"
2974 [(set (match_operand:HI 0 "register_operand" "=&r")
2975 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2976 (match_operand:HI 2 "o8_operand" "n")))
2977 (clobber (match_scratch:QI 3 "=&a"))]
2980 "&& reload_completed"
2985 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2986 (sign_extend:HI (match_dup 1))))]
2988 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2991 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2992 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2993 ;; at that time. Fix that.
2994 (define_insn_and_split "*ashiftqihi2.signx.1_split"
2995 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2996 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
3000 "&& reload_completed"
3001 [(parallel [(set (match_dup 0)
3002 (ashift:HI (sign_extend:HI (match_dup 1))
3004 (clobber (reg:CC REG_CC))])])
3006 (define_insn "*ashiftqihi2.signx.1"
3007 [(set (match_operand:HI 0 "register_operand" "=r,*r")
3008 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
3010 (clobber (reg:CC REG_CC)) ]
3013 lsl %A0\;sbc %B0,%B0
3014 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
3015 [(set_attr "length" "2,3")])
3017 (define_insn_and_split "*ashifthi3.signx.const"
3018 [(set (match_operand:HI 0 "register_operand" "=r")
3019 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
3020 (match_operand:HI 2 "const_2_to_6_operand" "I")))
3021 (clobber (match_scratch:QI 3 "=&d"))]
3024 "&& reload_completed"
3029 (mult:HI (sign_extend:HI (match_dup 1))
3030 (sign_extend:HI (match_dup 3))))]
3032 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
3035 (define_insn_and_split "*ashifthi3.signx.const7"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3039 (clobber (match_scratch:QI 2 "=&a"))]
3042 "&& reload_completed"
3047 (mult:HI (zero_extend:HI (match_dup 2))
3048 (sign_extend:HI (match_dup 1))))]
3050 operands[3] = gen_int_mode (1 << 7, QImode);
3053 (define_insn_and_split "*ashifthi3.zerox.const"
3054 [(set (match_operand:HI 0 "register_operand" "=r")
3055 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3056 (match_operand:HI 2 "const_2_to_7_operand" "I")))
3057 (clobber (match_scratch:QI 3 "=&d"))]
3060 "&& reload_completed"
3065 (mult:HI (zero_extend:HI (match_dup 1))
3066 (zero_extend:HI (match_dup 3))))]
3068 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
3071 ;******************************************************************************
3072 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
3073 ;******************************************************************************
3075 (define_insn_and_split "mulsqihi3"
3076 [(set (match_operand:HI 0 "register_operand" "=&r")
3077 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3078 (match_operand:HI 2 "register_operand" "a")))]
3081 "&& reload_completed"
3082 [(parallel [(set (match_dup 0)
3083 (mult:HI (sign_extend:HI (match_dup 1))
3085 (clobber (reg:CC REG_CC))])])
3087 (define_insn "*mulsqihi3"
3088 [(set (match_operand:HI 0 "register_operand" "=&r")
3089 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
3090 (match_operand:HI 2 "register_operand" "a")))
3091 (clobber (reg:CC REG_CC))]
3092 "AVR_HAVE_MUL && reload_completed"
3098 [(set_attr "length" "5")])
3100 (define_insn_and_split "muluqihi3"
3101 [(set (match_operand:HI 0 "register_operand" "=&r")
3102 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3103 (match_operand:HI 2 "register_operand" "r")))]
3106 "&& reload_completed"
3107 [(parallel [(set (match_dup 0)
3108 (mult:HI (zero_extend:HI (match_dup 1))
3110 (clobber (reg:CC REG_CC))])])
3112 (define_insn "*muluqihi3"
3113 [(set (match_operand:HI 0 "register_operand" "=&r")
3114 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
3115 (match_operand:HI 2 "register_operand" "r")))
3116 (clobber (reg:CC REG_CC))]
3117 "AVR_HAVE_MUL && reload_completed"
3123 [(set_attr "length" "5")])
3125 ;; one-extend operand 1
3127 (define_insn_and_split "muloqihi3"
3128 [(set (match_operand:HI 0 "register_operand" "=&r")
3129 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
3130 (match_operand:HI 2 "register_operand" "r")))]
3133 "&& reload_completed"
3134 [(parallel [(set (match_dup 0)
3135 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 1))))
3137 (clobber (reg:CC REG_CC))])])
3139 (define_insn "*muloqihi3"
3140 [(set (match_operand:HI 0 "register_operand" "=&r")
3141 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
3142 (match_operand:HI 2 "register_operand" "r")))
3143 (clobber (reg:CC REG_CC))]
3144 "AVR_HAVE_MUL && reload_completed"
3151 [(set_attr "length" "6")])
3153 ;******************************************************************************
3155 (define_expand "mulhi3"
3156 [(set (match_operand:HI 0 "register_operand" "")
3157 (mult:HI (match_operand:HI 1 "register_operand" "")
3158 (match_operand:HI 2 "register_or_s9_operand" "")))]
3163 if (!register_operand (operands[2], HImode))
3164 operands[2] = force_reg (HImode, operands[2]);
3166 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
3170 /* ; For small constants we can do better by extending them on the fly.
3171 ; The constant can be loaded in one instruction and the widening
3172 ; multiplication is shorter. First try the unsigned variant because it
3173 ; allows constraint "d" instead of "a" for the signed version. */
3175 if (s9_operand (operands[2], HImode))
3177 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
3179 if (u8_operand (operands[2], HImode))
3181 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
3183 else if (s8_operand (operands[2], HImode))
3185 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
3189 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
3195 if (!register_operand (operands[2], HImode))
3196 operands[2] = force_reg (HImode, operands[2]);
3199 (define_insn_and_split "*mulhi3_enh_split"
3200 [(set (match_operand:HI 0 "register_operand" "=&r")
3201 (mult:HI (match_operand:HI 1 "register_operand" "r")
3202 (match_operand:HI 2 "register_operand" "r")))]
3205 "&& reload_completed"
3206 [(parallel [(set (match_dup 0)
3207 (mult:HI (match_dup 1)
3209 (clobber (reg:CC REG_CC))])])
3211 (define_insn "*mulhi3_enh"
3212 [(set (match_operand:HI 0 "register_operand" "=&r")
3213 (mult:HI (match_operand:HI 1 "register_operand" "r")
3214 (match_operand:HI 2 "register_operand" "r")))
3215 (clobber (reg:CC REG_CC))]
3216 "AVR_HAVE_MUL && reload_completed"
3218 return REGNO (operands[1]) == REGNO (operands[2])
3219 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
3220 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
3222 [(set_attr "length" "7")])
3224 (define_expand "mulhi3_call"
3225 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
3226 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
3227 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3228 (clobber (reg:HI 22))
3229 (clobber (reg:QI 21))])
3230 (set (match_operand:HI 0 "register_operand" "")
3234 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
3238 (define_insn_and_split "*mulhi3_call_split"
3239 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3240 (clobber (reg:HI 22))
3241 (clobber (reg:QI 21))]
3244 "&& reload_completed"
3245 [(parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3246 (clobber (reg:HI 22))
3247 (clobber (reg:QI 21))
3248 (clobber (reg:CC REG_CC))])])
3250 (define_insn "*mulhi3_call"
3251 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
3252 (clobber (reg:HI 22))
3253 (clobber (reg:QI 21))
3254 (clobber (reg:CC REG_CC))]
3255 "!AVR_HAVE_MUL && reload_completed"
3257 [(set_attr "type" "xcall")])
3259 ;; To support widening multiplication with constant we postpone
3260 ;; expanding to the implicit library call until post combine and
3261 ;; prior to register allocation. Clobber all hard registers that
3262 ;; might be used by the (widening) multiply until it is split and
3263 ;; it's final register footprint is worked out.
3265 (define_expand "mulsi3"
3266 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3267 (mult:SI (match_operand:SI 1 "register_operand" "")
3268 (match_operand:SI 2 "nonmemory_operand" "")))
3269 (clobber (reg:HI 26))
3270 (clobber (reg:DI 18))])]
3273 if (u16_operand (operands[2], SImode))
3275 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3276 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
3280 if (o16_operand (operands[2], SImode))
3282 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3283 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
3287 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
3288 regmask (DImode, 18) | regmask (HImode, 26)))
3292 (define_insn_and_split "*mulsi3"
3293 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3294 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
3295 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3296 (clobber (reg:HI 26))
3297 (clobber (reg:DI 18))]
3298 "AVR_HAVE_MUL && !reload_completed"
3299 { gcc_unreachable(); }
3305 (parallel [(set (reg:SI 22)
3306 (mult:SI (reg:SI 22)
3308 (clobber (reg:HI 26))])
3312 if (u16_operand (operands[2], SImode))
3314 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3315 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
3319 if (o16_operand (operands[2], SImode))
3321 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3322 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
3329 (define_expand "mulu<mode>si3"
3330 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3331 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
3332 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3333 (clobber (reg:HI 26))
3334 (clobber (reg:DI 18))])]
3337 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3338 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
3339 regmask (DImode, 18) | regmask (HImode, 26)))
3345 (define_insn_and_split "*mulu<mode>si3"
3346 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3347 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3348 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3349 (clobber (reg:HI 26))
3350 (clobber (reg:DI 18))]
3351 "AVR_HAVE_MUL && !reload_completed"
3352 { gcc_unreachable(); }
3359 (mult:SI (zero_extend:SI (reg:HI 26))
3364 /* Do the QI -> HI extension explicitely before the multiplication. */
3365 /* Do the HI -> SI extension implicitely and after the multiplication. */
3367 if (QImode == <MODE>mode)
3368 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
3370 if (u16_operand (operands[2], SImode))
3372 operands[1] = force_reg (HImode, operands[1]);
3373 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3374 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
3381 (define_expand "muls<mode>si3"
3382 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3383 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
3384 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3385 (clobber (reg:HI 26))
3386 (clobber (reg:DI 18))])]
3389 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3390 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
3391 regmask (DImode, 18) | regmask (HImode, 26)))
3397 (define_insn_and_split "*muls<mode>si3"
3398 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3399 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3400 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3401 (clobber (reg:HI 26))
3402 (clobber (reg:DI 18))]
3403 "AVR_HAVE_MUL && !reload_completed"
3404 { gcc_unreachable(); }
3411 (mult:SI (sign_extend:SI (reg:HI 26))
3416 /* Do the QI -> HI extension explicitely before the multiplication. */
3417 /* Do the HI -> SI extension implicitely and after the multiplication. */
3419 if (QImode == <MODE>mode)
3420 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
3422 if (u16_operand (operands[2], SImode)
3423 || s16_operand (operands[2], SImode))
3425 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
3427 operands[1] = force_reg (HImode, operands[1]);
3429 if (u16_operand (operands[2], SImode))
3430 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
3432 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
3438 ;; One-extend operand 1
3440 (define_expand "mulohisi3"
3441 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3442 (mult:SI (not:SI (zero_extend:SI
3443 (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
3444 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
3445 (clobber (reg:HI 26))
3446 (clobber (reg:DI 18))])]
3449 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
3450 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
3451 regmask (DImode, 18) | regmask (HImode, 26)))
3455 (define_insn_and_split "*mulohisi3"
3456 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3457 (mult:SI (not:SI (zero_extend:SI
3458 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
3459 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
3460 (clobber (reg:HI 26))
3461 (clobber (reg:DI 18))]
3462 "AVR_HAVE_MUL && !reload_completed"
3463 { gcc_unreachable(); }
3470 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3477 (define_expand "<extend_u>mulhisi3"
3478 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3479 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
3480 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
3481 (clobber (reg:HI 26))
3482 (clobber (reg:DI 18))])]
3485 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
3486 regmask (DImode, 18) | regmask (HImode, 26)))
3490 (define_expand "usmulhisi3"
3491 [(parallel [(set (match_operand:SI 0 "register_operand" "")
3492 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
3493 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
3494 (clobber (reg:HI 26))
3495 (clobber (reg:DI 18))])]
3498 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
3499 regmask (DImode, 18) | regmask (HImode, 26)))
3503 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
3504 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
3505 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
3506 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
3507 (define_insn_and_split
3508 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
3509 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
3510 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
3511 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
3512 (clobber (reg:HI 26))
3513 (clobber (reg:DI 18))]
3514 "AVR_HAVE_MUL && !reload_completed"
3515 { gcc_unreachable(); }
3522 (mult:SI (match_dup 3)
3527 rtx xop1 = operands[1];
3528 rtx xop2 = operands[2];
3530 /* Do the QI -> HI extension explicitely before the multiplication. */
3531 /* Do the HI -> SI extension implicitely and after the multiplication. */
3533 if (QImode == <QIHI:MODE>mode)
3534 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
3536 if (QImode == <QIHI2:MODE>mode)
3537 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
3539 if (<any_extend:CODE> == <any_extend2:CODE>
3540 || <any_extend:CODE> == ZERO_EXTEND)
3544 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
3545 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
3549 /* <any_extend:CODE> = SIGN_EXTEND */
3550 /* <any_extend2:CODE> = ZERO_EXTEND */
3554 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
3555 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
3559 ;; "smulhi3_highpart"
3560 ;; "umulhi3_highpart"
3561 (define_expand "<extend_su>mulhi3_highpart"
3563 (match_operand:HI 1 "nonmemory_operand" ""))
3565 (match_operand:HI 2 "nonmemory_operand" ""))
3566 (parallel [(set (reg:HI 24)
3567 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3568 (any_extend:SI (reg:HI 26)))
3570 (clobber (reg:HI 22))])
3571 (set (match_operand:HI 0 "register_operand" "")
3575 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
3578 (define_insn_and_split "*mulsi3_call_split"
3580 (mult:SI (reg:SI 22)
3582 (clobber (reg:HI 26))]
3585 "&& reload_completed"
3586 [(parallel [(set (reg:SI 22)
3587 (mult:SI (reg:SI 22)
3589 (clobber (reg:HI 26))
3590 (clobber (reg:CC REG_CC))])])
3592 (define_insn "*mulsi3_call"
3594 (mult:SI (reg:SI 22)
3596 (clobber (reg:HI 26))
3597 (clobber (reg:CC REG_CC))]
3598 "AVR_HAVE_MUL && reload_completed"
3600 [(set_attr "type" "xcall")])
3603 ;; "*umulhisi3_call"
3604 (define_insn_and_split "*<extend_u>mulhisi3_call_split"
3606 (mult:SI (any_extend:SI (reg:HI 18))
3607 (any_extend:SI (reg:HI 26))))]
3610 "&& reload_completed"
3611 [(parallel [(set (reg:SI 22)
3612 (mult:SI (any_extend:SI (reg:HI 18))
3613 (any_extend:SI (reg:HI 26))))
3614 (clobber (reg:CC REG_CC))])])
3616 (define_insn "*<extend_u>mulhisi3_call"
3618 (mult:SI (any_extend:SI (reg:HI 18))
3619 (any_extend:SI (reg:HI 26))))
3620 (clobber (reg:CC REG_CC))]
3621 "AVR_HAVE_MUL && reload_completed"
3622 "%~call __<extend_u>mulhisi3"
3623 [(set_attr "type" "xcall")])
3625 ;; "*umulhi3_highpart_call"
3626 ;; "*smulhi3_highpart_call"
3627 (define_insn_and_split "*<extend_su>mulhi3_highpart_call_split"
3629 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3630 (any_extend:SI (reg:HI 26)))
3632 (clobber (reg:HI 22))]
3635 "&& reload_completed"
3636 [(parallel [(set (reg:HI 24)
3637 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3638 (any_extend:SI (reg:HI 26)))
3640 (clobber (reg:HI 22))
3641 (clobber (reg:CC REG_CC))])])
3643 (define_insn "*<extend_su>mulhi3_highpart_call"
3645 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
3646 (any_extend:SI (reg:HI 26)))
3648 (clobber (reg:HI 22))
3649 (clobber (reg:CC REG_CC))]
3650 "AVR_HAVE_MUL && reload_completed"
3651 "%~call __<extend_u>mulhisi3"
3652 [(set_attr "type" "xcall")])
3654 (define_insn_and_split "*usmulhisi3_call_split"
3656 (mult:SI (zero_extend:SI (reg:HI 18))
3657 (sign_extend:SI (reg:HI 26))))]
3660 "&& reload_completed"
3661 [(parallel [(set (reg:SI 22)
3662 (mult:SI (zero_extend:SI (reg:HI 18))
3663 (sign_extend:SI (reg:HI 26))))
3664 (clobber (reg:CC REG_CC))])])
3666 (define_insn "*usmulhisi3_call"
3668 (mult:SI (zero_extend:SI (reg:HI 18))
3669 (sign_extend:SI (reg:HI 26))))
3670 (clobber (reg:CC REG_CC))]
3671 "AVR_HAVE_MUL && reload_completed"
3672 "%~call __usmulhisi3"
3673 [(set_attr "type" "xcall")])
3675 (define_insn_and_split "*mul<extend_su>hisi3_call_split"
3677 (mult:SI (any_extend:SI (reg:HI 26))
3681 "&& reload_completed"
3682 [(parallel [(set (reg:SI 22)
3683 (mult:SI (any_extend:SI (reg:HI 26))
3685 (clobber (reg:CC REG_CC))])])
3687 (define_insn "*mul<extend_su>hisi3_call"
3689 (mult:SI (any_extend:SI (reg:HI 26))
3691 (clobber (reg:CC REG_CC))]
3692 "AVR_HAVE_MUL && reload_completed"
3693 "%~call __mul<extend_su>hisi3"
3694 [(set_attr "type" "xcall")])
3696 (define_insn_and_split "*mulohisi3_call_split"
3698 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3702 "&& reload_completed"
3703 [(parallel [(set (reg:SI 22)
3704 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3706 (clobber (reg:CC REG_CC))])])
3708 (define_insn "*mulohisi3_call"
3710 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
3712 (clobber (reg:CC REG_CC))]
3713 "AVR_HAVE_MUL && reload_completed"
3714 "%~call __mulohisi3"
3715 [(set_attr "type" "xcall")])
3717 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
3720 ;; Generate lib1funcs.S calls ourselves, because:
3721 ;; - we know exactly which registers are clobbered (for QI and HI
3722 ;; modes, some of the call-used registers are preserved)
3723 ;; - we get both the quotient and the remainder at no extra cost
3724 ;; - we split the patterns only after the first CSE passes because
3725 ;; CSE has problems to operate on hard regs.
3727 (define_insn_and_split "divmodqi4"
3728 [(set (match_operand:QI 0 "pseudo_register_operand")
3729 (div:QI (match_operand:QI 1 "pseudo_register_operand")
3730 (match_operand:QI 2 "pseudo_register_operand")))
3731 (set (match_operand:QI 3 "pseudo_register_operand")
3732 (mod:QI (match_dup 1) (match_dup 2)))
3733 (clobber (reg:QI 22))
3734 (clobber (reg:QI 23))
3735 (clobber (reg:QI 24))
3736 (clobber (reg:QI 25))]
3738 { gcc_unreachable(); }
3740 [(set (reg:QI 24) (match_dup 1))
3741 (set (reg:QI 22) (match_dup 2))
3742 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3743 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3744 (clobber (reg:QI 22))
3745 (clobber (reg:QI 23))])
3746 (set (match_dup 0) (reg:QI 24))
3747 (set (match_dup 3) (reg:QI 25))])
3749 (define_insn_and_split "*divmodqi4_call_split"
3750 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3751 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3752 (clobber (reg:QI 22))
3753 (clobber (reg:QI 23))]
3756 "&& reload_completed"
3757 [(parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3758 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3759 (clobber (reg:QI 22))
3760 (clobber (reg:QI 23))
3761 (clobber (reg:CC REG_CC))])])
3763 (define_insn "*divmodqi4_call"
3764 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
3765 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
3766 (clobber (reg:QI 22))
3767 (clobber (reg:QI 23))
3768 (clobber (reg:CC REG_CC))]
3770 "%~call __divmodqi4"
3771 [(set_attr "type" "xcall")])
3773 (define_insn_and_split "udivmodqi4"
3774 [(set (match_operand:QI 0 "pseudo_register_operand")
3775 (udiv:QI (match_operand:QI 1 "pseudo_register_operand")
3776 (match_operand:QI 2 "pseudo_register_operand")))
3777 (set (match_operand:QI 3 "pseudo_register_operand")
3778 (umod:QI (match_dup 1) (match_dup 2)))
3779 (clobber (reg:QI 22))
3780 (clobber (reg:QI 23))
3781 (clobber (reg:QI 24))
3782 (clobber (reg:QI 25))]
3784 { gcc_unreachable(); }
3786 [(set (reg:QI 24) (match_dup 1))
3787 (set (reg:QI 22) (match_dup 2))
3788 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3789 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3790 (clobber (reg:QI 23))])
3791 (set (match_dup 0) (reg:QI 24))
3792 (set (match_dup 3) (reg:QI 25))])
3794 (define_insn_and_split "*udivmodqi4_call_split"
3795 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3796 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3797 (clobber (reg:QI 23))]
3800 "&& reload_completed"
3801 [(parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3802 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3803 (clobber (reg:QI 23))
3804 (clobber (reg:CC REG_CC))])])
3806 (define_insn "*udivmodqi4_call"
3807 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
3808 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
3809 (clobber (reg:QI 23))
3810 (clobber (reg:CC REG_CC))]
3812 "%~call __udivmodqi4"
3813 [(set_attr "type" "xcall")])
3815 (define_insn_and_split "divmodhi4"
3816 [(set (match_operand:HI 0 "pseudo_register_operand")
3817 (div:HI (match_operand:HI 1 "pseudo_register_operand")
3818 (match_operand:HI 2 "pseudo_register_operand")))
3819 (set (match_operand:HI 3 "pseudo_register_operand")
3820 (mod:HI (match_dup 1) (match_dup 2)))
3821 (clobber (reg:QI 21))
3822 (clobber (reg:HI 22))
3823 (clobber (reg:HI 24))
3824 (clobber (reg:HI 26))]
3826 { gcc_unreachable(); }
3828 [(set (reg:HI 24) (match_dup 1))
3829 (set (reg:HI 22) (match_dup 2))
3830 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3831 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3832 (clobber (reg:HI 26))
3833 (clobber (reg:QI 21))])
3834 (set (match_dup 0) (reg:HI 22))
3835 (set (match_dup 3) (reg:HI 24))])
3837 (define_insn_and_split "*divmodhi4_call_split"
3838 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3839 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3840 (clobber (reg:HI 26))
3841 (clobber (reg:QI 21))]
3844 "&& reload_completed"
3845 [(parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3846 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3847 (clobber (reg:HI 26))
3848 (clobber (reg:QI 21))
3849 (clobber (reg:CC REG_CC))])])
3851 (define_insn "*divmodhi4_call"
3852 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
3853 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
3854 (clobber (reg:HI 26))
3855 (clobber (reg:QI 21))
3856 (clobber (reg:CC REG_CC))]
3858 "%~call __divmodhi4"
3859 [(set_attr "type" "xcall")])
3861 (define_insn_and_split "udivmodhi4"
3862 [(set (match_operand:HI 0 "pseudo_register_operand")
3863 (udiv:HI (match_operand:HI 1 "pseudo_register_operand")
3864 (match_operand:HI 2 "pseudo_register_operand")))
3865 (set (match_operand:HI 3 "pseudo_register_operand")
3866 (umod:HI (match_dup 1) (match_dup 2)))
3867 (clobber (reg:QI 21))
3868 (clobber (reg:HI 22))
3869 (clobber (reg:HI 24))
3870 (clobber (reg:HI 26))]
3872 { gcc_unreachable(); }
3874 [(set (reg:HI 24) (match_dup 1))
3875 (set (reg:HI 22) (match_dup 2))
3876 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3877 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3878 (clobber (reg:HI 26))
3879 (clobber (reg:QI 21))])
3880 (set (match_dup 0) (reg:HI 22))
3881 (set (match_dup 3) (reg:HI 24))])
3883 (define_insn_and_split "*udivmodhi4_call_split"
3884 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3885 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3886 (clobber (reg:HI 26))
3887 (clobber (reg:QI 21))]
3890 "&& reload_completed"
3891 [(parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3892 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3893 (clobber (reg:HI 26))
3894 (clobber (reg:QI 21))
3895 (clobber (reg:CC REG_CC))])])
3897 (define_insn "*udivmodhi4_call"
3898 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
3899 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
3900 (clobber (reg:HI 26))
3901 (clobber (reg:QI 21))
3902 (clobber (reg:CC REG_CC))
3905 "%~call __udivmodhi4"
3906 [(set_attr "type" "xcall")])
3908 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3911 ;; To support widening multiplication with constant we postpone
3912 ;; expanding to the implicit library call until post combine and
3913 ;; prior to register allocation. Clobber all hard registers that
3914 ;; might be used by the (widening) multiply until it is split and
3915 ;; it's final register footprint is worked out.
3917 (define_expand "mulpsi3"
3918 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3919 (mult:PSI (match_operand:PSI 1 "register_operand" "")
3920 (match_operand:PSI 2 "nonmemory_operand" "")))
3921 (clobber (reg:HI 26))
3922 (clobber (reg:DI 18))])]
3925 if (s8_operand (operands[2], PSImode))
3927 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
3928 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
3932 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
3933 regmask (DImode, 18) | regmask (HImode, 26)))
3937 (define_insn_and_split "*umulqihipsi3_split"
3938 [(set (match_operand:PSI 0 "register_operand" "=&r")
3939 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
3940 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
3943 "&& reload_completed"
3944 [(parallel [(set (match_dup 0)
3945 (mult:PSI (zero_extend:PSI (match_dup 1))
3946 (zero_extend:PSI (match_dup 2))))
3947 (clobber (reg:CC REG_CC))])])
3949 (define_insn "*umulqihipsi3"
3950 [(set (match_operand:PSI 0 "register_operand" "=&r")
3951 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
3952 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))
3953 (clobber (reg:CC REG_CC))]
3954 "AVR_HAVE_MUL && reload_completed"
3962 [(set_attr "length" "7")])
3964 (define_insn_and_split "*umulhiqipsi3_split"
3965 [(set (match_operand:PSI 0 "register_operand" "=&r")
3966 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
3967 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
3970 "&& reload_completed"
3971 [(parallel [(set (match_dup 0)
3972 (mult:PSI (zero_extend:PSI (match_dup 2))
3973 (zero_extend:PSI (match_dup 1))))
3974 (clobber (reg:CC REG_CC))])])
3976 (define_insn "*umulhiqipsi3"
3977 [(set (match_operand:PSI 0 "register_operand" "=&r")
3978 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
3979 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))
3980 (clobber (reg:CC REG_CC))]
3981 "AVR_HAVE_MUL && reload_completed"
3988 adc %C0,__zero_reg__"
3989 [(set_attr "length" "7")])
3991 (define_expand "mulsqipsi3"
3992 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
3993 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
3994 (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
3995 (clobber (reg:HI 26))
3996 (clobber (reg:DI 18))])]
3999 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
4000 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
4001 regmask (DImode, 18) | regmask (HImode, 26)))
4005 (define_insn_and_split "*mulsqipsi3"
4006 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
4007 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
4008 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
4009 (clobber (reg:HI 26))
4010 (clobber (reg:DI 18))]
4011 "AVR_HAVE_MUL && !reload_completed"
4012 { gcc_unreachable(); }
4019 (mult:PSI (sign_extend:PSI (reg:QI 25))
4024 (define_insn_and_split "*mulpsi3"
4025 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
4026 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
4027 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
4028 (clobber (reg:HI 26))
4029 (clobber (reg:DI 18))]
4030 "AVR_HAVE_MUL && !reload_completed"
4031 { gcc_unreachable(); }
4037 (parallel [(set (reg:PSI 22)
4038 (mult:PSI (reg:PSI 22)
4040 (clobber (reg:QI 21))
4041 (clobber (reg:QI 25))
4042 (clobber (reg:HI 26))])
4046 if (s8_operand (operands[2], PSImode))
4048 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
4049 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
4054 (define_insn_and_split "*mulsqipsi3.libgcc_split"
4056 (mult:PSI (sign_extend:PSI (reg:QI 25))
4060 "&& reload_completed"
4061 [(parallel [(set (reg:PSI 18)
4062 (mult:PSI (sign_extend:PSI (reg:QI 25))
4064 (clobber (reg:CC REG_CC))])])
4066 (define_insn "*mulsqipsi3.libgcc"
4068 (mult:PSI (sign_extend:PSI (reg:QI 25))
4070 (clobber (reg:CC REG_CC))]
4071 "AVR_HAVE_MUL && reload_completed"
4072 "%~call __mulsqipsi3"
4073 [(set_attr "type" "xcall")])
4075 (define_insn_and_split "*mulpsi3.libgcc_split"
4077 (mult:PSI (reg:PSI 22)
4079 (clobber (reg:QI 21))
4080 (clobber (reg:QI 25))
4081 (clobber (reg:HI 26))]
4084 "&& reload_completed"
4085 [(parallel [(set (reg:PSI 22)
4086 (mult:PSI (reg:PSI 22)
4088 (clobber (reg:QI 21))
4089 (clobber (reg:QI 25))
4090 (clobber (reg:HI 26))
4091 (clobber (reg:CC REG_CC))])])
4093 (define_insn "*mulpsi3.libgcc"
4095 (mult:PSI (reg:PSI 22)
4097 (clobber (reg:QI 21))
4098 (clobber (reg:QI 25))
4099 (clobber (reg:HI 26))
4100 (clobber (reg:CC REG_CC))]
4101 "AVR_HAVE_MUL && reload_completed"
4103 [(set_attr "type" "xcall")])
4106 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4107 ;; 24-bit signed/unsigned division and modulo.
4108 ;; Notice that the libgcc implementation return the quotient in R22
4109 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
4110 ;; implementation works the other way round.
4112 (define_insn_and_split "divmodpsi4"
4113 [(set (match_operand:PSI 0 "pseudo_register_operand")
4114 (div:PSI (match_operand:PSI 1 "pseudo_register_operand")
4115 (match_operand:PSI 2 "pseudo_register_operand")))
4116 (set (match_operand:PSI 3 "pseudo_register_operand")
4117 (mod:PSI (match_dup 1)
4119 (clobber (reg:DI 18))
4120 (clobber (reg:QI 26))]
4122 { gcc_unreachable(); }
4124 [(set (reg:PSI 22) (match_dup 1))
4125 (set (reg:PSI 18) (match_dup 2))
4126 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4127 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4128 (clobber (reg:QI 21))
4129 (clobber (reg:QI 25))
4130 (clobber (reg:QI 26))])
4131 (set (match_dup 0) (reg:PSI 22))
4132 (set (match_dup 3) (reg:PSI 18))])
4134 (define_insn_and_split "*divmodpsi4_call_split"
4135 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4136 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4137 (clobber (reg:QI 21))
4138 (clobber (reg:QI 25))
4139 (clobber (reg:QI 26))]
4142 "&& reload_completed"
4143 [(parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4144 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4145 (clobber (reg:QI 21))
4146 (clobber (reg:QI 25))
4147 (clobber (reg:QI 26))
4148 (clobber (reg:CC REG_CC))])])
4150 (define_insn "*divmodpsi4_call"
4151 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
4152 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
4153 (clobber (reg:QI 21))
4154 (clobber (reg:QI 25))
4155 (clobber (reg:QI 26))
4156 (clobber (reg:CC REG_CC))]
4158 "%~call __divmodpsi4"
4159 [(set_attr "type" "xcall")])
4161 (define_insn_and_split "udivmodpsi4"
4162 [(set (match_operand:PSI 0 "pseudo_register_operand")
4163 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand")
4164 (match_operand:PSI 2 "pseudo_register_operand")))
4165 (set (match_operand:PSI 3 "pseudo_register_operand")
4166 (umod:PSI (match_dup 1)
4168 (clobber (reg:DI 18))
4169 (clobber (reg:QI 26))]
4171 { gcc_unreachable(); }
4173 [(set (reg:PSI 22) (match_dup 1))
4174 (set (reg:PSI 18) (match_dup 2))
4175 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4176 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4177 (clobber (reg:QI 21))
4178 (clobber (reg:QI 25))
4179 (clobber (reg:QI 26))])
4180 (set (match_dup 0) (reg:PSI 22))
4181 (set (match_dup 3) (reg:PSI 18))])
4183 (define_insn_and_split "*udivmodpsi4_call_split"
4184 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4185 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4186 (clobber (reg:QI 21))
4187 (clobber (reg:QI 25))
4188 (clobber (reg:QI 26))]
4191 "&& reload_completed"
4192 [(parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4193 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4194 (clobber (reg:QI 21))
4195 (clobber (reg:QI 25))
4196 (clobber (reg:QI 26))
4197 (clobber (reg:CC REG_CC))])])
4199 (define_insn "*udivmodpsi4_call"
4200 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
4201 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
4202 (clobber (reg:QI 21))
4203 (clobber (reg:QI 25))
4204 (clobber (reg:QI 26))
4205 (clobber (reg:CC REG_CC))]
4207 "%~call __udivmodpsi4"
4208 [(set_attr "type" "xcall")])
4210 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4212 (define_insn_and_split "divmodsi4"
4213 [(set (match_operand:SI 0 "pseudo_register_operand")
4214 (div:SI (match_operand:SI 1 "pseudo_register_operand")
4215 (match_operand:SI 2 "pseudo_register_operand")))
4216 (set (match_operand:SI 3 "pseudo_register_operand")
4217 (mod:SI (match_dup 1)
4219 (clobber (reg:SI 18))
4220 (clobber (reg:SI 22))
4221 (clobber (reg:HI 26))
4222 (clobber (reg:HI 30))]
4224 { gcc_unreachable(); }
4226 [(set (reg:SI 22) (match_dup 1))
4227 (set (reg:SI 18) (match_dup 2))
4228 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4229 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4230 (clobber (reg:HI 26))
4231 (clobber (reg:HI 30))])
4232 (set (match_dup 0) (reg:SI 18))
4233 (set (match_dup 3) (reg:SI 22))])
4235 (define_insn_and_split "*divmodsi4_call_split"
4236 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4237 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4238 (clobber (reg:HI 26))
4239 (clobber (reg:HI 30))]
4242 "&& reload_completed"
4243 [(parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4244 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4245 (clobber (reg:HI 26))
4246 (clobber (reg:HI 30))
4247 (clobber (reg:CC REG_CC))])])
4249 (define_insn "*divmodsi4_call"
4250 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
4251 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
4252 (clobber (reg:HI 26))
4253 (clobber (reg:HI 30))
4254 (clobber (reg:CC REG_CC))]
4256 "%~call __divmodsi4"
4257 [(set_attr "type" "xcall")])
4259 (define_insn_and_split "udivmodsi4"
4260 [(set (match_operand:SI 0 "pseudo_register_operand")
4261 (udiv:SI (match_operand:SI 1 "pseudo_register_operand")
4262 (match_operand:SI 2 "pseudo_register_operand")))
4263 (set (match_operand:SI 3 "pseudo_register_operand")
4264 (umod:SI (match_dup 1)
4266 (clobber (reg:SI 18))
4267 (clobber (reg:SI 22))
4268 (clobber (reg:HI 26))
4269 (clobber (reg:HI 30))]
4271 { gcc_unreachable(); }
4273 [(set (reg:SI 22) (match_dup 1))
4274 (set (reg:SI 18) (match_dup 2))
4275 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4276 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4277 (clobber (reg:HI 26))
4278 (clobber (reg:HI 30))])
4279 (set (match_dup 0) (reg:SI 18))
4280 (set (match_dup 3) (reg:SI 22))])
4282 (define_insn_and_split "*udivmodsi4_call_split"
4283 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4284 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4285 (clobber (reg:HI 26))
4286 (clobber (reg:HI 30))]
4289 "&& reload_completed"
4290 [(parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4291 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4292 (clobber (reg:HI 26))
4293 (clobber (reg:HI 30))
4294 (clobber (reg:CC REG_CC))])])
4296 (define_insn "*udivmodsi4_call"
4297 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
4298 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
4299 (clobber (reg:HI 26))
4300 (clobber (reg:HI 30))
4301 (clobber (reg:CC REG_CC))]
4303 "%~call __udivmodsi4"
4304 [(set_attr "type" "xcall")])
4306 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
4309 (define_insn_and_split "andqi3"
4310 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4311 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4312 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))]
4315 "&& reload_completed"
4316 [(parallel [(set (match_dup 0)
4317 (and:QI (match_dup 1)
4319 (clobber (reg:CC REG_CC))])])
4321 (define_insn "*andqi3"
4322 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4323 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4324 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))
4325 (clobber (reg:CC REG_CC))]
4330 * return avr_out_bitop (insn, operands, NULL);"
4331 [(set_attr "length" "1,1,2")])
4333 (define_insn_and_split "andhi3"
4334 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4335 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4336 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
4337 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
4340 "&& reload_completed"
4341 [(parallel [(set (match_dup 0)
4342 (and:HI (match_dup 1)
4344 (clobber (match_dup 3))
4345 (clobber (reg:CC REG_CC))])])
4347 (define_insn "*andhi3"
4348 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4349 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4350 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
4351 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))
4352 (clobber (reg:CC REG_CC))]
4355 if (which_alternative == 0)
4356 return "and %A0,%A2\;and %B0,%B2";
4357 else if (which_alternative == 1)
4358 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
4360 return avr_out_bitop (insn, operands, NULL);
4362 [(set_attr "length" "2,2,2,4,4")
4363 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")])
4365 (define_insn_and_split "andpsi3"
4366 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4367 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4368 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
4369 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4372 "&& reload_completed"
4373 [(parallel [(set (match_dup 0)
4374 (and:PSI (match_dup 1)
4376 (clobber (match_dup 3))
4377 (clobber (reg:CC REG_CC))])])
4379 (define_insn "*andpsi3"
4380 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4381 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4382 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
4383 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4384 (clobber (reg:CC REG_CC))]
4387 if (which_alternative == 0)
4388 return "and %A0,%A2" CR_TAB
4389 "and %B0,%B2" CR_TAB
4392 return avr_out_bitop (insn, operands, NULL);
4394 [(set_attr "length" "3,3,6,6")
4395 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4397 (define_insn_and_split "andsi3"
4398 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4399 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4400 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
4401 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4404 "&& reload_completed"
4405 [(parallel [(set (match_dup 0)
4406 (and:SI (match_dup 1)
4408 (clobber (match_dup 3))
4409 (clobber (reg:CC REG_CC))])])
4411 (define_insn "*andsi3"
4412 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4413 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4414 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
4415 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4416 (clobber (reg:CC REG_CC))]
4419 if (which_alternative == 0)
4420 return "and %0,%2" CR_TAB
4421 "and %B0,%B2" CR_TAB
4422 "and %C0,%C2" CR_TAB
4425 return avr_out_bitop (insn, operands, NULL);
4427 [(set_attr "length" "4,4,8,8")
4428 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4430 (define_peephole2 ; andi
4431 [(parallel [(set (match_operand:QI 0 "d_register_operand" "")
4432 (and:QI (match_dup 0)
4433 (match_operand:QI 1 "const_int_operand" "")))
4434 (clobber (reg:CC REG_CC))])
4435 (parallel [(set (match_dup 0)
4436 (and:QI (match_dup 0)
4437 (match_operand:QI 2 "const_int_operand" "")))
4438 (clobber (reg:CC REG_CC))])]
4440 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
4441 (clobber (reg:CC REG_CC))])]
4443 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
4446 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4449 (define_insn_and_split "iorqi3"
4450 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4451 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4452 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))]
4455 "&& reload_completed"
4456 [(parallel [(set (match_dup 0)
4457 (ior:QI (match_dup 1)
4459 (clobber (reg:CC REG_CC))])])
4461 (define_insn "*iorqi3"
4462 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
4463 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
4464 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))
4465 (clobber (reg:CC REG_CC))]
4470 * return avr_out_bitop (insn, operands, NULL);"
4471 [(set_attr "length" "1,1,2")])
4473 (define_insn_and_split "iorhi3"
4474 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4475 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4476 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
4477 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
4480 "&& reload_completed"
4481 [(parallel [(set (match_dup 0)
4482 (ior:HI (match_dup 1)
4484 (clobber (match_dup 3))
4485 (clobber (reg:CC REG_CC))])])
4487 (define_insn "*iorhi3"
4488 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
4489 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
4490 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
4491 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))
4492 (clobber (reg:CC REG_CC))]
4495 if (which_alternative == 0)
4496 return "or %A0,%A2\;or %B0,%B2";
4497 else if (which_alternative == 1)
4498 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
4500 return avr_out_bitop (insn, operands, NULL);
4502 [(set_attr "length" "2,2,2,4,4")
4503 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")])
4505 (define_insn_and_split "iorpsi3"
4506 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4507 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4508 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
4509 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4512 "&& reload_completed"
4513 [(parallel [(set (match_dup 0)
4514 (ior:PSI (match_dup 1)
4516 (clobber (match_dup 3))
4517 (clobber (reg:CC REG_CC))])])
4519 (define_insn "*iorpsi3"
4520 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
4521 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
4522 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
4523 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4524 (clobber (reg:CC REG_CC))]
4527 if (which_alternative == 0)
4528 return "or %A0,%A2" CR_TAB
4532 return avr_out_bitop (insn, operands, NULL);
4534 [(set_attr "length" "3,3,6,6")
4535 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4537 (define_insn_and_split "iorsi3"
4538 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4539 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4540 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
4541 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
4544 "&& reload_completed"
4545 [(parallel [(set (match_dup 0)
4546 (ior:SI (match_dup 1)
4548 (clobber (match_dup 3))
4549 (clobber (reg:CC REG_CC))])])
4551 (define_insn "*iorsi3"
4552 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
4553 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
4554 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
4555 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))
4556 (clobber (reg:CC REG_CC))]
4559 if (which_alternative == 0)
4560 return "or %0,%2" CR_TAB
4565 return avr_out_bitop (insn, operands, NULL);
4567 [(set_attr "length" "4,4,8,8")
4568 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")])
4570 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4573 (define_insn_and_split "xorqi3"
4574 [(set (match_operand:QI 0 "register_operand" "=r")
4575 (xor:QI (match_operand:QI 1 "register_operand" "%0")
4576 (match_operand:QI 2 "register_operand" "r")))]
4579 "&& reload_completed"
4580 [(parallel [(set (match_dup 0)
4581 (xor:QI (match_dup 1)
4583 (clobber (reg:CC REG_CC))])])
4585 (define_insn "*xorqi3"
4586 [(set (match_operand:QI 0 "register_operand" "=r")
4587 (xor:QI (match_operand:QI 1 "register_operand" "%0")
4588 (match_operand:QI 2 "register_operand" "r")))
4589 (clobber (reg:CC REG_CC))]
4592 [(set_attr "length" "1")])
4594 (define_insn_and_split "xorhi3"
4595 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
4596 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
4597 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
4598 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4601 "&& reload_completed"
4602 [(parallel [(set (match_dup 0)
4603 (xor:HI (match_dup 1)
4605 (clobber (match_dup 3))
4606 (clobber (reg:CC REG_CC))])])
4608 (define_insn "*xorhi3"
4609 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
4610 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
4611 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
4612 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4613 (clobber (reg:CC REG_CC))]
4616 if (which_alternative == 0)
4617 return "eor %A0,%A2\;eor %B0,%B2";
4619 return avr_out_bitop (insn, operands, NULL);
4621 [(set_attr "length" "2,2,4")
4622 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4624 (define_insn_and_split "xorpsi3"
4625 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
4626 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
4627 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
4628 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4631 "&& reload_completed"
4632 [(parallel [(set (match_dup 0)
4633 (xor:PSI (match_dup 1)
4635 (clobber (match_dup 3))
4636 (clobber (reg:CC REG_CC))])])
4638 (define_insn "*xorpsi3"
4639 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
4640 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
4641 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
4642 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4643 (clobber (reg:CC REG_CC))]
4646 if (which_alternative == 0)
4647 return "eor %A0,%A2" CR_TAB
4648 "eor %B0,%B2" CR_TAB
4651 return avr_out_bitop (insn, operands, NULL);
4653 [(set_attr "length" "3,6,6")
4654 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4656 (define_insn_and_split "xorsi3"
4657 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
4658 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
4659 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
4660 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
4663 "&& reload_completed"
4664 [(parallel [(set (match_dup 0)
4665 (xor:SI (match_dup 1)
4667 (clobber (match_dup 3))
4668 (clobber (reg:CC REG_CC))])])
4670 (define_insn "*xorsi3"
4671 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
4672 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
4673 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
4674 (clobber (match_scratch:QI 3 "=X,X ,&d"))
4675 (clobber (reg:CC REG_CC))]
4678 if (which_alternative == 0)
4679 return "eor %0,%2" CR_TAB
4680 "eor %B0,%B2" CR_TAB
4681 "eor %C0,%C2" CR_TAB
4684 return avr_out_bitop (insn, operands, NULL);
4686 [(set_attr "length" "4,8,8")
4687 (set_attr "adjust_len" "*,out_bitop,out_bitop")])
4691 [(set (match_operand:SPLIT34 0 "register_operand")
4692 (match_operand:SPLIT34 1 "register_operand"))]
4694 && reload_completed"
4695 [(set (match_dup 2) (match_dup 3))
4696 (set (match_dup 4) (match_dup 5))]
4698 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode;
4699 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]);
4700 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0);
4701 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0);
4702 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2);
4703 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2);
4705 operands[2] = lo_first ? dst_lo : dst_hi;
4706 operands[3] = lo_first ? src_lo : src_hi;
4707 operands[4] = lo_first ? dst_hi : dst_lo;
4708 operands[5] = lo_first ? src_hi : src_lo;
4712 [(set (match_operand:HI 0 "register_operand")
4713 (match_operand:HI 1 "reg_or_0_operand"))]
4716 && GENERAL_REG_P (operands[0])
4717 && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1]))
4719 || const0_rtx == operands[1])"
4720 [(set (match_dup 2) (match_dup 3))
4721 (set (match_dup 4) (match_dup 5))]
4723 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
4724 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
4725 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
4726 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
4729 ;; Split andhi3, andpsi3, andsi3.
4730 ;; Split iorhi3, iorpsi3, iorsi3.
4731 ;; Split xorhi3, xorpsi3, xorsi3.
4733 [(parallel [(set (match_operand:HISI 0 "register_operand")
4734 (bitop:HISI (match_dup 0)
4735 (match_operand:HISI 1 "register_operand")))
4736 (clobber (scratch:QI))
4737 (clobber (reg:CC REG_CC))])]
4739 && reload_completed"
4742 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
4744 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
4745 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
4746 emit_insn (gen_<code>qi3 (dst, dst, src));
4751 ;; If $0 = $0 <op> const requires a QI scratch, and d-reg $1 dies after
4752 ;; the first insn, then we can replace
4754 ;; $0 = $0 <op> const
4756 ;; $1 = $1 <op> const
4758 ;; This transorms constraint alternative "r,0,n,&d" of the first operation
4759 ;; to alternative "d,0,n,X".
4760 ;; "*addhi3_clobber" "*addpsi3" "*addsi3"
4761 ;; "*addhq3" "*adduhq3" "*addha3" "*adduha3"
4762 ;; "*addsq3" "*addusq3" "*addsa3" "*addusa3"
4763 ;; "*iorhi3" "*iorpsi3" "*iorsi3"
4764 ;; "*andhi3" "*andpsi3" "*andsi3"
4766 [(parallel [(set (match_operand:ORDERED234 0 "register_operand")
4767 (match_operand:ORDERED234 1 "d_register_operand"))
4768 (clobber (reg:CC REG_CC))])
4769 (parallel [(set (match_dup 0)
4770 (piaop:ORDERED234 (match_dup 0)
4771 (match_operand:ORDERED234 2 "const_operand")))
4772 ; A d-reg as scratch tells that this insn is expensive, and
4773 ; that $0 is not a d-register: l-reg or something like SI:14 etc.
4774 (clobber (match_operand:QI 3 "d_register_operand"))
4775 (clobber (reg:CC REG_CC))])]
4776 "peep2_reg_dead_p (1, operands[1])"
4777 [(parallel [(set (match_dup 1)
4778 (piaop:ORDERED234 (match_dup 1)
4780 (clobber (scratch:QI))
4781 (clobber (reg:CC REG_CC))])
4782 ; Unfortunately, the following insn misses a REG_DEAD note for $1,
4783 ; so this peep2 works only once.
4784 (parallel [(set (match_dup 0)
4786 (clobber (reg:CC REG_CC))])])
4789 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
4792 (define_expand "rotlqi3"
4793 [(set (match_operand:QI 0 "register_operand" "")
4794 (rotate:QI (match_operand:QI 1 "register_operand" "")
4795 (match_operand:QI 2 "const_0_to_7_operand" "")))]
4798 if (!CONST_INT_P (operands[2]))
4801 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
4804 ;; Expander used by __builtin_avr_swap
4805 (define_expand "rotlqi3_4"
4806 [(set (match_operand:QI 0 "register_operand" "")
4807 (rotate:QI (match_operand:QI 1 "register_operand" "")
4810 (define_insn_and_split "*rotlqi3_split"
4811 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
4812 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
4813 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
4816 "&& reload_completed"
4817 [(parallel [(set (match_dup 0)
4818 (rotate:QI (match_dup 1)
4820 (clobber (reg:CC REG_CC))])])
4822 (define_insn "*rotlqi3"
4823 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
4824 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
4825 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))
4826 (clobber (reg:CC REG_CC))]
4829 lsl %0\;adc %0,__zero_reg__
4830 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
4831 swap %0\;bst %0,0\;ror %0\;bld %0,7
4833 swap %0\;lsl %0\;adc %0,__zero_reg__
4834 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
4835 bst %0,0\;ror %0\;bld %0,7
4837 [(set_attr "length" "2,4,4,1,3,5,3,0")])
4839 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
4840 ;; a whole number of bytes. The split creates the appropriate moves and
4841 ;; considers all overlap situations.
4843 ;; HImode does not need scratch. Use attribute for this constraint.
4845 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
4846 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
4851 (define_expand "rotl<mode>3"
4852 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
4853 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
4854 (match_operand:HISI 2 "const_int_operand" "")))
4855 (clobber (match_dup 3))])]
4860 if (!CONST_INT_P (operands[2]))
4863 offset = INTVAL (operands[2]);
4865 if (0 == offset % 8)
4867 if (AVR_HAVE_MOVW && 0 == offset % 16)
4868 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
4870 operands[3] = gen_rtx_SCRATCH (QImode);
4872 else if (offset == 1
4873 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
4875 /*; Support rotate left/right by 1 */
4877 emit_move_insn (operands[0],
4878 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
4885 (define_insn_and_split "*rotlhi2.1_split"
4886 [(set (match_operand:HI 0 "register_operand" "=r")
4887 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4891 "&& reload_completed"
4892 [(parallel [(set (match_dup 0)
4893 (rotate:HI (match_dup 1)
4895 (clobber (reg:CC REG_CC))])])
4897 (define_insn "*rotlhi2.1"
4898 [(set (match_operand:HI 0 "register_operand" "=r")
4899 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4901 (clobber (reg:CC REG_CC))]
4903 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
4904 [(set_attr "length" "3")])
4906 (define_insn_and_split "*rotlhi2.15_split"
4907 [(set (match_operand:HI 0 "register_operand" "=r")
4908 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4912 "&& reload_completed"
4913 [(parallel [(set (match_dup 0)
4914 (rotate:HI (match_dup 1)
4916 (clobber (reg:CC REG_CC))])])
4918 (define_insn "*rotlhi2.15"
4919 [(set (match_operand:HI 0 "register_operand" "=r")
4920 (rotate:HI (match_operand:HI 1 "register_operand" "0")
4922 (clobber (reg:CC REG_CC))]
4924 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
4925 [(set_attr "length" "4")])
4927 (define_insn_and_split "*rotlpsi2.1_split"
4928 [(set (match_operand:PSI 0 "register_operand" "=r")
4929 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4933 "&& reload_completed"
4934 [(parallel [(set (match_dup 0)
4935 (rotate:PSI (match_dup 1)
4937 (clobber (reg:CC REG_CC))])])
4939 (define_insn "*rotlpsi2.1"
4940 [(set (match_operand:PSI 0 "register_operand" "=r")
4941 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4943 (clobber (reg:CC REG_CC))]
4945 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
4946 [(set_attr "length" "4")])
4948 (define_insn_and_split "*rotlpsi2.23_split"
4949 [(set (match_operand:PSI 0 "register_operand" "=r")
4950 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4954 "&& reload_completed"
4955 [(parallel [(set (match_dup 0)
4956 (rotate:PSI (match_dup 1)
4958 (clobber (reg:CC REG_CC))])])
4960 (define_insn "*rotlpsi2.23"
4961 [(set (match_operand:PSI 0 "register_operand" "=r")
4962 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
4964 (clobber (reg:CC REG_CC))]
4966 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
4967 [(set_attr "length" "5")])
4969 (define_insn_and_split "*rotlsi2.1_split"
4970 [(set (match_operand:SI 0 "register_operand" "=r")
4971 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4975 "&& reload_completed"
4976 [(parallel [(set (match_dup 0)
4977 (rotate:SI (match_dup 1)
4979 (clobber (reg:CC REG_CC))])])
4981 (define_insn "*rotlsi2.1"
4982 [(set (match_operand:SI 0 "register_operand" "=r")
4983 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4985 (clobber (reg:CC REG_CC))]
4987 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
4988 [(set_attr "length" "5")])
4990 (define_insn_and_split "*rotlsi2.31_split"
4991 [(set (match_operand:SI 0 "register_operand" "=r")
4992 (rotate:SI (match_operand:SI 1 "register_operand" "0")
4996 "&& reload_completed"
4997 [(parallel [(set (match_dup 0)
4998 (rotate:SI (match_dup 1)
5000 (clobber (reg:CC REG_CC))])])
5002 (define_insn "*rotlsi2.31"
5003 [(set (match_operand:SI 0 "register_operand" "=r")
5004 (rotate:SI (match_operand:SI 1 "register_operand" "0")
5006 (clobber (reg:CC REG_CC))]
5008 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
5009 [(set_attr "length" "6")])
5011 ;; Overlapping non-HImode registers often (but not always) need a scratch.
5012 ;; The best we can do is use early clobber alternative "#&r" so that
5013 ;; completely non-overlapping operands dont get a scratch but # so register
5014 ;; allocation does not prefer non-overlapping.
5017 ;; Split word aligned rotates using scratch that is mode dependent.
5021 (define_insn_and_split "*rotw<mode>"
5022 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
5023 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
5024 (match_operand 2 "const_int_operand" "n,n,n")))
5025 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
5027 && CONST_INT_P (operands[2])
5028 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
5029 && 0 == INTVAL (operands[2]) % 16"
5031 "&& reload_completed"
5034 avr_rotate_bytes (operands);
5039 ;; Split byte aligned rotates using scratch that is always QI mode.
5044 (define_insn_and_split "*rotb<mode>"
5045 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
5046 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
5047 (match_operand 2 "const_int_operand" "n,n,n")))
5048 (clobber (match_scratch:QI 3 "=<rotx>"))]
5049 "CONST_INT_P (operands[2])
5050 && (8 == INTVAL (operands[2]) % 16
5052 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
5053 && 0 == INTVAL (operands[2]) % 16))"
5055 "&& reload_completed"
5058 avr_rotate_bytes (operands);
5063 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
5064 ;; arithmetic shift left
5067 ;; "ashlqq3" "ashluqq3"
5068 (define_expand "ashl<mode>3"
5069 [(set (match_operand:ALL1 0 "register_operand" "")
5070 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
5071 (match_operand:QI 2 "nop_general_operand" "")))])
5073 (define_split ; ashlqi3_const4
5074 [(set (match_operand:ALL1 0 "d_register_operand" "")
5075 (ashift:ALL1 (match_dup 0)
5079 (rotate:QI (match_dup 1)
5082 (and:QI (match_dup 1)
5085 operands[1] = avr_to_int_mode (operands[0]);
5088 (define_split ; ashlqi3_const5
5089 [(set (match_operand:ALL1 0 "d_register_operand" "")
5090 (ashift:ALL1 (match_dup 0)
5093 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5094 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
5095 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
5097 operands[1] = avr_to_int_mode (operands[0]);
5100 (define_split ; ashlqi3_const6
5101 [(set (match_operand:ALL1 0 "d_register_operand" "")
5102 (ashift:ALL1 (match_dup 0)
5105 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5106 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
5107 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
5109 operands[1] = avr_to_int_mode (operands[0]);
5113 ;; "*ashlqq3" "*ashluqq3"
5114 (define_insn_and_split "*ashl<mode>3_split"
5115 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5116 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5117 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
5120 "&& reload_completed"
5121 [(parallel [(set (match_dup 0)
5122 (ashift:ALL1 (match_dup 1)
5124 (clobber (reg:CC REG_CC))])])
5126 (define_insn "*ashl<mode>3"
5127 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5128 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5129 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))
5130 (clobber (reg:CC REG_CC))]
5133 return ashlqi3_out (insn, operands, NULL);
5135 [(set_attr "length" "5,0,1,2,4,6,9")
5136 (set_attr "adjust_len" "ashlqi")])
5138 (define_insn_and_split "ashl<mode>3"
5139 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5140 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5141 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5144 "&& reload_completed"
5145 [(parallel [(set (match_dup 0)
5146 (ashift:ALL2 (match_dup 1)
5148 (clobber (reg:CC REG_CC))])])
5150 (define_insn "*ashl<mode>3"
5151 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5152 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5153 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5154 (clobber (reg:CC REG_CC))]
5157 return ashlhi3_out (insn, operands, NULL);
5159 [(set_attr "length" "6,0,2,2,4,10,10")
5160 (set_attr "adjust_len" "ashlhi")])
5163 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
5164 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
5168 (define_insn_and_split "*ashl<extend_su>qihiqi3"
5169 [(set (match_operand:QI 0 "register_operand" "=r")
5170 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
5171 (match_operand:QI 2 "register_operand" "r"))
5177 (ashift:QI (match_dup 1)
5180 ;; ??? Combiner does not recognize that it could split the following insn;
5181 ;; presumably because he has no register handy?
5183 ;; "*ashluqihiqi3.mem"
5184 ;; "*ashlsqihiqi3.mem"
5185 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
5186 [(set (match_operand:QI 0 "memory_operand" "=m")
5187 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
5188 (match_operand:QI 2 "register_operand" "r"))
5191 { gcc_unreachable(); }
5194 (ashift:QI (match_dup 1)
5199 operands[3] = gen_reg_rtx (QImode);
5204 (define_insn_and_split "*ashlhiqi3"
5205 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
5206 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
5207 (match_operand:QI 2 "register_operand" "r")) 0))]
5209 { gcc_unreachable(); }
5212 (ashift:QI (match_dup 3)
5217 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
5218 operands[4] = gen_reg_rtx (QImode);
5221 ;; High part of 16-bit shift is unused after the instruction:
5222 ;; No need to compute it, map to 8-bit shift.
5225 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5226 (ashift:HI (match_dup 0)
5227 (match_operand:QI 1 "register_operand" "")))
5228 (clobber (reg:CC REG_CC))])]
5230 [(parallel [(set (match_dup 2)
5231 (ashift:QI (match_dup 2)
5233 (clobber (reg:CC REG_CC))])
5234 (clobber (match_dup 3))]
5236 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
5238 if (!peep2_reg_dead_p (1, operands[3]))
5241 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
5246 ;; "ashlsq3" "ashlusq3"
5247 ;; "ashlsa3" "ashlusa3"
5248 (define_insn_and_split "ashl<mode>3"
5249 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5250 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5251 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5254 "&& reload_completed"
5255 [(parallel [(set (match_dup 0)
5256 (ashift:ALL4 (match_dup 1)
5258 (clobber (reg:CC REG_CC))])])
5260 (define_insn "*ashl<mode>3"
5261 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5262 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5263 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5264 (clobber (reg:CC REG_CC))]
5267 return ashlsi3_out (insn, operands, NULL);
5269 [(set_attr "length" "8,0,4,4,8,10,12")
5270 (set_attr "adjust_len" "ashlsi")])
5272 ;; Optimize if a scratch register from LD_REGS happens to be available.
5274 (define_peephole2 ; ashlqi3_l_const4
5275 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5276 (ashift:ALL1 (match_dup 0)
5278 (clobber (reg:CC REG_CC))])
5279 (match_scratch:QI 1 "d")]
5281 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5282 (clobber (reg:CC REG_CC))])
5283 (parallel [(set (match_dup 1) (const_int -16))
5284 (clobber (reg:CC REG_CC))])
5285 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5286 (clobber (reg:CC REG_CC))])]
5288 operands[2] = avr_to_int_mode (operands[0]);
5291 (define_peephole2 ; ashlqi3_l_const5
5292 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5293 (ashift:ALL1 (match_dup 0)
5295 (clobber (reg:CC REG_CC))])
5296 (match_scratch:QI 1 "d")]
5298 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5299 (clobber (reg:CC REG_CC))])
5300 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
5301 (clobber (reg:CC REG_CC))])
5302 (parallel [(set (match_dup 1) (const_int -32))
5303 (clobber (reg:CC REG_CC))])
5304 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5305 (clobber (reg:CC REG_CC))])]
5307 operands[2] = avr_to_int_mode (operands[0]);
5310 (define_peephole2 ; ashlqi3_l_const6
5311 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5312 (ashift:ALL1 (match_dup 0)
5314 (clobber (reg:CC REG_CC))])
5315 (match_scratch:QI 1 "d")]
5317 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5318 (clobber (reg:CC REG_CC))])
5319 (parallel [(set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
5320 (clobber (reg:CC REG_CC))])
5321 (parallel [(set (match_dup 1) (const_int -64))
5322 (clobber (reg:CC REG_CC))])
5323 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5324 (clobber (reg:CC REG_CC))])]
5326 operands[2] = avr_to_int_mode (operands[0]);
5330 [(match_scratch:QI 3 "d")
5331 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5332 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
5333 (match_operand:QI 2 "const_int_operand" "")))
5334 (clobber (reg:CC REG_CC))])]
5336 [(parallel [(set (match_dup 0)
5337 (ashift:ALL2 (match_dup 1)
5339 (clobber (match_dup 3))
5340 (clobber (reg:CC REG_CC))])])
5343 ;; "*ashlhq3_const" "*ashluhq3_const"
5344 ;; "*ashlha3_const" "*ashluha3_const"
5345 (define_insn_and_split "*ashl<mode>3_const_split"
5346 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5347 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5348 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5349 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5352 "&& reload_completed"
5353 [(parallel [(set (match_dup 0)
5354 (ashift:ALL2 (match_dup 1)
5356 (clobber (match_dup 3))
5357 (clobber (reg:CC REG_CC))])])
5359 (define_insn "*ashl<mode>3_const"
5360 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5361 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5362 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5363 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5364 (clobber (reg:CC REG_CC))]
5367 return ashlhi3_out (insn, operands, NULL);
5369 [(set_attr "length" "0,2,2,4,10")
5370 (set_attr "adjust_len" "ashlhi")])
5373 [(match_scratch:QI 3 "d")
5374 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5375 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
5376 (match_operand:QI 2 "const_int_operand" "")))
5377 (clobber (reg:CC REG_CC))])]
5379 [(parallel [(set (match_dup 0)
5380 (ashift:ALL4 (match_dup 1)
5382 (clobber (match_dup 3))
5383 (clobber (reg:CC REG_CC))])])
5386 ;; "*ashlsq3_const" "*ashlusq3_const"
5387 ;; "*ashlsa3_const" "*ashlusa3_const"
5388 (define_insn_and_split "*ashl<mode>3_const_split"
5389 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5390 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5391 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5392 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5395 "&& reload_completed"
5396 [(parallel [(set (match_dup 0)
5397 (ashift:ALL4 (match_dup 1)
5399 (clobber (match_dup 3))
5400 (clobber (reg:CC REG_CC))])])
5402 (define_insn "*ashl<mode>3_const"
5403 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5404 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5405 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5406 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5407 (clobber (reg:CC REG_CC))]
5410 return ashlsi3_out (insn, operands, NULL);
5412 [(set_attr "length" "0,4,4,10")
5413 (set_attr "adjust_len" "ashlsi")])
5415 (define_expand "ashlpsi3"
5416 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
5417 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
5418 (match_operand:QI 2 "nonmemory_operand" "")))
5419 (clobber (scratch:QI))])]
5423 && CONST_INT_P (operands[2]))
5425 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
5427 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
5428 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
5431 else if (optimize_insn_for_speed_p ()
5432 && INTVAL (operands[2]) != 16
5433 && IN_RANGE (INTVAL (operands[2]), 9, 22))
5435 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
5436 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
5442 (define_insn_and_split "*ashlpsi3_split"
5443 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
5444 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
5445 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
5446 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5449 "&& reload_completed"
5450 [(parallel [(set (match_dup 0)
5451 (ashift:PSI (match_dup 1)
5453 (clobber (match_dup 3))
5454 (clobber (reg:CC REG_CC))])])
5456 (define_insn "*ashlpsi3"
5457 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
5458 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
5459 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
5460 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5461 (clobber (reg:CC REG_CC))]
5464 return avr_out_ashlpsi3 (insn, operands, NULL);
5466 [(set_attr "adjust_len" "ashlpsi")])
5468 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
5469 ;; arithmetic shift right
5472 ;; "ashrqq3" "ashruqq3"
5473 (define_insn_and_split "ashr<mode>3"
5474 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
5475 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
5476 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
5479 "&& reload_completed"
5480 [(parallel [(set (match_dup 0)
5481 (ashiftrt:ALL1 (match_dup 1)
5483 (clobber (reg:CC REG_CC))])])
5485 (define_insn "*ashr<mode>3"
5486 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
5487 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
5488 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))
5489 (clobber (reg:CC REG_CC))]
5492 return ashrqi3_out (insn, operands, NULL);
5494 [(set_attr "length" "5,0,1,2,5,4,9")
5495 (set_attr "adjust_len" "ashrqi")])
5498 ;; "ashrhq3" "ashruhq3"
5499 ;; "ashrha3" "ashruha3"
5500 (define_insn_and_split "ashr<mode>3"
5501 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5502 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5503 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5506 "&& reload_completed"
5507 [(parallel [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5508 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5509 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5510 (clobber (reg:CC REG_CC))])])
5512 (define_insn "*ashr<mode>3"
5513 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5514 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5515 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5516 (clobber (reg:CC REG_CC))]
5519 return ashrhi3_out (insn, operands, NULL);
5521 [(set_attr "length" "6,0,2,4,4,10,10")
5522 (set_attr "adjust_len" "ashrhi")])
5524 (define_insn_and_split "ashrpsi3"
5525 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5526 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
5527 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
5528 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5531 "&& reload_completed"
5532 [(parallel [(set (match_dup 0)
5533 (ashiftrt:PSI (match_dup 1)
5535 (clobber (match_dup 3))
5536 (clobber (reg:CC REG_CC))])])
5538 (define_insn "*ashrpsi3"
5539 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5540 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
5541 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
5542 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5543 (clobber (reg:CC REG_CC))]
5546 return avr_out_ashrpsi3 (insn, operands, NULL);
5548 [(set_attr "adjust_len" "ashrpsi")])
5551 ;; "ashrsq3" "ashrusq3"
5552 ;; "ashrsa3" "ashrusa3"
5553 (define_insn_and_split "ashr<mode>3"
5554 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5555 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5556 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5559 "&& reload_completed"
5560 [(parallel [(set (match_dup 0)
5561 (ashiftrt:ALL4 (match_dup 1)
5563 (clobber (reg:CC REG_CC))])])
5565 (define_insn "*ashr<mode>3"
5566 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5567 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5568 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5569 (clobber (reg:CC REG_CC))]
5572 return ashrsi3_out (insn, operands, NULL);
5574 [(set_attr "length" "8,0,4,6,8,10,12")
5575 (set_attr "adjust_len" "ashrsi")])
5577 ;; Optimize if a scratch register from LD_REGS happens to be available.
5580 [(match_scratch:QI 3 "d")
5581 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5582 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
5583 (match_operand:QI 2 "const_int_operand" "")))
5584 (clobber (reg:CC REG_CC))])]
5586 [(parallel [(set (match_dup 0)
5587 (ashiftrt:ALL2 (match_dup 1)
5589 (clobber (match_dup 3))
5590 (clobber (reg:CC REG_CC))])])
5593 ;; "*ashrhq3_const" "*ashruhq3_const"
5594 ;; "*ashrha3_const" "*ashruha3_const"
5595 (define_insn_and_split "*ashr<mode>3_const_split"
5596 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5597 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5598 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5599 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5602 "&& reload_completed"
5603 [(parallel [(set (match_dup 0)
5604 (ashiftrt:ALL2 (match_dup 1)
5606 (clobber (match_dup 3))
5607 (clobber (reg:CC REG_CC))])])
5609 (define_insn "*ashr<mode>3_const"
5610 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5611 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5612 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5613 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5614 (clobber (reg:CC REG_CC))]
5617 return ashrhi3_out (insn, operands, NULL);
5619 [(set_attr "length" "0,2,4,4,10")
5620 (set_attr "adjust_len" "ashrhi")])
5623 [(match_scratch:QI 3 "d")
5624 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5625 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
5626 (match_operand:QI 2 "const_int_operand" "")))
5627 (clobber (reg:CC REG_CC))])]
5629 [(parallel [(set (match_dup 0)
5630 (ashiftrt:ALL4 (match_dup 1)
5632 (clobber (match_dup 3))
5633 (clobber (reg:CC REG_CC))])])
5636 ;; "*ashrsq3_const" "*ashrusq3_const"
5637 ;; "*ashrsa3_const" "*ashrusa3_const"
5638 (define_insn_and_split "*ashr<mode>3_const_split"
5639 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5640 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5641 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5642 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5645 "&& reload_completed"
5646 [(parallel [(set (match_dup 0)
5647 (ashiftrt:ALL4 (match_dup 1)
5649 (clobber (match_dup 3))
5650 (clobber (reg:CC REG_CC))])])
5652 (define_insn "*ashr<mode>3_const"
5653 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5654 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5655 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5656 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5657 (clobber (reg:CC REG_CC))]
5660 return ashrsi3_out (insn, operands, NULL);
5662 [(set_attr "length" "0,4,4,10")
5663 (set_attr "adjust_len" "ashrsi")])
5665 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
5666 ;; logical shift right
5669 ;; "lshrqq3" "lshruqq3"
5670 (define_expand "lshr<mode>3"
5671 [(set (match_operand:ALL1 0 "register_operand" "")
5672 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
5673 (match_operand:QI 2 "nop_general_operand" "")))])
5675 (define_split ; lshrqi3_const4
5676 [(set (match_operand:ALL1 0 "d_register_operand" "")
5677 (lshiftrt:ALL1 (match_dup 0)
5681 (rotate:QI (match_dup 1)
5684 (and:QI (match_dup 1)
5687 operands[1] = avr_to_int_mode (operands[0]);
5690 (define_split ; lshrqi3_const5
5691 [(set (match_operand:ALL1 0 "d_register_operand" "")
5692 (lshiftrt:ALL1 (match_dup 0)
5695 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5696 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
5697 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
5699 operands[1] = avr_to_int_mode (operands[0]);
5702 (define_split ; lshrqi3_const6
5703 [(set (match_operand:QI 0 "d_register_operand" "")
5704 (lshiftrt:QI (match_dup 0)
5707 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
5708 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
5709 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
5711 operands[1] = avr_to_int_mode (operands[0]);
5717 (define_insn_and_split "*lshr<mode>3_split"
5718 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5719 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5720 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
5723 "&& reload_completed"
5724 [(parallel [(set (match_dup 0)
5725 (lshiftrt:ALL1 (match_dup 1)
5727 (clobber (reg:CC REG_CC))])])
5729 (define_insn "*lshr<mode>3"
5730 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
5731 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
5732 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))
5733 (clobber (reg:CC REG_CC))]
5736 return lshrqi3_out (insn, operands, NULL);
5738 [(set_attr "length" "5,0,1,2,4,6,9")
5739 (set_attr "adjust_len" "lshrqi")])
5742 ;; "lshrhq3" "lshruhq3"
5743 ;; "lshrha3" "lshruha3"
5744 (define_insn_and_split "lshr<mode>3"
5745 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5746 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5747 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5750 "&& reload_completed"
5751 [(parallel [(set (match_dup 0)
5752 (lshiftrt:ALL2 (match_dup 1)
5754 (clobber (reg:CC REG_CC))])])
5756 (define_insn "*lshr<mode>3"
5757 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
5758 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
5759 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5760 (clobber (reg:CC REG_CC))]
5763 return lshrhi3_out (insn, operands, NULL);
5765 [(set_attr "length" "6,0,2,2,4,10,10")
5766 (set_attr "adjust_len" "lshrhi")])
5768 (define_insn_and_split "lshrpsi3"
5769 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5770 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
5771 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
5772 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5775 "&& reload_completed"
5776 [(parallel [(set (match_dup 0)
5777 (lshiftrt:PSI (match_dup 1)
5779 (clobber (match_dup 3))
5780 (clobber (reg:CC REG_CC))])])
5782 (define_insn "*lshrpsi3"
5783 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
5784 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
5785 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
5786 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5787 (clobber (reg:CC REG_CC))]
5790 return avr_out_lshrpsi3 (insn, operands, NULL);
5792 [(set_attr "adjust_len" "lshrpsi")])
5795 ;; "lshrsq3" "lshrusq3"
5796 ;; "lshrsa3" "lshrusa3"
5797 (define_insn_and_split "lshr<mode>3"
5798 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5799 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5800 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
5803 "&& reload_completed"
5804 [(parallel [(set (match_dup 0)
5805 (lshiftrt:ALL4 (match_dup 1)
5807 (clobber (reg:CC REG_CC))])])
5809 (define_insn "*lshr<mode>3"
5810 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
5811 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
5812 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))
5813 (clobber (reg:CC REG_CC))]
5816 return lshrsi3_out (insn, operands, NULL);
5818 [(set_attr "length" "8,0,4,4,8,10,12")
5819 (set_attr "adjust_len" "lshrsi")])
5821 ;; Optimize if a scratch register from LD_REGS happens to be available.
5823 (define_peephole2 ; lshrqi3_l_const4
5824 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5825 (lshiftrt:ALL1 (match_dup 0)
5827 (clobber (reg:CC REG_CC))])
5828 (match_scratch:QI 1 "d")]
5830 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5831 (clobber (reg:CC REG_CC))])
5832 (parallel [(set (match_dup 1) (const_int 15))
5833 (clobber (reg:CC REG_CC))])
5834 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5835 (clobber (reg:CC REG_CC))])]
5837 operands[2] = avr_to_int_mode (operands[0]);
5840 (define_peephole2 ; lshrqi3_l_const5
5841 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5842 (lshiftrt:ALL1 (match_dup 0)
5844 (clobber (reg:CC REG_CC))])
5845 (match_scratch:QI 1 "d")]
5847 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5848 (clobber (reg:CC REG_CC))])
5849 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
5850 (clobber (reg:CC REG_CC))])
5851 (parallel [(set (match_dup 1) (const_int 7))
5852 (clobber (reg:CC REG_CC))])
5853 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5854 (clobber (reg:CC REG_CC))])]
5856 operands[2] = avr_to_int_mode (operands[0]);
5859 (define_peephole2 ; lshrqi3_l_const6
5860 [(parallel [(set (match_operand:ALL1 0 "l_register_operand" "")
5861 (lshiftrt:ALL1 (match_dup 0)
5863 (clobber (reg:CC REG_CC))])
5864 (match_scratch:QI 1 "d")]
5866 [(parallel [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
5867 (clobber (reg:CC REG_CC))])
5868 (parallel [(set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
5869 (clobber (reg:CC REG_CC))])
5870 (parallel [(set (match_dup 1) (const_int 3))
5871 (clobber (reg:CC REG_CC))])
5872 (parallel [(set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))
5873 (clobber (reg:CC REG_CC))])]
5875 operands[2] = avr_to_int_mode (operands[0]);
5879 [(match_scratch:QI 3 "d")
5880 (parallel [(set (match_operand:ALL2 0 "register_operand" "")
5881 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
5882 (match_operand:QI 2 "const_int_operand" "")))
5883 (clobber (reg:CC REG_CC))])]
5885 [(parallel [(set (match_dup 0)
5886 (lshiftrt:ALL2 (match_dup 1)
5888 (clobber (match_dup 3))
5889 (clobber (reg:CC REG_CC))])])
5892 ;; "*lshrhq3_const" "*lshruhq3_const"
5893 ;; "*lshrha3_const" "*lshruha3_const"
5894 (define_insn_and_split "*lshr<mode>3_const_split"
5895 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5896 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5897 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5898 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
5901 "&& reload_completed"
5902 [(parallel [(set (match_dup 0)
5903 (lshiftrt:ALL2 (match_dup 1)
5905 (clobber (match_dup 3))
5906 (clobber (reg:CC REG_CC))])])
5908 (define_insn "*lshr<mode>3_const"
5909 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
5910 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
5911 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
5912 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))
5913 (clobber (reg:CC REG_CC))]
5916 return lshrhi3_out (insn, operands, NULL);
5918 [(set_attr "length" "0,2,2,4,10")
5919 (set_attr "adjust_len" "lshrhi")])
5922 [(match_scratch:QI 3 "d")
5923 (parallel [(set (match_operand:ALL4 0 "register_operand" "")
5924 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
5925 (match_operand:QI 2 "const_int_operand" "")))
5926 (clobber (reg:CC REG_CC))])]
5928 [(parallel [(set (match_dup 0)
5929 (lshiftrt:ALL4 (match_dup 1)
5931 (clobber (match_dup 3))
5932 (clobber (reg:CC REG_CC))])])
5935 ;; "*lshrsq3_const" "*lshrusq3_const"
5936 ;; "*lshrsa3_const" "*lshrusa3_const"
5937 (define_insn_and_split "*lshr<mode>3_const_split"
5938 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5939 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5940 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5941 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
5944 "&& reload_completed"
5945 [(parallel [(set (match_dup 0)
5946 (lshiftrt:ALL4 (match_dup 1)
5948 (clobber (match_dup 3))
5949 (clobber (reg:CC REG_CC))])])
5951 (define_insn "*lshr<mode>3_const"
5952 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
5953 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
5954 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
5955 (clobber (match_scratch:QI 3 "=X,X,X,&d"))
5956 (clobber (reg:CC REG_CC))]
5959 return lshrsi3_out (insn, operands, NULL);
5961 [(set_attr "length" "0,4,4,10")
5962 (set_attr "adjust_len" "lshrsi")])
5964 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
5967 (define_insn_and_split "absqi2"
5968 [(set (match_operand:QI 0 "register_operand" "=r")
5969 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
5972 "&& reload_completed"
5973 [(parallel [(set (match_dup 0)
5974 (abs:QI (match_dup 1)))
5975 (clobber (reg:CC REG_CC))])])
5977 (define_insn "*absqi2"
5978 [(set (match_operand:QI 0 "register_operand" "=r")
5979 (abs:QI (match_operand:QI 1 "register_operand" "0")))
5980 (clobber (reg:CC REG_CC))]
5984 [(set_attr "length" "2")])
5987 (define_insn_and_split "abssf2"
5988 [(set (match_operand:SF 0 "register_operand" "=d,r")
5989 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
5992 "&& reload_completed"
5993 [(parallel [(set (match_dup 0)
5994 (abs:SF (match_dup 1)))
5995 (clobber (reg:CC REG_CC))])])
5997 (define_insn "*abssf2"
5998 [(set (match_operand:SF 0 "register_operand" "=d,r")
5999 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))
6000 (clobber (reg:CC REG_CC))]
6005 [(set_attr "length" "1,2")])
6007 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
6010 (define_insn_and_split "negqi2"
6011 [(set (match_operand:QI 0 "register_operand" "=r")
6012 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
6015 "&& reload_completed"
6016 [(parallel [(set (match_dup 0)
6017 (neg:QI (match_dup 1)))
6018 (clobber (reg:CC REG_CC))])])
6020 (define_insn "*negqi2"
6021 [(set (match_operand:QI 0 "register_operand" "=r")
6022 (neg:QI (match_operand:QI 1 "register_operand" "0")))
6023 (clobber (reg:CC REG_CC))]
6026 [(set_attr "length" "1")])
6028 (define_insn_and_split "*negqihi2_split"
6029 [(set (match_operand:HI 0 "register_operand" "=r")
6030 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
6033 "&& reload_completed"
6034 [(parallel [(set (match_dup 0)
6035 (neg:HI (sign_extend:HI (match_dup 1))))
6036 (clobber (reg:CC REG_CC))])])
6038 (define_insn "*negqihi2"
6039 [(set (match_operand:HI 0 "register_operand" "=r")
6040 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))
6041 (clobber (reg:CC REG_CC))]
6043 "clr %B0\;neg %A0\;brge .+2\;com %B0"
6044 [(set_attr "length" "4")])
6046 (define_insn_and_split "neghi2"
6047 [(set (match_operand:HI 0 "register_operand" "=r,&r")
6048 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
6051 "&& reload_completed"
6052 [(parallel [(set (match_dup 0)
6053 (neg:HI (match_dup 1)))
6054 (clobber (reg:CC REG_CC))])])
6056 (define_insn "*neghi2"
6057 [(set (match_operand:HI 0 "register_operand" "=r,&r")
6058 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))
6059 (clobber (reg:CC REG_CC))]
6062 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
6063 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
6064 [(set_attr "length" "3,4")])
6066 (define_insn_and_split "negpsi2"
6067 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
6068 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
6071 "&& reload_completed"
6072 [(parallel [(set (match_dup 0)
6073 (neg:PSI (match_dup 1)))
6074 (clobber (reg:CC REG_CC))])])
6076 (define_insn "*negpsi2"
6077 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
6078 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))
6079 (clobber (reg:CC REG_CC))]
6082 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
6083 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
6084 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
6085 [(set_attr "length" "5,6,6")])
6087 (define_insn_and_split "negsi2"
6088 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
6089 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
6092 "&& reload_completed"
6093 [(parallel [(set (match_dup 0)
6094 (neg:SI (match_dup 1)))
6095 (clobber (reg:CC REG_CC))])]
6097 [(set_attr "isa" "*,*,mov,movw")])
6099 (define_insn "*negsi2"
6100 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
6101 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))
6102 (clobber (reg:CC REG_CC))]
6105 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
6106 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
6107 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
6108 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
6109 [(set_attr "length" "7,8,8,7")
6110 (set_attr "isa" "*,*,mov,movw")])
6112 (define_insn_and_split "negsf2"
6113 [(set (match_operand:SF 0 "register_operand" "=d,r")
6114 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
6117 "&& reload_completed"
6118 [(parallel [(set (match_dup 0)
6119 (neg:SF (match_dup 1)))
6120 (clobber (reg:CC REG_CC))])])
6122 (define_insn "*negsf2"
6123 [(set (match_operand:SF 0 "register_operand" "=d,r")
6124 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))
6125 (clobber (reg:CC REG_CC))]
6129 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
6130 [(set_attr "length" "1,4")])
6132 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6135 (define_insn_and_split "one_cmplqi2"
6136 [(set (match_operand:QI 0 "register_operand" "=r")
6137 (not:QI (match_operand:QI 1 "register_operand" "0")))]
6140 "&& reload_completed"
6141 [(parallel [(set (match_dup 0)
6142 (not:QI (match_dup 1)))
6143 (clobber (reg:CC REG_CC))])])
6145 (define_insn "*one_cmplqi2"
6146 [(set (match_operand:QI 0 "register_operand" "=r")
6147 (not:QI (match_operand:QI 1 "register_operand" "0")))
6148 (clobber (reg:CC REG_CC))]
6151 [(set_attr "length" "1")])
6153 (define_insn_and_split "one_cmplhi2"
6154 [(set (match_operand:HI 0 "register_operand" "=r")
6155 (not:HI (match_operand:HI 1 "register_operand" "0")))]
6158 "&& reload_completed"
6159 [(parallel [(set (match_dup 0)
6160 (not:HI (match_dup 1)))
6161 (clobber (reg:CC REG_CC))])])
6163 (define_insn "*one_cmplhi2"
6164 [(set (match_operand:HI 0 "register_operand" "=r")
6165 (not:HI (match_operand:HI 1 "register_operand" "0")))
6166 (clobber (reg:CC REG_CC))]
6170 [(set_attr "length" "2")])
6172 (define_insn_and_split "one_cmplpsi2"
6173 [(set (match_operand:PSI 0 "register_operand" "=r")
6174 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
6177 "&& reload_completed"
6178 [(parallel [(set (match_dup 0)
6179 (not:PSI (match_dup 1)))
6180 (clobber (reg:CC REG_CC))])])
6182 (define_insn "*one_cmplpsi2"
6183 [(set (match_operand:PSI 0 "register_operand" "=r")
6184 (not:PSI (match_operand:PSI 1 "register_operand" "0")))
6185 (clobber (reg:CC REG_CC))]
6187 "com %0\;com %B0\;com %C0"
6188 [(set_attr "length" "3")])
6190 (define_insn_and_split "one_cmplsi2"
6191 [(set (match_operand:SI 0 "register_operand" "=r")
6192 (not:SI (match_operand:SI 1 "register_operand" "0")))]
6195 "&& reload_completed"
6196 [(parallel [(set (match_dup 0)
6197 (not:SI (match_dup 1)))
6198 (clobber (reg:CC REG_CC))])])
6200 (define_insn "*one_cmplsi2"
6201 [(set (match_operand:SI 0 "register_operand" "=r")
6202 (not:SI (match_operand:SI 1 "register_operand" "0")))
6203 (clobber (reg:CC REG_CC))]
6209 [(set_attr "length" "4")])
6211 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
6214 ;; We keep combiner from inserting hard registers into the input of sign- and
6215 ;; zero-extends. A hard register in the input operand is not wanted because
6216 ;; 32-bit multiply patterns clobber some hard registers and extends with a
6217 ;; hard register that overlaps these clobbers won't be combined to a widening
6218 ;; multiplication. There is no need for combine to propagate hard registers,
6219 ;; register allocation can do it just as well.
6221 (define_insn_and_split "extendqihi2"
6222 [(set (match_operand:HI 0 "register_operand" "=r,r")
6223 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6226 "&& reload_completed"
6227 [(parallel [(set (match_dup 0)
6228 (sign_extend:HI (match_dup 1)))
6229 (clobber (reg:CC REG_CC))])])
6231 (define_insn "*extendqihi2"
6232 [(set (match_operand:HI 0 "register_operand" "=r,r")
6233 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6234 (clobber (reg:CC REG_CC))]
6237 return avr_out_sign_extend (insn, operands, NULL);
6239 [(set_attr "length" "3,4")
6240 (set_attr "adjust_len" "sext")])
6242 (define_insn_and_split "extendqipsi2"
6243 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6244 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6247 "&& reload_completed"
6248 [(parallel [(set (match_dup 0)
6249 (sign_extend:PSI (match_dup 1)))
6250 (clobber (reg:CC REG_CC))])])
6252 (define_insn "*extendqipsi2"
6253 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6254 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6255 (clobber (reg:CC REG_CC))]
6258 return avr_out_sign_extend (insn, operands, NULL);
6260 [(set_attr "length" "4,5")
6261 (set_attr "adjust_len" "sext")])
6263 (define_insn_and_split "extendqisi2"
6264 [(set (match_operand:SI 0 "register_operand" "=r,r")
6265 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
6268 "&& reload_completed"
6269 [(parallel [(set (match_dup 0)
6270 (sign_extend:SI (match_dup 1)))
6271 (clobber (reg:CC REG_CC))])])
6273 (define_insn "*extendqisi2"
6274 [(set (match_operand:SI 0 "register_operand" "=r,r")
6275 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))
6276 (clobber (reg:CC REG_CC))]
6279 return avr_out_sign_extend (insn, operands, NULL);
6281 [(set_attr "length" "5,6")
6282 (set_attr "adjust_len" "sext")])
6284 (define_insn_and_split "extendhipsi2"
6285 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6286 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
6289 "&& reload_completed"
6290 [(parallel [(set (match_dup 0)
6291 (sign_extend:PSI (match_dup 1)))
6292 (clobber (reg:CC REG_CC))])])
6294 (define_insn "*extendhipsi2"
6295 [(set (match_operand:PSI 0 "register_operand" "=r,r")
6296 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))
6297 (clobber (reg:CC REG_CC))]
6300 return avr_out_sign_extend (insn, operands, NULL);
6302 [(set_attr "length" "3,5")
6303 (set_attr "adjust_len" "sext")])
6305 (define_insn_and_split "extendhisi2"
6306 [(set (match_operand:SI 0 "register_operand" "=r,r")
6307 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
6310 "&& reload_completed"
6311 [(parallel [(set (match_dup 0)
6312 (sign_extend:SI (match_dup 1)))
6313 (clobber (reg:CC REG_CC))])])
6315 (define_insn "*extendhisi2"
6316 [(set (match_operand:SI 0 "register_operand" "=r,r")
6317 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))
6318 (clobber (reg:CC REG_CC))]
6321 return avr_out_sign_extend (insn, operands, NULL);
6323 [(set_attr "length" "4,6")
6324 (set_attr "adjust_len" "sext")])
6326 (define_insn_and_split "extendpsisi2"
6327 [(set (match_operand:SI 0 "register_operand" "=r")
6328 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
6331 "&& reload_completed"
6332 [(parallel [(set (match_dup 0)
6333 (sign_extend:SI (match_dup 1)))
6334 (clobber (reg:CC REG_CC))])])
6336 (define_insn "*extendpsisi2"
6337 [(set (match_operand:SI 0 "register_operand" "=r")
6338 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))
6339 (clobber (reg:CC REG_CC))]
6342 return avr_out_sign_extend (insn, operands, NULL);
6344 [(set_attr "length" "3")
6345 (set_attr "adjust_len" "sext")])
6347 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
6350 (define_insn_and_split "zero_extendqihi2"
6351 [(set (match_operand:HI 0 "register_operand" "=r")
6352 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6356 [(set (match_dup 2) (match_dup 1))
6357 (set (match_dup 3) (const_int 0))]
6359 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
6360 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
6362 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
6363 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
6366 (define_insn_and_split "zero_extendqipsi2"
6367 [(set (match_operand:PSI 0 "register_operand" "=r")
6368 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6372 [(set (match_dup 2) (match_dup 1))
6373 (set (match_dup 3) (const_int 0))
6374 (set (match_dup 4) (const_int 0))]
6376 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
6377 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
6378 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6381 (define_insn_and_split "zero_extendqisi2"
6382 [(set (match_operand:SI 0 "register_operand" "=r")
6383 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
6387 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
6388 (set (match_dup 3) (const_int 0))]
6390 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
6391 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
6393 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
6394 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
6397 (define_insn_and_split "zero_extendhipsi2"
6398 [(set (match_operand:PSI 0 "register_operand" "=r")
6399 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
6403 [(set (match_dup 2) (match_dup 1))
6404 (set (match_dup 3) (const_int 0))]
6406 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
6407 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6410 (define_insn_and_split "n_extendhipsi2"
6411 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
6412 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
6413 (match_operand:HI 2 "register_operand" "r,r,r,r")))
6414 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
6418 [(set (match_dup 4) (match_dup 2))
6419 (set (match_dup 3) (match_dup 6))
6420 ; no-op move in the case where no scratch is needed
6421 (set (match_dup 5) (match_dup 3))]
6423 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
6424 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
6425 operands[6] = operands[1];
6427 if (GET_CODE (operands[3]) == SCRATCH)
6428 operands[3] = operands[5];
6431 (define_insn_and_split "zero_extendhisi2"
6432 [(set (match_operand:SI 0 "register_operand" "=r")
6433 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
6437 [(set (match_dup 2) (match_dup 1))
6438 (set (match_dup 3) (const_int 0))]
6440 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
6441 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
6443 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
6444 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
6447 (define_insn_and_split "zero_extendpsisi2"
6448 [(set (match_operand:SI 0 "register_operand" "=r")
6449 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
6453 [(set (match_dup 2) (match_dup 1))
6454 (set (match_dup 3) (const_int 0))]
6456 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
6457 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
6460 (define_insn_and_split "zero_extendqidi2"
6461 [(set (match_operand:DI 0 "register_operand" "=r")
6462 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
6466 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
6467 (set (match_dup 3) (const_int 0))]
6469 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6470 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6472 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6473 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6476 (define_insn_and_split "zero_extendhidi2"
6477 [(set (match_operand:DI 0 "register_operand" "=r")
6478 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
6482 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
6483 (set (match_dup 3) (const_int 0))]
6485 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6486 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6488 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6489 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6492 (define_insn_and_split "zero_extendsidi2"
6493 [(set (match_operand:DI 0 "register_operand" "=r")
6494 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
6498 [(set (match_dup 2) (match_dup 1))
6499 (set (match_dup 3) (const_int 0))]
6501 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
6502 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
6504 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
6505 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
6508 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
6511 ;; "*swapped_tstqi" "*swapped_tstqq"
6512 (define_insn "*swapped_tst<mode>"
6513 [(set (reg:CC REG_CC)
6514 (compare:CC (match_operand:ALLs1 0 "const0_operand" "Y00")
6515 (match_operand:ALLs1 1 "register_operand" "r")))]
6517 "cp __zero_reg__,%1"
6518 [(set_attr "length" "1")])
6521 ;; "*swapped_tsthi" "*swapped_tsthq" "*swapped_tstha"
6522 (define_insn "*swapped_tst<mode>"
6523 [(set (reg:CC REG_CC)
6524 (compare:CC (match_operand:ALLs2 0 "const0_operand" "Y00")
6525 (match_operand:ALLs2 1 "register_operand" "r")))]
6527 "cp __zero_reg__,%A1
6528 cpc __zero_reg__,%B1"
6529 [(set_attr "length" "2")])
6532 (define_insn "*swapped_tstpsi"
6533 [(set (reg:CC REG_CC)
6534 (compare:CC (const_int 0)
6535 (match_operand:PSI 0 "register_operand" "r")))]
6537 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
6538 [(set_attr "length" "3")])
6541 ;; "*swapped_tstsi" "*swapped_tstsq" "*swapped_tstsa"
6542 (define_insn "*swapped_tst<mode>"
6543 [(set (reg:CC REG_CC)
6544 (compare:CC (match_operand:ALLs4 0 "const0_operand" "Y00")
6545 (match_operand:ALLs4 1 "register_operand" "r")))]
6547 "cp __zero_reg__,%A1
6548 cpc __zero_reg__,%B1
6549 cpc __zero_reg__,%C1
6550 cpc __zero_reg__,%D1"
6551 [(set_attr "length" "4")])
6555 ;; "cmpqq3" "cmpuqq3"
6556 (define_insn "cmp<mode>3"
6557 [(set (reg:CC REG_CC)
6558 (compare:CC (match_operand:ALL1 0 "register_operand" "r ,r,d")
6559 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
6565 [(set_attr "length" "1,1,1")])
6568 ;; May be generated by "*cbranch<HISI:mode>.<code><QIPSI:mode>.0/1".
6569 (define_insn "*cmp<HISI:mode>.<code><QIPSI:mode>.0"
6570 [(set (reg:CC REG_CC)
6571 (compare:CC (any_extend:HISI (match_operand:QIPSI 0 "register_operand" "r"))
6572 (match_operand:HISI 1 "register_operand" "r")))]
6574 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
6576 return avr_out_cmp_ext (operands, <CODE>, nullptr);
6578 [(set_attr "adjust_len" "cmp_<extend_su>ext")])
6580 ;; Swapped version of the above.
6581 ;; May be generated by "*cbranch<HISI:mode>.<code><QIPSI:mode>.0/1".
6582 (define_insn "*cmp<HISI:mode>.<code><QIPSI:mode>.1"
6583 [(set (reg:CC REG_CC)
6584 (compare:CC (match_operand:HISI 0 "register_operand" "r")
6585 (any_extend:HISI (match_operand:QIPSI 1 "register_operand" "r"))))]
6587 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
6589 return avr_out_cmp_ext (operands, <CODE>, nullptr);
6591 [(set_attr "adjust_len" "cmp_<extend_su>ext")])
6595 ;; "cmphq3" "cmpuhq3"
6596 ;; "cmpha3" "cmpuha3"
6597 (define_insn "cmp<mode>3"
6598 [(set (reg:CC REG_CC)
6599 (compare:CC (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
6600 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
6601 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
6604 switch (which_alternative)
6608 return avr_out_tsthi (insn, operands, NULL);
6611 return "cp %A0,%A1\;cpc %B0,%B1";
6614 if (<MODE>mode != HImode)
6616 return reg_unused_after (insn, operands[0])
6617 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
6618 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
6621 if (<MODE>mode != HImode)
6623 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
6626 return avr_out_compare (insn, operands, NULL);
6628 [(set_attr "length" "2,2,2,3,4,2,4")
6629 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
6631 (define_insn "*cmppsi"
6632 [(set (reg:CC REG_CC)
6633 (compare:CC (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
6634 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
6635 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
6638 switch (which_alternative)
6641 return avr_out_tstpsi (insn, operands, NULL);
6644 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
6647 return reg_unused_after (insn, operands[0])
6648 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
6649 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
6652 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
6655 return avr_out_compare (insn, operands, NULL);
6657 [(set_attr "length" "3,3,5,6,3,7")
6658 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
6661 ;; "*cmpsq" "*cmpusq"
6662 ;; "*cmpsa" "*cmpusa"
6663 (define_insn "*cmp<mode>"
6664 [(set (reg:CC REG_CC)
6665 (compare:CC (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
6666 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
6667 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
6670 if (0 == which_alternative)
6671 return avr_out_tstsi (insn, operands, NULL);
6672 else if (1 == which_alternative)
6673 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
6675 return avr_out_compare (insn, operands, NULL);
6677 [(set_attr "length" "4,4,4,5,8")
6678 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
6681 ;; A helper for avr_pass_ifelse::avr_rest_of_handle_ifelse().
6682 (define_expand "gen_compare<mode>"
6683 [(parallel [(set (reg:CC REG_CC)
6684 (compare:CC (match_operand:HISI 0 "register_operand")
6685 (match_operand:HISI 1 "const_int_operand")))
6686 (clobber (match_operand:QI 2 "scratch_operand"))])])
6688 ;; ----------------------------------------------------------------------
6689 ;; JUMP INSTRUCTIONS
6690 ;; ----------------------------------------------------------------------
6691 ;; Conditional jump instructions
6693 (define_expand "cbranch<mode>4"
6695 (if_then_else (match_operator 0 "ordered_comparison_operator"
6696 [(match_operand:ALL1 1 "register_operand")
6697 (match_operand:ALL1 2 "nonmemory_operand")])
6698 (label_ref (match_operand 3))
6702 int icode = (int) GET_CODE (operands[0]);
6704 targetm.canonicalize_comparison (&icode, &operands[1], &operands[2], false);
6705 PUT_CODE (operands[0], (enum rtx_code) icode);
6708 (define_expand "cbranch<mode>4"
6711 (if_then_else (match_operator 0 "ordered_comparison_operator"
6712 [(match_operand:ALL234 1 "register_operand")
6713 (match_operand:ALL234 2 "nonmemory_operand")])
6714 (label_ref (match_operand 3))
6716 (clobber (match_scratch:QI 4))])]
6719 int icode = (int) GET_CODE (operands[0]);
6721 targetm.canonicalize_comparison (&icode, &operands[1], &operands[2], false);
6722 PUT_CODE (operands[0], (enum rtx_code) icode);
6726 ;; "cbranchqi4_insn"
6727 ;; "cbranchqq4_insn" "cbranchuqq4_insn"
6728 (define_insn_and_split "cbranch<mode>4_insn"
6730 (if_then_else (match_operator 0 "ordered_comparison_operator"
6731 [(match_operand:ALL1 1 "register_operand" "r ,r,d")
6732 (match_operand:ALL1 2 "nonmemory_operand" "Y00,r,i")])
6733 (label_ref (match_operand 3))
6738 [(set (reg:CC REG_CC)
6739 (compare:CC (match_dup 1) (match_dup 2)))
6741 (if_then_else (match_op_dup 0
6742 [(reg:CC REG_CC) (const_int 0)])
6743 (label_ref (match_dup 3))
6746 ;; "cbranchsi4_insn"
6747 ;; "cbranchsq4_insn" "cbranchusq4_insn" "cbranchsa4_insn" "cbranchusa4_insn"
6748 (define_insn_and_split "cbranch<mode>4_insn"
6751 (match_operator 0 "ordered_comparison_operator"
6752 [(match_operand:ALL4 1 "register_operand" "r ,r,d,r ,r")
6753 (match_operand:ALL4 2 "nonmemory_operand" "Y00,r,M,M ,n Ynn")])
6754 (label_ref (match_operand 3))
6756 (clobber (match_scratch:QI 4 "=X ,X,X,&d,&d"))]
6760 [(parallel [(set (reg:CC REG_CC)
6761 (compare:CC (match_dup 1) (match_dup 2)))
6762 (clobber (match_dup 4))])
6764 (if_then_else (match_op_dup 0
6765 [(reg:CC REG_CC) (const_int 0)])
6766 (label_ref (match_dup 3))
6769 ;; "cbranchpsi4_insn"
6770 (define_insn_and_split "cbranchpsi4_insn"
6773 (match_operator 0 "ordered_comparison_operator"
6774 [(match_operand:PSI 1 "register_operand" "r,r,d ,r ,d,r")
6775 (match_operand:PSI 2 "nonmemory_operand" "L,r,s ,s ,M,n")])
6776 (label_ref (match_operand 3))
6778 (clobber (match_scratch:QI 4 "=X,X,&d,&d,X,&d"))]
6782 [(parallel [(set (reg:CC REG_CC)
6783 (compare:CC (match_dup 1) (match_dup 2)))
6784 (clobber (match_dup 4))])
6786 (if_then_else (match_op_dup 0
6787 [(reg:CC REG_CC) (const_int 0)])
6788 (label_ref (match_dup 3))
6791 ;; "cbranchhi4_insn"
6792 ;; "cbranchhq4_insn" "cbranchuhq4_insn" "cbranchha4_insn" "cbranchuha4_insn"
6793 (define_insn_and_split "cbranch<mode>4_insn"
6796 (match_operator 0 "ordered_comparison_operator"
6797 [(match_operand:ALL2 1 "register_operand" "!w ,r ,r,d ,r ,d,r")
6798 (match_operand:ALL2 2 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")])
6799 (label_ref (match_operand 3))
6801 (clobber (match_scratch:QI 4 "=X ,X ,X,&d,&d,X,&d"))]
6805 [(parallel [(set (reg:CC REG_CC)
6806 (compare:CC (match_dup 1) (match_dup 2)))
6807 (clobber (match_dup 4))])
6809 (if_then_else (match_op_dup 0
6810 [(reg:CC REG_CC) (const_int 0)])
6811 (label_ref (match_dup 3))
6814 ;; Combiner pattern to compare sign- or zero-extended register against
6815 ;; a wider register, like comparing uint8_t against uint16_t.
6816 (define_insn_and_split "*cbranch<HISI:mode>.<code><QIPSI:mode>.0"
6818 (if_then_else (match_operator 0 "ordered_comparison_operator"
6819 [(any_extend:HISI (match_operand:QIPSI 1 "register_operand" "r"))
6820 (match_operand:HISI 2 "register_operand" "r")])
6821 (label_ref (match_operand 3))
6824 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
6826 "&& reload_completed"
6827 [; "*cmp<HISI:mode>.<code><QIPSI:mode>.0"
6828 (set (reg:CC REG_CC)
6829 (compare:CC (match_dup 1)
6833 (if_then_else (match_op_dup 0 [(reg:CC REG_CC)
6835 (label_ref (match_dup 3))
6838 operands[1] = gen_rtx_<CODE> (<HISI:MODE>mode, operands[1]);
6839 if (difficult_comparison_operator (operands[0], VOIDmode))
6841 PUT_CODE (operands[0], swap_condition (GET_CODE (operands[0])));
6842 std::swap (operands[1], operands[2]);
6846 ;; Same combiner pattern, but with swapped operands.
6847 (define_insn_and_split "*cbranch<HISI:mode>.<code><QIPSI:mode>.0"
6849 (if_then_else (match_operator 0 "ordered_comparison_operator"
6850 [(match_operand:HISI 1 "register_operand" "r")
6851 (any_extend:HISI (match_operand:QIPSI 2 "register_operand" "r"))])
6852 (label_ref (match_operand 3))
6855 && GET_MODE_SIZE (<HISI:MODE>mode) > GET_MODE_SIZE (<QIPSI:MODE>mode)"
6857 "&& reload_completed"
6858 [; "*cmp<HISI:mode>.<code><QIPSI:mode>.0"
6859 (set (reg:CC REG_CC)
6860 (compare:CC (match_dup 1)
6864 (if_then_else (match_op_dup 0 [(reg:CC REG_CC)
6866 (label_ref (match_dup 3))
6869 operands[2] = gen_rtx_<CODE> (<HISI:MODE>mode, operands[2]);
6870 if (difficult_comparison_operator (operands[0], VOIDmode))
6872 PUT_CODE (operands[0], swap_condition (GET_CODE (operands[0])));
6873 std::swap (operands[1], operands[2]);
6878 ;; Test a single bit in a QI/HI/SImode register.
6879 ;; Combine will create zero extract patterns for single bit tests.
6880 ;; permit any mode in source pattern by using VOIDmode.
6882 (define_insn_and_split "*sbrx_branch<mode>_split"
6885 (match_operator 0 "eqne_operator"
6887 (match_operand:VOID 1 "register_operand" "r")
6889 (match_operand 2 "const_int_operand" "n"))
6891 (label_ref (match_operand 3 "" ""))
6895 "&& reload_completed"
6896 [(parallel [(set (pc)
6904 (label_ref (match_dup 3))
6906 (clobber (reg:CC REG_CC))])])
6908 (define_insn "*sbrx_branch<mode>"
6911 (match_operator 0 "eqne_operator"
6913 (match_operand:VOID 1 "register_operand" "r")
6915 (match_operand 2 "const_int_operand" "n"))
6917 (label_ref (match_operand 3 "" ""))
6919 (clobber (reg:CC REG_CC))]
6922 return avr_out_sbxx_branch (insn, operands);
6924 [(set (attr "length")
6925 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
6926 (le (minus (pc) (match_dup 3)) (const_int 2046)))
6928 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
6932 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
6933 ;; or for old peepholes.
6934 ;; Fixme - bitwise Mask will not work for DImode
6936 (define_insn_and_split "*sbrx_and_branch<mode>_split"
6939 (match_operator 0 "eqne_operator"
6941 (match_operand:QISI 1 "register_operand" "r")
6942 (match_operand:QISI 2 "single_one_operand" "n"))
6944 (label_ref (match_operand 3 "" ""))
6948 "&& reload_completed"
6949 [(parallel [(set (pc)
6950 (if_then_else (match_op_dup 0 [(and:QISI (match_dup 1)
6953 (label_ref (match_dup 3))
6955 (clobber (reg:CC REG_CC))])])
6957 (define_insn "*sbrx_and_branch<mode>"
6960 (match_operator 0 "eqne_operator"
6962 (match_operand:QISI 1 "register_operand" "r")
6963 (match_operand:QISI 2 "single_one_operand" "n"))
6965 (label_ref (match_operand 3 "" ""))
6967 (clobber (reg:CC REG_CC))]
6970 HOST_WIDE_INT bitnumber;
6971 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
6972 operands[2] = GEN_INT (bitnumber);
6973 return avr_out_sbxx_branch (insn, operands);
6975 [(set (attr "length")
6976 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
6977 (le (minus (pc) (match_dup 3)) (const_int 2046)))
6979 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
6984 ;; Convert sign tests to bit 7 tests that match the above insns.
6985 (define_peephole2 ; "*sbrx_branch<mode>"
6986 [(set (reg:CC REG_CC)
6987 (compare:CC (match_operand:ALLs1 0 "register_operand")
6988 (match_operand:ALLs1 1 "const0_operand")))
6990 (if_then_else (gelt (reg:CC REG_CC)
6992 (label_ref (match_operand 2))
6994 "peep2_regno_dead_p (2, REG_CC)"
6995 [(parallel [(set (pc)
6996 (if_then_else (<gelt_eqne> (zero_extract:HI (match_dup 0)
7000 (label_ref (match_dup 2))
7002 (clobber (reg:CC REG_CC))])]
7004 operands[0] = avr_to_int_mode (operands[0]);
7005 operands[1] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7008 ;; Convert sign tests to bit 15/23/31 tests that match the above insns.
7009 (define_peephole2 ; "*sbrx_branch<mode>"
7010 [(parallel [(set (reg:CC REG_CC)
7011 (compare:CC (match_operand:ALLs234 0 "register_operand")
7012 (match_operand:ALLs234 1 "const0_operand")))
7013 (clobber (match_operand:QI 3 "scratch_operand"))])
7015 (if_then_else (gelt (reg:CC REG_CC)
7017 (label_ref (match_operand 2))
7019 "peep2_regno_dead_p (2, REG_CC)"
7020 [(parallel [(set (pc)
7021 (if_then_else (<gelt_eqne> (zero_extract:HI (match_dup 0)
7025 (label_ref (match_dup 2))
7027 (clobber (reg:CC REG_CC))])]
7029 operands[0] = avr_to_int_mode (operands[0]);
7030 operands[1] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7034 ;; ************************************************************************
7035 ;; Implementation of conditional jumps here.
7036 ;; Compare with 0 (test) jumps
7037 ;; ************************************************************************
7039 (define_insn "branch"
7041 (if_then_else (match_operator 1 "simple_comparison_operator"
7044 (label_ref (match_operand 0))
7048 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
7050 [(set_attr "type" "branch")])
7053 (define_insn "difficult_branch"
7055 (if_then_else (match_operator 1 "difficult_comparison_operator"
7058 (label_ref (match_operand 0 "" ""))
7062 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
7064 [(set_attr "type" "branch1")])
7067 ;; **************************************************************************
7068 ;; Unconditional and other jump instructions.
7072 (label_ref (match_operand 0 "" "")))]
7075 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
7079 [(set (attr "length")
7080 (if_then_else (match_operand 0 "symbol_ref_operand" "")
7081 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7084 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
7085 (le (minus (pc) (match_dup 0)) (const_int 2047)))
7091 ;; Operand 1 not used on the AVR.
7092 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7093 (define_expand "call"
7094 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
7095 (match_operand:HI 1 "general_operand" ""))
7096 (use (const_int 0))])])
7098 ;; Operand 1 not used on the AVR.
7099 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7100 (define_expand "sibcall"
7101 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
7102 (match_operand:HI 1 "general_operand" ""))
7103 (use (const_int 1))])])
7107 ;; Operand 2 not used on the AVR.
7108 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7109 (define_expand "call_value"
7110 [(parallel[(set (match_operand 0 "register_operand" "")
7111 (call (match_operand:HI 1 "call_insn_operand" "")
7112 (match_operand:HI 2 "general_operand" "")))
7113 (use (const_int 0))])])
7115 ;; Operand 2 not used on the AVR.
7116 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7117 (define_expand "sibcall_value"
7118 [(parallel[(set (match_operand 0 "register_operand" "")
7119 (call (match_operand:HI 1 "call_insn_operand" "")
7120 (match_operand:HI 2 "general_operand" "")))
7121 (use (const_int 1))])])
7123 (define_insn "call_insn"
7124 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
7125 (match_operand:HI 1 "general_operand" "X,X,X,X"))
7126 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
7127 ;; Operand 1 not used on the AVR.
7128 ;; Operand 2 is 1 for tail-call, 0 otherwise.
7135 [(set_attr "length" "1,*,1,*")
7136 (set_attr "adjust_len" "*,call,*,call")])
7138 (define_insn "call_value_insn"
7139 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
7140 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
7141 (match_operand:HI 2 "general_operand" "X,X,X,X")))
7142 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
7143 ;; Operand 2 not used on the AVR.
7144 ;; Operand 3 is 1 for tail-call, 0 otherwise.
7151 [(set_attr "length" "1,*,1,*")
7152 (set_attr "adjust_len" "*,call,*,call")])
7158 [(set_attr "length" "1")])
7162 (define_expand "indirect_jump"
7164 (match_operand:HI 0 "nonmemory_operand" ""))]
7167 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
7169 operands[0] = copy_to_mode_reg (HImode, operands[0]);
7174 (define_insn "*indirect_jump"
7176 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
7182 push %A0\;push %B0\;ret
7184 [(set_attr "length" "1,2,1,3,1")
7185 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")])
7188 ;; For entries in jump table see avr_output_addr_vec.
7191 ;; "rjmp .L<n>" instructions for <= 8K devices
7192 ;; ".word gs(.L<n>)" addresses for > 8K devices
7193 (define_insn_and_split "*tablejump_split"
7195 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
7197 (use (label_ref (match_operand 1 "" "")))
7198 (clobber (match_dup 0))
7199 (clobber (const_int 0))]
7200 "!AVR_HAVE_EIJMP_EICALL"
7202 "&& reload_completed"
7203 [(parallel [(set (pc)
7204 (unspec:HI [(match_dup 0)]
7206 (use (label_ref (match_dup 1)))
7207 (clobber (match_dup 0))
7208 (clobber (const_int 0))
7209 (clobber (reg:CC REG_CC))])]
7211 [(set_attr "isa" "rjmp,rjmp,jmp")])
7213 (define_insn "*tablejump"
7215 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
7217 (use (label_ref (match_operand 1 "" "")))
7218 (clobber (match_dup 0))
7219 (clobber (const_int 0))
7220 (clobber (reg:CC REG_CC))]
7221 "!AVR_HAVE_EIJMP_EICALL && reload_completed"
7224 push %A0\;push %B0\;ret
7226 [(set_attr "length" "1,3,2")
7227 (set_attr "isa" "rjmp,rjmp,jmp")])
7229 (define_insn_and_split "*tablejump.3byte-pc_split"
7231 (unspec:HI [(reg:HI REG_Z)]
7233 (use (label_ref (match_operand 0 "" "")))
7234 (clobber (reg:HI REG_Z))
7235 (clobber (reg:QI 24))]
7236 "AVR_HAVE_EIJMP_EICALL"
7238 "&& reload_completed"
7239 [(parallel [(set (pc)
7240 (unspec:HI [(reg:HI REG_Z)]
7242 (use (label_ref (match_dup 0)))
7243 (clobber (reg:HI REG_Z))
7244 (clobber (reg:QI 24))
7245 (clobber (reg:CC REG_CC))])]
7247 [(set_attr "isa" "eijmp")])
7250 (define_insn "*tablejump.3byte-pc"
7252 (unspec:HI [(reg:HI REG_Z)]
7254 (use (label_ref (match_operand 0 "" "")))
7255 (clobber (reg:HI REG_Z))
7256 (clobber (reg:QI 24))
7257 (clobber (reg:CC REG_CC))]
7258 "AVR_HAVE_EIJMP_EICALL && reload_completed"
7259 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
7260 [(set_attr "length" "6")
7261 (set_attr "isa" "eijmp")])
7264 ;; FIXME: casesi comes up with an SImode switch value $0 which
7265 ;; is quite some overhead because most code would use HI or
7266 ;; even QI. We add an AVR specific pass .avr-casesi which
7267 ;; tries to recover from the superfluous extension to SImode.
7269 ;; Using "tablejump" could be a way out, but this also does
7270 ;; not perform in a satisfying manner as the middle end will
7271 ;; already multiply the table index by 2. Note that this
7272 ;; multiplication is performed by libgcc's __tablejump2__.
7273 ;; The multiplication there, however, runs *after* the table
7274 ;; start (a byte address) has been added, not before it like
7275 ;; "tablejump" will do.
7277 ;; The preferred solution would be to let the middle ends pass
7278 ;; down information on the index as an additional casesi operand.
7280 ;; If this expander is changed, you'll likely have to go through
7281 ;; "casesi_<mode>_sequence" (used to recog + extract casesi
7282 ;; sequences in pass .avr-casesi) and propagate all adjustments
7283 ;; also to that pattern and the code of the extra pass.
7285 (define_expand "casesi"
7286 [(parallel [(set (match_dup 5)
7287 (plus:SI (match_operand:SI 0 "register_operand")
7288 (match_operand:SI 1 "const_int_operand")))
7289 (clobber (scratch:QI))])
7291 (parallel [(set (pc)
7292 (if_then_else (gtu (match_dup 5)
7293 (match_operand:SI 2 "const_int_operand"))
7294 (label_ref (match_operand 4))
7296 (clobber (scratch:QI))])
7301 (parallel [(set (pc)
7302 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
7303 (use (label_ref (match_dup 3)))
7304 (clobber (match_dup 7))
7305 (clobber (match_dup 8))])]
7308 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
7309 operands[5] = gen_reg_rtx (SImode);
7310 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
7312 if (AVR_HAVE_EIJMP_EICALL)
7314 operands[7] = gen_rtx_REG (HImode, REG_Z);
7315 operands[8] = all_regs_rtx[24];
7319 operands[6] = gen_rtx_PLUS (HImode, operands[6],
7320 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
7321 operands[7] = gen_reg_rtx (HImode);
7322 operands[8] = const0_rtx;
7327 ;; This insn is used only for easy operand extraction.
7328 ;; The elements must match an extension to SImode plus
7329 ;; a sequence generated by casesi above.
7331 ;; "casesi_qi_sequence"
7332 ;; "casesi_hi_sequence"
7333 (define_insn "casesi_<mode>_sequence"
7334 [(set (match_operand:SI 0 "register_operand")
7335 (match_operator:SI 9 "extend_operator"
7336 [(match_operand:QIHI 10 "register_operand")]))
7338 ;; What follows is a matcher for code from casesi.
7339 ;; We keep the same operand numbering (except for $9 and $10
7340 ;; which don't appear in casesi).
7341 (parallel [(set (match_operand:SI 5 "register_operand")
7342 (plus:SI (match_dup 0)
7343 (match_operand:SI 1 "const_int_operand")))
7344 (clobber (scratch:QI))])
7346 (parallel [(set (pc)
7347 (if_then_else (gtu (match_dup 5)
7348 (match_operand:SI 2 "const_int_operand"))
7349 (label_ref (match_operand 4))
7351 (clobber (scratch:QI))])
7353 (set (match_operand:HI 7 "register_operand")
7354 (match_operand:HI 6))
7356 (parallel [(set (pc)
7357 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
7358 (use (label_ref (match_operand 3)))
7359 (clobber (match_dup 7))
7360 (clobber (match_operand:QI 8))])]
7362 && avr_casei_sequence_check_operands (operands)"
7363 { gcc_unreachable(); }
7367 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7368 ;; Clear/set/test a single bit in I/O address space.
7371 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
7372 (and:QI (mem:QI (match_dup 0))
7373 (match_operand:QI 1 "single_zero_operand" "n")))]
7376 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
7377 return "cbi %i0,%2";
7379 [(set_attr "length" "1")])
7382 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
7383 (ior:QI (mem:QI (match_dup 0))
7384 (match_operand:QI 1 "single_one_operand" "n")))]
7387 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
7388 return "sbi %i0,%2";
7390 [(set_attr "length" "1")])
7392 ;; Lower half of the I/O space - use sbic/sbis directly.
7393 (define_insn_and_split "*sbix_branch_split"
7396 (match_operator 0 "eqne_operator"
7398 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
7400 (match_operand 2 "const_int_operand" "n"))
7402 (label_ref (match_operand 3 "" ""))
7406 "&& reload_completed"
7407 [(parallel [(set (pc)
7409 (match_operator 0 "eqne_operator"
7411 (mem:QI (match_dup 1))
7415 (label_ref (match_dup 3))
7417 (clobber (reg:CC REG_CC))])])
7419 (define_insn "*sbix_branch"
7422 (match_operator 0 "eqne_operator"
7424 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
7426 (match_operand 2 "const_int_operand" "n"))
7428 (label_ref (match_operand 3 "" ""))
7430 (clobber (reg:CC REG_CC))]
7433 return avr_out_sbxx_branch (insn, operands);
7435 [(set (attr "length")
7436 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7437 (le (minus (pc) (match_dup 3)) (const_int 2046)))
7439 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7443 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
7444 (define_insn_and_split "*sbix_branch_bit7_split"
7447 (match_operator 0 "gelt_operator"
7448 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
7450 (label_ref (match_operand 2 "" ""))
7454 "&& reload_completed"
7455 [(parallel [(set (pc)
7457 (match_operator 0 "gelt_operator"
7458 [(mem:QI (match_dup 1))
7460 (label_ref (match_dup 2))
7462 (clobber (reg:CC REG_CC))])])
7464 (define_insn "*sbix_branch_bit7"
7467 (match_operator 0 "gelt_operator"
7468 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
7470 (label_ref (match_operand 2 "" ""))
7472 (clobber (reg:CC REG_CC))]
7475 operands[3] = operands[2];
7476 operands[2] = GEN_INT (7);
7477 return avr_out_sbxx_branch (insn, operands);
7479 [(set (attr "length")
7480 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
7481 (le (minus (pc) (match_dup 2)) (const_int 2046)))
7483 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7487 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
7488 (define_insn_and_split "*sbix_branch_tmp_split"
7491 (match_operator 0 "eqne_operator"
7493 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
7495 (match_operand 2 "const_int_operand" "n"))
7497 (label_ref (match_operand 3 "" ""))
7501 "&& reload_completed"
7502 [(parallel [(set (pc)
7504 (match_operator 0 "eqne_operator"
7506 (mem:QI (match_dup 1))
7510 (label_ref (match_dup 3))
7512 (clobber (reg:CC REG_CC))])])
7514 (define_insn "*sbix_branch_tmp"
7517 (match_operator 0 "eqne_operator"
7519 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
7521 (match_operand 2 "const_int_operand" "n"))
7523 (label_ref (match_operand 3 "" ""))
7525 (clobber (reg:CC REG_CC))]
7528 return avr_out_sbxx_branch (insn, operands);
7530 [(set (attr "length")
7531 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
7532 (le (minus (pc) (match_dup 3)) (const_int 2045)))
7534 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7538 (define_insn_and_split "*sbix_branch_tmp_bit7_split"
7541 (match_operator 0 "gelt_operator"
7542 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
7544 (label_ref (match_operand 2 "" ""))
7548 "&& reload_completed"
7549 [(parallel [(set (pc)
7551 (match_operator 0 "gelt_operator"
7552 [(mem:QI (match_dup 1))
7554 (label_ref (match_dup 2))
7556 (clobber (reg:CC REG_CC))])])
7558 (define_insn "*sbix_branch_tmp_bit7"
7561 (match_operator 0 "gelt_operator"
7562 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
7564 (label_ref (match_operand 2 "" ""))
7566 (clobber (reg:CC REG_CC))]
7569 operands[3] = operands[2];
7570 operands[2] = GEN_INT (7);
7571 return avr_out_sbxx_branch (insn, operands);
7573 [(set (attr "length")
7574 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
7575 (le (minus (pc) (match_dup 2)) (const_int 2045)))
7577 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
7581 ;; ************************* Peepholes ********************************
7583 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
7584 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
7585 (plus:SI (match_dup 0)
7587 (clobber (scratch:QI))
7588 (clobber (reg:CC REG_CC))])
7589 (parallel [(set (reg:CC REG_CC)
7590 (compare:CC (match_dup 0)
7592 (clobber (match_operand:QI 1 "scratch_or_d_register_operand"))])
7594 (if_then_else (eqne (reg:CC REG_CC)
7596 (label_ref (match_operand 2))
7598 "dead_or_set_regno_p (insn, REG_CC)"
7602 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7603 output_asm_insn ("sbiw %0,1" CR_TAB
7604 "sbc %C0,__zero_reg__" CR_TAB
7605 "sbc %D0,__zero_reg__", operands);
7607 output_asm_insn ("subi %A0,1" CR_TAB
7608 "sbc %B0,__zero_reg__" CR_TAB
7609 "sbc %C0,__zero_reg__" CR_TAB
7610 "sbc %D0,__zero_reg__", operands);
7612 jump_mode = avr_jump_mode (operands[2], insn);
7613 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7614 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7618 case 1: return "%1 %2";
7619 case 2: return "%1 .+2\;rjmp %2";
7620 case 3: return "%1 .+4\;jmp %2";
7627 (define_peephole ; "*dec-and-branchhi!=-1"
7628 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
7629 (plus:HI (match_dup 0)
7631 (clobber (reg:CC REG_CC))])
7632 (parallel [(set (reg:CC REG_CC)
7633 (compare:CC (match_dup 0)
7635 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7637 (if_then_else (eqne (reg:CC REG_CC)
7639 (label_ref (match_operand 2))
7641 "dead_or_set_regno_p (insn, REG_CC)"
7645 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7646 output_asm_insn ("sbiw %0,1", operands);
7648 output_asm_insn ("subi %A0,1" CR_TAB
7649 "sbc %B0,__zero_reg__", operands);
7651 jump_mode = avr_jump_mode (operands[2], insn);
7652 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7653 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7657 case 1: return "%1 %2";
7658 case 2: return "%1 .+2\;rjmp %2";
7659 case 3: return "%1 .+4\;jmp %2";
7666 ;; Same as above but with clobber flavour of addhi3
7667 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
7668 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
7669 (plus:HI (match_dup 0)
7671 (clobber (scratch:QI))
7672 (clobber (reg:CC REG_CC))])
7673 (parallel [(set (reg:CC REG_CC)
7674 (compare:CC (match_dup 0)
7676 (clobber (match_operand:QI 1 "scratch_or_d_register_operand"))])
7678 (if_then_else (eqne (reg:CC REG_CC)
7680 (label_ref (match_operand 2))
7682 "dead_or_set_regno_p (insn, REG_CC)"
7686 if (test_hard_reg_class (ADDW_REGS, operands[0]))
7687 output_asm_insn ("sbiw %0,1", operands);
7689 output_asm_insn ("subi %A0,1" CR_TAB
7690 "sbc %B0,__zero_reg__", operands);
7692 jump_mode = avr_jump_mode (operands[2], insn);
7693 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7694 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7698 case 1: return "%1 %2";
7699 case 2: return "%1 .+2\;rjmp %2";
7700 case 3: return "%1 .+4\;jmp %2";
7707 ;; Same as above but with clobber flavour of addhi3
7708 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
7709 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
7710 (plus:HI (match_dup 0)
7712 (clobber (match_operand:QI 3 "d_register_operand" ""))
7713 (clobber (reg:CC REG_CC))])
7714 (parallel [(set (reg:CC REG_CC)
7715 (compare:CC (match_dup 0)
7717 (clobber (match_operand:QI 1 "d_register_operand" ""))])
7719 (if_then_else (eqne (reg:CC REG_CC)
7721 (label_ref (match_operand 2))
7723 "dead_or_set_regno_p (insn, REG_CC)"
7727 output_asm_insn ("ldi %3,1" CR_TAB
7729 "sbc %B0,__zero_reg__", operands);
7731 jump_mode = avr_jump_mode (operands[2], insn);
7732 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7733 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
7737 case 1: return "%1 %2";
7738 case 2: return "%1 .+2\;rjmp %2";
7739 case 3: return "%1 .+4\;jmp %2";
7746 (define_peephole ; "*dec-and-branchqi!=-1"
7747 [(parallel [(set (match_operand:QI 0 "d_register_operand" "")
7748 (plus:QI (match_dup 0)
7750 (clobber (reg:CC REG_CC))])
7751 (set (reg:CC REG_CC)
7752 (compare:CC (match_dup 0)
7755 (if_then_else (eqne (reg:CC REG_CC)
7757 (label_ref (match_operand 1))
7759 "dead_or_set_regno_p (insn, REG_CC)"
7764 output_asm_insn ("subi %A0,1", operands);
7766 jump_mode = avr_jump_mode (operands[1], insn);
7767 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
7768 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
7772 case 1: return "%0 %1";
7773 case 2: return "%0 .+2\;rjmp %1";
7774 case 3: return "%0 .+4\;jmp %1";
7782 (define_peephole ; "*cpse.eq"
7783 [(set (reg:CC REG_CC)
7784 (compare:CC (match_operand:ALL1 1 "register_operand" "r,r")
7785 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
7787 (if_then_else (eq (reg:CC REG_CC)
7789 (label_ref (match_operand 0))
7791 "jump_over_one_insn_p (insn, operands[0])
7792 && dead_or_set_regno_p (insn, REG_CC)"
7795 cpse %1,__zero_reg__")
7797 ;; This peephole avoids code like
7800 ;; BREQ .+2 ; branch
7803 ;; Notice that the peephole is always shorter than cmpqi + branch.
7804 ;; The reason to write it as peephole is that sequences like
7809 ;; shall not be superseeded. With a respective combine pattern
7810 ;; the latter sequence would be
7813 ;; CPSE Rm, __zero_reg__
7816 ;; and thus longer and slower and not easy to be rolled back.
7818 (define_peephole ; "*cpse.ne"
7819 [(set (reg:CC REG_CC)
7820 (compare:CC (match_operand:ALL1 1 "register_operand")
7821 (match_operand:ALL1 2 "reg_or_0_operand")))
7823 (if_then_else (ne (reg:CC REG_CC)
7825 (label_ref (match_operand 0))
7827 "(!AVR_HAVE_JMP_CALL
7828 || !TARGET_SKIP_BUG)
7829 && dead_or_set_regno_p (insn, REG_CC)"
7831 if (operands[2] == CONST0_RTX (<MODE>mode))
7832 operands[2] = zero_reg_rtx;
7834 return 3 == avr_jump_mode (operands[0], insn)
7835 ? "cpse %1,%2\;jmp %0"
7836 : "cpse %1,%2\;rjmp %0";
7839 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
7840 ;;prologue/epilogue support instructions
7842 (define_insn "popqi"
7843 [(set (match_operand:QI 0 "register_operand" "=r")
7844 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
7847 [(set_attr "length" "1")])
7849 ;; Enable Interrupts
7850 (define_expand "enable_interrupt"
7851 [(clobber (const_int 0))]
7854 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7855 MEM_VOLATILE_P (mem) = 1;
7856 emit_insn (gen_cli_sei (const1_rtx, mem));
7860 ;; Disable Interrupts
7861 (define_expand "disable_interrupt"
7862 [(clobber (const_int 0))]
7865 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7866 MEM_VOLATILE_P (mem) = 1;
7867 emit_insn (gen_cli_sei (const0_rtx, mem));
7871 (define_insn "cli_sei"
7872 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
7873 UNSPECV_ENABLE_IRQS)
7874 (set (match_operand:BLK 1 "" "")
7875 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
7880 [(set_attr "length" "1")])
7882 ;; Library prologue saves
7883 (define_insn "call_prologue_saves"
7884 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
7885 (match_operand:HI 0 "immediate_operand" "i,i")
7886 (set (reg:HI REG_SP)
7887 (minus:HI (reg:HI REG_SP)
7888 (match_operand:HI 1 "immediate_operand" "i,i")))
7889 (use (reg:HI REG_X))
7890 (clobber (reg:HI REG_Z))
7891 (clobber (reg:CC REG_CC))]
7893 "ldi r30,lo8(gs(1f))
7895 %~jmp __prologue_saves__+((18 - %0) * 2)
7897 [(set_attr "length" "5,6")
7898 (set_attr "isa" "rjmp,jmp")])
7900 ; epilogue restores using library
7901 (define_insn "epilogue_restores"
7902 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
7904 (plus:HI (reg:HI REG_Y)
7905 (match_operand:HI 0 "immediate_operand" "i,i")))
7906 (set (reg:HI REG_SP)
7907 (plus:HI (reg:HI REG_Y)
7909 (clobber (reg:QI REG_Z))
7910 (clobber (reg:CC REG_CC))]
7913 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
7914 [(set_attr "length" "2,3")
7915 (set_attr "isa" "rjmp,jmp")])
7918 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue
7919 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
7920 (define_expand "gasisr"
7921 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
7922 (match_operand:QI 1 "const_int_operand")]
7924 (set (reg:HI REG_SP)
7925 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
7927 (unspec_volatile:BLK [(match_dup 2)]
7928 UNSPECV_MEMORY_BARRIER))
7929 (clobber (reg:CC REG_CC))])]
7930 "avr_gasisr_prologues"
7932 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7933 MEM_VOLATILE_P (operands[2]) = 1;
7936 (define_insn "*gasisr"
7937 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
7938 (match_operand:QI 1 "const_int_operand" "n,n")]
7940 (set (reg:HI REG_SP)
7941 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
7942 (set (match_operand:BLK 2)
7943 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))
7944 (clobber (reg:CC REG_CC))]
7945 "avr_gasisr_prologues"
7947 [(set_attr "length" "6,5")])
7951 (define_insn "return"
7953 "reload_completed && avr_simple_epilogue ()"
7955 [(set_attr "length" "1")])
7957 (define_insn "return_from_epilogue"
7961 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
7962 && !cfun->machine->is_naked"
7964 [(set_attr "length" "1")])
7966 (define_insn "return_from_interrupt_epilogue"
7970 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
7971 && !cfun->machine->is_naked"
7973 [(set_attr "length" "1")])
7975 (define_insn "return_from_naked_epilogue"
7979 && cfun->machine->is_naked"
7981 [(set_attr "length" "0")])
7983 (define_expand "prologue"
7987 avr_expand_prologue ();
7991 (define_expand "epilogue"
7995 avr_expand_epilogue (false /* sibcall_p */);
7999 (define_expand "sibcall_epilogue"
8003 avr_expand_epilogue (true /* sibcall_p */);
8007 ;; Some instructions resp. instruction sequences available
8010 (define_insn_and_split "delay_cycles_1"
8011 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
8013 UNSPECV_DELAY_CYCLES)
8014 (set (match_operand:BLK 1 "" "")
8015 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8016 (clobber (match_scratch:QI 2 "=&d"))]
8019 "&& reload_completed"
8020 [(parallel [(unspec_volatile [(match_dup 0)
8022 UNSPECV_DELAY_CYCLES)
8024 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8025 (clobber (match_dup 2))
8026 (clobber (reg:CC REG_CC))])])
8028 (define_insn "*delay_cycles_1"
8029 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
8031 UNSPECV_DELAY_CYCLES)
8032 (set (match_operand:BLK 1 "" "")
8033 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8034 (clobber (match_scratch:QI 2 "=&d"))
8035 (clobber (reg:CC REG_CC))]
8040 [(set_attr "length" "3")])
8042 (define_insn_and_split "delay_cycles_2"
8043 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
8045 UNSPECV_DELAY_CYCLES)
8046 (set (match_operand:BLK 1 "" "")
8047 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8048 (clobber (match_scratch:HI 2 "=&w,&d"))]
8051 "&& reload_completed"
8052 [(parallel [(unspec_volatile [(match_dup 0)
8054 UNSPECV_DELAY_CYCLES)
8056 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8057 (clobber (match_dup 2))
8058 (clobber (reg:CC REG_CC))])]
8060 [(set_attr "isa" "no_tiny,tiny")])
8062 (define_insn "*delay_cycles_2"
8063 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
8065 UNSPECV_DELAY_CYCLES)
8066 (set (match_operand:BLK 1 "" "")
8067 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8068 (clobber (match_scratch:HI 2 "=&w,&d"))
8069 (clobber (reg:CC REG_CC))]
8072 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b
8073 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b"
8074 [(set_attr "length" "4,5")
8075 (set_attr "isa" "no_tiny,tiny")])
8077 (define_insn_and_split "delay_cycles_3"
8078 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8080 UNSPECV_DELAY_CYCLES)
8081 (set (match_operand:BLK 1 "" "")
8082 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8083 (clobber (match_scratch:QI 2 "=&d"))
8084 (clobber (match_scratch:QI 3 "=&d"))
8085 (clobber (match_scratch:QI 4 "=&d"))]
8088 "&& reload_completed"
8089 [(parallel [(unspec_volatile [(match_dup 0)
8091 UNSPECV_DELAY_CYCLES)
8093 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8094 (clobber (match_dup 2))
8095 (clobber (match_dup 3))
8096 (clobber (match_dup 4))
8097 (clobber (reg:CC REG_CC))])])
8099 (define_insn "*delay_cycles_3"
8100 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8102 UNSPECV_DELAY_CYCLES)
8103 (set (match_operand:BLK 1 "" "")
8104 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8105 (clobber (match_scratch:QI 2 "=&d"))
8106 (clobber (match_scratch:QI 3 "=&d"))
8107 (clobber (match_scratch:QI 4 "=&d"))
8108 (clobber (reg:CC REG_CC))]
8117 [(set_attr "length" "7")])
8119 (define_insn_and_split "delay_cycles_4"
8120 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8122 UNSPECV_DELAY_CYCLES)
8123 (set (match_operand:BLK 1 "" "")
8124 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8125 (clobber (match_scratch:QI 2 "=&d"))
8126 (clobber (match_scratch:QI 3 "=&d"))
8127 (clobber (match_scratch:QI 4 "=&d"))
8128 (clobber (match_scratch:QI 5 "=&d"))]
8131 "&& reload_completed"
8132 [(parallel [(unspec_volatile [(match_dup 0)
8134 UNSPECV_DELAY_CYCLES)
8136 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8137 (clobber (match_dup 2))
8138 (clobber (match_dup 3))
8139 (clobber (match_dup 4))
8140 (clobber (match_dup 5))
8141 (clobber (reg:CC REG_CC))])])
8143 (define_insn "*delay_cycles_4"
8144 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
8146 UNSPECV_DELAY_CYCLES)
8147 (set (match_operand:BLK 1 "" "")
8148 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
8149 (clobber (match_scratch:QI 2 "=&d"))
8150 (clobber (match_scratch:QI 3 "=&d"))
8151 (clobber (match_scratch:QI 4 "=&d"))
8152 (clobber (match_scratch:QI 5 "=&d"))
8153 (clobber (reg:CC REG_CC))]
8164 [(set_attr "length" "9")])
8167 ;; __builtin_avr_insert_bits
8169 (define_insn_and_split "insert_bits"
8170 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
8171 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
8172 (match_operand:QI 2 "register_operand" "r ,r ,r")
8173 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
8174 UNSPEC_INSERT_BITS))]
8177 "&& reload_completed"
8178 [(parallel [(set (match_dup 0)
8179 (unspec:QI [(match_dup 1)
8182 UNSPEC_INSERT_BITS))
8183 (clobber (reg:CC REG_CC))])])
8185 (define_insn "*insert_bits"
8186 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
8187 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
8188 (match_operand:QI 2 "register_operand" "r ,r ,r")
8189 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
8190 UNSPEC_INSERT_BITS))
8191 (clobber (reg:CC REG_CC))]
8194 return avr_out_insert_bits (operands, NULL);
8196 [(set_attr "adjust_len" "insert_bits")])
8199 ;; __builtin_avr_flash_segment
8201 ;; Just a helper for the next "official" expander.
8203 (define_expand "flash_segment1"
8204 [(set (match_operand:QI 0 "register_operand" "")
8205 (subreg:QI (match_operand:PSI 1 "register_operand" "")
8208 (if_then_else (ge (match_dup 0)
8210 (label_ref (match_operand 2 "" ""))
8215 (define_insn_and_split "*flash_segment1"
8217 (if_then_else (ge (match_operand:QI 0 "register_operand" "")
8219 (label_ref (match_operand 1 "" ""))
8224 [(set (reg:CC REG_CC)
8225 (compare:CC (match_dup 0) (const_int 0)))
8227 (if_then_else (ge (reg:CC REG_CC) (const_int 0))
8228 (label_ref (match_dup 1))
8232 (define_expand "flash_segment"
8233 [(parallel [(match_operand:QI 0 "register_operand" "")
8234 (match_operand:PSI 1 "register_operand" "")])]
8237 rtx label = gen_label_rtx ();
8238 emit (gen_flash_segment1 (operands[0], operands[1], label));
8243 ;; Actually, it's too late now to work out address spaces known at compiletime.
8244 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
8245 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
8246 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
8248 (define_insn_and_split "*split.flash_segment"
8249 [(set (match_operand:QI 0 "register_operand" "=d")
8250 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
8251 (match_operand:HI 2 "register_operand" "r"))
8254 { gcc_unreachable(); }
8262 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
8263 ;; better 8-bit parity recognition.
8265 (define_expand "parityhi2"
8266 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8267 (parity:HI (match_operand:HI 1 "register_operand" "")))
8268 (clobber (reg:HI 24))])])
8270 (define_insn_and_split "*parityhi2"
8271 [(set (match_operand:HI 0 "register_operand" "=r")
8272 (parity:HI (match_operand:HI 1 "register_operand" "r")))
8273 (clobber (reg:HI 24))]
8275 { gcc_unreachable(); }
8280 (parity:HI (reg:HI 24)))
8284 (define_insn_and_split "*parityqihi2"
8285 [(set (match_operand:HI 0 "register_operand" "=r")
8286 (parity:HI (match_operand:QI 1 "register_operand" "r")))
8287 (clobber (reg:HI 24))]
8289 { gcc_unreachable(); }
8294 (zero_extend:HI (parity:QI (reg:QI 24))))
8298 (define_expand "paritysi2"
8300 (match_operand:SI 1 "register_operand" ""))
8302 (truncate:HI (parity:SI (reg:SI 22))))
8305 (set (match_operand:SI 0 "register_operand" "")
8306 (zero_extend:SI (match_dup 2)))]
8309 operands[2] = gen_reg_rtx (HImode);
8312 (define_insn_and_split "*parityhi2.libgcc_split"
8314 (parity:HI (reg:HI 24)))]
8317 "&& reload_completed"
8318 [(parallel [(set (reg:HI 24)
8319 (parity:HI (reg:HI 24)))
8320 (clobber (reg:CC REG_CC))])])
8322 (define_insn "*parityhi2.libgcc"
8324 (parity:HI (reg:HI 24)))
8325 (clobber (reg:CC REG_CC))]
8327 "%~call __parityhi2"
8328 [(set_attr "type" "xcall")])
8330 (define_insn_and_split "*parityqihi2.libgcc_split"
8332 (zero_extend:HI (parity:QI (reg:QI 24))))]
8335 "&& reload_completed"
8336 [(parallel [(set (reg:HI 24)
8337 (zero_extend:HI (parity:QI (reg:QI 24))))
8338 (clobber (reg:CC REG_CC))])])
8340 (define_insn "*parityqihi2.libgcc"
8342 (zero_extend:HI (parity:QI (reg:QI 24))))
8343 (clobber (reg:CC REG_CC))]
8345 "%~call __parityqi2"
8346 [(set_attr "type" "xcall")])
8348 (define_insn_and_split "*paritysihi2.libgcc_split"
8350 (truncate:HI (parity:SI (reg:SI 22))))]
8353 "&& reload_completed"
8354 [(parallel [(set (reg:HI 24)
8355 (truncate:HI (parity:SI (reg:SI 22))))
8356 (clobber (reg:CC REG_CC))])])
8358 (define_insn "*paritysihi2.libgcc"
8360 (truncate:HI (parity:SI (reg:SI 22))))
8361 (clobber (reg:CC REG_CC))]
8363 "%~call __paritysi2"
8364 [(set_attr "type" "xcall")])
8369 (define_expand "popcounthi2"
8371 (match_operand:HI 1 "register_operand" ""))
8373 (popcount:HI (reg:HI 24)))
8374 (set (match_operand:HI 0 "register_operand" "")
8379 (define_expand "popcountsi2"
8381 (match_operand:SI 1 "register_operand" ""))
8383 (truncate:HI (popcount:SI (reg:SI 22))))
8386 (set (match_operand:SI 0 "register_operand" "")
8387 (zero_extend:SI (match_dup 2)))]
8390 operands[2] = gen_reg_rtx (HImode);
8393 (define_insn_and_split "*popcounthi2.libgcc_split"
8395 (popcount:HI (reg:HI 24)))]
8398 "&& reload_completed"
8399 [(parallel [(set (reg:HI 24)
8400 (popcount:HI (reg:HI 24)))
8401 (clobber (reg:CC REG_CC))])])
8403 (define_insn "*popcounthi2.libgcc"
8405 (popcount:HI (reg:HI 24)))
8406 (clobber (reg:CC REG_CC))]
8408 "%~call __popcounthi2"
8409 [(set_attr "type" "xcall")])
8411 (define_insn_and_split "*popcountsi2.libgcc_split"
8413 (truncate:HI (popcount:SI (reg:SI 22))))]
8416 "&& reload_completed"
8417 [(parallel [(set (reg:HI 24)
8418 (truncate:HI (popcount:SI (reg:SI 22))))
8419 (clobber (reg:CC REG_CC))])])
8421 (define_insn "*popcountsi2.libgcc"
8423 (truncate:HI (popcount:SI (reg:SI 22))))
8424 (clobber (reg:CC REG_CC))]
8426 "%~call __popcountsi2"
8427 [(set_attr "type" "xcall")])
8429 (define_insn_and_split "*popcountqi2.libgcc_split"
8431 (popcount:QI (reg:QI 24)))]
8434 "&& reload_completed"
8435 [(parallel [(set (reg:QI 24)
8436 (popcount:QI (reg:QI 24)))
8437 (clobber (reg:CC REG_CC))])])
8439 (define_insn "*popcountqi2.libgcc"
8441 (popcount:QI (reg:QI 24)))
8442 (clobber (reg:CC REG_CC))]
8444 "%~call __popcountqi2"
8445 [(set_attr "type" "xcall")])
8447 (define_insn_and_split "*popcountqihi2.libgcc"
8449 (zero_extend:HI (popcount:QI (reg:QI 24))))]
8454 (popcount:QI (reg:QI 24)))
8458 ;; Count Leading Zeros
8460 (define_expand "clzhi2"
8462 (match_operand:HI 1 "register_operand" ""))
8463 (parallel [(set (reg:HI 24)
8464 (clz:HI (reg:HI 24)))
8465 (clobber (reg:QI 26))])
8466 (set (match_operand:HI 0 "register_operand" "")
8469 (define_expand "clzsi2"
8471 (match_operand:SI 1 "register_operand" ""))
8472 (parallel [(set (reg:HI 24)
8473 (truncate:HI (clz:SI (reg:SI 22))))
8474 (clobber (reg:QI 26))])
8477 (set (match_operand:SI 0 "register_operand" "")
8478 (zero_extend:SI (match_dup 2)))]
8481 operands[2] = gen_reg_rtx (HImode);
8484 (define_insn_and_split "*clzhi2.libgcc_split"
8486 (clz:HI (reg:HI 24)))
8487 (clobber (reg:QI 26))]
8490 "&& reload_completed"
8491 [(parallel [(set (reg:HI 24)
8492 (clz:HI (reg:HI 24)))
8493 (clobber (reg:QI 26))
8494 (clobber (reg:CC REG_CC))])])
8496 (define_insn "*clzhi2.libgcc"
8498 (clz:HI (reg:HI 24)))
8499 (clobber (reg:QI 26))
8500 (clobber (reg:CC REG_CC))]
8503 [(set_attr "type" "xcall")])
8505 (define_insn_and_split "*clzsihi2.libgcc_split"
8507 (truncate:HI (clz:SI (reg:SI 22))))
8508 (clobber (reg:QI 26))]
8511 "&& reload_completed"
8512 [(parallel [(set (reg:HI 24)
8513 (truncate:HI (clz:SI (reg:SI 22))))
8514 (clobber (reg:QI 26))
8515 (clobber (reg:CC REG_CC))])])
8517 (define_insn "*clzsihi2.libgcc"
8519 (truncate:HI (clz:SI (reg:SI 22))))
8520 (clobber (reg:QI 26))
8521 (clobber (reg:CC REG_CC))]
8524 [(set_attr "type" "xcall")])
8526 ;; Count Trailing Zeros
8528 (define_expand "ctzhi2"
8530 (match_operand:HI 1 "register_operand" ""))
8531 (parallel [(set (reg:HI 24)
8532 (ctz:HI (reg:HI 24)))
8533 (clobber (reg:QI 26))])
8534 (set (match_operand:HI 0 "register_operand" "")
8537 (define_expand "ctzsi2"
8539 (match_operand:SI 1 "register_operand" ""))
8540 (parallel [(set (reg:HI 24)
8541 (truncate:HI (ctz:SI (reg:SI 22))))
8542 (clobber (reg:QI 22))
8543 (clobber (reg:QI 26))])
8546 (set (match_operand:SI 0 "register_operand" "")
8547 (zero_extend:SI (match_dup 2)))]
8550 operands[2] = gen_reg_rtx (HImode);
8553 (define_insn_and_split "*ctzhi2.libgcc_split"
8555 (ctz:HI (reg:HI 24)))
8556 (clobber (reg:QI 26))]
8559 "&& reload_completed"
8560 [(parallel [(set (reg:HI 24)
8561 (ctz:HI (reg:HI 24)))
8562 (clobber (reg:QI 26))
8563 (clobber (reg:CC REG_CC))])])
8565 (define_insn "*ctzhi2.libgcc"
8567 (ctz:HI (reg:HI 24)))
8568 (clobber (reg:QI 26))
8569 (clobber (reg:CC REG_CC))]
8572 [(set_attr "type" "xcall")])
8574 (define_insn_and_split "*ctzsihi2.libgcc_split"
8576 (truncate:HI (ctz:SI (reg:SI 22))))
8577 (clobber (reg:QI 22))
8578 (clobber (reg:QI 26))]
8581 "&& reload_completed"
8582 [(parallel [(set (reg:HI 24)
8583 (truncate:HI (ctz:SI (reg:SI 22))))
8584 (clobber (reg:QI 22))
8585 (clobber (reg:QI 26))
8586 (clobber (reg:CC REG_CC))])])
8588 (define_insn "*ctzsihi2.libgcc"
8590 (truncate:HI (ctz:SI (reg:SI 22))))
8591 (clobber (reg:QI 22))
8592 (clobber (reg:QI 26))
8593 (clobber (reg:CC REG_CC))]
8596 [(set_attr "type" "xcall")])
8600 (define_expand "ffshi2"
8602 (match_operand:HI 1 "register_operand" ""))
8603 (parallel [(set (reg:HI 24)
8604 (ffs:HI (reg:HI 24)))
8605 (clobber (reg:QI 26))])
8606 (set (match_operand:HI 0 "register_operand" "")
8609 (define_expand "ffssi2"
8611 (match_operand:SI 1 "register_operand" ""))
8612 (parallel [(set (reg:HI 24)
8613 (truncate:HI (ffs:SI (reg:SI 22))))
8614 (clobber (reg:QI 22))
8615 (clobber (reg:QI 26))])
8618 (set (match_operand:SI 0 "register_operand" "")
8619 (zero_extend:SI (match_dup 2)))]
8622 operands[2] = gen_reg_rtx (HImode);
8625 (define_insn_and_split "*ffshi2.libgcc_split"
8627 (ffs:HI (reg:HI 24)))
8628 (clobber (reg:QI 26))]
8631 "&& reload_completed"
8632 [(parallel [(set (reg:HI 24)
8633 (ffs:HI (reg:HI 24)))
8634 (clobber (reg:QI 26))
8635 (clobber (reg:CC REG_CC))])])
8637 (define_insn "*ffshi2.libgcc"
8639 (ffs:HI (reg:HI 24)))
8640 (clobber (reg:QI 26))
8641 (clobber (reg:CC REG_CC))]
8644 [(set_attr "type" "xcall")])
8646 (define_insn_and_split "*ffssihi2.libgcc_split"
8648 (truncate:HI (ffs:SI (reg:SI 22))))
8649 (clobber (reg:QI 22))
8650 (clobber (reg:QI 26))]
8653 "&& reload_completed"
8654 [(parallel [(set (reg:HI 24)
8655 (truncate:HI (ffs:SI (reg:SI 22))))
8656 (clobber (reg:QI 22))
8657 (clobber (reg:QI 26))
8658 (clobber (reg:CC REG_CC))])])
8660 (define_insn "*ffssihi2.libgcc"
8662 (truncate:HI (ffs:SI (reg:SI 22))))
8663 (clobber (reg:QI 22))
8664 (clobber (reg:QI 26))
8665 (clobber (reg:CC REG_CC))]
8668 [(set_attr "type" "xcall")])
8672 (define_insn "copysignsf3"
8673 [(set (match_operand:SF 0 "register_operand" "=r")
8674 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
8675 (match_operand:SF 2 "register_operand" "r")]
8678 "bst %D2,7\;bld %D0,7"
8679 [(set_attr "length" "2")])
8681 ;; Swap Bytes (change byte-endianness)
8683 (define_expand "bswapsi2"
8685 (match_operand:SI 1 "register_operand" ""))
8687 (bswap:SI (reg:SI 22)))
8688 (set (match_operand:SI 0 "register_operand" "")
8691 (define_insn_and_split "*bswapsi2.libgcc_split"
8693 (bswap:SI (reg:SI 22)))]
8696 "&& reload_completed"
8697 [(parallel [(set (reg:SI 22)
8698 (bswap:SI (reg:SI 22)))
8699 (clobber (reg:CC REG_CC))])])
8701 (define_insn "*bswapsi2.libgcc"
8703 (bswap:SI (reg:SI 22)))
8704 (clobber (reg:CC REG_CC))]
8707 [(set_attr "type" "xcall")])
8712 ;; NOP taking 1 or 2 Ticks
8713 (define_expand "nopv"
8714 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
8717 (unspec_volatile:BLK [(match_dup 1)]
8718 UNSPECV_MEMORY_BARRIER))])]
8721 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8722 MEM_VOLATILE_P (operands[1]) = 1;
8725 (define_insn "*nopv"
8726 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
8728 (set (match_operand:BLK 1 "" "")
8729 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
8734 [(set_attr "length" "1")])
8737 (define_expand "sleep"
8738 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
8740 (unspec_volatile:BLK [(match_dup 0)]
8741 UNSPECV_MEMORY_BARRIER))])]
8744 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8745 MEM_VOLATILE_P (operands[0]) = 1;
8748 (define_insn "*sleep"
8749 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
8750 (set (match_operand:BLK 0 "" "")
8751 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
8754 [(set_attr "length" "1")])
8757 (define_expand "wdr"
8758 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
8760 (unspec_volatile:BLK [(match_dup 0)]
8761 UNSPECV_MEMORY_BARRIER))])]
8764 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
8765 MEM_VOLATILE_P (operands[0]) = 1;
8769 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
8770 (set (match_operand:BLK 0 "" "")
8771 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
8774 [(set_attr "length" "1")])
8777 (define_expand "fmul"
8779 (match_operand:QI 1 "register_operand" ""))
8781 (match_operand:QI 2 "register_operand" ""))
8782 (parallel [(set (reg:HI 22)
8783 (unspec:HI [(reg:QI 24)
8784 (reg:QI 25)] UNSPEC_FMUL))
8785 (clobber (reg:HI 24))])
8786 (set (match_operand:HI 0 "register_operand" "")
8792 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
8795 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
8798 (define_insn_and_split "fmul_insn"
8799 [(set (match_operand:HI 0 "register_operand" "=r")
8800 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8801 (match_operand:QI 2 "register_operand" "a")]
8805 "&& reload_completed"
8806 [(parallel [(set (match_dup 0)
8807 (unspec:HI [(match_dup 1)
8810 (clobber (reg:CC REG_CC))])])
8812 (define_insn "*fmul_insn"
8813 [(set (match_operand:HI 0 "register_operand" "=r")
8814 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8815 (match_operand:QI 2 "register_operand" "a")]
8817 (clobber (reg:CC REG_CC))]
8818 "AVR_HAVE_MUL && reload_completed"
8822 [(set_attr "length" "3")])
8824 (define_insn_and_split "*fmul.call_split"
8826 (unspec:HI [(reg:QI 24)
8827 (reg:QI 25)] UNSPEC_FMUL))
8828 (clobber (reg:HI 24))]
8831 "&& reload_completed"
8832 [(parallel [(set (reg:HI 22)
8833 (unspec:HI [(reg:QI 24)
8834 (reg:QI 25)] UNSPEC_FMUL))
8835 (clobber (reg:HI 24))
8836 (clobber (reg:CC REG_CC))])])
8838 (define_insn "*fmul.call"
8840 (unspec:HI [(reg:QI 24)
8841 (reg:QI 25)] UNSPEC_FMUL))
8842 (clobber (reg:HI 24))
8843 (clobber (reg:CC REG_CC))]
8844 "!AVR_HAVE_MUL && reload_completed"
8846 [(set_attr "type" "xcall")])
8849 (define_expand "fmuls"
8851 (match_operand:QI 1 "register_operand" ""))
8853 (match_operand:QI 2 "register_operand" ""))
8854 (parallel [(set (reg:HI 22)
8855 (unspec:HI [(reg:QI 24)
8856 (reg:QI 25)] UNSPEC_FMULS))
8857 (clobber (reg:HI 24))])
8858 (set (match_operand:HI 0 "register_operand" "")
8864 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
8867 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
8870 (define_insn_and_split "fmuls_insn"
8871 [(set (match_operand:HI 0 "register_operand" "=r")
8872 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8873 (match_operand:QI 2 "register_operand" "a")]
8877 "&& reload_completed"
8878 [(parallel [(set (match_dup 0)
8879 (unspec:HI [(match_dup 1)
8882 (clobber (reg:CC REG_CC))])])
8884 (define_insn "*fmuls_insn"
8885 [(set (match_operand:HI 0 "register_operand" "=r")
8886 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8887 (match_operand:QI 2 "register_operand" "a")]
8889 (clobber (reg:CC REG_CC))]
8890 "AVR_HAVE_MUL && reload_completed"
8894 [(set_attr "length" "3")])
8896 (define_insn_and_split "*fmuls.call_split"
8898 (unspec:HI [(reg:QI 24)
8899 (reg:QI 25)] UNSPEC_FMULS))
8900 (clobber (reg:HI 24))]
8903 "&& reload_completed"
8904 [(parallel [(set (reg:HI 22)
8905 (unspec:HI [(reg:QI 24)
8906 (reg:QI 25)] UNSPEC_FMULS))
8907 (clobber (reg:HI 24))
8908 (clobber (reg:CC REG_CC))])])
8910 (define_insn "*fmuls.call"
8912 (unspec:HI [(reg:QI 24)
8913 (reg:QI 25)] UNSPEC_FMULS))
8914 (clobber (reg:HI 24))
8915 (clobber (reg:CC REG_CC))]
8916 "!AVR_HAVE_MUL && reload_completed"
8918 [(set_attr "type" "xcall")])
8921 (define_expand "fmulsu"
8923 (match_operand:QI 1 "register_operand" ""))
8925 (match_operand:QI 2 "register_operand" ""))
8926 (parallel [(set (reg:HI 22)
8927 (unspec:HI [(reg:QI 24)
8928 (reg:QI 25)] UNSPEC_FMULSU))
8929 (clobber (reg:HI 24))])
8930 (set (match_operand:HI 0 "register_operand" "")
8936 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
8939 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
8942 (define_insn_and_split "fmulsu_insn"
8943 [(set (match_operand:HI 0 "register_operand" "=r")
8944 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8945 (match_operand:QI 2 "register_operand" "a")]
8949 "&& reload_completed"
8950 [(parallel [(set (match_dup 0)
8951 (unspec:HI [(match_dup 1)
8954 (clobber (reg:CC REG_CC))])])
8956 (define_insn "*fmulsu_insn"
8957 [(set (match_operand:HI 0 "register_operand" "=r")
8958 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
8959 (match_operand:QI 2 "register_operand" "a")]
8961 (clobber (reg:CC REG_CC))]
8962 "AVR_HAVE_MUL && reload_completed"
8966 [(set_attr "length" "3")])
8968 (define_insn_and_split "*fmulsu.call_split"
8970 (unspec:HI [(reg:QI 24)
8971 (reg:QI 25)] UNSPEC_FMULSU))
8972 (clobber (reg:HI 24))]
8975 "&& reload_completed"
8976 [(parallel [(set (reg:HI 22)
8977 (unspec:HI [(reg:QI 24)
8978 (reg:QI 25)] UNSPEC_FMULSU))
8979 (clobber (reg:HI 24))
8980 (clobber (reg:CC REG_CC))])])
8982 (define_insn "*fmulsu.call"
8984 (unspec:HI [(reg:QI 24)
8985 (reg:QI 25)] UNSPEC_FMULSU))
8986 (clobber (reg:HI 24))
8987 (clobber (reg:CC REG_CC))]
8988 "!AVR_HAVE_MUL && reload_completed"
8990 [(set_attr "type" "xcall")
8994 ;; Some combiner patterns dealing with bits.
8997 ;; Move bit $3.0 into bit $0.$4
8998 (define_insn "*movbitqi.1-6.a"
8999 [(set (match_operand:QI 0 "register_operand" "=r")
9000 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9001 (match_operand:QI 2 "single_zero_operand" "n"))
9002 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
9003 (match_operand:QI 4 "const_0_to_7_operand" "n"))
9004 (match_operand:QI 5 "single_one_operand" "n"))))]
9005 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
9006 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
9007 "bst %3,0\;bld %0,%4"
9008 [(set_attr "length" "2")])
9010 ;; Move bit $3.0 into bit $0.$4
9011 ;; Variation of above. Unfortunately, there is no canonicalized representation
9012 ;; of moving around bits. So what we see here depends on how user writes down
9013 ;; bit manipulations.
9014 (define_insn "*movbitqi.1-6.b"
9015 [(set (match_operand:QI 0 "register_operand" "=r")
9016 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9017 (match_operand:QI 2 "single_zero_operand" "n"))
9018 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
9020 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
9021 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
9022 "bst %3,0\;bld %0,%4"
9023 [(set_attr "length" "2")])
9025 ;; Move bit $3.x into bit $0.x.
9026 (define_insn "*movbit<mode>.0-6"
9027 [(set (match_operand:QISI 0 "register_operand" "=r")
9028 (ior:QISI (and:QISI (match_operand:QISI 1 "register_operand" "0")
9029 (match_operand:QISI 2 "single_zero_operand" "n"))
9030 (and:QISI (match_operand:QISI 3 "register_operand" "r")
9031 (match_operand:QISI 4 "single_one_operand" "n"))))]
9032 "GET_MODE_MASK(<MODE>mode)
9033 == (GET_MODE_MASK(<MODE>mode) & (INTVAL(operands[2]) ^ INTVAL(operands[4])))"
9035 auto bitmask = GET_MODE_MASK (<MODE>mode) & UINTVAL (operands[4]);
9036 operands[4] = GEN_INT (exact_log2 (bitmask));
9037 return "bst %T3%T4" CR_TAB "bld %T0%T4";
9039 [(set_attr "length" "2")])
9041 ;; Move bit $2.0 into bit $0.7.
9042 ;; For bit 7, combiner generates slightly different pattern
9043 (define_insn "*movbitqi.7"
9044 [(set (match_operand:QI 0 "register_operand" "=r")
9045 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
9047 (ashift:QI (match_operand:QI 2 "register_operand" "r")
9050 "bst %2,0\;bld %0,7"
9051 [(set_attr "length" "2")])
9053 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
9054 ;; and input/output match. We provide a special pattern for this, because
9055 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
9056 ;; operation on I/O is atomic.
9057 (define_insn "*insv.io"
9058 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
9060 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
9061 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
9066 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
9067 [(set_attr "length" "1,1,4")])
9069 (define_insn "*insv.not.io"
9070 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
9072 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9073 (not:QI (match_operand:QI 2 "register_operand" "r")))]
9075 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
9076 [(set_attr "length" "4")])
9078 ;; The insv expander.
9079 ;; We only support 1-bit inserts
9080 (define_expand "insv"
9081 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
9082 (match_operand:QI 1 "const1_operand" "") ; width
9083 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
9084 (match_operand:QI 3 "nonmemory_operand" ""))]
9087 ;; Some more patterns to support moving around one bit which can be accomplished
9088 ;; by BST + BLD in most situations. Unfortunately, there is no canonical
9089 ;; representation, and we just implement some more cases that are not too
9092 ;; Insert bit $2.0 into $0.$1
9093 (define_insn_and_split "*insv.reg_split"
9094 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
9096 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
9097 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
9100 "&& reload_completed"
9101 [(parallel [(set (zero_extract:QI (match_dup 0)
9105 (clobber (reg:CC REG_CC))])])
9107 (define_insn "*insv.reg"
9108 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
9110 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
9111 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))
9112 (clobber (reg:CC REG_CC))]
9116 andi %0,lo8(~(1<<%1))
9120 [(set_attr "length" "2,1,1,2,2")])
9122 ;; Insert bit $2.$3 into $0.$1
9123 (define_insn "*insv.extract"
9124 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9126 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9127 (any_extract:QI (match_operand:QI 2 "register_operand" "r")
9129 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9131 "bst %2,%3\;bld %0,%1"
9132 [(set_attr "length" "2")])
9134 ;; Insert bit $2.$3 into $0.$1
9135 (define_insn "*insv.shiftrt"
9136 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9138 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9139 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9140 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9142 "bst %2,%3\;bld %0,%1"
9143 [(set_attr "length" "2")])
9145 ;; Same, but with a NOT inverting the source bit.
9146 ;; Insert bit ~$2.$3 into $0.$1
9147 (define_insn_and_split "*insv.not-shiftrt_split"
9148 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9150 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9151 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9152 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
9155 "&& reload_completed"
9156 [(parallel [(set (zero_extract:QI (match_dup 0)
9159 (not:QI (any_shiftrt:QI (match_dup 2)
9161 (clobber (reg:CC REG_CC))])])
9163 (define_insn "*insv.not-shiftrt"
9164 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9166 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9167 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
9168 (match_operand:QI 3 "const_0_to_7_operand" "n"))))
9169 (clobber (reg:CC REG_CC))]
9172 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
9174 [(set_attr "adjust_len" "insv_notbit")])
9176 ;; Insert bit ~$2.0 into $0.$1
9177 (define_insn_and_split "*insv.xor1-bit.0_split"
9178 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9180 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9181 (xor:QI (match_operand:QI 2 "register_operand" "r")
9185 "&& reload_completed"
9186 [(parallel [(set (zero_extract:QI (match_dup 0)
9189 (xor:QI (match_dup 2)
9191 (clobber (reg:CC REG_CC))])])
9193 (define_insn "*insv.xor1-bit.0"
9194 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9196 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9197 (xor:QI (match_operand:QI 2 "register_operand" "r")
9199 (clobber (reg:CC REG_CC))]
9202 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
9204 [(set_attr "adjust_len" "insv_notbit_0")])
9206 ;; Insert bit ~$2.0 into $0.$1
9207 (define_insn_and_split "*insv.not-bit.0_split"
9208 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9210 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9211 (not:QI (match_operand:QI 2 "register_operand" "r")))]
9214 "&& reload_completed"
9215 [(parallel [(set (zero_extract:QI (match_dup 0)
9218 (not:QI (match_dup 2)))
9219 (clobber (reg:CC REG_CC))])])
9221 (define_insn "*insv.not-bit.0"
9222 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9224 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9225 (not:QI (match_operand:QI 2 "register_operand" "r")))
9226 (clobber (reg:CC REG_CC))]
9229 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
9231 [(set_attr "adjust_len" "insv_notbit_0")])
9233 ;; Insert bit ~$2.7 into $0.$1
9234 (define_insn_and_split "*insv.not-bit.7_split"
9235 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9237 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9238 (ge:QI (match_operand:QI 2 "register_operand" "r")
9242 "&& reload_completed"
9243 [(parallel [(set (zero_extract:QI (match_dup 0)
9246 (ge:QI (match_dup 2)
9248 (clobber (reg:CC REG_CC))])])
9250 (define_insn "*insv.not-bit.7"
9251 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9253 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9254 (ge:QI (match_operand:QI 2 "register_operand" "r")
9256 (clobber (reg:CC REG_CC))]
9259 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
9261 [(set_attr "adjust_len" "insv_notbit_7")])
9263 ;; Insert bit ~$2.$3 into $0.$1
9264 (define_insn_and_split "*insv.xor-extract_split"
9265 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9267 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9268 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
9269 (match_operand:QI 4 "const_int_operand" "n"))
9271 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
9272 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
9274 "&& reload_completed"
9275 [(parallel [(set (zero_extract:QI (match_dup 0)
9278 (any_extract:QI (xor:QI (match_dup 2)
9282 (clobber (reg:CC REG_CC))])])
9284 (define_insn "*insv.xor-extract"
9285 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
9287 (match_operand:QI 1 "const_0_to_7_operand" "n"))
9288 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
9289 (match_operand:QI 4 "const_int_operand" "n"))
9291 (match_operand:QI 3 "const_0_to_7_operand" "n")))
9292 (clobber (reg:CC REG_CC))]
9293 "INTVAL (operands[4]) & (1 << INTVAL (operands[3])) && reload_completed"
9295 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
9297 [(set_attr "adjust_len" "insv_notbit")])
9300 ;; Some combine patterns that try to fix bad code when a value is composed
9301 ;; from byte parts like in PR27663.
9302 ;; The patterns give some release but the code still is not optimal,
9303 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
9304 ;; That switch obfuscates things here and in many other places.
9306 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
9307 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
9308 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
9309 [(set (match_operand:HISI 0 "register_operand" "=r")
9311 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
9312 (match_operand:HISI 2 "register_operand" "0")))]
9317 (xior:QI (match_dup 3)
9320 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
9323 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
9324 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
9325 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
9326 [(set (match_operand:HISI 0 "register_operand" "=r")
9328 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
9329 (match_operand:QI 2 "const_8_16_24_operand" "n"))
9330 (match_operand:HISI 3 "register_operand" "0")))]
9331 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
9333 "&& reload_completed"
9335 (xior:QI (match_dup 4)
9338 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
9339 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
9343 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
9344 [(set (match_operand:HI 0 "register_operand" "=r,r")
9345 (ior:HI (ashift:HI (any_extend:HI
9346 (match_operand:QI 1 "register_operand" "r,r"))
9348 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))]
9350 { gcc_unreachable(); }
9351 "&& reload_completed"
9352 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
9353 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
9354 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
9356 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9357 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9359 if (!reg_overlap_mentioned_p (hi, operands[2]))
9361 emit_move_insn (hi, operands[1]);
9362 emit_move_insn (lo, operands[2]);
9365 else if (!reg_overlap_mentioned_p (lo, operands[1]))
9367 emit_move_insn (lo, operands[2]);
9368 emit_move_insn (hi, operands[1]);
9372 gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
9373 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
9376 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
9377 [(set (match_operand:HI 0 "register_operand" "=r")
9378 (ior:HI (ashift:HI (any_extend:HI
9379 (match_operand:QI 1 "register_operand" "r"))
9381 (match_operand:HI 2 "register_operand" "0")))]
9383 { gcc_unreachable(); }
9384 "&& reload_completed"
9386 (ior:QI (match_dup 4)
9389 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9390 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
9393 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
9394 [(set (match_operand:HI 0 "register_operand" "=r")
9395 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
9397 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
9399 { gcc_unreachable(); }
9400 "&& reload_completed"
9404 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9405 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
9410 [(parallel [(set (match_operand:QI 0 "register_operand")
9412 (clobber (reg:CC REG_CC))])
9413 (parallel [(set (match_dup 0)
9414 (ior:QI (match_dup 0)
9415 (match_operand:QI 1 "register_operand")))
9416 (clobber (reg:CC REG_CC))])]
9418 [(parallel [(set (match_dup 0)
9420 (clobber (reg:CC REG_CC))])])
9423 ;; Try optimize decrement-and-branch. When we have an addition followed
9424 ;; by a comparison of the result against zero, we can output the addition
9425 ;; in such a way that SREG.N and SREG.Z are set according to the result.
9427 ;; { -1, +1 } for QImode, otherwise the empty set.
9428 (define_mode_attr p1m1 [(QI "N P")
9429 (HI "Yxx") (PSI "Yxx") (SI "Yxx")])
9431 ;; FIXME: reload1.cc::do_output_reload() does not support output reloads
9432 ;; for JUMP_INSNs, hence letting combine doing decrement-and-branch like
9433 ;; the following might run into ICE. Doing reloads by hand is too painful...
9435 ; (define_insn_and_split "*add.for.eqne.<mode>.cbranch"
9437 ; (if_then_else (eqne (match_operand:QISI 1 "register_operand" "0")
9438 ; (match_operand:QISI 2 "const_int_operand" "n"))
9439 ; (label_ref (match_operand 4))
9441 ; (set (match_operand:QISI 0 "register_operand" "=r")
9442 ; (plus:QISI (match_dup 1)
9443 ; (match_operand:QISI 3 "const_int_operand" "n")))]
9444 ; ;; No clobber for now as combine might not have one handy.
9445 ; ;; We pop a scatch in split1.
9446 ; "!reload_completed
9447 ; && const0_rtx == simplify_binary_operation (PLUS, <MODE>mode,
9448 ; operands[2], operands[3])"
9449 ; { gcc_unreachable(); }
9451 ; [(parallel [(set (pc)
9452 ; (if_then_else (eqne (match_dup 1)
9454 ; (label_ref (match_dup 4))
9456 ; (set (match_dup 0)
9457 ; (plus:QISI (match_dup 1)
9459 ; (clobber (scratch:QI))])])
9461 ;; ...Hence, stick with RTL peepholes for now. Unfortunately, there is no
9462 ;; canonical form, and if reload shuffles registers around, we might miss
9463 ;; opportunities to match a decrement-and-branch.
9464 ;; doloop_end doesn't reload either, so doloop_end also won't work.
9466 (define_expand "gen_add_for_<code>_<mode>"
9467 ; "*add.for.eqne.<mode>"
9468 [(parallel [(set (reg:CC REG_CC)
9469 (compare:CC (plus:QISI (match_operand:QISI 0 "register_operand")
9470 (match_operand:QISI 1 "const_int_operand"))
9473 (plus:QISI (match_dup 0)
9475 (clobber (match_operand:QI 3))])
9478 (if_then_else (eqne (reg:CC REG_CC)
9480 (label_ref (match_dup 2))
9484 ;; 1/3: A version without clobber: d-reg or 8-bit adds +/-1.
9486 [(parallel [(set (match_operand:QISI 0 "register_operand")
9487 (plus:QISI (match_dup 0)
9488 (match_operand:QISI 1 "const_int_operand")))
9489 (clobber (reg:CC REG_CC))])
9490 (set (reg:CC REG_CC)
9491 (compare:CC (match_dup 0)
9494 (if_then_else (eqne (reg:CC REG_CC)
9496 (label_ref (match_operand 2))
9498 "peep2_regno_dead_p (3, REG_CC)
9499 && (d_register_operand (operands[0], <MODE>mode)
9500 || (<MODE>mode == QImode
9501 && (INTVAL (operands[1]) == 1
9502 || INTVAL (operands[1]) == -1)))"
9505 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2],
9506 gen_rtx_SCRATCH (QImode)));
9510 ;; 2/3: A version with clobber from the insn.
9512 [(parallel [(set (match_operand:QISI 0 "register_operand")
9513 (plus:QISI (match_dup 0)
9514 (match_operand:QISI 1 "const_int_operand")))
9515 (clobber (match_operand:QI 3 "scratch_or_d_register_operand"))
9516 (clobber (reg:CC REG_CC))])
9517 (parallel [(set (reg:CC REG_CC)
9518 (compare:CC (match_dup 0)
9520 (clobber (match_operand:QI 4 "scratch_or_d_register_operand"))])
9522 (if_then_else (eqne (reg:CC REG_CC)
9524 (label_ref (match_operand 2))
9526 "peep2_regno_dead_p (3, REG_CC)"
9529 rtx scratch = REG_P (operands[3]) ? operands[3] : operands[4];
9531 // We need either a d-register or a scratch register to clobber.
9532 if (! REG_P (scratch)
9533 && ! d_register_operand (operands[0], <MODE>mode)
9534 && ! (QImode == <MODE>mode
9535 && (INTVAL (operands[1]) == 1
9536 || INTVAL (operands[1]) == -1)))
9540 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2],
9545 ;; 3/3 A version with a clobber from peephole2.
9547 [(match_scratch:QI 3 "d")
9548 (parallel [(set (match_operand:QISI 0 "register_operand")
9549 (plus:QISI (match_dup 0)
9550 (match_operand:QISI 1 "const_int_operand")))
9551 (clobber (reg:CC REG_CC))])
9552 (set (reg:CC REG_CC)
9553 (compare:CC (match_dup 0)
9556 (if_then_else (eqne (reg:CC REG_CC)
9558 (label_ref (match_operand 2))
9560 "peep2_regno_dead_p (3, REG_CC)"
9563 emit (gen_gen_add_for_<code>_<mode> (operands[0], operands[1], operands[2],
9568 ;; Result of the above three peepholes is an addition that also
9569 ;; performs an EQ or NE comparison (of the result) against zero.
9570 ;; FIXME: Using (match_dup 0) instead of operands[3/4] makes rnregs
9571 ;; barf in regrename.cc::merge_overlapping_regs(). For now, use the
9572 ;; fix from PR50788: Constrain as "0".
9573 (define_insn "*add.for.eqne.<mode>"
9574 [(set (reg:CC REG_CC)
9576 (plus:QISI (match_operand:QISI 3 "register_operand" "0,0 ,0")
9577 (match_operand:QISI 1 "const_int_operand" "n,<p1m1>,n"))
9579 (set (match_operand:QISI 0 "register_operand" "=d,*r ,r")
9580 (plus:QISI (match_operand:QISI 4 "register_operand" "0,0 ,0")
9582 (clobber (match_scratch:QI 2 "=X,X ,&d"))]
9585 return avr_out_plus_set_ZN (operands, nullptr);
9587 [(set_attr "adjust_len" "add_set_ZN")])
9590 ;; Swapping both comparison and branch condition. This can turn difficult
9591 ;; branches to easy ones. And in some cases, a comparison against one can
9592 ;; be turned into a comparison against zero.
9594 (define_peephole2 ; "*swapped_tst<mode>"
9595 [(parallel [(set (reg:CC REG_CC)
9596 (compare:CC (match_operand:ALLs234 1 "register_operand")
9597 (match_operand:ALLs234 2 "const_operand")))
9598 (clobber (match_operand:QI 3 "scratch_operand"))])
9600 (if_then_else (match_operator 0 "ordered_comparison_operator"
9603 (label_ref (match_operand 4))
9605 "peep2_regno_dead_p (2, REG_CC)"
9606 [(set (reg:CC REG_CC)
9607 (compare:CC (match_dup 2)
9611 (if_then_else (match_op_dup 0 [(reg:CC REG_CC)
9613 (label_ref (match_dup 4))
9616 rtx xval = avr_to_int_mode (operands[2]);
9617 enum rtx_code code = GET_CODE (operands[0]);
9619 if (code == GT && xval == const0_rtx)
9621 else if (code == GE && xval == const1_rtx)
9623 else if (code == LE && xval == const0_rtx)
9625 else if (code == LT && xval == const1_rtx)
9630 operands[2] = CONST0_RTX (<MODE>mode);
9631 PUT_CODE (operands[0], code);
9634 ;; Same, but for 8-bit modes which have no scratch reg.
9635 (define_peephole2 ; "*swapped_tst<mode>"
9636 [(set (reg:CC REG_CC)
9637 (compare:CC (match_operand:ALLs1 1 "register_operand")
9638 (match_operand:ALLs1 2 "const_operand")))
9640 (if_then_else (match_operator 0 "ordered_comparison_operator"
9643 (label_ref (match_operand 4))
9645 "peep2_regno_dead_p (2, REG_CC)"
9646 [(set (reg:CC REG_CC)
9647 (compare:CC (match_dup 2)
9651 (if_then_else (match_op_dup 0 [(reg:CC REG_CC)
9653 (label_ref (match_dup 4))
9656 rtx xval = avr_to_int_mode (operands[2]);
9657 enum rtx_code code = GET_CODE (operands[0]);
9659 if (code == GT && xval == const0_rtx)
9661 else if (code == GE && xval == const1_rtx)
9663 else if (code == LE && xval == const0_rtx)
9665 else if (code == LT && xval == const1_rtx)
9670 operands[2] = CONST0_RTX (<MODE>mode);
9671 PUT_CODE (operands[0], code);
9675 (define_expand "extzv"
9676 [(set (match_operand:QI 0 "register_operand" "")
9677 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
9678 (match_operand:QI 2 "const1_operand" "")
9679 (match_operand:QI 3 "const_0_to_7_operand" "")))])
9681 (define_insn_and_split "*extzv_split"
9682 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
9683 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
9685 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
9688 "&& reload_completed"
9689 [(parallel [(set (match_dup 0)
9690 (zero_extract:QI (match_dup 1)
9693 (clobber (reg:CC REG_CC))])])
9695 (define_insn "*extzv"
9696 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
9697 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
9699 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))
9700 (clobber (reg:CC REG_CC))]
9704 mov %0,%1\;andi %0,1
9707 bst %1,%2\;clr %0\;bld %0,0"
9708 [(set_attr "length" "1,2,2,2,3")])
9710 (define_insn_and_split "*extzv.qihi1"
9711 [(set (match_operand:HI 0 "register_operand" "=r")
9712 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
9714 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
9719 (zero_extract:QI (match_dup 1)
9725 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9726 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9729 (define_insn_and_split "*extzv.qihi2"
9730 [(set (match_operand:HI 0 "register_operand" "=r")
9732 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
9734 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
9739 (zero_extract:QI (match_dup 1)
9745 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
9746 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
9749 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
9750 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example.
9751 (define_insn_and_split "*extract.subreg.bit"
9752 [(set (match_operand:QI 0 "register_operand" "=r")
9753 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
9754 (match_operand:QI 2 "const_int_operand" "n"))
9757 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
9758 { gcc_unreachable(); }
9759 "&& reload_completed"
9762 (zero_extract:QI (match_dup 3)
9766 int bitno = INTVAL (operands[2]);
9767 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
9768 operands[4] = GEN_INT (bitno % 8);
9772 ;; Fixed-point instructions
9773 (include "avr-fixed.md")
9775 ;; Operations on 64-bit registers
9776 (include "avr-dimode.md")