1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2019 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.
61 (LPM_REGNO 0) ; implicit target register of LPM
62 (TMP_REGNO 0) ; temporary register r0
63 (ZERO_REGNO 1) ; zero register r1
67 [(TMP_REGNO_TINY 16) ; r16 is temp register for AVR_TINY
68 (ZERO_REGNO_TINY 17) ; r17 is zero register for AVR_TINY
71 (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.c: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,
170 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
172 ;; mov : ISA has no MOVW movw : ISA has MOVW
173 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
174 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
175 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
176 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
177 ;; no_xmega: non-XMEGA core xmega : XMEGA core
178 ;; no_tiny: non-TINY core tiny : TINY core
181 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega, no_tiny,tiny,
183 (const_string "standard"))
185 (define_attr "enabled" ""
186 (cond [(eq_attr "isa" "standard")
189 (and (eq_attr "isa" "mov")
190 (match_test "!AVR_HAVE_MOVW"))
193 (and (eq_attr "isa" "movw")
194 (match_test "AVR_HAVE_MOVW"))
197 (and (eq_attr "isa" "rjmp")
198 (match_test "!AVR_HAVE_JMP_CALL"))
201 (and (eq_attr "isa" "jmp")
202 (match_test "AVR_HAVE_JMP_CALL"))
205 (and (eq_attr "isa" "ijmp")
206 (match_test "!AVR_HAVE_EIJMP_EICALL"))
209 (and (eq_attr "isa" "eijmp")
210 (match_test "AVR_HAVE_EIJMP_EICALL"))
213 (and (eq_attr "isa" "lpm")
214 (match_test "!AVR_HAVE_LPMX"))
217 (and (eq_attr "isa" "lpmx")
218 (match_test "AVR_HAVE_LPMX"))
221 (and (eq_attr "isa" "elpm")
222 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
225 (and (eq_attr "isa" "elpmx")
226 (match_test "AVR_HAVE_ELPMX"))
229 (and (eq_attr "isa" "xmega")
230 (match_test "AVR_XMEGA"))
233 (and (eq_attr "isa" "tiny")
234 (match_test "AVR_TINY"))
237 (and (eq_attr "isa" "no_xmega")
238 (match_test "!AVR_XMEGA"))
241 (and (eq_attr "isa" "no_tiny")
242 (match_test "!AVR_TINY"))
248 ;; Define mode iterators
249 (define_mode_iterator QIHI [QI HI])
250 (define_mode_iterator QIHI2 [QI HI])
251 (define_mode_iterator QISI [QI HI PSI SI])
252 (define_mode_iterator QIDI [QI HI PSI SI DI])
253 (define_mode_iterator HISI [HI PSI SI])
255 (define_mode_iterator ALL1 [QI QQ UQQ])
256 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
257 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
259 ;; All supported move-modes
260 (define_mode_iterator MOVMODE [QI QQ UQQ
265 ;; Supported ordered modes that are 2, 3, 4 bytes wide
266 (define_mode_iterator ORDERED234 [HI SI PSI
270 ;; Post-reload split of 3, 4 bytes wide moves.
271 (define_mode_iterator SPLIT34 [SI SF PSI
274 ;; Define code iterators
275 ;; Define two incarnations so that we can build the cross product.
276 (define_code_iterator any_extend [sign_extend zero_extend])
277 (define_code_iterator any_extend2 [sign_extend zero_extend])
278 (define_code_iterator any_extract [sign_extract zero_extract])
279 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
281 (define_code_iterator bitop [xor ior and])
282 (define_code_iterator xior [xor ior])
283 (define_code_iterator eqne [eq ne])
285 (define_code_iterator ss_addsub [ss_plus ss_minus])
286 (define_code_iterator us_addsub [us_plus us_minus])
287 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
289 ;; Define code attributes
290 (define_code_attr extend_su
294 (define_code_attr extend_u
298 (define_code_attr extend_s
302 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
303 (define_code_attr mul_r_d
307 (define_code_attr abelian
308 [(ss_minus "") (us_minus "")
309 (ss_plus "%") (us_plus "%")])
311 ;; Map RTX code to its standard insn name
312 (define_code_attr code_stdname
319 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
320 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
323 ;;========================================================================
324 ;; The following is used by nonlocal_goto and setjmp.
325 ;; The receiver pattern will create no instructions since internally
326 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
327 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
328 ;; The 'null' receiver also avoids problems with optimisation
329 ;; not recognising incoming jmp and removing code that resets frame_pointer.
330 ;; The code derived from builtins.c.
332 (define_expand "nonlocal_goto_receiver"
334 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
337 rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode);
338 emit_move_insn (virtual_stack_vars_rtx,
339 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset));
340 /* ; This might change the hard frame pointer in ways that aren't
341 ; apparent to early optimization passes, so force a clobber. */
342 emit_clobber (hard_frame_pointer_rtx);
347 ;; Defining nonlocal_goto_receiver means we must also define this
348 ;; even though its function is identical to that in builtins.c
350 (define_expand "nonlocal_goto"
351 [(use (match_operand 0 "general_operand"))
352 (use (match_operand 1 "general_operand"))
353 (use (match_operand 2 "general_operand"))
354 (use (match_operand 3 "general_operand"))]
357 rtx r_label = copy_to_reg (operands[1]);
358 rtx r_fp = operands[3];
359 rtx r_sp = operands[2];
361 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
363 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
365 emit_move_insn (hard_frame_pointer_rtx, r_fp);
366 emit_stack_restore (SAVE_NONLOCAL, r_sp);
368 emit_use (hard_frame_pointer_rtx);
369 emit_use (stack_pointer_rtx);
371 emit_indirect_jump (r_label);
377 ;; "pushqq1" "pushuqq1"
378 (define_insn "push<mode>1"
379 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
380 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
385 [(set_attr "length" "1,1")])
387 (define_insn "pushhi1_insn"
388 [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
389 (match_operand:HI 0 "register_operand" "r"))]
392 [(set_attr "length" "2")])
394 ;; All modes for a multi-byte push. We must include complex modes here too,
395 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
396 (define_mode_iterator MPUSH
405 (define_expand "push<mode>1"
406 [(match_operand:MPUSH 0 "" "")]
409 if (MEM_P (operands[0])
410 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
412 // Avoid (subreg (mem)) for non-generic address spaces. Because
413 // of the poor addressing capabilities of these spaces it's better to
414 // load them in one chunk. And it avoids PR61443.
416 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
418 else if (REG_P (operands[0])
419 && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER,
420 LAST_VIRTUAL_REGISTER))
422 // Byte-wise pushing of virtual regs might result in something like
424 // (set (mem:QI (post_dec:HI (reg:HI 32 SP)))
425 // (subreg:QI (plus:HI (reg:HI 28)
426 // (const_int 17)) 0))
428 // after elimination. This cannot be handled by reload, cf. PR64452.
429 // Reload virtuals in one chunk. That way it's possible to reload
430 // above situation and finally
435 // (plus:HI (reg:HI **)
437 // (set (mem:HI (post_dec:HI (reg:HI 32 SP))
440 emit_insn (gen_pushhi1_insn (operands[0]));
444 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
446 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
447 if (part != const0_rtx)
448 part = force_reg (QImode, part);
449 emit_insn (gen_pushqi1 (part));
454 ;; Notice a special-case when adding N to SP where N results in a
455 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
457 [(set (reg:HI REG_SP)
458 (match_operand:HI 0 "register_operand" ""))]
460 && frame_pointer_needed
461 && !cfun->calls_alloca
462 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
463 [(set (reg:HI REG_SP)
466 ;;========================================================================
474 (define_expand "load<mode>_libgcc"
477 (set (reg:MOVMODE 22)
478 (match_operand:MOVMODE 1 "memory_operand" ""))
479 (set (match_operand:MOVMODE 0 "register_operand" "")
481 "avr_load_libgcc_p (operands[1])"
483 operands[3] = gen_rtx_REG (HImode, REG_Z);
484 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
485 operands[1] = replace_equiv_address (operands[1], operands[3]);
486 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
494 (define_insn "load_<mode>_libgcc"
495 [(set (reg:MOVMODE 22)
496 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
497 "avr_load_libgcc_p (operands[0])
498 && REG_P (XEXP (operands[0], 0))
499 && REG_Z == REGNO (XEXP (operands[0], 0))"
501 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
502 return "%~call __load_%0";
504 [(set_attr "length" "1,2")
505 (set_attr "isa" "rjmp,jmp")
506 (set_attr "cc" "clobber")])
510 ;; "xload8qq_A" "xload8uqq_A"
511 (define_insn_and_split "xload8<mode>_A"
512 [(set (match_operand:ALL1 0 "register_operand" "=r")
513 (match_operand:ALL1 1 "memory_operand" "m"))
514 (clobber (reg:HI REG_Z))]
515 "can_create_pseudo_p()
516 && !avr_xload_libgcc_p (<MODE>mode)
517 && avr_mem_memx_p (operands[1])
518 && REG_P (XEXP (operands[1], 0))"
519 { gcc_unreachable(); }
521 [(clobber (const_int 0))]
523 /* ; Split away the high part of the address. GCC's register allocator
524 ; in not able to allocate segment registers and reload the resulting
525 ; expressions. Notice that no address register can hold a PSImode. */
528 rtx addr = XEXP (operands[1], 0);
529 rtx hi8 = gen_reg_rtx (QImode);
530 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
532 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
533 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
535 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
536 set_mem_addr_space (SET_SRC (single_set (insn)),
537 MEM_ADDR_SPACE (operands[1]));
541 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
542 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
543 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
546 (define_insn_and_split "xload<mode>_A"
547 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
548 (match_operand:MOVMODE 1 "memory_operand" "m"))
549 (clobber (reg:MOVMODE 22))
550 (clobber (reg:QI 21))
551 (clobber (reg:HI REG_Z))]
552 "can_create_pseudo_p()
553 && avr_mem_memx_p (operands[1])
554 && REG_P (XEXP (operands[1], 0))"
555 { gcc_unreachable(); }
557 [(clobber (const_int 0))]
559 rtx addr = XEXP (operands[1], 0);
560 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
561 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
562 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
565 /* Split the address to R21:Z */
566 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
567 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
569 /* Load with code from libgcc */
570 insn = emit_insn (gen_xload_<mode>_libgcc ());
571 set_mem_addr_space (SET_SRC (single_set (insn)), as);
573 /* Move to destination */
574 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
579 ;; Move value from address space memx to a register
580 ;; These insns must be prior to respective generic move insn.
583 ;; "xloadqq_8" "xloaduqq_8"
584 (define_insn "xload<mode>_8"
585 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
586 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
588 "!avr_xload_libgcc_p (<MODE>mode)"
590 return avr_out_xload (insn, operands, NULL);
592 [(set_attr "length" "4,4")
593 (set_attr "adjust_len" "*,xload")
594 (set_attr "isa" "lpmx,lpm")
595 (set_attr "cc" "none")])
597 ;; R21:Z : 24-bit source address
598 ;; R22 : 1-4 byte output
600 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
601 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
602 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
604 ;; "xload_psi_libgcc"
605 (define_insn "xload_<mode>_libgcc"
606 [(set (reg:MOVMODE 22)
607 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
609 (clobber (reg:QI 21))
610 (clobber (reg:HI REG_Z))]
611 "avr_xload_libgcc_p (<MODE>mode)"
613 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
615 output_asm_insn ("%~call __xload_%0", &x_bytes);
618 [(set_attr "type" "xcall")
619 (set_attr "cc" "clobber")])
622 ;; General move expanders
624 ;; "movqi" "movqq" "movuqq"
625 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
626 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
629 (define_expand "mov<mode>"
630 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
631 (match_operand:MOVMODE 1 "general_operand" ""))]
634 rtx dest = operands[0];
635 rtx src = avr_eval_addr_attrib (operands[1]);
637 if (avr_mem_flash_p (dest))
640 if (QImode == <MODE>mode
642 && CONSTANT_ADDRESS_P (SUBREG_REG (src))
643 && can_create_pseudo_p())
645 // store_bitfield may want to store a SYMBOL_REF or CONST in a
646 // structure that's represented as PSImode. As the upper 16 bits
647 // of PSImode cannot be expressed as an HImode subreg, the rhs is
648 // decomposed into QImode (word_mode) subregs of SYMBOL_REF,
649 // CONST or LABEL_REF; cf. PR71103.
651 rtx const_addr = SUBREG_REG (src);
652 operands[1] = src = copy_rtx (src);
653 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr);
656 /* One of the operands has to be in a register. */
657 if (!register_operand (dest, <MODE>mode)
658 && !reg_or_0_operand (src, <MODE>mode))
660 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
663 if (avr_mem_memx_p (src))
665 rtx addr = XEXP (src, 0);
668 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
670 if (!avr_xload_libgcc_p (<MODE>mode))
671 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
672 ; insn-emit does not depend on the mode, it's all about operands. */
673 emit_insn (gen_xload8qi_A (dest, src));
675 emit_insn (gen_xload<mode>_A (dest, src));
680 if (avr_load_libgcc_p (src))
682 /* For the small devices, do loads per libgcc call. */
683 emit_insn (gen_load<mode>_libgcc (dest, src));
688 ;;========================================================================
690 ;; The last alternative (any immediate constant to any register) is
691 ;; very expensive. It should be optimized by peephole2 if a scratch
692 ;; register is available, but then that register could just as well be
693 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
694 ;; are call-saved registers, and most of LD_REGS are call-used registers,
695 ;; so this may still be a win for registers live across function calls.
698 ;; "movqq_insn" "movuqq_insn"
699 (define_insn "mov<mode>_insn"
700 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
701 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
702 "register_operand (operands[0], <MODE>mode)
703 || reg_or_0_operand (operands[1], <MODE>mode)"
705 return output_movqi (insn, operands, NULL);
707 [(set_attr "length" "1,1,5,5,1,1,4")
708 (set_attr "adjust_len" "mov8")
709 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
711 ;; This is used in peephole2 to optimize loading immediate constants
712 ;; if a scratch register from LD_REGS happens to be available.
715 ;; "*reload_inqq" "*reload_inuqq"
716 (define_insn "*reload_in<mode>"
717 [(set (match_operand:ALL1 0 "register_operand" "=l")
718 (match_operand:ALL1 1 "const_operand" "i"))
719 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
723 [(set_attr "length" "2")
724 (set_attr "cc" "none")])
727 [(match_scratch:QI 2 "d")
728 (set (match_operand:ALL1 0 "l_register_operand" "")
729 (match_operand:ALL1 1 "const_operand" ""))]
730 ; No need for a clobber reg for 0x0, 0x01 or 0xff
731 "!satisfies_constraint_Y00 (operands[1])
732 && !satisfies_constraint_Y01 (operands[1])
733 && !satisfies_constraint_Ym1 (operands[1])"
734 [(parallel [(set (match_dup 0)
736 (clobber (match_dup 2))])])
738 ;;============================================================================
739 ;; move word (16 bit)
741 ;; Move register $1 to the Stack Pointer register SP.
742 ;; This insn is emit during function prologue/epilogue generation.
743 ;; $2 = 0: We know that IRQs are off
744 ;; $2 = 1: We know that IRQs are on
745 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
746 ;; $2 = -1: We don't know anything about IRQ on/off
747 ;; Always write SP via unspec, see PR50063
749 (define_insn "movhi_sp_r"
750 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
751 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
752 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
756 out %B0,%B1\;out %A0,%A1
757 cli\;out %B0,%B1\;sei\;out %A0,%A1
758 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
760 out %A0,%A1\;out %B0,%B1"
761 [(set_attr "length" "2,4,5,1,2")
762 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
763 (set_attr "cc" "none")])
766 [(match_scratch:QI 2 "d")
767 (set (match_operand:ALL2 0 "l_register_operand" "")
768 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
769 "operands[1] != CONST0_RTX (<MODE>mode)"
770 [(parallel [(set (match_dup 0)
772 (clobber (match_dup 2))])])
774 ;; '*' because it is not used in rtl generation, only in above peephole
776 ;; "*reload_inhq" "*reload_inuhq"
777 ;; "*reload_inha" "*reload_inuha"
778 (define_insn "*reload_in<mode>"
779 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
780 (match_operand:ALL2 1 "immediate_operand" "i"))
781 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
784 return output_reload_inhi (operands, operands[2], NULL);
786 [(set_attr "length" "4")
787 (set_attr "adjust_len" "reload_in16")
788 (set_attr "cc" "clobber")])
791 ;; "*movhq" "*movuhq"
792 ;; "*movha" "*movuha"
793 (define_insn "*mov<mode>"
794 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
795 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
796 "register_operand (operands[0], <MODE>mode)
797 || reg_or_0_operand (operands[1], <MODE>mode)"
799 return output_movhi (insn, operands, NULL);
801 [(set_attr "length" "2,2,6,7,2,6,5,2")
802 (set_attr "adjust_len" "mov16")
803 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
805 (define_peephole2 ; movw
806 [(set (match_operand:ALL1 0 "even_register_operand" "")
807 (match_operand:ALL1 1 "even_register_operand" ""))
808 (set (match_operand:ALL1 2 "odd_register_operand" "")
809 (match_operand:ALL1 3 "odd_register_operand" ""))]
811 && REGNO (operands[0]) == REGNO (operands[2]) - 1
812 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
816 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
817 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
820 (define_peephole2 ; movw_r
821 [(set (match_operand:ALL1 0 "odd_register_operand" "")
822 (match_operand:ALL1 1 "odd_register_operand" ""))
823 (set (match_operand:ALL1 2 "even_register_operand" "")
824 (match_operand:ALL1 3 "even_register_operand" ""))]
826 && REGNO (operands[2]) == REGNO (operands[0]) - 1
827 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
831 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
832 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
835 ;; For LPM loads from AS1 we split
839 ;; Z = Z - sizeof (R)
841 ;; so that the second instruction can be optimized out.
843 (define_split ; "split-lpmx"
844 [(set (match_operand:HISI 0 "register_operand" "")
845 (match_operand:HISI 1 "memory_operand" ""))]
851 (plus:HI (match_dup 3)
854 rtx addr = XEXP (operands[1], 0);
856 if (!avr_mem_flash_p (operands[1])
858 || reg_overlap_mentioned_p (addr, operands[0]))
863 operands[2] = replace_equiv_address (operands[1],
864 gen_rtx_POST_INC (Pmode, addr));
866 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
869 ;;==========================================================================
870 ;; xpointer move (24 bit)
872 (define_peephole2 ; *reload_inpsi
873 [(match_scratch:QI 2 "d")
874 (set (match_operand:PSI 0 "l_register_operand" "")
875 (match_operand:PSI 1 "immediate_operand" ""))
877 "operands[1] != const0_rtx
878 && operands[1] != constm1_rtx"
879 [(parallel [(set (match_dup 0)
881 (clobber (match_dup 2))])])
883 ;; '*' because it is not used in rtl generation.
884 (define_insn "*reload_inpsi"
885 [(set (match_operand:PSI 0 "register_operand" "=r")
886 (match_operand:PSI 1 "immediate_operand" "i"))
887 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
890 return avr_out_reload_inpsi (operands, operands[2], NULL);
892 [(set_attr "length" "6")
893 (set_attr "adjust_len" "reload_in24")
894 (set_attr "cc" "clobber")])
896 (define_insn "*movpsi"
897 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
898 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
899 "register_operand (operands[0], PSImode)
900 || register_operand (operands[1], PSImode)
901 || const0_rtx == operands[1]"
903 return avr_out_movpsi (insn, operands, NULL);
905 [(set_attr "length" "3,3,8,9,4,10")
906 (set_attr "adjust_len" "mov24")
907 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
909 ;;==========================================================================
910 ;; move double word (32 bit)
912 (define_peephole2 ; *reload_insi
913 [(match_scratch:QI 2 "d")
914 (set (match_operand:ALL4 0 "l_register_operand" "")
915 (match_operand:ALL4 1 "immediate_operand" ""))
917 "operands[1] != CONST0_RTX (<MODE>mode)"
918 [(parallel [(set (match_dup 0)
920 (clobber (match_dup 2))])])
922 ;; '*' because it is not used in rtl generation.
924 ;; "*reload_insq" "*reload_inusq"
925 ;; "*reload_insa" "*reload_inusa"
926 (define_insn "*reload_insi"
927 [(set (match_operand:ALL4 0 "register_operand" "=r")
928 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
929 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
932 return output_reload_insisf (operands, operands[2], NULL);
934 [(set_attr "length" "8")
935 (set_attr "adjust_len" "reload_in32")
936 (set_attr "cc" "clobber")])
940 ;; "*movsq" "*movusq"
941 ;; "*movsa" "*movusa"
942 (define_insn "*mov<mode>"
943 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
944 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
945 "register_operand (operands[0], <MODE>mode)
946 || reg_or_0_operand (operands[1], <MODE>mode)"
948 return output_movsisf (insn, operands, NULL);
950 [(set_attr "length" "4,4,8,9,4,10")
951 (set_attr "adjust_len" "mov32")
952 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
954 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
955 ;; move floating point numbers (32 bit)
957 (define_insn "*movsf"
958 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
959 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
960 "register_operand (operands[0], SFmode)
961 || reg_or_0_operand (operands[1], SFmode)"
963 return output_movsisf (insn, operands, NULL);
965 [(set_attr "length" "4,4,8,9,4,10")
966 (set_attr "adjust_len" "mov32")
967 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
969 (define_peephole2 ; *reload_insf
970 [(match_scratch:QI 2 "d")
971 (set (match_operand:SF 0 "l_register_operand" "")
972 (match_operand:SF 1 "const_double_operand" ""))
974 "operands[1] != CONST0_RTX (SFmode)"
975 [(parallel [(set (match_dup 0)
977 (clobber (match_dup 2))])])
979 ;; '*' because it is not used in rtl generation.
980 (define_insn "*reload_insf"
981 [(set (match_operand:SF 0 "register_operand" "=r")
982 (match_operand:SF 1 "const_double_operand" "F"))
983 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
986 return output_reload_insisf (operands, operands[2], NULL);
988 [(set_attr "length" "8")
989 (set_attr "adjust_len" "reload_in32")
990 (set_attr "cc" "clobber")])
992 ;;=========================================================================
993 ;; move string (like memcpy)
995 (define_expand "cpymemhi"
996 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
997 (match_operand:BLK 1 "memory_operand" ""))
998 (use (match_operand:HI 2 "const_int_operand" ""))
999 (use (match_operand:HI 3 "const_int_operand" ""))])]
1002 if (avr_emit_cpymemhi (operands))
1008 (define_mode_attr CPYMEM_r_d [(QI "r")
1011 ;; $0 : Address Space
1012 ;; $1, $2 : Loop register
1013 ;; R30 : source address
1014 ;; R26 : destination address
1018 (define_insn "cpymem_<mode>"
1019 [(set (mem:BLK (reg:HI REG_X))
1020 (mem:BLK (reg:HI REG_Z)))
1021 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1023 (use (match_operand:QIHI 1 "register_operand" "<CPYMEM_r_d>"))
1024 (clobber (reg:HI REG_X))
1025 (clobber (reg:HI REG_Z))
1026 (clobber (reg:QI LPM_REGNO))
1027 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
1030 return avr_out_cpymem (insn, operands, NULL);
1032 [(set_attr "adjust_len" "cpymem")
1033 (set_attr "cc" "clobber")])
1036 ;; $0 : Address Space
1037 ;; $1 : RAMPZ RAM address
1038 ;; R24 : #bytes and loop register
1039 ;; R23:Z : 24-bit source address
1040 ;; R26 : 16-bit destination address
1044 (define_insn "cpymemx_<mode>"
1045 [(set (mem:BLK (reg:HI REG_X))
1046 (mem:BLK (lo_sum:PSI (reg:QI 23)
1048 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1051 (clobber (reg:HI REG_X))
1052 (clobber (reg:HI REG_Z))
1053 (clobber (reg:QI LPM_REGNO))
1054 (clobber (reg:HI 24))
1055 (clobber (reg:QI 23))
1056 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
1058 "%~call __movmemx_<mode>"
1059 [(set_attr "type" "xcall")
1060 (set_attr "cc" "clobber")])
1063 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
1064 ;; memset (%0, %2, %1)
1066 (define_expand "setmemhi"
1067 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1068 (match_operand 2 "const_int_operand" ""))
1069 (use (match_operand:HI 1 "const_int_operand" ""))
1070 (use (match_operand:HI 3 "const_int_operand" ""))
1071 (clobber (match_scratch:HI 5 ""))
1072 (clobber (match_dup 4))])]
1078 /* If value to set is not zero, use the library routine. */
1079 if (operands[2] != const0_rtx)
1082 if (!CONST_INT_P (operands[1]))
1085 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1086 operands[4] = gen_rtx_SCRATCH (mode);
1087 operands[1] = copy_to_mode_reg (mode,
1088 gen_int_mode (INTVAL (operands[1]), mode));
1089 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1090 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1094 (define_insn "*clrmemqi"
1095 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1097 (use (match_operand:QI 1 "register_operand" "r"))
1098 (use (match_operand:QI 2 "const_int_operand" "n"))
1099 (clobber (match_scratch:HI 3 "=0"))
1100 (clobber (match_scratch:QI 4 "=&1"))]
1102 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1103 [(set_attr "length" "3")
1104 (set_attr "cc" "clobber")])
1107 (define_insn "*clrmemhi"
1108 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1110 (use (match_operand:HI 1 "register_operand" "!w,d"))
1111 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1112 (clobber (match_scratch:HI 3 "=0,0"))
1113 (clobber (match_scratch:HI 4 "=&1,&1"))]
1116 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1117 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1118 [(set_attr "length" "3,4")
1119 (set_attr "cc" "clobber,clobber")])
1121 (define_expand "strlenhi"
1123 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1124 (match_operand:QI 2 "const_int_operand" "")
1125 (match_operand:HI 3 "immediate_operand" "")]
1128 (plus:HI (match_dup 4)
1130 (parallel [(set (match_operand:HI 0 "register_operand" "")
1131 (minus:HI (match_dup 4)
1133 (clobber (scratch:QI))])]
1137 if (operands[2] != const0_rtx)
1139 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1140 operands[1] = gen_rtx_MEM (BLKmode, addr);
1142 operands[4] = gen_reg_rtx (HImode);
1145 (define_insn "*strlenhi"
1146 [(set (match_operand:HI 0 "register_operand" "=e")
1147 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1149 (match_operand:HI 2 "immediate_operand" "i")]
1152 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1153 [(set_attr "length" "3")
1154 (set_attr "cc" "clobber")])
1156 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1160 ;; "addqq3" "adduqq3"
1161 (define_insn "add<mode>3"
1162 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1163 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1164 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1173 [(set_attr "length" "1,1,1,1,2,2")
1174 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1177 ;; "addhq3" "adduhq3"
1178 ;; "addha3" "adduha3"
1179 (define_expand "add<mode>3"
1180 [(set (match_operand:ALL2 0 "register_operand" "")
1181 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1182 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1185 if (CONST_INT_P (operands[2]))
1187 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1189 if (can_create_pseudo_p()
1190 && !stack_register_operand (operands[0], HImode)
1191 && !stack_register_operand (operands[1], HImode)
1192 && !d_register_operand (operands[0], HImode)
1193 && !d_register_operand (operands[1], HImode))
1195 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1200 if (CONST_FIXED_P (operands[2]))
1202 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1208 (define_insn "*addhi3_zero_extend"
1209 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1210 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1211 (match_operand:HI 2 "register_operand" "0 ,r")))]
1214 add %A0,%1\;adc %B0,__zero_reg__
1215 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
1216 [(set_attr "length" "2,3")
1217 (set_attr "cc" "set_n")])
1219 (define_insn "*addhi3_zero_extend1"
1220 [(set (match_operand:HI 0 "register_operand" "=r")
1221 (plus:HI (match_operand:HI 1 "register_operand" "0")
1222 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1224 "add %A0,%2\;adc %B0,__zero_reg__"
1225 [(set_attr "length" "2")
1226 (set_attr "cc" "set_n")])
1228 (define_insn "*addhi3.sign_extend1"
1229 [(set (match_operand:HI 0 "register_operand" "=r")
1230 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1231 (match_operand:HI 2 "register_operand" "0")))]
1234 return reg_overlap_mentioned_p (operands[0], operands[1])
1235 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1236 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1238 [(set_attr "length" "5")
1239 (set_attr "cc" "clobber")])
1241 (define_insn "*addhi3_zero_extend.const"
1242 [(set (match_operand:HI 0 "register_operand" "=d")
1243 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1244 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
1246 "subi %A0,%n2\;sbc %B0,%B0"
1247 [(set_attr "length" "2")
1248 (set_attr "cc" "set_czn")])
1250 (define_insn "*usum_widenqihi3"
1251 [(set (match_operand:HI 0 "register_operand" "=r")
1252 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1253 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1255 "add %A0,%2\;clr %B0\;rol %B0"
1256 [(set_attr "length" "3")
1257 (set_attr "cc" "clobber")])
1259 (define_insn "*udiff_widenqihi3"
1260 [(set (match_operand:HI 0 "register_operand" "=r")
1261 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1262 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1264 "sub %A0,%2\;sbc %B0,%B0"
1265 [(set_attr "length" "2")
1266 (set_attr "cc" "set_czn")])
1268 (define_insn "*addhi3_sp"
1269 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1270 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1271 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1274 return avr_out_addto_sp (operands, NULL);
1276 [(set_attr "length" "6")
1277 (set_attr "adjust_len" "addto_sp")])
1280 ;; "*addhq3" "*adduhq3"
1281 ;; "*addha3" "*adduha3"
1282 (define_insn "*add<mode>3"
1283 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1284 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1285 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1288 return avr_out_plus (insn, operands);
1290 [(set_attr "length" "2")
1291 (set_attr "adjust_len" "plus")
1292 (set_attr "cc" "plus")])
1294 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1295 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1296 ;; itself because that insn is special to reload.
1298 (define_peephole2 ; addhi3_clobber
1299 [(set (match_operand:ALL2 0 "d_register_operand" "")
1300 (match_operand:ALL2 1 "const_operand" ""))
1301 (set (match_operand:ALL2 2 "l_register_operand" "")
1302 (plus:ALL2 (match_dup 2)
1304 "peep2_reg_dead_p (2, operands[0])"
1305 [(parallel [(set (match_dup 2)
1306 (plus:ALL2 (match_dup 2)
1308 (clobber (match_dup 3))])]
1310 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1313 ;; Same, but with reload to NO_LD_REGS
1314 ;; Combine *reload_inhi with *addhi3
1316 (define_peephole2 ; addhi3_clobber
1317 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1318 (match_operand:ALL2 1 "const_operand" ""))
1319 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1320 (set (match_operand:ALL2 3 "l_register_operand" "")
1321 (plus:ALL2 (match_dup 3)
1323 "peep2_reg_dead_p (2, operands[0])"
1324 [(parallel [(set (match_dup 3)
1325 (plus:ALL2 (match_dup 3)
1327 (clobber (match_dup 2))])])
1330 ;; "addhq3_clobber" "adduhq3_clobber"
1331 ;; "addha3_clobber" "adduha3_clobber"
1332 (define_insn "add<mode>3_clobber"
1333 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1334 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1335 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1336 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1339 return avr_out_plus (insn, operands);
1341 [(set_attr "length" "4")
1342 (set_attr "adjust_len" "plus")
1343 (set_attr "cc" "plus")])
1347 ;; "addsq3" "addusq3"
1348 ;; "addsa3" "addusa3"
1349 (define_insn "add<mode>3"
1350 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1351 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1352 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1353 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1356 return avr_out_plus (insn, operands);
1358 [(set_attr "length" "4")
1359 (set_attr "adjust_len" "plus")
1360 (set_attr "cc" "plus")])
1362 (define_insn "*addpsi3_zero_extend.qi"
1363 [(set (match_operand:PSI 0 "register_operand" "=r")
1364 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1365 (match_operand:PSI 2 "register_operand" "0")))]
1367 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1368 [(set_attr "length" "3")
1369 (set_attr "cc" "set_n")])
1371 (define_insn "*addpsi3_zero_extend.hi"
1372 [(set (match_operand:PSI 0 "register_operand" "=r")
1373 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1374 (match_operand:PSI 2 "register_operand" "0")))]
1376 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1377 [(set_attr "length" "3")
1378 (set_attr "cc" "set_n")])
1380 (define_insn "*addpsi3_sign_extend.hi"
1381 [(set (match_operand:PSI 0 "register_operand" "=r")
1382 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1383 (match_operand:PSI 2 "register_operand" "0")))]
1385 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1386 [(set_attr "length" "5")
1387 (set_attr "cc" "set_n")])
1389 (define_insn "*addsi3_zero_extend"
1390 [(set (match_operand:SI 0 "register_operand" "=r")
1391 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1392 (match_operand:SI 2 "register_operand" "0")))]
1394 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1395 [(set_attr "length" "4")
1396 (set_attr "cc" "set_n")])
1398 (define_insn "*addsi3_zero_extend.hi"
1399 [(set (match_operand:SI 0 "register_operand" "=r")
1400 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1401 (match_operand:SI 2 "register_operand" "0")))]
1403 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1404 [(set_attr "length" "4")
1405 (set_attr "cc" "set_n")])
1407 (define_insn "addpsi3"
1408 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1409 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1410 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1411 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1414 return avr_out_plus (insn, operands);
1416 [(set_attr "length" "3")
1417 (set_attr "adjust_len" "plus")
1418 (set_attr "cc" "plus")])
1420 (define_insn "subpsi3"
1421 [(set (match_operand:PSI 0 "register_operand" "=r")
1422 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1423 (match_operand:PSI 2 "register_operand" "r")))]
1425 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1426 [(set_attr "length" "3")
1427 (set_attr "cc" "set_czn")])
1429 (define_insn "*subpsi3_zero_extend.qi"
1430 [(set (match_operand:PSI 0 "register_operand" "=r")
1431 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1432 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1434 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1435 [(set_attr "length" "3")
1436 (set_attr "cc" "set_czn")])
1438 (define_insn "*subpsi3_zero_extend.hi"
1439 [(set (match_operand:PSI 0 "register_operand" "=r")
1440 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1441 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1443 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1444 [(set_attr "length" "3")
1445 (set_attr "cc" "set_czn")])
1447 (define_insn "*subpsi3_sign_extend.hi"
1448 [(set (match_operand:PSI 0 "register_operand" "=r")
1449 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1450 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1452 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1453 [(set_attr "length" "5")
1454 (set_attr "cc" "set_czn")])
1456 ;-----------------------------------------------------------------------------
1460 ;; "subqq3" "subuqq3"
1461 (define_insn "sub<mode>3"
1462 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1463 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1464 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1473 [(set_attr "length" "1,1,1,1,2,2")
1474 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1477 ;; "subhq3" "subuhq3"
1478 ;; "subha3" "subuha3"
1479 (define_insn "sub<mode>3"
1480 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1481 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1482 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1483 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1486 return avr_out_plus (insn, operands);
1488 [(set_attr "adjust_len" "plus")
1489 (set_attr "cc" "plus")])
1491 (define_insn "*subhi3_zero_extend1"
1492 [(set (match_operand:HI 0 "register_operand" "=r")
1493 (minus:HI (match_operand:HI 1 "register_operand" "0")
1494 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1496 "sub %A0,%2\;sbc %B0,__zero_reg__"
1497 [(set_attr "length" "2")
1498 (set_attr "cc" "set_czn")])
1500 (define_insn "*subhi3.sign_extend2"
1501 [(set (match_operand:HI 0 "register_operand" "=r")
1502 (minus:HI (match_operand:HI 1 "register_operand" "0")
1503 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1506 return reg_overlap_mentioned_p (operands[0], operands[2])
1507 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1508 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1510 [(set_attr "length" "5")
1511 (set_attr "cc" "clobber")])
1514 ;; "subsq3" "subusq3"
1515 ;; "subsa3" "subusa3"
1516 (define_insn "sub<mode>3"
1517 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1518 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1519 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1520 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1523 return avr_out_plus (insn, operands);
1525 [(set_attr "adjust_len" "plus")
1526 (set_attr "cc" "plus")])
1528 (define_insn "*subsi3_zero_extend"
1529 [(set (match_operand:SI 0 "register_operand" "=r")
1530 (minus:SI (match_operand:SI 1 "register_operand" "0")
1531 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1533 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1534 [(set_attr "length" "4")
1535 (set_attr "cc" "set_czn")])
1537 (define_insn "*subsi3_zero_extend.hi"
1538 [(set (match_operand:SI 0 "register_operand" "=r")
1539 (minus:SI (match_operand:SI 1 "register_operand" "0")
1540 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1542 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1543 [(set_attr "length" "4")
1544 (set_attr "cc" "set_czn")])
1546 ;******************************************************************************
1549 (define_expand "mulqi3"
1550 [(set (match_operand:QI 0 "register_operand" "")
1551 (mult:QI (match_operand:QI 1 "register_operand" "")
1552 (match_operand:QI 2 "register_operand" "")))]
1557 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1562 (define_insn "*mulqi3_enh"
1563 [(set (match_operand:QI 0 "register_operand" "=r")
1564 (mult:QI (match_operand:QI 1 "register_operand" "r")
1565 (match_operand:QI 2 "register_operand" "r")))]
1570 [(set_attr "length" "3")
1571 (set_attr "cc" "clobber")])
1573 (define_expand "mulqi3_call"
1574 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1575 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1576 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1577 (clobber (reg:QI 22))])
1578 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1581 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
1584 (define_insn "*mulqi3_call"
1585 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1586 (clobber (reg:QI 22))]
1589 [(set_attr "type" "xcall")
1590 (set_attr "cc" "clobber")])
1592 ;; "umulqi3_highpart"
1593 ;; "smulqi3_highpart"
1594 (define_insn "<extend_su>mulqi3_highpart"
1595 [(set (match_operand:QI 0 "register_operand" "=r")
1597 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1598 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1601 "mul<extend_s> %1,%2
1604 [(set_attr "length" "3")
1605 (set_attr "cc" "clobber")])
1608 ;; Used when expanding div or mod inline for some special values
1609 (define_insn "*subqi3.ashiftrt7"
1610 [(set (match_operand:QI 0 "register_operand" "=r")
1611 (minus:QI (match_operand:QI 1 "register_operand" "0")
1612 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1616 [(set_attr "length" "2")
1617 (set_attr "cc" "clobber")])
1619 (define_insn "*addqi3.lt0"
1620 [(set (match_operand:QI 0 "register_operand" "=r")
1621 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1623 (match_operand:QI 2 "register_operand" "0")))]
1626 [(set_attr "length" "2")
1627 (set_attr "cc" "clobber")])
1629 (define_insn "*addhi3.lt0"
1630 [(set (match_operand:HI 0 "register_operand" "=w,r")
1631 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1633 (match_operand:HI 2 "register_operand" "0,0")))
1634 (clobber (match_scratch:QI 3 "=X,&1"))]
1637 sbrc %1,7\;adiw %0,1
1638 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1639 [(set_attr "length" "2,3")
1640 (set_attr "cc" "clobber")])
1642 (define_insn "*addpsi3.lt0"
1643 [(set (match_operand:PSI 0 "register_operand" "=r")
1644 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1646 (match_operand:PSI 2 "register_operand" "0")))]
1648 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1649 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1650 [(set_attr "length" "5")
1651 (set_attr "cc" "clobber")])
1653 (define_insn "*addsi3.lt0"
1654 [(set (match_operand:SI 0 "register_operand" "=r")
1655 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1657 (match_operand:SI 2 "register_operand" "0")))]
1659 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1660 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1661 [(set_attr "length" "6")
1662 (set_attr "cc" "clobber")])
1664 (define_insn "*umulqihi3.call"
1666 (mult:HI (zero_extend:HI (reg:QI 22))
1667 (zero_extend:HI (reg:QI 24))))
1668 (clobber (reg:QI 21))
1669 (clobber (reg:HI 22))]
1671 "%~call __umulqihi3"
1672 [(set_attr "type" "xcall")
1673 (set_attr "cc" "clobber")])
1677 (define_insn "<extend_u>mulqihi3"
1678 [(set (match_operand:HI 0 "register_operand" "=r")
1679 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1680 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1682 "mul<extend_s> %1,%2
1685 [(set_attr "length" "3")
1686 (set_attr "cc" "clobber")])
1688 (define_insn "usmulqihi3"
1689 [(set (match_operand:HI 0 "register_operand" "=r")
1690 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1691 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1696 [(set_attr "length" "3")
1697 (set_attr "cc" "clobber")])
1699 ;; Above insn is not canonicalized by insn combine, so here is a version with
1700 ;; operands swapped.
1702 (define_insn "*sumulqihi3"
1703 [(set (match_operand:HI 0 "register_operand" "=r")
1704 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1705 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1710 [(set_attr "length" "3")
1711 (set_attr "cc" "clobber")])
1713 ;; One-extend operand 1
1715 (define_insn "*osmulqihi3"
1716 [(set (match_operand:HI 0 "register_operand" "=&r")
1717 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1718 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1724 [(set_attr "length" "4")
1725 (set_attr "cc" "clobber")])
1727 (define_insn "*oumulqihi3"
1728 [(set (match_operand:HI 0 "register_operand" "=&r")
1729 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1730 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1736 [(set_attr "length" "4")
1737 (set_attr "cc" "clobber")])
1739 ;******************************************************************************
1740 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1741 ;******************************************************************************
1743 (define_insn "*maddqi4"
1744 [(set (match_operand:QI 0 "register_operand" "=r")
1745 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1746 (match_operand:QI 2 "register_operand" "r"))
1747 (match_operand:QI 3 "register_operand" "0")))]
1753 [(set_attr "length" "4")
1754 (set_attr "cc" "clobber")])
1756 (define_insn "*msubqi4"
1757 [(set (match_operand:QI 0 "register_operand" "=r")
1758 (minus:QI (match_operand:QI 3 "register_operand" "0")
1759 (mult:QI (match_operand:QI 1 "register_operand" "r")
1760 (match_operand:QI 2 "register_operand" "r"))))]
1765 [(set_attr "length" "4")
1766 (set_attr "cc" "clobber")])
1768 (define_insn_and_split "*maddqi4.const"
1769 [(set (match_operand:QI 0 "register_operand" "=r")
1770 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1771 (match_operand:QI 2 "const_int_operand" "n"))
1772 (match_operand:QI 3 "register_operand" "0")))
1773 (clobber (match_scratch:QI 4 "=&d"))]
1776 "&& reload_completed"
1781 (plus:QI (mult:QI (match_dup 1)
1785 (define_insn_and_split "*msubqi4.const"
1786 [(set (match_operand:QI 0 "register_operand" "=r")
1787 (minus:QI (match_operand:QI 3 "register_operand" "0")
1788 (mult:QI (match_operand:QI 1 "register_operand" "r")
1789 (match_operand:QI 2 "const_int_operand" "n"))))
1790 (clobber (match_scratch:QI 4 "=&d"))]
1793 "&& reload_completed"
1798 (minus:QI (match_dup 3)
1799 (mult:QI (match_dup 1)
1803 ;******************************************************************************
1804 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1805 ;******************************************************************************
1807 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1810 ;; int foo (unsigned char z)
1812 ;; extern int aInt[];
1813 ;; return aInt[3*z+2];
1816 ;; because the constant +4 then is added explicitely instead of consuming it
1817 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1818 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1819 ;; The implementational effort is the same so we are fine with that approach.
1824 (define_insn "*<extend_u>maddqihi4"
1825 [(set (match_operand:HI 0 "register_operand" "=r")
1826 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1827 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1828 (match_operand:HI 3 "register_operand" "0")))]
1831 "mul<extend_s> %1,%2
1835 [(set_attr "length" "4")
1836 (set_attr "cc" "clobber")])
1840 (define_insn "*<extend_u>msubqihi4"
1841 [(set (match_operand:HI 0 "register_operand" "=r")
1842 (minus:HI (match_operand:HI 3 "register_operand" "0")
1843 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1844 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1846 "mul<extend_s> %1,%2
1850 [(set_attr "length" "4")
1851 (set_attr "cc" "clobber")])
1855 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1856 [(set (match_operand:HI 0 "register_operand" "=r")
1857 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1858 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1859 (match_operand:HI 3 "register_operand" "0")))]
1862 && <any_extend:CODE> != <any_extend2:CODE>"
1864 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1865 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1867 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1869 [(set_attr "length" "4")
1870 (set_attr "cc" "clobber")])
1874 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1875 [(set (match_operand:HI 0 "register_operand" "=r")
1876 (minus:HI (match_operand:HI 3 "register_operand" "0")
1877 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1878 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1881 && <any_extend:CODE> != <any_extend2:CODE>"
1883 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1884 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1886 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1888 [(set_attr "length" "4")
1889 (set_attr "cc" "clobber")])
1891 ;; Handle small constants
1893 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1894 ;; This is shorter, faster than MUL and has lower register pressure.
1896 (define_insn_and_split "*umaddqihi4.2"
1897 [(set (match_operand:HI 0 "register_operand" "=r")
1898 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1900 (match_operand:HI 2 "register_operand" "r")))]
1902 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1903 { gcc_unreachable(); }
1907 ; *addhi3_zero_extend
1909 (plus:HI (zero_extend:HI (match_dup 1))
1911 ; *addhi3_zero_extend
1913 (plus:HI (zero_extend:HI (match_dup 1))
1916 ;; "umaddqihi4.uconst"
1917 ;; "maddqihi4.sconst"
1918 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1919 [(set (match_operand:HI 0 "register_operand" "=r")
1920 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1921 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1922 (match_operand:HI 3 "register_operand" "0")))
1923 (clobber (match_scratch:QI 4 "=&d"))]
1926 "&& reload_completed"
1929 ; *umaddqihi4 resp. *maddqihi4
1931 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1932 (any_extend:HI (match_dup 4)))
1935 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1938 ;; "*umsubqihi4.uconst"
1939 ;; "*msubqihi4.sconst"
1940 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1941 [(set (match_operand:HI 0 "register_operand" "=r")
1942 (minus:HI (match_operand:HI 3 "register_operand" "0")
1943 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1944 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1945 (clobber (match_scratch:QI 4 "=&d"))]
1948 "&& reload_completed"
1951 ; *umsubqihi4 resp. *msubqihi4
1953 (minus:HI (match_dup 3)
1954 (mult:HI (any_extend:HI (match_dup 1))
1955 (any_extend:HI (match_dup 4)))))]
1957 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1960 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1961 ;; for MULT with power of 2 and skips trying MULT insn above.
1963 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1964 [(set (match_operand:HI 0 "register_operand" "=r")
1965 (minus:HI (match_operand:HI 3 "register_operand" "0")
1966 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1967 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1968 (clobber (match_scratch:QI 4 "=&d"))]
1971 "&& reload_completed"
1976 (minus:HI (match_dup 3)
1977 (mult:HI (zero_extend:HI (match_dup 1))
1978 (zero_extend:HI (match_dup 4)))))]
1980 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1983 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1984 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1985 ;; because this would require an extra pattern for just one value.
1987 (define_insn_and_split "*msubqihi4.sconst.ashift"
1988 [(set (match_operand:HI 0 "register_operand" "=r")
1989 (minus:HI (match_operand:HI 3 "register_operand" "0")
1990 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1991 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1992 (clobber (match_scratch:QI 4 "=&d"))]
1995 "&& reload_completed"
2000 (minus:HI (match_dup 3)
2001 (mult:HI (sign_extend:HI (match_dup 1))
2002 (sign_extend:HI (match_dup 4)))))]
2004 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2007 ;; For signed/unsigned combinations that require narrow constraint "a"
2008 ;; just provide a pattern if signed/unsigned combination is actually needed.
2010 (define_insn_and_split "*sumaddqihi4.uconst"
2011 [(set (match_operand:HI 0 "register_operand" "=r")
2012 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2013 (match_operand:HI 2 "u8_operand" "M"))
2014 (match_operand:HI 3 "register_operand" "0")))
2015 (clobber (match_scratch:QI 4 "=&a"))]
2017 && !s8_operand (operands[2], VOIDmode)"
2019 "&& reload_completed"
2024 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
2025 (zero_extend:HI (match_dup 4)))
2028 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2031 (define_insn_and_split "*sumsubqihi4.uconst"
2032 [(set (match_operand:HI 0 "register_operand" "=r")
2033 (minus:HI (match_operand:HI 3 "register_operand" "0")
2034 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2035 (match_operand:HI 2 "u8_operand" "M"))))
2036 (clobber (match_scratch:QI 4 "=&a"))]
2038 && !s8_operand (operands[2], VOIDmode)"
2040 "&& reload_completed"
2045 (minus:HI (match_dup 3)
2046 (mult:HI (sign_extend:HI (match_dup 1))
2047 (zero_extend:HI (match_dup 4)))))]
2049 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2052 ;******************************************************************************
2053 ; mul HI: $1 = sign/zero-extend, $2 = small constant
2054 ;******************************************************************************
2056 ;; "*muluqihi3.uconst"
2057 ;; "*mulsqihi3.sconst"
2058 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
2059 [(set (match_operand:HI 0 "register_operand" "=r")
2060 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2061 (match_operand:HI 2 "<extend_su>8_operand" "n")))
2062 (clobber (match_scratch:QI 3 "=&d"))]
2065 "&& reload_completed"
2068 ; umulqihi3 resp. mulqihi3
2070 (mult:HI (any_extend:HI (match_dup 1))
2071 (any_extend:HI (match_dup 3))))]
2073 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2076 (define_insn_and_split "*muluqihi3.sconst"
2077 [(set (match_operand:HI 0 "register_operand" "=r")
2078 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2079 (match_operand:HI 2 "s8_operand" "n")))
2080 (clobber (match_scratch:QI 3 "=&a"))]
2083 "&& reload_completed"
2088 (mult:HI (zero_extend:HI (match_dup 1))
2089 (sign_extend:HI (match_dup 3))))]
2091 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2094 (define_insn_and_split "*mulsqihi3.uconst"
2095 [(set (match_operand:HI 0 "register_operand" "=r")
2096 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2097 (match_operand:HI 2 "u8_operand" "M")))
2098 (clobber (match_scratch:QI 3 "=&a"))]
2101 "&& reload_completed"
2106 (mult:HI (zero_extend:HI (match_dup 3))
2107 (sign_extend:HI (match_dup 1))))]
2109 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2112 (define_insn_and_split "*mulsqihi3.oconst"
2113 [(set (match_operand:HI 0 "register_operand" "=&r")
2114 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2115 (match_operand:HI 2 "o8_operand" "n")))
2116 (clobber (match_scratch:QI 3 "=&a"))]
2119 "&& reload_completed"
2124 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2125 (sign_extend:HI (match_dup 1))))]
2127 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2130 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2131 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2132 ;; at that time. Fix that.
2134 (define_insn "*ashiftqihi2.signx.1"
2135 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2136 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2140 lsl %A0\;sbc %B0,%B0
2141 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2142 [(set_attr "length" "2,3")
2143 (set_attr "cc" "clobber")])
2145 (define_insn_and_split "*ashifthi3.signx.const"
2146 [(set (match_operand:HI 0 "register_operand" "=r")
2147 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2148 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2149 (clobber (match_scratch:QI 3 "=&d"))]
2152 "&& reload_completed"
2157 (mult:HI (sign_extend:HI (match_dup 1))
2158 (sign_extend:HI (match_dup 3))))]
2160 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2163 (define_insn_and_split "*ashifthi3.signx.const7"
2164 [(set (match_operand:HI 0 "register_operand" "=r")
2165 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2167 (clobber (match_scratch:QI 2 "=&a"))]
2170 "&& reload_completed"
2175 (mult:HI (zero_extend:HI (match_dup 2))
2176 (sign_extend:HI (match_dup 1))))]
2178 operands[3] = gen_int_mode (1 << 7, QImode);
2181 (define_insn_and_split "*ashifthi3.zerox.const"
2182 [(set (match_operand:HI 0 "register_operand" "=r")
2183 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2184 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2185 (clobber (match_scratch:QI 3 "=&d"))]
2188 "&& reload_completed"
2193 (mult:HI (zero_extend:HI (match_dup 1))
2194 (zero_extend:HI (match_dup 3))))]
2196 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2199 ;******************************************************************************
2200 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2201 ;******************************************************************************
2203 (define_insn "mulsqihi3"
2204 [(set (match_operand:HI 0 "register_operand" "=&r")
2205 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2206 (match_operand:HI 2 "register_operand" "a")))]
2213 [(set_attr "length" "5")
2214 (set_attr "cc" "clobber")])
2216 (define_insn "muluqihi3"
2217 [(set (match_operand:HI 0 "register_operand" "=&r")
2218 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2219 (match_operand:HI 2 "register_operand" "r")))]
2226 [(set_attr "length" "5")
2227 (set_attr "cc" "clobber")])
2229 ;; one-extend operand 1
2231 (define_insn "muloqihi3"
2232 [(set (match_operand:HI 0 "register_operand" "=&r")
2233 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2234 (match_operand:HI 2 "register_operand" "r")))]
2242 [(set_attr "length" "6")
2243 (set_attr "cc" "clobber")])
2245 ;******************************************************************************
2247 (define_expand "mulhi3"
2248 [(set (match_operand:HI 0 "register_operand" "")
2249 (mult:HI (match_operand:HI 1 "register_operand" "")
2250 (match_operand:HI 2 "register_or_s9_operand" "")))]
2255 if (!register_operand (operands[2], HImode))
2256 operands[2] = force_reg (HImode, operands[2]);
2258 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2262 /* ; For small constants we can do better by extending them on the fly.
2263 ; The constant can be loaded in one instruction and the widening
2264 ; multiplication is shorter. First try the unsigned variant because it
2265 ; allows constraint "d" instead of "a" for the signed version. */
2267 if (s9_operand (operands[2], HImode))
2269 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2271 if (u8_operand (operands[2], HImode))
2273 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2275 else if (s8_operand (operands[2], HImode))
2277 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2281 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2287 if (!register_operand (operands[2], HImode))
2288 operands[2] = force_reg (HImode, operands[2]);
2291 (define_insn "*mulhi3_enh"
2292 [(set (match_operand:HI 0 "register_operand" "=&r")
2293 (mult:HI (match_operand:HI 1 "register_operand" "r")
2294 (match_operand:HI 2 "register_operand" "r")))]
2297 return REGNO (operands[1]) == REGNO (operands[2])
2298 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2299 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2301 [(set_attr "length" "7")
2302 (set_attr "cc" "clobber")])
2304 (define_expand "mulhi3_call"
2305 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2306 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2307 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2308 (clobber (reg:HI 22))
2309 (clobber (reg:QI 21))])
2310 (set (match_operand:HI 0 "register_operand" "")
2314 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
2318 (define_insn "*mulhi3_call"
2319 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2320 (clobber (reg:HI 22))
2321 (clobber (reg:QI 21))]
2324 [(set_attr "type" "xcall")
2325 (set_attr "cc" "clobber")])
2327 ;; To support widening multiplication with constant we postpone
2328 ;; expanding to the implicit library call until post combine and
2329 ;; prior to register allocation. Clobber all hard registers that
2330 ;; might be used by the (widening) multiply until it is split and
2331 ;; it's final register footprint is worked out.
2333 (define_expand "mulsi3"
2334 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2335 (mult:SI (match_operand:SI 1 "register_operand" "")
2336 (match_operand:SI 2 "nonmemory_operand" "")))
2337 (clobber (reg:HI 26))
2338 (clobber (reg:DI 18))])]
2341 if (u16_operand (operands[2], SImode))
2343 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2344 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2348 if (o16_operand (operands[2], SImode))
2350 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2351 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2355 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
2356 regmask (DImode, 18) | regmask (HImode, 26)))
2360 (define_insn_and_split "*mulsi3"
2361 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2362 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2363 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2364 (clobber (reg:HI 26))
2365 (clobber (reg:DI 18))]
2366 "AVR_HAVE_MUL && !reload_completed"
2367 { gcc_unreachable(); }
2373 (parallel [(set (reg:SI 22)
2374 (mult:SI (reg:SI 22)
2376 (clobber (reg:HI 26))])
2380 if (u16_operand (operands[2], SImode))
2382 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2383 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2387 if (o16_operand (operands[2], SImode))
2389 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2390 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2397 (define_expand "mulu<mode>si3"
2398 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2399 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
2400 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2401 (clobber (reg:HI 26))
2402 (clobber (reg:DI 18))])]
2405 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2406 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
2407 regmask (DImode, 18) | regmask (HImode, 26)))
2413 (define_insn_and_split "*mulu<mode>si3"
2414 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2415 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2416 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2417 (clobber (reg:HI 26))
2418 (clobber (reg:DI 18))]
2419 "AVR_HAVE_MUL && !reload_completed"
2420 { gcc_unreachable(); }
2427 (mult:SI (zero_extend:SI (reg:HI 26))
2432 /* Do the QI -> HI extension explicitely before the multiplication. */
2433 /* Do the HI -> SI extension implicitely and after the multiplication. */
2435 if (QImode == <MODE>mode)
2436 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2438 if (u16_operand (operands[2], SImode))
2440 operands[1] = force_reg (HImode, operands[1]);
2441 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2442 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2449 (define_expand "muls<mode>si3"
2450 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2451 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
2452 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2453 (clobber (reg:HI 26))
2454 (clobber (reg:DI 18))])]
2457 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2458 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
2459 regmask (DImode, 18) | regmask (HImode, 26)))
2465 (define_insn_and_split "*muls<mode>si3"
2466 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2467 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2468 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2469 (clobber (reg:HI 26))
2470 (clobber (reg:DI 18))]
2471 "AVR_HAVE_MUL && !reload_completed"
2472 { gcc_unreachable(); }
2479 (mult:SI (sign_extend:SI (reg:HI 26))
2484 /* Do the QI -> HI extension explicitely before the multiplication. */
2485 /* Do the HI -> SI extension implicitely and after the multiplication. */
2487 if (QImode == <MODE>mode)
2488 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2490 if (u16_operand (operands[2], SImode)
2491 || s16_operand (operands[2], SImode))
2493 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2495 operands[1] = force_reg (HImode, operands[1]);
2497 if (u16_operand (operands[2], SImode))
2498 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2500 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2506 ;; One-extend operand 1
2508 (define_expand "mulohisi3"
2509 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2510 (mult:SI (not:SI (zero_extend:SI
2511 (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
2512 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2513 (clobber (reg:HI 26))
2514 (clobber (reg:DI 18))])]
2517 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2518 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
2519 regmask (DImode, 18) | regmask (HImode, 26)))
2523 (define_insn_and_split "*mulohisi3"
2524 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2525 (mult:SI (not:SI (zero_extend:SI
2526 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2527 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2528 (clobber (reg:HI 26))
2529 (clobber (reg:DI 18))]
2530 "AVR_HAVE_MUL && !reload_completed"
2531 { gcc_unreachable(); }
2538 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2545 (define_expand "<extend_u>mulhisi3"
2546 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2547 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2548 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2549 (clobber (reg:HI 26))
2550 (clobber (reg:DI 18))])]
2553 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
2554 regmask (DImode, 18) | regmask (HImode, 26)))
2558 (define_expand "usmulhisi3"
2559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2560 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2561 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2562 (clobber (reg:HI 26))
2563 (clobber (reg:DI 18))])]
2566 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
2567 regmask (DImode, 18) | regmask (HImode, 26)))
2571 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2572 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2573 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2574 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2575 (define_insn_and_split
2576 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2577 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2578 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2579 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2580 (clobber (reg:HI 26))
2581 (clobber (reg:DI 18))]
2582 "AVR_HAVE_MUL && !reload_completed"
2583 { gcc_unreachable(); }
2590 (mult:SI (match_dup 3)
2595 rtx xop1 = operands[1];
2596 rtx xop2 = operands[2];
2598 /* Do the QI -> HI extension explicitely before the multiplication. */
2599 /* Do the HI -> SI extension implicitely and after the multiplication. */
2601 if (QImode == <QIHI:MODE>mode)
2602 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2604 if (QImode == <QIHI2:MODE>mode)
2605 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2607 if (<any_extend:CODE> == <any_extend2:CODE>
2608 || <any_extend:CODE> == ZERO_EXTEND)
2612 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2613 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2617 /* <any_extend:CODE> = SIGN_EXTEND */
2618 /* <any_extend2:CODE> = ZERO_EXTEND */
2622 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2623 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2627 ;; "smulhi3_highpart"
2628 ;; "umulhi3_highpart"
2629 (define_expand "<extend_su>mulhi3_highpart"
2631 (match_operand:HI 1 "nonmemory_operand" ""))
2633 (match_operand:HI 2 "nonmemory_operand" ""))
2634 (parallel [(set (reg:HI 24)
2635 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2636 (any_extend:SI (reg:HI 26)))
2638 (clobber (reg:HI 22))])
2639 (set (match_operand:HI 0 "register_operand" "")
2643 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
2647 (define_insn "*mulsi3_call"
2649 (mult:SI (reg:SI 22)
2651 (clobber (reg:HI 26))]
2654 [(set_attr "type" "xcall")
2655 (set_attr "cc" "clobber")])
2658 ;; "*umulhisi3_call"
2659 (define_insn "*<extend_u>mulhisi3_call"
2661 (mult:SI (any_extend:SI (reg:HI 18))
2662 (any_extend:SI (reg:HI 26))))]
2664 "%~call __<extend_u>mulhisi3"
2665 [(set_attr "type" "xcall")
2666 (set_attr "cc" "clobber")])
2668 ;; "*umulhi3_highpart_call"
2669 ;; "*smulhi3_highpart_call"
2670 (define_insn "*<extend_su>mulhi3_highpart_call"
2672 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2673 (any_extend:SI (reg:HI 26)))
2675 (clobber (reg:HI 22))]
2677 "%~call __<extend_u>mulhisi3"
2678 [(set_attr "type" "xcall")
2679 (set_attr "cc" "clobber")])
2681 (define_insn "*usmulhisi3_call"
2683 (mult:SI (zero_extend:SI (reg:HI 18))
2684 (sign_extend:SI (reg:HI 26))))]
2686 "%~call __usmulhisi3"
2687 [(set_attr "type" "xcall")
2688 (set_attr "cc" "clobber")])
2690 (define_insn "*mul<extend_su>hisi3_call"
2692 (mult:SI (any_extend:SI (reg:HI 26))
2695 "%~call __mul<extend_su>hisi3"
2696 [(set_attr "type" "xcall")
2697 (set_attr "cc" "clobber")])
2699 (define_insn "*mulohisi3_call"
2701 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2704 "%~call __mulohisi3"
2705 [(set_attr "type" "xcall")
2706 (set_attr "cc" "clobber")])
2708 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2711 ;; Generate lib1funcs.S calls ourselves, because:
2712 ;; - we know exactly which registers are clobbered (for QI and HI
2713 ;; modes, some of the call-used registers are preserved)
2714 ;; - we get both the quotient and the remainder at no extra cost
2715 ;; - we split the patterns only after the first CSE passes because
2716 ;; CSE has problems to operate on hard regs.
2718 (define_insn_and_split "divmodqi4"
2719 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2720 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2721 (match_operand:QI 2 "pseudo_register_operand" "")))
2722 (set (match_operand:QI 3 "pseudo_register_operand" "")
2723 (mod:QI (match_dup 1) (match_dup 2)))
2724 (clobber (reg:QI 22))
2725 (clobber (reg:QI 23))
2726 (clobber (reg:QI 24))
2727 (clobber (reg:QI 25))])]
2729 "this divmodqi4 pattern should have been splitted;"
2731 [(set (reg:QI 24) (match_dup 1))
2732 (set (reg:QI 22) (match_dup 2))
2733 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2734 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2735 (clobber (reg:QI 22))
2736 (clobber (reg:QI 23))])
2737 (set (match_dup 0) (reg:QI 24))
2738 (set (match_dup 3) (reg:QI 25))])
2740 (define_insn "*divmodqi4_call"
2741 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2742 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2743 (clobber (reg:QI 22))
2744 (clobber (reg:QI 23))]
2746 "%~call __divmodqi4"
2747 [(set_attr "type" "xcall")
2748 (set_attr "cc" "clobber")])
2750 (define_insn_and_split "udivmodqi4"
2751 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2752 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2753 (match_operand:QI 2 "pseudo_register_operand" "")))
2754 (set (match_operand:QI 3 "pseudo_register_operand" "")
2755 (umod:QI (match_dup 1) (match_dup 2)))
2756 (clobber (reg:QI 22))
2757 (clobber (reg:QI 23))
2758 (clobber (reg:QI 24))
2759 (clobber (reg:QI 25))])]
2761 "this udivmodqi4 pattern should have been splitted;"
2763 [(set (reg:QI 24) (match_dup 1))
2764 (set (reg:QI 22) (match_dup 2))
2765 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2766 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2767 (clobber (reg:QI 23))])
2768 (set (match_dup 0) (reg:QI 24))
2769 (set (match_dup 3) (reg:QI 25))])
2771 (define_insn "*udivmodqi4_call"
2772 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2773 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2774 (clobber (reg:QI 23))]
2776 "%~call __udivmodqi4"
2777 [(set_attr "type" "xcall")
2778 (set_attr "cc" "clobber")])
2780 (define_insn_and_split "divmodhi4"
2781 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2782 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2783 (match_operand:HI 2 "pseudo_register_operand" "")))
2784 (set (match_operand:HI 3 "pseudo_register_operand" "")
2785 (mod:HI (match_dup 1) (match_dup 2)))
2786 (clobber (reg:QI 21))
2787 (clobber (reg:HI 22))
2788 (clobber (reg:HI 24))
2789 (clobber (reg:HI 26))])]
2791 "this should have been splitted;"
2793 [(set (reg:HI 24) (match_dup 1))
2794 (set (reg:HI 22) (match_dup 2))
2795 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2796 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2797 (clobber (reg:HI 26))
2798 (clobber (reg:QI 21))])
2799 (set (match_dup 0) (reg:HI 22))
2800 (set (match_dup 3) (reg:HI 24))])
2802 (define_insn "*divmodhi4_call"
2803 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2804 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2805 (clobber (reg:HI 26))
2806 (clobber (reg:QI 21))]
2808 "%~call __divmodhi4"
2809 [(set_attr "type" "xcall")
2810 (set_attr "cc" "clobber")])
2812 (define_insn_and_split "udivmodhi4"
2813 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2814 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2815 (match_operand:HI 2 "pseudo_register_operand" "")))
2816 (set (match_operand:HI 3 "pseudo_register_operand" "")
2817 (umod:HI (match_dup 1) (match_dup 2)))
2818 (clobber (reg:QI 21))
2819 (clobber (reg:HI 22))
2820 (clobber (reg:HI 24))
2821 (clobber (reg:HI 26))])]
2823 "this udivmodhi4 pattern should have been splitted.;"
2825 [(set (reg:HI 24) (match_dup 1))
2826 (set (reg:HI 22) (match_dup 2))
2827 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2828 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2829 (clobber (reg:HI 26))
2830 (clobber (reg:QI 21))])
2831 (set (match_dup 0) (reg:HI 22))
2832 (set (match_dup 3) (reg:HI 24))])
2834 (define_insn "*udivmodhi4_call"
2835 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2836 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2837 (clobber (reg:HI 26))
2838 (clobber (reg:QI 21))]
2840 "%~call __udivmodhi4"
2841 [(set_attr "type" "xcall")
2842 (set_attr "cc" "clobber")])
2844 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2847 ;; To support widening multiplication with constant we postpone
2848 ;; expanding to the implicit library call until post combine and
2849 ;; prior to register allocation. Clobber all hard registers that
2850 ;; might be used by the (widening) multiply until it is split and
2851 ;; it's final register footprint is worked out.
2853 (define_expand "mulpsi3"
2854 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2855 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2856 (match_operand:PSI 2 "nonmemory_operand" "")))
2857 (clobber (reg:HI 26))
2858 (clobber (reg:DI 18))])]
2861 if (s8_operand (operands[2], PSImode))
2863 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2864 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2868 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
2869 regmask (DImode, 18) | regmask (HImode, 26)))
2873 (define_insn "*umulqihipsi3"
2874 [(set (match_operand:PSI 0 "register_operand" "=&r")
2875 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2876 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2885 [(set_attr "length" "7")
2886 (set_attr "cc" "clobber")])
2888 (define_insn "*umulhiqipsi3"
2889 [(set (match_operand:PSI 0 "register_operand" "=&r")
2890 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2891 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2899 adc %C0,__zero_reg__"
2900 [(set_attr "length" "7")
2901 (set_attr "cc" "clobber")])
2903 (define_expand "mulsqipsi3"
2904 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2905 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
2906 (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
2907 (clobber (reg:HI 26))
2908 (clobber (reg:DI 18))])]
2911 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2912 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
2913 regmask (DImode, 18) | regmask (HImode, 26)))
2917 (define_insn_and_split "*mulsqipsi3"
2918 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2919 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2920 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2921 (clobber (reg:HI 26))
2922 (clobber (reg:DI 18))]
2923 "AVR_HAVE_MUL && !reload_completed"
2924 { gcc_unreachable(); }
2931 (mult:PSI (sign_extend:PSI (reg:QI 25))
2936 (define_insn_and_split "*mulpsi3"
2937 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2938 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2939 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2940 (clobber (reg:HI 26))
2941 (clobber (reg:DI 18))]
2942 "AVR_HAVE_MUL && !reload_completed"
2943 { gcc_unreachable(); }
2949 (parallel [(set (reg:PSI 22)
2950 (mult:PSI (reg:PSI 22)
2952 (clobber (reg:QI 21))
2953 (clobber (reg:QI 25))
2954 (clobber (reg:HI 26))])
2958 if (s8_operand (operands[2], PSImode))
2960 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2961 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2966 (define_insn "*mulsqipsi3.libgcc"
2968 (mult:PSI (sign_extend:PSI (reg:QI 25))
2971 "%~call __mulsqipsi3"
2972 [(set_attr "type" "xcall")
2973 (set_attr "cc" "clobber")])
2975 (define_insn "*mulpsi3.libgcc"
2977 (mult:PSI (reg:PSI 22)
2979 (clobber (reg:QI 21))
2980 (clobber (reg:QI 25))
2981 (clobber (reg:HI 26))]
2984 [(set_attr "type" "xcall")
2985 (set_attr "cc" "clobber")])
2988 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2989 ;; 24-bit signed/unsigned division and modulo.
2990 ;; Notice that the libgcc implementation return the quotient in R22
2991 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2992 ;; implementation works the other way round.
2994 (define_insn_and_split "divmodpsi4"
2995 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2996 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2997 (match_operand:PSI 2 "pseudo_register_operand" "")))
2998 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2999 (mod:PSI (match_dup 1)
3001 (clobber (reg:DI 18))
3002 (clobber (reg:QI 26))])]
3004 { gcc_unreachable(); }
3006 [(set (reg:PSI 22) (match_dup 1))
3007 (set (reg:PSI 18) (match_dup 2))
3008 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
3009 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
3010 (clobber (reg:QI 21))
3011 (clobber (reg:QI 25))
3012 (clobber (reg:QI 26))])
3013 (set (match_dup 0) (reg:PSI 22))
3014 (set (match_dup 3) (reg:PSI 18))])
3016 (define_insn "*divmodpsi4_call"
3017 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
3018 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
3019 (clobber (reg:QI 21))
3020 (clobber (reg:QI 25))
3021 (clobber (reg:QI 26))]
3023 "%~call __divmodpsi4"
3024 [(set_attr "type" "xcall")
3025 (set_attr "cc" "clobber")])
3027 (define_insn_and_split "udivmodpsi4"
3028 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
3029 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
3030 (match_operand:PSI 2 "pseudo_register_operand" "")))
3031 (set (match_operand:PSI 3 "pseudo_register_operand" "")
3032 (umod:PSI (match_dup 1)
3034 (clobber (reg:DI 18))
3035 (clobber (reg:QI 26))])]
3037 { gcc_unreachable(); }
3039 [(set (reg:PSI 22) (match_dup 1))
3040 (set (reg:PSI 18) (match_dup 2))
3041 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
3042 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
3043 (clobber (reg:QI 21))
3044 (clobber (reg:QI 25))
3045 (clobber (reg:QI 26))])
3046 (set (match_dup 0) (reg:PSI 22))
3047 (set (match_dup 3) (reg:PSI 18))])
3049 (define_insn "*udivmodpsi4_call"
3050 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
3051 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
3052 (clobber (reg:QI 21))
3053 (clobber (reg:QI 25))
3054 (clobber (reg:QI 26))]
3056 "%~call __udivmodpsi4"
3057 [(set_attr "type" "xcall")
3058 (set_attr "cc" "clobber")])
3060 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3062 (define_insn_and_split "divmodsi4"
3063 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3064 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
3065 (match_operand:SI 2 "pseudo_register_operand" "")))
3066 (set (match_operand:SI 3 "pseudo_register_operand" "")
3067 (mod:SI (match_dup 1) (match_dup 2)))
3068 (clobber (reg:SI 18))
3069 (clobber (reg:SI 22))
3070 (clobber (reg:HI 26))
3071 (clobber (reg:HI 30))])]
3073 "this divmodsi4 pattern should have been splitted;"
3075 [(set (reg:SI 22) (match_dup 1))
3076 (set (reg:SI 18) (match_dup 2))
3077 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
3078 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
3079 (clobber (reg:HI 26))
3080 (clobber (reg:HI 30))])
3081 (set (match_dup 0) (reg:SI 18))
3082 (set (match_dup 3) (reg:SI 22))])
3084 (define_insn "*divmodsi4_call"
3085 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
3086 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
3087 (clobber (reg:HI 26))
3088 (clobber (reg:HI 30))]
3090 "%~call __divmodsi4"
3091 [(set_attr "type" "xcall")
3092 (set_attr "cc" "clobber")])
3094 (define_insn_and_split "udivmodsi4"
3095 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3096 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
3097 (match_operand:SI 2 "pseudo_register_operand" "")))
3098 (set (match_operand:SI 3 "pseudo_register_operand" "")
3099 (umod:SI (match_dup 1) (match_dup 2)))
3100 (clobber (reg:SI 18))
3101 (clobber (reg:SI 22))
3102 (clobber (reg:HI 26))
3103 (clobber (reg:HI 30))])]
3105 "this udivmodsi4 pattern should have been splitted;"
3107 [(set (reg:SI 22) (match_dup 1))
3108 (set (reg:SI 18) (match_dup 2))
3109 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
3110 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
3111 (clobber (reg:HI 26))
3112 (clobber (reg:HI 30))])
3113 (set (match_dup 0) (reg:SI 18))
3114 (set (match_dup 3) (reg:SI 22))])
3116 (define_insn "*udivmodsi4_call"
3117 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
3118 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
3119 (clobber (reg:HI 26))
3120 (clobber (reg:HI 30))]
3122 "%~call __udivmodsi4"
3123 [(set_attr "type" "xcall")
3124 (set_attr "cc" "clobber")])
3126 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3129 (define_insn "andqi3"
3130 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
3131 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
3132 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))]
3137 * return avr_out_bitop (insn, operands, NULL);"
3138 [(set_attr "length" "1,1,2")
3139 (set_attr "cc" "set_zn,set_zn,none")])
3141 (define_insn "andhi3"
3142 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3143 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3144 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
3145 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3148 if (which_alternative == 0)
3149 return "and %A0,%A2\;and %B0,%B2";
3150 else if (which_alternative == 1)
3151 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
3153 return avr_out_bitop (insn, operands, NULL);
3155 [(set_attr "length" "2,2,2,4,4")
3156 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3157 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3159 (define_insn "andpsi3"
3160 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3161 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3162 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
3163 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3166 if (which_alternative == 0)
3167 return "and %A0,%A2" CR_TAB
3168 "and %B0,%B2" CR_TAB
3171 return avr_out_bitop (insn, operands, NULL);
3173 [(set_attr "length" "3,3,6,6")
3174 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3175 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3177 (define_insn "andsi3"
3178 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3179 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3180 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
3181 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3184 if (which_alternative == 0)
3185 return "and %0,%2" CR_TAB
3186 "and %B0,%B2" CR_TAB
3187 "and %C0,%C2" CR_TAB
3190 return avr_out_bitop (insn, operands, NULL);
3192 [(set_attr "length" "4,4,8,8")
3193 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3194 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3196 (define_peephole2 ; andi
3197 [(set (match_operand:QI 0 "d_register_operand" "")
3198 (and:QI (match_dup 0)
3199 (match_operand:QI 1 "const_int_operand" "")))
3201 (and:QI (match_dup 0)
3202 (match_operand:QI 2 "const_int_operand" "")))]
3204 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3206 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3209 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3212 (define_insn "iorqi3"
3213 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
3214 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
3215 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))]
3220 * return avr_out_bitop (insn, operands, NULL);"
3221 [(set_attr "length" "1,1,2")
3222 (set_attr "cc" "set_zn,set_zn,none")])
3224 (define_insn "iorhi3"
3225 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3226 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3227 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3228 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3231 if (which_alternative == 0)
3232 return "or %A0,%A2\;or %B0,%B2";
3233 else if (which_alternative == 1)
3234 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3236 return avr_out_bitop (insn, operands, NULL);
3238 [(set_attr "length" "2,2,2,4,4")
3239 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3240 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3242 (define_insn "iorpsi3"
3243 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3244 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3245 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3246 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3249 if (which_alternative == 0)
3250 return "or %A0,%A2" CR_TAB
3254 return avr_out_bitop (insn, operands, NULL);
3256 [(set_attr "length" "3,3,6,6")
3257 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3258 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3260 (define_insn "iorsi3"
3261 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3262 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3263 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3264 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3267 if (which_alternative == 0)
3268 return "or %0,%2" CR_TAB
3273 return avr_out_bitop (insn, operands, NULL);
3275 [(set_attr "length" "4,4,8,8")
3276 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3277 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3279 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3282 (define_insn "xorqi3"
3283 [(set (match_operand:QI 0 "register_operand" "=r")
3284 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3285 (match_operand:QI 2 "register_operand" "r")))]
3288 [(set_attr "length" "1")
3289 (set_attr "cc" "set_zn")])
3291 (define_insn "xorhi3"
3292 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3293 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3294 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3295 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3298 if (which_alternative == 0)
3299 return "eor %A0,%A2\;eor %B0,%B2";
3301 return avr_out_bitop (insn, operands, NULL);
3303 [(set_attr "length" "2,2,4")
3304 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3305 (set_attr "cc" "set_n,clobber,clobber")])
3307 (define_insn "xorpsi3"
3308 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3309 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3310 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3311 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3314 if (which_alternative == 0)
3315 return "eor %A0,%A2" CR_TAB
3316 "eor %B0,%B2" CR_TAB
3319 return avr_out_bitop (insn, operands, NULL);
3321 [(set_attr "length" "3,6,6")
3322 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3323 (set_attr "cc" "set_n,clobber,clobber")])
3325 (define_insn "xorsi3"
3326 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3327 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3328 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3329 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3332 if (which_alternative == 0)
3333 return "eor %0,%2" CR_TAB
3334 "eor %B0,%B2" CR_TAB
3335 "eor %C0,%C2" CR_TAB
3338 return avr_out_bitop (insn, operands, NULL);
3340 [(set_attr "length" "4,8,8")
3341 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3342 (set_attr "cc" "set_n,clobber,clobber")])
3346 [(set (match_operand:SPLIT34 0 "register_operand")
3347 (match_operand:SPLIT34 1 "register_operand"))]
3349 && reload_completed"
3350 [(set (match_dup 2) (match_dup 3))
3351 (set (match_dup 4) (match_dup 5))]
3353 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode;
3354 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]);
3355 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0);
3356 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0);
3357 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2);
3358 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2);
3360 operands[2] = lo_first ? dst_lo : dst_hi;
3361 operands[3] = lo_first ? src_lo : src_hi;
3362 operands[4] = lo_first ? dst_hi : dst_lo;
3363 operands[5] = lo_first ? src_hi : src_lo;
3367 [(set (match_operand:HI 0 "register_operand")
3368 (match_operand:HI 1 "reg_or_0_operand"))]
3371 && GENERAL_REG_P (operands[0])
3372 && (operands[1] == const0_rtx || GENERAL_REG_P (operands[1]))
3374 || const0_rtx == operands[1])"
3375 [(set (match_dup 2) (match_dup 3))
3376 (set (match_dup 4) (match_dup 5))]
3378 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3379 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
3380 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3381 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3384 ;; Split andhi3, andpsi3, andsi3.
3385 ;; Split iorhi3, iorpsi3, iorsi3.
3386 ;; Split xorhi3, xorpsi3, xorsi3.
3388 [(parallel [(set (match_operand:HISI 0 "register_operand")
3389 (bitop:HISI (match_dup 0)
3390 (match_operand:HISI 1 "register_operand")))
3391 (clobber (scratch:QI))])]
3393 && reload_completed"
3396 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
3398 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
3399 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
3400 emit_insn (gen_<code>qi3 (dst, dst, src));
3406 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3409 (define_expand "rotlqi3"
3410 [(set (match_operand:QI 0 "register_operand" "")
3411 (rotate:QI (match_operand:QI 1 "register_operand" "")
3412 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3415 if (!CONST_INT_P (operands[2]))
3418 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3421 ;; Expander used by __builtin_avr_swap
3422 (define_expand "rotlqi3_4"
3423 [(set (match_operand:QI 0 "register_operand" "")
3424 (rotate:QI (match_operand:QI 1 "register_operand" "")
3427 (define_insn "*rotlqi3"
3428 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3429 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3430 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3433 lsl %0\;adc %0,__zero_reg__
3434 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3435 swap %0\;bst %0,0\;ror %0\;bld %0,7
3437 swap %0\;lsl %0\;adc %0,__zero_reg__
3438 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3439 bst %0,0\;ror %0\;bld %0,7
3441 [(set_attr "length" "2,4,4,1,3,5,3,0")
3442 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3444 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3445 ;; a whole number of bytes. The split creates the appropriate moves and
3446 ;; considers all overlap situations.
3448 ;; HImode does not need scratch. Use attribute for this constraint.
3450 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3451 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3456 (define_expand "rotl<mode>3"
3457 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3458 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3459 (match_operand:HISI 2 "const_int_operand" "")))
3460 (clobber (match_dup 3))])]
3465 if (!CONST_INT_P (operands[2]))
3468 offset = INTVAL (operands[2]);
3470 if (0 == offset % 8)
3472 if (AVR_HAVE_MOVW && 0 == offset % 16)
3473 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3475 operands[3] = gen_rtx_SCRATCH (QImode);
3477 else if (offset == 1
3478 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3480 /*; Support rotate left/right by 1 */
3482 emit_move_insn (operands[0],
3483 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3490 (define_insn "*rotlhi2.1"
3491 [(set (match_operand:HI 0 "register_operand" "=r")
3492 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3495 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3496 [(set_attr "length" "3")
3497 (set_attr "cc" "clobber")])
3499 (define_insn "*rotlhi2.15"
3500 [(set (match_operand:HI 0 "register_operand" "=r")
3501 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3504 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3505 [(set_attr "length" "4")
3506 (set_attr "cc" "clobber")])
3508 (define_insn "*rotlpsi2.1"
3509 [(set (match_operand:PSI 0 "register_operand" "=r")
3510 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3513 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3514 [(set_attr "length" "4")
3515 (set_attr "cc" "clobber")])
3517 (define_insn "*rotlpsi2.23"
3518 [(set (match_operand:PSI 0 "register_operand" "=r")
3519 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3522 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3523 [(set_attr "length" "5")
3524 (set_attr "cc" "clobber")])
3526 (define_insn "*rotlsi2.1"
3527 [(set (match_operand:SI 0 "register_operand" "=r")
3528 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3531 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3532 [(set_attr "length" "5")
3533 (set_attr "cc" "clobber")])
3535 (define_insn "*rotlsi2.31"
3536 [(set (match_operand:SI 0 "register_operand" "=r")
3537 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3540 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3541 [(set_attr "length" "6")
3542 (set_attr "cc" "clobber")])
3544 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3545 ;; The best we can do is use early clobber alternative "#&r" so that
3546 ;; completely non-overlapping operands dont get a scratch but # so register
3547 ;; allocation does not prefer non-overlapping.
3550 ;; Split word aligned rotates using scratch that is mode dependent.
3554 (define_insn_and_split "*rotw<mode>"
3555 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3556 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3557 (match_operand 2 "const_int_operand" "n,n,n")))
3558 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3560 && CONST_INT_P (operands[2])
3561 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3562 && 0 == INTVAL (operands[2]) % 16"
3564 "&& reload_completed"
3567 avr_rotate_bytes (operands);
3572 ;; Split byte aligned rotates using scratch that is always QI mode.
3577 (define_insn_and_split "*rotb<mode>"
3578 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3579 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3580 (match_operand 2 "const_int_operand" "n,n,n")))
3581 (clobber (match_scratch:QI 3 "=<rotx>"))]
3582 "CONST_INT_P (operands[2])
3583 && (8 == INTVAL (operands[2]) % 16
3585 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3586 && 0 == INTVAL (operands[2]) % 16))"
3588 "&& reload_completed"
3591 avr_rotate_bytes (operands);
3596 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3597 ;; arithmetic shift left
3600 ;; "ashlqq3" "ashluqq3"
3601 (define_expand "ashl<mode>3"
3602 [(set (match_operand:ALL1 0 "register_operand" "")
3603 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3604 (match_operand:QI 2 "nop_general_operand" "")))])
3606 (define_split ; ashlqi3_const4
3607 [(set (match_operand:ALL1 0 "d_register_operand" "")
3608 (ashift:ALL1 (match_dup 0)
3612 (rotate:QI (match_dup 1)
3615 (and:QI (match_dup 1)
3618 operands[1] = avr_to_int_mode (operands[0]);
3621 (define_split ; ashlqi3_const5
3622 [(set (match_operand:ALL1 0 "d_register_operand" "")
3623 (ashift:ALL1 (match_dup 0)
3626 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3627 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3628 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3630 operands[1] = avr_to_int_mode (operands[0]);
3633 (define_split ; ashlqi3_const6
3634 [(set (match_operand:ALL1 0 "d_register_operand" "")
3635 (ashift:ALL1 (match_dup 0)
3638 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3639 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3640 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3642 operands[1] = avr_to_int_mode (operands[0]);
3646 ;; "*ashlqq3" "*ashluqq3"
3647 (define_insn "*ashl<mode>3"
3648 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3649 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3650 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3653 return ashlqi3_out (insn, operands, NULL);
3655 [(set_attr "length" "5,0,1,2,4,6,9")
3656 (set_attr "adjust_len" "ashlqi")
3657 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3659 (define_insn "ashl<mode>3"
3660 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3661 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3662 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3665 return ashlhi3_out (insn, operands, NULL);
3667 [(set_attr "length" "6,0,2,2,4,10,10")
3668 (set_attr "adjust_len" "ashlhi")
3669 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3672 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3673 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3677 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3678 [(set (match_operand:QI 0 "register_operand" "=r")
3679 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3680 (match_operand:QI 2 "register_operand" "r"))
3686 (ashift:QI (match_dup 1)
3689 ;; ??? Combiner does not recognize that it could split the following insn;
3690 ;; presumably because he has no register handy?
3692 ;; "*ashluqihiqi3.mem"
3693 ;; "*ashlsqihiqi3.mem"
3694 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3695 [(set (match_operand:QI 0 "memory_operand" "=m")
3696 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3697 (match_operand:QI 2 "register_operand" "r"))
3700 { gcc_unreachable(); }
3703 (ashift:QI (match_dup 1)
3708 operands[3] = gen_reg_rtx (QImode);
3713 (define_insn_and_split "*ashlhiqi3"
3714 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3715 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3716 (match_operand:QI 2 "register_operand" "r")) 0))]
3718 { gcc_unreachable(); }
3721 (ashift:QI (match_dup 3)
3726 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3727 operands[4] = gen_reg_rtx (QImode);
3730 ;; High part of 16-bit shift is unused after the instruction:
3731 ;; No need to compute it, map to 8-bit shift.
3734 [(set (match_operand:HI 0 "register_operand" "")
3735 (ashift:HI (match_dup 0)
3736 (match_operand:QI 1 "register_operand" "")))]
3739 (ashift:QI (match_dup 2)
3741 (clobber (match_dup 3))]
3743 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3745 if (!peep2_reg_dead_p (1, operands[3]))
3748 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3753 ;; "ashlsq3" "ashlusq3"
3754 ;; "ashlsa3" "ashlusa3"
3755 (define_insn "ashl<mode>3"
3756 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3757 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3758 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3761 return ashlsi3_out (insn, operands, NULL);
3763 [(set_attr "length" "8,0,4,4,8,10,12")
3764 (set_attr "adjust_len" "ashlsi")
3765 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3767 ;; Optimize if a scratch register from LD_REGS happens to be available.
3769 (define_peephole2 ; ashlqi3_l_const4
3770 [(set (match_operand:ALL1 0 "l_register_operand" "")
3771 (ashift:ALL1 (match_dup 0)
3773 (match_scratch:QI 1 "d")]
3775 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3776 (set (match_dup 1) (const_int -16))
3777 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3779 operands[2] = avr_to_int_mode (operands[0]);
3782 (define_peephole2 ; ashlqi3_l_const5
3783 [(set (match_operand:ALL1 0 "l_register_operand" "")
3784 (ashift:ALL1 (match_dup 0)
3786 (match_scratch:QI 1 "d")]
3788 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3789 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3790 (set (match_dup 1) (const_int -32))
3791 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3793 operands[2] = avr_to_int_mode (operands[0]);
3796 (define_peephole2 ; ashlqi3_l_const6
3797 [(set (match_operand:ALL1 0 "l_register_operand" "")
3798 (ashift:ALL1 (match_dup 0)
3800 (match_scratch:QI 1 "d")]
3802 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3803 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3804 (set (match_dup 1) (const_int -64))
3805 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3807 operands[2] = avr_to_int_mode (operands[0]);
3811 [(match_scratch:QI 3 "d")
3812 (set (match_operand:ALL2 0 "register_operand" "")
3813 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3814 (match_operand:QI 2 "const_int_operand" "")))]
3816 [(parallel [(set (match_dup 0)
3817 (ashift:ALL2 (match_dup 1)
3819 (clobber (match_dup 3))])])
3822 ;; "*ashlhq3_const" "*ashluhq3_const"
3823 ;; "*ashlha3_const" "*ashluha3_const"
3824 (define_insn "*ashl<mode>3_const"
3825 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3826 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3827 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3828 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3831 return ashlhi3_out (insn, operands, NULL);
3833 [(set_attr "length" "0,2,2,4,10")
3834 (set_attr "adjust_len" "ashlhi")
3835 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3838 [(match_scratch:QI 3 "d")
3839 (set (match_operand:ALL4 0 "register_operand" "")
3840 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3841 (match_operand:QI 2 "const_int_operand" "")))]
3843 [(parallel [(set (match_dup 0)
3844 (ashift:ALL4 (match_dup 1)
3846 (clobber (match_dup 3))])])
3849 ;; "*ashlsq3_const" "*ashlusq3_const"
3850 ;; "*ashlsa3_const" "*ashlusa3_const"
3851 (define_insn "*ashl<mode>3_const"
3852 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3853 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3854 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3855 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3858 return ashlsi3_out (insn, operands, NULL);
3860 [(set_attr "length" "0,4,4,10")
3861 (set_attr "adjust_len" "ashlsi")
3862 (set_attr "cc" "none,set_n,clobber,clobber")])
3864 (define_expand "ashlpsi3"
3865 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3866 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3867 (match_operand:QI 2 "nonmemory_operand" "")))
3868 (clobber (scratch:QI))])]
3872 && CONST_INT_P (operands[2]))
3874 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3876 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3877 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3880 else if (optimize_insn_for_speed_p ()
3881 && INTVAL (operands[2]) != 16
3882 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3884 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3885 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3891 (define_insn "*ashlpsi3"
3892 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3893 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3894 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3895 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3898 return avr_out_ashlpsi3 (insn, operands, NULL);
3900 [(set_attr "adjust_len" "ashlpsi")
3901 (set_attr "cc" "clobber")])
3903 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3904 ;; arithmetic shift right
3907 ;; "ashrqq3" "ashruqq3"
3908 (define_insn "ashr<mode>3"
3909 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3910 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3911 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3914 return ashrqi3_out (insn, operands, NULL);
3916 [(set_attr "length" "5,0,1,2,5,4,9")
3917 (set_attr "adjust_len" "ashrqi")
3918 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3921 ;; "ashrhq3" "ashruhq3"
3922 ;; "ashrha3" "ashruha3"
3923 (define_insn "ashr<mode>3"
3924 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3925 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3926 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3929 return ashrhi3_out (insn, operands, NULL);
3931 [(set_attr "length" "6,0,2,4,4,10,10")
3932 (set_attr "adjust_len" "ashrhi")
3933 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3935 (define_insn "ashrpsi3"
3936 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3937 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3938 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3939 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3942 return avr_out_ashrpsi3 (insn, operands, NULL);
3944 [(set_attr "adjust_len" "ashrpsi")
3945 (set_attr "cc" "clobber")])
3948 ;; "ashrsq3" "ashrusq3"
3949 ;; "ashrsa3" "ashrusa3"
3950 (define_insn "ashr<mode>3"
3951 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3952 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3953 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3956 return ashrsi3_out (insn, operands, NULL);
3958 [(set_attr "length" "8,0,4,6,8,10,12")
3959 (set_attr "adjust_len" "ashrsi")
3960 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3962 ;; Optimize if a scratch register from LD_REGS happens to be available.
3965 [(match_scratch:QI 3 "d")
3966 (set (match_operand:ALL2 0 "register_operand" "")
3967 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3968 (match_operand:QI 2 "const_int_operand" "")))]
3970 [(parallel [(set (match_dup 0)
3971 (ashiftrt:ALL2 (match_dup 1)
3973 (clobber (match_dup 3))])])
3976 ;; "*ashrhq3_const" "*ashruhq3_const"
3977 ;; "*ashrha3_const" "*ashruha3_const"
3978 (define_insn "*ashr<mode>3_const"
3979 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3980 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3981 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3982 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3985 return ashrhi3_out (insn, operands, NULL);
3987 [(set_attr "length" "0,2,4,4,10")
3988 (set_attr "adjust_len" "ashrhi")
3989 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3992 [(match_scratch:QI 3 "d")
3993 (set (match_operand:ALL4 0 "register_operand" "")
3994 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3995 (match_operand:QI 2 "const_int_operand" "")))]
3997 [(parallel [(set (match_dup 0)
3998 (ashiftrt:ALL4 (match_dup 1)
4000 (clobber (match_dup 3))])])
4003 ;; "*ashrsq3_const" "*ashrusq3_const"
4004 ;; "*ashrsa3_const" "*ashrusa3_const"
4005 (define_insn "*ashr<mode>3_const"
4006 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4007 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4008 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4009 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4012 return ashrsi3_out (insn, operands, NULL);
4014 [(set_attr "length" "0,4,4,10")
4015 (set_attr "adjust_len" "ashrsi")
4016 (set_attr "cc" "none,clobber,set_n,clobber")])
4018 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
4019 ;; logical shift right
4022 ;; "lshrqq3" "lshruqq3"
4023 (define_expand "lshr<mode>3"
4024 [(set (match_operand:ALL1 0 "register_operand" "")
4025 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
4026 (match_operand:QI 2 "nop_general_operand" "")))])
4028 (define_split ; lshrqi3_const4
4029 [(set (match_operand:ALL1 0 "d_register_operand" "")
4030 (lshiftrt:ALL1 (match_dup 0)
4034 (rotate:QI (match_dup 1)
4037 (and:QI (match_dup 1)
4040 operands[1] = avr_to_int_mode (operands[0]);
4043 (define_split ; lshrqi3_const5
4044 [(set (match_operand:ALL1 0 "d_register_operand" "")
4045 (lshiftrt:ALL1 (match_dup 0)
4048 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4049 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
4050 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
4052 operands[1] = avr_to_int_mode (operands[0]);
4055 (define_split ; lshrqi3_const6
4056 [(set (match_operand:QI 0 "d_register_operand" "")
4057 (lshiftrt:QI (match_dup 0)
4060 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4061 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
4062 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
4064 operands[1] = avr_to_int_mode (operands[0]);
4070 (define_insn "*lshr<mode>3"
4071 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
4072 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
4073 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
4076 return lshrqi3_out (insn, operands, NULL);
4078 [(set_attr "length" "5,0,1,2,4,6,9")
4079 (set_attr "adjust_len" "lshrqi")
4080 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
4083 ;; "lshrhq3" "lshruhq3"
4084 ;; "lshrha3" "lshruha3"
4085 (define_insn "lshr<mode>3"
4086 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
4087 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
4088 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4091 return lshrhi3_out (insn, operands, NULL);
4093 [(set_attr "length" "6,0,2,2,4,10,10")
4094 (set_attr "adjust_len" "lshrhi")
4095 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4097 (define_insn "lshrpsi3"
4098 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
4099 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
4100 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
4101 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4104 return avr_out_lshrpsi3 (insn, operands, NULL);
4106 [(set_attr "adjust_len" "lshrpsi")
4107 (set_attr "cc" "clobber")])
4110 ;; "lshrsq3" "lshrusq3"
4111 ;; "lshrsa3" "lshrusa3"
4112 (define_insn "lshr<mode>3"
4113 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
4114 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
4115 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4118 return lshrsi3_out (insn, operands, NULL);
4120 [(set_attr "length" "8,0,4,4,8,10,12")
4121 (set_attr "adjust_len" "lshrsi")
4122 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4124 ;; Optimize if a scratch register from LD_REGS happens to be available.
4126 (define_peephole2 ; lshrqi3_l_const4
4127 [(set (match_operand:ALL1 0 "l_register_operand" "")
4128 (lshiftrt:ALL1 (match_dup 0)
4130 (match_scratch:QI 1 "d")]
4132 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4133 (set (match_dup 1) (const_int 15))
4134 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4136 operands[2] = avr_to_int_mode (operands[0]);
4139 (define_peephole2 ; lshrqi3_l_const5
4140 [(set (match_operand:ALL1 0 "l_register_operand" "")
4141 (lshiftrt:ALL1 (match_dup 0)
4143 (match_scratch:QI 1 "d")]
4145 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4146 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
4147 (set (match_dup 1) (const_int 7))
4148 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4150 operands[2] = avr_to_int_mode (operands[0]);
4153 (define_peephole2 ; lshrqi3_l_const6
4154 [(set (match_operand:ALL1 0 "l_register_operand" "")
4155 (lshiftrt:ALL1 (match_dup 0)
4157 (match_scratch:QI 1 "d")]
4159 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4160 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
4161 (set (match_dup 1) (const_int 3))
4162 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4164 operands[2] = avr_to_int_mode (operands[0]);
4168 [(match_scratch:QI 3 "d")
4169 (set (match_operand:ALL2 0 "register_operand" "")
4170 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
4171 (match_operand:QI 2 "const_int_operand" "")))]
4173 [(parallel [(set (match_dup 0)
4174 (lshiftrt:ALL2 (match_dup 1)
4176 (clobber (match_dup 3))])])
4179 ;; "*lshrhq3_const" "*lshruhq3_const"
4180 ;; "*lshrha3_const" "*lshruha3_const"
4181 (define_insn "*lshr<mode>3_const"
4182 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
4183 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
4184 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
4185 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4188 return lshrhi3_out (insn, operands, NULL);
4190 [(set_attr "length" "0,2,2,4,10")
4191 (set_attr "adjust_len" "lshrhi")
4192 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
4195 [(match_scratch:QI 3 "d")
4196 (set (match_operand:ALL4 0 "register_operand" "")
4197 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
4198 (match_operand:QI 2 "const_int_operand" "")))]
4200 [(parallel [(set (match_dup 0)
4201 (lshiftrt:ALL4 (match_dup 1)
4203 (clobber (match_dup 3))])])
4206 ;; "*lshrsq3_const" "*lshrusq3_const"
4207 ;; "*lshrsa3_const" "*lshrusa3_const"
4208 (define_insn "*lshr<mode>3_const"
4209 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4210 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4211 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4212 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4215 return lshrsi3_out (insn, operands, NULL);
4217 [(set_attr "length" "0,4,4,10")
4218 (set_attr "adjust_len" "lshrsi")
4219 (set_attr "cc" "none,clobber,clobber,clobber")])
4221 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
4224 (define_insn "absqi2"
4225 [(set (match_operand:QI 0 "register_operand" "=r")
4226 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
4230 [(set_attr "length" "2")
4231 (set_attr "cc" "clobber")])
4234 (define_insn "abssf2"
4235 [(set (match_operand:SF 0 "register_operand" "=d,r")
4236 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4241 [(set_attr "length" "1,2")
4242 (set_attr "cc" "set_n,clobber")])
4244 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
4247 (define_insn "negqi2"
4248 [(set (match_operand:QI 0 "register_operand" "=r")
4249 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4252 [(set_attr "length" "1")
4253 (set_attr "cc" "set_vzn")])
4255 (define_insn "*negqihi2"
4256 [(set (match_operand:HI 0 "register_operand" "=r")
4257 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4259 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4260 [(set_attr "length" "4")
4261 (set_attr "cc" "set_n")])
4263 (define_insn "neghi2"
4264 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4265 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4268 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4269 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4270 [(set_attr "length" "3,4")
4271 (set_attr "cc" "set_czn")])
4273 (define_insn "negpsi2"
4274 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4275 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4278 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4279 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4280 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4281 [(set_attr "length" "5,6,6")
4282 (set_attr "cc" "set_czn,set_n,set_czn")])
4284 (define_insn "negsi2"
4285 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4286 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4289 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4290 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4291 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4292 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4293 [(set_attr "length" "7,8,8,7")
4294 (set_attr "isa" "*,*,mov,movw")
4295 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4297 (define_insn "negsf2"
4298 [(set (match_operand:SF 0 "register_operand" "=d,r")
4299 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4303 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4304 [(set_attr "length" "1,4")
4305 (set_attr "cc" "set_n,set_n")])
4307 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4310 (define_insn "one_cmplqi2"
4311 [(set (match_operand:QI 0 "register_operand" "=r")
4312 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4315 [(set_attr "length" "1")
4316 (set_attr "cc" "set_czn")])
4318 (define_insn "one_cmplhi2"
4319 [(set (match_operand:HI 0 "register_operand" "=r")
4320 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4324 [(set_attr "length" "2")
4325 (set_attr "cc" "set_n")])
4327 (define_insn "one_cmplpsi2"
4328 [(set (match_operand:PSI 0 "register_operand" "=r")
4329 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4331 "com %0\;com %B0\;com %C0"
4332 [(set_attr "length" "3")
4333 (set_attr "cc" "set_n")])
4335 (define_insn "one_cmplsi2"
4336 [(set (match_operand:SI 0 "register_operand" "=r")
4337 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4343 [(set_attr "length" "4")
4344 (set_attr "cc" "set_n")])
4346 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4349 ;; We keep combiner from inserting hard registers into the input of sign- and
4350 ;; zero-extends. A hard register in the input operand is not wanted because
4351 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4352 ;; hard register that overlaps these clobbers won't be combined to a widening
4353 ;; multiplication. There is no need for combine to propagate hard registers,
4354 ;; register allocation can do it just as well.
4356 (define_insn "extendqihi2"
4357 [(set (match_operand:HI 0 "register_operand" "=r,r")
4358 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4361 return avr_out_sign_extend (insn, operands, NULL);
4363 [(set_attr "length" "3,4")
4364 (set_attr "adjust_len" "sext")
4365 (set_attr "cc" "set_n")])
4367 (define_insn "extendqipsi2"
4368 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4369 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4372 return avr_out_sign_extend (insn, operands, NULL);
4374 [(set_attr "length" "4,5")
4375 (set_attr "adjust_len" "sext")
4376 (set_attr "cc" "set_n")])
4378 (define_insn "extendqisi2"
4379 [(set (match_operand:SI 0 "register_operand" "=r,r")
4380 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4383 return avr_out_sign_extend (insn, operands, NULL);
4385 [(set_attr "length" "5,6")
4386 (set_attr "adjust_len" "sext")
4387 (set_attr "cc" "set_n")])
4389 (define_insn "extendhipsi2"
4390 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4391 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4394 return avr_out_sign_extend (insn, operands, NULL);
4396 [(set_attr "length" "3,5")
4397 (set_attr "adjust_len" "sext")
4398 (set_attr "cc" "set_n")])
4400 (define_insn "extendhisi2"
4401 [(set (match_operand:SI 0 "register_operand" "=r,r")
4402 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4405 return avr_out_sign_extend (insn, operands, NULL);
4407 [(set_attr "length" "4,6")
4408 (set_attr "adjust_len" "sext")
4409 (set_attr "cc" "set_n")])
4411 (define_insn "extendpsisi2"
4412 [(set (match_operand:SI 0 "register_operand" "=r")
4413 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4416 return avr_out_sign_extend (insn, operands, NULL);
4418 [(set_attr "length" "3")
4419 (set_attr "adjust_len" "sext")
4420 (set_attr "cc" "set_n")])
4422 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4425 (define_insn_and_split "zero_extendqihi2"
4426 [(set (match_operand:HI 0 "register_operand" "=r")
4427 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4431 [(set (match_dup 2) (match_dup 1))
4432 (set (match_dup 3) (const_int 0))]
4434 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4435 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4437 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4438 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4441 (define_insn_and_split "zero_extendqipsi2"
4442 [(set (match_operand:PSI 0 "register_operand" "=r")
4443 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4447 [(set (match_dup 2) (match_dup 1))
4448 (set (match_dup 3) (const_int 0))
4449 (set (match_dup 4) (const_int 0))]
4451 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4452 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4453 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4456 (define_insn_and_split "zero_extendqisi2"
4457 [(set (match_operand:SI 0 "register_operand" "=r")
4458 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4462 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4463 (set (match_dup 3) (const_int 0))]
4465 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4466 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4468 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4469 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4472 (define_insn_and_split "zero_extendhipsi2"
4473 [(set (match_operand:PSI 0 "register_operand" "=r")
4474 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4478 [(set (match_dup 2) (match_dup 1))
4479 (set (match_dup 3) (const_int 0))]
4481 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4482 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4485 (define_insn_and_split "n_extendhipsi2"
4486 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4487 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4488 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4489 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4493 [(set (match_dup 4) (match_dup 2))
4494 (set (match_dup 3) (match_dup 6))
4495 ; no-op move in the case where no scratch is needed
4496 (set (match_dup 5) (match_dup 3))]
4498 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4499 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4500 operands[6] = operands[1];
4502 if (GET_CODE (operands[3]) == SCRATCH)
4503 operands[3] = operands[5];
4506 (define_insn_and_split "zero_extendhisi2"
4507 [(set (match_operand:SI 0 "register_operand" "=r")
4508 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4512 [(set (match_dup 2) (match_dup 1))
4513 (set (match_dup 3) (const_int 0))]
4515 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4516 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4518 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4519 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4522 (define_insn_and_split "zero_extendpsisi2"
4523 [(set (match_operand:SI 0 "register_operand" "=r")
4524 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4528 [(set (match_dup 2) (match_dup 1))
4529 (set (match_dup 3) (const_int 0))]
4531 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4532 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4535 (define_insn_and_split "zero_extendqidi2"
4536 [(set (match_operand:DI 0 "register_operand" "=r")
4537 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4541 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4542 (set (match_dup 3) (const_int 0))]
4544 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4545 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4547 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4548 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4551 (define_insn_and_split "zero_extendhidi2"
4552 [(set (match_operand:DI 0 "register_operand" "=r")
4553 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4557 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4558 (set (match_dup 3) (const_int 0))]
4560 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4561 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4563 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4564 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4567 (define_insn_and_split "zero_extendsidi2"
4568 [(set (match_operand:DI 0 "register_operand" "=r")
4569 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4573 [(set (match_dup 2) (match_dup 1))
4574 (set (match_dup 3) (const_int 0))]
4576 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4577 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4579 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4580 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4583 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4586 ; Optimize negated tests into reverse compare if overflow is undefined.
4587 (define_insn "*negated_tstqi"
4589 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4591 "!flag_wrapv && !flag_trapv"
4592 "cp __zero_reg__,%0"
4593 [(set_attr "cc" "compare")
4594 (set_attr "length" "1")])
4596 (define_insn "*reversed_tstqi"
4598 (compare (const_int 0)
4599 (match_operand:QI 0 "register_operand" "r")))]
4601 "cp __zero_reg__,%0"
4602 [(set_attr "cc" "compare")
4603 (set_attr "length" "2")])
4605 (define_insn "*negated_tsthi"
4607 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4609 "!flag_wrapv && !flag_trapv"
4610 "cp __zero_reg__,%A0
4611 cpc __zero_reg__,%B0"
4612 [(set_attr "cc" "compare")
4613 (set_attr "length" "2")])
4615 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4616 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4617 (define_insn "*reversed_tsthi"
4619 (compare (const_int 0)
4620 (match_operand:HI 0 "register_operand" "r")))
4621 (clobber (match_scratch:QI 1 "=X"))]
4623 "cp __zero_reg__,%A0
4624 cpc __zero_reg__,%B0"
4625 [(set_attr "cc" "compare")
4626 (set_attr "length" "2")])
4628 (define_insn "*negated_tstpsi"
4630 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4632 "!flag_wrapv && !flag_trapv"
4633 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4634 [(set_attr "cc" "compare")
4635 (set_attr "length" "3")])
4637 (define_insn "*reversed_tstpsi"
4639 (compare (const_int 0)
4640 (match_operand:PSI 0 "register_operand" "r")))
4641 (clobber (match_scratch:QI 1 "=X"))]
4643 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4644 [(set_attr "cc" "compare")
4645 (set_attr "length" "3")])
4647 (define_insn "*negated_tstsi"
4649 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4651 "!flag_wrapv && !flag_trapv"
4652 "cp __zero_reg__,%A0
4653 cpc __zero_reg__,%B0
4654 cpc __zero_reg__,%C0
4655 cpc __zero_reg__,%D0"
4656 [(set_attr "cc" "compare")
4657 (set_attr "length" "4")])
4659 ;; "*reversed_tstsi"
4660 ;; "*reversed_tstsq" "*reversed_tstusq"
4661 ;; "*reversed_tstsa" "*reversed_tstusa"
4662 (define_insn "*reversed_tst<mode>"
4664 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4665 (match_operand:ALL4 1 "register_operand" "r")))
4666 (clobber (match_scratch:QI 2 "=X"))]
4668 "cp __zero_reg__,%A1
4669 cpc __zero_reg__,%B1
4670 cpc __zero_reg__,%C1
4671 cpc __zero_reg__,%D1"
4672 [(set_attr "cc" "compare")
4673 (set_attr "length" "4")])
4677 ;; "cmpqq3" "cmpuqq3"
4678 (define_insn "cmp<mode>3"
4680 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4681 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4687 [(set_attr "cc" "compare,compare,compare")
4688 (set_attr "length" "1,1,1")])
4690 (define_insn "*cmpqi_sign_extend"
4692 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4693 (match_operand:HI 1 "s8_operand" "n")))]
4696 [(set_attr "cc" "compare")
4697 (set_attr "length" "1")])
4700 (define_insn "*cmphi.zero-extend.0"
4702 (compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
4703 (match_operand:HI 1 "register_operand" "r")))]
4705 "cp %0,%A1\;cpc __zero_reg__,%B1"
4706 [(set_attr "cc" "compare")
4707 (set_attr "length" "2")])
4709 (define_insn "*cmphi.zero-extend.1"
4711 (compare (match_operand:HI 0 "register_operand" "r")
4712 (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
4714 "cp %A0,%1\;cpc %B0,__zero_reg__"
4715 [(set_attr "cc" "compare")
4716 (set_attr "length" "2")])
4719 ;; "cmphq3" "cmpuhq3"
4720 ;; "cmpha3" "cmpuha3"
4721 (define_insn "cmp<mode>3"
4723 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4724 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4725 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4728 switch (which_alternative)
4732 return avr_out_tsthi (insn, operands, NULL);
4735 return "cp %A0,%A1\;cpc %B0,%B1";
4738 if (<MODE>mode != HImode)
4740 return reg_unused_after (insn, operands[0])
4741 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4742 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4745 if (<MODE>mode != HImode)
4747 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4750 return avr_out_compare (insn, operands, NULL);
4752 [(set_attr "cc" "compare")
4753 (set_attr "length" "1,2,2,3,4,2,4")
4754 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4756 (define_insn "*cmppsi"
4758 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4759 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4760 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4763 switch (which_alternative)
4766 return avr_out_tstpsi (insn, operands, NULL);
4769 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4772 return reg_unused_after (insn, operands[0])
4773 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4774 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4777 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4780 return avr_out_compare (insn, operands, NULL);
4782 [(set_attr "cc" "compare")
4783 (set_attr "length" "3,3,5,6,3,7")
4784 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4787 ;; "*cmpsq" "*cmpusq"
4788 ;; "*cmpsa" "*cmpusa"
4789 (define_insn "*cmp<mode>"
4791 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4792 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4793 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4796 if (0 == which_alternative)
4797 return avr_out_tstsi (insn, operands, NULL);
4798 else if (1 == which_alternative)
4799 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4801 return avr_out_compare (insn, operands, NULL);
4803 [(set_attr "cc" "compare")
4804 (set_attr "length" "4,4,4,5,8")
4805 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4808 ;; ----------------------------------------------------------------------
4809 ;; JUMP INSTRUCTIONS
4810 ;; ----------------------------------------------------------------------
4811 ;; Conditional jump instructions
4814 ;; "cbranchqq4" "cbranchuqq4"
4815 (define_expand "cbranch<mode>4"
4817 (compare (match_operand:ALL1 1 "register_operand" "")
4818 (match_operand:ALL1 2 "nonmemory_operand" "")))
4821 (match_operator 0 "ordered_comparison_operator" [(cc0)
4823 (label_ref (match_operand 3 "" ""))
4826 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4827 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4829 (define_expand "cbranch<mode>4"
4830 [(parallel [(set (cc0)
4831 (compare (match_operand:ORDERED234 1 "register_operand" "")
4832 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4833 (clobber (match_scratch:QI 4 ""))])
4836 (match_operator 0 "ordered_comparison_operator" [(cc0)
4838 (label_ref (match_operand 3 "" ""))
4842 ;; Test a single bit in a QI/HI/SImode register.
4843 ;; Combine will create zero extract patterns for single bit tests.
4844 ;; permit any mode in source pattern by using VOIDmode.
4846 (define_insn "*sbrx_branch<mode>"
4849 (match_operator 0 "eqne_operator"
4851 (match_operand:VOID 1 "register_operand" "r")
4853 (match_operand 2 "const_int_operand" "n"))
4855 (label_ref (match_operand 3 "" ""))
4859 return avr_out_sbxx_branch (insn, operands);
4861 [(set (attr "length")
4862 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4863 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4865 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4868 (set_attr "cc" "clobber")])
4870 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4871 ;; or for old peepholes.
4872 ;; Fixme - bitwise Mask will not work for DImode
4874 (define_insn "*sbrx_and_branch<mode>"
4877 (match_operator 0 "eqne_operator"
4879 (match_operand:QISI 1 "register_operand" "r")
4880 (match_operand:QISI 2 "single_one_operand" "n"))
4882 (label_ref (match_operand 3 "" ""))
4886 HOST_WIDE_INT bitnumber;
4887 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4888 operands[2] = GEN_INT (bitnumber);
4889 return avr_out_sbxx_branch (insn, operands);
4891 [(set (attr "length")
4892 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4893 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4895 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4898 (set_attr "cc" "clobber")])
4900 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4902 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4904 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4905 (label_ref (match_operand 1 "" ""))
4908 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4912 (label_ref (match_dup 1))
4916 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4918 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4919 (label_ref (match_operand 1 "" ""))
4922 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4926 (label_ref (match_dup 1))
4930 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4932 (clobber (match_operand:HI 2 ""))])
4933 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4934 (label_ref (match_operand 1 "" ""))
4937 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4939 (label_ref (match_dup 1))
4943 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4945 (clobber (match_operand:HI 2 ""))])
4946 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4947 (label_ref (match_operand 1 "" ""))
4950 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4952 (label_ref (match_dup 1))
4956 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4958 (clobber (match_operand:SI 2 ""))])
4959 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4960 (label_ref (match_operand 1 "" ""))
4963 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4965 (label_ref (match_dup 1))
4967 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4970 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4972 (clobber (match_operand:SI 2 ""))])
4973 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4974 (label_ref (match_operand 1 "" ""))
4977 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4979 (label_ref (match_dup 1))
4981 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4983 ;; ************************************************************************
4984 ;; Implementation of conditional jumps here.
4985 ;; Compare with 0 (test) jumps
4986 ;; ************************************************************************
4988 (define_insn "branch"
4990 (if_then_else (match_operator 1 "simple_comparison_operator"
4993 (label_ref (match_operand 0 "" ""))
4997 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4999 [(set_attr "type" "branch")
5000 (set_attr "cc" "clobber")])
5003 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
5004 ;; or optimized in the remainder.
5006 (define_insn "branch_unspec"
5008 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
5011 (label_ref (match_operand 0 "" ""))
5013 ] UNSPEC_IDENTITY))]
5016 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5018 [(set_attr "type" "branch")
5019 (set_attr "cc" "none")])
5021 ;; ****************************************************************
5022 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
5023 ;; Convert them all to proper jumps.
5024 ;; ****************************************************************/
5026 (define_insn "difficult_branch"
5028 (if_then_else (match_operator 1 "difficult_comparison_operator"
5031 (label_ref (match_operand 0 "" ""))
5035 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5037 [(set_attr "type" "branch1")
5038 (set_attr "cc" "clobber")])
5042 (define_insn "rvbranch"
5044 (if_then_else (match_operator 1 "simple_comparison_operator"
5048 (label_ref (match_operand 0 "" ""))))]
5051 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5053 [(set_attr "type" "branch1")
5054 (set_attr "cc" "clobber")])
5056 (define_insn "difficult_rvbranch"
5058 (if_then_else (match_operator 1 "difficult_comparison_operator"
5062 (label_ref (match_operand 0 "" ""))))]
5065 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5067 [(set_attr "type" "branch")
5068 (set_attr "cc" "clobber")])
5070 ;; **************************************************************************
5071 ;; Unconditional and other jump instructions.
5075 (label_ref (match_operand 0 "" "")))]
5078 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
5082 [(set (attr "length")
5083 (if_then_else (match_operand 0 "symbol_ref_operand" "")
5084 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5087 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
5088 (le (minus (pc) (match_dup 0)) (const_int 2047)))
5091 (set_attr "cc" "none")])
5095 ;; Operand 1 not used on the AVR.
5096 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5097 (define_expand "call"
5098 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5099 (match_operand:HI 1 "general_operand" ""))
5100 (use (const_int 0))])])
5102 ;; Operand 1 not used on the AVR.
5103 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5104 (define_expand "sibcall"
5105 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5106 (match_operand:HI 1 "general_operand" ""))
5107 (use (const_int 1))])])
5111 ;; Operand 2 not used on the AVR.
5112 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5113 (define_expand "call_value"
5114 [(parallel[(set (match_operand 0 "register_operand" "")
5115 (call (match_operand:HI 1 "call_insn_operand" "")
5116 (match_operand:HI 2 "general_operand" "")))
5117 (use (const_int 0))])])
5119 ;; Operand 2 not used on the AVR.
5120 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5121 (define_expand "sibcall_value"
5122 [(parallel[(set (match_operand 0 "register_operand" "")
5123 (call (match_operand:HI 1 "call_insn_operand" "")
5124 (match_operand:HI 2 "general_operand" "")))
5125 (use (const_int 1))])])
5127 (define_insn "call_insn"
5128 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
5129 (match_operand:HI 1 "general_operand" "X,X,X,X"))
5130 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
5131 ;; Operand 1 not used on the AVR.
5132 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5139 [(set_attr "cc" "clobber")
5140 (set_attr "length" "1,*,1,*")
5141 (set_attr "adjust_len" "*,call,*,call")])
5143 (define_insn "call_value_insn"
5144 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
5145 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
5146 (match_operand:HI 2 "general_operand" "X,X,X,X")))
5147 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
5148 ;; Operand 2 not used on the AVR.
5149 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5156 [(set_attr "cc" "clobber")
5157 (set_attr "length" "1,*,1,*")
5158 (set_attr "adjust_len" "*,call,*,call")])
5164 [(set_attr "cc" "none")
5165 (set_attr "length" "1")])
5169 (define_expand "indirect_jump"
5171 (match_operand:HI 0 "nonmemory_operand" ""))]
5174 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
5176 operands[0] = copy_to_mode_reg (HImode, operands[0]);
5181 (define_insn "*indirect_jump"
5183 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
5189 push %A0\;push %B0\;ret
5191 [(set_attr "length" "1,2,1,3,1")
5192 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
5193 (set_attr "cc" "none")])
5196 ;; For entries in jump table see avr_output_addr_vec.
5199 ;; "rjmp .L<n>" instructions for <= 8K devices
5200 ;; ".word gs(.L<n>)" addresses for > 8K devices
5201 (define_insn "*tablejump"
5203 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
5205 (use (label_ref (match_operand 1 "" "")))
5206 (clobber (match_dup 0))
5207 (clobber (const_int 0))]
5208 "!AVR_HAVE_EIJMP_EICALL"
5211 push %A0\;push %B0\;ret
5213 [(set_attr "length" "1,3,2")
5214 (set_attr "isa" "rjmp,rjmp,jmp")
5215 (set_attr "cc" "none,none,clobber")])
5217 (define_insn "*tablejump.3byte-pc"
5219 (unspec:HI [(reg:HI REG_Z)]
5221 (use (label_ref (match_operand 0 "" "")))
5222 (clobber (reg:HI REG_Z))
5223 (clobber (reg:QI 24))]
5224 "AVR_HAVE_EIJMP_EICALL"
5225 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
5226 [(set_attr "length" "6")
5227 (set_attr "isa" "eijmp")
5228 (set_attr "cc" "clobber")])
5231 ;; FIXME: casesi comes up with an SImode switch value $0 which
5232 ;; is quite some overhead because most code would use HI or
5233 ;; even QI. We add an AVR specific pass .avr-casesi which
5234 ;; tries to recover from the superfluous extension to SImode.
5236 ;; Using "tablejump" could be a way out, but this also does
5237 ;; not perform in a satisfying manner as the middle end will
5238 ;; already multiply the table index by 2. Note that this
5239 ;; multiplication is performed by libgcc's __tablejump2__.
5240 ;; The multiplication there, however, runs *after* the table
5241 ;; start (a byte address) has been added, not before it like
5242 ;; "tablejump" will do.
5244 ;; The preferred solution would be to let the middle ends pass
5245 ;; down information on the index as an additional casesi operand.
5247 ;; If this expander is changed, you'll likely have to go through
5248 ;; "casesi_<mode>_sequence" (used to recog + extract casesi
5249 ;; sequences in pass .avr-casesi) and propagate all adjustments
5250 ;; also to that pattern and the code of the extra pass.
5252 (define_expand "casesi"
5253 [(parallel [(set (match_dup 5)
5254 (plus:SI (match_operand:SI 0 "register_operand")
5255 (match_operand:SI 1 "const_int_operand")))
5256 (clobber (scratch:QI))])
5257 (parallel [(set (cc0)
5258 (compare (match_dup 5)
5259 (match_operand:SI 2 "const_int_operand")))
5260 (clobber (scratch:QI))])
5263 (if_then_else (gtu (cc0)
5265 (label_ref (match_operand 4))
5271 (parallel [(set (pc)
5272 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5273 (use (label_ref (match_dup 3)))
5274 (clobber (match_dup 7))
5275 (clobber (match_dup 8))])]
5278 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
5279 operands[5] = gen_reg_rtx (SImode);
5280 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
5282 if (AVR_HAVE_EIJMP_EICALL)
5284 operands[7] = gen_rtx_REG (HImode, REG_Z);
5285 operands[8] = all_regs_rtx[24];
5289 operands[6] = gen_rtx_PLUS (HImode, operands[6],
5290 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
5291 operands[7] = gen_reg_rtx (HImode);
5292 operands[8] = const0_rtx;
5297 ;; This insn is used only for easy operand extraction.
5298 ;; The elements must match an extension to SImode plus
5299 ;; a sequence generated by casesi above.
5301 ;; "casesi_qi_sequence"
5302 ;; "casesi_hi_sequence"
5303 (define_insn "casesi_<mode>_sequence"
5304 [(set (match_operand:SI 0 "register_operand")
5305 (match_operator:SI 9 "extend_operator"
5306 [(match_operand:QIHI 10 "register_operand")]))
5308 ;; What follows is a matcher for code from casesi.
5309 ;; We keep the same operand numbering (except for $9 and $10
5310 ;; which don't appear in casesi).
5311 (parallel [(set (match_operand:SI 5 "register_operand")
5312 (plus:SI (match_dup 0)
5313 (match_operand:SI 1 "const_int_operand")))
5314 (clobber (scratch:QI))])
5315 (parallel [(set (cc0)
5316 (compare (match_dup 5)
5317 (match_operand:SI 2 "const_int_operand")))
5318 (clobber (scratch:QI))])
5321 (if_then_else (gtu (cc0)
5323 (label_ref (match_operand 4))
5326 (set (match_operand:HI 7 "register_operand")
5327 (match_operand:HI 6))
5329 (parallel [(set (pc)
5330 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5331 (use (label_ref (match_operand 3)))
5332 (clobber (match_dup 7))
5333 (clobber (match_operand:QI 8))])]
5335 && avr_casei_sequence_check_operands (operands)"
5336 { gcc_unreachable(); }
5340 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5341 ;; This instruction sets Z flag
5344 [(set (cc0) (const_int 0))]
5347 [(set_attr "length" "1")
5348 (set_attr "cc" "compare")])
5350 ;; Clear/set/test a single bit in I/O address space.
5353 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5354 (and:QI (mem:QI (match_dup 0))
5355 (match_operand:QI 1 "single_zero_operand" "n")))]
5358 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5359 return "cbi %i0,%2";
5361 [(set_attr "length" "1")
5362 (set_attr "cc" "none")])
5365 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5366 (ior:QI (mem:QI (match_dup 0))
5367 (match_operand:QI 1 "single_one_operand" "n")))]
5370 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5371 return "sbi %i0,%2";
5373 [(set_attr "length" "1")
5374 (set_attr "cc" "none")])
5376 ;; Lower half of the I/O space - use sbic/sbis directly.
5377 (define_insn "*sbix_branch"
5380 (match_operator 0 "eqne_operator"
5382 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
5384 (match_operand 2 "const_int_operand" "n"))
5386 (label_ref (match_operand 3 "" ""))
5390 return avr_out_sbxx_branch (insn, operands);
5392 [(set (attr "length")
5393 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5394 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5396 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5399 (set_attr "cc" "clobber")])
5401 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5402 (define_insn "*sbix_branch_bit7"
5405 (match_operator 0 "gelt_operator"
5406 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
5408 (label_ref (match_operand 2 "" ""))
5412 operands[3] = operands[2];
5413 operands[2] = GEN_INT (7);
5414 return avr_out_sbxx_branch (insn, operands);
5416 [(set (attr "length")
5417 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5418 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5420 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5423 (set_attr "cc" "clobber")])
5425 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5426 (define_insn "*sbix_branch_tmp"
5429 (match_operator 0 "eqne_operator"
5431 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5433 (match_operand 2 "const_int_operand" "n"))
5435 (label_ref (match_operand 3 "" ""))
5439 return avr_out_sbxx_branch (insn, operands);
5441 [(set (attr "length")
5442 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5443 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5445 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5448 (set_attr "cc" "clobber")])
5450 (define_insn "*sbix_branch_tmp_bit7"
5453 (match_operator 0 "gelt_operator"
5454 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5456 (label_ref (match_operand 2 "" ""))
5460 operands[3] = operands[2];
5461 operands[2] = GEN_INT (7);
5462 return avr_out_sbxx_branch (insn, operands);
5464 [(set (attr "length")
5465 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5466 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5468 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5471 (set_attr "cc" "clobber")])
5473 ;; ************************* Peepholes ********************************
5475 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5476 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5477 (plus:SI (match_dup 0)
5479 (clobber (scratch:QI))])
5480 (parallel [(set (cc0)
5481 (compare (match_dup 0)
5483 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5485 (if_then_else (eqne (cc0)
5487 (label_ref (match_operand 2 "" ""))
5494 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5495 output_asm_insn ("sbiw %0,1" CR_TAB
5496 "sbc %C0,__zero_reg__" CR_TAB
5497 "sbc %D0,__zero_reg__", operands);
5499 output_asm_insn ("subi %A0,1" CR_TAB
5500 "sbc %B0,__zero_reg__" CR_TAB
5501 "sbc %C0,__zero_reg__" CR_TAB
5502 "sbc %D0,__zero_reg__", operands);
5504 jump_mode = avr_jump_mode (operands[2], insn);
5505 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5506 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5510 case 1: return "%1 %2";
5511 case 2: return "%1 .+2\;rjmp %2";
5512 case 3: return "%1 .+4\;jmp %2";
5519 (define_peephole ; "*dec-and-branchhi!=-1"
5520 [(set (match_operand:HI 0 "d_register_operand" "")
5521 (plus:HI (match_dup 0)
5523 (parallel [(set (cc0)
5524 (compare (match_dup 0)
5526 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5528 (if_then_else (eqne (cc0)
5530 (label_ref (match_operand 2 "" ""))
5537 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5538 output_asm_insn ("sbiw %0,1", operands);
5540 output_asm_insn ("subi %A0,1" CR_TAB
5541 "sbc %B0,__zero_reg__", operands);
5543 jump_mode = avr_jump_mode (operands[2], insn);
5544 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5545 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5549 case 1: return "%1 %2";
5550 case 2: return "%1 .+2\;rjmp %2";
5551 case 3: return "%1 .+4\;jmp %2";
5558 ;; Same as above but with clobber flavour of addhi3
5559 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5560 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5561 (plus:HI (match_dup 0)
5563 (clobber (scratch:QI))])
5564 (parallel [(set (cc0)
5565 (compare (match_dup 0)
5567 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5569 (if_then_else (eqne (cc0)
5571 (label_ref (match_operand 2 "" ""))
5578 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5579 output_asm_insn ("sbiw %0,1", operands);
5581 output_asm_insn ("subi %A0,1" CR_TAB
5582 "sbc %B0,__zero_reg__", operands);
5584 jump_mode = avr_jump_mode (operands[2], insn);
5585 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5586 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5590 case 1: return "%1 %2";
5591 case 2: return "%1 .+2\;rjmp %2";
5592 case 3: return "%1 .+4\;jmp %2";
5599 ;; Same as above but with clobber flavour of addhi3
5600 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5601 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5602 (plus:HI (match_dup 0)
5604 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5605 (parallel [(set (cc0)
5606 (compare (match_dup 0)
5608 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5610 (if_then_else (eqne (cc0)
5612 (label_ref (match_operand 2 "" ""))
5619 output_asm_insn ("ldi %3,1" CR_TAB
5621 "sbc %B0,__zero_reg__", operands);
5623 jump_mode = avr_jump_mode (operands[2], insn);
5624 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5625 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5629 case 1: return "%1 %2";
5630 case 2: return "%1 .+2\;rjmp %2";
5631 case 3: return "%1 .+4\;jmp %2";
5638 (define_peephole ; "*dec-and-branchqi!=-1"
5639 [(set (match_operand:QI 0 "d_register_operand" "")
5640 (plus:QI (match_dup 0)
5643 (compare (match_dup 0)
5646 (if_then_else (eqne (cc0)
5648 (label_ref (match_operand 1 "" ""))
5655 cc_status.value1 = operands[0];
5656 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5658 output_asm_insn ("subi %A0,1", operands);
5660 jump_mode = avr_jump_mode (operands[1], insn);
5661 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5662 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5666 case 1: return "%0 %1";
5667 case 2: return "%0 .+2\;rjmp %1";
5668 case 3: return "%0 .+4\;jmp %1";
5676 (define_peephole ; "*cpse.eq"
5678 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5679 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5681 (if_then_else (eq (cc0)
5683 (label_ref (match_operand 0 "" ""))
5685 "jump_over_one_insn_p (insn, operands[0])"
5688 cpse %1,__zero_reg__")
5690 ;; This peephole avoids code like
5693 ;; BREQ .+2 ; branch
5696 ;; Notice that the peephole is always shorter than cmpqi + branch.
5697 ;; The reason to write it as peephole is that sequences like
5702 ;; shall not be superseeded. With a respective combine pattern
5703 ;; the latter sequence would be
5706 ;; CPSE Rm, __zero_reg__
5709 ;; and thus longer and slower and not easy to be rolled back.
5711 (define_peephole ; "*cpse.ne"
5713 (compare (match_operand:ALL1 1 "register_operand" "")
5714 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5716 (if_then_else (ne (cc0)
5718 (label_ref (match_operand 0 "" ""))
5721 || !TARGET_SKIP_BUG"
5723 if (operands[2] == CONST0_RTX (<MODE>mode))
5724 operands[2] = zero_reg_rtx;
5726 return 3 == avr_jump_mode (operands[0], insn)
5727 ? "cpse %1,%2\;jmp %0"
5728 : "cpse %1,%2\;rjmp %0";
5731 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5732 ;;prologue/epilogue support instructions
5734 (define_insn "popqi"
5735 [(set (match_operand:QI 0 "register_operand" "=r")
5736 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5739 [(set_attr "cc" "none")
5740 (set_attr "length" "1")])
5742 ;; Enable Interrupts
5743 (define_expand "enable_interrupt"
5744 [(clobber (const_int 0))]
5747 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5748 MEM_VOLATILE_P (mem) = 1;
5749 emit_insn (gen_cli_sei (const1_rtx, mem));
5753 ;; Disable Interrupts
5754 (define_expand "disable_interrupt"
5755 [(clobber (const_int 0))]
5758 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5759 MEM_VOLATILE_P (mem) = 1;
5760 emit_insn (gen_cli_sei (const0_rtx, mem));
5764 (define_insn "cli_sei"
5765 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5766 UNSPECV_ENABLE_IRQS)
5767 (set (match_operand:BLK 1 "" "")
5768 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5773 [(set_attr "length" "1")
5774 (set_attr "cc" "none")])
5776 ;; Library prologue saves
5777 (define_insn "call_prologue_saves"
5778 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5779 (match_operand:HI 0 "immediate_operand" "i,i")
5780 (set (reg:HI REG_SP)
5781 (minus:HI (reg:HI REG_SP)
5782 (match_operand:HI 1 "immediate_operand" "i,i")))
5783 (use (reg:HI REG_X))
5784 (clobber (reg:HI REG_Z))]
5786 "ldi r30,lo8(gs(1f))
5788 %~jmp __prologue_saves__+((18 - %0) * 2)
5790 [(set_attr "length" "5,6")
5791 (set_attr "cc" "clobber")
5792 (set_attr "isa" "rjmp,jmp")])
5794 ; epilogue restores using library
5795 (define_insn "epilogue_restores"
5796 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5798 (plus:HI (reg:HI REG_Y)
5799 (match_operand:HI 0 "immediate_operand" "i,i")))
5800 (set (reg:HI REG_SP)
5801 (plus:HI (reg:HI REG_Y)
5803 (clobber (reg:QI REG_Z))]
5806 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5807 [(set_attr "length" "2,3")
5808 (set_attr "cc" "clobber")
5809 (set_attr "isa" "rjmp,jmp")])
5812 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue
5813 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
5814 (define_expand "gasisr"
5815 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
5816 (match_operand:QI 1 "const_int_operand")]
5818 (set (reg:HI REG_SP)
5819 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5821 (unspec_volatile:BLK [(match_dup 2)]
5822 UNSPECV_MEMORY_BARRIER))])]
5823 "avr_gasisr_prologues"
5825 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5826 MEM_VOLATILE_P (operands[2]) = 1;
5829 (define_insn "*gasisr"
5830 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
5831 (match_operand:QI 1 "const_int_operand" "n,n")]
5833 (set (reg:HI REG_SP)
5834 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5835 (set (match_operand:BLK 2)
5836 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))]
5837 "avr_gasisr_prologues"
5839 [(set_attr "length" "6,5")
5840 (set_attr "cc" "clobber")])
5844 (define_insn "return"
5846 "reload_completed && avr_simple_epilogue ()"
5848 [(set_attr "cc" "none")
5849 (set_attr "length" "1")])
5851 (define_insn "return_from_epilogue"
5855 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5856 && !cfun->machine->is_naked"
5858 [(set_attr "cc" "none")
5859 (set_attr "length" "1")])
5861 (define_insn "return_from_interrupt_epilogue"
5865 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5866 && !cfun->machine->is_naked"
5868 [(set_attr "cc" "none")
5869 (set_attr "length" "1")])
5871 (define_insn "return_from_naked_epilogue"
5875 && cfun->machine->is_naked"
5877 [(set_attr "cc" "none")
5878 (set_attr "length" "0")])
5880 (define_expand "prologue"
5884 avr_expand_prologue ();
5888 (define_expand "epilogue"
5892 avr_expand_epilogue (false /* sibcall_p */);
5896 (define_expand "sibcall_epilogue"
5900 avr_expand_epilogue (true /* sibcall_p */);
5904 ;; Some instructions resp. instruction sequences available
5907 (define_insn "delay_cycles_1"
5908 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5910 UNSPECV_DELAY_CYCLES)
5911 (set (match_operand:BLK 1 "" "")
5912 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5913 (clobber (match_scratch:QI 2 "=&d"))]
5918 [(set_attr "length" "3")
5919 (set_attr "cc" "clobber")])
5921 (define_insn "delay_cycles_2"
5922 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
5924 UNSPECV_DELAY_CYCLES)
5925 (set (match_operand:BLK 1 "" "")
5926 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5927 (clobber (match_scratch:HI 2 "=&w,&d"))]
5930 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b
5931 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b"
5932 [(set_attr "length" "4,5")
5933 (set_attr "isa" "no_tiny,tiny")
5934 (set_attr "cc" "clobber")])
5936 (define_insn "delay_cycles_3"
5937 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5939 UNSPECV_DELAY_CYCLES)
5940 (set (match_operand:BLK 1 "" "")
5941 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5942 (clobber (match_scratch:QI 2 "=&d"))
5943 (clobber (match_scratch:QI 3 "=&d"))
5944 (clobber (match_scratch:QI 4 "=&d"))]
5953 [(set_attr "length" "7")
5954 (set_attr "cc" "clobber")])
5956 (define_insn "delay_cycles_4"
5957 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5959 UNSPECV_DELAY_CYCLES)
5960 (set (match_operand:BLK 1 "" "")
5961 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5962 (clobber (match_scratch:QI 2 "=&d"))
5963 (clobber (match_scratch:QI 3 "=&d"))
5964 (clobber (match_scratch:QI 4 "=&d"))
5965 (clobber (match_scratch:QI 5 "=&d"))]
5976 [(set_attr "length" "9")
5977 (set_attr "cc" "clobber")])
5980 ;; __builtin_avr_insert_bits
5982 (define_insn "insert_bits"
5983 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5984 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5985 (match_operand:QI 2 "register_operand" "r ,r ,r")
5986 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5987 UNSPEC_INSERT_BITS))]
5990 return avr_out_insert_bits (operands, NULL);
5992 [(set_attr "adjust_len" "insert_bits")
5993 (set_attr "cc" "clobber")])
5996 ;; __builtin_avr_flash_segment
5998 ;; Just a helper for the next "official" expander.
6000 (define_expand "flash_segment1"
6001 [(set (match_operand:QI 0 "register_operand" "")
6002 (subreg:QI (match_operand:PSI 1 "register_operand" "")
6005 (compare (match_dup 0)
6008 (if_then_else (ge (cc0)
6010 (label_ref (match_operand 2 "" ""))
6015 (define_expand "flash_segment"
6016 [(parallel [(match_operand:QI 0 "register_operand" "")
6017 (match_operand:PSI 1 "register_operand" "")])]
6020 rtx label = gen_label_rtx ();
6021 emit (gen_flash_segment1 (operands[0], operands[1], label));
6026 ;; Actually, it's too late now to work out address spaces known at compiletime.
6027 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
6028 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
6029 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
6031 (define_insn_and_split "*split.flash_segment"
6032 [(set (match_operand:QI 0 "register_operand" "=d")
6033 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
6034 (match_operand:HI 2 "register_operand" "r"))
6037 { gcc_unreachable(); }
6045 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
6046 ;; better 8-bit parity recognition.
6048 (define_expand "parityhi2"
6049 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6050 (parity:HI (match_operand:HI 1 "register_operand" "")))
6051 (clobber (reg:HI 24))])])
6053 (define_insn_and_split "*parityhi2"
6054 [(set (match_operand:HI 0 "register_operand" "=r")
6055 (parity:HI (match_operand:HI 1 "register_operand" "r")))
6056 (clobber (reg:HI 24))]
6058 { gcc_unreachable(); }
6063 (parity:HI (reg:HI 24)))
6067 (define_insn_and_split "*parityqihi2"
6068 [(set (match_operand:HI 0 "register_operand" "=r")
6069 (parity:HI (match_operand:QI 1 "register_operand" "r")))
6070 (clobber (reg:HI 24))]
6072 { gcc_unreachable(); }
6077 (zero_extend:HI (parity:QI (reg:QI 24))))
6081 (define_expand "paritysi2"
6083 (match_operand:SI 1 "register_operand" ""))
6085 (truncate:HI (parity:SI (reg:SI 22))))
6088 (set (match_operand:SI 0 "register_operand" "")
6089 (zero_extend:SI (match_dup 2)))]
6092 operands[2] = gen_reg_rtx (HImode);
6095 (define_insn "*parityhi2.libgcc"
6097 (parity:HI (reg:HI 24)))]
6099 "%~call __parityhi2"
6100 [(set_attr "type" "xcall")
6101 (set_attr "cc" "clobber")])
6103 (define_insn "*parityqihi2.libgcc"
6105 (zero_extend:HI (parity:QI (reg:QI 24))))]
6107 "%~call __parityqi2"
6108 [(set_attr "type" "xcall")
6109 (set_attr "cc" "clobber")])
6111 (define_insn "*paritysihi2.libgcc"
6113 (truncate:HI (parity:SI (reg:SI 22))))]
6115 "%~call __paritysi2"
6116 [(set_attr "type" "xcall")
6117 (set_attr "cc" "clobber")])
6122 (define_expand "popcounthi2"
6124 (match_operand:HI 1 "register_operand" ""))
6126 (popcount:HI (reg:HI 24)))
6127 (set (match_operand:HI 0 "register_operand" "")
6132 (define_expand "popcountsi2"
6134 (match_operand:SI 1 "register_operand" ""))
6136 (truncate:HI (popcount:SI (reg:SI 22))))
6139 (set (match_operand:SI 0 "register_operand" "")
6140 (zero_extend:SI (match_dup 2)))]
6143 operands[2] = gen_reg_rtx (HImode);
6146 (define_insn "*popcounthi2.libgcc"
6148 (popcount:HI (reg:HI 24)))]
6150 "%~call __popcounthi2"
6151 [(set_attr "type" "xcall")
6152 (set_attr "cc" "clobber")])
6154 (define_insn "*popcountsi2.libgcc"
6156 (truncate:HI (popcount:SI (reg:SI 22))))]
6158 "%~call __popcountsi2"
6159 [(set_attr "type" "xcall")
6160 (set_attr "cc" "clobber")])
6162 (define_insn "*popcountqi2.libgcc"
6164 (popcount:QI (reg:QI 24)))]
6166 "%~call __popcountqi2"
6167 [(set_attr "type" "xcall")
6168 (set_attr "cc" "clobber")])
6170 (define_insn_and_split "*popcountqihi2.libgcc"
6172 (zero_extend:HI (popcount:QI (reg:QI 24))))]
6177 (popcount:QI (reg:QI 24)))
6181 ;; Count Leading Zeros
6183 (define_expand "clzhi2"
6185 (match_operand:HI 1 "register_operand" ""))
6186 (parallel [(set (reg:HI 24)
6187 (clz:HI (reg:HI 24)))
6188 (clobber (reg:QI 26))])
6189 (set (match_operand:HI 0 "register_operand" "")
6192 (define_expand "clzsi2"
6194 (match_operand:SI 1 "register_operand" ""))
6195 (parallel [(set (reg:HI 24)
6196 (truncate:HI (clz:SI (reg:SI 22))))
6197 (clobber (reg:QI 26))])
6200 (set (match_operand:SI 0 "register_operand" "")
6201 (zero_extend:SI (match_dup 2)))]
6204 operands[2] = gen_reg_rtx (HImode);
6207 (define_insn "*clzhi2.libgcc"
6209 (clz:HI (reg:HI 24)))
6210 (clobber (reg:QI 26))]
6213 [(set_attr "type" "xcall")
6214 (set_attr "cc" "clobber")])
6216 (define_insn "*clzsihi2.libgcc"
6218 (truncate:HI (clz:SI (reg:SI 22))))
6219 (clobber (reg:QI 26))]
6222 [(set_attr "type" "xcall")
6223 (set_attr "cc" "clobber")])
6225 ;; Count Trailing Zeros
6227 (define_expand "ctzhi2"
6229 (match_operand:HI 1 "register_operand" ""))
6230 (parallel [(set (reg:HI 24)
6231 (ctz:HI (reg:HI 24)))
6232 (clobber (reg:QI 26))])
6233 (set (match_operand:HI 0 "register_operand" "")
6236 (define_expand "ctzsi2"
6238 (match_operand:SI 1 "register_operand" ""))
6239 (parallel [(set (reg:HI 24)
6240 (truncate:HI (ctz:SI (reg:SI 22))))
6241 (clobber (reg:QI 22))
6242 (clobber (reg:QI 26))])
6245 (set (match_operand:SI 0 "register_operand" "")
6246 (zero_extend:SI (match_dup 2)))]
6249 operands[2] = gen_reg_rtx (HImode);
6252 (define_insn "*ctzhi2.libgcc"
6254 (ctz:HI (reg:HI 24)))
6255 (clobber (reg:QI 26))]
6258 [(set_attr "type" "xcall")
6259 (set_attr "cc" "clobber")])
6261 (define_insn "*ctzsihi2.libgcc"
6263 (truncate:HI (ctz:SI (reg:SI 22))))
6264 (clobber (reg:QI 22))
6265 (clobber (reg:QI 26))]
6268 [(set_attr "type" "xcall")
6269 (set_attr "cc" "clobber")])
6273 (define_expand "ffshi2"
6275 (match_operand:HI 1 "register_operand" ""))
6276 (parallel [(set (reg:HI 24)
6277 (ffs:HI (reg:HI 24)))
6278 (clobber (reg:QI 26))])
6279 (set (match_operand:HI 0 "register_operand" "")
6282 (define_expand "ffssi2"
6284 (match_operand:SI 1 "register_operand" ""))
6285 (parallel [(set (reg:HI 24)
6286 (truncate:HI (ffs:SI (reg:SI 22))))
6287 (clobber (reg:QI 22))
6288 (clobber (reg:QI 26))])
6291 (set (match_operand:SI 0 "register_operand" "")
6292 (zero_extend:SI (match_dup 2)))]
6295 operands[2] = gen_reg_rtx (HImode);
6298 (define_insn "*ffshi2.libgcc"
6300 (ffs:HI (reg:HI 24)))
6301 (clobber (reg:QI 26))]
6304 [(set_attr "type" "xcall")
6305 (set_attr "cc" "clobber")])
6307 (define_insn "*ffssihi2.libgcc"
6309 (truncate:HI (ffs:SI (reg:SI 22))))
6310 (clobber (reg:QI 22))
6311 (clobber (reg:QI 26))]
6314 [(set_attr "type" "xcall")
6315 (set_attr "cc" "clobber")])
6319 (define_insn "copysignsf3"
6320 [(set (match_operand:SF 0 "register_operand" "=r")
6321 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
6322 (match_operand:SF 2 "register_operand" "r")]
6325 "bst %D2,7\;bld %D0,7"
6326 [(set_attr "length" "2")
6327 (set_attr "cc" "none")])
6329 ;; Swap Bytes (change byte-endianness)
6331 (define_expand "bswapsi2"
6333 (match_operand:SI 1 "register_operand" ""))
6335 (bswap:SI (reg:SI 22)))
6336 (set (match_operand:SI 0 "register_operand" "")
6339 (define_insn "*bswapsi2.libgcc"
6341 (bswap:SI (reg:SI 22)))]
6344 [(set_attr "type" "xcall")
6345 (set_attr "cc" "clobber")])
6350 ;; NOP taking 1 or 2 Ticks
6351 (define_expand "nopv"
6352 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
6355 (unspec_volatile:BLK [(match_dup 1)]
6356 UNSPECV_MEMORY_BARRIER))])]
6359 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6360 MEM_VOLATILE_P (operands[1]) = 1;
6363 (define_insn "*nopv"
6364 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6366 (set (match_operand:BLK 1 "" "")
6367 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6372 [(set_attr "length" "1")
6373 (set_attr "cc" "none")])
6376 (define_expand "sleep"
6377 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6379 (unspec_volatile:BLK [(match_dup 0)]
6380 UNSPECV_MEMORY_BARRIER))])]
6383 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6384 MEM_VOLATILE_P (operands[0]) = 1;
6387 (define_insn "*sleep"
6388 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6389 (set (match_operand:BLK 0 "" "")
6390 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6393 [(set_attr "length" "1")
6394 (set_attr "cc" "none")])
6397 (define_expand "wdr"
6398 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6400 (unspec_volatile:BLK [(match_dup 0)]
6401 UNSPECV_MEMORY_BARRIER))])]
6404 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6405 MEM_VOLATILE_P (operands[0]) = 1;
6409 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6410 (set (match_operand:BLK 0 "" "")
6411 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6414 [(set_attr "length" "1")
6415 (set_attr "cc" "none")])
6418 (define_expand "fmul"
6420 (match_operand:QI 1 "register_operand" ""))
6422 (match_operand:QI 2 "register_operand" ""))
6423 (parallel [(set (reg:HI 22)
6424 (unspec:HI [(reg:QI 24)
6425 (reg:QI 25)] UNSPEC_FMUL))
6426 (clobber (reg:HI 24))])
6427 (set (match_operand:HI 0 "register_operand" "")
6433 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6436 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6439 (define_insn "fmul_insn"
6440 [(set (match_operand:HI 0 "register_operand" "=r")
6441 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6442 (match_operand:QI 2 "register_operand" "a")]
6448 [(set_attr "length" "3")
6449 (set_attr "cc" "clobber")])
6451 (define_insn "*fmul.call"
6453 (unspec:HI [(reg:QI 24)
6454 (reg:QI 25)] UNSPEC_FMUL))
6455 (clobber (reg:HI 24))]
6458 [(set_attr "type" "xcall")
6459 (set_attr "cc" "clobber")])
6462 (define_expand "fmuls"
6464 (match_operand:QI 1 "register_operand" ""))
6466 (match_operand:QI 2 "register_operand" ""))
6467 (parallel [(set (reg:HI 22)
6468 (unspec:HI [(reg:QI 24)
6469 (reg:QI 25)] UNSPEC_FMULS))
6470 (clobber (reg:HI 24))])
6471 (set (match_operand:HI 0 "register_operand" "")
6477 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6480 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6483 (define_insn "fmuls_insn"
6484 [(set (match_operand:HI 0 "register_operand" "=r")
6485 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6486 (match_operand:QI 2 "register_operand" "a")]
6492 [(set_attr "length" "3")
6493 (set_attr "cc" "clobber")])
6495 (define_insn "*fmuls.call"
6497 (unspec:HI [(reg:QI 24)
6498 (reg:QI 25)] UNSPEC_FMULS))
6499 (clobber (reg:HI 24))]
6502 [(set_attr "type" "xcall")
6503 (set_attr "cc" "clobber")])
6506 (define_expand "fmulsu"
6508 (match_operand:QI 1 "register_operand" ""))
6510 (match_operand:QI 2 "register_operand" ""))
6511 (parallel [(set (reg:HI 22)
6512 (unspec:HI [(reg:QI 24)
6513 (reg:QI 25)] UNSPEC_FMULSU))
6514 (clobber (reg:HI 24))])
6515 (set (match_operand:HI 0 "register_operand" "")
6521 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6524 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6527 (define_insn "fmulsu_insn"
6528 [(set (match_operand:HI 0 "register_operand" "=r")
6529 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6530 (match_operand:QI 2 "register_operand" "a")]
6536 [(set_attr "length" "3")
6537 (set_attr "cc" "clobber")])
6539 (define_insn "*fmulsu.call"
6541 (unspec:HI [(reg:QI 24)
6542 (reg:QI 25)] UNSPEC_FMULSU))
6543 (clobber (reg:HI 24))]
6546 [(set_attr "type" "xcall")
6547 (set_attr "cc" "clobber")])
6550 ;; Some combiner patterns dealing with bits.
6553 ;; Move bit $3.0 into bit $0.$4
6554 (define_insn "*movbitqi.1-6.a"
6555 [(set (match_operand:QI 0 "register_operand" "=r")
6556 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6557 (match_operand:QI 2 "single_zero_operand" "n"))
6558 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6559 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6560 (match_operand:QI 5 "single_one_operand" "n"))))]
6561 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6562 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6563 "bst %3,0\;bld %0,%4"
6564 [(set_attr "length" "2")
6565 (set_attr "cc" "none")])
6567 ;; Move bit $3.0 into bit $0.$4
6568 ;; Variation of above. Unfortunately, there is no canonicalized representation
6569 ;; of moving around bits. So what we see here depends on how user writes down
6570 ;; bit manipulations.
6571 (define_insn "*movbitqi.1-6.b"
6572 [(set (match_operand:QI 0 "register_operand" "=r")
6573 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6574 (match_operand:QI 2 "single_zero_operand" "n"))
6575 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6577 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6578 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6579 "bst %3,0\;bld %0,%4"
6580 [(set_attr "length" "2")
6581 (set_attr "cc" "none")])
6583 ;; Move bit $3.0 into bit $0.0.
6584 ;; For bit 0, combiner generates slightly different pattern.
6585 (define_insn "*movbitqi.0"
6586 [(set (match_operand:QI 0 "register_operand" "=r")
6587 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6588 (match_operand:QI 2 "single_zero_operand" "n"))
6589 (and:QI (match_operand:QI 3 "register_operand" "r")
6591 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6592 "bst %3,0\;bld %0,0"
6593 [(set_attr "length" "2")
6594 (set_attr "cc" "none")])
6596 ;; Move bit $2.0 into bit $0.7.
6597 ;; For bit 7, combiner generates slightly different pattern
6598 (define_insn "*movbitqi.7"
6599 [(set (match_operand:QI 0 "register_operand" "=r")
6600 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6602 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6605 "bst %2,0\;bld %0,7"
6606 [(set_attr "length" "2")
6607 (set_attr "cc" "none")])
6609 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6610 ;; and input/output match. We provide a special pattern for this, because
6611 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6612 ;; operation on I/O is atomic.
6613 (define_insn "*insv.io"
6614 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
6616 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6617 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6622 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6623 [(set_attr "length" "1,1,4")
6624 (set_attr "cc" "none")])
6626 (define_insn "*insv.not.io"
6627 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
6629 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6630 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6632 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6633 [(set_attr "length" "4")
6634 (set_attr "cc" "none")])
6636 ;; The insv expander.
6637 ;; We only support 1-bit inserts
6638 (define_expand "insv"
6639 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6640 (match_operand:QI 1 "const1_operand" "") ; width
6641 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6642 (match_operand:QI 3 "nonmemory_operand" ""))]
6645 ;; Some more patterns to support moving around one bit which can be accomplished
6646 ;; by BST + BLD in most situations. Unfortunately, there is no canonical
6647 ;; representation, and we just implement some more cases that are not too
6650 ;; Insert bit $2.0 into $0.$1
6651 (define_insn "*insv.reg"
6652 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6654 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6655 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6659 andi %0,lo8(~(1<<%1))
6663 [(set_attr "length" "2,1,1,2,2")
6664 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6666 ;; Insert bit $2.$3 into $0.$1
6667 (define_insn "*insv.extract"
6668 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6670 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6671 (any_extract:QI (match_operand:QI 2 "register_operand" "r")
6673 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6675 "bst %2,%3\;bld %0,%1"
6676 [(set_attr "length" "2")
6677 (set_attr "cc" "none")])
6679 ;; Insert bit $2.$3 into $0.$1
6680 (define_insn "*insv.shiftrt"
6681 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6683 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6684 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6685 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6687 "bst %2,%3\;bld %0,%1"
6688 [(set_attr "length" "2")
6689 (set_attr "cc" "none")])
6691 ;; Same, but with a NOT inverting the source bit.
6692 ;; Insert bit ~$2.$3 into $0.$1
6693 (define_insn "*insv.not-shiftrt"
6694 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6696 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6697 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6698 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
6701 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6703 [(set_attr "adjust_len" "insv_notbit")
6704 (set_attr "cc" "clobber")])
6706 ;; Insert bit ~$2.0 into $0.$1
6707 (define_insn "*insv.xor1-bit.0"
6708 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6710 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6711 (xor:QI (match_operand:QI 2 "register_operand" "r")
6715 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6717 [(set_attr "adjust_len" "insv_notbit_0")
6718 (set_attr "cc" "clobber")])
6720 ;; Insert bit ~$2.0 into $0.$1
6721 (define_insn "*insv.not-bit.0"
6722 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6724 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6725 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6728 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6730 [(set_attr "adjust_len" "insv_notbit_0")
6731 (set_attr "cc" "clobber")])
6733 ;; Insert bit ~$2.7 into $0.$1
6734 (define_insn "*insv.not-bit.7"
6735 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6737 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6738 (ge:QI (match_operand:QI 2 "register_operand" "r")
6742 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
6744 [(set_attr "adjust_len" "insv_notbit_7")
6745 (set_attr "cc" "clobber")])
6747 ;; Insert bit ~$2.$3 into $0.$1
6748 (define_insn "*insv.xor-extract"
6749 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6751 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6752 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
6753 (match_operand:QI 4 "const_int_operand" "n"))
6755 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6756 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
6758 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6760 [(set_attr "adjust_len" "insv_notbit")
6761 (set_attr "cc" "clobber")])
6764 ;; Some combine patterns that try to fix bad code when a value is composed
6765 ;; from byte parts like in PR27663.
6766 ;; The patterns give some release but the code still is not optimal,
6767 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6768 ;; That switch obfuscates things here and in many other places.
6770 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6771 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6772 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6773 [(set (match_operand:HISI 0 "register_operand" "=r")
6775 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6776 (match_operand:HISI 2 "register_operand" "0")))]
6781 (xior:QI (match_dup 3)
6784 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6787 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6788 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6789 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6790 [(set (match_operand:HISI 0 "register_operand" "=r")
6792 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6793 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6794 (match_operand:HISI 3 "register_operand" "0")))]
6795 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6797 "&& reload_completed"
6799 (xior:QI (match_dup 4)
6802 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6803 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6807 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
6808 [(set (match_operand:HI 0 "register_operand" "=r,r")
6809 (ior:HI (ashift:HI (any_extend:HI
6810 (match_operand:QI 1 "register_operand" "r,r"))
6812 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))]
6814 { gcc_unreachable(); }
6815 "&& reload_completed"
6816 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
6817 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
6818 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
6820 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6821 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6823 if (!reg_overlap_mentioned_p (hi, operands[2]))
6825 emit_move_insn (hi, operands[1]);
6826 emit_move_insn (lo, operands[2]);
6829 else if (!reg_overlap_mentioned_p (lo, operands[1]))
6831 emit_move_insn (lo, operands[2]);
6832 emit_move_insn (hi, operands[1]);
6836 gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
6837 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
6840 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
6841 [(set (match_operand:HI 0 "register_operand" "=r")
6842 (ior:HI (ashift:HI (any_extend:HI
6843 (match_operand:QI 1 "register_operand" "r"))
6845 (match_operand:HI 2 "register_operand" "0")))]
6847 { gcc_unreachable(); }
6848 "&& reload_completed"
6850 (ior:QI (match_dup 4)
6853 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6854 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
6857 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
6858 [(set (match_operand:HI 0 "register_operand" "=r")
6859 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
6861 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
6863 { gcc_unreachable(); }
6864 "&& reload_completed"
6868 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6869 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
6874 [(set (match_operand:QI 0 "register_operand")
6877 (ior:QI (match_dup 0)
6878 (match_operand:QI 1 "register_operand")))]
6884 (define_expand "extzv"
6885 [(set (match_operand:QI 0 "register_operand" "")
6886 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6887 (match_operand:QI 2 "const1_operand" "")
6888 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6890 (define_insn "*extzv"
6891 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6892 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6894 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6898 mov %0,%1\;andi %0,1
6901 bst %1,%2\;clr %0\;bld %0,0"
6902 [(set_attr "length" "1,2,2,2,3")
6903 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6905 (define_insn_and_split "*extzv.qihi1"
6906 [(set (match_operand:HI 0 "register_operand" "=r")
6907 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6909 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6914 (zero_extract:QI (match_dup 1)
6920 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6921 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6924 (define_insn_and_split "*extzv.qihi2"
6925 [(set (match_operand:HI 0 "register_operand" "=r")
6927 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6929 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6934 (zero_extract:QI (match_dup 1)
6940 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6941 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6944 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
6945 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example.
6946 (define_insn_and_split "*extract.subreg.bit"
6947 [(set (match_operand:QI 0 "register_operand" "=r")
6948 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
6949 (match_operand:QI 2 "const_int_operand" "n"))
6952 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6953 { gcc_unreachable(); }
6954 "&& reload_completed"
6957 (zero_extract:QI (match_dup 3)
6961 int bitno = INTVAL (operands[2]);
6962 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
6963 operands[4] = GEN_INT (bitno % 8);
6967 ;; Fixed-point instructions
6968 (include "avr-fixed.md")
6970 ;; Operations on 64-bit registers
6971 (include "avr-dimode.md")