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 emit_move_insn (virtual_stack_vars_rtx,
338 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
339 gen_int_mode (STARTING_FRAME_OFFSET,
341 /* ; This might change the hard frame pointer in ways that aren't
342 ; apparent to early optimization passes, so force a clobber. */
343 emit_clobber (hard_frame_pointer_rtx);
348 ;; Defining nonlocal_goto_receiver means we must also define this.
349 ;; even though its function is identical to that in builtins.c
351 (define_expand "nonlocal_goto"
352 [(use (match_operand 0 "general_operand"))
353 (use (match_operand 1 "general_operand"))
354 (use (match_operand 2 "general_operand"))
355 (use (match_operand 3 "general_operand"))]
358 rtx r_label = copy_to_reg (operands[1]);
359 rtx r_fp = operands[3];
360 rtx r_sp = operands[2];
362 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
364 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
366 emit_move_insn (hard_frame_pointer_rtx, r_fp);
367 emit_stack_restore (SAVE_NONLOCAL, r_sp);
369 emit_use (hard_frame_pointer_rtx);
370 emit_use (stack_pointer_rtx);
372 emit_indirect_jump (r_label);
378 ;; "pushqq1" "pushuqq1"
379 (define_insn "push<mode>1"
380 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
381 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
386 [(set_attr "length" "1,1")])
388 (define_insn "pushhi1_insn"
389 [(set (mem:HI (post_dec:HI (reg:HI REG_SP)))
390 (match_operand:HI 0 "register_operand" "r"))]
393 [(set_attr "length" "2")])
395 ;; All modes for a multi-byte push. We must include complex modes here too,
396 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
397 (define_mode_iterator MPUSH
406 (define_expand "push<mode>1"
407 [(match_operand:MPUSH 0 "" "")]
410 if (MEM_P (operands[0])
411 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[0])))
413 // Avoid (subreg (mem)) for non-generic address spaces. Because
414 // of the poor addressing capabilities of these spaces it's better to
415 // load them in one chunk. And it avoids PR61443.
417 operands[0] = copy_to_mode_reg (<MODE>mode, operands[0]);
419 else if (REG_P (operands[0])
420 && IN_RANGE (REGNO (operands[0]), FIRST_VIRTUAL_REGISTER,
421 LAST_VIRTUAL_REGISTER))
423 // Byte-wise pushing of virtual regs might result in something like
425 // (set (mem:QI (post_dec:HI (reg:HI 32 SP)))
426 // (subreg:QI (plus:HI (reg:HI 28)
427 // (const_int 17)) 0))
429 // after elimination. This cannot be handled by reload, cf. PR64452.
430 // Reload virtuals in one chunk. That way it's possible to reload
431 // above situation and finally
436 // (plus:HI (reg:HI **)
438 // (set (mem:HI (post_dec:HI (reg:HI 32 SP))
441 emit_insn (gen_pushhi1_insn (operands[0]));
445 for (int i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
447 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
448 if (part != const0_rtx)
449 part = force_reg (QImode, part);
450 emit_insn (gen_pushqi1 (part));
455 ;; Notice a special-case when adding N to SP where N results in a
456 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
458 [(set (reg:HI REG_SP)
459 (match_operand:HI 0 "register_operand" ""))]
461 && frame_pointer_needed
462 && !cfun->calls_alloca
463 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
464 [(set (reg:HI REG_SP)
467 ;;========================================================================
475 (define_expand "load<mode>_libgcc"
478 (set (reg:MOVMODE 22)
479 (match_operand:MOVMODE 1 "memory_operand" ""))
480 (set (match_operand:MOVMODE 0 "register_operand" "")
482 "avr_load_libgcc_p (operands[1])"
484 operands[3] = gen_rtx_REG (HImode, REG_Z);
485 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
486 operands[1] = replace_equiv_address (operands[1], operands[3]);
487 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
495 (define_insn "load_<mode>_libgcc"
496 [(set (reg:MOVMODE 22)
497 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
498 "avr_load_libgcc_p (operands[0])
499 && REG_P (XEXP (operands[0], 0))
500 && REG_Z == REGNO (XEXP (operands[0], 0))"
502 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
503 return "%~call __load_%0";
505 [(set_attr "length" "1,2")
506 (set_attr "isa" "rjmp,jmp")
507 (set_attr "cc" "clobber")])
511 ;; "xload8qq_A" "xload8uqq_A"
512 (define_insn_and_split "xload8<mode>_A"
513 [(set (match_operand:ALL1 0 "register_operand" "=r")
514 (match_operand:ALL1 1 "memory_operand" "m"))
515 (clobber (reg:HI REG_Z))]
516 "can_create_pseudo_p()
517 && !avr_xload_libgcc_p (<MODE>mode)
518 && avr_mem_memx_p (operands[1])
519 && REG_P (XEXP (operands[1], 0))"
520 { gcc_unreachable(); }
522 [(clobber (const_int 0))]
524 /* ; Split away the high part of the address. GCC's register allocator
525 ; in not able to allocate segment registers and reload the resulting
526 ; expressions. Notice that no address register can hold a PSImode. */
529 rtx addr = XEXP (operands[1], 0);
530 rtx hi8 = gen_reg_rtx (QImode);
531 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
533 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
534 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
536 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
537 set_mem_addr_space (SET_SRC (single_set (insn)),
538 MEM_ADDR_SPACE (operands[1]));
542 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
543 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
544 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
547 (define_insn_and_split "xload<mode>_A"
548 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
549 (match_operand:MOVMODE 1 "memory_operand" "m"))
550 (clobber (reg:MOVMODE 22))
551 (clobber (reg:QI 21))
552 (clobber (reg:HI REG_Z))]
553 "can_create_pseudo_p()
554 && avr_mem_memx_p (operands[1])
555 && REG_P (XEXP (operands[1], 0))"
556 { gcc_unreachable(); }
558 [(clobber (const_int 0))]
560 rtx addr = XEXP (operands[1], 0);
561 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
562 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
563 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
566 /* Split the address to R21:Z */
567 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
568 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
570 /* Load with code from libgcc */
571 insn = emit_insn (gen_xload_<mode>_libgcc ());
572 set_mem_addr_space (SET_SRC (single_set (insn)), as);
574 /* Move to destination */
575 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
580 ;; Move value from address space memx to a register
581 ;; These insns must be prior to respective generic move insn.
584 ;; "xloadqq_8" "xloaduqq_8"
585 (define_insn "xload<mode>_8"
586 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
587 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
589 "!avr_xload_libgcc_p (<MODE>mode)"
591 return avr_out_xload (insn, operands, NULL);
593 [(set_attr "length" "4,4")
594 (set_attr "adjust_len" "*,xload")
595 (set_attr "isa" "lpmx,lpm")
596 (set_attr "cc" "none")])
598 ;; R21:Z : 24-bit source address
599 ;; R22 : 1-4 byte output
601 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
602 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
603 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
605 ;; "xload_psi_libgcc"
606 (define_insn "xload_<mode>_libgcc"
607 [(set (reg:MOVMODE 22)
608 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
610 (clobber (reg:QI 21))
611 (clobber (reg:HI REG_Z))]
612 "avr_xload_libgcc_p (<MODE>mode)"
614 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
616 output_asm_insn ("%~call __xload_%0", &x_bytes);
619 [(set_attr "type" "xcall")
620 (set_attr "cc" "clobber")])
623 ;; General move expanders
625 ;; "movqi" "movqq" "movuqq"
626 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
627 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
630 (define_expand "mov<mode>"
631 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
632 (match_operand:MOVMODE 1 "general_operand" ""))]
635 rtx dest = operands[0];
636 rtx src = avr_eval_addr_attrib (operands[1]);
638 if (avr_mem_flash_p (dest))
641 if (QImode == <MODE>mode
643 && CONSTANT_ADDRESS_P (SUBREG_REG (src))
644 && can_create_pseudo_p())
646 // store_bitfield may want to store a SYMBOL_REF or CONST in a
647 // structure that's represented as PSImode. As the upper 16 bits
648 // of PSImode cannot be expressed as an HImode subreg, the rhs is
649 // decomposed into QImode (word_mode) subregs of SYMBOL_REF,
650 // CONST or LABEL_REF; cf. PR71103.
652 rtx const_addr = SUBREG_REG (src);
653 operands[1] = src = copy_rtx (src);
654 SUBREG_REG (src) = copy_to_mode_reg (GET_MODE (const_addr), const_addr);
657 /* One of the operands has to be in a register. */
658 if (!register_operand (dest, <MODE>mode)
659 && !reg_or_0_operand (src, <MODE>mode))
661 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
664 if (avr_mem_memx_p (src))
666 rtx addr = XEXP (src, 0);
669 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
671 if (!avr_xload_libgcc_p (<MODE>mode))
672 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
673 ; insn-emit does not depend on the mode, it's all about operands. */
674 emit_insn (gen_xload8qi_A (dest, src));
676 emit_insn (gen_xload<mode>_A (dest, src));
681 if (avr_load_libgcc_p (src))
683 /* For the small devices, do loads per libgcc call. */
684 emit_insn (gen_load<mode>_libgcc (dest, src));
689 ;;========================================================================
691 ;; The last alternative (any immediate constant to any register) is
692 ;; very expensive. It should be optimized by peephole2 if a scratch
693 ;; register is available, but then that register could just as well be
694 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
695 ;; are call-saved registers, and most of LD_REGS are call-used registers,
696 ;; so this may still be a win for registers live across function calls.
699 ;; "movqq_insn" "movuqq_insn"
700 (define_insn "mov<mode>_insn"
701 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
702 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
703 "register_operand (operands[0], <MODE>mode)
704 || reg_or_0_operand (operands[1], <MODE>mode)"
706 return output_movqi (insn, operands, NULL);
708 [(set_attr "length" "1,1,5,5,1,1,4")
709 (set_attr "adjust_len" "mov8")
710 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
712 ;; This is used in peephole2 to optimize loading immediate constants
713 ;; if a scratch register from LD_REGS happens to be available.
716 ;; "*reload_inqq" "*reload_inuqq"
717 (define_insn "*reload_in<mode>"
718 [(set (match_operand:ALL1 0 "register_operand" "=l")
719 (match_operand:ALL1 1 "const_operand" "i"))
720 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
724 [(set_attr "length" "2")
725 (set_attr "cc" "none")])
728 [(match_scratch:QI 2 "d")
729 (set (match_operand:ALL1 0 "l_register_operand" "")
730 (match_operand:ALL1 1 "const_operand" ""))]
731 ; No need for a clobber reg for 0x0, 0x01 or 0xff
732 "!satisfies_constraint_Y00 (operands[1])
733 && !satisfies_constraint_Y01 (operands[1])
734 && !satisfies_constraint_Ym1 (operands[1])"
735 [(parallel [(set (match_dup 0)
737 (clobber (match_dup 2))])])
739 ;;============================================================================
740 ;; move word (16 bit)
742 ;; Move register $1 to the Stack Pointer register SP.
743 ;; This insn is emit during function prologue/epilogue generation.
744 ;; $2 = 0: We know that IRQs are off
745 ;; $2 = 1: We know that IRQs are on
746 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
747 ;; $2 = -1: We don't know anything about IRQ on/off
748 ;; Always write SP via unspec, see PR50063
750 (define_insn "movhi_sp_r"
751 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
752 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
753 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
757 out %B0,%B1\;out %A0,%A1
758 cli\;out %B0,%B1\;sei\;out %A0,%A1
759 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
761 out %A0,%A1\;out %B0,%B1"
762 [(set_attr "length" "2,4,5,1,2")
763 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
764 (set_attr "cc" "none")])
767 [(match_scratch:QI 2 "d")
768 (set (match_operand:ALL2 0 "l_register_operand" "")
769 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
770 "operands[1] != CONST0_RTX (<MODE>mode)"
771 [(parallel [(set (match_dup 0)
773 (clobber (match_dup 2))])])
775 ;; '*' because it is not used in rtl generation, only in above peephole
777 ;; "*reload_inhq" "*reload_inuhq"
778 ;; "*reload_inha" "*reload_inuha"
779 (define_insn "*reload_in<mode>"
780 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
781 (match_operand:ALL2 1 "immediate_operand" "i"))
782 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
785 return output_reload_inhi (operands, operands[2], NULL);
787 [(set_attr "length" "4")
788 (set_attr "adjust_len" "reload_in16")
789 (set_attr "cc" "clobber")])
792 ;; "*movhq" "*movuhq"
793 ;; "*movha" "*movuha"
794 (define_insn "*mov<mode>"
795 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
796 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
797 "register_operand (operands[0], <MODE>mode)
798 || reg_or_0_operand (operands[1], <MODE>mode)"
800 return output_movhi (insn, operands, NULL);
802 [(set_attr "length" "2,2,6,7,2,6,5,2")
803 (set_attr "adjust_len" "mov16")
804 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
806 (define_peephole2 ; movw
807 [(set (match_operand:ALL1 0 "even_register_operand" "")
808 (match_operand:ALL1 1 "even_register_operand" ""))
809 (set (match_operand:ALL1 2 "odd_register_operand" "")
810 (match_operand:ALL1 3 "odd_register_operand" ""))]
812 && REGNO (operands[0]) == REGNO (operands[2]) - 1
813 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
817 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
818 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
821 (define_peephole2 ; movw_r
822 [(set (match_operand:ALL1 0 "odd_register_operand" "")
823 (match_operand:ALL1 1 "odd_register_operand" ""))
824 (set (match_operand:ALL1 2 "even_register_operand" "")
825 (match_operand:ALL1 3 "even_register_operand" ""))]
827 && REGNO (operands[2]) == REGNO (operands[0]) - 1
828 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
832 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
833 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
836 ;; For LPM loads from AS1 we split
840 ;; Z = Z - sizeof (R)
842 ;; so that the second instruction can be optimized out.
844 (define_split ; "split-lpmx"
845 [(set (match_operand:HISI 0 "register_operand" "")
846 (match_operand:HISI 1 "memory_operand" ""))]
852 (plus:HI (match_dup 3)
855 rtx addr = XEXP (operands[1], 0);
857 if (!avr_mem_flash_p (operands[1])
859 || reg_overlap_mentioned_p (addr, operands[0]))
864 operands[2] = replace_equiv_address (operands[1],
865 gen_rtx_POST_INC (Pmode, addr));
867 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
870 ;;==========================================================================
871 ;; xpointer move (24 bit)
873 (define_peephole2 ; *reload_inpsi
874 [(match_scratch:QI 2 "d")
875 (set (match_operand:PSI 0 "l_register_operand" "")
876 (match_operand:PSI 1 "immediate_operand" ""))
878 "operands[1] != const0_rtx
879 && operands[1] != constm1_rtx"
880 [(parallel [(set (match_dup 0)
882 (clobber (match_dup 2))])])
884 ;; '*' because it is not used in rtl generation.
885 (define_insn "*reload_inpsi"
886 [(set (match_operand:PSI 0 "register_operand" "=r")
887 (match_operand:PSI 1 "immediate_operand" "i"))
888 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
891 return avr_out_reload_inpsi (operands, operands[2], NULL);
893 [(set_attr "length" "6")
894 (set_attr "adjust_len" "reload_in24")
895 (set_attr "cc" "clobber")])
897 (define_insn "*movpsi"
898 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
899 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
900 "register_operand (operands[0], PSImode)
901 || register_operand (operands[1], PSImode)
902 || const0_rtx == operands[1]"
904 return avr_out_movpsi (insn, operands, NULL);
906 [(set_attr "length" "3,3,8,9,4,10")
907 (set_attr "adjust_len" "mov24")
908 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
910 ;;==========================================================================
911 ;; move double word (32 bit)
913 (define_peephole2 ; *reload_insi
914 [(match_scratch:QI 2 "d")
915 (set (match_operand:ALL4 0 "l_register_operand" "")
916 (match_operand:ALL4 1 "immediate_operand" ""))
918 "operands[1] != CONST0_RTX (<MODE>mode)"
919 [(parallel [(set (match_dup 0)
921 (clobber (match_dup 2))])])
923 ;; '*' because it is not used in rtl generation.
925 ;; "*reload_insq" "*reload_inusq"
926 ;; "*reload_insa" "*reload_inusa"
927 (define_insn "*reload_insi"
928 [(set (match_operand:ALL4 0 "register_operand" "=r")
929 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
930 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
933 return output_reload_insisf (operands, operands[2], NULL);
935 [(set_attr "length" "8")
936 (set_attr "adjust_len" "reload_in32")
937 (set_attr "cc" "clobber")])
941 ;; "*movsq" "*movusq"
942 ;; "*movsa" "*movusa"
943 (define_insn "*mov<mode>"
944 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
945 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
946 "register_operand (operands[0], <MODE>mode)
947 || reg_or_0_operand (operands[1], <MODE>mode)"
949 return output_movsisf (insn, operands, NULL);
951 [(set_attr "length" "4,4,8,9,4,10")
952 (set_attr "adjust_len" "mov32")
953 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
955 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
956 ;; move floating point numbers (32 bit)
958 (define_insn "*movsf"
959 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
960 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
961 "register_operand (operands[0], SFmode)
962 || reg_or_0_operand (operands[1], SFmode)"
964 return output_movsisf (insn, operands, NULL);
966 [(set_attr "length" "4,4,8,9,4,10")
967 (set_attr "adjust_len" "mov32")
968 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
970 (define_peephole2 ; *reload_insf
971 [(match_scratch:QI 2 "d")
972 (set (match_operand:SF 0 "l_register_operand" "")
973 (match_operand:SF 1 "const_double_operand" ""))
975 "operands[1] != CONST0_RTX (SFmode)"
976 [(parallel [(set (match_dup 0)
978 (clobber (match_dup 2))])])
980 ;; '*' because it is not used in rtl generation.
981 (define_insn "*reload_insf"
982 [(set (match_operand:SF 0 "register_operand" "=r")
983 (match_operand:SF 1 "const_double_operand" "F"))
984 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
987 return output_reload_insisf (operands, operands[2], NULL);
989 [(set_attr "length" "8")
990 (set_attr "adjust_len" "reload_in32")
991 (set_attr "cc" "clobber")])
993 ;;=========================================================================
994 ;; move string (like memcpy)
996 (define_expand "movmemhi"
997 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
998 (match_operand:BLK 1 "memory_operand" ""))
999 (use (match_operand:HI 2 "const_int_operand" ""))
1000 (use (match_operand:HI 3 "const_int_operand" ""))])]
1003 if (avr_emit_movmemhi (operands))
1009 (define_mode_attr MOVMEM_r_d [(QI "r")
1012 ;; $0 : Address Space
1013 ;; $1, $2 : Loop register
1014 ;; R30 : source address
1015 ;; R26 : destination address
1019 (define_insn "movmem_<mode>"
1020 [(set (mem:BLK (reg:HI REG_X))
1021 (mem:BLK (reg:HI REG_Z)))
1022 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1024 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
1025 (clobber (reg:HI REG_X))
1026 (clobber (reg:HI REG_Z))
1027 (clobber (reg:QI LPM_REGNO))
1028 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
1031 return avr_out_movmem (insn, operands, NULL);
1033 [(set_attr "adjust_len" "movmem")
1034 (set_attr "cc" "clobber")])
1037 ;; $0 : Address Space
1038 ;; $1 : RAMPZ RAM address
1039 ;; R24 : #bytes and loop register
1040 ;; R23:Z : 24-bit source address
1041 ;; R26 : 16-bit destination address
1045 (define_insn "movmemx_<mode>"
1046 [(set (mem:BLK (reg:HI REG_X))
1047 (mem:BLK (lo_sum:PSI (reg:QI 23)
1049 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
1052 (clobber (reg:HI REG_X))
1053 (clobber (reg:HI REG_Z))
1054 (clobber (reg:QI LPM_REGNO))
1055 (clobber (reg:HI 24))
1056 (clobber (reg:QI 23))
1057 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
1059 "%~call __movmemx_<mode>"
1060 [(set_attr "type" "xcall")
1061 (set_attr "cc" "clobber")])
1064 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
1065 ;; memset (%0, %2, %1)
1067 (define_expand "setmemhi"
1068 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1069 (match_operand 2 "const_int_operand" ""))
1070 (use (match_operand:HI 1 "const_int_operand" ""))
1071 (use (match_operand:HI 3 "const_int_operand" ""))
1072 (clobber (match_scratch:HI 5 ""))
1073 (clobber (match_dup 4))])]
1079 /* If value to set is not zero, use the library routine. */
1080 if (operands[2] != const0_rtx)
1083 if (!CONST_INT_P (operands[1]))
1086 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1087 operands[4] = gen_rtx_SCRATCH (mode);
1088 operands[1] = copy_to_mode_reg (mode,
1089 gen_int_mode (INTVAL (operands[1]), mode));
1090 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1091 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1095 (define_insn "*clrmemqi"
1096 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1098 (use (match_operand:QI 1 "register_operand" "r"))
1099 (use (match_operand:QI 2 "const_int_operand" "n"))
1100 (clobber (match_scratch:HI 3 "=0"))
1101 (clobber (match_scratch:QI 4 "=&1"))]
1103 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1104 [(set_attr "length" "3")
1105 (set_attr "cc" "clobber")])
1108 (define_insn "*clrmemhi"
1109 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1111 (use (match_operand:HI 1 "register_operand" "!w,d"))
1112 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1113 (clobber (match_scratch:HI 3 "=0,0"))
1114 (clobber (match_scratch:HI 4 "=&1,&1"))]
1117 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1118 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1119 [(set_attr "length" "3,4")
1120 (set_attr "cc" "clobber,clobber")])
1122 (define_expand "strlenhi"
1124 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1125 (match_operand:QI 2 "const_int_operand" "")
1126 (match_operand:HI 3 "immediate_operand" "")]
1129 (plus:HI (match_dup 4)
1131 (parallel [(set (match_operand:HI 0 "register_operand" "")
1132 (minus:HI (match_dup 4)
1134 (clobber (scratch:QI))])]
1138 if (operands[2] != const0_rtx)
1140 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1141 operands[1] = gen_rtx_MEM (BLKmode, addr);
1143 operands[4] = gen_reg_rtx (HImode);
1146 (define_insn "*strlenhi"
1147 [(set (match_operand:HI 0 "register_operand" "=e")
1148 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1150 (match_operand:HI 2 "immediate_operand" "i")]
1153 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1154 [(set_attr "length" "3")
1155 (set_attr "cc" "clobber")])
1157 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1161 ;; "addqq3" "adduqq3"
1162 (define_insn "add<mode>3"
1163 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1164 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1165 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1174 [(set_attr "length" "1,1,1,1,2,2")
1175 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1178 ;; "addhq3" "adduhq3"
1179 ;; "addha3" "adduha3"
1180 (define_expand "add<mode>3"
1181 [(set (match_operand:ALL2 0 "register_operand" "")
1182 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1183 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1186 if (CONST_INT_P (operands[2]))
1188 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1190 if (can_create_pseudo_p()
1191 && !stack_register_operand (operands[0], HImode)
1192 && !stack_register_operand (operands[1], HImode)
1193 && !d_register_operand (operands[0], HImode)
1194 && !d_register_operand (operands[1], HImode))
1196 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1201 if (CONST_FIXED_P (operands[2]))
1203 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1209 (define_insn "*addhi3_zero_extend"
1210 [(set (match_operand:HI 0 "register_operand" "=r,*?r")
1211 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r ,0"))
1212 (match_operand:HI 2 "register_operand" "0 ,r")))]
1215 add %A0,%1\;adc %B0,__zero_reg__
1216 add %A0,%A2\;mov %B0,%B2\;adc %B0,__zero_reg__"
1217 [(set_attr "length" "2,3")
1218 (set_attr "cc" "set_n")])
1220 (define_insn "*addhi3_zero_extend1"
1221 [(set (match_operand:HI 0 "register_operand" "=r")
1222 (plus:HI (match_operand:HI 1 "register_operand" "0")
1223 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1225 "add %A0,%2\;adc %B0,__zero_reg__"
1226 [(set_attr "length" "2")
1227 (set_attr "cc" "set_n")])
1229 (define_insn "*addhi3.sign_extend1"
1230 [(set (match_operand:HI 0 "register_operand" "=r")
1231 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1232 (match_operand:HI 2 "register_operand" "0")))]
1235 return reg_overlap_mentioned_p (operands[0], operands[1])
1236 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1237 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1239 [(set_attr "length" "5")
1240 (set_attr "cc" "clobber")])
1242 (define_insn "*addhi3_zero_extend.const"
1243 [(set (match_operand:HI 0 "register_operand" "=d")
1244 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1245 (match_operand:HI 2 "const_m255_to_m1_operand" "Cn8")))]
1247 "subi %A0,%n2\;sbc %B0,%B0"
1248 [(set_attr "length" "2")
1249 (set_attr "cc" "set_czn")])
1251 (define_insn "*usum_widenqihi3"
1252 [(set (match_operand:HI 0 "register_operand" "=r")
1253 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1254 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1256 "add %A0,%2\;clr %B0\;rol %B0"
1257 [(set_attr "length" "3")
1258 (set_attr "cc" "clobber")])
1260 (define_insn "*udiff_widenqihi3"
1261 [(set (match_operand:HI 0 "register_operand" "=r")
1262 (minus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
1263 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1265 "sub %A0,%2\;sbc %B0,%B0"
1266 [(set_attr "length" "2")
1267 (set_attr "cc" "set_czn")])
1269 (define_insn "*addhi3_sp"
1270 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1271 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1272 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1275 return avr_out_addto_sp (operands, NULL);
1277 [(set_attr "length" "6")
1278 (set_attr "adjust_len" "addto_sp")])
1281 ;; "*addhq3" "*adduhq3"
1282 ;; "*addha3" "*adduha3"
1283 (define_insn "*add<mode>3"
1284 [(set (match_operand:ALL2 0 "register_operand" "=??r,d,!w ,d")
1285 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1286 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1289 return avr_out_plus (insn, operands);
1291 [(set_attr "length" "2")
1292 (set_attr "adjust_len" "plus")
1293 (set_attr "cc" "plus")])
1295 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1296 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1297 ;; itself because that insn is special to reload.
1299 (define_peephole2 ; addhi3_clobber
1300 [(set (match_operand:ALL2 0 "d_register_operand" "")
1301 (match_operand:ALL2 1 "const_operand" ""))
1302 (set (match_operand:ALL2 2 "l_register_operand" "")
1303 (plus:ALL2 (match_dup 2)
1305 "peep2_reg_dead_p (2, operands[0])"
1306 [(parallel [(set (match_dup 2)
1307 (plus:ALL2 (match_dup 2)
1309 (clobber (match_dup 3))])]
1311 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1314 ;; Same, but with reload to NO_LD_REGS
1315 ;; Combine *reload_inhi with *addhi3
1317 (define_peephole2 ; addhi3_clobber
1318 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1319 (match_operand:ALL2 1 "const_operand" ""))
1320 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1321 (set (match_operand:ALL2 3 "l_register_operand" "")
1322 (plus:ALL2 (match_dup 3)
1324 "peep2_reg_dead_p (2, operands[0])"
1325 [(parallel [(set (match_dup 3)
1326 (plus:ALL2 (match_dup 3)
1328 (clobber (match_dup 2))])])
1331 ;; "addhq3_clobber" "adduhq3_clobber"
1332 ;; "addha3_clobber" "adduha3_clobber"
1333 (define_insn "add<mode>3_clobber"
1334 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1335 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1336 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1337 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1340 return avr_out_plus (insn, operands);
1342 [(set_attr "length" "4")
1343 (set_attr "adjust_len" "plus")
1344 (set_attr "cc" "plus")])
1348 ;; "addsq3" "addusq3"
1349 ;; "addsa3" "addusa3"
1350 (define_insn "add<mode>3"
1351 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1352 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1353 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1354 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1357 return avr_out_plus (insn, operands);
1359 [(set_attr "length" "4")
1360 (set_attr "adjust_len" "plus")
1361 (set_attr "cc" "plus")])
1363 (define_insn "*addpsi3_zero_extend.qi"
1364 [(set (match_operand:PSI 0 "register_operand" "=r")
1365 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1366 (match_operand:PSI 2 "register_operand" "0")))]
1368 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1369 [(set_attr "length" "3")
1370 (set_attr "cc" "set_n")])
1372 (define_insn "*addpsi3_zero_extend.hi"
1373 [(set (match_operand:PSI 0 "register_operand" "=r")
1374 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1375 (match_operand:PSI 2 "register_operand" "0")))]
1377 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1378 [(set_attr "length" "3")
1379 (set_attr "cc" "set_n")])
1381 (define_insn "*addpsi3_sign_extend.hi"
1382 [(set (match_operand:PSI 0 "register_operand" "=r")
1383 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1384 (match_operand:PSI 2 "register_operand" "0")))]
1386 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1387 [(set_attr "length" "5")
1388 (set_attr "cc" "set_n")])
1390 (define_insn "*addsi3_zero_extend"
1391 [(set (match_operand:SI 0 "register_operand" "=r")
1392 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1393 (match_operand:SI 2 "register_operand" "0")))]
1395 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1396 [(set_attr "length" "4")
1397 (set_attr "cc" "set_n")])
1399 (define_insn "*addsi3_zero_extend.hi"
1400 [(set (match_operand:SI 0 "register_operand" "=r")
1401 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1402 (match_operand:SI 2 "register_operand" "0")))]
1404 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1405 [(set_attr "length" "4")
1406 (set_attr "cc" "set_n")])
1408 (define_insn "addpsi3"
1409 [(set (match_operand:PSI 0 "register_operand" "=??r,d ,d,r")
1410 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1411 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1412 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1415 return avr_out_plus (insn, operands);
1417 [(set_attr "length" "3")
1418 (set_attr "adjust_len" "plus")
1419 (set_attr "cc" "plus")])
1421 (define_insn "subpsi3"
1422 [(set (match_operand:PSI 0 "register_operand" "=r")
1423 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1424 (match_operand:PSI 2 "register_operand" "r")))]
1426 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1427 [(set_attr "length" "3")
1428 (set_attr "cc" "set_czn")])
1430 (define_insn "*subpsi3_zero_extend.qi"
1431 [(set (match_operand:PSI 0 "register_operand" "=r")
1432 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1433 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1435 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1436 [(set_attr "length" "3")
1437 (set_attr "cc" "set_czn")])
1439 (define_insn "*subpsi3_zero_extend.hi"
1440 [(set (match_operand:PSI 0 "register_operand" "=r")
1441 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1442 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1444 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1445 [(set_attr "length" "3")
1446 (set_attr "cc" "set_czn")])
1448 (define_insn "*subpsi3_sign_extend.hi"
1449 [(set (match_operand:PSI 0 "register_operand" "=r")
1450 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1451 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1453 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1454 [(set_attr "length" "5")
1455 (set_attr "cc" "set_czn")])
1457 ;-----------------------------------------------------------------------------
1461 ;; "subqq3" "subuqq3"
1462 (define_insn "sub<mode>3"
1463 [(set (match_operand:ALL1 0 "register_operand" "=??r,d ,r ,r ,r ,r")
1464 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1465 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1474 [(set_attr "length" "1,1,1,1,2,2")
1475 (set_attr "cc" "set_czn,set_czn,set_vzn,set_vzn,set_vzn,set_vzn")])
1478 ;; "subhq3" "subuhq3"
1479 ;; "subha3" "subuha3"
1480 (define_insn "sub<mode>3"
1481 [(set (match_operand:ALL2 0 "register_operand" "=??r,d ,*r")
1482 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1483 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1484 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1487 return avr_out_plus (insn, operands);
1489 [(set_attr "adjust_len" "plus")
1490 (set_attr "cc" "plus")])
1492 (define_insn "*subhi3_zero_extend1"
1493 [(set (match_operand:HI 0 "register_operand" "=r")
1494 (minus:HI (match_operand:HI 1 "register_operand" "0")
1495 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1497 "sub %A0,%2\;sbc %B0,__zero_reg__"
1498 [(set_attr "length" "2")
1499 (set_attr "cc" "set_czn")])
1501 (define_insn "*subhi3.sign_extend2"
1502 [(set (match_operand:HI 0 "register_operand" "=r")
1503 (minus:HI (match_operand:HI 1 "register_operand" "0")
1504 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1507 return reg_overlap_mentioned_p (operands[0], operands[2])
1508 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1509 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1511 [(set_attr "length" "5")
1512 (set_attr "cc" "clobber")])
1515 ;; "subsq3" "subusq3"
1516 ;; "subsa3" "subusa3"
1517 (define_insn "sub<mode>3"
1518 [(set (match_operand:ALL4 0 "register_operand" "=??r,d ,r")
1519 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1520 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1521 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1524 return avr_out_plus (insn, operands);
1526 [(set_attr "adjust_len" "plus")
1527 (set_attr "cc" "plus")])
1529 (define_insn "*subsi3_zero_extend"
1530 [(set (match_operand:SI 0 "register_operand" "=r")
1531 (minus:SI (match_operand:SI 1 "register_operand" "0")
1532 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1534 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1535 [(set_attr "length" "4")
1536 (set_attr "cc" "set_czn")])
1538 (define_insn "*subsi3_zero_extend.hi"
1539 [(set (match_operand:SI 0 "register_operand" "=r")
1540 (minus:SI (match_operand:SI 1 "register_operand" "0")
1541 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1543 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1544 [(set_attr "length" "4")
1545 (set_attr "cc" "set_czn")])
1547 ;******************************************************************************
1550 (define_expand "mulqi3"
1551 [(set (match_operand:QI 0 "register_operand" "")
1552 (mult:QI (match_operand:QI 1 "register_operand" "")
1553 (match_operand:QI 2 "register_operand" "")))]
1558 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1563 (define_insn "*mulqi3_enh"
1564 [(set (match_operand:QI 0 "register_operand" "=r")
1565 (mult:QI (match_operand:QI 1 "register_operand" "r")
1566 (match_operand:QI 2 "register_operand" "r")))]
1571 [(set_attr "length" "3")
1572 (set_attr "cc" "clobber")])
1574 (define_expand "mulqi3_call"
1575 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1576 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1577 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1578 (clobber (reg:QI 22))])
1579 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1582 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
1585 (define_insn "*mulqi3_call"
1586 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1587 (clobber (reg:QI 22))]
1590 [(set_attr "type" "xcall")
1591 (set_attr "cc" "clobber")])
1593 ;; "umulqi3_highpart"
1594 ;; "smulqi3_highpart"
1595 (define_insn "<extend_su>mulqi3_highpart"
1596 [(set (match_operand:QI 0 "register_operand" "=r")
1598 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1599 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1602 "mul<extend_s> %1,%2
1605 [(set_attr "length" "3")
1606 (set_attr "cc" "clobber")])
1609 ;; Used when expanding div or mod inline for some special values
1610 (define_insn "*subqi3.ashiftrt7"
1611 [(set (match_operand:QI 0 "register_operand" "=r")
1612 (minus:QI (match_operand:QI 1 "register_operand" "0")
1613 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1617 [(set_attr "length" "2")
1618 (set_attr "cc" "clobber")])
1620 (define_insn "*addqi3.lt0"
1621 [(set (match_operand:QI 0 "register_operand" "=r")
1622 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1624 (match_operand:QI 2 "register_operand" "0")))]
1627 [(set_attr "length" "2")
1628 (set_attr "cc" "clobber")])
1630 (define_insn "*addhi3.lt0"
1631 [(set (match_operand:HI 0 "register_operand" "=w,r")
1632 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1634 (match_operand:HI 2 "register_operand" "0,0")))
1635 (clobber (match_scratch:QI 3 "=X,&1"))]
1638 sbrc %1,7\;adiw %0,1
1639 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1640 [(set_attr "length" "2,3")
1641 (set_attr "cc" "clobber")])
1643 (define_insn "*addpsi3.lt0"
1644 [(set (match_operand:PSI 0 "register_operand" "=r")
1645 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1647 (match_operand:PSI 2 "register_operand" "0")))]
1649 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1650 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1651 [(set_attr "length" "5")
1652 (set_attr "cc" "clobber")])
1654 (define_insn "*addsi3.lt0"
1655 [(set (match_operand:SI 0 "register_operand" "=r")
1656 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1658 (match_operand:SI 2 "register_operand" "0")))]
1660 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1661 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1662 [(set_attr "length" "6")
1663 (set_attr "cc" "clobber")])
1665 (define_insn "*umulqihi3.call"
1667 (mult:HI (zero_extend:HI (reg:QI 22))
1668 (zero_extend:HI (reg:QI 24))))
1669 (clobber (reg:QI 21))
1670 (clobber (reg:HI 22))]
1672 "%~call __umulqihi3"
1673 [(set_attr "type" "xcall")
1674 (set_attr "cc" "clobber")])
1678 (define_insn "<extend_u>mulqihi3"
1679 [(set (match_operand:HI 0 "register_operand" "=r")
1680 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1681 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1683 "mul<extend_s> %1,%2
1686 [(set_attr "length" "3")
1687 (set_attr "cc" "clobber")])
1689 (define_insn "usmulqihi3"
1690 [(set (match_operand:HI 0 "register_operand" "=r")
1691 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1692 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1697 [(set_attr "length" "3")
1698 (set_attr "cc" "clobber")])
1700 ;; Above insn is not canonicalized by insn combine, so here is a version with
1701 ;; operands swapped.
1703 (define_insn "*sumulqihi3"
1704 [(set (match_operand:HI 0 "register_operand" "=r")
1705 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1706 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1711 [(set_attr "length" "3")
1712 (set_attr "cc" "clobber")])
1714 ;; One-extend operand 1
1716 (define_insn "*osmulqihi3"
1717 [(set (match_operand:HI 0 "register_operand" "=&r")
1718 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1719 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1725 [(set_attr "length" "4")
1726 (set_attr "cc" "clobber")])
1728 (define_insn "*oumulqihi3"
1729 [(set (match_operand:HI 0 "register_operand" "=&r")
1730 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1731 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1737 [(set_attr "length" "4")
1738 (set_attr "cc" "clobber")])
1740 ;******************************************************************************
1741 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1742 ;******************************************************************************
1744 (define_insn "*maddqi4"
1745 [(set (match_operand:QI 0 "register_operand" "=r")
1746 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1747 (match_operand:QI 2 "register_operand" "r"))
1748 (match_operand:QI 3 "register_operand" "0")))]
1754 [(set_attr "length" "4")
1755 (set_attr "cc" "clobber")])
1757 (define_insn "*msubqi4"
1758 [(set (match_operand:QI 0 "register_operand" "=r")
1759 (minus:QI (match_operand:QI 3 "register_operand" "0")
1760 (mult:QI (match_operand:QI 1 "register_operand" "r")
1761 (match_operand:QI 2 "register_operand" "r"))))]
1766 [(set_attr "length" "4")
1767 (set_attr "cc" "clobber")])
1769 (define_insn_and_split "*maddqi4.const"
1770 [(set (match_operand:QI 0 "register_operand" "=r")
1771 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1772 (match_operand:QI 2 "const_int_operand" "n"))
1773 (match_operand:QI 3 "register_operand" "0")))
1774 (clobber (match_scratch:QI 4 "=&d"))]
1777 "&& reload_completed"
1782 (plus:QI (mult:QI (match_dup 1)
1786 (define_insn_and_split "*msubqi4.const"
1787 [(set (match_operand:QI 0 "register_operand" "=r")
1788 (minus:QI (match_operand:QI 3 "register_operand" "0")
1789 (mult:QI (match_operand:QI 1 "register_operand" "r")
1790 (match_operand:QI 2 "const_int_operand" "n"))))
1791 (clobber (match_scratch:QI 4 "=&d"))]
1794 "&& reload_completed"
1799 (minus:QI (match_dup 3)
1800 (mult:QI (match_dup 1)
1804 ;******************************************************************************
1805 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1806 ;******************************************************************************
1808 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1811 ;; int foo (unsigned char z)
1813 ;; extern int aInt[];
1814 ;; return aInt[3*z+2];
1817 ;; because the constant +4 then is added explicitely instead of consuming it
1818 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1819 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1820 ;; The implementational effort is the same so we are fine with that approach.
1825 (define_insn "*<extend_u>maddqihi4"
1826 [(set (match_operand:HI 0 "register_operand" "=r")
1827 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1828 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1829 (match_operand:HI 3 "register_operand" "0")))]
1832 "mul<extend_s> %1,%2
1836 [(set_attr "length" "4")
1837 (set_attr "cc" "clobber")])
1841 (define_insn "*<extend_u>msubqihi4"
1842 [(set (match_operand:HI 0 "register_operand" "=r")
1843 (minus:HI (match_operand:HI 3 "register_operand" "0")
1844 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1845 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1847 "mul<extend_s> %1,%2
1851 [(set_attr "length" "4")
1852 (set_attr "cc" "clobber")])
1856 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1857 [(set (match_operand:HI 0 "register_operand" "=r")
1858 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1859 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1860 (match_operand:HI 3 "register_operand" "0")))]
1863 && <any_extend:CODE> != <any_extend2:CODE>"
1865 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1866 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1868 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1870 [(set_attr "length" "4")
1871 (set_attr "cc" "clobber")])
1875 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1876 [(set (match_operand:HI 0 "register_operand" "=r")
1877 (minus:HI (match_operand:HI 3 "register_operand" "0")
1878 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1879 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1882 && <any_extend:CODE> != <any_extend2:CODE>"
1884 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1885 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1887 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1889 [(set_attr "length" "4")
1890 (set_attr "cc" "clobber")])
1892 ;; Handle small constants
1894 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1895 ;; This is shorter, faster than MUL and has lower register pressure.
1897 (define_insn_and_split "*umaddqihi4.2"
1898 [(set (match_operand:HI 0 "register_operand" "=r")
1899 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1901 (match_operand:HI 2 "register_operand" "r")))]
1903 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1904 { gcc_unreachable(); }
1908 ; *addhi3_zero_extend
1910 (plus:HI (zero_extend:HI (match_dup 1))
1912 ; *addhi3_zero_extend
1914 (plus:HI (zero_extend:HI (match_dup 1))
1917 ;; "umaddqihi4.uconst"
1918 ;; "maddqihi4.sconst"
1919 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1920 [(set (match_operand:HI 0 "register_operand" "=r")
1921 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1922 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1923 (match_operand:HI 3 "register_operand" "0")))
1924 (clobber (match_scratch:QI 4 "=&d"))]
1927 "&& reload_completed"
1930 ; *umaddqihi4 resp. *maddqihi4
1932 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1933 (any_extend:HI (match_dup 4)))
1936 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1939 ;; "*umsubqihi4.uconst"
1940 ;; "*msubqihi4.sconst"
1941 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1942 [(set (match_operand:HI 0 "register_operand" "=r")
1943 (minus:HI (match_operand:HI 3 "register_operand" "0")
1944 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1945 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1946 (clobber (match_scratch:QI 4 "=&d"))]
1949 "&& reload_completed"
1952 ; *umsubqihi4 resp. *msubqihi4
1954 (minus:HI (match_dup 3)
1955 (mult:HI (any_extend:HI (match_dup 1))
1956 (any_extend:HI (match_dup 4)))))]
1958 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1961 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1962 ;; for MULT with power of 2 and skips trying MULT insn above.
1964 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1965 [(set (match_operand:HI 0 "register_operand" "=r")
1966 (minus:HI (match_operand:HI 3 "register_operand" "0")
1967 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1968 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1969 (clobber (match_scratch:QI 4 "=&d"))]
1972 "&& reload_completed"
1977 (minus:HI (match_dup 3)
1978 (mult:HI (zero_extend:HI (match_dup 1))
1979 (zero_extend:HI (match_dup 4)))))]
1981 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1984 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1985 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1986 ;; because this would require an extra pattern for just one value.
1988 (define_insn_and_split "*msubqihi4.sconst.ashift"
1989 [(set (match_operand:HI 0 "register_operand" "=r")
1990 (minus:HI (match_operand:HI 3 "register_operand" "0")
1991 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1992 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1993 (clobber (match_scratch:QI 4 "=&d"))]
1996 "&& reload_completed"
2001 (minus:HI (match_dup 3)
2002 (mult:HI (sign_extend:HI (match_dup 1))
2003 (sign_extend:HI (match_dup 4)))))]
2005 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2008 ;; For signed/unsigned combinations that require narrow constraint "a"
2009 ;; just provide a pattern if signed/unsigned combination is actually needed.
2011 (define_insn_and_split "*sumaddqihi4.uconst"
2012 [(set (match_operand:HI 0 "register_operand" "=r")
2013 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2014 (match_operand:HI 2 "u8_operand" "M"))
2015 (match_operand:HI 3 "register_operand" "0")))
2016 (clobber (match_scratch:QI 4 "=&a"))]
2018 && !s8_operand (operands[2], VOIDmode)"
2020 "&& reload_completed"
2025 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
2026 (zero_extend:HI (match_dup 4)))
2029 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2032 (define_insn_and_split "*sumsubqihi4.uconst"
2033 [(set (match_operand:HI 0 "register_operand" "=r")
2034 (minus:HI (match_operand:HI 3 "register_operand" "0")
2035 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2036 (match_operand:HI 2 "u8_operand" "M"))))
2037 (clobber (match_scratch:QI 4 "=&a"))]
2039 && !s8_operand (operands[2], VOIDmode)"
2041 "&& reload_completed"
2046 (minus:HI (match_dup 3)
2047 (mult:HI (sign_extend:HI (match_dup 1))
2048 (zero_extend:HI (match_dup 4)))))]
2050 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2053 ;******************************************************************************
2054 ; mul HI: $1 = sign/zero-extend, $2 = small constant
2055 ;******************************************************************************
2057 ;; "*muluqihi3.uconst"
2058 ;; "*mulsqihi3.sconst"
2059 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
2060 [(set (match_operand:HI 0 "register_operand" "=r")
2061 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
2062 (match_operand:HI 2 "<extend_su>8_operand" "n")))
2063 (clobber (match_scratch:QI 3 "=&d"))]
2066 "&& reload_completed"
2069 ; umulqihi3 resp. mulqihi3
2071 (mult:HI (any_extend:HI (match_dup 1))
2072 (any_extend:HI (match_dup 3))))]
2074 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2077 (define_insn_and_split "*muluqihi3.sconst"
2078 [(set (match_operand:HI 0 "register_operand" "=r")
2079 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2080 (match_operand:HI 2 "s8_operand" "n")))
2081 (clobber (match_scratch:QI 3 "=&a"))]
2084 "&& reload_completed"
2089 (mult:HI (zero_extend:HI (match_dup 1))
2090 (sign_extend:HI (match_dup 3))))]
2092 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2095 (define_insn_and_split "*mulsqihi3.uconst"
2096 [(set (match_operand:HI 0 "register_operand" "=r")
2097 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2098 (match_operand:HI 2 "u8_operand" "M")))
2099 (clobber (match_scratch:QI 3 "=&a"))]
2102 "&& reload_completed"
2107 (mult:HI (zero_extend:HI (match_dup 3))
2108 (sign_extend:HI (match_dup 1))))]
2110 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2113 (define_insn_and_split "*mulsqihi3.oconst"
2114 [(set (match_operand:HI 0 "register_operand" "=&r")
2115 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2116 (match_operand:HI 2 "o8_operand" "n")))
2117 (clobber (match_scratch:QI 3 "=&a"))]
2120 "&& reload_completed"
2125 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2126 (sign_extend:HI (match_dup 1))))]
2128 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2131 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2132 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2133 ;; at that time. Fix that.
2135 (define_insn "*ashiftqihi2.signx.1"
2136 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2137 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2141 lsl %A0\;sbc %B0,%B0
2142 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2143 [(set_attr "length" "2,3")
2144 (set_attr "cc" "clobber")])
2146 (define_insn_and_split "*ashifthi3.signx.const"
2147 [(set (match_operand:HI 0 "register_operand" "=r")
2148 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2149 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2150 (clobber (match_scratch:QI 3 "=&d"))]
2153 "&& reload_completed"
2158 (mult:HI (sign_extend:HI (match_dup 1))
2159 (sign_extend:HI (match_dup 3))))]
2161 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2164 (define_insn_and_split "*ashifthi3.signx.const7"
2165 [(set (match_operand:HI 0 "register_operand" "=r")
2166 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2168 (clobber (match_scratch:QI 2 "=&a"))]
2171 "&& reload_completed"
2176 (mult:HI (zero_extend:HI (match_dup 2))
2177 (sign_extend:HI (match_dup 1))))]
2179 operands[3] = gen_int_mode (1 << 7, QImode);
2182 (define_insn_and_split "*ashifthi3.zerox.const"
2183 [(set (match_operand:HI 0 "register_operand" "=r")
2184 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2185 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2186 (clobber (match_scratch:QI 3 "=&d"))]
2189 "&& reload_completed"
2194 (mult:HI (zero_extend:HI (match_dup 1))
2195 (zero_extend:HI (match_dup 3))))]
2197 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2200 ;******************************************************************************
2201 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2202 ;******************************************************************************
2204 (define_insn "mulsqihi3"
2205 [(set (match_operand:HI 0 "register_operand" "=&r")
2206 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2207 (match_operand:HI 2 "register_operand" "a")))]
2214 [(set_attr "length" "5")
2215 (set_attr "cc" "clobber")])
2217 (define_insn "muluqihi3"
2218 [(set (match_operand:HI 0 "register_operand" "=&r")
2219 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2220 (match_operand:HI 2 "register_operand" "r")))]
2227 [(set_attr "length" "5")
2228 (set_attr "cc" "clobber")])
2230 ;; one-extend operand 1
2232 (define_insn "muloqihi3"
2233 [(set (match_operand:HI 0 "register_operand" "=&r")
2234 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2235 (match_operand:HI 2 "register_operand" "r")))]
2243 [(set_attr "length" "6")
2244 (set_attr "cc" "clobber")])
2246 ;******************************************************************************
2248 (define_expand "mulhi3"
2249 [(set (match_operand:HI 0 "register_operand" "")
2250 (mult:HI (match_operand:HI 1 "register_operand" "")
2251 (match_operand:HI 2 "register_or_s9_operand" "")))]
2256 if (!register_operand (operands[2], HImode))
2257 operands[2] = force_reg (HImode, operands[2]);
2259 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2263 /* ; For small constants we can do better by extending them on the fly.
2264 ; The constant can be loaded in one instruction and the widening
2265 ; multiplication is shorter. First try the unsigned variant because it
2266 ; allows constraint "d" instead of "a" for the signed version. */
2268 if (s9_operand (operands[2], HImode))
2270 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2272 if (u8_operand (operands[2], HImode))
2274 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2276 else if (s8_operand (operands[2], HImode))
2278 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2282 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2288 if (!register_operand (operands[2], HImode))
2289 operands[2] = force_reg (HImode, operands[2]);
2292 (define_insn "*mulhi3_enh"
2293 [(set (match_operand:HI 0 "register_operand" "=&r")
2294 (mult:HI (match_operand:HI 1 "register_operand" "r")
2295 (match_operand:HI 2 "register_operand" "r")))]
2298 return REGNO (operands[1]) == REGNO (operands[2])
2299 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2300 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2302 [(set_attr "length" "7")
2303 (set_attr "cc" "clobber")])
2305 (define_expand "mulhi3_call"
2306 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2307 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2308 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2309 (clobber (reg:HI 22))
2310 (clobber (reg:QI 21))])
2311 (set (match_operand:HI 0 "register_operand" "")
2315 avr_fix_inputs (operands, (1 << 2), regmask (HImode, 24));
2319 (define_insn "*mulhi3_call"
2320 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2321 (clobber (reg:HI 22))
2322 (clobber (reg:QI 21))]
2325 [(set_attr "type" "xcall")
2326 (set_attr "cc" "clobber")])
2328 ;; To support widening multiplication with constant we postpone
2329 ;; expanding to the implicit library call until post combine and
2330 ;; prior to register allocation. Clobber all hard registers that
2331 ;; might be used by the (widening) multiply until it is split and
2332 ;; it's final register footprint is worked out.
2334 (define_expand "mulsi3"
2335 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2336 (mult:SI (match_operand:SI 1 "register_operand" "")
2337 (match_operand:SI 2 "nonmemory_operand" "")))
2338 (clobber (reg:HI 26))
2339 (clobber (reg:DI 18))])]
2342 if (u16_operand (operands[2], SImode))
2344 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2345 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2349 if (o16_operand (operands[2], SImode))
2351 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2352 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2356 if (avr_emit3_fix_outputs (gen_mulsi3, operands, 1 << 0,
2357 regmask (DImode, 18) | regmask (HImode, 26)))
2361 (define_insn_and_split "*mulsi3"
2362 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2363 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2364 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2365 (clobber (reg:HI 26))
2366 (clobber (reg:DI 18))]
2367 "AVR_HAVE_MUL && !reload_completed"
2368 { gcc_unreachable(); }
2374 (parallel [(set (reg:SI 22)
2375 (mult:SI (reg:SI 22)
2377 (clobber (reg:HI 26))])
2381 if (u16_operand (operands[2], SImode))
2383 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2384 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2388 if (o16_operand (operands[2], SImode))
2390 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2391 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2398 (define_expand "mulu<mode>si3"
2399 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2400 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
2401 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2402 (clobber (reg:HI 26))
2403 (clobber (reg:DI 18))])]
2406 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2407 if (avr_emit3_fix_outputs (gen_mulu<mode>si3, operands, 1 << 0,
2408 regmask (DImode, 18) | regmask (HImode, 26)))
2414 (define_insn_and_split "*mulu<mode>si3"
2415 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2416 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2417 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2418 (clobber (reg:HI 26))
2419 (clobber (reg:DI 18))]
2420 "AVR_HAVE_MUL && !reload_completed"
2421 { gcc_unreachable(); }
2428 (mult:SI (zero_extend:SI (reg:HI 26))
2433 /* Do the QI -> HI extension explicitely before the multiplication. */
2434 /* Do the HI -> SI extension implicitely and after the multiplication. */
2436 if (QImode == <MODE>mode)
2437 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2439 if (u16_operand (operands[2], SImode))
2441 operands[1] = force_reg (HImode, operands[1]);
2442 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2443 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2450 (define_expand "muls<mode>si3"
2451 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2452 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" ""))
2453 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2454 (clobber (reg:HI 26))
2455 (clobber (reg:DI 18))])]
2458 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2459 if (avr_emit3_fix_outputs (gen_muls<mode>si3, operands, 1 << 0,
2460 regmask (DImode, 18) | regmask (HImode, 26)))
2466 (define_insn_and_split "*muls<mode>si3"
2467 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2468 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2469 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2470 (clobber (reg:HI 26))
2471 (clobber (reg:DI 18))]
2472 "AVR_HAVE_MUL && !reload_completed"
2473 { gcc_unreachable(); }
2480 (mult:SI (sign_extend:SI (reg:HI 26))
2485 /* Do the QI -> HI extension explicitely before the multiplication. */
2486 /* Do the HI -> SI extension implicitely and after the multiplication. */
2488 if (QImode == <MODE>mode)
2489 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2491 if (u16_operand (operands[2], SImode)
2492 || s16_operand (operands[2], SImode))
2494 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2496 operands[1] = force_reg (HImode, operands[1]);
2498 if (u16_operand (operands[2], SImode))
2499 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2501 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2507 ;; One-extend operand 1
2509 (define_expand "mulohisi3"
2510 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2511 (mult:SI (not:SI (zero_extend:SI
2512 (not:HI (match_operand:HI 1 "pseudo_register_operand" ""))))
2513 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "")))
2514 (clobber (reg:HI 26))
2515 (clobber (reg:DI 18))])]
2518 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2519 if (avr_emit3_fix_outputs (gen_mulohisi3, operands, 1 << 0,
2520 regmask (DImode, 18) | regmask (HImode, 26)))
2524 (define_insn_and_split "*mulohisi3"
2525 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2526 (mult:SI (not:SI (zero_extend:SI
2527 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2528 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2529 (clobber (reg:HI 26))
2530 (clobber (reg:DI 18))]
2531 "AVR_HAVE_MUL && !reload_completed"
2532 { gcc_unreachable(); }
2539 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2546 (define_expand "<extend_u>mulhisi3"
2547 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2548 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2549 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2550 (clobber (reg:HI 26))
2551 (clobber (reg:DI 18))])]
2554 if (avr_emit3_fix_outputs (gen_<extend_u>mulhisi3, operands, 1 << 0,
2555 regmask (DImode, 18) | regmask (HImode, 26)))
2559 (define_expand "usmulhisi3"
2560 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2561 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2562 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2563 (clobber (reg:HI 26))
2564 (clobber (reg:DI 18))])]
2567 if (avr_emit3_fix_outputs (gen_usmulhisi3, operands, 1 << 0,
2568 regmask (DImode, 18) | regmask (HImode, 26)))
2572 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2573 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2574 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2575 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2576 (define_insn_and_split
2577 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2578 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2579 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2580 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2581 (clobber (reg:HI 26))
2582 (clobber (reg:DI 18))]
2583 "AVR_HAVE_MUL && !reload_completed"
2584 { gcc_unreachable(); }
2591 (mult:SI (match_dup 3)
2596 rtx xop1 = operands[1];
2597 rtx xop2 = operands[2];
2599 /* Do the QI -> HI extension explicitely before the multiplication. */
2600 /* Do the HI -> SI extension implicitely and after the multiplication. */
2602 if (QImode == <QIHI:MODE>mode)
2603 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2605 if (QImode == <QIHI2:MODE>mode)
2606 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2608 if (<any_extend:CODE> == <any_extend2:CODE>
2609 || <any_extend:CODE> == ZERO_EXTEND)
2613 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2614 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2618 /* <any_extend:CODE> = SIGN_EXTEND */
2619 /* <any_extend2:CODE> = ZERO_EXTEND */
2623 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2624 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2628 ;; "smulhi3_highpart"
2629 ;; "umulhi3_highpart"
2630 (define_expand "<extend_su>mulhi3_highpart"
2632 (match_operand:HI 1 "nonmemory_operand" ""))
2634 (match_operand:HI 2 "nonmemory_operand" ""))
2635 (parallel [(set (reg:HI 24)
2636 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2637 (any_extend:SI (reg:HI 26)))
2639 (clobber (reg:HI 22))])
2640 (set (match_operand:HI 0 "register_operand" "")
2644 avr_fix_inputs (operands, 1 << 2, regmask (HImode, 18));
2648 (define_insn "*mulsi3_call"
2650 (mult:SI (reg:SI 22)
2652 (clobber (reg:HI 26))]
2655 [(set_attr "type" "xcall")
2656 (set_attr "cc" "clobber")])
2659 ;; "*umulhisi3_call"
2660 (define_insn "*<extend_u>mulhisi3_call"
2662 (mult:SI (any_extend:SI (reg:HI 18))
2663 (any_extend:SI (reg:HI 26))))]
2665 "%~call __<extend_u>mulhisi3"
2666 [(set_attr "type" "xcall")
2667 (set_attr "cc" "clobber")])
2669 ;; "*umulhi3_highpart_call"
2670 ;; "*smulhi3_highpart_call"
2671 (define_insn "*<extend_su>mulhi3_highpart_call"
2673 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2674 (any_extend:SI (reg:HI 26)))
2676 (clobber (reg:HI 22))]
2678 "%~call __<extend_u>mulhisi3"
2679 [(set_attr "type" "xcall")
2680 (set_attr "cc" "clobber")])
2682 (define_insn "*usmulhisi3_call"
2684 (mult:SI (zero_extend:SI (reg:HI 18))
2685 (sign_extend:SI (reg:HI 26))))]
2687 "%~call __usmulhisi3"
2688 [(set_attr "type" "xcall")
2689 (set_attr "cc" "clobber")])
2691 (define_insn "*mul<extend_su>hisi3_call"
2693 (mult:SI (any_extend:SI (reg:HI 26))
2696 "%~call __mul<extend_su>hisi3"
2697 [(set_attr "type" "xcall")
2698 (set_attr "cc" "clobber")])
2700 (define_insn "*mulohisi3_call"
2702 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2705 "%~call __mulohisi3"
2706 [(set_attr "type" "xcall")
2707 (set_attr "cc" "clobber")])
2709 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2712 ;; Generate lib1funcs.S calls ourselves, because:
2713 ;; - we know exactly which registers are clobbered (for QI and HI
2714 ;; modes, some of the call-used registers are preserved)
2715 ;; - we get both the quotient and the remainder at no extra cost
2716 ;; - we split the patterns only after the first CSE passes because
2717 ;; CSE has problems to operate on hard regs.
2719 (define_insn_and_split "divmodqi4"
2720 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2721 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2722 (match_operand:QI 2 "pseudo_register_operand" "")))
2723 (set (match_operand:QI 3 "pseudo_register_operand" "")
2724 (mod:QI (match_dup 1) (match_dup 2)))
2725 (clobber (reg:QI 22))
2726 (clobber (reg:QI 23))
2727 (clobber (reg:QI 24))
2728 (clobber (reg:QI 25))])]
2730 "this divmodqi4 pattern should have been splitted;"
2732 [(set (reg:QI 24) (match_dup 1))
2733 (set (reg:QI 22) (match_dup 2))
2734 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2735 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2736 (clobber (reg:QI 22))
2737 (clobber (reg:QI 23))])
2738 (set (match_dup 0) (reg:QI 24))
2739 (set (match_dup 3) (reg:QI 25))])
2741 (define_insn "*divmodqi4_call"
2742 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2743 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2744 (clobber (reg:QI 22))
2745 (clobber (reg:QI 23))]
2747 "%~call __divmodqi4"
2748 [(set_attr "type" "xcall")
2749 (set_attr "cc" "clobber")])
2751 (define_insn_and_split "udivmodqi4"
2752 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2753 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2754 (match_operand:QI 2 "pseudo_register_operand" "")))
2755 (set (match_operand:QI 3 "pseudo_register_operand" "")
2756 (umod:QI (match_dup 1) (match_dup 2)))
2757 (clobber (reg:QI 22))
2758 (clobber (reg:QI 23))
2759 (clobber (reg:QI 24))
2760 (clobber (reg:QI 25))])]
2762 "this udivmodqi4 pattern should have been splitted;"
2764 [(set (reg:QI 24) (match_dup 1))
2765 (set (reg:QI 22) (match_dup 2))
2766 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2767 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2768 (clobber (reg:QI 23))])
2769 (set (match_dup 0) (reg:QI 24))
2770 (set (match_dup 3) (reg:QI 25))])
2772 (define_insn "*udivmodqi4_call"
2773 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2774 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2775 (clobber (reg:QI 23))]
2777 "%~call __udivmodqi4"
2778 [(set_attr "type" "xcall")
2779 (set_attr "cc" "clobber")])
2781 (define_insn_and_split "divmodhi4"
2782 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2783 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2784 (match_operand:HI 2 "pseudo_register_operand" "")))
2785 (set (match_operand:HI 3 "pseudo_register_operand" "")
2786 (mod:HI (match_dup 1) (match_dup 2)))
2787 (clobber (reg:QI 21))
2788 (clobber (reg:HI 22))
2789 (clobber (reg:HI 24))
2790 (clobber (reg:HI 26))])]
2792 "this should have been splitted;"
2794 [(set (reg:HI 24) (match_dup 1))
2795 (set (reg:HI 22) (match_dup 2))
2796 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2797 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2798 (clobber (reg:HI 26))
2799 (clobber (reg:QI 21))])
2800 (set (match_dup 0) (reg:HI 22))
2801 (set (match_dup 3) (reg:HI 24))])
2803 (define_insn "*divmodhi4_call"
2804 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2805 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2806 (clobber (reg:HI 26))
2807 (clobber (reg:QI 21))]
2809 "%~call __divmodhi4"
2810 [(set_attr "type" "xcall")
2811 (set_attr "cc" "clobber")])
2813 (define_insn_and_split "udivmodhi4"
2814 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2815 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2816 (match_operand:HI 2 "pseudo_register_operand" "")))
2817 (set (match_operand:HI 3 "pseudo_register_operand" "")
2818 (umod:HI (match_dup 1) (match_dup 2)))
2819 (clobber (reg:QI 21))
2820 (clobber (reg:HI 22))
2821 (clobber (reg:HI 24))
2822 (clobber (reg:HI 26))])]
2824 "this udivmodhi4 pattern should have been splitted.;"
2826 [(set (reg:HI 24) (match_dup 1))
2827 (set (reg:HI 22) (match_dup 2))
2828 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2829 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2830 (clobber (reg:HI 26))
2831 (clobber (reg:QI 21))])
2832 (set (match_dup 0) (reg:HI 22))
2833 (set (match_dup 3) (reg:HI 24))])
2835 (define_insn "*udivmodhi4_call"
2836 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2837 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2838 (clobber (reg:HI 26))
2839 (clobber (reg:QI 21))]
2841 "%~call __udivmodhi4"
2842 [(set_attr "type" "xcall")
2843 (set_attr "cc" "clobber")])
2845 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2848 ;; To support widening multiplication with constant we postpone
2849 ;; expanding to the implicit library call until post combine and
2850 ;; prior to register allocation. Clobber all hard registers that
2851 ;; might be used by the (widening) multiply until it is split and
2852 ;; it's final register footprint is worked out.
2854 (define_expand "mulpsi3"
2855 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2856 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2857 (match_operand:PSI 2 "nonmemory_operand" "")))
2858 (clobber (reg:HI 26))
2859 (clobber (reg:DI 18))])]
2862 if (s8_operand (operands[2], PSImode))
2864 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2865 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2869 if (avr_emit3_fix_outputs (gen_mulpsi3, operands, 1u << 0,
2870 regmask (DImode, 18) | regmask (HImode, 26)))
2874 (define_insn "*umulqihipsi3"
2875 [(set (match_operand:PSI 0 "register_operand" "=&r")
2876 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2877 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2886 [(set_attr "length" "7")
2887 (set_attr "cc" "clobber")])
2889 (define_insn "*umulhiqipsi3"
2890 [(set (match_operand:PSI 0 "register_operand" "=&r")
2891 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2892 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2900 adc %C0,__zero_reg__"
2901 [(set_attr "length" "7")
2902 (set_attr "cc" "clobber")])
2904 (define_expand "mulsqipsi3"
2905 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2906 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" ""))
2907 (match_operand:PSI 2 "pseudo_register_or_const_int_operand""")))
2908 (clobber (reg:HI 26))
2909 (clobber (reg:DI 18))])]
2912 avr_fix_inputs (operands, (1 << 1) | (1 << 2), -1u);
2913 if (avr_emit3_fix_outputs (gen_mulsqipsi3, operands, 1 << 0,
2914 regmask (DImode, 18) | regmask (HImode, 26)))
2918 (define_insn_and_split "*mulsqipsi3"
2919 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2920 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2921 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2922 (clobber (reg:HI 26))
2923 (clobber (reg:DI 18))]
2924 "AVR_HAVE_MUL && !reload_completed"
2925 { gcc_unreachable(); }
2932 (mult:PSI (sign_extend:PSI (reg:QI 25))
2937 (define_insn_and_split "*mulpsi3"
2938 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2939 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2940 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2941 (clobber (reg:HI 26))
2942 (clobber (reg:DI 18))]
2943 "AVR_HAVE_MUL && !reload_completed"
2944 { gcc_unreachable(); }
2950 (parallel [(set (reg:PSI 22)
2951 (mult:PSI (reg:PSI 22)
2953 (clobber (reg:QI 21))
2954 (clobber (reg:QI 25))
2955 (clobber (reg:HI 26))])
2959 if (s8_operand (operands[2], PSImode))
2961 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2962 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2967 (define_insn "*mulsqipsi3.libgcc"
2969 (mult:PSI (sign_extend:PSI (reg:QI 25))
2972 "%~call __mulsqipsi3"
2973 [(set_attr "type" "xcall")
2974 (set_attr "cc" "clobber")])
2976 (define_insn "*mulpsi3.libgcc"
2978 (mult:PSI (reg:PSI 22)
2980 (clobber (reg:QI 21))
2981 (clobber (reg:QI 25))
2982 (clobber (reg:HI 26))]
2985 [(set_attr "type" "xcall")
2986 (set_attr "cc" "clobber")])
2989 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2990 ;; 24-bit signed/unsigned division and modulo.
2991 ;; Notice that the libgcc implementation return the quotient in R22
2992 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2993 ;; implementation works the other way round.
2995 (define_insn_and_split "divmodpsi4"
2996 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2997 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2998 (match_operand:PSI 2 "pseudo_register_operand" "")))
2999 (set (match_operand:PSI 3 "pseudo_register_operand" "")
3000 (mod:PSI (match_dup 1)
3002 (clobber (reg:DI 18))
3003 (clobber (reg:QI 26))])]
3005 { gcc_unreachable(); }
3007 [(set (reg:PSI 22) (match_dup 1))
3008 (set (reg:PSI 18) (match_dup 2))
3009 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
3010 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
3011 (clobber (reg:QI 21))
3012 (clobber (reg:QI 25))
3013 (clobber (reg:QI 26))])
3014 (set (match_dup 0) (reg:PSI 22))
3015 (set (match_dup 3) (reg:PSI 18))])
3017 (define_insn "*divmodpsi4_call"
3018 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
3019 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
3020 (clobber (reg:QI 21))
3021 (clobber (reg:QI 25))
3022 (clobber (reg:QI 26))]
3024 "%~call __divmodpsi4"
3025 [(set_attr "type" "xcall")
3026 (set_attr "cc" "clobber")])
3028 (define_insn_and_split "udivmodpsi4"
3029 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
3030 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
3031 (match_operand:PSI 2 "pseudo_register_operand" "")))
3032 (set (match_operand:PSI 3 "pseudo_register_operand" "")
3033 (umod:PSI (match_dup 1)
3035 (clobber (reg:DI 18))
3036 (clobber (reg:QI 26))])]
3038 { gcc_unreachable(); }
3040 [(set (reg:PSI 22) (match_dup 1))
3041 (set (reg:PSI 18) (match_dup 2))
3042 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
3043 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
3044 (clobber (reg:QI 21))
3045 (clobber (reg:QI 25))
3046 (clobber (reg:QI 26))])
3047 (set (match_dup 0) (reg:PSI 22))
3048 (set (match_dup 3) (reg:PSI 18))])
3050 (define_insn "*udivmodpsi4_call"
3051 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
3052 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
3053 (clobber (reg:QI 21))
3054 (clobber (reg:QI 25))
3055 (clobber (reg:QI 26))]
3057 "%~call __udivmodpsi4"
3058 [(set_attr "type" "xcall")
3059 (set_attr "cc" "clobber")])
3061 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3063 (define_insn_and_split "divmodsi4"
3064 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3065 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
3066 (match_operand:SI 2 "pseudo_register_operand" "")))
3067 (set (match_operand:SI 3 "pseudo_register_operand" "")
3068 (mod:SI (match_dup 1) (match_dup 2)))
3069 (clobber (reg:SI 18))
3070 (clobber (reg:SI 22))
3071 (clobber (reg:HI 26))
3072 (clobber (reg:HI 30))])]
3074 "this divmodsi4 pattern should have been splitted;"
3076 [(set (reg:SI 22) (match_dup 1))
3077 (set (reg:SI 18) (match_dup 2))
3078 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
3079 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
3080 (clobber (reg:HI 26))
3081 (clobber (reg:HI 30))])
3082 (set (match_dup 0) (reg:SI 18))
3083 (set (match_dup 3) (reg:SI 22))])
3085 (define_insn "*divmodsi4_call"
3086 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
3087 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
3088 (clobber (reg:HI 26))
3089 (clobber (reg:HI 30))]
3091 "%~call __divmodsi4"
3092 [(set_attr "type" "xcall")
3093 (set_attr "cc" "clobber")])
3095 (define_insn_and_split "udivmodsi4"
3096 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
3097 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
3098 (match_operand:SI 2 "pseudo_register_operand" "")))
3099 (set (match_operand:SI 3 "pseudo_register_operand" "")
3100 (umod:SI (match_dup 1) (match_dup 2)))
3101 (clobber (reg:SI 18))
3102 (clobber (reg:SI 22))
3103 (clobber (reg:HI 26))
3104 (clobber (reg:HI 30))])]
3106 "this udivmodsi4 pattern should have been splitted;"
3108 [(set (reg:SI 22) (match_dup 1))
3109 (set (reg:SI 18) (match_dup 2))
3110 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
3111 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
3112 (clobber (reg:HI 26))
3113 (clobber (reg:HI 30))])
3114 (set (match_dup 0) (reg:SI 18))
3115 (set (match_dup 3) (reg:SI 22))])
3117 (define_insn "*udivmodsi4_call"
3118 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
3119 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
3120 (clobber (reg:HI 26))
3121 (clobber (reg:HI 30))]
3123 "%~call __udivmodsi4"
3124 [(set_attr "type" "xcall")
3125 (set_attr "cc" "clobber")])
3127 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
3130 (define_insn "andqi3"
3131 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
3132 (and:QI (match_operand:QI 1 "register_operand" "%0,0,0")
3133 (match_operand:QI 2 "nonmemory_operand" "r,i,Ca1")))]
3138 * return avr_out_bitop (insn, operands, NULL);"
3139 [(set_attr "length" "1,1,2")
3140 (set_attr "cc" "set_zn,set_zn,none")])
3142 (define_insn "andhi3"
3143 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3144 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3145 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
3146 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3149 if (which_alternative == 0)
3150 return "and %A0,%A2\;and %B0,%B2";
3151 else if (which_alternative == 1)
3152 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
3154 return avr_out_bitop (insn, operands, NULL);
3156 [(set_attr "length" "2,2,2,4,4")
3157 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3158 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3160 (define_insn "andpsi3"
3161 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3162 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3163 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
3164 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3167 if (which_alternative == 0)
3168 return "and %A0,%A2" CR_TAB
3169 "and %B0,%B2" CR_TAB
3172 return avr_out_bitop (insn, operands, NULL);
3174 [(set_attr "length" "3,3,6,6")
3175 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3176 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3178 (define_insn "andsi3"
3179 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3180 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3181 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
3182 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3185 if (which_alternative == 0)
3186 return "and %0,%2" CR_TAB
3187 "and %B0,%B2" CR_TAB
3188 "and %C0,%C2" CR_TAB
3191 return avr_out_bitop (insn, operands, NULL);
3193 [(set_attr "length" "4,4,8,8")
3194 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3195 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3197 (define_peephole2 ; andi
3198 [(set (match_operand:QI 0 "d_register_operand" "")
3199 (and:QI (match_dup 0)
3200 (match_operand:QI 1 "const_int_operand" "")))
3202 (and:QI (match_dup 0)
3203 (match_operand:QI 2 "const_int_operand" "")))]
3205 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3207 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3210 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3213 (define_insn "iorqi3"
3214 [(set (match_operand:QI 0 "register_operand" "=??r,d,*l")
3215 (ior:QI (match_operand:QI 1 "register_operand" "%0,0,0")
3216 (match_operand:QI 2 "nonmemory_operand" "r,i,Co1")))]
3221 * return avr_out_bitop (insn, operands, NULL);"
3222 [(set_attr "length" "1,1,2")
3223 (set_attr "cc" "set_zn,set_zn,none")])
3225 (define_insn "iorhi3"
3226 [(set (match_operand:HI 0 "register_operand" "=??r,d,d,r ,r")
3227 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3228 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3229 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3232 if (which_alternative == 0)
3233 return "or %A0,%A2\;or %B0,%B2";
3234 else if (which_alternative == 1)
3235 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3237 return avr_out_bitop (insn, operands, NULL);
3239 [(set_attr "length" "2,2,2,4,4")
3240 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3241 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3243 (define_insn "iorpsi3"
3244 [(set (match_operand:PSI 0 "register_operand" "=??r,d,r ,r")
3245 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3246 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3247 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3250 if (which_alternative == 0)
3251 return "or %A0,%A2" CR_TAB
3255 return avr_out_bitop (insn, operands, NULL);
3257 [(set_attr "length" "3,3,6,6")
3258 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3259 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3261 (define_insn "iorsi3"
3262 [(set (match_operand:SI 0 "register_operand" "=??r,d,r ,r")
3263 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3264 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3265 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3268 if (which_alternative == 0)
3269 return "or %0,%2" CR_TAB
3274 return avr_out_bitop (insn, operands, NULL);
3276 [(set_attr "length" "4,4,8,8")
3277 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3278 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3280 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3283 (define_insn "xorqi3"
3284 [(set (match_operand:QI 0 "register_operand" "=r")
3285 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3286 (match_operand:QI 2 "register_operand" "r")))]
3289 [(set_attr "length" "1")
3290 (set_attr "cc" "set_zn")])
3292 (define_insn "xorhi3"
3293 [(set (match_operand:HI 0 "register_operand" "=??r,r ,r")
3294 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3295 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3296 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3299 if (which_alternative == 0)
3300 return "eor %A0,%A2\;eor %B0,%B2";
3302 return avr_out_bitop (insn, operands, NULL);
3304 [(set_attr "length" "2,2,4")
3305 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3306 (set_attr "cc" "set_n,clobber,clobber")])
3308 (define_insn "xorpsi3"
3309 [(set (match_operand:PSI 0 "register_operand" "=??r,r ,r")
3310 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3311 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3312 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3315 if (which_alternative == 0)
3316 return "eor %A0,%A2" CR_TAB
3317 "eor %B0,%B2" CR_TAB
3320 return avr_out_bitop (insn, operands, NULL);
3322 [(set_attr "length" "3,6,6")
3323 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3324 (set_attr "cc" "set_n,clobber,clobber")])
3326 (define_insn "xorsi3"
3327 [(set (match_operand:SI 0 "register_operand" "=??r,r ,r")
3328 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3329 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3330 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3333 if (which_alternative == 0)
3334 return "eor %0,%2" CR_TAB
3335 "eor %B0,%B2" CR_TAB
3336 "eor %C0,%C2" CR_TAB
3339 return avr_out_bitop (insn, operands, NULL);
3341 [(set_attr "length" "4,8,8")
3342 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3343 (set_attr "cc" "set_n,clobber,clobber")])
3347 [(set (match_operand:SPLIT34 0 "register_operand")
3348 (match_operand:SPLIT34 1 "register_operand"))]
3350 && reload_completed"
3351 [(set (match_dup 2) (match_dup 3))
3352 (set (match_dup 4) (match_dup 5))]
3354 machine_mode mode_hi = 4 == GET_MODE_SIZE (<MODE>mode) ? HImode : QImode;
3355 bool lo_first = REGNO (operands[0]) < REGNO (operands[1]);
3356 rtx dst_lo = simplify_gen_subreg (HImode, operands[0], <MODE>mode, 0);
3357 rtx src_lo = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 0);
3358 rtx dst_hi = simplify_gen_subreg (mode_hi, operands[0], <MODE>mode, 2);
3359 rtx src_hi = simplify_gen_subreg (mode_hi, operands[1], <MODE>mode, 2);
3361 operands[2] = lo_first ? dst_lo : dst_hi;
3362 operands[3] = lo_first ? src_lo : src_hi;
3363 operands[4] = lo_first ? dst_hi : dst_lo;
3364 operands[5] = lo_first ? src_hi : src_lo;
3368 [(set (match_operand:HI 0 "register_operand")
3369 (match_operand:HI 1 "reg_or_0_operand"))]
3373 || const0_rtx == operands[1])"
3374 [(set (match_dup 2) (match_dup 3))
3375 (set (match_dup 4) (match_dup 5))]
3377 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3378 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 1);
3379 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3380 operands[5] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3383 ;; Split andhi3, andpsi3, andsi3.
3384 ;; Split iorhi3, iorpsi3, iorsi3.
3385 ;; Split xorhi3, xorpsi3, xorsi3.
3387 [(parallel [(set (match_operand:HISI 0 "register_operand")
3388 (bitop:HISI (match_dup 0)
3389 (match_operand:HISI 1 "register_operand")))
3390 (clobber (scratch:QI))])]
3392 && reload_completed"
3395 for (int i = 0; i < GET_MODE_SIZE (<MODE>mode); i++)
3397 rtx dst = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
3398 rtx src = simplify_gen_subreg (QImode, operands[1], <MODE>mode, i);
3399 emit_insn (gen_<code>qi3 (dst, dst, src));
3405 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3408 (define_expand "rotlqi3"
3409 [(set (match_operand:QI 0 "register_operand" "")
3410 (rotate:QI (match_operand:QI 1 "register_operand" "")
3411 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3414 if (!CONST_INT_P (operands[2]))
3417 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3420 ;; Expander used by __builtin_avr_swap
3421 (define_expand "rotlqi3_4"
3422 [(set (match_operand:QI 0 "register_operand" "")
3423 (rotate:QI (match_operand:QI 1 "register_operand" "")
3426 (define_insn "*rotlqi3"
3427 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3428 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3429 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3432 lsl %0\;adc %0,__zero_reg__
3433 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3434 swap %0\;bst %0,0\;ror %0\;bld %0,7
3436 swap %0\;lsl %0\;adc %0,__zero_reg__
3437 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3438 bst %0,0\;ror %0\;bld %0,7
3440 [(set_attr "length" "2,4,4,1,3,5,3,0")
3441 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3443 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3444 ;; a whole number of bytes. The split creates the appropriate moves and
3445 ;; considers all overlap situations.
3447 ;; HImode does not need scratch. Use attribute for this constraint.
3449 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3450 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3455 (define_expand "rotl<mode>3"
3456 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3457 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3458 (match_operand:HISI 2 "const_int_operand" "")))
3459 (clobber (match_dup 3))])]
3464 if (!CONST_INT_P (operands[2]))
3467 offset = INTVAL (operands[2]);
3469 if (0 == offset % 8)
3471 if (AVR_HAVE_MOVW && 0 == offset % 16)
3472 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3474 operands[3] = gen_rtx_SCRATCH (QImode);
3476 else if (offset == 1
3477 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3479 /*; Support rotate left/right by 1 */
3481 emit_move_insn (operands[0],
3482 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3489 (define_insn "*rotlhi2.1"
3490 [(set (match_operand:HI 0 "register_operand" "=r")
3491 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3494 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3495 [(set_attr "length" "3")
3496 (set_attr "cc" "clobber")])
3498 (define_insn "*rotlhi2.15"
3499 [(set (match_operand:HI 0 "register_operand" "=r")
3500 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3503 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3504 [(set_attr "length" "4")
3505 (set_attr "cc" "clobber")])
3507 (define_insn "*rotlpsi2.1"
3508 [(set (match_operand:PSI 0 "register_operand" "=r")
3509 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3512 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3513 [(set_attr "length" "4")
3514 (set_attr "cc" "clobber")])
3516 (define_insn "*rotlpsi2.23"
3517 [(set (match_operand:PSI 0 "register_operand" "=r")
3518 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3521 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3522 [(set_attr "length" "5")
3523 (set_attr "cc" "clobber")])
3525 (define_insn "*rotlsi2.1"
3526 [(set (match_operand:SI 0 "register_operand" "=r")
3527 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3530 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3531 [(set_attr "length" "5")
3532 (set_attr "cc" "clobber")])
3534 (define_insn "*rotlsi2.31"
3535 [(set (match_operand:SI 0 "register_operand" "=r")
3536 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3539 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3540 [(set_attr "length" "6")
3541 (set_attr "cc" "clobber")])
3543 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3544 ;; The best we can do is use early clobber alternative "#&r" so that
3545 ;; completely non-overlapping operands dont get a scratch but # so register
3546 ;; allocation does not prefer non-overlapping.
3549 ;; Split word aligned rotates using scratch that is mode dependent.
3553 (define_insn_and_split "*rotw<mode>"
3554 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3555 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3556 (match_operand 2 "const_int_operand" "n,n,n")))
3557 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3559 && CONST_INT_P (operands[2])
3560 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3561 && 0 == INTVAL (operands[2]) % 16"
3563 "&& reload_completed"
3566 avr_rotate_bytes (operands);
3571 ;; Split byte aligned rotates using scratch that is always QI mode.
3576 (define_insn_and_split "*rotb<mode>"
3577 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3578 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3579 (match_operand 2 "const_int_operand" "n,n,n")))
3580 (clobber (match_scratch:QI 3 "=<rotx>"))]
3581 "CONST_INT_P (operands[2])
3582 && (8 == INTVAL (operands[2]) % 16
3584 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3585 && 0 == INTVAL (operands[2]) % 16))"
3587 "&& reload_completed"
3590 avr_rotate_bytes (operands);
3595 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3596 ;; arithmetic shift left
3599 ;; "ashlqq3" "ashluqq3"
3600 (define_expand "ashl<mode>3"
3601 [(set (match_operand:ALL1 0 "register_operand" "")
3602 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3603 (match_operand:QI 2 "nop_general_operand" "")))])
3605 (define_split ; ashlqi3_const4
3606 [(set (match_operand:ALL1 0 "d_register_operand" "")
3607 (ashift:ALL1 (match_dup 0)
3611 (rotate:QI (match_dup 1)
3614 (and:QI (match_dup 1)
3617 operands[1] = avr_to_int_mode (operands[0]);
3620 (define_split ; ashlqi3_const5
3621 [(set (match_operand:ALL1 0 "d_register_operand" "")
3622 (ashift:ALL1 (match_dup 0)
3625 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3626 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3627 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3629 operands[1] = avr_to_int_mode (operands[0]);
3632 (define_split ; ashlqi3_const6
3633 [(set (match_operand:ALL1 0 "d_register_operand" "")
3634 (ashift:ALL1 (match_dup 0)
3637 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3638 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3639 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3641 operands[1] = avr_to_int_mode (operands[0]);
3645 ;; "*ashlqq3" "*ashluqq3"
3646 (define_insn "*ashl<mode>3"
3647 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3648 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3649 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3652 return ashlqi3_out (insn, operands, NULL);
3654 [(set_attr "length" "5,0,1,2,4,6,9")
3655 (set_attr "adjust_len" "ashlqi")
3656 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3658 (define_insn "ashl<mode>3"
3659 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3660 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3661 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3664 return ashlhi3_out (insn, operands, NULL);
3666 [(set_attr "length" "6,0,2,2,4,10,10")
3667 (set_attr "adjust_len" "ashlhi")
3668 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3671 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3672 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3676 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3677 [(set (match_operand:QI 0 "register_operand" "=r")
3678 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3679 (match_operand:QI 2 "register_operand" "r"))
3685 (ashift:QI (match_dup 1)
3688 ;; ??? Combiner does not recognize that it could split the following insn;
3689 ;; presumably because he has no register handy?
3691 ;; "*ashluqihiqi3.mem"
3692 ;; "*ashlsqihiqi3.mem"
3693 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3694 [(set (match_operand:QI 0 "memory_operand" "=m")
3695 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3696 (match_operand:QI 2 "register_operand" "r"))
3699 { gcc_unreachable(); }
3702 (ashift:QI (match_dup 1)
3707 operands[3] = gen_reg_rtx (QImode);
3712 (define_insn_and_split "*ashlhiqi3"
3713 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3714 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3715 (match_operand:QI 2 "register_operand" "r")) 0))]
3717 { gcc_unreachable(); }
3720 (ashift:QI (match_dup 3)
3725 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3726 operands[4] = gen_reg_rtx (QImode);
3729 ;; High part of 16-bit shift is unused after the instruction:
3730 ;; No need to compute it, map to 8-bit shift.
3733 [(set (match_operand:HI 0 "register_operand" "")
3734 (ashift:HI (match_dup 0)
3735 (match_operand:QI 1 "register_operand" "")))]
3738 (ashift:QI (match_dup 2)
3740 (clobber (match_dup 3))]
3742 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3744 if (!peep2_reg_dead_p (1, operands[3]))
3747 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3752 ;; "ashlsq3" "ashlusq3"
3753 ;; "ashlsa3" "ashlusa3"
3754 (define_insn "ashl<mode>3"
3755 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3756 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3757 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3760 return ashlsi3_out (insn, operands, NULL);
3762 [(set_attr "length" "8,0,4,4,8,10,12")
3763 (set_attr "adjust_len" "ashlsi")
3764 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3766 ;; Optimize if a scratch register from LD_REGS happens to be available.
3768 (define_peephole2 ; ashlqi3_l_const4
3769 [(set (match_operand:ALL1 0 "l_register_operand" "")
3770 (ashift:ALL1 (match_dup 0)
3772 (match_scratch:QI 1 "d")]
3774 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3775 (set (match_dup 1) (const_int -16))
3776 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3778 operands[2] = avr_to_int_mode (operands[0]);
3781 (define_peephole2 ; ashlqi3_l_const5
3782 [(set (match_operand:ALL1 0 "l_register_operand" "")
3783 (ashift:ALL1 (match_dup 0)
3785 (match_scratch:QI 1 "d")]
3787 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3788 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3789 (set (match_dup 1) (const_int -32))
3790 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3792 operands[2] = avr_to_int_mode (operands[0]);
3795 (define_peephole2 ; ashlqi3_l_const6
3796 [(set (match_operand:ALL1 0 "l_register_operand" "")
3797 (ashift:ALL1 (match_dup 0)
3799 (match_scratch:QI 1 "d")]
3801 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3802 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3803 (set (match_dup 1) (const_int -64))
3804 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3806 operands[2] = avr_to_int_mode (operands[0]);
3810 [(match_scratch:QI 3 "d")
3811 (set (match_operand:ALL2 0 "register_operand" "")
3812 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3813 (match_operand:QI 2 "const_int_operand" "")))]
3815 [(parallel [(set (match_dup 0)
3816 (ashift:ALL2 (match_dup 1)
3818 (clobber (match_dup 3))])])
3821 ;; "*ashlhq3_const" "*ashluhq3_const"
3822 ;; "*ashlha3_const" "*ashluha3_const"
3823 (define_insn "*ashl<mode>3_const"
3824 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3825 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3826 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3827 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3830 return ashlhi3_out (insn, operands, NULL);
3832 [(set_attr "length" "0,2,2,4,10")
3833 (set_attr "adjust_len" "ashlhi")
3834 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3837 [(match_scratch:QI 3 "d")
3838 (set (match_operand:ALL4 0 "register_operand" "")
3839 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3840 (match_operand:QI 2 "const_int_operand" "")))]
3842 [(parallel [(set (match_dup 0)
3843 (ashift:ALL4 (match_dup 1)
3845 (clobber (match_dup 3))])])
3848 ;; "*ashlsq3_const" "*ashlusq3_const"
3849 ;; "*ashlsa3_const" "*ashlusa3_const"
3850 (define_insn "*ashl<mode>3_const"
3851 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3852 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3853 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3854 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3857 return ashlsi3_out (insn, operands, NULL);
3859 [(set_attr "length" "0,4,4,10")
3860 (set_attr "adjust_len" "ashlsi")
3861 (set_attr "cc" "none,set_n,clobber,clobber")])
3863 (define_expand "ashlpsi3"
3864 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3865 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3866 (match_operand:QI 2 "nonmemory_operand" "")))
3867 (clobber (scratch:QI))])]
3871 && CONST_INT_P (operands[2]))
3873 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3875 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3876 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3879 else if (optimize_insn_for_speed_p ()
3880 && INTVAL (operands[2]) != 16
3881 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3883 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3884 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3890 (define_insn "*ashlpsi3"
3891 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3892 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3893 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3894 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3897 return avr_out_ashlpsi3 (insn, operands, NULL);
3899 [(set_attr "adjust_len" "ashlpsi")
3900 (set_attr "cc" "clobber")])
3902 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3903 ;; arithmetic shift right
3906 ;; "ashrqq3" "ashruqq3"
3907 (define_insn "ashr<mode>3"
3908 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3909 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3910 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3913 return ashrqi3_out (insn, operands, NULL);
3915 [(set_attr "length" "5,0,1,2,5,4,9")
3916 (set_attr "adjust_len" "ashrqi")
3917 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3920 ;; "ashrhq3" "ashruhq3"
3921 ;; "ashrha3" "ashruha3"
3922 (define_insn "ashr<mode>3"
3923 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3924 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3925 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3928 return ashrhi3_out (insn, operands, NULL);
3930 [(set_attr "length" "6,0,2,4,4,10,10")
3931 (set_attr "adjust_len" "ashrhi")
3932 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3934 (define_insn "ashrpsi3"
3935 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3936 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3937 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3938 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3941 return avr_out_ashrpsi3 (insn, operands, NULL);
3943 [(set_attr "adjust_len" "ashrpsi")
3944 (set_attr "cc" "clobber")])
3947 ;; "ashrsq3" "ashrusq3"
3948 ;; "ashrsa3" "ashrusa3"
3949 (define_insn "ashr<mode>3"
3950 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3951 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3952 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3955 return ashrsi3_out (insn, operands, NULL);
3957 [(set_attr "length" "8,0,4,6,8,10,12")
3958 (set_attr "adjust_len" "ashrsi")
3959 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3961 ;; Optimize if a scratch register from LD_REGS happens to be available.
3964 [(match_scratch:QI 3 "d")
3965 (set (match_operand:ALL2 0 "register_operand" "")
3966 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3967 (match_operand:QI 2 "const_int_operand" "")))]
3969 [(parallel [(set (match_dup 0)
3970 (ashiftrt:ALL2 (match_dup 1)
3972 (clobber (match_dup 3))])])
3975 ;; "*ashrhq3_const" "*ashruhq3_const"
3976 ;; "*ashrha3_const" "*ashruha3_const"
3977 (define_insn "*ashr<mode>3_const"
3978 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3979 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3980 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3981 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3984 return ashrhi3_out (insn, operands, NULL);
3986 [(set_attr "length" "0,2,4,4,10")
3987 (set_attr "adjust_len" "ashrhi")
3988 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3991 [(match_scratch:QI 3 "d")
3992 (set (match_operand:ALL4 0 "register_operand" "")
3993 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3994 (match_operand:QI 2 "const_int_operand" "")))]
3996 [(parallel [(set (match_dup 0)
3997 (ashiftrt:ALL4 (match_dup 1)
3999 (clobber (match_dup 3))])])
4002 ;; "*ashrsq3_const" "*ashrusq3_const"
4003 ;; "*ashrsa3_const" "*ashrusa3_const"
4004 (define_insn "*ashr<mode>3_const"
4005 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4006 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4007 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4008 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4011 return ashrsi3_out (insn, operands, NULL);
4013 [(set_attr "length" "0,4,4,10")
4014 (set_attr "adjust_len" "ashrsi")
4015 (set_attr "cc" "none,clobber,set_n,clobber")])
4017 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
4018 ;; logical shift right
4021 ;; "lshrqq3" "lshruqq3"
4022 (define_expand "lshr<mode>3"
4023 [(set (match_operand:ALL1 0 "register_operand" "")
4024 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
4025 (match_operand:QI 2 "nop_general_operand" "")))])
4027 (define_split ; lshrqi3_const4
4028 [(set (match_operand:ALL1 0 "d_register_operand" "")
4029 (lshiftrt:ALL1 (match_dup 0)
4033 (rotate:QI (match_dup 1)
4036 (and:QI (match_dup 1)
4039 operands[1] = avr_to_int_mode (operands[0]);
4042 (define_split ; lshrqi3_const5
4043 [(set (match_operand:ALL1 0 "d_register_operand" "")
4044 (lshiftrt:ALL1 (match_dup 0)
4047 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4048 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
4049 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
4051 operands[1] = avr_to_int_mode (operands[0]);
4054 (define_split ; lshrqi3_const6
4055 [(set (match_operand:QI 0 "d_register_operand" "")
4056 (lshiftrt:QI (match_dup 0)
4059 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
4060 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
4061 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
4063 operands[1] = avr_to_int_mode (operands[0]);
4069 (define_insn "*lshr<mode>3"
4070 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
4071 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
4072 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
4075 return lshrqi3_out (insn, operands, NULL);
4077 [(set_attr "length" "5,0,1,2,4,6,9")
4078 (set_attr "adjust_len" "lshrqi")
4079 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
4082 ;; "lshrhq3" "lshruhq3"
4083 ;; "lshrha3" "lshruha3"
4084 (define_insn "lshr<mode>3"
4085 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
4086 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
4087 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4090 return lshrhi3_out (insn, operands, NULL);
4092 [(set_attr "length" "6,0,2,2,4,10,10")
4093 (set_attr "adjust_len" "lshrhi")
4094 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4096 (define_insn "lshrpsi3"
4097 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
4098 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
4099 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
4100 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4103 return avr_out_lshrpsi3 (insn, operands, NULL);
4105 [(set_attr "adjust_len" "lshrpsi")
4106 (set_attr "cc" "clobber")])
4109 ;; "lshrsq3" "lshrusq3"
4110 ;; "lshrsa3" "lshrusa3"
4111 (define_insn "lshr<mode>3"
4112 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
4113 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
4114 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
4117 return lshrsi3_out (insn, operands, NULL);
4119 [(set_attr "length" "8,0,4,4,8,10,12")
4120 (set_attr "adjust_len" "lshrsi")
4121 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
4123 ;; Optimize if a scratch register from LD_REGS happens to be available.
4125 (define_peephole2 ; lshrqi3_l_const4
4126 [(set (match_operand:ALL1 0 "l_register_operand" "")
4127 (lshiftrt:ALL1 (match_dup 0)
4129 (match_scratch:QI 1 "d")]
4131 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4132 (set (match_dup 1) (const_int 15))
4133 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4135 operands[2] = avr_to_int_mode (operands[0]);
4138 (define_peephole2 ; lshrqi3_l_const5
4139 [(set (match_operand:ALL1 0 "l_register_operand" "")
4140 (lshiftrt:ALL1 (match_dup 0)
4142 (match_scratch:QI 1 "d")]
4144 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4145 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
4146 (set (match_dup 1) (const_int 7))
4147 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4149 operands[2] = avr_to_int_mode (operands[0]);
4152 (define_peephole2 ; lshrqi3_l_const6
4153 [(set (match_operand:ALL1 0 "l_register_operand" "")
4154 (lshiftrt:ALL1 (match_dup 0)
4156 (match_scratch:QI 1 "d")]
4158 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
4159 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
4160 (set (match_dup 1) (const_int 3))
4161 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
4163 operands[2] = avr_to_int_mode (operands[0]);
4167 [(match_scratch:QI 3 "d")
4168 (set (match_operand:ALL2 0 "register_operand" "")
4169 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
4170 (match_operand:QI 2 "const_int_operand" "")))]
4172 [(parallel [(set (match_dup 0)
4173 (lshiftrt:ALL2 (match_dup 1)
4175 (clobber (match_dup 3))])])
4178 ;; "*lshrhq3_const" "*lshruhq3_const"
4179 ;; "*lshrha3_const" "*lshruha3_const"
4180 (define_insn "*lshr<mode>3_const"
4181 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
4182 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
4183 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
4184 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
4187 return lshrhi3_out (insn, operands, NULL);
4189 [(set_attr "length" "0,2,2,4,10")
4190 (set_attr "adjust_len" "lshrhi")
4191 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
4194 [(match_scratch:QI 3 "d")
4195 (set (match_operand:ALL4 0 "register_operand" "")
4196 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
4197 (match_operand:QI 2 "const_int_operand" "")))]
4199 [(parallel [(set (match_dup 0)
4200 (lshiftrt:ALL4 (match_dup 1)
4202 (clobber (match_dup 3))])])
4205 ;; "*lshrsq3_const" "*lshrusq3_const"
4206 ;; "*lshrsa3_const" "*lshrusa3_const"
4207 (define_insn "*lshr<mode>3_const"
4208 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
4209 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
4210 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
4211 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4214 return lshrsi3_out (insn, operands, NULL);
4216 [(set_attr "length" "0,4,4,10")
4217 (set_attr "adjust_len" "lshrsi")
4218 (set_attr "cc" "none,clobber,clobber,clobber")])
4220 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
4223 (define_insn "absqi2"
4224 [(set (match_operand:QI 0 "register_operand" "=r")
4225 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
4229 [(set_attr "length" "2")
4230 (set_attr "cc" "clobber")])
4233 (define_insn "abssf2"
4234 [(set (match_operand:SF 0 "register_operand" "=d,r")
4235 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4240 [(set_attr "length" "1,2")
4241 (set_attr "cc" "set_n,clobber")])
4243 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
4246 (define_insn "negqi2"
4247 [(set (match_operand:QI 0 "register_operand" "=r")
4248 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4251 [(set_attr "length" "1")
4252 (set_attr "cc" "set_vzn")])
4254 (define_insn "*negqihi2"
4255 [(set (match_operand:HI 0 "register_operand" "=r")
4256 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4258 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4259 [(set_attr "length" "4")
4260 (set_attr "cc" "set_n")])
4262 (define_insn "neghi2"
4263 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4264 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4267 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4268 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4269 [(set_attr "length" "3,4")
4270 (set_attr "cc" "set_czn")])
4272 (define_insn "negpsi2"
4273 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4274 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4277 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4278 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4279 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4280 [(set_attr "length" "5,6,6")
4281 (set_attr "cc" "set_czn,set_n,set_czn")])
4283 (define_insn "negsi2"
4284 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4285 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4288 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4289 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4290 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4291 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4292 [(set_attr "length" "7,8,8,7")
4293 (set_attr "isa" "*,*,mov,movw")
4294 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4296 (define_insn "negsf2"
4297 [(set (match_operand:SF 0 "register_operand" "=d,r")
4298 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4302 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4303 [(set_attr "length" "1,4")
4304 (set_attr "cc" "set_n,set_n")])
4306 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4309 (define_insn "one_cmplqi2"
4310 [(set (match_operand:QI 0 "register_operand" "=r")
4311 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4314 [(set_attr "length" "1")
4315 (set_attr "cc" "set_czn")])
4317 (define_insn "one_cmplhi2"
4318 [(set (match_operand:HI 0 "register_operand" "=r")
4319 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4323 [(set_attr "length" "2")
4324 (set_attr "cc" "set_n")])
4326 (define_insn "one_cmplpsi2"
4327 [(set (match_operand:PSI 0 "register_operand" "=r")
4328 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4330 "com %0\;com %B0\;com %C0"
4331 [(set_attr "length" "3")
4332 (set_attr "cc" "set_n")])
4334 (define_insn "one_cmplsi2"
4335 [(set (match_operand:SI 0 "register_operand" "=r")
4336 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4342 [(set_attr "length" "4")
4343 (set_attr "cc" "set_n")])
4345 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4348 ;; We keep combiner from inserting hard registers into the input of sign- and
4349 ;; zero-extends. A hard register in the input operand is not wanted because
4350 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4351 ;; hard register that overlaps these clobbers won't be combined to a widening
4352 ;; multiplication. There is no need for combine to propagate hard registers,
4353 ;; register allocation can do it just as well.
4355 (define_insn "extendqihi2"
4356 [(set (match_operand:HI 0 "register_operand" "=r,r")
4357 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4360 return avr_out_sign_extend (insn, operands, NULL);
4362 [(set_attr "length" "3,4")
4363 (set_attr "adjust_len" "sext")
4364 (set_attr "cc" "set_n")])
4366 (define_insn "extendqipsi2"
4367 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4368 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4371 return avr_out_sign_extend (insn, operands, NULL);
4373 [(set_attr "length" "4,5")
4374 (set_attr "adjust_len" "sext")
4375 (set_attr "cc" "set_n")])
4377 (define_insn "extendqisi2"
4378 [(set (match_operand:SI 0 "register_operand" "=r,r")
4379 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4382 return avr_out_sign_extend (insn, operands, NULL);
4384 [(set_attr "length" "5,6")
4385 (set_attr "adjust_len" "sext")
4386 (set_attr "cc" "set_n")])
4388 (define_insn "extendhipsi2"
4389 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4390 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4393 return avr_out_sign_extend (insn, operands, NULL);
4395 [(set_attr "length" "3,5")
4396 (set_attr "adjust_len" "sext")
4397 (set_attr "cc" "set_n")])
4399 (define_insn "extendhisi2"
4400 [(set (match_operand:SI 0 "register_operand" "=r,r")
4401 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
4404 return avr_out_sign_extend (insn, operands, NULL);
4406 [(set_attr "length" "4,6")
4407 (set_attr "adjust_len" "sext")
4408 (set_attr "cc" "set_n")])
4410 (define_insn "extendpsisi2"
4411 [(set (match_operand:SI 0 "register_operand" "=r")
4412 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4415 return avr_out_sign_extend (insn, operands, NULL);
4417 [(set_attr "length" "3")
4418 (set_attr "adjust_len" "sext")
4419 (set_attr "cc" "set_n")])
4421 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4424 (define_insn_and_split "zero_extendqihi2"
4425 [(set (match_operand:HI 0 "register_operand" "=r")
4426 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4430 [(set (match_dup 2) (match_dup 1))
4431 (set (match_dup 3) (const_int 0))]
4433 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4434 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4436 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4437 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4440 (define_insn_and_split "zero_extendqipsi2"
4441 [(set (match_operand:PSI 0 "register_operand" "=r")
4442 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4446 [(set (match_dup 2) (match_dup 1))
4447 (set (match_dup 3) (const_int 0))
4448 (set (match_dup 4) (const_int 0))]
4450 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4451 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4452 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4455 (define_insn_and_split "zero_extendqisi2"
4456 [(set (match_operand:SI 0 "register_operand" "=r")
4457 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4461 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4462 (set (match_dup 3) (const_int 0))]
4464 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4465 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4467 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4468 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4471 (define_insn_and_split "zero_extendhipsi2"
4472 [(set (match_operand:PSI 0 "register_operand" "=r")
4473 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4477 [(set (match_dup 2) (match_dup 1))
4478 (set (match_dup 3) (const_int 0))]
4480 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4481 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4484 (define_insn_and_split "n_extendhipsi2"
4485 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4486 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4487 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4488 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4492 [(set (match_dup 4) (match_dup 2))
4493 (set (match_dup 3) (match_dup 6))
4494 ; no-op move in the case where no scratch is needed
4495 (set (match_dup 5) (match_dup 3))]
4497 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4498 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4499 operands[6] = operands[1];
4501 if (GET_CODE (operands[3]) == SCRATCH)
4502 operands[3] = operands[5];
4505 (define_insn_and_split "zero_extendhisi2"
4506 [(set (match_operand:SI 0 "register_operand" "=r")
4507 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4511 [(set (match_dup 2) (match_dup 1))
4512 (set (match_dup 3) (const_int 0))]
4514 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4515 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4517 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4518 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4521 (define_insn_and_split "zero_extendpsisi2"
4522 [(set (match_operand:SI 0 "register_operand" "=r")
4523 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4527 [(set (match_dup 2) (match_dup 1))
4528 (set (match_dup 3) (const_int 0))]
4530 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4531 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4534 (define_insn_and_split "zero_extendqidi2"
4535 [(set (match_operand:DI 0 "register_operand" "=r")
4536 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4540 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4541 (set (match_dup 3) (const_int 0))]
4543 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4544 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4546 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4547 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4550 (define_insn_and_split "zero_extendhidi2"
4551 [(set (match_operand:DI 0 "register_operand" "=r")
4552 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4556 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4557 (set (match_dup 3) (const_int 0))]
4559 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4560 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4562 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4563 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4566 (define_insn_and_split "zero_extendsidi2"
4567 [(set (match_operand:DI 0 "register_operand" "=r")
4568 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4572 [(set (match_dup 2) (match_dup 1))
4573 (set (match_dup 3) (const_int 0))]
4575 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4576 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4578 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4579 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4582 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4585 ; Optimize negated tests into reverse compare if overflow is undefined.
4586 (define_insn "*negated_tstqi"
4588 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4590 "!flag_wrapv && !flag_trapv"
4591 "cp __zero_reg__,%0"
4592 [(set_attr "cc" "compare")
4593 (set_attr "length" "1")])
4595 (define_insn "*reversed_tstqi"
4597 (compare (const_int 0)
4598 (match_operand:QI 0 "register_operand" "r")))]
4600 "cp __zero_reg__,%0"
4601 [(set_attr "cc" "compare")
4602 (set_attr "length" "2")])
4604 (define_insn "*negated_tsthi"
4606 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4608 "!flag_wrapv && !flag_trapv"
4609 "cp __zero_reg__,%A0
4610 cpc __zero_reg__,%B0"
4611 [(set_attr "cc" "compare")
4612 (set_attr "length" "2")])
4614 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4615 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4616 (define_insn "*reversed_tsthi"
4618 (compare (const_int 0)
4619 (match_operand:HI 0 "register_operand" "r")))
4620 (clobber (match_scratch:QI 1 "=X"))]
4622 "cp __zero_reg__,%A0
4623 cpc __zero_reg__,%B0"
4624 [(set_attr "cc" "compare")
4625 (set_attr "length" "2")])
4627 (define_insn "*negated_tstpsi"
4629 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4631 "!flag_wrapv && !flag_trapv"
4632 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4633 [(set_attr "cc" "compare")
4634 (set_attr "length" "3")])
4636 (define_insn "*reversed_tstpsi"
4638 (compare (const_int 0)
4639 (match_operand:PSI 0 "register_operand" "r")))
4640 (clobber (match_scratch:QI 1 "=X"))]
4642 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4643 [(set_attr "cc" "compare")
4644 (set_attr "length" "3")])
4646 (define_insn "*negated_tstsi"
4648 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4650 "!flag_wrapv && !flag_trapv"
4651 "cp __zero_reg__,%A0
4652 cpc __zero_reg__,%B0
4653 cpc __zero_reg__,%C0
4654 cpc __zero_reg__,%D0"
4655 [(set_attr "cc" "compare")
4656 (set_attr "length" "4")])
4658 ;; "*reversed_tstsi"
4659 ;; "*reversed_tstsq" "*reversed_tstusq"
4660 ;; "*reversed_tstsa" "*reversed_tstusa"
4661 (define_insn "*reversed_tst<mode>"
4663 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4664 (match_operand:ALL4 1 "register_operand" "r")))
4665 (clobber (match_scratch:QI 2 "=X"))]
4667 "cp __zero_reg__,%A1
4668 cpc __zero_reg__,%B1
4669 cpc __zero_reg__,%C1
4670 cpc __zero_reg__,%D1"
4671 [(set_attr "cc" "compare")
4672 (set_attr "length" "4")])
4676 ;; "cmpqq3" "cmpuqq3"
4677 (define_insn "cmp<mode>3"
4679 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4680 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4686 [(set_attr "cc" "compare,compare,compare")
4687 (set_attr "length" "1,1,1")])
4689 (define_insn "*cmpqi_sign_extend"
4691 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4692 (match_operand:HI 1 "s8_operand" "n")))]
4695 [(set_attr "cc" "compare")
4696 (set_attr "length" "1")])
4699 (define_insn "*cmphi.zero-extend.0"
4701 (compare (zero_extend:HI (match_operand:QI 0 "register_operand" "r"))
4702 (match_operand:HI 1 "register_operand" "r")))]
4704 "cp %0,%A1\;cpc __zero_reg__,%B1"
4705 [(set_attr "cc" "compare")
4706 (set_attr "length" "2")])
4708 (define_insn "*cmphi.zero-extend.1"
4710 (compare (match_operand:HI 0 "register_operand" "r")
4711 (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))))]
4713 "cp %A0,%1\;cpc %B0,__zero_reg__"
4714 [(set_attr "cc" "compare")
4715 (set_attr "length" "2")])
4718 ;; "cmphq3" "cmpuhq3"
4719 ;; "cmpha3" "cmpuha3"
4720 (define_insn "cmp<mode>3"
4722 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4723 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4724 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4727 switch (which_alternative)
4731 return avr_out_tsthi (insn, operands, NULL);
4734 return "cp %A0,%A1\;cpc %B0,%B1";
4737 if (<MODE>mode != HImode)
4739 return reg_unused_after (insn, operands[0])
4740 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4741 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4744 if (<MODE>mode != HImode)
4746 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4749 return avr_out_compare (insn, operands, NULL);
4751 [(set_attr "cc" "compare")
4752 (set_attr "length" "1,2,2,3,4,2,4")
4753 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4755 (define_insn "*cmppsi"
4757 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4758 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4759 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4762 switch (which_alternative)
4765 return avr_out_tstpsi (insn, operands, NULL);
4768 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4771 return reg_unused_after (insn, operands[0])
4772 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4773 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4776 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4779 return avr_out_compare (insn, operands, NULL);
4781 [(set_attr "cc" "compare")
4782 (set_attr "length" "3,3,5,6,3,7")
4783 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4786 ;; "*cmpsq" "*cmpusq"
4787 ;; "*cmpsa" "*cmpusa"
4788 (define_insn "*cmp<mode>"
4790 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4791 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4792 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4795 if (0 == which_alternative)
4796 return avr_out_tstsi (insn, operands, NULL);
4797 else if (1 == which_alternative)
4798 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4800 return avr_out_compare (insn, operands, NULL);
4802 [(set_attr "cc" "compare")
4803 (set_attr "length" "4,4,4,5,8")
4804 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4807 ;; ----------------------------------------------------------------------
4808 ;; JUMP INSTRUCTIONS
4809 ;; ----------------------------------------------------------------------
4810 ;; Conditional jump instructions
4813 ;; "cbranchqq4" "cbranchuqq4"
4814 (define_expand "cbranch<mode>4"
4816 (compare (match_operand:ALL1 1 "register_operand" "")
4817 (match_operand:ALL1 2 "nonmemory_operand" "")))
4820 (match_operator 0 "ordered_comparison_operator" [(cc0)
4822 (label_ref (match_operand 3 "" ""))
4825 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4826 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4828 (define_expand "cbranch<mode>4"
4829 [(parallel [(set (cc0)
4830 (compare (match_operand:ORDERED234 1 "register_operand" "")
4831 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4832 (clobber (match_scratch:QI 4 ""))])
4835 (match_operator 0 "ordered_comparison_operator" [(cc0)
4837 (label_ref (match_operand 3 "" ""))
4841 ;; Test a single bit in a QI/HI/SImode register.
4842 ;; Combine will create zero extract patterns for single bit tests.
4843 ;; permit any mode in source pattern by using VOIDmode.
4845 (define_insn "*sbrx_branch<mode>"
4848 (match_operator 0 "eqne_operator"
4850 (match_operand:VOID 1 "register_operand" "r")
4852 (match_operand 2 "const_int_operand" "n"))
4854 (label_ref (match_operand 3 "" ""))
4858 return avr_out_sbxx_branch (insn, operands);
4860 [(set (attr "length")
4861 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4862 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4864 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4867 (set_attr "cc" "clobber")])
4869 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4870 ;; or for old peepholes.
4871 ;; Fixme - bitwise Mask will not work for DImode
4873 (define_insn "*sbrx_and_branch<mode>"
4876 (match_operator 0 "eqne_operator"
4878 (match_operand:QISI 1 "register_operand" "r")
4879 (match_operand:QISI 2 "single_one_operand" "n"))
4881 (label_ref (match_operand 3 "" ""))
4885 HOST_WIDE_INT bitnumber;
4886 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4887 operands[2] = GEN_INT (bitnumber);
4888 return avr_out_sbxx_branch (insn, operands);
4890 [(set (attr "length")
4891 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4892 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4894 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4897 (set_attr "cc" "clobber")])
4899 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4901 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4903 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4904 (label_ref (match_operand 1 "" ""))
4907 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4911 (label_ref (match_dup 1))
4915 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4917 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4918 (label_ref (match_operand 1 "" ""))
4921 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4925 (label_ref (match_dup 1))
4929 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4931 (clobber (match_operand:HI 2 ""))])
4932 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4933 (label_ref (match_operand 1 "" ""))
4936 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4938 (label_ref (match_dup 1))
4942 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4944 (clobber (match_operand:HI 2 ""))])
4945 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4946 (label_ref (match_operand 1 "" ""))
4949 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4951 (label_ref (match_dup 1))
4955 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4957 (clobber (match_operand:SI 2 ""))])
4958 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4959 (label_ref (match_operand 1 "" ""))
4962 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4964 (label_ref (match_dup 1))
4966 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4969 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4971 (clobber (match_operand:SI 2 ""))])
4972 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4973 (label_ref (match_operand 1 "" ""))
4976 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4978 (label_ref (match_dup 1))
4980 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4982 ;; ************************************************************************
4983 ;; Implementation of conditional jumps here.
4984 ;; Compare with 0 (test) jumps
4985 ;; ************************************************************************
4987 (define_insn "branch"
4989 (if_then_else (match_operator 1 "simple_comparison_operator"
4992 (label_ref (match_operand 0 "" ""))
4996 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4998 [(set_attr "type" "branch")
4999 (set_attr "cc" "clobber")])
5002 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
5003 ;; or optimized in the remainder.
5005 (define_insn "branch_unspec"
5007 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
5010 (label_ref (match_operand 0 "" ""))
5012 ] UNSPEC_IDENTITY))]
5015 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5017 [(set_attr "type" "branch")
5018 (set_attr "cc" "none")])
5020 ;; ****************************************************************
5021 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
5022 ;; Convert them all to proper jumps.
5023 ;; ****************************************************************/
5025 (define_insn "difficult_branch"
5027 (if_then_else (match_operator 1 "difficult_comparison_operator"
5030 (label_ref (match_operand 0 "" ""))
5034 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
5036 [(set_attr "type" "branch1")
5037 (set_attr "cc" "clobber")])
5041 (define_insn "rvbranch"
5043 (if_then_else (match_operator 1 "simple_comparison_operator"
5047 (label_ref (match_operand 0 "" ""))))]
5050 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5052 [(set_attr "type" "branch1")
5053 (set_attr "cc" "clobber")])
5055 (define_insn "difficult_rvbranch"
5057 (if_then_else (match_operator 1 "difficult_comparison_operator"
5061 (label_ref (match_operand 0 "" ""))))]
5064 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
5066 [(set_attr "type" "branch")
5067 (set_attr "cc" "clobber")])
5069 ;; **************************************************************************
5070 ;; Unconditional and other jump instructions.
5074 (label_ref (match_operand 0 "" "")))]
5077 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
5081 [(set (attr "length")
5082 (if_then_else (match_operand 0 "symbol_ref_operand" "")
5083 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5086 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
5087 (le (minus (pc) (match_dup 0)) (const_int 2047)))
5090 (set_attr "cc" "none")])
5094 ;; Operand 1 not used on the AVR.
5095 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5096 (define_expand "call"
5097 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5098 (match_operand:HI 1 "general_operand" ""))
5099 (use (const_int 0))])])
5101 ;; Operand 1 not used on the AVR.
5102 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5103 (define_expand "sibcall"
5104 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
5105 (match_operand:HI 1 "general_operand" ""))
5106 (use (const_int 1))])])
5110 ;; Operand 2 not used on the AVR.
5111 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5112 (define_expand "call_value"
5113 [(parallel[(set (match_operand 0 "register_operand" "")
5114 (call (match_operand:HI 1 "call_insn_operand" "")
5115 (match_operand:HI 2 "general_operand" "")))
5116 (use (const_int 0))])])
5118 ;; Operand 2 not used on the AVR.
5119 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5120 (define_expand "sibcall_value"
5121 [(parallel[(set (match_operand 0 "register_operand" "")
5122 (call (match_operand:HI 1 "call_insn_operand" "")
5123 (match_operand:HI 2 "general_operand" "")))
5124 (use (const_int 1))])])
5126 (define_insn "call_insn"
5127 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
5128 (match_operand:HI 1 "general_operand" "X,X,X,X"))
5129 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
5130 ;; Operand 1 not used on the AVR.
5131 ;; Operand 2 is 1 for tail-call, 0 otherwise.
5138 [(set_attr "cc" "clobber")
5139 (set_attr "length" "1,*,1,*")
5140 (set_attr "adjust_len" "*,call,*,call")])
5142 (define_insn "call_value_insn"
5143 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
5144 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
5145 (match_operand:HI 2 "general_operand" "X,X,X,X")))
5146 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
5147 ;; Operand 2 not used on the AVR.
5148 ;; Operand 3 is 1 for tail-call, 0 otherwise.
5155 [(set_attr "cc" "clobber")
5156 (set_attr "length" "1,*,1,*")
5157 (set_attr "adjust_len" "*,call,*,call")])
5163 [(set_attr "cc" "none")
5164 (set_attr "length" "1")])
5168 (define_expand "indirect_jump"
5170 (match_operand:HI 0 "nonmemory_operand" ""))]
5173 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
5175 operands[0] = copy_to_mode_reg (HImode, operands[0]);
5180 (define_insn "*indirect_jump"
5182 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
5188 push %A0\;push %B0\;ret
5190 [(set_attr "length" "1,2,1,3,1")
5191 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
5192 (set_attr "cc" "none")])
5195 ;; For entries in jump table see avr_output_addr_vec.
5198 ;; "rjmp .L<n>" instructions for <= 8K devices
5199 ;; ".word gs(.L<n>)" addresses for > 8K devices
5200 (define_insn "*tablejump"
5202 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
5204 (use (label_ref (match_operand 1 "" "")))
5205 (clobber (match_dup 0))
5206 (clobber (const_int 0))]
5207 "!AVR_HAVE_EIJMP_EICALL"
5210 push %A0\;push %B0\;ret
5212 [(set_attr "length" "1,3,2")
5213 (set_attr "isa" "rjmp,rjmp,jmp")
5214 (set_attr "cc" "none,none,clobber")])
5216 (define_insn "*tablejump.3byte-pc"
5218 (unspec:HI [(reg:HI REG_Z)]
5220 (use (label_ref (match_operand 0 "" "")))
5221 (clobber (reg:HI REG_Z))
5222 (clobber (reg:QI 24))]
5223 "AVR_HAVE_EIJMP_EICALL"
5224 "clr r24\;subi r30,pm_lo8(-(%0))\;sbci r31,pm_hi8(-(%0))\;sbci r24,pm_hh8(-(%0))\;jmp __tablejump2__"
5225 [(set_attr "length" "6")
5226 (set_attr "isa" "eijmp")
5227 (set_attr "cc" "clobber")])
5230 ;; FIXME: casesi comes up with an SImode switch value $0 which
5231 ;; is quite some overhead because most code would use HI or
5232 ;; even QI. We add an AVR specific pass .avr-casesi which
5233 ;; tries to recover from the superfluous extension to SImode.
5235 ;; Using "tablejump" could be a way out, but this also does
5236 ;; not perform in a satisfying manner as the middle end will
5237 ;; already multiply the table index by 2. Note that this
5238 ;; multiplication is performed by libgcc's __tablejump2__.
5239 ;; The multiplication there, however, runs *after* the table
5240 ;; start (a byte address) has been added, not before it like
5241 ;; "tablejump" will do.
5243 ;; The preferred solution would be to let the middle ends pass
5244 ;; down information on the index as an additional casesi operand.
5246 ;; If this expander is changed, you'll likely have to go through
5247 ;; "casesi_<mode>_sequence" (used to recog + extract casesi
5248 ;; sequences in pass .avr-casesi) and propagate all adjustments
5249 ;; also to that pattern and the code of the extra pass.
5251 (define_expand "casesi"
5252 [(parallel [(set (match_dup 5)
5253 (plus:SI (match_operand:SI 0 "register_operand")
5254 (match_operand:SI 1 "const_int_operand")))
5255 (clobber (scratch:QI))])
5256 (parallel [(set (cc0)
5257 (compare (match_dup 5)
5258 (match_operand:SI 2 "const_int_operand")))
5259 (clobber (scratch:QI))])
5262 (if_then_else (gtu (cc0)
5264 (label_ref (match_operand 4))
5270 (parallel [(set (pc)
5271 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5272 (use (label_ref (match_dup 3)))
5273 (clobber (match_dup 7))
5274 (clobber (match_dup 8))])]
5277 operands[1] = simplify_unary_operation (NEG, SImode, operands[1], SImode);
5278 operands[5] = gen_reg_rtx (SImode);
5279 operands[6] = simplify_gen_subreg (HImode, operands[5], SImode, 0);
5281 if (AVR_HAVE_EIJMP_EICALL)
5283 operands[7] = gen_rtx_REG (HImode, REG_Z);
5284 operands[8] = all_regs_rtx[24];
5288 operands[6] = gen_rtx_PLUS (HImode, operands[6],
5289 gen_rtx_LABEL_REF (VOIDmode, operands[3]));
5290 operands[7] = gen_reg_rtx (HImode);
5291 operands[8] = const0_rtx;
5296 ;; This insn is used only for easy operand extraction.
5297 ;; The elements must match an extension to SImode plus
5298 ;; a sequence generated by casesi above.
5300 ;; "casesi_qi_sequence"
5301 ;; "casesi_hi_sequence"
5302 (define_insn "casesi_<mode>_sequence"
5303 [(set (match_operand:SI 0 "register_operand")
5304 (match_operator:SI 9 "extend_operator"
5305 [(match_operand:QIHI 10 "register_operand")]))
5307 ;; What follows is a matcher for code from casesi.
5308 ;; We keep the same operand numbering (except for $9 and $10
5309 ;; which don't appear in casesi).
5310 (parallel [(set (match_operand:SI 5 "register_operand")
5311 (plus:SI (match_dup 0)
5312 (match_operand:SI 1 "const_int_operand")))
5313 (clobber (scratch:QI))])
5314 (parallel [(set (cc0)
5315 (compare (match_dup 5)
5316 (match_operand:SI 2 "const_int_operand")))
5317 (clobber (scratch:QI))])
5320 (if_then_else (gtu (cc0)
5322 (label_ref (match_operand 4))
5325 (set (match_operand:HI 7 "register_operand")
5326 (match_operand:HI 6))
5328 (parallel [(set (pc)
5329 (unspec:HI [(match_dup 7)] UNSPEC_INDEX_JMP))
5330 (use (label_ref (match_operand 3)))
5331 (clobber (match_dup 7))
5332 (clobber (match_operand:QI 8))])]
5334 && avr_casei_sequence_check_operands (operands)"
5335 { gcc_unreachable(); }
5339 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5340 ;; This instruction sets Z flag
5343 [(set (cc0) (const_int 0))]
5346 [(set_attr "length" "1")
5347 (set_attr "cc" "compare")])
5349 ;; Clear/set/test a single bit in I/O address space.
5352 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5353 (and:QI (mem:QI (match_dup 0))
5354 (match_operand:QI 1 "single_zero_operand" "n")))]
5357 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5358 return "cbi %i0,%2";
5360 [(set_attr "length" "1")
5361 (set_attr "cc" "none")])
5364 [(set (mem:QI (match_operand 0 "low_io_address_operand" "i"))
5365 (ior:QI (mem:QI (match_dup 0))
5366 (match_operand:QI 1 "single_one_operand" "n")))]
5369 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5370 return "sbi %i0,%2";
5372 [(set_attr "length" "1")
5373 (set_attr "cc" "none")])
5375 ;; Lower half of the I/O space - use sbic/sbis directly.
5376 (define_insn "*sbix_branch"
5379 (match_operator 0 "eqne_operator"
5381 (mem:QI (match_operand 1 "low_io_address_operand" "i"))
5383 (match_operand 2 "const_int_operand" "n"))
5385 (label_ref (match_operand 3 "" ""))
5389 return avr_out_sbxx_branch (insn, operands);
5391 [(set (attr "length")
5392 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5393 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5395 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5398 (set_attr "cc" "clobber")])
5400 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5401 (define_insn "*sbix_branch_bit7"
5404 (match_operator 0 "gelt_operator"
5405 [(mem:QI (match_operand 1 "low_io_address_operand" "i"))
5407 (label_ref (match_operand 2 "" ""))
5411 operands[3] = operands[2];
5412 operands[2] = GEN_INT (7);
5413 return avr_out_sbxx_branch (insn, operands);
5415 [(set (attr "length")
5416 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5417 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5419 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5422 (set_attr "cc" "clobber")])
5424 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5425 (define_insn "*sbix_branch_tmp"
5428 (match_operator 0 "eqne_operator"
5430 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5432 (match_operand 2 "const_int_operand" "n"))
5434 (label_ref (match_operand 3 "" ""))
5438 return avr_out_sbxx_branch (insn, operands);
5440 [(set (attr "length")
5441 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5442 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5444 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5447 (set_attr "cc" "clobber")])
5449 (define_insn "*sbix_branch_tmp_bit7"
5452 (match_operator 0 "gelt_operator"
5453 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5455 (label_ref (match_operand 2 "" ""))
5459 operands[3] = operands[2];
5460 operands[2] = GEN_INT (7);
5461 return avr_out_sbxx_branch (insn, operands);
5463 [(set (attr "length")
5464 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5465 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5467 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5470 (set_attr "cc" "clobber")])
5472 ;; ************************* Peepholes ********************************
5474 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5475 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5476 (plus:SI (match_dup 0)
5478 (clobber (scratch:QI))])
5479 (parallel [(set (cc0)
5480 (compare (match_dup 0)
5482 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5484 (if_then_else (eqne (cc0)
5486 (label_ref (match_operand 2 "" ""))
5493 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5494 output_asm_insn ("sbiw %0,1" CR_TAB
5495 "sbc %C0,__zero_reg__" CR_TAB
5496 "sbc %D0,__zero_reg__", operands);
5498 output_asm_insn ("subi %A0,1" CR_TAB
5499 "sbc %B0,__zero_reg__" CR_TAB
5500 "sbc %C0,__zero_reg__" CR_TAB
5501 "sbc %D0,__zero_reg__", operands);
5503 jump_mode = avr_jump_mode (operands[2], insn);
5504 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5505 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5509 case 1: return "%1 %2";
5510 case 2: return "%1 .+2\;rjmp %2";
5511 case 3: return "%1 .+4\;jmp %2";
5518 (define_peephole ; "*dec-and-branchhi!=-1"
5519 [(set (match_operand:HI 0 "d_register_operand" "")
5520 (plus:HI (match_dup 0)
5522 (parallel [(set (cc0)
5523 (compare (match_dup 0)
5525 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5527 (if_then_else (eqne (cc0)
5529 (label_ref (match_operand 2 "" ""))
5536 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5537 output_asm_insn ("sbiw %0,1", operands);
5539 output_asm_insn ("subi %A0,1" CR_TAB
5540 "sbc %B0,__zero_reg__", operands);
5542 jump_mode = avr_jump_mode (operands[2], insn);
5543 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5544 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5548 case 1: return "%1 %2";
5549 case 2: return "%1 .+2\;rjmp %2";
5550 case 3: return "%1 .+4\;jmp %2";
5557 ;; Same as above but with clobber flavour of addhi3
5558 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5559 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5560 (plus:HI (match_dup 0)
5562 (clobber (scratch:QI))])
5563 (parallel [(set (cc0)
5564 (compare (match_dup 0)
5566 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5568 (if_then_else (eqne (cc0)
5570 (label_ref (match_operand 2 "" ""))
5577 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5578 output_asm_insn ("sbiw %0,1", operands);
5580 output_asm_insn ("subi %A0,1" CR_TAB
5581 "sbc %B0,__zero_reg__", operands);
5583 jump_mode = avr_jump_mode (operands[2], insn);
5584 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5585 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5589 case 1: return "%1 %2";
5590 case 2: return "%1 .+2\;rjmp %2";
5591 case 3: return "%1 .+4\;jmp %2";
5598 ;; Same as above but with clobber flavour of addhi3
5599 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5600 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5601 (plus:HI (match_dup 0)
5603 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5604 (parallel [(set (cc0)
5605 (compare (match_dup 0)
5607 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5609 (if_then_else (eqne (cc0)
5611 (label_ref (match_operand 2 "" ""))
5618 output_asm_insn ("ldi %3,1" CR_TAB
5620 "sbc %B0,__zero_reg__", operands);
5622 jump_mode = avr_jump_mode (operands[2], insn);
5623 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5624 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5628 case 1: return "%1 %2";
5629 case 2: return "%1 .+2\;rjmp %2";
5630 case 3: return "%1 .+4\;jmp %2";
5637 (define_peephole ; "*dec-and-branchqi!=-1"
5638 [(set (match_operand:QI 0 "d_register_operand" "")
5639 (plus:QI (match_dup 0)
5642 (compare (match_dup 0)
5645 (if_then_else (eqne (cc0)
5647 (label_ref (match_operand 1 "" ""))
5654 cc_status.value1 = operands[0];
5655 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5657 output_asm_insn ("subi %A0,1", operands);
5659 jump_mode = avr_jump_mode (operands[1], insn);
5660 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5661 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5665 case 1: return "%0 %1";
5666 case 2: return "%0 .+2\;rjmp %1";
5667 case 3: return "%0 .+4\;jmp %1";
5675 (define_peephole ; "*cpse.eq"
5677 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5678 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5680 (if_then_else (eq (cc0)
5682 (label_ref (match_operand 0 "" ""))
5684 "jump_over_one_insn_p (insn, operands[0])"
5687 cpse %1,__zero_reg__")
5689 ;; This peephole avoids code like
5692 ;; BREQ .+2 ; branch
5695 ;; Notice that the peephole is always shorter than cmpqi + branch.
5696 ;; The reason to write it as peephole is that sequences like
5701 ;; shall not be superseeded. With a respective combine pattern
5702 ;; the latter sequence would be
5705 ;; CPSE Rm, __zero_reg__
5708 ;; and thus longer and slower and not easy to be rolled back.
5710 (define_peephole ; "*cpse.ne"
5712 (compare (match_operand:ALL1 1 "register_operand" "")
5713 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5715 (if_then_else (ne (cc0)
5717 (label_ref (match_operand 0 "" ""))
5720 || !TARGET_SKIP_BUG"
5722 if (operands[2] == CONST0_RTX (<MODE>mode))
5723 operands[2] = zero_reg_rtx;
5725 return 3 == avr_jump_mode (operands[0], insn)
5726 ? "cpse %1,%2\;jmp %0"
5727 : "cpse %1,%2\;rjmp %0";
5730 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5731 ;;prologue/epilogue support instructions
5733 (define_insn "popqi"
5734 [(set (match_operand:QI 0 "register_operand" "=r")
5735 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5738 [(set_attr "cc" "none")
5739 (set_attr "length" "1")])
5741 ;; Enable Interrupts
5742 (define_expand "enable_interrupt"
5743 [(clobber (const_int 0))]
5746 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5747 MEM_VOLATILE_P (mem) = 1;
5748 emit_insn (gen_cli_sei (const1_rtx, mem));
5752 ;; Disable Interrupts
5753 (define_expand "disable_interrupt"
5754 [(clobber (const_int 0))]
5757 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5758 MEM_VOLATILE_P (mem) = 1;
5759 emit_insn (gen_cli_sei (const0_rtx, mem));
5763 (define_insn "cli_sei"
5764 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5765 UNSPECV_ENABLE_IRQS)
5766 (set (match_operand:BLK 1 "" "")
5767 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5772 [(set_attr "length" "1")
5773 (set_attr "cc" "none")])
5775 ;; Library prologue saves
5776 (define_insn "call_prologue_saves"
5777 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5778 (match_operand:HI 0 "immediate_operand" "i,i")
5779 (set (reg:HI REG_SP)
5780 (minus:HI (reg:HI REG_SP)
5781 (match_operand:HI 1 "immediate_operand" "i,i")))
5782 (use (reg:HI REG_X))
5783 (clobber (reg:HI REG_Z))]
5785 "ldi r30,lo8(gs(1f))
5787 %~jmp __prologue_saves__+((18 - %0) * 2)
5789 [(set_attr "length" "5,6")
5790 (set_attr "cc" "clobber")
5791 (set_attr "isa" "rjmp,jmp")])
5793 ; epilogue restores using library
5794 (define_insn "epilogue_restores"
5795 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5797 (plus:HI (reg:HI REG_Y)
5798 (match_operand:HI 0 "immediate_operand" "i,i")))
5799 (set (reg:HI REG_SP)
5800 (plus:HI (reg:HI REG_Y)
5802 (clobber (reg:QI REG_Z))]
5805 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5806 [(set_attr "length" "2,3")
5807 (set_attr "cc" "clobber")
5808 (set_attr "isa" "rjmp,jmp")])
5811 ;; $0 = Chunk: 1 = Prologue, 2 = Epilogue
5812 ;; $1 = Register as printed by chunk 0 (Done) in final postscan.
5813 (define_expand "gasisr"
5814 [(parallel [(unspec_volatile [(match_operand:QI 0 "const_int_operand")
5815 (match_operand:QI 1 "const_int_operand")]
5817 (set (reg:HI REG_SP)
5818 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5820 (unspec_volatile:BLK [(match_dup 2)]
5821 UNSPECV_MEMORY_BARRIER))])]
5822 "avr_gasisr_prologues"
5824 operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5825 MEM_VOLATILE_P (operands[2]) = 1;
5828 (define_insn "*gasisr"
5829 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "P,K")
5830 (match_operand:QI 1 "const_int_operand" "n,n")]
5832 (set (reg:HI REG_SP)
5833 (unspec_volatile:HI [(reg:HI REG_SP)] UNSPECV_GASISR))
5834 (set (match_operand:BLK 2)
5835 (unspec_volatile:BLK [(match_dup 2)] UNSPECV_MEMORY_BARRIER))]
5836 "avr_gasisr_prologues"
5838 [(set_attr "length" "6,5")
5839 (set_attr "cc" "clobber")])
5843 (define_insn "return"
5845 "reload_completed && avr_simple_epilogue ()"
5847 [(set_attr "cc" "none")
5848 (set_attr "length" "1")])
5850 (define_insn "return_from_epilogue"
5854 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5855 && !cfun->machine->is_naked"
5857 [(set_attr "cc" "none")
5858 (set_attr "length" "1")])
5860 (define_insn "return_from_interrupt_epilogue"
5864 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5865 && !cfun->machine->is_naked"
5867 [(set_attr "cc" "none")
5868 (set_attr "length" "1")])
5870 (define_insn "return_from_naked_epilogue"
5874 && cfun->machine->is_naked"
5876 [(set_attr "cc" "none")
5877 (set_attr "length" "0")])
5879 (define_expand "prologue"
5883 avr_expand_prologue ();
5887 (define_expand "epilogue"
5891 avr_expand_epilogue (false /* sibcall_p */);
5895 (define_expand "sibcall_epilogue"
5899 avr_expand_epilogue (true /* sibcall_p */);
5903 ;; Some instructions resp. instruction sequences available
5906 (define_insn "delay_cycles_1"
5907 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5909 UNSPECV_DELAY_CYCLES)
5910 (set (match_operand:BLK 1 "" "")
5911 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5912 (clobber (match_scratch:QI 2 "=&d"))]
5917 [(set_attr "length" "3")
5918 (set_attr "cc" "clobber")])
5920 (define_insn "delay_cycles_2"
5921 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n,n")
5923 UNSPECV_DELAY_CYCLES)
5924 (set (match_operand:BLK 1 "" "")
5925 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5926 (clobber (match_scratch:HI 2 "=&w,&d"))]
5929 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: sbiw %A2,1\;brne 1b
5930 ldi %A2,lo8(%0)\;ldi %B2,hi8(%0)\n1: subi %A2,1\;sbci %B2,0\;brne 1b"
5931 [(set_attr "length" "4,5")
5932 (set_attr "isa" "no_tiny,tiny")
5933 (set_attr "cc" "clobber")])
5935 (define_insn "delay_cycles_3"
5936 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5938 UNSPECV_DELAY_CYCLES)
5939 (set (match_operand:BLK 1 "" "")
5940 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5941 (clobber (match_scratch:QI 2 "=&d"))
5942 (clobber (match_scratch:QI 3 "=&d"))
5943 (clobber (match_scratch:QI 4 "=&d"))]
5952 [(set_attr "length" "7")
5953 (set_attr "cc" "clobber")])
5955 (define_insn "delay_cycles_4"
5956 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5958 UNSPECV_DELAY_CYCLES)
5959 (set (match_operand:BLK 1 "" "")
5960 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5961 (clobber (match_scratch:QI 2 "=&d"))
5962 (clobber (match_scratch:QI 3 "=&d"))
5963 (clobber (match_scratch:QI 4 "=&d"))
5964 (clobber (match_scratch:QI 5 "=&d"))]
5975 [(set_attr "length" "9")
5976 (set_attr "cc" "clobber")])
5979 ;; __builtin_avr_insert_bits
5981 (define_insn "insert_bits"
5982 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5983 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5984 (match_operand:QI 2 "register_operand" "r ,r ,r")
5985 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5986 UNSPEC_INSERT_BITS))]
5989 return avr_out_insert_bits (operands, NULL);
5991 [(set_attr "adjust_len" "insert_bits")
5992 (set_attr "cc" "clobber")])
5995 ;; __builtin_avr_flash_segment
5997 ;; Just a helper for the next "official" expander.
5999 (define_expand "flash_segment1"
6000 [(set (match_operand:QI 0 "register_operand" "")
6001 (subreg:QI (match_operand:PSI 1 "register_operand" "")
6004 (compare (match_dup 0)
6007 (if_then_else (ge (cc0)
6009 (label_ref (match_operand 2 "" ""))
6014 (define_expand "flash_segment"
6015 [(parallel [(match_operand:QI 0 "register_operand" "")
6016 (match_operand:PSI 1 "register_operand" "")])]
6019 rtx label = gen_label_rtx ();
6020 emit (gen_flash_segment1 (operands[0], operands[1], label));
6025 ;; Actually, it's too late now to work out address spaces known at compiletime.
6026 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
6027 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
6028 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
6030 (define_insn_and_split "*split.flash_segment"
6031 [(set (match_operand:QI 0 "register_operand" "=d")
6032 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
6033 (match_operand:HI 2 "register_operand" "r"))
6036 { gcc_unreachable(); }
6044 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
6045 ;; better 8-bit parity recognition.
6047 (define_expand "parityhi2"
6048 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6049 (parity:HI (match_operand:HI 1 "register_operand" "")))
6050 (clobber (reg:HI 24))])])
6052 (define_insn_and_split "*parityhi2"
6053 [(set (match_operand:HI 0 "register_operand" "=r")
6054 (parity:HI (match_operand:HI 1 "register_operand" "r")))
6055 (clobber (reg:HI 24))]
6057 { gcc_unreachable(); }
6062 (parity:HI (reg:HI 24)))
6066 (define_insn_and_split "*parityqihi2"
6067 [(set (match_operand:HI 0 "register_operand" "=r")
6068 (parity:HI (match_operand:QI 1 "register_operand" "r")))
6069 (clobber (reg:HI 24))]
6071 { gcc_unreachable(); }
6076 (zero_extend:HI (parity:QI (reg:QI 24))))
6080 (define_expand "paritysi2"
6082 (match_operand:SI 1 "register_operand" ""))
6084 (truncate:HI (parity:SI (reg:SI 22))))
6087 (set (match_operand:SI 0 "register_operand" "")
6088 (zero_extend:SI (match_dup 2)))]
6091 operands[2] = gen_reg_rtx (HImode);
6094 (define_insn "*parityhi2.libgcc"
6096 (parity:HI (reg:HI 24)))]
6098 "%~call __parityhi2"
6099 [(set_attr "type" "xcall")
6100 (set_attr "cc" "clobber")])
6102 (define_insn "*parityqihi2.libgcc"
6104 (zero_extend:HI (parity:QI (reg:QI 24))))]
6106 "%~call __parityqi2"
6107 [(set_attr "type" "xcall")
6108 (set_attr "cc" "clobber")])
6110 (define_insn "*paritysihi2.libgcc"
6112 (truncate:HI (parity:SI (reg:SI 22))))]
6114 "%~call __paritysi2"
6115 [(set_attr "type" "xcall")
6116 (set_attr "cc" "clobber")])
6121 (define_expand "popcounthi2"
6123 (match_operand:HI 1 "register_operand" ""))
6125 (popcount:HI (reg:HI 24)))
6126 (set (match_operand:HI 0 "register_operand" "")
6131 (define_expand "popcountsi2"
6133 (match_operand:SI 1 "register_operand" ""))
6135 (truncate:HI (popcount:SI (reg:SI 22))))
6138 (set (match_operand:SI 0 "register_operand" "")
6139 (zero_extend:SI (match_dup 2)))]
6142 operands[2] = gen_reg_rtx (HImode);
6145 (define_insn "*popcounthi2.libgcc"
6147 (popcount:HI (reg:HI 24)))]
6149 "%~call __popcounthi2"
6150 [(set_attr "type" "xcall")
6151 (set_attr "cc" "clobber")])
6153 (define_insn "*popcountsi2.libgcc"
6155 (truncate:HI (popcount:SI (reg:SI 22))))]
6157 "%~call __popcountsi2"
6158 [(set_attr "type" "xcall")
6159 (set_attr "cc" "clobber")])
6161 (define_insn "*popcountqi2.libgcc"
6163 (popcount:QI (reg:QI 24)))]
6165 "%~call __popcountqi2"
6166 [(set_attr "type" "xcall")
6167 (set_attr "cc" "clobber")])
6169 (define_insn_and_split "*popcountqihi2.libgcc"
6171 (zero_extend:HI (popcount:QI (reg:QI 24))))]
6176 (popcount:QI (reg:QI 24)))
6180 ;; Count Leading Zeros
6182 (define_expand "clzhi2"
6184 (match_operand:HI 1 "register_operand" ""))
6185 (parallel [(set (reg:HI 24)
6186 (clz:HI (reg:HI 24)))
6187 (clobber (reg:QI 26))])
6188 (set (match_operand:HI 0 "register_operand" "")
6191 (define_expand "clzsi2"
6193 (match_operand:SI 1 "register_operand" ""))
6194 (parallel [(set (reg:HI 24)
6195 (truncate:HI (clz:SI (reg:SI 22))))
6196 (clobber (reg:QI 26))])
6199 (set (match_operand:SI 0 "register_operand" "")
6200 (zero_extend:SI (match_dup 2)))]
6203 operands[2] = gen_reg_rtx (HImode);
6206 (define_insn "*clzhi2.libgcc"
6208 (clz:HI (reg:HI 24)))
6209 (clobber (reg:QI 26))]
6212 [(set_attr "type" "xcall")
6213 (set_attr "cc" "clobber")])
6215 (define_insn "*clzsihi2.libgcc"
6217 (truncate:HI (clz:SI (reg:SI 22))))
6218 (clobber (reg:QI 26))]
6221 [(set_attr "type" "xcall")
6222 (set_attr "cc" "clobber")])
6224 ;; Count Trailing Zeros
6226 (define_expand "ctzhi2"
6228 (match_operand:HI 1 "register_operand" ""))
6229 (parallel [(set (reg:HI 24)
6230 (ctz:HI (reg:HI 24)))
6231 (clobber (reg:QI 26))])
6232 (set (match_operand:HI 0 "register_operand" "")
6235 (define_expand "ctzsi2"
6237 (match_operand:SI 1 "register_operand" ""))
6238 (parallel [(set (reg:HI 24)
6239 (truncate:HI (ctz:SI (reg:SI 22))))
6240 (clobber (reg:QI 22))
6241 (clobber (reg:QI 26))])
6244 (set (match_operand:SI 0 "register_operand" "")
6245 (zero_extend:SI (match_dup 2)))]
6248 operands[2] = gen_reg_rtx (HImode);
6251 (define_insn "*ctzhi2.libgcc"
6253 (ctz:HI (reg:HI 24)))
6254 (clobber (reg:QI 26))]
6257 [(set_attr "type" "xcall")
6258 (set_attr "cc" "clobber")])
6260 (define_insn "*ctzsihi2.libgcc"
6262 (truncate:HI (ctz:SI (reg:SI 22))))
6263 (clobber (reg:QI 22))
6264 (clobber (reg:QI 26))]
6267 [(set_attr "type" "xcall")
6268 (set_attr "cc" "clobber")])
6272 (define_expand "ffshi2"
6274 (match_operand:HI 1 "register_operand" ""))
6275 (parallel [(set (reg:HI 24)
6276 (ffs:HI (reg:HI 24)))
6277 (clobber (reg:QI 26))])
6278 (set (match_operand:HI 0 "register_operand" "")
6281 (define_expand "ffssi2"
6283 (match_operand:SI 1 "register_operand" ""))
6284 (parallel [(set (reg:HI 24)
6285 (truncate:HI (ffs:SI (reg:SI 22))))
6286 (clobber (reg:QI 22))
6287 (clobber (reg:QI 26))])
6290 (set (match_operand:SI 0 "register_operand" "")
6291 (zero_extend:SI (match_dup 2)))]
6294 operands[2] = gen_reg_rtx (HImode);
6297 (define_insn "*ffshi2.libgcc"
6299 (ffs:HI (reg:HI 24)))
6300 (clobber (reg:QI 26))]
6303 [(set_attr "type" "xcall")
6304 (set_attr "cc" "clobber")])
6306 (define_insn "*ffssihi2.libgcc"
6308 (truncate:HI (ffs:SI (reg:SI 22))))
6309 (clobber (reg:QI 22))
6310 (clobber (reg:QI 26))]
6313 [(set_attr "type" "xcall")
6314 (set_attr "cc" "clobber")])
6318 (define_insn "copysignsf3"
6319 [(set (match_operand:SF 0 "register_operand" "=r")
6320 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
6321 (match_operand:SF 2 "register_operand" "r")]
6324 "bst %D2,7\;bld %D0,7"
6325 [(set_attr "length" "2")
6326 (set_attr "cc" "none")])
6328 ;; Swap Bytes (change byte-endianness)
6330 (define_expand "bswapsi2"
6332 (match_operand:SI 1 "register_operand" ""))
6334 (bswap:SI (reg:SI 22)))
6335 (set (match_operand:SI 0 "register_operand" "")
6338 (define_insn "*bswapsi2.libgcc"
6340 (bswap:SI (reg:SI 22)))]
6343 [(set_attr "type" "xcall")
6344 (set_attr "cc" "clobber")])
6349 ;; NOP taking 1 or 2 Ticks
6350 (define_expand "nopv"
6351 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
6354 (unspec_volatile:BLK [(match_dup 1)]
6355 UNSPECV_MEMORY_BARRIER))])]
6358 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6359 MEM_VOLATILE_P (operands[1]) = 1;
6362 (define_insn "*nopv"
6363 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6365 (set (match_operand:BLK 1 "" "")
6366 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6371 [(set_attr "length" "1")
6372 (set_attr "cc" "none")])
6375 (define_expand "sleep"
6376 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6378 (unspec_volatile:BLK [(match_dup 0)]
6379 UNSPECV_MEMORY_BARRIER))])]
6382 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6383 MEM_VOLATILE_P (operands[0]) = 1;
6386 (define_insn "*sleep"
6387 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6388 (set (match_operand:BLK 0 "" "")
6389 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6392 [(set_attr "length" "1")
6393 (set_attr "cc" "none")])
6396 (define_expand "wdr"
6397 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6399 (unspec_volatile:BLK [(match_dup 0)]
6400 UNSPECV_MEMORY_BARRIER))])]
6403 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6404 MEM_VOLATILE_P (operands[0]) = 1;
6408 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6409 (set (match_operand:BLK 0 "" "")
6410 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6413 [(set_attr "length" "1")
6414 (set_attr "cc" "none")])
6417 (define_expand "fmul"
6419 (match_operand:QI 1 "register_operand" ""))
6421 (match_operand:QI 2 "register_operand" ""))
6422 (parallel [(set (reg:HI 22)
6423 (unspec:HI [(reg:QI 24)
6424 (reg:QI 25)] UNSPEC_FMUL))
6425 (clobber (reg:HI 24))])
6426 (set (match_operand:HI 0 "register_operand" "")
6432 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6435 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6438 (define_insn "fmul_insn"
6439 [(set (match_operand:HI 0 "register_operand" "=r")
6440 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6441 (match_operand:QI 2 "register_operand" "a")]
6447 [(set_attr "length" "3")
6448 (set_attr "cc" "clobber")])
6450 (define_insn "*fmul.call"
6452 (unspec:HI [(reg:QI 24)
6453 (reg:QI 25)] UNSPEC_FMUL))
6454 (clobber (reg:HI 24))]
6457 [(set_attr "type" "xcall")
6458 (set_attr "cc" "clobber")])
6461 (define_expand "fmuls"
6463 (match_operand:QI 1 "register_operand" ""))
6465 (match_operand:QI 2 "register_operand" ""))
6466 (parallel [(set (reg:HI 22)
6467 (unspec:HI [(reg:QI 24)
6468 (reg:QI 25)] UNSPEC_FMULS))
6469 (clobber (reg:HI 24))])
6470 (set (match_operand:HI 0 "register_operand" "")
6476 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6479 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6482 (define_insn "fmuls_insn"
6483 [(set (match_operand:HI 0 "register_operand" "=r")
6484 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6485 (match_operand:QI 2 "register_operand" "a")]
6491 [(set_attr "length" "3")
6492 (set_attr "cc" "clobber")])
6494 (define_insn "*fmuls.call"
6496 (unspec:HI [(reg:QI 24)
6497 (reg:QI 25)] UNSPEC_FMULS))
6498 (clobber (reg:HI 24))]
6501 [(set_attr "type" "xcall")
6502 (set_attr "cc" "clobber")])
6505 (define_expand "fmulsu"
6507 (match_operand:QI 1 "register_operand" ""))
6509 (match_operand:QI 2 "register_operand" ""))
6510 (parallel [(set (reg:HI 22)
6511 (unspec:HI [(reg:QI 24)
6512 (reg:QI 25)] UNSPEC_FMULSU))
6513 (clobber (reg:HI 24))])
6514 (set (match_operand:HI 0 "register_operand" "")
6520 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6523 avr_fix_inputs (operands, 1 << 2, regmask (QImode, 24));
6526 (define_insn "fmulsu_insn"
6527 [(set (match_operand:HI 0 "register_operand" "=r")
6528 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6529 (match_operand:QI 2 "register_operand" "a")]
6535 [(set_attr "length" "3")
6536 (set_attr "cc" "clobber")])
6538 (define_insn "*fmulsu.call"
6540 (unspec:HI [(reg:QI 24)
6541 (reg:QI 25)] UNSPEC_FMULSU))
6542 (clobber (reg:HI 24))]
6545 [(set_attr "type" "xcall")
6546 (set_attr "cc" "clobber")])
6549 ;; Some combiner patterns dealing with bits.
6552 ;; Move bit $3.0 into bit $0.$4
6553 (define_insn "*movbitqi.1-6.a"
6554 [(set (match_operand:QI 0 "register_operand" "=r")
6555 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6556 (match_operand:QI 2 "single_zero_operand" "n"))
6557 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6558 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6559 (match_operand:QI 5 "single_one_operand" "n"))))]
6560 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6561 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6562 "bst %3,0\;bld %0,%4"
6563 [(set_attr "length" "2")
6564 (set_attr "cc" "none")])
6566 ;; Move bit $3.0 into bit $0.$4
6567 ;; Variation of above. Unfortunately, there is no canonicalized representation
6568 ;; of moving around bits. So what we see here depends on how user writes down
6569 ;; bit manipulations.
6570 (define_insn "*movbitqi.1-6.b"
6571 [(set (match_operand:QI 0 "register_operand" "=r")
6572 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6573 (match_operand:QI 2 "single_zero_operand" "n"))
6574 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6576 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6577 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6578 "bst %3,0\;bld %0,%4"
6579 [(set_attr "length" "2")
6580 (set_attr "cc" "none")])
6582 ;; Move bit $3.0 into bit $0.0.
6583 ;; For bit 0, combiner generates slightly different pattern.
6584 (define_insn "*movbitqi.0"
6585 [(set (match_operand:QI 0 "register_operand" "=r")
6586 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6587 (match_operand:QI 2 "single_zero_operand" "n"))
6588 (and:QI (match_operand:QI 3 "register_operand" "r")
6590 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6591 "bst %3,0\;bld %0,0"
6592 [(set_attr "length" "2")
6593 (set_attr "cc" "none")])
6595 ;; Move bit $2.0 into bit $0.7.
6596 ;; For bit 7, combiner generates slightly different pattern
6597 (define_insn "*movbitqi.7"
6598 [(set (match_operand:QI 0 "register_operand" "=r")
6599 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6601 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6604 "bst %2,0\;bld %0,7"
6605 [(set_attr "length" "2")
6606 (set_attr "cc" "none")])
6608 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6609 ;; and input/output match. We provide a special pattern for this, because
6610 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6611 ;; operation on I/O is atomic.
6612 (define_insn "*insv.io"
6613 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i,i,i"))
6615 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6616 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6621 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6622 [(set_attr "length" "1,1,4")
6623 (set_attr "cc" "none")])
6625 (define_insn "*insv.not.io"
6626 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "i"))
6628 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6629 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6631 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6632 [(set_attr "length" "4")
6633 (set_attr "cc" "none")])
6635 ;; The insv expander.
6636 ;; We only support 1-bit inserts
6637 (define_expand "insv"
6638 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6639 (match_operand:QI 1 "const1_operand" "") ; width
6640 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6641 (match_operand:QI 3 "nonmemory_operand" ""))]
6644 ;; Some more patterns to support moving around one bit which can be accomplished
6645 ;; by BST + BLD in most situations. Unfortunately, there is no canonical
6646 ;; representation, and we just implement some more cases that are not too
6649 ;; Insert bit $2.0 into $0.$1
6650 (define_insn "*insv.reg"
6651 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6653 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6654 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6658 andi %0,lo8(~(1<<%1))
6662 [(set_attr "length" "2,1,1,2,2")
6663 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6665 ;; Insert bit $2.$3 into $0.$1
6666 (define_insn "*insv.extract"
6667 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6669 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6670 (any_extract:QI (match_operand:QI 2 "register_operand" "r")
6672 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6674 "bst %2,%3\;bld %0,%1"
6675 [(set_attr "length" "2")
6676 (set_attr "cc" "none")])
6678 ;; Insert bit $2.$3 into $0.$1
6679 (define_insn "*insv.shiftrt"
6680 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6682 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6683 (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6684 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6686 "bst %2,%3\;bld %0,%1"
6687 [(set_attr "length" "2")
6688 (set_attr "cc" "none")])
6690 ;; Same, but with a NOT inverting the source bit.
6691 ;; Insert bit ~$2.$3 into $0.$1
6692 (define_insn "*insv.not-shiftrt"
6693 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6695 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6696 (not:QI (any_shiftrt:QI (match_operand:QI 2 "register_operand" "r")
6697 (match_operand:QI 3 "const_0_to_7_operand" "n"))))]
6700 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6702 [(set_attr "adjust_len" "insv_notbit")
6703 (set_attr "cc" "clobber")])
6705 ;; Insert bit ~$2.0 into $0.$1
6706 (define_insn "*insv.xor1-bit.0"
6707 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6709 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6710 (xor:QI (match_operand:QI 2 "register_operand" "r")
6714 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6716 [(set_attr "adjust_len" "insv_notbit_0")
6717 (set_attr "cc" "clobber")])
6719 ;; Insert bit ~$2.0 into $0.$1
6720 (define_insn "*insv.not-bit.0"
6721 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6723 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6724 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6727 return avr_out_insert_notbit (insn, operands, const0_rtx, NULL);
6729 [(set_attr "adjust_len" "insv_notbit_0")
6730 (set_attr "cc" "clobber")])
6732 ;; Insert bit ~$2.7 into $0.$1
6733 (define_insn "*insv.not-bit.7"
6734 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6736 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6737 (ge:QI (match_operand:QI 2 "register_operand" "r")
6741 return avr_out_insert_notbit (insn, operands, GEN_INT (7), NULL);
6743 [(set_attr "adjust_len" "insv_notbit_7")
6744 (set_attr "cc" "clobber")])
6746 ;; Insert bit ~$2.$3 into $0.$1
6747 (define_insn "*insv.xor-extract"
6748 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r")
6750 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6751 (any_extract:QI (xor:QI (match_operand:QI 2 "register_operand" "r")
6752 (match_operand:QI 4 "const_int_operand" "n"))
6754 (match_operand:QI 3 "const_0_to_7_operand" "n")))]
6755 "INTVAL (operands[4]) & (1 << INTVAL (operands[3]))"
6757 return avr_out_insert_notbit (insn, operands, NULL_RTX, NULL);
6759 [(set_attr "adjust_len" "insv_notbit")
6760 (set_attr "cc" "clobber")])
6763 ;; Some combine patterns that try to fix bad code when a value is composed
6764 ;; from byte parts like in PR27663.
6765 ;; The patterns give some release but the code still is not optimal,
6766 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6767 ;; That switch obfuscates things here and in many other places.
6769 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6770 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6771 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6772 [(set (match_operand:HISI 0 "register_operand" "=r")
6774 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6775 (match_operand:HISI 2 "register_operand" "0")))]
6780 (xior:QI (match_dup 3)
6783 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6786 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6787 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6788 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6789 [(set (match_operand:HISI 0 "register_operand" "=r")
6791 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6792 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6793 (match_operand:HISI 3 "register_operand" "0")))]
6794 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6796 "&& reload_completed"
6798 (xior:QI (match_dup 4)
6801 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6802 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6806 (define_insn_and_split "*iorhi3.ashift8-ext.zerox"
6807 [(set (match_operand:HI 0 "register_operand" "=r")
6808 (ior:HI (ashift:HI (any_extend:HI
6809 (match_operand:QI 1 "register_operand" "r"))
6811 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
6813 { gcc_unreachable(); }
6814 "&& reload_completed"
6815 [(set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))
6816 (set (match_dup 2) (xor:QI (match_dup 2) (match_dup 1)))
6817 (set (match_dup 1) (xor:QI (match_dup 1) (match_dup 2)))]
6819 rtx hi = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6820 rtx lo = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6822 if (!reg_overlap_mentioned_p (hi, operands[2]))
6824 emit_move_insn (hi, operands[1]);
6825 emit_move_insn (lo, operands[2]);
6828 else if (!reg_overlap_mentioned_p (lo, operands[1]))
6830 emit_move_insn (lo, operands[2]);
6831 emit_move_insn (hi, operands[1]);
6835 gcc_assert (REGNO (operands[1]) == REGNO (operands[0]));
6836 gcc_assert (REGNO (operands[2]) == 1 + REGNO (operands[0]));
6839 (define_insn_and_split "*iorhi3.ashift8-ext.reg"
6840 [(set (match_operand:HI 0 "register_operand" "=r")
6841 (ior:HI (ashift:HI (any_extend:HI
6842 (match_operand:QI 1 "register_operand" "r"))
6844 (match_operand:HI 2 "register_operand" "0")))]
6846 { gcc_unreachable(); }
6847 "&& reload_completed"
6849 (ior:QI (match_dup 4)
6852 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6853 operands[4] = simplify_gen_subreg (QImode, operands[2], HImode, 1);
6856 (define_insn_and_split "*iorhi3.ashift8-reg.zerox"
6857 [(set (match_operand:HI 0 "register_operand" "=r")
6858 (ior:HI (ashift:HI (match_operand:HI 1 "register_operand" "r")
6860 (zero_extend:HI (match_operand:QI 2 "register_operand" "0"))))]
6862 { gcc_unreachable(); }
6863 "&& reload_completed"
6867 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6868 operands[4] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
6873 [(set (match_operand:QI 0 "register_operand")
6876 (ior:QI (match_dup 0)
6877 (match_operand:QI 1 "register_operand")))]
6883 (define_expand "extzv"
6884 [(set (match_operand:QI 0 "register_operand" "")
6885 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6886 (match_operand:QI 2 "const1_operand" "")
6887 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6889 (define_insn "*extzv"
6890 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6891 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6893 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6897 mov %0,%1\;andi %0,1
6900 bst %1,%2\;clr %0\;bld %0,0"
6901 [(set_attr "length" "1,2,2,2,3")
6902 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6904 (define_insn_and_split "*extzv.qihi1"
6905 [(set (match_operand:HI 0 "register_operand" "=r")
6906 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6908 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6913 (zero_extract:QI (match_dup 1)
6919 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6920 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6923 (define_insn_and_split "*extzv.qihi2"
6924 [(set (match_operand:HI 0 "register_operand" "=r")
6926 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6928 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6933 (zero_extract:QI (match_dup 1)
6939 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6940 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6943 ;; ??? do_store_flag emits a hard-coded right shift to extract a bit without
6944 ;; even considering rtx_costs, extzv, or a bit-test. See PR 55181 for an example.
6945 (define_insn_and_split "*extract.subreg.bit"
6946 [(set (match_operand:QI 0 "register_operand" "=r")
6947 (and:QI (subreg:QI (any_shiftrt:HISI (match_operand:HISI 1 "register_operand" "r")
6948 (match_operand:QI 2 "const_int_operand" "n"))
6951 "INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6952 { gcc_unreachable(); }
6953 "&& reload_completed"
6956 (zero_extract:QI (match_dup 3)
6960 int bitno = INTVAL (operands[2]);
6961 operands[3] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, bitno / 8);
6962 operands[4] = GEN_INT (bitno % 8);
6966 ;; Fixed-point instructions
6967 (include "avr-fixed.md")
6969 ;; Operations on 64-bit registers
6970 (include "avr-dimode.md")