1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998-2017 Free Software Foundation, Inc.
4 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
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 "movmemhi"
996 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
997 (match_operand:BLK 1 "memory_operand" ""))
998 (use (match_operand:HI 2 "const_int_operand" ""))
999 (use (match_operand:HI 3 "const_int_operand" ""))])]
1002 if (avr_emit_movmemhi (operands))
1008 (define_mode_attr MOVMEM_r_d [(QI "r")
1011 ;; $0 : Address Space
1012 ;; $1, $2 : Loop register
1013 ;; R30 : source address
1014 ;; R26 : destination address
1018 (define_insn "movmem_<mode>"
1019 [(set (mem:BLK (reg:HI REG_X))
1020 (mem:BLK (reg:HI REG_Z)))
1021 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1023 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
1024 (clobber (reg:HI REG_X))
1025 (clobber (reg:HI REG_Z))
1026 (clobber (reg:QI LPM_REGNO))
1027 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
1030 return avr_out_movmem (insn, operands, NULL);
1032 [(set_attr "adjust_len" "movmem")
1033 (set_attr "cc" "clobber")])
1036 ;; $0 : Address Space
1037 ;; $1 : RAMPZ RAM address
1038 ;; R24 : #bytes and loop register
1039 ;; R23:Z : 24-bit source address
1040 ;; R26 : 16-bit destination address
1044 (define_insn "movmemx_<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"))]
3372 || const0_rtx == operands[1])"
3373 [(set (match_dup 2) (match_dup 3))
3374 (set (match_dup 4) (match_dup 5))]
3376 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3377 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
3378 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3379 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3382 ;; Split andhi3, andpsi3, andsi3.
3383 ;; Split iorhi3, iorpsi3, iorsi3.
3384 ;; Split xorhi3, xorpsi3, xorsi3.
3386 [(parallel [(set (match_operand:HISI 0 "register_operand")
3387 (bitop:HISI (match_dup 0)
3388 (match_operand:HISI 1 "register_operand")))
3389 (clobber (scratch:QI))])]
3391 && reload_completed"
3394 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
3396 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
3397 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
3398 emit_insn (gen_<code>qi3 (dst, dst, src));
3404 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3407 (define_expand "rotlqi3"
3408 [(set (match_operand:QI 0 "register_operand" "")
3409 (rotate:QI (match_operand:QI 1 "register_operand" "")
3410 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3413 if (!CONST_INT_P (operands[2]))
3416 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3419 ;; Expander used by __builtin_avr_swap
3420 (define_expand "rotlqi3_4"
3421 [(set (match_operand:QI 0 "register_operand" "")
3422 (rotate:QI (match_operand:QI 1 "register_operand" "")
3425 (define_insn "*rotlqi3"
3426 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3427 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3428 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3431 lsl %0\;adc %0,__zero_reg__
3432 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3433 swap %0\;bst %0,0\;ror %0\;bld %0,7
3435 swap %0\;lsl %0\;adc %0,__zero_reg__
3436 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3437 bst %0,0\;ror %0\;bld %0,7
3439 [(set_attr "length" "2,4,4,1,3,5,3,0")
3440 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3442 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3443 ;; a whole number of bytes. The split creates the appropriate moves and
3444 ;; considers all overlap situations.
3446 ;; HImode does not need scratch. Use attribute for this constraint.
3448 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3449 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3454 (define_expand "rotl<mode>3"
3455 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3456 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3457 (match_operand:HISI 2 "const_int_operand" "")))
3458 (clobber (match_dup 3))])]
3463 if (!CONST_INT_P (operands[2]))
3466 offset = INTVAL (operands[2]);
3468 if (0 == offset % 8)
3470 if (AVR_HAVE_MOVW && 0 == offset % 16)
3471 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3473 operands[3] = gen_rtx_SCRATCH (QImode);
3475 else if (offset == 1
3476 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3478 /*; Support rotate left/right by 1 */
3480 emit_move_insn (operands[0],
3481 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3488 (define_insn "*rotlhi2.1"
3489 [(set (match_operand:HI 0 "register_operand" "=r")
3490 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3493 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3494 [(set_attr "length" "3")
3495 (set_attr "cc" "clobber")])
3497 (define_insn "*rotlhi2.15"
3498 [(set (match_operand:HI 0 "register_operand" "=r")
3499 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3502 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3503 [(set_attr "length" "4")
3504 (set_attr "cc" "clobber")])
3506 (define_insn "*rotlpsi2.1"
3507 [(set (match_operand:PSI 0 "register_operand" "=r")
3508 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3511 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3512 [(set_attr "length" "4")
3513 (set_attr "cc" "clobber")])
3515 (define_insn "*rotlpsi2.23"
3516 [(set (match_operand:PSI 0 "register_operand" "=r")
3517 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3520 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3521 [(set_attr "length" "5")
3522 (set_attr "cc" "clobber")])
3524 (define_insn "*rotlsi2.1"
3525 [(set (match_operand:SI 0 "register_operand" "=r")
3526 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3529 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3530 [(set_attr "length" "5")
3531 (set_attr "cc" "clobber")])
3533 (define_insn "*rotlsi2.31"
3534 [(set (match_operand:SI 0 "register_operand" "=r")
3535 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3538 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3539 [(set_attr "length" "6")
3540 (set_attr "cc" "clobber")])
3542 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3543 ;; The best we can do is use early clobber alternative "#&r" so that
3544 ;; completely non-overlapping operands dont get a scratch but # so register
3545 ;; allocation does not prefer non-overlapping.
3548 ;; Split word aligned rotates using scratch that is mode dependent.
3552 (define_insn_and_split "*rotw<mode>"
3553 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3554 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3555 (match_operand 2 "const_int_operand" "n,n,n")))
3556 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3558 && CONST_INT_P (operands[2])
3559 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3560 && 0 == INTVAL (operands[2]) % 16"
3562 "&& reload_completed"
3565 avr_rotate_bytes (operands);
3570 ;; Split byte aligned rotates using scratch that is always QI mode.
3575 (define_insn_and_split "*rotb<mode>"
3576 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3577 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3578 (match_operand 2 "const_int_operand" "n,n,n")))
3579 (clobber (match_scratch:QI 3 "=<rotx>"))]
3580 "CONST_INT_P (operands[2])
3581 && (8 == INTVAL (operands[2]) % 16
3583 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3584 && 0 == INTVAL (operands[2]) % 16))"
3586 "&& reload_completed"
3589 avr_rotate_bytes (operands);
3594 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3595 ;; arithmetic shift left
3598 ;; "ashlqq3" "ashluqq3"
3599 (define_expand "ashl<mode>3"
3600 [(set (match_operand:ALL1 0 "register_operand" "")
3601 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3602 (match_operand:QI 2 "nop_general_operand" "")))])
3604 (define_split ; ashlqi3_const4
3605 [(set (match_operand:ALL1 0 "d_register_operand" "")
3606 (ashift:ALL1 (match_dup 0)
3610 (rotate:QI (match_dup 1)
3613 (and:QI (match_dup 1)
3616 operands[1] = avr_to_int_mode (operands[0]);
3619 (define_split ; ashlqi3_const5
3620 [(set (match_operand:ALL1 0 "d_register_operand" "")
3621 (ashift:ALL1 (match_dup 0)
3624 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3625 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3626 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3628 operands[1] = avr_to_int_mode (operands[0]);
3631 (define_split ; ashlqi3_const6
3632 [(set (match_operand:ALL1 0 "d_register_operand" "")
3633 (ashift:ALL1 (match_dup 0)
3636 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3637 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3638 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3640 operands[1] = avr_to_int_mode (operands[0]);
3644 ;; "*ashlqq3" "*ashluqq3"
3645 (define_insn "*ashl<mode>3"
3646 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3647 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3648 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3651 return ashlqi3_out (insn, operands, NULL);
3653 [(set_attr "length" "5,0,1,2,4,6,9")
3654 (set_attr "adjust_len" "ashlqi")
3655 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3657 (define_insn "ashl<mode>3"
3658 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3659 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3660 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3663 return ashlhi3_out (insn, operands, NULL);
3665 [(set_attr "length" "6,0,2,2,4,10,10")
3666 (set_attr "adjust_len" "ashlhi")
3667 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3670 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3671 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3675 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3676 [(set (match_operand:QI 0 "register_operand" "=r")
3677 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3678 (match_operand:QI 2 "register_operand" "r"))
3684 (ashift:QI (match_dup 1)
3687 ;; ??? Combiner does not recognize that it could split the following insn;
3688 ;; presumably because he has no register handy?
3690 ;; "*ashluqihiqi3.mem"
3691 ;; "*ashlsqihiqi3.mem"
3692 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3693 [(set (match_operand:QI 0 "memory_operand" "=m")
3694 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3695 (match_operand:QI 2 "register_operand" "r"))
3698 { gcc_unreachable(); }
3701 (ashift:QI (match_dup 1)
3706 operands[3] = gen_reg_rtx (QImode);
3711 (define_insn_and_split "*ashlhiqi3"
3712 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3713 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3714 (match_operand:QI 2 "register_operand" "r")) 0))]
3716 { gcc_unreachable(); }
3719 (ashift:QI (match_dup 3)
3724 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3725 operands[4] = gen_reg_rtx (QImode);
3728 ;; High part of 16-bit shift is unused after the instruction:
3729 ;; No need to compute it, map to 8-bit shift.
3732 [(set (match_operand:HI 0 "register_operand" "")
3733 (ashift:HI (match_dup 0)
3734 (match_operand:QI 1 "register_operand" "")))]
3737 (ashift:QI (match_dup 2)
3739 (clobber (match_dup 3))]
3741 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3743 if (!peep2_reg_dead_p (1, operands[3]))
3746 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3751 ;; "ashlsq3" "ashlusq3"
3752 ;; "ashlsa3" "ashlusa3"
3753 (define_insn "ashl<mode>3"
3754 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3755 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3756 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3759 return ashlsi3_out (insn, operands, NULL);
3761 [(set_attr "length" "8,0,4,4,8,10,12")
3762 (set_attr "adjust_len" "ashlsi")
3763 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3765 ;; Optimize if a scratch register from LD_REGS happens to be available.
3767 (define_peephole2 ; ashlqi3_l_const4
3768 [(set (match_operand:ALL1 0 "l_register_operand" "")
3769 (ashift:ALL1 (match_dup 0)
3771 (match_scratch:QI 1 "d")]
3773 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3774 (set (match_dup 1) (const_int -16))
3775 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3777 operands[2] = avr_to_int_mode (operands[0]);
3780 (define_peephole2 ; ashlqi3_l_const5
3781 [(set (match_operand:ALL1 0 "l_register_operand" "")
3782 (ashift:ALL1 (match_dup 0)
3784 (match_scratch:QI 1 "d")]
3786 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3787 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3788 (set (match_dup 1) (const_int -32))
3789 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3791 operands[2] = avr_to_int_mode (operands[0]);
3794 (define_peephole2 ; ashlqi3_l_const6
3795 [(set (match_operand:ALL1 0 "l_register_operand" "")
3796 (ashift:ALL1 (match_dup 0)
3798 (match_scratch:QI 1 "d")]
3800 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3801 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3802 (set (match_dup 1) (const_int -64))
3803 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3805 operands[2] = avr_to_int_mode (operands[0]);
3809 [(match_scratch:QI 3 "d")
3810 (set (match_operand:ALL2 0 "register_operand" "")
3811 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3812 (match_operand:QI 2 "const_int_operand" "")))]
3814 [(parallel [(set (match_dup 0)
3815 (ashift:ALL2 (match_dup 1)
3817 (clobber (match_dup 3))])])
3820 ;; "*ashlhq3_const" "*ashluhq3_const"
3821 ;; "*ashlha3_const" "*ashluha3_const"
3822 (define_insn "*ashl<mode>3_const"
3823 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3824 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3825 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3826 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3829 return ashlhi3_out (insn, operands, NULL);
3831 [(set_attr "length" "0,2,2,4,10")
3832 (set_attr "adjust_len" "ashlhi")
3833 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3836 [(match_scratch:QI 3 "d")
3837 (set (match_operand:ALL4 0 "register_operand" "")
3838 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3839 (match_operand:QI 2 "const_int_operand" "")))]
3841 [(parallel [(set (match_dup 0)
3842 (ashift:ALL4 (match_dup 1)
3844 (clobber (match_dup 3))])])
3847 ;; "*ashlsq3_const" "*ashlusq3_const"
3848 ;; "*ashlsa3_const" "*ashlusa3_const"
3849 (define_insn "*ashl<mode>3_const"
3850 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3851 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3852 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3853 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3856 return ashlsi3_out (insn, operands, NULL);
3858 [(set_attr "length" "0,4,4,10")
3859 (set_attr "adjust_len" "ashlsi")
3860 (set_attr "cc" "none,set_n,clobber,clobber")])
3862 (define_expand "ashlpsi3"
3863 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3864 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3865 (match_operand:QI 2 "nonmemory_operand" "")))
3866 (clobber (scratch:QI))])]
3870 && CONST_INT_P (operands[2]))
3872 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3874 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3875 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3878 else if (optimize_insn_for_speed_p ()
3879 && INTVAL (operands[2]) != 16
3880 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3882 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3883 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3889 (define_insn "*ashlpsi3"
3890 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3891 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3892 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3893 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3896 return avr_out_ashlpsi3 (insn, operands, NULL);
3898 [(set_attr "adjust_len" "ashlpsi")
3899 (set_attr "cc" "clobber")])
3901 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3902 ;; arithmetic shift right
3905 ;; "ashrqq3" "ashruqq3"
3906 (define_insn "ashr<mode>3"
3907 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3908 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3909 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3912 return ashrqi3_out (insn, operands, NULL);
3914 [(set_attr "length" "5,0,1,2,5,4,9")
3915 (set_attr "adjust_len" "ashrqi")
3916 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3919 ;; "ashrhq3" "ashruhq3"
3920 ;; "ashrha3" "ashruha3"
3921 (define_insn "ashr<mode>3"
3922 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3923 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3924 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3927 return ashrhi3_out (insn, operands, NULL);
3929 [(set_attr "length" "6,0,2,4,4,10,10")
3930 (set_attr "adjust_len" "ashrhi")
3931 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3933 (define_insn "ashrpsi3"
3934 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3935 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3936 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3937 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3940 return avr_out_ashrpsi3 (insn, operands, NULL);
3942 [(set_attr "adjust_len" "ashrpsi")
3943 (set_attr "cc" "clobber")])
3946 ;; "ashrsq3" "ashrusq3"
3947 ;; "ashrsa3" "ashrusa3"
3948 (define_insn "ashr<mode>3"
3949 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3950 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3951 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3954 return ashrsi3_out (insn, operands, NULL);
3956 [(set_attr "length" "8,0,4,6,8,10,12")
3957 (set_attr "adjust_len" "ashrsi")
3958 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3960 ;; Optimize if a scratch register from LD_REGS happens to be available.
3963 [(match_scratch:QI 3 "d")
3964 (set (match_operand:ALL2 0 "register_operand" "")
3965 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3966 (match_operand:QI 2 "const_int_operand" "")))]
3968 [(parallel [(set (match_dup 0)
3969 (ashiftrt:ALL2 (match_dup 1)
3971 (clobber (match_dup 3))])])
3974 ;; "*ashrhq3_const" "*ashruhq3_const"
3975 ;; "*ashrha3_const" "*ashruha3_const"
3976 (define_insn "*ashr<mode>3_const"
3977 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3978 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3979 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3980 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3983 return ashrhi3_out (insn, operands, NULL);
3985 [(set_attr "length" "0,2,4,4,10")
3986 (set_attr "adjust_len" "ashrhi")
3987 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3990 [(match_scratch:QI 3 "d")
3991 (set (match_operand:ALL4 0 "register_operand" "")
3992 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3993 (match_operand:QI 2 "const_int_operand" "")))]
3995 [(parallel [(set (match_dup 0)
3996 (ashiftrt:ALL4 (match_dup 1)
3998 (clobber (match_dup 3))])])
4001 ;; "*ashrsq3_const" "*ashrusq3_const"
4002 ;; "*ashrsa3_const" "*ashrusa3_const"
4003 (define_insn "*ashr<mode>3_const"
4004 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4005 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4006 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4007 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4010 return ashrsi3_out (insn, operands, NULL);
4012 [(set_attr "length" "0,4,4,10")
4013 (set_attr "adjust_len" "ashrsi")
4014 (set_attr "cc" "none,clobber,set_n,clobber")])
4016 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
4017 ;; logical shift right
4020 ;; "lshrqq3" "lshruqq3"
4021 (define_expand "lshr<mode>3"
4022 [(set (match_operand:ALL1 0 "register_operand" "")
4023 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
4024 (match_operand:QI 2 "nop_general_operand" "")))])
4026 (define_split ; lshrqi3_const4
4027 [(set (match_operand:ALL1 0 "d_register_operand" "")
4028 (lshiftrt:ALL1 (match_dup 0)
4032 (rotate:QI (match_dup 1)
4035 (and:QI (match_dup 1)
4038 operands[1] = avr_to_int_mode (operands[0]);
4041 (define_split ; lshrqi3_const5
4042 [(set (match_operand:ALL1 0 "d_register_operand" "")
4043 (lshiftrt:ALL1 (match_dup 0)
4046 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4047 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
4048 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
4050 operands[1] = avr_to_int_mode (operands[0]);
4053 (define_split ; lshrqi3_const6
4054 [(set (match_operand:QI 0 "d_register_operand" "")
4055 (lshiftrt:QI (match_dup 0)
4058 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4059 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
4060 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
4062 operands[1] = avr_to_int_mode (operands[0]);
4068 (define_insn "*lshr<mode>3"
4069 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
4070 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
4071 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
4074 return lshrqi3_out (insn, operands, NULL);
4076 [(set_attr "length" "5,0,1,2,4,6,9")
4077 (set_attr "adjust_len" "lshrqi")
4078 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
4081 ;; "lshrhq3" "lshruhq3"
4082 ;; "lshrha3" "lshruha3"
4083 (define_insn "lshr<mode>3"
4084 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
4085 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
4086 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4089 return lshrhi3_out (insn, operands, NULL);
4091 [(set_attr "length" "6,0,2,2,4,10,10")
4092 (set_attr "adjust_len" "lshrhi")
4093 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4095 (define_insn "lshrpsi3"
4096 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
4097 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
4098 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
4099 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4102 return avr_out_lshrpsi3 (insn, operands, NULL);
4104 [(set_attr "adjust_len" "lshrpsi")
4105 (set_attr "cc" "clobber")])
4108 ;; "lshrsq3" "lshrusq3"
4109 ;; "lshrsa3" "lshrusa3"
4110 (define_insn "lshr<mode>3"
4111 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
4112 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
4113 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4116 return lshrsi3_out (insn, operands, NULL);
4118 [(set_attr "length" "8,0,4,4,8,10,12")
4119 (set_attr "adjust_len" "lshrsi")
4120 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4122 ;; Optimize if a scratch register from LD_REGS happens to be available.
4124 (define_peephole2 ; lshrqi3_l_const4
4125 [(set (match_operand:ALL1 0 "l_register_operand" "")
4126 (lshiftrt:ALL1 (match_dup 0)
4128 (match_scratch:QI 1 "d")]
4130 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4131 (set (match_dup 1) (const_int 15))
4132 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4134 operands[2] = avr_to_int_mode (operands[0]);
4137 (define_peephole2 ; lshrqi3_l_const5
4138 [(set (match_operand:ALL1 0 "l_register_operand" "")
4139 (lshiftrt:ALL1 (match_dup 0)
4141 (match_scratch:QI 1 "d")]
4143 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4144 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
4145 (set (match_dup 1) (const_int 7))
4146 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4148 operands[2] = avr_to_int_mode (operands[0]);
4151 (define_peephole2 ; lshrqi3_l_const6
4152 [(set (match_operand:ALL1 0 "l_register_operand" "")
4153 (lshiftrt:ALL1 (match_dup 0)
4155 (match_scratch:QI 1 "d")]
4157 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4158 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
4159 (set (match_dup 1) (const_int 3))
4160 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4162 operands[2] = avr_to_int_mode (operands[0]);
4166 [(match_scratch:QI 3 "d")
4167 (set (match_operand:ALL2 0 "register_operand" "")
4168 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
4169 (match_operand:QI 2 "const_int_operand" "")))]
4171 [(parallel [(set (match_dup 0)
4172 (lshiftrt:ALL2 (match_dup 1)
4174 (clobber (match_dup 3))])])
4177 ;; "*lshrhq3_const" "*lshruhq3_const"
4178 ;; "*lshrha3_const" "*lshruha3_const"
4179 (define_insn "*lshr<mode>3_const"
4180 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
4181 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
4182 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
4183 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4186 return lshrhi3_out (insn, operands, NULL);
4188 [(set_attr "length" "0,2,2,4,10")
4189 (set_attr "adjust_len" "lshrhi")
4190 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
4193 [(match_scratch:QI 3 "d")
4194 (set (match_operand:ALL4 0 "register_operand" "")
4195 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
4196 (match_operand:QI 2 "const_int_operand" "")))]
4198 [(parallel [(set (match_dup 0)
4199 (lshiftrt:ALL4 (match_dup 1)
4201 (clobber (match_dup 3))])])
4204 ;; "*lshrsq3_const" "*lshrusq3_const"
4205 ;; "*lshrsa3_const" "*lshrusa3_const"
4206 (define_insn "*lshr<mode>3_const"
4207 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4208 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4209 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4210 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4213 return lshrsi3_out (insn, operands, NULL);
4215 [(set_attr "length" "0,4,4,10")
4216 (set_attr "adjust_len" "lshrsi")
4217 (set_attr "cc" "none,clobber,clobber,clobber")])
4219 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
4222 (define_insn "absqi2"
4223 [(set (match_operand:QI 0 "register_operand" "=r")
4224 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
4228 [(set_attr "length" "2")
4229 (set_attr "cc" "clobber")])
4232 (define_insn "abssf2"
4233 [(set (match_operand:SF 0 "register_operand" "=d,r")
4234 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4239 [(set_attr "length" "1,2")
4240 (set_attr "cc" "set_n,clobber")])
4242 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
4245 (define_insn "negqi2"
4246 [(set (match_operand:QI 0 "register_operand" "=r")
4247 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4250 [(set_attr "length" "1")
4251 (set_attr "cc" "set_vzn")])
4253 (define_insn "*negqihi2"
4254 [(set (match_operand:HI 0 "register_operand" "=r")
4255 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4257 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4258 [(set_attr "length" "4")
4259 (set_attr "cc" "set_n")])
4261 (define_insn "neghi2"
4262 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4263 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4266 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4267 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4268 [(set_attr "length" "3,4")
4269 (set_attr "cc" "set_czn")])
4271 (define_insn "negpsi2"
4272 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4273 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4276 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4277 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4278 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4279 [(set_attr "length" "5,6,6")
4280 (set_attr "cc" "set_czn,set_n,set_czn")])
4282 (define_insn "negsi2"
4283 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4284 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4287 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4288 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4289 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4290 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4291 [(set_attr "length" "7,8,8,7")
4292 (set_attr "isa" "*,*,mov,movw")
4293 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4295 (define_insn "negsf2"
4296 [(set (match_operand:SF 0 "register_operand" "=d,r")
4297 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4301 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4302 [(set_attr "length" "1,4")
4303 (set_attr "cc" "set_n,set_n")])
4305 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4308 (define_insn "one_cmplqi2"
4309 [(set (match_operand:QI 0 "register_operand" "=r")
4310 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4313 [(set_attr "length" "1")
4314 (set_attr "cc" "set_czn")])
4316 (define_insn "one_cmplhi2"
4317 [(set (match_operand:HI 0 "register_operand" "=r")
4318 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4322 [(set_attr "length" "2")
4323 (set_attr "cc" "set_n")])
4325 (define_insn "one_cmplpsi2"
4326 [(set (match_operand:PSI 0 "register_operand" "=r")
4327 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4329 "com %0\;com %B0\;com %C0"
4330 [(set_attr "length" "3")
4331 (set_attr "cc" "set_n")])
4333 (define_insn "one_cmplsi2"
4334 [(set (match_operand:SI 0 "register_operand" "=r")
4335 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4341 [(set_attr "length" "4")
4342 (set_attr "cc" "set_n")])
4344 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4347 ;; We keep combiner from inserting hard registers into the input of sign- and
4348 ;; zero-extends. A hard register in the input operand is not wanted because
4349 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4350 ;; hard register that overlaps these clobbers won't be combined to a widening
4351 ;; multiplication. There is no need for combine to propagate hard registers,
4352 ;; register allocation can do it just as well.
4354 (define_insn "extendqihi2"
4355 [(set (match_operand:HI 0 "register_operand" "=r,r")
4356 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4359 return avr_out_sign_extend (insn, operands, NULL);
4361 [(set_attr "length" "3,4")
4362 (set_attr "adjust_len" "sext")
4363 (set_attr "cc" "set_n")])
4365 (define_insn "extendqipsi2"
4366 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4367 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4370 return avr_out_sign_extend (insn, operands, NULL);
4372 [(set_attr "length" "4,5")
4373 (set_attr "adjust_len" "sext")
4374 (set_attr "cc" "set_n")])
4376 (define_insn "extendqisi2"
4377 [(set (match_operand:SI 0 "register_operand" "=r,r")
4378 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4381 return avr_out_sign_extend (insn, operands, NULL);
4383 [(set_attr "length" "5,6")
4384 (set_attr "adjust_len" "sext")
4385 (set_attr "cc" "set_n")])
4387 (define_insn "extendhipsi2"
4388 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4389 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4392 return avr_out_sign_extend (insn, operands, NULL);
4394 [(set_attr "length" "3,5")
4395 (set_attr "adjust_len" "sext")
4396 (set_attr "cc" "set_n")])
4398 (define_insn "extendhisi2"
4399 [(set (match_operand:SI 0 "register_operand" "=r,r")
4400 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4403 return avr_out_sign_extend (insn, operands, NULL);
4405 [(set_attr "length" "4,6")
4406 (set_attr "adjust_len" "sext")
4407 (set_attr "cc" "set_n")])
4409 (define_insn "extendpsisi2"
4410 [(set (match_operand:SI 0 "register_operand" "=r")
4411 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4414 return avr_out_sign_extend (insn, operands, NULL);
4416 [(set_attr "length" "3")
4417 (set_attr "adjust_len" "sext")
4418 (set_attr "cc" "set_n")])
4420 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4423 (define_insn_and_split "zero_extendqihi2"
4424 [(set (match_operand:HI 0 "register_operand" "=r")
4425 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4429 [(set (match_dup 2) (match_dup 1))
4430 (set (match_dup 3) (const_int 0))]
4432 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4433 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4435 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4436 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4439 (define_insn_and_split "zero_extendqipsi2"
4440 [(set (match_operand:PSI 0 "register_operand" "=r")
4441 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4445 [(set (match_dup 2) (match_dup 1))
4446 (set (match_dup 3) (const_int 0))
4447 (set (match_dup 4) (const_int 0))]
4449 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4450 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4451 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4454 (define_insn_and_split "zero_extendqisi2"
4455 [(set (match_operand:SI 0 "register_operand" "=r")
4456 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4460 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4461 (set (match_dup 3) (const_int 0))]
4463 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4464 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4466 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4467 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4470 (define_insn_and_split "zero_extendhipsi2"
4471 [(set (match_operand:PSI 0 "register_operand" "=r")
4472 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 3) (const_int 0))]
4479 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4480 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4483 (define_insn_and_split "n_extendhipsi2"
4484 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4485 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4486 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4487 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4491 [(set (match_dup 4) (match_dup 2))
4492 (set (match_dup 3) (match_dup 6))
4493 ; no-op move in the case where no scratch is needed
4494 (set (match_dup 5) (match_dup 3))]
4496 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4497 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4498 operands[6] = operands[1];
4500 if (GET_CODE (operands[3]) == SCRATCH)
4501 operands[3] = operands[5];
4504 (define_insn_and_split "zero_extendhisi2"
4505 [(set (match_operand:SI 0 "register_operand" "=r")
4506 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4510 [(set (match_dup 2) (match_dup 1))
4511 (set (match_dup 3) (const_int 0))]
4513 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4514 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4516 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4517 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4520 (define_insn_and_split "zero_extendpsisi2"
4521 [(set (match_operand:SI 0 "register_operand" "=r")
4522 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4526 [(set (match_dup 2) (match_dup 1))
4527 (set (match_dup 3) (const_int 0))]
4529 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4530 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4533 (define_insn_and_split "zero_extendqidi2"
4534 [(set (match_operand:DI 0 "register_operand" "=r")
4535 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4539 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4540 (set (match_dup 3) (const_int 0))]
4542 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4543 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4545 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4546 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4549 (define_insn_and_split "zero_extendhidi2"
4550 [(set (match_operand:DI 0 "register_operand" "=r")
4551 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4555 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4556 (set (match_dup 3) (const_int 0))]
4558 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4559 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4561 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4562 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4565 (define_insn_and_split "zero_extendsidi2"
4566 [(set (match_operand:DI 0 "register_operand" "=r")
4567 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4571 [(set (match_dup 2) (match_dup 1))
4572 (set (match_dup 3) (const_int 0))]
4574 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4575 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4577 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4578 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4581 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4584 ; Optimize negated tests into reverse compare if overflow is undefined.
4585 (define_insn "*negated_tstqi"
4587 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4589 "!flag_wrapv && !flag_trapv"
4590 "cp __zero_reg__,%0"
4591 [(set_attr "cc" "compare")
4592 (set_attr "length" "1")])
4594 (define_insn "*reversed_tstqi"
4596 (compare (const_int 0)
4597 (match_operand:QI 0 "register_operand" "r")))]
4599 "cp __zero_reg__,%0"
4600 [(set_attr "cc" "compare")
4601 (set_attr "length" "2")])
4603 (define_insn "*negated_tsthi"
4605 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4607 "!flag_wrapv && !flag_trapv"
4608 "cp __zero_reg__,%A0
4609 cpc __zero_reg__,%B0"
4610 [(set_attr "cc" "compare")
4611 (set_attr "length" "2")])
4613 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4614 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4615 (define_insn "*reversed_tsthi"
4617 (compare (const_int 0)
4618 (match_operand:HI 0 "register_operand" "r")))
4619 (clobber (match_scratch:QI 1 "=X"))]
4621 "cp __zero_reg__,%A0
4622 cpc __zero_reg__,%B0"
4623 [(set_attr "cc" "compare")
4624 (set_attr "length" "2")])
4626 (define_insn "*negated_tstpsi"
4628 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4630 "!flag_wrapv && !flag_trapv"
4631 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4632 [(set_attr "cc" "compare")
4633 (set_attr "length" "3")])
4635 (define_insn "*reversed_tstpsi"
4637 (compare (const_int 0)
4638 (match_operand:PSI 0 "register_operand" "r")))
4639 (clobber (match_scratch:QI 1 "=X"))]
4641 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4642 [(set_attr "cc" "compare")
4643 (set_attr "length" "3")])
4645 (define_insn "*negated_tstsi"
4647 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4649 "!flag_wrapv && !flag_trapv"
4650 "cp __zero_reg__,%A0
4651 cpc __zero_reg__,%B0
4652 cpc __zero_reg__,%C0
4653 cpc __zero_reg__,%D0"
4654 [(set_attr "cc" "compare")
4655 (set_attr "length" "4")])
4657 ;; "*reversed_tstsi"
4658 ;; "*reversed_tstsq" "*reversed_tstusq"
4659 ;; "*reversed_tstsa" "*reversed_tstusa"
4660 (define_insn "*reversed_tst<mode>"
4662 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4663 (match_operand:ALL4 1 "register_operand" "r")))
4664 (clobber (match_scratch:QI 2 "=X"))]
4666 "cp __zero_reg__,%A1
4667 cpc __zero_reg__,%B1
4668 cpc __zero_reg__,%C1
4669 cpc __zero_reg__,%D1"
4670 [(set_attr "cc" "compare")
4671 (set_attr "length" "4")])
4675 ;; "cmpqq3" "cmpuqq3"
4676 (define_insn "cmp<mode>3"
4678 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4679 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4685 [(set_attr "cc" "compare,compare,compare")
4686 (set_attr "length" "1,1,1")])
4688 (define_insn "*cmpqi_sign_extend"
4690 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4691 (match_operand:HI 1 "s8_operand" "n")))]
4694 [(set_attr "cc" "compare")
4695 (set_attr "length" "1")])
4698 (define_insn "*cmphi.zero-extend.0"
4700 (compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
4701 (match_operand:HI 1 "register_operand" "r")))]
4703 "cp %0,%A1\;cpc __zero_reg__,%B1"
4704 [(set_attr "cc" "compare")
4705 (set_attr "length" "2")])
4707 (define_insn "*cmphi.zero-extend.1"
4709 (compare (match_operand:HI 0 "register_operand" "r")
4710 (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
4712 "cp %A0,%1\;cpc %B0,__zero_reg__"
4713 [(set_attr "cc" "compare")
4714 (set_attr "length" "2")])
4717 ;; "cmphq3" "cmpuhq3"
4718 ;; "cmpha3" "cmpuha3"
4719 (define_insn "cmp<mode>3"
4721 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4722 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4723 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4726 switch (which_alternative)
4730 return avr_out_tsthi (insn, operands, NULL);
4733 return "cp %A0,%A1\;cpc %B0,%B1";
4736 if (<MODE>mode != HImode)
4738 return reg_unused_after (insn, operands[0])
4739 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4740 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4743 if (<MODE>mode != HImode)
4745 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4748 return avr_out_compare (insn, operands, NULL);
4750 [(set_attr "cc" "compare")
4751 (set_attr "length" "1,2,2,3,4,2,4")
4752 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4754 (define_insn "*cmppsi"
4756 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4757 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4758 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4761 switch (which_alternative)
4764 return avr_out_tstpsi (insn, operands, NULL);
4767 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4770 return reg_unused_after (insn, operands[0])
4771 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4772 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4775 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4778 return avr_out_compare (insn, operands, NULL);
4780 [(set_attr "cc" "compare")
4781 (set_attr "length" "3,3,5,6,3,7")
4782 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4785 ;; "*cmpsq" "*cmpusq"
4786 ;; "*cmpsa" "*cmpusa"
4787 (define_insn "*cmp<mode>"
4789 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4790 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4791 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4794 if (0 == which_alternative)
4795 return avr_out_tstsi (insn, operands, NULL);
4796 else if (1 == which_alternative)
4797 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4799 return avr_out_compare (insn, operands, NULL);
4801 [(set_attr "cc" "compare")
4802 (set_attr "length" "4,4,4,5,8")
4803 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4806 ;; ----------------------------------------------------------------------
4807 ;; JUMP INSTRUCTIONS
4808 ;; ----------------------------------------------------------------------
4809 ;; Conditional jump instructions
4812 ;; "cbranchqq4" "cbranchuqq4"
4813 (define_expand "cbranch<mode>4"
4815 (compare (match_operand:ALL1 1 "register_operand" "")
4816 (match_operand:ALL1 2 "nonmemory_operand" "")))
4819 (match_operator 0 "ordered_comparison_operator" [(cc0)
4821 (label_ref (match_operand 3 "" ""))
4824 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4825 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4827 (define_expand "cbranch<mode>4"
4828 [(parallel [(set (cc0)
4829 (compare (match_operand:ORDERED234 1 "register_operand" "")
4830 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4831 (clobber (match_scratch:QI 4 ""))])
4834 (match_operator 0 "ordered_comparison_operator" [(cc0)
4836 (label_ref (match_operand 3 "" ""))
4840 ;; Test a single bit in a QI/HI/SImode register.
4841 ;; Combine will create zero extract patterns for single bit tests.
4842 ;; permit any mode in source pattern by using VOIDmode.
4844 (define_insn "*sbrx_branch<mode>"
4847 (match_operator 0 "eqne_operator"
4849 (match_operand:VOID 1 "register_operand" "r")
4851 (match_operand 2 "const_int_operand" "n"))
4853 (label_ref (match_operand 3 "" ""))
4857 return avr_out_sbxx_branch (insn, operands);
4859 [(set (attr "length")
4860 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4861 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4863 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4866 (set_attr "cc" "clobber")])
4868 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4869 ;; or for old peepholes.
4870 ;; Fixme - bitwise Mask will not work for DImode
4872 (define_insn "*sbrx_and_branch<mode>"
4875 (match_operator 0 "eqne_operator"
4877 (match_operand:QISI 1 "register_operand" "r")
4878 (match_operand:QISI 2 "single_one_operand" "n"))
4880 (label_ref (match_operand 3 "" ""))
4884 HOST_WIDE_INT bitnumber;
4885 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4886 operands[2] = GEN_INT (bitnumber);
4887 return avr_out_sbxx_branch (insn, operands);
4889 [(set (attr "length")
4890 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4891 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4893 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4896 (set_attr "cc" "clobber")])
4898 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4900 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4902 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4903 (label_ref (match_operand 1 "" ""))
4906 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4910 (label_ref (match_dup 1))
4914 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4916 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4917 (label_ref (match_operand 1 "" ""))
4920 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4924 (label_ref (match_dup 1))
4928 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4930 (clobber (match_operand:HI 2 ""))])
4931 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4932 (label_ref (match_operand 1 "" ""))
4935 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4937 (label_ref (match_dup 1))
4941 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4943 (clobber (match_operand:HI 2 ""))])
4944 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4945 (label_ref (match_operand 1 "" ""))
4948 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4950 (label_ref (match_dup 1))
4954 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4956 (clobber (match_operand:SI 2 ""))])
4957 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4958 (label_ref (match_operand 1 "" ""))
4961 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4963 (label_ref (match_dup 1))
4965 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4968 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4970 (clobber (match_operand:SI 2 ""))])
4971 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4972 (label_ref (match_operand 1 "" ""))
4975 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4977 (label_ref (match_dup 1))
4979 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4981 ;; ************************************************************************
4982 ;; Implementation of conditional jumps here.
4983 ;; Compare with 0 (test) jumps
4984 ;; ************************************************************************
4986 (define_insn "branch"
4988 (if_then_else (match_operator 1 "simple_comparison_operator"
4991 (label_ref (match_operand 0 "" ""))
4995 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4997 [(set_attr "type" "branch")
4998 (set_attr "cc" "clobber")])
5001 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
5002 ;; or optimized in the remainder.
5004 (define_insn "branch_unspec"
5006 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
5009 (label_ref (match_operand 0 "" ""))
5011 ] UNSPEC_IDENTITY))]
5014 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5016 [(set_attr "type" "branch")
5017 (set_attr "cc" "none")])
5019 ;; ****************************************************************
5020 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
5021 ;; Convert them all to proper jumps.
5022 ;; ****************************************************************/
5024 (define_insn "difficult_branch"
5026 (if_then_else (match_operator 1 "difficult_comparison_operator"
5029 (label_ref (match_operand 0 "" ""))
5033 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5035 [(set_attr "type" "branch1")
5036 (set_attr "cc" "clobber")])
5040 (define_insn "rvbranch"
5042 (if_then_else (match_operator 1 "simple_comparison_operator"
5046 (label_ref (match_operand 0 "" ""))))]
5049 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5051 [(set_attr "type" "branch1")
5052 (set_attr "cc" "clobber")])
5054 (define_insn "difficult_rvbranch"
5056 (if_then_else (match_operator 1 "difficult_comparison_operator"
5060 (label_ref (match_operand 0 "" ""))))]
5063 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5065 [(set_attr "type" "branch")
5066 (set_attr "cc" "clobber")])
5068 ;; **************************************************************************
5069 ;; Unconditional and other jump instructions.
5073 (label_ref (match_operand 0 "" "")))]
5076 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
5080 [(set (attr "length")
5081 (if_then_else (match_operand 0 "symbol_ref_operand" "")
5082 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5085 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
5086 (le (minus (pc) (match_dup 0)) (const_int 2047)))
5089 (set_attr "cc" "none")])
5093 ;; Operand 1 not used on the AVR.
5094 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5095 (define_expand "call"
5096 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5097 (match_operand:HI 1 "general_operand" ""))
5098 (use (const_int 0))])])
5100 ;; Operand 1 not used on the AVR.
5101 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5102 (define_expand "sibcall"
5103 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5104 (match_operand:HI 1 "general_operand" ""))
5105 (use (const_int 1))])])
5109 ;; Operand 2 not used on the AVR.
5110 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5111 (define_expand "call_value"
5112 [(parallel[(set (match_operand 0 "register_operand" "")
5113 (call (match_operand:HI 1 "call_insn_operand" "")
5114 (match_operand:HI 2 "general_operand" "")))
5115 (use (const_int 0))])])
5117 ;; Operand 2 not used on the AVR.
5118 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5119 (define_expand "sibcall_value"
5120 [(parallel[(set (match_operand 0 "register_operand" "")
5121 (call (match_operand:HI 1 "call_insn_operand" "")
5122 (match_operand:HI 2 "general_operand" "")))
5123 (use (const_int 1))])])
5125 (define_insn "call_insn"
5126 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
5127 (match_operand:HI 1 "general_operand" "X,X,X,X"))
5128 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
5129 ;; Operand 1 not used on the AVR.
5130 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5137 [(set_attr "cc" "clobber")
5138 (set_attr "length" "1,*,1,*")
5139 (set_attr "adjust_len" "*,call,*,call")])
5141 (define_insn "call_value_insn"
5142 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
5143 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
5144 (match_operand:HI 2 "general_operand" "X,X,X,X")))
5145 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
5146 ;; Operand 2 not used on the AVR.
5147 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5154 [(set_attr "cc" "clobber")
5155 (set_attr "length" "1,*,1,*")
5156 (set_attr "adjust_len" "*,call,*,call")])
5162 [(set_attr "cc" "none")
5163 (set_attr "length" "1")])
5167 (define_expand "indirect_jump"
5169 (match_operand:HI 0 "nonmemory_operand" ""))]
5172 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
5174 operands[0] = copy_to_mode_reg (HImode, operands[0]);
5179 (define_insn "*indirect_jump"
5181 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
5187 push %A0\;push %B0\;ret
5189 [(set_attr "length" "1,2,1,3,1")
5190 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
5191 (set_attr "cc" "none")])
5194 ;; For entries in jump table see avr_output_addr_vec.
5197 ;; "rjmp .L<n>" instructions for <= 8K devices
5198 ;; ".word gs(.L<n>)" addresses for > 8K devices
5199 (define_insn "*tablejump"
5201 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
5203 (use (label_ref (match_operand 1 "" "")))
5204 (clobber (match_dup 0))
5205 (clobber (const_int 0))]
5206 "!AVR_HAVE_EIJMP_EICALL"
5209 push %A0\;push %B0\;ret
5211 [(set_attr "length" "1,3,2")
5212 (set_attr "isa" "rjmp,rjmp,jmp")
5213 (set_attr "cc" "none,none,clobber")])
5215 (define_insn "*tablejump.3byte-pc"
5217 (unspec:HI [(reg:HI REG_Z)]
5219 (use (label_ref (match_operand 0 "" "")))
5220 (clobber (reg:HI REG_Z))
5221 (clobber (reg:QI 24))]
5222 "AVR_HAVE_EIJMP_EICALL"
5223 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
5224 [(set_attr "length" "6")
5225 (set_attr "isa" "eijmp")
5226 (set_attr "cc" "clobber")])
5229 ;; FIXME: casesi comes up with an SImode switch value $0 which
5230 ;; is quite some overhead because most code would use HI or
5231 ;; even QI. We add an AVR specific pass .avr-casesi which
5232 ;; tries to recover from the superfluous extension to SImode.
5234 ;; Using "tablejump" could be a way out, but this also does
5235 ;; not perform in a satisfying manner as the middle end will
5236 ;; already multiply the table index by 2. Note that this
5237 ;; multiplication is performed by libgcc's __tablejump2__.
5238 ;; The multiplication there, however, runs *after* the table
5239 ;; start (a byte address) has been added, not before it like
5240 ;; "tablejump" will do.
5242 ;; The preferred solution would be to let the middle ends pass
5243 ;; down information on the index as an additional casesi operand.
5245 ;; If this expander is changed, you'll likely have to go through
5246 ;; "casesi_<mode>_sequence" (used to recog + extract casesi
5247 ;; sequences in pass .avr-casesi) and propagate all adjustments
5248 ;; also to that pattern and the code of the extra pass.
5250 (define_expand "casesi"
5251 [(parallel [(set (match_dup 5)
5252 (plus:SI (match_operand:SI 0 "register_operand")
5253 (match_operand:SI 1 "const_int_operand")))
5254 (clobber (scratch:QI))])
5255 (parallel [(set (cc0)
5256 (compare (match_dup 5)
5257 (match_operand:SI 2 "const_int_operand")))
5258 (clobber (scratch:QI))])
5261 (if_then_else (gtu (cc0)
5263 (label_ref (match_operand 4))
5269 (parallel [(set (pc)
5270 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5271 (use (label_ref (match_dup 3)))
5272 (clobber (match_dup 7))
5273 (clobber (match_dup 8))])]
5276 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
5277 operands[5] = gen_reg_rtx (SImode);
5278 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
5280 if (AVR_HAVE_EIJMP_EICALL)
5282 operands[7] = gen_rtx_REG (HImode, REG_Z);
5283 operands[8] = all_regs_rtx[24];
5287 operands[6] = gen_rtx_PLUS (HImode, operands[6],
5288 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
5289 operands[7] = gen_reg_rtx (HImode);
5290 operands[8] = const0_rtx;
5295 ;; This insn is used only for easy operand extraction.
5296 ;; The elements must match an extension to SImode plus
5297 ;; a sequence generated by casesi above.
5299 ;; "casesi_qi_sequence"
5300 ;; "casesi_hi_sequence"
5301 (define_insn "casesi_<mode>_sequence"
5302 [(set (match_operand:SI 0 "register_operand")
5303 (match_operator:SI 9 "extend_operator"
5304 [(match_operand:QIHI 10 "register_operand")]))
5306 ;; What follows is a matcher for code from casesi.
5307 ;; We keep the same operand numbering (except for $9 and $10
5308 ;; which don't appear in casesi).
5309 (parallel [(set (match_operand:SI 5 "register_operand")
5310 (plus:SI (match_dup 0)
5311 (match_operand:SI 1 "const_int_operand")))
5312 (clobber (scratch:QI))])
5313 (parallel [(set (cc0)
5314 (compare (match_dup 5)
5315 (match_operand:SI 2 "const_int_operand")))
5316 (clobber (scratch:QI))])
5319 (if_then_else (gtu (cc0)
5321 (label_ref (match_operand 4))
5324 (set (match_operand:HI 7 "register_operand")
5325 (match_operand:HI 6))
5327 (parallel [(set (pc)
5328 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5329 (use (label_ref (match_operand 3)))
5330 (clobber (match_dup 7))
5331 (clobber (match_operand:QI 8))])]
5333 && avr_casei_sequence_check_operands (operands)"
5334 { gcc_unreachable(); }
5338 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5339 ;; This instruction sets Z flag
5342 [(set (cc0) (const_int 0))]
5345 [(set_attr "length" "1")
5346 (set_attr "cc" "compare")])
5348 ;; Clear/set/test a single bit in I/O address space.
5351 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5352 (and:QI (mem:QI (match_dup 0))
5353 (match_operand:QI 1 "single_zero_operand" "n")))]
5356 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5357 return "cbi %i0,%2";
5359 [(set_attr "length" "1")
5360 (set_attr "cc" "none")])
5363 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5364 (ior:QI (mem:QI (match_dup 0))
5365 (match_operand:QI 1 "single_one_operand" "n")))]
5368 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5369 return "sbi %i0,%2";
5371 [(set_attr "length" "1")
5372 (set_attr "cc" "none")])
5374 ;; Lower half of the I/O space - use sbic/sbis directly.
5375 (define_insn "*sbix_branch"
5378 (match_operator 0 "eqne_operator"
5380 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
5382 (match_operand 2 "const_int_operand" "n"))
5384 (label_ref (match_operand 3 "" ""))
5388 return avr_out_sbxx_branch (insn, operands);
5390 [(set (attr "length")
5391 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5392 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5394 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5397 (set_attr "cc" "clobber")])
5399 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5400 (define_insn "*sbix_branch_bit7"
5403 (match_operator 0 "gelt_operator"
5404 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
5406 (label_ref (match_operand 2 "" ""))
5410 operands[3] = operands[2];
5411 operands[2] = GEN_INT (7);
5412 return avr_out_sbxx_branch (insn, operands);
5414 [(set (attr "length")
5415 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5416 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5418 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5421 (set_attr "cc" "clobber")])
5423 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5424 (define_insn "*sbix_branch_tmp"
5427 (match_operator 0 "eqne_operator"
5429 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5431 (match_operand 2 "const_int_operand" "n"))
5433 (label_ref (match_operand 3 "" ""))
5437 return avr_out_sbxx_branch (insn, operands);
5439 [(set (attr "length")
5440 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5441 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5443 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5446 (set_attr "cc" "clobber")])
5448 (define_insn "*sbix_branch_tmp_bit7"
5451 (match_operator 0 "gelt_operator"
5452 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5454 (label_ref (match_operand 2 "" ""))
5458 operands[3] = operands[2];
5459 operands[2] = GEN_INT (7);
5460 return avr_out_sbxx_branch (insn, operands);
5462 [(set (attr "length")
5463 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5464 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5466 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5469 (set_attr "cc" "clobber")])
5471 ;; ************************* Peepholes ********************************
5473 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5474 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5475 (plus:SI (match_dup 0)
5477 (clobber (scratch:QI))])
5478 (parallel [(set (cc0)
5479 (compare (match_dup 0)
5481 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5483 (if_then_else (eqne (cc0)
5485 (label_ref (match_operand 2 "" ""))
5492 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5493 output_asm_insn ("sbiw %0,1" CR_TAB
5494 "sbc %C0,__zero_reg__" CR_TAB
5495 "sbc %D0,__zero_reg__", operands);
5497 output_asm_insn ("subi %A0,1" CR_TAB
5498 "sbc %B0,__zero_reg__" CR_TAB
5499 "sbc %C0,__zero_reg__" CR_TAB
5500 "sbc %D0,__zero_reg__", operands);
5502 jump_mode = avr_jump_mode (operands[2], insn);
5503 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5504 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5508 case 1: return "%1 %2";
5509 case 2: return "%1 .+2\;rjmp %2";
5510 case 3: return "%1 .+4\;jmp %2";
5517 (define_peephole ; "*dec-and-branchhi!=-1"
5518 [(set (match_operand:HI 0 "d_register_operand" "")
5519 (plus:HI (match_dup 0)
5521 (parallel [(set (cc0)
5522 (compare (match_dup 0)
5524 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5526 (if_then_else (eqne (cc0)
5528 (label_ref (match_operand 2 "" ""))
5535 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5536 output_asm_insn ("sbiw %0,1", operands);
5538 output_asm_insn ("subi %A0,1" CR_TAB
5539 "sbc %B0,__zero_reg__", operands);
5541 jump_mode = avr_jump_mode (operands[2], insn);
5542 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5543 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5547 case 1: return "%1 %2";
5548 case 2: return "%1 .+2\;rjmp %2";
5549 case 3: return "%1 .+4\;jmp %2";
5556 ;; Same as above but with clobber flavour of addhi3
5557 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5558 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5559 (plus:HI (match_dup 0)
5561 (clobber (scratch:QI))])
5562 (parallel [(set (cc0)
5563 (compare (match_dup 0)
5565 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5567 (if_then_else (eqne (cc0)
5569 (label_ref (match_operand 2 "" ""))
5576 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5577 output_asm_insn ("sbiw %0,1", operands);
5579 output_asm_insn ("subi %A0,1" CR_TAB
5580 "sbc %B0,__zero_reg__", operands);
5582 jump_mode = avr_jump_mode (operands[2], insn);
5583 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5584 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5588 case 1: return "%1 %2";
5589 case 2: return "%1 .+2\;rjmp %2";
5590 case 3: return "%1 .+4\;jmp %2";
5597 ;; Same as above but with clobber flavour of addhi3
5598 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5599 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5600 (plus:HI (match_dup 0)
5602 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5603 (parallel [(set (cc0)
5604 (compare (match_dup 0)
5606 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5608 (if_then_else (eqne (cc0)
5610 (label_ref (match_operand 2 "" ""))
5617 output_asm_insn ("ldi %3,1" CR_TAB
5619 "sbc %B0,__zero_reg__", operands);
5621 jump_mode = avr_jump_mode (operands[2], insn);
5622 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5623 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5627 case 1: return "%1 %2";
5628 case 2: return "%1 .+2\;rjmp %2";
5629 case 3: return "%1 .+4\;jmp %2";
5636 (define_peephole ; "*dec-and-branchqi!=-1"
5637 [(set (match_operand:QI 0 "d_register_operand" "")
5638 (plus:QI (match_dup 0)
5641 (compare (match_dup 0)
5644 (if_then_else (eqne (cc0)
5646 (label_ref (match_operand 1 "" ""))
5653 cc_status.value1 = operands[0];
5654 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5656 output_asm_insn ("subi %A0,1", operands);
5658 jump_mode = avr_jump_mode (operands[1], insn);
5659 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5660 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5664 case 1: return "%0 %1";
5665 case 2: return "%0 .+2\;rjmp %1";
5666 case 3: return "%0 .+4\;jmp %1";
5674 (define_peephole ; "*cpse.eq"
5676 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5677 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5679 (if_then_else (eq (cc0)
5681 (label_ref (match_operand 0 "" ""))
5683 "jump_over_one_insn_p (insn, operands[0])"
5686 cpse %1,__zero_reg__")
5688 ;; This peephole avoids code like
5691 ;; BREQ .+2 ; branch
5694 ;; Notice that the peephole is always shorter than cmpqi + branch.
5695 ;; The reason to write it as peephole is that sequences like
5700 ;; shall not be superseeded. With a respective combine pattern
5701 ;; the latter sequence would be
5704 ;; CPSE Rm, __zero_reg__
5707 ;; and thus longer and slower and not easy to be rolled back.
5709 (define_peephole ; "*cpse.ne"
5711 (compare (match_operand:ALL1 1 "register_operand" "")
5712 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5714 (if_then_else (ne (cc0)
5716 (label_ref (match_operand 0 "" ""))
5719 || !TARGET_SKIP_BUG"
5721 if (operands[2] == CONST0_RTX (<MODE>mode))
5722 operands[2] = zero_reg_rtx;
5724 return 3 == avr_jump_mode (operands[0], insn)
5725 ? "cpse %1,%2\;jmp %0"
5726 : "cpse %1,%2\;rjmp %0";
5729 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5730 ;;prologue/epilogue support instructions
5732 (define_insn "popqi"
5733 [(set (match_operand:QI 0 "register_operand" "=r")
5734 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5737 [(set_attr "cc" "none")
5738 (set_attr "length" "1")])
5740 ;; Enable Interrupts
5741 (define_expand "enable_interrupt"
5742 [(clobber (const_int 0))]
5745 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5746 MEM_VOLATILE_P (mem) = 1;
5747 emit_insn (gen_cli_sei (const1_rtx, mem));
5751 ;; Disable Interrupts
5752 (define_expand "disable_interrupt"
5753 [(clobber (const_int 0))]
5756 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5757 MEM_VOLATILE_P (mem) = 1;
5758 emit_insn (gen_cli_sei (const0_rtx, mem));
5762 (define_insn "cli_sei"
5763 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5764 UNSPECV_ENABLE_IRQS)
5765 (set (match_operand:BLK 1 "" "")
5766 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5771 [(set_attr "length" "1")
5772 (set_attr "cc" "none")])
5774 ;; Library prologue saves
5775 (define_insn "call_prologue_saves"
5776 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5777 (match_operand:HI 0 "immediate_operand" "i,i")
5778 (set (reg:HI REG_SP)
5779 (minus:HI (reg:HI REG_SP)
5780 (match_operand:HI 1 "immediate_operand" "i,i")))
5781 (use (reg:HI REG_X))
5782 (clobber (reg:HI REG_Z))]
5784 "ldi r30,lo8(gs(1f))
5786 %~jmp __prologue_saves__+((18 - %0) * 2)
5788 [(set_attr "length" "5,6")
5789 (set_attr "cc" "clobber")
5790 (set_attr "isa" "rjmp,jmp")])
5792 ; epilogue restores using library
5793 (define_insn "epilogue_restores"
5794 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5796 (plus:HI (reg:HI REG_Y)
5797 (match_operand:HI 0 "immediate_operand" "i,i")))
5798 (set (reg:HI REG_SP)
5799 (plus:HI (reg:HI REG_Y)
5801 (clobber (reg:QI REG_Z))]
5804 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5805 [(set_attr "length" "2,3")
5806 (set_attr "cc" "clobber")
5807 (set_attr "isa" "rjmp,jmp")])
5810 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue
5811 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
5812 (define_expand "gasisr"
5813 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
5814 (match_operand:QI 1 "const_int_operand")]
5816 (set (reg:HI REG_SP)
5817 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5819 (unspec_volatile:BLK [(match_dup 2)]
5820 UNSPECV_MEMORY_BARRIER))])]
5821 "avr_gasisr_prologues"
5823 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5824 MEM_VOLATILE_P (operands[2]) = 1;
5827 (define_insn "*gasisr"
5828 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
5829 (match_operand:QI 1 "const_int_operand" "n,n")]
5831 (set (reg:HI REG_SP)
5832 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5833 (set (match_operand:BLK 2)
5834 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))]
5835 "avr_gasisr_prologues"
5837 [(set_attr "length" "6,5")
5838 (set_attr "cc" "clobber")])
5842 (define_insn "return"
5844 "reload_completed && avr_simple_epilogue ()"
5846 [(set_attr "cc" "none")
5847 (set_attr "length" "1")])
5849 (define_insn "return_from_epilogue"
5853 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5854 && !cfun->machine->is_naked"
5856 [(set_attr "cc" "none")
5857 (set_attr "length" "1")])
5859 (define_insn "return_from_interrupt_epilogue"
5863 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5864 && !cfun->machine->is_naked"
5866 [(set_attr "cc" "none")
5867 (set_attr "length" "1")])
5869 (define_insn "return_from_naked_epilogue"
5873 && cfun->machine->is_naked"
5875 [(set_attr "cc" "none")
5876 (set_attr "length" "0")])
5878 (define_expand "prologue"
5882 avr_expand_prologue ();
5886 (define_expand "epilogue"
5890 avr_expand_epilogue (false /* sibcall_p */);
5894 (define_expand "sibcall_epilogue"
5898 avr_expand_epilogue (true /* sibcall_p */);
5902 ;; Some instructions resp. instruction sequences available
5905 (define_insn "delay_cycles_1"
5906 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5908 UNSPECV_DELAY_CYCLES)
5909 (set (match_operand:BLK 1 "" "")
5910 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5911 (clobber (match_scratch:QI 2 "=&d"))]
5916 [(set_attr "length" "3")
5917 (set_attr "cc" "clobber")])
5919 (define_insn "delay_cycles_2"
5920 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
5922 UNSPECV_DELAY_CYCLES)
5923 (set (match_operand:BLK 1 "" "")
5924 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5925 (clobber (match_scratch:HI 2 "=&w,&d"))]
5928 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b
5929 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b"
5930 [(set_attr "length" "4,5")
5931 (set_attr "isa" "no_tiny,tiny")
5932 (set_attr "cc" "clobber")])
5934 (define_insn "delay_cycles_3"
5935 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5937 UNSPECV_DELAY_CYCLES)
5938 (set (match_operand:BLK 1 "" "")
5939 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5940 (clobber (match_scratch:QI 2 "=&d"))
5941 (clobber (match_scratch:QI 3 "=&d"))
5942 (clobber (match_scratch:QI 4 "=&d"))]
5951 [(set_attr "length" "7")
5952 (set_attr "cc" "clobber")])
5954 (define_insn "delay_cycles_4"
5955 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5957 UNSPECV_DELAY_CYCLES)
5958 (set (match_operand:BLK 1 "" "")
5959 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5960 (clobber (match_scratch:QI 2 "=&d"))
5961 (clobber (match_scratch:QI 3 "=&d"))
5962 (clobber (match_scratch:QI 4 "=&d"))
5963 (clobber (match_scratch:QI 5 "=&d"))]
5974 [(set_attr "length" "9")
5975 (set_attr "cc" "clobber")])
5978 ;; __builtin_avr_insert_bits
5980 (define_insn "insert_bits"
5981 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5982 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5983 (match_operand:QI 2 "register_operand" "r ,r ,r")
5984 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5985 UNSPEC_INSERT_BITS))]
5988 return avr_out_insert_bits (operands, NULL);
5990 [(set_attr "adjust_len" "insert_bits")
5991 (set_attr "cc" "clobber")])
5994 ;; __builtin_avr_flash_segment
5996 ;; Just a helper for the next "official" expander.
5998 (define_expand "flash_segment1"
5999 [(set (match_operand:QI 0 "register_operand" "")
6000 (subreg:QI (match_operand:PSI 1 "register_operand" "")
6003 (compare (match_dup 0)
6006 (if_then_else (ge (cc0)
6008 (label_ref (match_operand 2 "" ""))
6013 (define_expand "flash_segment"
6014 [(parallel [(match_operand:QI 0 "register_operand" "")
6015 (match_operand:PSI 1 "register_operand" "")])]
6018 rtx label = gen_label_rtx ();
6019 emit (gen_flash_segment1 (operands[0], operands[1], label));
6024 ;; Actually, it's too late now to work out address spaces known at compiletime.
6025 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
6026 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
6027 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
6029 (define_insn_and_split "*split.flash_segment"
6030 [(set (match_operand:QI 0 "register_operand" "=d")
6031 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
6032 (match_operand:HI 2 "register_operand" "r"))
6035 { gcc_unreachable(); }
6043 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
6044 ;; better 8-bit parity recognition.
6046 (define_expand "parityhi2"
6047 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6048 (parity:HI (match_operand:HI 1 "register_operand" "")))
6049 (clobber (reg:HI 24))])])
6051 (define_insn_and_split "*parityhi2"
6052 [(set (match_operand:HI 0 "register_operand" "=r")
6053 (parity:HI (match_operand:HI 1 "register_operand" "r")))
6054 (clobber (reg:HI 24))]
6056 { gcc_unreachable(); }
6061 (parity:HI (reg:HI 24)))
6065 (define_insn_and_split "*parityqihi2"
6066 [(set (match_operand:HI 0 "register_operand" "=r")
6067 (parity:HI (match_operand:QI 1 "register_operand" "r")))
6068 (clobber (reg:HI 24))]
6070 { gcc_unreachable(); }
6075 (zero_extend:HI (parity:QI (reg:QI 24))))
6079 (define_expand "paritysi2"
6081 (match_operand:SI 1 "register_operand" ""))
6083 (truncate:HI (parity:SI (reg:SI 22))))
6086 (set (match_operand:SI 0 "register_operand" "")
6087 (zero_extend:SI (match_dup 2)))]
6090 operands[2] = gen_reg_rtx (HImode);
6093 (define_insn "*parityhi2.libgcc"
6095 (parity:HI (reg:HI 24)))]
6097 "%~call __parityhi2"
6098 [(set_attr "type" "xcall")
6099 (set_attr "cc" "clobber")])
6101 (define_insn "*parityqihi2.libgcc"
6103 (zero_extend:HI (parity:QI (reg:QI 24))))]
6105 "%~call __parityqi2"
6106 [(set_attr "type" "xcall")
6107 (set_attr "cc" "clobber")])
6109 (define_insn "*paritysihi2.libgcc"
6111 (truncate:HI (parity:SI (reg:SI 22))))]
6113 "%~call __paritysi2"
6114 [(set_attr "type" "xcall")
6115 (set_attr "cc" "clobber")])
6120 (define_expand "popcounthi2"
6122 (match_operand:HI 1 "register_operand" ""))
6124 (popcount:HI (reg:HI 24)))
6125 (set (match_operand:HI 0 "register_operand" "")
6130 (define_expand "popcountsi2"
6132 (match_operand:SI 1 "register_operand" ""))
6134 (truncate:HI (popcount:SI (reg:SI 22))))
6137 (set (match_operand:SI 0 "register_operand" "")
6138 (zero_extend:SI (match_dup 2)))]
6141 operands[2] = gen_reg_rtx (HImode);
6144 (define_insn "*popcounthi2.libgcc"
6146 (popcount:HI (reg:HI 24)))]
6148 "%~call __popcounthi2"
6149 [(set_attr "type" "xcall")
6150 (set_attr "cc" "clobber")])
6152 (define_insn "*popcountsi2.libgcc"
6154 (truncate:HI (popcount:SI (reg:SI 22))))]
6156 "%~call __popcountsi2"
6157 [(set_attr "type" "xcall")
6158 (set_attr "cc" "clobber")])
6160 (define_insn "*popcountqi2.libgcc"
6162 (popcount:QI (reg:QI 24)))]
6164 "%~call __popcountqi2"
6165 [(set_attr "type" "xcall")
6166 (set_attr "cc" "clobber")])
6168 (define_insn_and_split "*popcountqihi2.libgcc"
6170 (zero_extend:HI (popcount:QI (reg:QI 24))))]
6175 (popcount:QI (reg:QI 24)))
6179 ;; Count Leading Zeros
6181 (define_expand "clzhi2"
6183 (match_operand:HI 1 "register_operand" ""))
6184 (parallel [(set (reg:HI 24)
6185 (clz:HI (reg:HI 24)))
6186 (clobber (reg:QI 26))])
6187 (set (match_operand:HI 0 "register_operand" "")
6190 (define_expand "clzsi2"
6192 (match_operand:SI 1 "register_operand" ""))
6193 (parallel [(set (reg:HI 24)
6194 (truncate:HI (clz:SI (reg:SI 22))))
6195 (clobber (reg:QI 26))])
6198 (set (match_operand:SI 0 "register_operand" "")
6199 (zero_extend:SI (match_dup 2)))]
6202 operands[2] = gen_reg_rtx (HImode);
6205 (define_insn "*clzhi2.libgcc"
6207 (clz:HI (reg:HI 24)))
6208 (clobber (reg:QI 26))]
6211 [(set_attr "type" "xcall")
6212 (set_attr "cc" "clobber")])
6214 (define_insn "*clzsihi2.libgcc"
6216 (truncate:HI (clz:SI (reg:SI 22))))
6217 (clobber (reg:QI 26))]
6220 [(set_attr "type" "xcall")
6221 (set_attr "cc" "clobber")])
6223 ;; Count Trailing Zeros
6225 (define_expand "ctzhi2"
6227 (match_operand:HI 1 "register_operand" ""))
6228 (parallel [(set (reg:HI 24)
6229 (ctz:HI (reg:HI 24)))
6230 (clobber (reg:QI 26))])
6231 (set (match_operand:HI 0 "register_operand" "")
6234 (define_expand "ctzsi2"
6236 (match_operand:SI 1 "register_operand" ""))
6237 (parallel [(set (reg:HI 24)
6238 (truncate:HI (ctz:SI (reg:SI 22))))
6239 (clobber (reg:QI 22))
6240 (clobber (reg:QI 26))])
6243 (set (match_operand:SI 0 "register_operand" "")
6244 (zero_extend:SI (match_dup 2)))]
6247 operands[2] = gen_reg_rtx (HImode);
6250 (define_insn "*ctzhi2.libgcc"
6252 (ctz:HI (reg:HI 24)))
6253 (clobber (reg:QI 26))]
6256 [(set_attr "type" "xcall")
6257 (set_attr "cc" "clobber")])
6259 (define_insn "*ctzsihi2.libgcc"
6261 (truncate:HI (ctz:SI (reg:SI 22))))
6262 (clobber (reg:QI 22))
6263 (clobber (reg:QI 26))]
6266 [(set_attr "type" "xcall")
6267 (set_attr "cc" "clobber")])
6271 (define_expand "ffshi2"
6273 (match_operand:HI 1 "register_operand" ""))
6274 (parallel [(set (reg:HI 24)
6275 (ffs:HI (reg:HI 24)))
6276 (clobber (reg:QI 26))])
6277 (set (match_operand:HI 0 "register_operand" "")
6280 (define_expand "ffssi2"
6282 (match_operand:SI 1 "register_operand" ""))
6283 (parallel [(set (reg:HI 24)
6284 (truncate:HI (ffs:SI (reg:SI 22))))
6285 (clobber (reg:QI 22))
6286 (clobber (reg:QI 26))])
6289 (set (match_operand:SI 0 "register_operand" "")
6290 (zero_extend:SI (match_dup 2)))]
6293 operands[2] = gen_reg_rtx (HImode);
6296 (define_insn "*ffshi2.libgcc"
6298 (ffs:HI (reg:HI 24)))
6299 (clobber (reg:QI 26))]
6302 [(set_attr "type" "xcall")
6303 (set_attr "cc" "clobber")])
6305 (define_insn "*ffssihi2.libgcc"
6307 (truncate:HI (ffs:SI (reg:SI 22))))
6308 (clobber (reg:QI 22))
6309 (clobber (reg:QI 26))]
6312 [(set_attr "type" "xcall")
6313 (set_attr "cc" "clobber")])
6317 (define_insn "copysignsf3"
6318 [(set (match_operand:SF 0 "register_operand" "=r")
6319 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
6320 (match_operand:SF 2 "register_operand" "r")]
6323 "bst %D2,7\;bld %D0,7"
6324 [(set_attr "length" "2")
6325 (set_attr "cc" "none")])
6327 ;; Swap Bytes (change byte-endianness)
6329 (define_expand "bswapsi2"
6331 (match_operand:SI 1 "register_operand" ""))
6333 (bswap:SI (reg:SI 22)))
6334 (set (match_operand:SI 0 "register_operand" "")
6337 (define_insn "*bswapsi2.libgcc"
6339 (bswap:SI (reg:SI 22)))]
6342 [(set_attr "type" "xcall")
6343 (set_attr "cc" "clobber")])
6348 ;; NOP taking 1 or 2 Ticks
6349 (define_expand "nopv"
6350 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
6353 (unspec_volatile:BLK [(match_dup 1)]
6354 UNSPECV_MEMORY_BARRIER))])]
6357 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6358 MEM_VOLATILE_P (operands[1]) = 1;
6361 (define_insn "*nopv"
6362 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6364 (set (match_operand:BLK 1 "" "")
6365 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6370 [(set_attr "length" "1")
6371 (set_attr "cc" "none")])
6374 (define_expand "sleep"
6375 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6377 (unspec_volatile:BLK [(match_dup 0)]
6378 UNSPECV_MEMORY_BARRIER))])]
6381 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6382 MEM_VOLATILE_P (operands[0]) = 1;
6385 (define_insn "*sleep"
6386 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6387 (set (match_operand:BLK 0 "" "")
6388 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6391 [(set_attr "length" "1")
6392 (set_attr "cc" "none")])
6395 (define_expand "wdr"
6396 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6398 (unspec_volatile:BLK [(match_dup 0)]
6399 UNSPECV_MEMORY_BARRIER))])]
6402 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6403 MEM_VOLATILE_P (operands[0]) = 1;
6407 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6408 (set (match_operand:BLK 0 "" "")
6409 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6412 [(set_attr "length" "1")
6413 (set_attr "cc" "none")])
6416 (define_expand "fmul"
6418 (match_operand:QI 1 "register_operand" ""))
6420 (match_operand:QI 2 "register_operand" ""))
6421 (parallel [(set (reg:HI 22)
6422 (unspec:HI [(reg:QI 24)
6423 (reg:QI 25)] UNSPEC_FMUL))
6424 (clobber (reg:HI 24))])
6425 (set (match_operand:HI 0 "register_operand" "")
6431 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6434 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6437 (define_insn "fmul_insn"
6438 [(set (match_operand:HI 0 "register_operand" "=r")
6439 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6440 (match_operand:QI 2 "register_operand" "a")]
6446 [(set_attr "length" "3")
6447 (set_attr "cc" "clobber")])
6449 (define_insn "*fmul.call"
6451 (unspec:HI [(reg:QI 24)
6452 (reg:QI 25)] UNSPEC_FMUL))
6453 (clobber (reg:HI 24))]
6456 [(set_attr "type" "xcall")
6457 (set_attr "cc" "clobber")])
6460 (define_expand "fmuls"
6462 (match_operand:QI 1 "register_operand" ""))
6464 (match_operand:QI 2 "register_operand" ""))
6465 (parallel [(set (reg:HI 22)
6466 (unspec:HI [(reg:QI 24)
6467 (reg:QI 25)] UNSPEC_FMULS))
6468 (clobber (reg:HI 24))])
6469 (set (match_operand:HI 0 "register_operand" "")
6475 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6478 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6481 (define_insn "fmuls_insn"
6482 [(set (match_operand:HI 0 "register_operand" "=r")
6483 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6484 (match_operand:QI 2 "register_operand" "a")]
6490 [(set_attr "length" "3")
6491 (set_attr "cc" "clobber")])
6493 (define_insn "*fmuls.call"
6495 (unspec:HI [(reg:QI 24)
6496 (reg:QI 25)] UNSPEC_FMULS))
6497 (clobber (reg:HI 24))]
6500 [(set_attr "type" "xcall")
6501 (set_attr "cc" "clobber")])
6504 (define_expand "fmulsu"
6506 (match_operand:QI 1 "register_operand" ""))
6508 (match_operand:QI 2 "register_operand" ""))
6509 (parallel [(set (reg:HI 22)
6510 (unspec:HI [(reg:QI 24)
6511 (reg:QI 25)] UNSPEC_FMULSU))
6512 (clobber (reg:HI 24))])
6513 (set (match_operand:HI 0 "register_operand" "")
6519 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6522 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6525 (define_insn "fmulsu_insn"
6526 [(set (match_operand:HI 0 "register_operand" "=r")
6527 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6528 (match_operand:QI 2 "register_operand" "a")]
6534 [(set_attr "length" "3")
6535 (set_attr "cc" "clobber")])
6537 (define_insn "*fmulsu.call"
6539 (unspec:HI [(reg:QI 24)
6540 (reg:QI 25)] UNSPEC_FMULSU))
6541 (clobber (reg:HI 24))]
6544 [(set_attr "type" "xcall")
6545 (set_attr "cc" "clobber")])
6548 ;; Some combiner patterns dealing with bits.
6551 ;; Move bit $3.0 into bit $0.$4
6552 (define_insn "*movbitqi.1-6.a"
6553 [(set (match_operand:QI 0 "register_operand" "=r")
6554 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6555 (match_operand:QI 2 "single_zero_operand" "n"))
6556 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6557 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6558 (match_operand:QI 5 "single_one_operand" "n"))))]
6559 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6560 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6561 "bst %3,0\;bld %0,%4"
6562 [(set_attr "length" "2")
6563 (set_attr "cc" "none")])
6565 ;; Move bit $3.0 into bit $0.$4
6566 ;; Variation of above. Unfortunately, there is no canonicalized representation
6567 ;; of moving around bits. So what we see here depends on how user writes down
6568 ;; bit manipulations.
6569 (define_insn "*movbitqi.1-6.b"
6570 [(set (match_operand:QI 0 "register_operand" "=r")
6571 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6572 (match_operand:QI 2 "single_zero_operand" "n"))
6573 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6575 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6576 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6577 "bst %3,0\;bld %0,%4"
6578 [(set_attr "length" "2")
6579 (set_attr "cc" "none")])
6581 ;; Move bit $3.0 into bit $0.0.
6582 ;; For bit 0, combiner generates slightly different pattern.
6583 (define_insn "*movbitqi.0"
6584 [(set (match_operand:QI 0 "register_operand" "=r")
6585 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6586 (match_operand:QI 2 "single_zero_operand" "n"))
6587 (and:QI (match_operand:QI 3 "register_operand" "r")
6589 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6590 "bst %3,0\;bld %0,0"
6591 [(set_attr "length" "2")
6592 (set_attr "cc" "none")])
6594 ;; Move bit $2.0 into bit $0.7.
6595 ;; For bit 7, combiner generates slightly different pattern
6596 (define_insn "*movbitqi.7"
6597 [(set (match_operand:QI 0 "register_operand" "=r")
6598 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6600 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6603 "bst %2,0\;bld %0,7"
6604 [(set_attr "length" "2")
6605 (set_attr "cc" "none")])
6607 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6608 ;; and input/output match. We provide a special pattern for this, because
6609 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6610 ;; operation on I/O is atomic.
6611 (define_insn "*insv.io"
6612 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
6614 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6615 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6620 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6621 [(set_attr "length" "1,1,4")
6622 (set_attr "cc" "none")])
6624 (define_insn "*insv.not.io"
6625 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
6627 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6628 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6630 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6631 [(set_attr "length" "4")
6632 (set_attr "cc" "none")])
6634 ;; The insv expander.
6635 ;; We only support 1-bit inserts
6636 (define_expand "insv"
6637 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6638 (match_operand:QI 1 "const1_operand" "") ; width
6639 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6640 (match_operand:QI 3 "nonmemory_operand" ""))]
6643 ;; Some more patterns to support moving around one bit which can be accomplished
6644 ;; by BST + BLD in most situations. Unfortunately, there is no canonical
6645 ;; representation, and we just implement some more cases that are not too
6648 ;; Insert bit $2.0 into $0.$1
6649 (define_insn "*insv.reg"
6650 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6652 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6653 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6657 andi %0,lo8(~(1<<%1))
6661 [(set_attr "length" "2,1,1,2,2")
6662 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6664 ;; Insert bit $2.$3 into $0.$1
6665 (define_insn "*insv.extract"
6666 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6668 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6669 (any_extract:QI (match_operand:QI 2 "register_operand" "r")
6671 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6673 "bst %2,%3\;bld %0,%1"
6674 [(set_attr "length" "2")
6675 (set_attr "cc" "none")])
6677 ;; Insert bit $2.$3 into $0.$1
6678 (define_insn "*insv.shiftrt"
6679 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6681 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6682 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6683 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6685 "bst %2,%3\;bld %0,%1"
6686 [(set_attr "length" "2")
6687 (set_attr "cc" "none")])
6689 ;; Same, but with a NOT inverting the source bit.
6690 ;; Insert bit ~$2.$3 into $0.$1
6691 (define_insn "*insv.not-shiftrt"
6692 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6694 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6695 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6696 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
6699 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6701 [(set_attr "adjust_len" "insv_notbit")
6702 (set_attr "cc" "clobber")])
6704 ;; Insert bit ~$2.0 into $0.$1
6705 (define_insn "*insv.xor1-bit.0"
6706 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6708 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6709 (xor:QI (match_operand:QI 2 "register_operand" "r")
6713 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6715 [(set_attr "adjust_len" "insv_notbit_0")
6716 (set_attr "cc" "clobber")])
6718 ;; Insert bit ~$2.0 into $0.$1
6719 (define_insn "*insv.not-bit.0"
6720 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6722 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6723 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6726 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6728 [(set_attr "adjust_len" "insv_notbit_0")
6729 (set_attr "cc" "clobber")])
6731 ;; Insert bit ~$2.7 into $0.$1
6732 (define_insn "*insv.not-bit.7"
6733 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6735 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6736 (ge:QI (match_operand:QI 2 "register_operand" "r")
6740 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
6742 [(set_attr "adjust_len" "insv_notbit_7")
6743 (set_attr "cc" "clobber")])
6745 ;; Insert bit ~$2.$3 into $0.$1
6746 (define_insn "*insv.xor-extract"
6747 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6749 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6750 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
6751 (match_operand:QI 4 "const_int_operand" "n"))
6753 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6754 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
6756 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6758 [(set_attr "adjust_len" "insv_notbit")
6759 (set_attr "cc" "clobber")])
6762 ;; Some combine patterns that try to fix bad code when a value is composed
6763 ;; from byte parts like in PR27663.
6764 ;; The patterns give some release but the code still is not optimal,
6765 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6766 ;; That switch obfuscates things here and in many other places.
6768 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6769 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6770 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6771 [(set (match_operand:HISI 0 "register_operand" "=r")
6773 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6774 (match_operand:HISI 2 "register_operand" "0")))]
6779 (xior:QI (match_dup 3)
6782 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6785 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6786 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6787 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6788 [(set (match_operand:HISI 0 "register_operand" "=r")
6790 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6791 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6792 (match_operand:HISI 3 "register_operand" "0")))]
6793 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6795 "&& reload_completed"
6797 (xior:QI (match_dup 4)
6800 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6801 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6805 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
6806 [(set (match_operand:HI 0 "register_operand" "=r,r")
6807 (ior:HI (ashift:HI (any_extend:HI
6808 (match_operand:QI 1 "register_operand" "r,r"))
6810 (zero_extend:HI (match_operand:QI 2 "register_operand" "0,r"))))]
6812 { gcc_unreachable(); }
6813 "&& reload_completed"
6814 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
6815 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
6816 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
6818 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6819 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6821 if (!reg_overlap_mentioned_p (hi, operands[2]))
6823 emit_move_insn (hi, operands[1]);
6824 emit_move_insn (lo, operands[2]);
6827 else if (!reg_overlap_mentioned_p (lo, operands[1]))
6829 emit_move_insn (lo, operands[2]);
6830 emit_move_insn (hi, operands[1]);
6834 gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
6835 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
6838 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
6839 [(set (match_operand:HI 0 "register_operand" "=r")
6840 (ior:HI (ashift:HI (any_extend:HI
6841 (match_operand:QI 1 "register_operand" "r"))
6843 (match_operand:HI 2 "register_operand" "0")))]
6845 { gcc_unreachable(); }
6846 "&& reload_completed"
6848 (ior:QI (match_dup 4)
6851 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6852 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
6855 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
6856 [(set (match_operand:HI 0 "register_operand" "=r")
6857 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
6859 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
6861 { gcc_unreachable(); }
6862 "&& reload_completed"
6866 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6867 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
6872 [(set (match_operand:QI 0 "register_operand")
6875 (ior:QI (match_dup 0)
6876 (match_operand:QI 1 "register_operand")))]
6882 (define_expand "extzv"
6883 [(set (match_operand:QI 0 "register_operand" "")
6884 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6885 (match_operand:QI 2 "const1_operand" "")
6886 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6888 (define_insn "*extzv"
6889 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6890 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6892 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6896 mov %0,%1\;andi %0,1
6899 bst %1,%2\;clr %0\;bld %0,0"
6900 [(set_attr "length" "1,2,2,2,3")
6901 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6903 (define_insn_and_split "*extzv.qihi1"
6904 [(set (match_operand:HI 0 "register_operand" "=r")
6905 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6907 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6912 (zero_extract:QI (match_dup 1)
6918 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6919 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6922 (define_insn_and_split "*extzv.qihi2"
6923 [(set (match_operand:HI 0 "register_operand" "=r")
6925 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6927 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6932 (zero_extract:QI (match_dup 1)
6938 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6939 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6942 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
6943 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example.
6944 (define_insn_and_split "*extract.subreg.bit"
6945 [(set (match_operand:QI 0 "register_operand" "=r")
6946 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
6947 (match_operand:QI 2 "const_int_operand" "n"))
6950 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6951 { gcc_unreachable(); }
6952 "&& reload_completed"
6955 (zero_extract:QI (match_dup 3)
6959 int bitno = INTVAL (operands[2]);
6960 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
6961 operands[4] = GEN_INT (bitno % 8);
6965 ;; Fixed-point instructions
6966 (include "avr-fixed.md")
6968 ;; Operations on 64-bit registers
6969 (include "avr-dimode.md")