1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;; 2009, 2010, 2011 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;; Special characters after '%':
24 ;; A No effect (add 0).
25 ;; B Add 1 to REG number, MEM address or CONST_INT.
28 ;; j Branch condition.
29 ;; k Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
32 ;; RAM address. The resulting addres is suitable to be used in IN/OUT.
33 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
34 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
35 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
62 (define_c_enum "unspec"
76 (define_c_enum "unspecv"
77 [UNSPECV_PROLOGUE_SAVES
78 UNSPECV_EPILOGUE_RESTORES
89 (include "predicates.md")
90 (include "constraints.md")
92 ;; Condition code settings.
93 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
94 out_plus, out_plus_noclobber,ldi"
95 (const_string "none"))
97 (define_attr "type" "branch,branch1,arith,xcall"
98 (const_string "arith"))
100 ;; The size of instructions in bytes.
101 ;; XXX may depend from "cc"
103 (define_attr "length" ""
104 (cond [(eq_attr "type" "branch")
105 (if_then_else (and (ge (minus (pc) (match_dup 0))
107 (le (minus (pc) (match_dup 0))
110 (if_then_else (and (ge (minus (pc) (match_dup 0))
112 (le (minus (pc) (match_dup 0))
116 (eq_attr "type" "branch1")
117 (if_then_else (and (ge (minus (pc) (match_dup 0))
119 (le (minus (pc) (match_dup 0))
122 (if_then_else (and (ge (minus (pc) (match_dup 0))
124 (le (minus (pc) (match_dup 0))
128 (eq_attr "type" "xcall")
129 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
134 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
135 ;; Following insn attribute tells if and how the adjustment has to be
137 ;; no No adjustment needed; attribute "length" is fine.
138 ;; Otherwise do special processing depending on the attribute.
140 (define_attr "adjust_len"
141 "out_bitop, out_plus, out_plus_noclobber, plus64, addto_sp,
142 tsthi, tstpsi, tstsi, compare, compare64, call,
143 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
144 xload, movmem, load_lpm,
145 ashlqi, ashrqi, lshrqi,
146 ashlhi, ashrhi, lshrhi,
147 ashlsi, ashrsi, lshrsi,
148 ashlpsi, ashrpsi, lshrpsi,
153 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
155 ;; mov : ISA has no MOVW movw : ISA has MOVW
156 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
157 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
158 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
159 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
160 ;; no_xmega: non-XMEGA core xmega : XMEGA core
163 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
165 (const_string "standard"))
167 (define_attr "enabled" ""
168 (cond [(eq_attr "isa" "standard")
171 (and (eq_attr "isa" "mov")
172 (match_test "!AVR_HAVE_MOVW"))
175 (and (eq_attr "isa" "movw")
176 (match_test "AVR_HAVE_MOVW"))
179 (and (eq_attr "isa" "rjmp")
180 (match_test "!AVR_HAVE_JMP_CALL"))
183 (and (eq_attr "isa" "jmp")
184 (match_test "AVR_HAVE_JMP_CALL"))
187 (and (eq_attr "isa" "ijmp")
188 (match_test "!AVR_HAVE_EIJMP_EICALL"))
191 (and (eq_attr "isa" "eijmp")
192 (match_test "AVR_HAVE_EIJMP_EICALL"))
195 (and (eq_attr "isa" "lpm")
196 (match_test "!AVR_HAVE_LPMX"))
199 (and (eq_attr "isa" "lpmx")
200 (match_test "AVR_HAVE_LPMX"))
203 (and (eq_attr "isa" "elpm")
204 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
207 (and (eq_attr "isa" "elpmx")
208 (match_test "AVR_HAVE_ELPMX"))
211 (and (eq_attr "isa" "xmega")
212 (match_test "AVR_XMEGA"))
215 (and (eq_attr "isa" "no_xmega")
216 (match_test "!AVR_XMEGA"))
221 ;; Define mode iterators
222 (define_mode_iterator QIHI [(QI "") (HI "")])
223 (define_mode_iterator QIHI2 [(QI "") (HI "")])
224 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
225 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
226 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
228 ;; All supported move-modes
229 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")])
231 ;; Define code iterators
232 ;; Define two incarnations so that we can build the cross product.
233 (define_code_iterator any_extend [sign_extend zero_extend])
234 (define_code_iterator any_extend2 [sign_extend zero_extend])
236 (define_code_iterator xior [xor ior])
237 (define_code_iterator eqne [eq ne])
239 ;; Define code attributes
240 (define_code_attr extend_su
244 (define_code_attr extend_u
248 (define_code_attr extend_s
252 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
253 (define_code_attr mul_r_d
257 ;; Map RTX code to its standard insn name
258 (define_code_attr code_stdname
266 ;;========================================================================
267 ;; The following is used by nonlocal_goto and setjmp.
268 ;; The receiver pattern will create no instructions since internally
269 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
270 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
271 ;; The 'null' receiver also avoids problems with optimisation
272 ;; not recognising incoming jmp and removing code that resets frame_pointer.
273 ;; The code derived from builtins.c.
275 (define_expand "nonlocal_goto_receiver"
277 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
280 emit_move_insn (virtual_stack_vars_rtx,
281 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
282 gen_int_mode (STARTING_FRAME_OFFSET,
284 /* This might change the hard frame pointer in ways that aren't
285 apparent to early optimization passes, so force a clobber. */
286 emit_clobber (hard_frame_pointer_rtx);
291 ;; Defining nonlocal_goto_receiver means we must also define this.
292 ;; even though its function is identical to that in builtins.c
294 (define_expand "nonlocal_goto"
295 [(use (match_operand 0 "general_operand"))
296 (use (match_operand 1 "general_operand"))
297 (use (match_operand 2 "general_operand"))
298 (use (match_operand 3 "general_operand"))]
301 rtx r_label = copy_to_reg (operands[1]);
302 rtx r_fp = operands[3];
303 rtx r_sp = operands[2];
305 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
307 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
309 emit_move_insn (hard_frame_pointer_rtx, r_fp);
310 emit_stack_restore (SAVE_NONLOCAL, r_sp);
312 emit_use (hard_frame_pointer_rtx);
313 emit_use (stack_pointer_rtx);
315 emit_indirect_jump (r_label);
320 (define_insn "pushqi1"
321 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
322 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
327 [(set_attr "length" "1,1")])
329 ;; All modes for a multi-byte push. We must include complex modes here too,
330 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
331 (define_mode_iterator MPUSH
339 (define_expand "push<mode>1"
340 [(match_operand:MPUSH 0 "" "")]
344 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
346 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
347 if (part != const0_rtx)
348 part = force_reg (QImode, part);
349 emit_insn (gen_pushqi1 (part));
354 ;; Notice a special-case when adding N to SP where N results in a
355 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
357 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
359 && frame_pointer_needed
360 && !cfun->calls_alloca
361 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
362 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
365 ;;========================================================================
368 ;; Represent a load from __flash that needs libgcc support as UNSPEC.
369 ;; This is legal because we read from non-changing memory.
370 ;; For rationale see the FIXME below.
375 (define_insn "load_<mode>_libgcc"
376 [(set (reg:MOVMODE 22)
377 (unspec:MOVMODE [(reg:HI REG_Z)]
381 rtx n_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
382 output_asm_insn ("%~call __load_%0", &n_bytes);
385 [(set_attr "type" "xcall")
386 (set_attr "cc" "clobber")])
389 ;; Similar for inline reads from flash. We use UNSPEC instead
390 ;; of MEM for the same reason as above: PR52543.
391 ;; $1 contains the memory segment.
393 (define_insn "load_<mode>"
394 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
395 (unspec:MOVMODE [(reg:HI REG_Z)
396 (match_operand:QI 1 "reg_or_0_operand" "rL")]
398 "(CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
399 || (REG_P (operands[1]) && AVR_HAVE_ELPMX)"
401 return avr_load_lpm (insn, operands, NULL);
403 [(set_attr "adjust_len" "load_lpm")
404 (set_attr "cc" "clobber")])
407 ;; Similar to above for the complementary situation when there is no [E]LPMx.
408 ;; Clobber Z in that case.
410 (define_insn "load_<mode>_clobber"
411 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
412 (unspec:MOVMODE [(reg:HI REG_Z)
413 (match_operand:QI 1 "reg_or_0_operand" "rL")]
415 (clobber (reg:HI REG_Z))]
416 "!((CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
417 || (REG_P (operands[1]) && AVR_HAVE_ELPMX))"
419 return avr_load_lpm (insn, operands, NULL);
421 [(set_attr "adjust_len" "load_lpm")
422 (set_attr "cc" "clobber")])
425 (define_insn_and_split "xload8_A"
426 [(set (match_operand:QI 0 "register_operand" "=r")
427 (match_operand:QI 1 "memory_operand" "m"))
428 (clobber (reg:HI REG_Z))]
429 "can_create_pseudo_p()
430 && !avr_xload_libgcc_p (QImode)
431 && avr_mem_memx_p (operands[1])
432 && REG_P (XEXP (operands[1], 0))"
433 { gcc_unreachable(); }
435 [(clobber (const_int 0))]
437 rtx insn, addr = XEXP (operands[1], 0);
438 rtx hi8 = gen_reg_rtx (QImode);
439 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
441 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
442 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
444 insn = emit_insn (gen_xload_8 (operands[0], hi8));
445 set_mem_addr_space (SET_SRC (single_set (insn)),
446 MEM_ADDR_SPACE (operands[1]));
455 (define_insn_and_split "xload<mode>_A"
456 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
457 (match_operand:MOVMODE 1 "memory_operand" "m"))
458 (clobber (reg:MOVMODE 22))
459 (clobber (reg:QI 21))
460 (clobber (reg:HI REG_Z))]
461 "can_create_pseudo_p()
462 && avr_mem_memx_p (operands[1])
463 && REG_P (XEXP (operands[1], 0))"
464 { gcc_unreachable(); }
466 [(clobber (const_int 0))]
468 rtx addr = XEXP (operands[1], 0);
469 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
470 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
471 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
474 /* Split the address to R21:Z */
475 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
476 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
478 /* Load with code from libgcc */
479 insn = emit_insn (gen_xload_<mode>_libgcc ());
480 set_mem_addr_space (SET_SRC (single_set (insn)), as);
482 /* Move to destination */
483 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
488 ;; Move value from address space memx to a register
489 ;; These insns must be prior to respective generic move insn.
491 (define_insn "xload_8"
492 [(set (match_operand:QI 0 "register_operand" "=&r,r")
493 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
495 "!avr_xload_libgcc_p (QImode)"
497 return avr_out_xload (insn, operands, NULL);
499 [(set_attr "length" "4,4")
500 (set_attr "adjust_len" "*,xload")
501 (set_attr "isa" "lpmx,lpm")
502 (set_attr "cc" "none")])
504 ;; R21:Z : 24-bit source address
505 ;; R22 : 1-4 byte output
509 ;; "xload_psi_libgcc"
512 (define_insn "xload_<mode>_libgcc"
513 [(set (reg:MOVMODE 22)
514 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
516 (clobber (reg:QI 21))
517 (clobber (reg:HI REG_Z))]
518 "avr_xload_libgcc_p (<MODE>mode)"
520 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
522 output_asm_insn ("%~call __xload_%0", &x_bytes);
525 [(set_attr "type" "xcall")
526 (set_attr "cc" "clobber")])
529 ;; General move expanders
536 (define_expand "mov<mode>"
537 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
538 (match_operand:MOVMODE 1 "general_operand" ""))]
541 rtx dest = operands[0];
542 rtx src = operands[1];
544 if (avr_mem_flash_p (dest))
547 /* One of the operands has to be in a register. */
548 if (!register_operand (dest, <MODE>mode)
549 && !(register_operand (src, <MODE>mode)
550 || src == CONST0_RTX (<MODE>mode)))
552 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
555 if (avr_mem_memx_p (src))
557 rtx addr = XEXP (src, 0);
560 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
562 if (!avr_xload_libgcc_p (<MODE>mode))
563 emit_insn (gen_xload8_A (dest, src));
565 emit_insn (gen_xload<mode>_A (dest, src));
570 /* For old devices without LPMx, prefer __flash loads per libcall. */
572 if (avr_load_libgcc_p (src))
574 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
575 force_reg (Pmode, XEXP (src, 0)));
577 emit_insn (gen_load_<mode>_libgcc ());
578 emit_move_insn (dest, gen_rtx_REG (<MODE>mode, 22));
582 /* ; FIXME: Hack around PR rtl-optimization/52543.
583 ; lower-subreg.c splits loads from the 16-bit address spaces which
584 ; causes code bloat because each load need his setting of RAMPZ.
585 ; Moreover, the split will happen in such a way that the loads don't
586 ; take advantage of POST_INC addressing. Thus, we use UNSPEC to
587 ; represent these loads instead. Notice that this is legitimate
588 ; because the memory content does not change: Loads from the same
589 ; address will yield the same value.
590 ; POST_INC addressing would make the addresses mode_dependent and could
591 ; work around that PR, too. However, notice that it is *not* legitimate
592 ; to expand to POST_INC at expand time: The following passes assert
593 ; that pre-/post-modify addressing is introduced by .auto_inc_dec and
594 ; does not exist before that pass. */
596 if (avr_mem_flash_p (src)
597 && (GET_MODE_SIZE (<MODE>mode) > 1
598 || MEM_ADDR_SPACE (src) != ADDR_SPACE_FLASH))
600 rtx xsegment = GEN_INT (avr_addrspace[MEM_ADDR_SPACE (src)].segment);
602 xsegment = const0_rtx;
603 if (xsegment != const0_rtx)
604 xsegment = force_reg (QImode, xsegment);
606 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
607 force_reg (Pmode, XEXP (src, 0)));
609 if ((CONST_INT_P (xsegment) && AVR_HAVE_LPMX)
610 || (REG_P (xsegment) && AVR_HAVE_ELPMX))
611 emit_insn (gen_load_<mode> (dest, xsegment));
613 emit_insn (gen_load_<mode>_clobber (dest, xsegment));
617 /* ; The only address-space for which we use plain MEM and reload
618 ; machinery are 1-byte loads from __flash. */
621 ;;========================================================================
623 ;; The last alternative (any immediate constant to any register) is
624 ;; very expensive. It should be optimized by peephole2 if a scratch
625 ;; register is available, but then that register could just as well be
626 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
627 ;; are call-saved registers, and most of LD_REGS are call-used registers,
628 ;; so this may still be a win for registers live across function calls.
630 (define_insn "movqi_insn"
631 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
632 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
633 "register_operand (operands[0], QImode)
634 || register_operand (operands[1], QImode)
635 || const0_rtx == operands[1]"
637 return output_movqi (insn, operands, NULL);
639 [(set_attr "length" "1,1,5,5,1,1,4")
640 (set_attr "adjust_len" "mov8")
641 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
643 ;; This is used in peephole2 to optimize loading immediate constants
644 ;; if a scratch register from LD_REGS happens to be available.
646 (define_insn "*reload_inqi"
647 [(set (match_operand:QI 0 "register_operand" "=l")
648 (match_operand:QI 1 "immediate_operand" "i"))
649 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
653 [(set_attr "length" "2")
654 (set_attr "cc" "none")])
657 [(match_scratch:QI 2 "d")
658 (set (match_operand:QI 0 "l_register_operand" "")
659 (match_operand:QI 1 "immediate_operand" ""))]
660 "(operands[1] != const0_rtx
661 && operands[1] != const1_rtx
662 && operands[1] != constm1_rtx)"
663 [(parallel [(set (match_dup 0) (match_dup 1))
664 (clobber (match_dup 2))])]
667 ;;============================================================================
668 ;; move word (16 bit)
670 ;; Move register $1 to the Stack Pointer register SP.
671 ;; This insn is emit during function prologue/epilogue generation.
672 ;; $2 = 0: We know that IRQs are off
673 ;; $2 = 1: We know that IRQs are on
674 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
675 ;; $2 = -1: We don't know anything about IRQ on/off
676 ;; Always write SP via unspec, see PR50063
678 (define_insn "movhi_sp_r"
679 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
680 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
681 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
685 out %B0,%B1\;out %A0,%A1
686 cli\;out %B0,%B1\;sei\;out %A0,%A1
687 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
689 out %A0,%A1\;out %B0,%B1"
690 [(set_attr "length" "2,4,5,1,2")
691 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
692 (set_attr "cc" "none")])
695 [(match_scratch:QI 2 "d")
696 (set (match_operand:HI 0 "l_register_operand" "")
697 (match_operand:HI 1 "immediate_operand" ""))]
698 "(operands[1] != const0_rtx
699 && operands[1] != constm1_rtx)"
700 [(parallel [(set (match_dup 0) (match_dup 1))
701 (clobber (match_dup 2))])]
704 ;; '*' because it is not used in rtl generation, only in above peephole
705 (define_insn "*reload_inhi"
706 [(set (match_operand:HI 0 "register_operand" "=r")
707 (match_operand:HI 1 "immediate_operand" "i"))
708 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
711 return output_reload_inhi (operands, operands[2], NULL);
713 [(set_attr "length" "4")
714 (set_attr "adjust_len" "reload_in16")
715 (set_attr "cc" "none")])
717 (define_insn "*movhi"
718 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
719 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
720 "register_operand (operands[0], HImode)
721 || register_operand (operands[1], HImode)
722 || const0_rtx == operands[1]"
724 return output_movhi (insn, operands, NULL);
726 [(set_attr "length" "2,2,6,7,2,6,5,2")
727 (set_attr "adjust_len" "mov16")
728 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
730 (define_peephole2 ; movw
731 [(set (match_operand:QI 0 "even_register_operand" "")
732 (match_operand:QI 1 "even_register_operand" ""))
733 (set (match_operand:QI 2 "odd_register_operand" "")
734 (match_operand:QI 3 "odd_register_operand" ""))]
736 && REGNO (operands[0]) == REGNO (operands[2]) - 1
737 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
738 [(set (match_dup 4) (match_dup 5))]
740 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
741 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
744 (define_peephole2 ; movw_r
745 [(set (match_operand:QI 0 "odd_register_operand" "")
746 (match_operand:QI 1 "odd_register_operand" ""))
747 (set (match_operand:QI 2 "even_register_operand" "")
748 (match_operand:QI 3 "even_register_operand" ""))]
750 && REGNO (operands[2]) == REGNO (operands[0]) - 1
751 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
752 [(set (match_dup 4) (match_dup 5))]
754 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
755 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
758 ;;==========================================================================
759 ;; xpointer move (24 bit)
761 (define_peephole2 ; *reload_inpsi
762 [(match_scratch:QI 2 "d")
763 (set (match_operand:PSI 0 "l_register_operand" "")
764 (match_operand:PSI 1 "immediate_operand" ""))
766 "operands[1] != const0_rtx
767 && operands[1] != constm1_rtx"
768 [(parallel [(set (match_dup 0)
770 (clobber (match_dup 2))])]
773 ;; '*' because it is not used in rtl generation.
774 (define_insn "*reload_inpsi"
775 [(set (match_operand:PSI 0 "register_operand" "=r")
776 (match_operand:PSI 1 "immediate_operand" "i"))
777 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
780 return avr_out_reload_inpsi (operands, operands[2], NULL);
782 [(set_attr "length" "6")
783 (set_attr "adjust_len" "reload_in24")
784 (set_attr "cc" "clobber")])
786 (define_insn "*movpsi"
787 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
788 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
789 "register_operand (operands[0], PSImode)
790 || register_operand (operands[1], PSImode)
791 || const0_rtx == operands[1]"
793 return avr_out_movpsi (insn, operands, NULL);
795 [(set_attr "length" "3,3,8,9,4,10")
796 (set_attr "adjust_len" "mov24")
797 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
799 ;;==========================================================================
800 ;; move double word (32 bit)
802 (define_peephole2 ; *reload_insi
803 [(match_scratch:QI 2 "d")
804 (set (match_operand:SI 0 "l_register_operand" "")
805 (match_operand:SI 1 "const_int_operand" ""))
807 "(operands[1] != const0_rtx
808 && operands[1] != constm1_rtx)"
809 [(parallel [(set (match_dup 0) (match_dup 1))
810 (clobber (match_dup 2))])]
813 ;; '*' because it is not used in rtl generation.
814 (define_insn "*reload_insi"
815 [(set (match_operand:SI 0 "register_operand" "=r")
816 (match_operand:SI 1 "const_int_operand" "n"))
817 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
820 return output_reload_insisf (operands, operands[2], NULL);
822 [(set_attr "length" "8")
823 (set_attr "adjust_len" "reload_in32")
824 (set_attr "cc" "clobber")])
827 (define_insn "*movsi"
828 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
829 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
830 "register_operand (operands[0], SImode)
831 || register_operand (operands[1], SImode)
832 || const0_rtx == operands[1]"
834 return output_movsisf (insn, operands, NULL);
836 [(set_attr "length" "4,4,8,9,4,10")
837 (set_attr "adjust_len" "mov32")
838 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
840 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
841 ;; move floating point numbers (32 bit)
843 (define_insn "*movsf"
844 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
845 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
846 "register_operand (operands[0], SFmode)
847 || register_operand (operands[1], SFmode)
848 || operands[1] == CONST0_RTX (SFmode)"
850 return output_movsisf (insn, operands, NULL);
852 [(set_attr "length" "4,4,8,9,4,10")
853 (set_attr "adjust_len" "mov32")
854 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
856 (define_peephole2 ; *reload_insf
857 [(match_scratch:QI 2 "d")
858 (set (match_operand:SF 0 "l_register_operand" "")
859 (match_operand:SF 1 "const_double_operand" ""))
861 "operands[1] != CONST0_RTX (SFmode)"
862 [(parallel [(set (match_dup 0)
864 (clobber (match_dup 2))])]
867 ;; '*' because it is not used in rtl generation.
868 (define_insn "*reload_insf"
869 [(set (match_operand:SF 0 "register_operand" "=r")
870 (match_operand:SF 1 "const_double_operand" "F"))
871 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
874 return output_reload_insisf (operands, operands[2], NULL);
876 [(set_attr "length" "8")
877 (set_attr "adjust_len" "reload_in32")
878 (set_attr "cc" "clobber")])
880 ;;=========================================================================
881 ;; move string (like memcpy)
883 (define_expand "movmemhi"
884 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
885 (match_operand:BLK 1 "memory_operand" ""))
886 (use (match_operand:HI 2 "const_int_operand" ""))
887 (use (match_operand:HI 3 "const_int_operand" ""))])]
890 if (avr_emit_movmemhi (operands))
896 (define_mode_attr MOVMEM_r_d [(QI "r")
899 ;; $0 : Address Space
900 ;; $1, $2 : Loop register
901 ;; R30 : source address
902 ;; R26 : destination address
906 (define_insn "movmem_<mode>"
907 [(set (mem:BLK (reg:HI REG_X))
908 (mem:BLK (reg:HI REG_Z)))
909 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
911 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
912 (clobber (reg:HI REG_X))
913 (clobber (reg:HI REG_Z))
914 (clobber (reg:QI LPM_REGNO))
915 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
918 return avr_out_movmem (insn, operands, NULL);
920 [(set_attr "adjust_len" "movmem")
921 (set_attr "cc" "clobber")])
924 ;; $0 : Address Space
925 ;; $1 : RAMPZ RAM address
926 ;; R24 : #bytes and loop register
927 ;; R23:Z : 24-bit source address
928 ;; R26 : 16-bit destination address
932 (define_insn "movmemx_<mode>"
933 [(set (mem:BLK (reg:HI REG_X))
934 (mem:BLK (lo_sum:PSI (reg:QI 23)
936 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
939 (clobber (reg:HI REG_X))
940 (clobber (reg:HI REG_Z))
941 (clobber (reg:QI LPM_REGNO))
942 (clobber (reg:HI 24))
943 (clobber (reg:QI 23))
944 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
946 "%~call __movmemx_<mode>"
947 [(set_attr "type" "xcall")
948 (set_attr "cc" "clobber")])
951 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
952 ;; memset (%0, %2, %1)
954 (define_expand "setmemhi"
955 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
956 (match_operand 2 "const_int_operand" ""))
957 (use (match_operand:HI 1 "const_int_operand" ""))
958 (use (match_operand:HI 3 "const_int_operand" ""))
959 (clobber (match_scratch:HI 4 ""))
960 (clobber (match_dup 5))])]
964 enum machine_mode mode;
966 /* If value to set is not zero, use the library routine. */
967 if (operands[2] != const0_rtx)
970 if (!CONST_INT_P (operands[1]))
973 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
974 operands[5] = gen_rtx_SCRATCH (mode);
975 operands[1] = copy_to_mode_reg (mode,
976 gen_int_mode (INTVAL (operands[1]), mode));
977 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
978 operands[0] = gen_rtx_MEM (BLKmode, addr0);
982 (define_insn "*clrmemqi"
983 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
985 (use (match_operand:QI 1 "register_operand" "r"))
986 (use (match_operand:QI 2 "const_int_operand" "n"))
987 (clobber (match_scratch:HI 3 "=0"))
988 (clobber (match_scratch:QI 4 "=&1"))]
990 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
991 [(set_attr "length" "3")
992 (set_attr "cc" "clobber")])
995 (define_insn "*clrmemhi"
996 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
998 (use (match_operand:HI 1 "register_operand" "!w,d"))
999 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1000 (clobber (match_scratch:HI 3 "=0,0"))
1001 (clobber (match_scratch:HI 4 "=&1,&1"))]
1004 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1005 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1006 [(set_attr "length" "3,4")
1007 (set_attr "cc" "clobber,clobber")])
1009 (define_expand "strlenhi"
1011 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1012 (match_operand:QI 2 "const_int_operand" "")
1013 (match_operand:HI 3 "immediate_operand" "")]
1016 (plus:HI (match_dup 4)
1018 (set (match_operand:HI 0 "register_operand" "")
1019 (minus:HI (match_dup 4)
1024 if (operands[2] != const0_rtx)
1026 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1027 operands[1] = gen_rtx_MEM (BLKmode, addr);
1029 operands[4] = gen_reg_rtx (HImode);
1032 (define_insn "*strlenhi"
1033 [(set (match_operand:HI 0 "register_operand" "=e")
1034 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1036 (match_operand:HI 2 "immediate_operand" "i")]
1039 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1040 [(set_attr "length" "3")
1041 (set_attr "cc" "clobber")])
1043 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1046 (define_insn "addqi3"
1047 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
1048 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
1049 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1058 [(set_attr "length" "1,1,1,1,2,2")
1059 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1062 (define_expand "addhi3"
1063 [(set (match_operand:HI 0 "register_operand" "")
1064 (plus:HI (match_operand:HI 1 "register_operand" "")
1065 (match_operand:HI 2 "nonmemory_operand" "")))]
1068 if (CONST_INT_P (operands[2]))
1070 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1072 if (can_create_pseudo_p()
1073 && !stack_register_operand (operands[0], HImode)
1074 && !stack_register_operand (operands[1], HImode)
1075 && !d_register_operand (operands[0], HImode)
1076 && !d_register_operand (operands[1], HImode))
1078 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1085 (define_insn "*addhi3_zero_extend"
1086 [(set (match_operand:HI 0 "register_operand" "=r")
1087 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1088 (match_operand:HI 2 "register_operand" "0")))]
1090 "add %A0,%1\;adc %B0,__zero_reg__"
1091 [(set_attr "length" "2")
1092 (set_attr "cc" "set_n")])
1094 (define_insn "*addhi3_zero_extend1"
1095 [(set (match_operand:HI 0 "register_operand" "=r")
1096 (plus:HI (match_operand:HI 1 "register_operand" "0")
1097 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1099 "add %A0,%2\;adc %B0,__zero_reg__"
1100 [(set_attr "length" "2")
1101 (set_attr "cc" "set_n")])
1103 (define_insn "*addhi3.sign_extend1"
1104 [(set (match_operand:HI 0 "register_operand" "=r")
1105 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1106 (match_operand:HI 2 "register_operand" "0")))]
1109 return reg_overlap_mentioned_p (operands[0], operands[1])
1110 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1111 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1113 [(set_attr "length" "5")
1114 (set_attr "cc" "clobber")])
1116 (define_insn "*addhi3_sp"
1117 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1118 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1119 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1122 return avr_out_addto_sp (operands, NULL);
1124 [(set_attr "length" "6")
1125 (set_attr "adjust_len" "addto_sp")])
1127 (define_insn "*addhi3"
1128 [(set (match_operand:HI 0 "register_operand" "=r,d,!w,d")
1129 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0 ,0")
1130 (match_operand:HI 2 "nonmemory_operand" "r,s,IJ,n")))]
1133 static const char * const asm_code[] =
1135 "add %A0,%A2\;adc %B0,%B2",
1136 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1141 if (*asm_code[which_alternative])
1142 return asm_code[which_alternative];
1144 return avr_out_plus_noclobber (operands, NULL, NULL);
1146 [(set_attr "length" "2,2,2,2")
1147 (set_attr "adjust_len" "*,*,out_plus_noclobber,out_plus_noclobber")
1148 (set_attr "cc" "set_n,set_czn,out_plus_noclobber,out_plus_noclobber")])
1150 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1151 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1152 ;; itself because that insn is special to reload.
1154 (define_peephole2 ; addhi3_clobber
1155 [(set (match_operand:HI 0 "d_register_operand" "")
1156 (match_operand:HI 1 "const_int_operand" ""))
1157 (set (match_operand:HI 2 "l_register_operand" "")
1158 (plus:HI (match_dup 2)
1160 "peep2_reg_dead_p (2, operands[0])"
1161 [(parallel [(set (match_dup 2)
1162 (plus:HI (match_dup 2)
1164 (clobber (match_dup 3))])]
1166 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1169 ;; Same, but with reload to NO_LD_REGS
1170 ;; Combine *reload_inhi with *addhi3
1172 (define_peephole2 ; addhi3_clobber
1173 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1174 (match_operand:HI 1 "const_int_operand" ""))
1175 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1176 (set (match_operand:HI 3 "l_register_operand" "")
1177 (plus:HI (match_dup 3)
1179 "peep2_reg_dead_p (2, operands[0])"
1180 [(parallel [(set (match_dup 3)
1181 (plus:HI (match_dup 3)
1183 (clobber (match_dup 2))])])
1185 (define_insn "addhi3_clobber"
1186 [(set (match_operand:HI 0 "register_operand" "=!w,d,r")
1187 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1188 (match_operand:HI 2 "const_int_operand" "IJ,n,n")))
1189 (clobber (match_scratch:QI 3 "=X,X,&d"))]
1192 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1194 return avr_out_plus (operands, NULL, NULL);
1196 [(set_attr "length" "4")
1197 (set_attr "adjust_len" "out_plus")
1198 (set_attr "cc" "out_plus")])
1201 (define_insn "addsi3"
1202 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1203 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1204 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1205 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1208 static const char * const asm_code[] =
1210 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1211 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1216 if (*asm_code[which_alternative])
1217 return asm_code[which_alternative];
1219 return avr_out_plus (operands, NULL, NULL);
1221 [(set_attr "length" "4,4,4,8")
1222 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1223 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1225 (define_insn "*addpsi3_zero_extend.qi"
1226 [(set (match_operand:PSI 0 "register_operand" "=r")
1227 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1228 (match_operand:PSI 2 "register_operand" "0")))]
1230 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1231 [(set_attr "length" "3")
1232 (set_attr "cc" "set_n")])
1234 (define_insn "*addpsi3_zero_extend.hi"
1235 [(set (match_operand:PSI 0 "register_operand" "=r")
1236 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1237 (match_operand:PSI 2 "register_operand" "0")))]
1239 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1240 [(set_attr "length" "3")
1241 (set_attr "cc" "set_n")])
1243 (define_insn "*addpsi3_sign_extend.hi"
1244 [(set (match_operand:PSI 0 "register_operand" "=r")
1245 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1246 (match_operand:PSI 2 "register_operand" "0")))]
1248 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1249 [(set_attr "length" "5")
1250 (set_attr "cc" "set_n")])
1252 (define_insn "*addsi3_zero_extend"
1253 [(set (match_operand:SI 0 "register_operand" "=r")
1254 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1255 (match_operand:SI 2 "register_operand" "0")))]
1257 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1258 [(set_attr "length" "4")
1259 (set_attr "cc" "set_n")])
1261 (define_insn "*addsi3_zero_extend.hi"
1262 [(set (match_operand:SI 0 "register_operand" "=r")
1263 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1264 (match_operand:SI 2 "register_operand" "0")))]
1266 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1267 [(set_attr "length" "4")
1268 (set_attr "cc" "set_n")])
1270 (define_insn "addpsi3"
1271 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1272 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1273 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1274 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1277 static const char * const asm_code[] =
1279 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1280 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1285 if (*asm_code[which_alternative])
1286 return asm_code[which_alternative];
1288 return avr_out_plus (operands, NULL, NULL);
1290 [(set_attr "length" "3,3,3,6")
1291 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1292 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1294 (define_insn "subpsi3"
1295 [(set (match_operand:PSI 0 "register_operand" "=r")
1296 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1297 (match_operand:PSI 2 "register_operand" "r")))]
1299 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1300 [(set_attr "length" "3")
1301 (set_attr "cc" "set_czn")])
1303 (define_insn "*subpsi3_zero_extend.qi"
1304 [(set (match_operand:PSI 0 "register_operand" "=r")
1305 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1306 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1308 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1309 [(set_attr "length" "3")
1310 (set_attr "cc" "set_czn")])
1312 (define_insn "*subpsi3_zero_extend.hi"
1313 [(set (match_operand:PSI 0 "register_operand" "=r")
1314 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1315 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1317 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1318 [(set_attr "length" "3")
1319 (set_attr "cc" "set_czn")])
1321 (define_insn "*subpsi3_sign_extend.hi"
1322 [(set (match_operand:PSI 0 "register_operand" "=r")
1323 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1324 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1326 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1327 [(set_attr "length" "5")
1328 (set_attr "cc" "set_czn")])
1330 ;-----------------------------------------------------------------------------
1332 (define_insn "subqi3"
1333 [(set (match_operand:QI 0 "register_operand" "=r,d")
1334 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1335 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1340 [(set_attr "length" "1,1")
1341 (set_attr "cc" "set_czn,set_czn")])
1343 (define_insn "subhi3"
1344 [(set (match_operand:HI 0 "register_operand" "=r,d")
1345 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1346 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1349 sub %A0,%A2\;sbc %B0,%B2
1350 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1351 [(set_attr "length" "2,2")
1352 (set_attr "cc" "set_czn,set_czn")])
1354 (define_insn "*subhi3_zero_extend1"
1355 [(set (match_operand:HI 0 "register_operand" "=r")
1356 (minus:HI (match_operand:HI 1 "register_operand" "0")
1357 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1359 "sub %A0,%2\;sbc %B0,__zero_reg__"
1360 [(set_attr "length" "2")
1361 (set_attr "cc" "set_czn")])
1363 (define_insn "*subhi3.sign_extend2"
1364 [(set (match_operand:HI 0 "register_operand" "=r")
1365 (minus:HI (match_operand:HI 1 "register_operand" "0")
1366 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1369 return reg_overlap_mentioned_p (operands[0], operands[2])
1370 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1371 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1373 [(set_attr "length" "5")
1374 (set_attr "cc" "clobber")])
1376 (define_insn "subsi3"
1377 [(set (match_operand:SI 0 "register_operand" "=r")
1378 (minus:SI (match_operand:SI 1 "register_operand" "0")
1379 (match_operand:SI 2 "register_operand" "r")))]
1381 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1382 [(set_attr "length" "4")
1383 (set_attr "cc" "set_czn")])
1385 (define_insn "*subsi3_zero_extend"
1386 [(set (match_operand:SI 0 "register_operand" "=r")
1387 (minus:SI (match_operand:SI 1 "register_operand" "0")
1388 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1390 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1391 [(set_attr "length" "4")
1392 (set_attr "cc" "set_czn")])
1394 (define_insn "*subsi3_zero_extend.hi"
1395 [(set (match_operand:SI 0 "register_operand" "=r")
1396 (minus:SI (match_operand:SI 1 "register_operand" "0")
1397 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1399 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1400 [(set_attr "length" "4")
1401 (set_attr "cc" "set_czn")])
1403 ;******************************************************************************
1406 (define_expand "mulqi3"
1407 [(set (match_operand:QI 0 "register_operand" "")
1408 (mult:QI (match_operand:QI 1 "register_operand" "")
1409 (match_operand:QI 2 "register_operand" "")))]
1414 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1419 (define_insn "*mulqi3_enh"
1420 [(set (match_operand:QI 0 "register_operand" "=r")
1421 (mult:QI (match_operand:QI 1 "register_operand" "r")
1422 (match_operand:QI 2 "register_operand" "r")))]
1427 [(set_attr "length" "3")
1428 (set_attr "cc" "clobber")])
1430 (define_expand "mulqi3_call"
1431 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1432 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1433 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1434 (clobber (reg:QI 22))])
1435 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1439 (define_insn "*mulqi3_call"
1440 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1441 (clobber (reg:QI 22))]
1444 [(set_attr "type" "xcall")
1445 (set_attr "cc" "clobber")])
1447 ;; "umulqi3_highpart"
1448 ;; "smulqi3_highpart"
1449 (define_insn "<extend_su>mulqi3_highpart"
1450 [(set (match_operand:QI 0 "register_operand" "=r")
1452 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1453 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1456 "mul<extend_s> %1,%2
1459 [(set_attr "length" "3")
1460 (set_attr "cc" "clobber")])
1463 ;; Used when expanding div or mod inline for some special values
1464 (define_insn "*subqi3.ashiftrt7"
1465 [(set (match_operand:QI 0 "register_operand" "=r")
1466 (minus:QI (match_operand:QI 1 "register_operand" "0")
1467 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1471 [(set_attr "length" "2")
1472 (set_attr "cc" "clobber")])
1474 (define_insn "*addqi3.lt0"
1475 [(set (match_operand:QI 0 "register_operand" "=r")
1476 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1478 (match_operand:QI 2 "register_operand" "0")))]
1481 [(set_attr "length" "2")
1482 (set_attr "cc" "clobber")])
1484 (define_insn "*addhi3.lt0"
1485 [(set (match_operand:HI 0 "register_operand" "=w,r")
1486 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1488 (match_operand:HI 2 "register_operand" "0,0")))
1489 (clobber (match_scratch:QI 3 "=X,&1"))]
1492 sbrc %1,7\;adiw %0,1
1493 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1494 [(set_attr "length" "2,3")
1495 (set_attr "cc" "clobber")])
1497 (define_insn "*addpsi3.lt0"
1498 [(set (match_operand:PSI 0 "register_operand" "=r")
1499 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1501 (match_operand:PSI 2 "register_operand" "0")))]
1503 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1504 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1505 [(set_attr "length" "5")
1506 (set_attr "cc" "clobber")])
1508 (define_insn "*addsi3.lt0"
1509 [(set (match_operand:SI 0 "register_operand" "=r")
1510 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1512 (match_operand:SI 2 "register_operand" "0")))]
1514 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1515 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1516 [(set_attr "length" "6")
1517 (set_attr "cc" "clobber")])
1522 (define_insn "<extend_u>mulqihi3"
1523 [(set (match_operand:HI 0 "register_operand" "=r")
1524 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1525 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1527 "mul<extend_s> %1,%2
1530 [(set_attr "length" "3")
1531 (set_attr "cc" "clobber")])
1533 (define_insn "usmulqihi3"
1534 [(set (match_operand:HI 0 "register_operand" "=r")
1535 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1536 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1541 [(set_attr "length" "3")
1542 (set_attr "cc" "clobber")])
1544 ;; Above insn is not canonicalized by insn combine, so here is a version with
1545 ;; operands swapped.
1547 (define_insn "*sumulqihi3"
1548 [(set (match_operand:HI 0 "register_operand" "=r")
1549 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1550 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1555 [(set_attr "length" "3")
1556 (set_attr "cc" "clobber")])
1558 ;; One-extend operand 1
1560 (define_insn "*osmulqihi3"
1561 [(set (match_operand:HI 0 "register_operand" "=&r")
1562 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1563 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1569 [(set_attr "length" "4")
1570 (set_attr "cc" "clobber")])
1572 (define_insn "*oumulqihi3"
1573 [(set (match_operand:HI 0 "register_operand" "=&r")
1574 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1575 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1581 [(set_attr "length" "4")
1582 (set_attr "cc" "clobber")])
1584 ;******************************************************************************
1585 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1586 ;******************************************************************************
1588 (define_insn "*maddqi4"
1589 [(set (match_operand:QI 0 "register_operand" "=r")
1590 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1591 (match_operand:QI 2 "register_operand" "r"))
1592 (match_operand:QI 3 "register_operand" "0")))]
1598 [(set_attr "length" "4")
1599 (set_attr "cc" "clobber")])
1601 (define_insn "*msubqi4"
1602 [(set (match_operand:QI 0 "register_operand" "=r")
1603 (minus:QI (match_operand:QI 3 "register_operand" "0")
1604 (mult:QI (match_operand:QI 1 "register_operand" "r")
1605 (match_operand:QI 2 "register_operand" "r"))))]
1610 [(set_attr "length" "4")
1611 (set_attr "cc" "clobber")])
1613 (define_insn_and_split "*maddqi4.const"
1614 [(set (match_operand:QI 0 "register_operand" "=r")
1615 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1616 (match_operand:QI 2 "const_int_operand" "n"))
1617 (match_operand:QI 3 "register_operand" "0")))
1618 (clobber (match_scratch:QI 4 "=&d"))]
1621 "&& reload_completed"
1626 (plus:QI (mult:QI (match_dup 1)
1631 (define_insn_and_split "*msubqi4.const"
1632 [(set (match_operand:QI 0 "register_operand" "=r")
1633 (minus:QI (match_operand:QI 3 "register_operand" "0")
1634 (mult:QI (match_operand:QI 1 "register_operand" "r")
1635 (match_operand:QI 2 "const_int_operand" "n"))))
1636 (clobber (match_scratch:QI 4 "=&d"))]
1639 "&& reload_completed"
1644 (minus:QI (match_dup 3)
1645 (mult:QI (match_dup 1)
1650 ;******************************************************************************
1651 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1652 ;******************************************************************************
1654 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1657 ;; int foo (unsigned char z)
1659 ;; extern int aInt[];
1660 ;; return aInt[3*z+2];
1663 ;; because the constant +4 then is added explicitely instead of consuming it
1664 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1665 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1666 ;; The implementational effort is the same so we are fine with that approach.
1671 (define_insn "*<extend_u>maddqihi4"
1672 [(set (match_operand:HI 0 "register_operand" "=r")
1673 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1674 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1675 (match_operand:HI 3 "register_operand" "0")))]
1678 "mul<extend_s> %1,%2
1682 [(set_attr "length" "4")
1683 (set_attr "cc" "clobber")])
1687 (define_insn "*<extend_u>msubqihi4"
1688 [(set (match_operand:HI 0 "register_operand" "=r")
1689 (minus:HI (match_operand:HI 3 "register_operand" "0")
1690 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1691 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1693 "mul<extend_s> %1,%2
1697 [(set_attr "length" "4")
1698 (set_attr "cc" "clobber")])
1702 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1703 [(set (match_operand:HI 0 "register_operand" "=r")
1704 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1705 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1706 (match_operand:HI 3 "register_operand" "0")))]
1709 && <any_extend:CODE> != <any_extend2:CODE>"
1711 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1712 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1714 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1716 [(set_attr "length" "4")
1717 (set_attr "cc" "clobber")])
1721 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1722 [(set (match_operand:HI 0 "register_operand" "=r")
1723 (minus:HI (match_operand:HI 3 "register_operand" "0")
1724 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1725 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1728 && <any_extend:CODE> != <any_extend2:CODE>"
1730 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1731 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1733 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1735 [(set_attr "length" "4")
1736 (set_attr "cc" "clobber")])
1738 ;; Handle small constants
1740 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1741 ;; This is shorter, faster than MUL and has lower register pressure.
1743 (define_insn_and_split "*umaddqihi4.2"
1744 [(set (match_operand:HI 0 "register_operand" "=r")
1745 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1747 (match_operand:HI 2 "register_operand" "r")))]
1749 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1750 { gcc_unreachable(); }
1754 ; *addhi3_zero_extend
1756 (plus:HI (zero_extend:HI (match_dup 1))
1758 ; *addhi3_zero_extend
1760 (plus:HI (zero_extend:HI (match_dup 1))
1763 ;; "umaddqihi4.uconst"
1764 ;; "maddqihi4.sconst"
1765 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1766 [(set (match_operand:HI 0 "register_operand" "=r")
1767 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1768 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1769 (match_operand:HI 3 "register_operand" "0")))
1770 (clobber (match_scratch:QI 4 "=&d"))]
1773 "&& reload_completed"
1776 ; *umaddqihi4 resp. *maddqihi4
1778 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1779 (any_extend:HI (match_dup 4)))
1782 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1785 ;; "*umsubqihi4.uconst"
1786 ;; "*msubqihi4.sconst"
1787 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1788 [(set (match_operand:HI 0 "register_operand" "=r")
1789 (minus:HI (match_operand:HI 3 "register_operand" "0")
1790 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1791 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1792 (clobber (match_scratch:QI 4 "=&d"))]
1795 "&& reload_completed"
1798 ; *umsubqihi4 resp. *msubqihi4
1800 (minus:HI (match_dup 3)
1801 (mult:HI (any_extend:HI (match_dup 1))
1802 (any_extend:HI (match_dup 4)))))]
1804 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1807 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1808 ;; for MULT with power of 2 and skips trying MULT insn above.
1810 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1811 [(set (match_operand:HI 0 "register_operand" "=r")
1812 (minus:HI (match_operand:HI 3 "register_operand" "0")
1813 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1814 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1815 (clobber (match_scratch:QI 4 "=&d"))]
1818 "&& reload_completed"
1823 (minus:HI (match_dup 3)
1824 (mult:HI (zero_extend:HI (match_dup 1))
1825 (zero_extend:HI (match_dup 4)))))]
1827 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1830 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1831 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1832 ;; because this would require an extra pattern for just one value.
1834 (define_insn_and_split "*msubqihi4.sconst.ashift"
1835 [(set (match_operand:HI 0 "register_operand" "=r")
1836 (minus:HI (match_operand:HI 3 "register_operand" "0")
1837 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1838 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1839 (clobber (match_scratch:QI 4 "=&d"))]
1842 "&& reload_completed"
1847 (minus:HI (match_dup 3)
1848 (mult:HI (sign_extend:HI (match_dup 1))
1849 (sign_extend:HI (match_dup 4)))))]
1851 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1854 ;; For signed/unsigned combinations that require narrow constraint "a"
1855 ;; just provide a pattern if signed/unsigned combination is actually needed.
1857 (define_insn_and_split "*sumaddqihi4.uconst"
1858 [(set (match_operand:HI 0 "register_operand" "=r")
1859 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1860 (match_operand:HI 2 "u8_operand" "M"))
1861 (match_operand:HI 3 "register_operand" "0")))
1862 (clobber (match_scratch:QI 4 "=&a"))]
1864 && !s8_operand (operands[2], VOIDmode)"
1866 "&& reload_completed"
1871 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1872 (zero_extend:HI (match_dup 4)))
1875 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1878 (define_insn_and_split "*sumsubqihi4.uconst"
1879 [(set (match_operand:HI 0 "register_operand" "=r")
1880 (minus:HI (match_operand:HI 3 "register_operand" "0")
1881 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1882 (match_operand:HI 2 "u8_operand" "M"))))
1883 (clobber (match_scratch:QI 4 "=&a"))]
1885 && !s8_operand (operands[2], VOIDmode)"
1887 "&& reload_completed"
1892 (minus:HI (match_dup 3)
1893 (mult:HI (sign_extend:HI (match_dup 1))
1894 (zero_extend:HI (match_dup 4)))))]
1896 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1899 ;******************************************************************************
1900 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1901 ;******************************************************************************
1903 ;; "*muluqihi3.uconst"
1904 ;; "*mulsqihi3.sconst"
1905 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1906 [(set (match_operand:HI 0 "register_operand" "=r")
1907 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1908 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1909 (clobber (match_scratch:QI 3 "=&d"))]
1912 "&& reload_completed"
1915 ; umulqihi3 resp. mulqihi3
1917 (mult:HI (any_extend:HI (match_dup 1))
1918 (any_extend:HI (match_dup 3))))]
1920 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1923 (define_insn_and_split "*muluqihi3.sconst"
1924 [(set (match_operand:HI 0 "register_operand" "=r")
1925 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1926 (match_operand:HI 2 "s8_operand" "n")))
1927 (clobber (match_scratch:QI 3 "=&a"))]
1930 "&& reload_completed"
1935 (mult:HI (zero_extend:HI (match_dup 1))
1936 (sign_extend:HI (match_dup 3))))]
1938 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1941 (define_insn_and_split "*mulsqihi3.uconst"
1942 [(set (match_operand:HI 0 "register_operand" "=r")
1943 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1944 (match_operand:HI 2 "u8_operand" "M")))
1945 (clobber (match_scratch:QI 3 "=&a"))]
1948 "&& reload_completed"
1953 (mult:HI (zero_extend:HI (match_dup 3))
1954 (sign_extend:HI (match_dup 1))))]
1956 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1959 (define_insn_and_split "*mulsqihi3.oconst"
1960 [(set (match_operand:HI 0 "register_operand" "=&r")
1961 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1962 (match_operand:HI 2 "o8_operand" "n")))
1963 (clobber (match_scratch:QI 3 "=&a"))]
1966 "&& reload_completed"
1971 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1972 (sign_extend:HI (match_dup 1))))]
1974 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1977 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1978 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1979 ;; at that time. Fix that.
1981 (define_insn "*ashiftqihi2.signx.1"
1982 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1983 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1987 lsl %A0\;sbc %B0,%B0
1988 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1989 [(set_attr "length" "2,3")
1990 (set_attr "cc" "clobber")])
1992 (define_insn_and_split "*ashifthi3.signx.const"
1993 [(set (match_operand:HI 0 "register_operand" "=r")
1994 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1995 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1996 (clobber (match_scratch:QI 3 "=&d"))]
1999 "&& reload_completed"
2004 (mult:HI (sign_extend:HI (match_dup 1))
2005 (sign_extend:HI (match_dup 3))))]
2007 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2010 (define_insn_and_split "*ashifthi3.signx.const7"
2011 [(set (match_operand:HI 0 "register_operand" "=r")
2012 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2014 (clobber (match_scratch:QI 2 "=&a"))]
2017 "&& reload_completed"
2022 (mult:HI (zero_extend:HI (match_dup 2))
2023 (sign_extend:HI (match_dup 1))))]
2025 operands[3] = gen_int_mode (1 << 7, QImode);
2028 (define_insn_and_split "*ashifthi3.zerox.const"
2029 [(set (match_operand:HI 0 "register_operand" "=r")
2030 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2031 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2032 (clobber (match_scratch:QI 3 "=&d"))]
2035 "&& reload_completed"
2040 (mult:HI (zero_extend:HI (match_dup 1))
2041 (zero_extend:HI (match_dup 3))))]
2043 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2046 ;******************************************************************************
2047 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2048 ;******************************************************************************
2050 (define_insn "mulsqihi3"
2051 [(set (match_operand:HI 0 "register_operand" "=&r")
2052 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2053 (match_operand:HI 2 "register_operand" "a")))]
2060 [(set_attr "length" "5")
2061 (set_attr "cc" "clobber")])
2063 (define_insn "muluqihi3"
2064 [(set (match_operand:HI 0 "register_operand" "=&r")
2065 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2066 (match_operand:HI 2 "register_operand" "r")))]
2073 [(set_attr "length" "5")
2074 (set_attr "cc" "clobber")])
2076 ;; one-extend operand 1
2078 (define_insn "muloqihi3"
2079 [(set (match_operand:HI 0 "register_operand" "=&r")
2080 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2081 (match_operand:HI 2 "register_operand" "r")))]
2089 [(set_attr "length" "6")
2090 (set_attr "cc" "clobber")])
2092 ;******************************************************************************
2094 (define_expand "mulhi3"
2095 [(set (match_operand:HI 0 "register_operand" "")
2096 (mult:HI (match_operand:HI 1 "register_operand" "")
2097 (match_operand:HI 2 "register_or_s9_operand" "")))]
2102 if (!register_operand (operands[2], HImode))
2103 operands[2] = force_reg (HImode, operands[2]);
2105 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2109 /* For small constants we can do better by extending them on the fly.
2110 The constant can be loaded in one instruction and the widening
2111 multiplication is shorter. First try the unsigned variant because it
2112 allows constraint "d" instead of "a" for the signed version. */
2114 if (s9_operand (operands[2], HImode))
2116 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2118 if (u8_operand (operands[2], HImode))
2120 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2122 else if (s8_operand (operands[2], HImode))
2124 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2128 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2134 if (!register_operand (operands[2], HImode))
2135 operands[2] = force_reg (HImode, operands[2]);
2138 (define_insn "*mulhi3_enh"
2139 [(set (match_operand:HI 0 "register_operand" "=&r")
2140 (mult:HI (match_operand:HI 1 "register_operand" "r")
2141 (match_operand:HI 2 "register_operand" "r")))]
2144 return REGNO (operands[1]) == REGNO (operands[2])
2145 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2146 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2148 [(set_attr "length" "7")
2149 (set_attr "cc" "clobber")])
2151 (define_expand "mulhi3_call"
2152 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2153 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2154 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2155 (clobber (reg:HI 22))
2156 (clobber (reg:QI 21))])
2157 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2161 (define_insn "*mulhi3_call"
2162 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2163 (clobber (reg:HI 22))
2164 (clobber (reg:QI 21))]
2167 [(set_attr "type" "xcall")
2168 (set_attr "cc" "clobber")])
2170 ;; To support widening multiplication with constant we postpone
2171 ;; expanding to the implicit library call until post combine and
2172 ;; prior to register allocation. Clobber all hard registers that
2173 ;; might be used by the (widening) multiply until it is split and
2174 ;; it's final register footprint is worked out.
2176 (define_expand "mulsi3"
2177 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2178 (mult:SI (match_operand:SI 1 "register_operand" "")
2179 (match_operand:SI 2 "nonmemory_operand" "")))
2180 (clobber (reg:HI 26))
2181 (clobber (reg:DI 18))])]
2184 if (u16_operand (operands[2], SImode))
2186 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2187 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2191 if (o16_operand (operands[2], SImode))
2193 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2194 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2199 (define_insn_and_split "*mulsi3"
2200 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2201 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2202 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2203 (clobber (reg:HI 26))
2204 (clobber (reg:DI 18))]
2205 "AVR_HAVE_MUL && !reload_completed"
2206 { gcc_unreachable(); }
2212 (parallel [(set (reg:SI 22)
2213 (mult:SI (reg:SI 22)
2215 (clobber (reg:HI 26))])
2219 if (u16_operand (operands[2], SImode))
2221 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2222 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2226 if (o16_operand (operands[2], SImode))
2228 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2229 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2236 (define_insn_and_split "mulu<mode>si3"
2237 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2238 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2239 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2240 (clobber (reg:HI 26))
2241 (clobber (reg:DI 18))]
2242 "AVR_HAVE_MUL && !reload_completed"
2243 { gcc_unreachable(); }
2250 (mult:SI (zero_extend:SI (reg:HI 26))
2255 /* Do the QI -> HI extension explicitely before the multiplication. */
2256 /* Do the HI -> SI extension implicitely and after the multiplication. */
2258 if (QImode == <MODE>mode)
2259 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2261 if (u16_operand (operands[2], SImode))
2263 operands[1] = force_reg (HImode, operands[1]);
2264 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2265 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2272 (define_insn_and_split "muls<mode>si3"
2273 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2274 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2275 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2276 (clobber (reg:HI 26))
2277 (clobber (reg:DI 18))]
2278 "AVR_HAVE_MUL && !reload_completed"
2279 { gcc_unreachable(); }
2286 (mult:SI (sign_extend:SI (reg:HI 26))
2291 /* Do the QI -> HI extension explicitely before the multiplication. */
2292 /* Do the HI -> SI extension implicitely and after the multiplication. */
2294 if (QImode == <MODE>mode)
2295 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2297 if (u16_operand (operands[2], SImode)
2298 || s16_operand (operands[2], SImode))
2300 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2302 operands[1] = force_reg (HImode, operands[1]);
2304 if (u16_operand (operands[2], SImode))
2305 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2307 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2313 ;; One-extend operand 1
2315 (define_insn_and_split "mulohisi3"
2316 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2317 (mult:SI (not:SI (zero_extend:SI
2318 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2319 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2320 (clobber (reg:HI 26))
2321 (clobber (reg:DI 18))]
2322 "AVR_HAVE_MUL && !reload_completed"
2323 { gcc_unreachable(); }
2330 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2338 (define_expand "<extend_u>mulhisi3"
2339 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2340 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2341 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2342 (clobber (reg:HI 26))
2343 (clobber (reg:DI 18))])]
2347 (define_expand "usmulhisi3"
2348 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2349 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2350 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2351 (clobber (reg:HI 26))
2352 (clobber (reg:DI 18))])]
2356 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2357 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2358 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2359 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2360 (define_insn_and_split
2361 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2362 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2363 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2364 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2365 (clobber (reg:HI 26))
2366 (clobber (reg:DI 18))]
2367 "AVR_HAVE_MUL && !reload_completed"
2368 { gcc_unreachable(); }
2375 (mult:SI (match_dup 3)
2380 rtx xop1 = operands[1];
2381 rtx xop2 = operands[2];
2383 /* Do the QI -> HI extension explicitely before the multiplication. */
2384 /* Do the HI -> SI extension implicitely and after the multiplication. */
2386 if (QImode == <QIHI:MODE>mode)
2387 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2389 if (QImode == <QIHI2:MODE>mode)
2390 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2392 if (<any_extend:CODE> == <any_extend2:CODE>
2393 || <any_extend:CODE> == ZERO_EXTEND)
2397 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2398 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2402 /* <any_extend:CODE> = SIGN_EXTEND */
2403 /* <any_extend2:CODE> = ZERO_EXTEND */
2407 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2408 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2412 ;; "smulhi3_highpart"
2413 ;; "umulhi3_highpart"
2414 (define_expand "<extend_su>mulhi3_highpart"
2416 (match_operand:HI 1 "nonmemory_operand" ""))
2418 (match_operand:HI 2 "nonmemory_operand" ""))
2419 (parallel [(set (reg:HI 24)
2420 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2421 (any_extend:SI (reg:HI 26)))
2423 (clobber (reg:HI 22))])
2424 (set (match_operand:HI 0 "register_operand" "")
2430 (define_insn "*mulsi3_call"
2432 (mult:SI (reg:SI 22)
2434 (clobber (reg:HI 26))]
2437 [(set_attr "type" "xcall")
2438 (set_attr "cc" "clobber")])
2441 ;; "*umulhisi3_call"
2442 (define_insn "*<extend_u>mulhisi3_call"
2444 (mult:SI (any_extend:SI (reg:HI 18))
2445 (any_extend:SI (reg:HI 26))))]
2447 "%~call __<extend_u>mulhisi3"
2448 [(set_attr "type" "xcall")
2449 (set_attr "cc" "clobber")])
2451 ;; "*umulhi3_highpart_call"
2452 ;; "*smulhi3_highpart_call"
2453 (define_insn "*<extend_su>mulhi3_highpart_call"
2455 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2456 (any_extend:SI (reg:HI 26)))
2458 (clobber (reg:HI 22))]
2460 "%~call __<extend_u>mulhisi3"
2461 [(set_attr "type" "xcall")
2462 (set_attr "cc" "clobber")])
2464 (define_insn "*usmulhisi3_call"
2466 (mult:SI (zero_extend:SI (reg:HI 18))
2467 (sign_extend:SI (reg:HI 26))))]
2469 "%~call __usmulhisi3"
2470 [(set_attr "type" "xcall")
2471 (set_attr "cc" "clobber")])
2473 (define_insn "*mul<extend_su>hisi3_call"
2475 (mult:SI (any_extend:SI (reg:HI 26))
2478 "%~call __mul<extend_su>hisi3"
2479 [(set_attr "type" "xcall")
2480 (set_attr "cc" "clobber")])
2482 (define_insn "*mulohisi3_call"
2484 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2487 "%~call __mulohisi3"
2488 [(set_attr "type" "xcall")
2489 (set_attr "cc" "clobber")])
2491 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2494 ;; Generate lib1funcs.S calls ourselves, because:
2495 ;; - we know exactly which registers are clobbered (for QI and HI
2496 ;; modes, some of the call-used registers are preserved)
2497 ;; - we get both the quotient and the remainder at no extra cost
2498 ;; - we split the patterns only after the first CSE passes because
2499 ;; CSE has problems to operate on hard regs.
2501 (define_insn_and_split "divmodqi4"
2502 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2503 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2504 (match_operand:QI 2 "pseudo_register_operand" "")))
2505 (set (match_operand:QI 3 "pseudo_register_operand" "")
2506 (mod:QI (match_dup 1) (match_dup 2)))
2507 (clobber (reg:QI 22))
2508 (clobber (reg:QI 23))
2509 (clobber (reg:QI 24))
2510 (clobber (reg:QI 25))])]
2512 "this divmodqi4 pattern should have been splitted;"
2514 [(set (reg:QI 24) (match_dup 1))
2515 (set (reg:QI 22) (match_dup 2))
2516 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2517 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2518 (clobber (reg:QI 22))
2519 (clobber (reg:QI 23))])
2520 (set (match_dup 0) (reg:QI 24))
2521 (set (match_dup 3) (reg:QI 25))]
2524 (define_insn "*divmodqi4_call"
2525 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2526 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2527 (clobber (reg:QI 22))
2528 (clobber (reg:QI 23))]
2530 "%~call __divmodqi4"
2531 [(set_attr "type" "xcall")
2532 (set_attr "cc" "clobber")])
2534 (define_insn_and_split "udivmodqi4"
2535 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2536 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2537 (match_operand:QI 2 "pseudo_register_operand" "")))
2538 (set (match_operand:QI 3 "pseudo_register_operand" "")
2539 (umod:QI (match_dup 1) (match_dup 2)))
2540 (clobber (reg:QI 22))
2541 (clobber (reg:QI 23))
2542 (clobber (reg:QI 24))
2543 (clobber (reg:QI 25))])]
2545 "this udivmodqi4 pattern should have been splitted;"
2547 [(set (reg:QI 24) (match_dup 1))
2548 (set (reg:QI 22) (match_dup 2))
2549 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2550 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2551 (clobber (reg:QI 23))])
2552 (set (match_dup 0) (reg:QI 24))
2553 (set (match_dup 3) (reg:QI 25))]
2556 (define_insn "*udivmodqi4_call"
2557 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2558 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2559 (clobber (reg:QI 23))]
2561 "%~call __udivmodqi4"
2562 [(set_attr "type" "xcall")
2563 (set_attr "cc" "clobber")])
2565 (define_insn_and_split "divmodhi4"
2566 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2567 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2568 (match_operand:HI 2 "pseudo_register_operand" "")))
2569 (set (match_operand:HI 3 "pseudo_register_operand" "")
2570 (mod:HI (match_dup 1) (match_dup 2)))
2571 (clobber (reg:QI 21))
2572 (clobber (reg:HI 22))
2573 (clobber (reg:HI 24))
2574 (clobber (reg:HI 26))])]
2576 "this should have been splitted;"
2578 [(set (reg:HI 24) (match_dup 1))
2579 (set (reg:HI 22) (match_dup 2))
2580 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2581 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2582 (clobber (reg:HI 26))
2583 (clobber (reg:QI 21))])
2584 (set (match_dup 0) (reg:HI 22))
2585 (set (match_dup 3) (reg:HI 24))]
2588 (define_insn "*divmodhi4_call"
2589 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2590 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2591 (clobber (reg:HI 26))
2592 (clobber (reg:QI 21))]
2594 "%~call __divmodhi4"
2595 [(set_attr "type" "xcall")
2596 (set_attr "cc" "clobber")])
2598 (define_insn_and_split "udivmodhi4"
2599 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2600 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2601 (match_operand:HI 2 "pseudo_register_operand" "")))
2602 (set (match_operand:HI 3 "pseudo_register_operand" "")
2603 (umod:HI (match_dup 1) (match_dup 2)))
2604 (clobber (reg:QI 21))
2605 (clobber (reg:HI 22))
2606 (clobber (reg:HI 24))
2607 (clobber (reg:HI 26))])]
2609 "this udivmodhi4 pattern should have been splitted.;"
2611 [(set (reg:HI 24) (match_dup 1))
2612 (set (reg:HI 22) (match_dup 2))
2613 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2614 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2615 (clobber (reg:HI 26))
2616 (clobber (reg:QI 21))])
2617 (set (match_dup 0) (reg:HI 22))
2618 (set (match_dup 3) (reg:HI 24))]
2621 (define_insn "*udivmodhi4_call"
2622 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2623 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2624 (clobber (reg:HI 26))
2625 (clobber (reg:QI 21))]
2627 "%~call __udivmodhi4"
2628 [(set_attr "type" "xcall")
2629 (set_attr "cc" "clobber")])
2631 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2634 ;; To support widening multiplication with constant we postpone
2635 ;; expanding to the implicit library call until post combine and
2636 ;; prior to register allocation. Clobber all hard registers that
2637 ;; might be used by the (widening) multiply until it is split and
2638 ;; it's final register footprint is worked out.
2640 (define_expand "mulpsi3"
2641 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2642 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2643 (match_operand:PSI 2 "nonmemory_operand" "")))
2644 (clobber (reg:HI 26))
2645 (clobber (reg:DI 18))])]
2648 if (s8_operand (operands[2], PSImode))
2650 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2651 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2656 (define_insn "*umulqihipsi3"
2657 [(set (match_operand:PSI 0 "register_operand" "=&r")
2658 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2659 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2668 [(set_attr "length" "7")
2669 (set_attr "cc" "clobber")])
2671 (define_insn "*umulhiqipsi3"
2672 [(set (match_operand:PSI 0 "register_operand" "=&r")
2673 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2674 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2682 adc %C0,__zero_reg__"
2683 [(set_attr "length" "7")
2684 (set_attr "cc" "clobber")])
2686 (define_insn_and_split "mulsqipsi3"
2687 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2688 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2689 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2690 (clobber (reg:HI 26))
2691 (clobber (reg:DI 18))]
2692 "AVR_HAVE_MUL && !reload_completed"
2693 { gcc_unreachable(); }
2700 (mult:PSI (sign_extend:PSI (reg:QI 25))
2705 (define_insn_and_split "*mulpsi3"
2706 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2707 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2708 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2709 (clobber (reg:HI 26))
2710 (clobber (reg:DI 18))]
2711 "AVR_HAVE_MUL && !reload_completed"
2712 { gcc_unreachable(); }
2718 (parallel [(set (reg:PSI 22)
2719 (mult:PSI (reg:PSI 22)
2721 (clobber (reg:QI 21))
2722 (clobber (reg:QI 25))
2723 (clobber (reg:HI 26))])
2727 if (s8_operand (operands[2], PSImode))
2729 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2730 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2735 (define_insn "*mulsqipsi3.libgcc"
2737 (mult:PSI (sign_extend:PSI (reg:QI 25))
2740 "%~call __mulsqipsi3"
2741 [(set_attr "type" "xcall")
2742 (set_attr "cc" "clobber")])
2744 (define_insn "*mulpsi3.libgcc"
2746 (mult:PSI (reg:PSI 22)
2748 (clobber (reg:QI 21))
2749 (clobber (reg:QI 25))
2750 (clobber (reg:HI 26))]
2753 [(set_attr "type" "xcall")
2754 (set_attr "cc" "clobber")])
2757 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2758 ;; 24-bit signed/unsigned division and modulo.
2759 ;; Notice that the libgcc implementation return the quotient in R22
2760 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2761 ;; implementation works the other way round.
2763 (define_insn_and_split "divmodpsi4"
2764 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2765 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2766 (match_operand:PSI 2 "pseudo_register_operand" "")))
2767 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2768 (mod:PSI (match_dup 1)
2770 (clobber (reg:DI 18))
2771 (clobber (reg:QI 26))])]
2773 { gcc_unreachable(); }
2775 [(set (reg:PSI 22) (match_dup 1))
2776 (set (reg:PSI 18) (match_dup 2))
2777 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2778 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2779 (clobber (reg:QI 21))
2780 (clobber (reg:QI 25))
2781 (clobber (reg:QI 26))])
2782 (set (match_dup 0) (reg:PSI 22))
2783 (set (match_dup 3) (reg:PSI 18))])
2785 (define_insn "*divmodpsi4_call"
2786 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2787 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2788 (clobber (reg:QI 21))
2789 (clobber (reg:QI 25))
2790 (clobber (reg:QI 26))]
2792 "%~call __divmodpsi4"
2793 [(set_attr "type" "xcall")
2794 (set_attr "cc" "clobber")])
2796 (define_insn_and_split "udivmodpsi4"
2797 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2798 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2799 (match_operand:PSI 2 "pseudo_register_operand" "")))
2800 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2801 (umod:PSI (match_dup 1)
2803 (clobber (reg:DI 18))
2804 (clobber (reg:QI 26))])]
2806 { gcc_unreachable(); }
2808 [(set (reg:PSI 22) (match_dup 1))
2809 (set (reg:PSI 18) (match_dup 2))
2810 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2811 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2812 (clobber (reg:QI 21))
2813 (clobber (reg:QI 25))
2814 (clobber (reg:QI 26))])
2815 (set (match_dup 0) (reg:PSI 22))
2816 (set (match_dup 3) (reg:PSI 18))])
2818 (define_insn "*udivmodpsi4_call"
2819 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2820 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2821 (clobber (reg:QI 21))
2822 (clobber (reg:QI 25))
2823 (clobber (reg:QI 26))]
2825 "%~call __udivmodpsi4"
2826 [(set_attr "type" "xcall")
2827 (set_attr "cc" "clobber")])
2829 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2831 (define_insn_and_split "divmodsi4"
2832 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2833 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2834 (match_operand:SI 2 "pseudo_register_operand" "")))
2835 (set (match_operand:SI 3 "pseudo_register_operand" "")
2836 (mod:SI (match_dup 1) (match_dup 2)))
2837 (clobber (reg:SI 18))
2838 (clobber (reg:SI 22))
2839 (clobber (reg:HI 26))
2840 (clobber (reg:HI 30))])]
2842 "this divmodsi4 pattern should have been splitted;"
2844 [(set (reg:SI 22) (match_dup 1))
2845 (set (reg:SI 18) (match_dup 2))
2846 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2847 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2848 (clobber (reg:HI 26))
2849 (clobber (reg:HI 30))])
2850 (set (match_dup 0) (reg:SI 18))
2851 (set (match_dup 3) (reg:SI 22))]
2854 (define_insn "*divmodsi4_call"
2855 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2856 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2857 (clobber (reg:HI 26))
2858 (clobber (reg:HI 30))]
2860 "%~call __divmodsi4"
2861 [(set_attr "type" "xcall")
2862 (set_attr "cc" "clobber")])
2864 (define_insn_and_split "udivmodsi4"
2865 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2866 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2867 (match_operand:SI 2 "pseudo_register_operand" "")))
2868 (set (match_operand:SI 3 "pseudo_register_operand" "")
2869 (umod:SI (match_dup 1) (match_dup 2)))
2870 (clobber (reg:SI 18))
2871 (clobber (reg:SI 22))
2872 (clobber (reg:HI 26))
2873 (clobber (reg:HI 30))])]
2875 "this udivmodsi4 pattern should have been splitted;"
2877 [(set (reg:SI 22) (match_dup 1))
2878 (set (reg:SI 18) (match_dup 2))
2879 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2880 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2881 (clobber (reg:HI 26))
2882 (clobber (reg:HI 30))])
2883 (set (match_dup 0) (reg:SI 18))
2884 (set (match_dup 3) (reg:SI 22))]
2887 (define_insn "*udivmodsi4_call"
2888 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2889 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2890 (clobber (reg:HI 26))
2891 (clobber (reg:HI 30))]
2893 "%~call __udivmodsi4"
2894 [(set_attr "type" "xcall")
2895 (set_attr "cc" "clobber")])
2897 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2900 (define_insn "andqi3"
2901 [(set (match_operand:QI 0 "register_operand" "=r,d")
2902 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2903 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2908 [(set_attr "length" "1,1")
2909 (set_attr "cc" "set_zn,set_zn")])
2911 (define_insn "andhi3"
2912 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2913 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2914 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2915 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2918 if (which_alternative == 0)
2919 return "and %A0,%A2\;and %B0,%B2";
2920 else if (which_alternative == 1)
2921 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2923 return avr_out_bitop (insn, operands, NULL);
2925 [(set_attr "length" "2,2,2,4,4")
2926 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2927 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2929 (define_insn "andpsi3"
2930 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2931 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2932 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2933 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2936 if (which_alternative == 0)
2937 return "and %A0,%A2" CR_TAB
2938 "and %B0,%B2" CR_TAB
2941 return avr_out_bitop (insn, operands, NULL);
2943 [(set_attr "length" "3,3,6,6")
2944 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2945 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2947 (define_insn "andsi3"
2948 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2949 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2950 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2951 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2954 if (which_alternative == 0)
2955 return "and %0,%2" CR_TAB
2956 "and %B0,%B2" CR_TAB
2957 "and %C0,%C2" CR_TAB
2960 return avr_out_bitop (insn, operands, NULL);
2962 [(set_attr "length" "4,4,8,8")
2963 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2964 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2966 (define_peephole2 ; andi
2967 [(set (match_operand:QI 0 "d_register_operand" "")
2968 (and:QI (match_dup 0)
2969 (match_operand:QI 1 "const_int_operand" "")))
2971 (and:QI (match_dup 0)
2972 (match_operand:QI 2 "const_int_operand" "")))]
2974 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2976 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2979 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2982 (define_insn "iorqi3"
2983 [(set (match_operand:QI 0 "register_operand" "=r,d")
2984 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2985 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2990 [(set_attr "length" "1,1")
2991 (set_attr "cc" "set_zn,set_zn")])
2993 (define_insn "iorhi3"
2994 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2995 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2996 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2997 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3000 if (which_alternative == 0)
3001 return "or %A0,%A2\;or %B0,%B2";
3002 else if (which_alternative == 1)
3003 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3005 return avr_out_bitop (insn, operands, NULL);
3007 [(set_attr "length" "2,2,2,4,4")
3008 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3009 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3011 (define_insn "iorpsi3"
3012 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3013 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3014 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3015 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3018 if (which_alternative == 0)
3019 return "or %A0,%A2" CR_TAB
3023 return avr_out_bitop (insn, operands, NULL);
3025 [(set_attr "length" "3,3,6,6")
3026 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3027 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3029 (define_insn "iorsi3"
3030 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3031 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3032 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3033 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3036 if (which_alternative == 0)
3037 return "or %0,%2" CR_TAB
3042 return avr_out_bitop (insn, operands, NULL);
3044 [(set_attr "length" "4,4,8,8")
3045 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3046 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3048 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3051 (define_insn "xorqi3"
3052 [(set (match_operand:QI 0 "register_operand" "=r")
3053 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3054 (match_operand:QI 2 "register_operand" "r")))]
3057 [(set_attr "length" "1")
3058 (set_attr "cc" "set_zn")])
3060 (define_insn "xorhi3"
3061 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3062 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3063 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3064 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3067 if (which_alternative == 0)
3068 return "eor %A0,%A2\;eor %B0,%B2";
3070 return avr_out_bitop (insn, operands, NULL);
3072 [(set_attr "length" "2,2,4")
3073 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3074 (set_attr "cc" "set_n,clobber,clobber")])
3076 (define_insn "xorpsi3"
3077 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3078 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3079 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3080 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3083 if (which_alternative == 0)
3084 return "eor %A0,%A2" CR_TAB
3085 "eor %B0,%B2" CR_TAB
3088 return avr_out_bitop (insn, operands, NULL);
3090 [(set_attr "length" "3,6,6")
3091 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3092 (set_attr "cc" "set_n,clobber,clobber")])
3094 (define_insn "xorsi3"
3095 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3096 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3097 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3098 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3101 if (which_alternative == 0)
3102 return "eor %0,%2" CR_TAB
3103 "eor %B0,%B2" CR_TAB
3104 "eor %C0,%C2" CR_TAB
3107 return avr_out_bitop (insn, operands, NULL);
3109 [(set_attr "length" "4,8,8")
3110 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3111 (set_attr "cc" "set_n,clobber,clobber")])
3113 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3116 (define_expand "rotlqi3"
3117 [(set (match_operand:QI 0 "register_operand" "")
3118 (rotate:QI (match_operand:QI 1 "register_operand" "")
3119 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3122 if (!CONST_INT_P (operands[2]))
3125 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3128 ;; Expander used by __builtin_avr_swap
3129 (define_expand "rotlqi3_4"
3130 [(set (match_operand:QI 0 "register_operand" "")
3131 (rotate:QI (match_operand:QI 1 "register_operand" "")
3134 (define_insn "*rotlqi3"
3135 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3136 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3137 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3140 lsl %0\;adc %0,__zero_reg__
3141 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3142 swap %0\;bst %0,0\;ror %0\;bld %0,7
3144 swap %0\;lsl %0\;adc %0,__zero_reg__
3145 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3146 bst %0,0\;ror %0\;bld %0,7
3148 [(set_attr "length" "2,4,4,1,3,5,3,0")
3149 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3151 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3152 ;; a whole number of bytes. The split creates the appropriate moves and
3153 ;; considers all overlap situations.
3155 ;; HImode does not need scratch. Use attribute for this constraint.
3157 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3158 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3163 (define_expand "rotl<mode>3"
3164 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3165 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3166 (match_operand:VOID 2 "const_int_operand" "")))
3167 (clobber (match_dup 3))])]
3172 if (!CONST_INT_P (operands[2]))
3175 offset = INTVAL (operands[2]);
3177 if (0 == offset % 8)
3179 if (AVR_HAVE_MOVW && 0 == offset % 16)
3180 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3182 operands[3] = gen_rtx_SCRATCH (QImode);
3184 else if (offset == 1
3185 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3187 /*; Support rotate left/right by 1 */
3189 emit_move_insn (operands[0],
3190 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3197 (define_insn "*rotlhi2.1"
3198 [(set (match_operand:HI 0 "register_operand" "=r")
3199 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3202 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3203 [(set_attr "length" "3")
3204 (set_attr "cc" "clobber")])
3206 (define_insn "*rotlhi2.15"
3207 [(set (match_operand:HI 0 "register_operand" "=r")
3208 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3211 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3212 [(set_attr "length" "4")
3213 (set_attr "cc" "clobber")])
3215 (define_insn "*rotlpsi2.1"
3216 [(set (match_operand:PSI 0 "register_operand" "=r")
3217 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3220 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3221 [(set_attr "length" "4")
3222 (set_attr "cc" "clobber")])
3224 (define_insn "*rotlpsi2.23"
3225 [(set (match_operand:PSI 0 "register_operand" "=r")
3226 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3229 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3230 [(set_attr "length" "5")
3231 (set_attr "cc" "clobber")])
3233 (define_insn "*rotlsi2.1"
3234 [(set (match_operand:SI 0 "register_operand" "=r")
3235 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3238 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3239 [(set_attr "length" "5")
3240 (set_attr "cc" "clobber")])
3242 (define_insn "*rotlsi2.31"
3243 [(set (match_operand:SI 0 "register_operand" "=r")
3244 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3247 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3248 [(set_attr "length" "6")
3249 (set_attr "cc" "clobber")])
3251 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3252 ;; The best we can do is use early clobber alternative "#&r" so that
3253 ;; completely non-overlapping operands dont get a scratch but # so register
3254 ;; allocation does not prefer non-overlapping.
3257 ;; Split word aligned rotates using scratch that is mode dependent.
3261 (define_insn_and_split "*rotw<mode>"
3262 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3263 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3264 (match_operand 2 "const_int_operand" "n,n,n")))
3265 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3267 && CONST_INT_P (operands[2])
3268 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3269 && 0 == INTVAL (operands[2]) % 16"
3271 "&& reload_completed"
3274 avr_rotate_bytes (operands);
3279 ;; Split byte aligned rotates using scratch that is always QI mode.
3284 (define_insn_and_split "*rotb<mode>"
3285 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3286 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3287 (match_operand 2 "const_int_operand" "n,n,n")))
3288 (clobber (match_scratch:QI 3 "=<rotx>"))]
3289 "CONST_INT_P (operands[2])
3290 && (8 == INTVAL (operands[2]) % 16
3292 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3293 && 0 == INTVAL (operands[2]) % 16))"
3295 "&& reload_completed"
3298 avr_rotate_bytes (operands);
3303 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3304 ;; arithmetic shift left
3306 (define_expand "ashlqi3"
3307 [(set (match_operand:QI 0 "register_operand" "")
3308 (ashift:QI (match_operand:QI 1 "register_operand" "")
3309 (match_operand:QI 2 "nop_general_operand" "")))])
3311 (define_split ; ashlqi3_const4
3312 [(set (match_operand:QI 0 "d_register_operand" "")
3313 (ashift:QI (match_dup 0)
3316 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3317 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3320 (define_split ; ashlqi3_const5
3321 [(set (match_operand:QI 0 "d_register_operand" "")
3322 (ashift:QI (match_dup 0)
3325 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3326 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3327 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3330 (define_split ; ashlqi3_const6
3331 [(set (match_operand:QI 0 "d_register_operand" "")
3332 (ashift:QI (match_dup 0)
3335 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3336 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3337 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3340 (define_insn "*ashlqi3"
3341 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3342 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3343 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3346 return ashlqi3_out (insn, operands, NULL);
3348 [(set_attr "length" "5,0,1,2,4,6,9")
3349 (set_attr "adjust_len" "ashlqi")
3350 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3352 (define_insn "ashlhi3"
3353 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3354 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3355 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3358 return ashlhi3_out (insn, operands, NULL);
3360 [(set_attr "length" "6,0,2,2,4,10,10")
3361 (set_attr "adjust_len" "ashlhi")
3362 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3365 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3366 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3370 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3371 [(set (match_operand:QI 0 "register_operand" "=r")
3372 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3373 (match_operand:QI 2 "register_operand" "r"))
3379 (ashift:QI (match_dup 1)
3383 ;; ??? Combiner does not recognize that it could split the following insn;
3384 ;; presumably because he has no register handy?
3386 ;; "*ashluqihiqi3.mem"
3387 ;; "*ashlsqihiqi3.mem"
3388 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3389 [(set (match_operand:QI 0 "memory_operand" "=m")
3390 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3391 (match_operand:QI 2 "register_operand" "r"))
3394 { gcc_unreachable(); }
3397 (ashift:QI (match_dup 1)
3402 operands[3] = gen_reg_rtx (QImode);
3407 (define_insn_and_split "*ashlhiqi3"
3408 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3409 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3410 (match_operand:QI 2 "register_operand" "r")) 0))]
3412 { gcc_unreachable(); }
3415 (ashift:QI (match_dup 3)
3420 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3421 operands[4] = gen_reg_rtx (QImode);
3424 ;; High part of 16-bit shift is unused after the instruction:
3425 ;; No need to compute it, map to 8-bit shift.
3428 [(set (match_operand:HI 0 "register_operand" "")
3429 (ashift:HI (match_dup 0)
3430 (match_operand:QI 1 "register_operand" "")))]
3433 (ashift:QI (match_dup 2)
3435 (clobber (match_dup 3))]
3437 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3439 if (!peep2_reg_dead_p (1, operands[3]))
3442 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3446 (define_insn "ashlsi3"
3447 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3448 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3449 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3452 return ashlsi3_out (insn, operands, NULL);
3454 [(set_attr "length" "8,0,4,4,8,10,12")
3455 (set_attr "adjust_len" "ashlsi")
3456 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3458 ;; Optimize if a scratch register from LD_REGS happens to be available.
3460 (define_peephole2 ; ashlqi3_l_const4
3461 [(set (match_operand:QI 0 "l_register_operand" "")
3462 (ashift:QI (match_dup 0)
3464 (match_scratch:QI 1 "d")]
3466 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3467 (set (match_dup 1) (const_int -16))
3468 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3471 (define_peephole2 ; ashlqi3_l_const5
3472 [(set (match_operand:QI 0 "l_register_operand" "")
3473 (ashift:QI (match_dup 0)
3475 (match_scratch:QI 1 "d")]
3477 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3478 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3479 (set (match_dup 1) (const_int -32))
3480 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3483 (define_peephole2 ; ashlqi3_l_const6
3484 [(set (match_operand:QI 0 "l_register_operand" "")
3485 (ashift:QI (match_dup 0)
3487 (match_scratch:QI 1 "d")]
3489 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3490 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3491 (set (match_dup 1) (const_int -64))
3492 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3496 [(match_scratch:QI 3 "d")
3497 (set (match_operand:HI 0 "register_operand" "")
3498 (ashift:HI (match_operand:HI 1 "register_operand" "")
3499 (match_operand:QI 2 "const_int_operand" "")))]
3501 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3502 (clobber (match_dup 3))])]
3505 (define_insn "*ashlhi3_const"
3506 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3507 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3508 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3509 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3512 return ashlhi3_out (insn, operands, NULL);
3514 [(set_attr "length" "0,2,2,4,10")
3515 (set_attr "adjust_len" "ashlhi")
3516 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3519 [(match_scratch:QI 3 "d")
3520 (set (match_operand:SI 0 "register_operand" "")
3521 (ashift:SI (match_operand:SI 1 "register_operand" "")
3522 (match_operand:QI 2 "const_int_operand" "")))]
3524 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3525 (clobber (match_dup 3))])]
3528 (define_insn "*ashlsi3_const"
3529 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3530 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3531 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3532 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3535 return ashlsi3_out (insn, operands, NULL);
3537 [(set_attr "length" "0,4,4,10")
3538 (set_attr "adjust_len" "ashlsi")
3539 (set_attr "cc" "none,set_n,clobber,clobber")])
3541 (define_expand "ashlpsi3"
3542 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3543 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3544 (match_operand:QI 2 "nonmemory_operand" "")))
3545 (clobber (scratch:QI))])]
3549 && CONST_INT_P (operands[2]))
3551 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3553 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3554 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3557 else if (optimize_insn_for_speed_p ()
3558 && INTVAL (operands[2]) != 16
3559 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3561 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3562 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3568 (define_insn "*ashlpsi3"
3569 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3570 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3571 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3572 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3575 return avr_out_ashlpsi3 (insn, operands, NULL);
3577 [(set_attr "adjust_len" "ashlpsi")
3578 (set_attr "cc" "clobber")])
3580 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3581 ;; arithmetic shift right
3583 (define_insn "ashrqi3"
3584 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3585 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3586 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3589 return ashrqi3_out (insn, operands, NULL);
3591 [(set_attr "length" "5,0,1,2,5,4,9")
3592 (set_attr "adjust_len" "ashrqi")
3593 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3595 (define_insn "ashrhi3"
3596 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3597 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3598 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3601 return ashrhi3_out (insn, operands, NULL);
3603 [(set_attr "length" "6,0,2,4,4,10,10")
3604 (set_attr "adjust_len" "ashrhi")
3605 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3607 (define_insn "ashrpsi3"
3608 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3609 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3610 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3611 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3614 return avr_out_ashrpsi3 (insn, operands, NULL);
3616 [(set_attr "adjust_len" "ashrpsi")
3617 (set_attr "cc" "clobber")])
3619 (define_insn "ashrsi3"
3620 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3621 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3622 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3625 return ashrsi3_out (insn, operands, NULL);
3627 [(set_attr "length" "8,0,4,6,8,10,12")
3628 (set_attr "adjust_len" "ashrsi")
3629 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3631 ;; Optimize if a scratch register from LD_REGS happens to be available.
3634 [(match_scratch:QI 3 "d")
3635 (set (match_operand:HI 0 "register_operand" "")
3636 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3637 (match_operand:QI 2 "const_int_operand" "")))]
3639 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3640 (clobber (match_dup 3))])]
3643 (define_insn "*ashrhi3_const"
3644 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3645 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3646 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3647 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3650 return ashrhi3_out (insn, operands, NULL);
3652 [(set_attr "length" "0,2,4,4,10")
3653 (set_attr "adjust_len" "ashrhi")
3654 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3657 [(match_scratch:QI 3 "d")
3658 (set (match_operand:SI 0 "register_operand" "")
3659 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3660 (match_operand:QI 2 "const_int_operand" "")))]
3662 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3663 (clobber (match_dup 3))])]
3666 (define_insn "*ashrsi3_const"
3667 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3668 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3669 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3670 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3673 return ashrsi3_out (insn, operands, NULL);
3675 [(set_attr "length" "0,4,4,10")
3676 (set_attr "adjust_len" "ashrsi")
3677 (set_attr "cc" "none,clobber,set_n,clobber")])
3679 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3680 ;; logical shift right
3682 (define_expand "lshrqi3"
3683 [(set (match_operand:QI 0 "register_operand" "")
3684 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3685 (match_operand:QI 2 "nop_general_operand" "")))])
3687 (define_split ; lshrqi3_const4
3688 [(set (match_operand:QI 0 "d_register_operand" "")
3689 (lshiftrt:QI (match_dup 0)
3692 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3693 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3696 (define_split ; lshrqi3_const5
3697 [(set (match_operand:QI 0 "d_register_operand" "")
3698 (lshiftrt:QI (match_dup 0)
3701 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3702 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3703 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3706 (define_split ; lshrqi3_const6
3707 [(set (match_operand:QI 0 "d_register_operand" "")
3708 (lshiftrt:QI (match_dup 0)
3711 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3712 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3713 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3716 (define_insn "*lshrqi3"
3717 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3718 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3719 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3722 return lshrqi3_out (insn, operands, NULL);
3724 [(set_attr "length" "5,0,1,2,4,6,9")
3725 (set_attr "adjust_len" "lshrqi")
3726 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3728 (define_insn "lshrhi3"
3729 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3730 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3731 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3734 return lshrhi3_out (insn, operands, NULL);
3736 [(set_attr "length" "6,0,2,2,4,10,10")
3737 (set_attr "adjust_len" "lshrhi")
3738 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3740 (define_insn "lshrpsi3"
3741 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3742 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3743 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3744 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3747 return avr_out_lshrpsi3 (insn, operands, NULL);
3749 [(set_attr "adjust_len" "lshrpsi")
3750 (set_attr "cc" "clobber")])
3752 (define_insn "lshrsi3"
3753 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3754 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3755 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3758 return lshrsi3_out (insn, operands, NULL);
3760 [(set_attr "length" "8,0,4,4,8,10,12")
3761 (set_attr "adjust_len" "lshrsi")
3762 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3764 ;; Optimize if a scratch register from LD_REGS happens to be available.
3766 (define_peephole2 ; lshrqi3_l_const4
3767 [(set (match_operand:QI 0 "l_register_operand" "")
3768 (lshiftrt:QI (match_dup 0)
3770 (match_scratch:QI 1 "d")]
3772 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3773 (set (match_dup 1) (const_int 15))
3774 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3777 (define_peephole2 ; lshrqi3_l_const5
3778 [(set (match_operand:QI 0 "l_register_operand" "")
3779 (lshiftrt:QI (match_dup 0)
3781 (match_scratch:QI 1 "d")]
3783 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3784 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3785 (set (match_dup 1) (const_int 7))
3786 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3789 (define_peephole2 ; lshrqi3_l_const6
3790 [(set (match_operand:QI 0 "l_register_operand" "")
3791 (lshiftrt:QI (match_dup 0)
3793 (match_scratch:QI 1 "d")]
3795 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3796 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3797 (set (match_dup 1) (const_int 3))
3798 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3802 [(match_scratch:QI 3 "d")
3803 (set (match_operand:HI 0 "register_operand" "")
3804 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3805 (match_operand:QI 2 "const_int_operand" "")))]
3807 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3808 (clobber (match_dup 3))])]
3811 (define_insn "*lshrhi3_const"
3812 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3813 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3814 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3815 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3818 return lshrhi3_out (insn, operands, NULL);
3820 [(set_attr "length" "0,2,2,4,10")
3821 (set_attr "adjust_len" "lshrhi")
3822 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3825 [(match_scratch:QI 3 "d")
3826 (set (match_operand:SI 0 "register_operand" "")
3827 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3828 (match_operand:QI 2 "const_int_operand" "")))]
3830 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3831 (clobber (match_dup 3))])]
3834 (define_insn "*lshrsi3_const"
3835 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3836 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3837 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3838 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3841 return lshrsi3_out (insn, operands, NULL);
3843 [(set_attr "length" "0,4,4,10")
3844 (set_attr "adjust_len" "lshrsi")
3845 (set_attr "cc" "none,clobber,clobber,clobber")])
3847 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3850 (define_insn "absqi2"
3851 [(set (match_operand:QI 0 "register_operand" "=r")
3852 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3856 [(set_attr "length" "2")
3857 (set_attr "cc" "clobber")])
3860 (define_insn "abssf2"
3861 [(set (match_operand:SF 0 "register_operand" "=d,r")
3862 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3867 [(set_attr "length" "1,2")
3868 (set_attr "cc" "set_n,clobber")])
3870 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3873 (define_insn "negqi2"
3874 [(set (match_operand:QI 0 "register_operand" "=r")
3875 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3878 [(set_attr "length" "1")
3879 (set_attr "cc" "set_zn")])
3881 (define_insn "*negqihi2"
3882 [(set (match_operand:HI 0 "register_operand" "=r")
3883 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3885 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3886 [(set_attr "length" "4")
3887 (set_attr "cc" "set_n")])
3889 (define_insn "neghi2"
3890 [(set (match_operand:HI 0 "register_operand" "=r,&r")
3891 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
3894 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
3895 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3896 [(set_attr "length" "3,4")
3897 (set_attr "cc" "set_czn")])
3899 (define_insn "negpsi2"
3900 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3901 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3904 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3905 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3906 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3907 [(set_attr "length" "5,6,6")
3908 (set_attr "cc" "set_czn,set_n,set_czn")])
3910 (define_insn "negsi2"
3911 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3912 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3915 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3916 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3917 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3918 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3919 [(set_attr "length" "7,8,8,7")
3920 (set_attr "isa" "*,*,mov,movw")
3921 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3923 (define_insn "negsf2"
3924 [(set (match_operand:SF 0 "register_operand" "=d,r")
3925 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3929 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3930 [(set_attr "length" "1,4")
3931 (set_attr "cc" "set_n,set_n")])
3933 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3936 (define_insn "one_cmplqi2"
3937 [(set (match_operand:QI 0 "register_operand" "=r")
3938 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3941 [(set_attr "length" "1")
3942 (set_attr "cc" "set_czn")])
3944 (define_insn "one_cmplhi2"
3945 [(set (match_operand:HI 0 "register_operand" "=r")
3946 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3950 [(set_attr "length" "2")
3951 (set_attr "cc" "set_n")])
3953 (define_insn "one_cmplpsi2"
3954 [(set (match_operand:PSI 0 "register_operand" "=r")
3955 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3957 "com %0\;com %B0\;com %C0"
3958 [(set_attr "length" "3")
3959 (set_attr "cc" "set_n")])
3961 (define_insn "one_cmplsi2"
3962 [(set (match_operand:SI 0 "register_operand" "=r")
3963 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3969 [(set_attr "length" "4")
3970 (set_attr "cc" "set_n")])
3972 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3975 ;; We keep combiner from inserting hard registers into the input of sign- and
3976 ;; zero-extends. A hard register in the input operand is not wanted because
3977 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3978 ;; hard register that overlaps these clobbers won't be combined to a widening
3979 ;; multiplication. There is no need for combine to propagate hard registers,
3980 ;; register allocation can do it just as well.
3982 (define_insn "extendqihi2"
3983 [(set (match_operand:HI 0 "register_operand" "=r,r")
3984 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3987 clr %B0\;sbrc %0,7\;com %B0
3988 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3989 [(set_attr "length" "3,4")
3990 (set_attr "cc" "set_n,set_n")])
3992 (define_insn "extendqipsi2"
3993 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3994 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3997 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3998 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3999 [(set_attr "length" "4,5")
4000 (set_attr "cc" "set_n,set_n")])
4002 (define_insn "extendqisi2"
4003 [(set (match_operand:SI 0 "register_operand" "=r,r")
4004 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4007 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4008 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4009 [(set_attr "length" "5,6")
4010 (set_attr "cc" "set_n,set_n")])
4012 (define_insn "extendhipsi2"
4013 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4014 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4017 clr %C0\;sbrc %B0,7\;com %C0
4018 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4019 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4020 [(set_attr "length" "3,5,4")
4021 (set_attr "isa" "*,mov,movw")
4022 (set_attr "cc" "set_n")])
4024 (define_insn "extendhisi2"
4025 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4026 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4029 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4030 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4031 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4032 [(set_attr "length" "4,6,5")
4033 (set_attr "isa" "*,mov,movw")
4034 (set_attr "cc" "set_n")])
4036 (define_insn "extendpsisi2"
4037 [(set (match_operand:SI 0 "register_operand" "=r")
4038 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4040 "clr %D0\;sbrc %C0,7\;com %D0"
4041 [(set_attr "length" "3")
4042 (set_attr "cc" "set_n")])
4044 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4047 (define_insn_and_split "zero_extendqihi2"
4048 [(set (match_operand:HI 0 "register_operand" "=r")
4049 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4053 [(set (match_dup 2) (match_dup 1))
4054 (set (match_dup 3) (const_int 0))]
4056 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4057 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4059 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4060 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4063 (define_insn_and_split "zero_extendqipsi2"
4064 [(set (match_operand:PSI 0 "register_operand" "=r")
4065 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4069 [(set (match_dup 2) (match_dup 1))
4070 (set (match_dup 3) (const_int 0))
4071 (set (match_dup 4) (const_int 0))]
4073 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4074 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4075 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4078 (define_insn_and_split "zero_extendqisi2"
4079 [(set (match_operand:SI 0 "register_operand" "=r")
4080 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4084 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4085 (set (match_dup 3) (const_int 0))]
4087 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4088 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4090 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4091 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4094 (define_insn_and_split "zero_extendhipsi2"
4095 [(set (match_operand:PSI 0 "register_operand" "=r")
4096 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4100 [(set (match_dup 2) (match_dup 1))
4101 (set (match_dup 3) (const_int 0))]
4103 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4104 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4107 (define_insn_and_split "n_extendhipsi2"
4108 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4109 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4110 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4111 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4115 [(set (match_dup 4) (match_dup 2))
4116 (set (match_dup 3) (match_dup 6))
4117 ; no-op move in the case where no scratch is needed
4118 (set (match_dup 5) (match_dup 3))]
4120 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4121 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4122 operands[6] = operands[1];
4124 if (GET_CODE (operands[3]) == SCRATCH)
4125 operands[3] = operands[5];
4128 (define_insn_and_split "zero_extendhisi2"
4129 [(set (match_operand:SI 0 "register_operand" "=r")
4130 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4134 [(set (match_dup 2) (match_dup 1))
4135 (set (match_dup 3) (const_int 0))]
4137 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4138 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4140 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4141 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4144 (define_insn_and_split "zero_extendpsisi2"
4145 [(set (match_operand:SI 0 "register_operand" "=r")
4146 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4150 [(set (match_dup 2) (match_dup 1))
4151 (set (match_dup 3) (const_int 0))]
4153 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4154 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4157 (define_insn_and_split "zero_extendqidi2"
4158 [(set (match_operand:DI 0 "register_operand" "=r")
4159 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4163 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4164 (set (match_dup 3) (const_int 0))]
4166 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4167 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4169 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4170 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4173 (define_insn_and_split "zero_extendhidi2"
4174 [(set (match_operand:DI 0 "register_operand" "=r")
4175 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4179 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4180 (set (match_dup 3) (const_int 0))]
4182 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4183 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4185 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4186 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4189 (define_insn_and_split "zero_extendsidi2"
4190 [(set (match_operand:DI 0 "register_operand" "=r")
4191 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4195 [(set (match_dup 2) (match_dup 1))
4196 (set (match_dup 3) (const_int 0))]
4198 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4199 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4201 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4202 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4205 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4208 ; Optimize negated tests into reverse compare if overflow is undefined.
4209 (define_insn "*negated_tstqi"
4211 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4213 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4214 "cp __zero_reg__,%0"
4215 [(set_attr "cc" "compare")
4216 (set_attr "length" "1")])
4218 (define_insn "*reversed_tstqi"
4220 (compare (const_int 0)
4221 (match_operand:QI 0 "register_operand" "r")))]
4223 "cp __zero_reg__,%0"
4224 [(set_attr "cc" "compare")
4225 (set_attr "length" "2")])
4227 (define_insn "*negated_tsthi"
4229 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4231 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4232 "cp __zero_reg__,%A0
4233 cpc __zero_reg__,%B0"
4234 [(set_attr "cc" "compare")
4235 (set_attr "length" "2")])
4237 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4238 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4239 (define_insn "*reversed_tsthi"
4241 (compare (const_int 0)
4242 (match_operand:HI 0 "register_operand" "r")))
4243 (clobber (match_scratch:QI 1 "=X"))]
4245 "cp __zero_reg__,%A0
4246 cpc __zero_reg__,%B0"
4247 [(set_attr "cc" "compare")
4248 (set_attr "length" "2")])
4250 (define_insn "*negated_tstpsi"
4252 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4254 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4255 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4256 [(set_attr "cc" "compare")
4257 (set_attr "length" "3")])
4259 (define_insn "*reversed_tstpsi"
4261 (compare (const_int 0)
4262 (match_operand:PSI 0 "register_operand" "r")))
4263 (clobber (match_scratch:QI 1 "=X"))]
4265 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4266 [(set_attr "cc" "compare")
4267 (set_attr "length" "3")])
4269 (define_insn "*negated_tstsi"
4271 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4273 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4274 "cp __zero_reg__,%A0
4275 cpc __zero_reg__,%B0
4276 cpc __zero_reg__,%C0
4277 cpc __zero_reg__,%D0"
4278 [(set_attr "cc" "compare")
4279 (set_attr "length" "4")])
4281 (define_insn "*reversed_tstsi"
4283 (compare (const_int 0)
4284 (match_operand:SI 0 "register_operand" "r")))
4285 (clobber (match_scratch:QI 1 "=X"))]
4287 "cp __zero_reg__,%A0
4288 cpc __zero_reg__,%B0
4289 cpc __zero_reg__,%C0
4290 cpc __zero_reg__,%D0"
4291 [(set_attr "cc" "compare")
4292 (set_attr "length" "4")])
4295 (define_insn "*cmpqi"
4297 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4298 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4304 [(set_attr "cc" "compare,compare,compare")
4305 (set_attr "length" "1,1,1")])
4307 (define_insn "*cmpqi_sign_extend"
4309 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4310 (match_operand:HI 1 "s8_operand" "n")))]
4313 [(set_attr "cc" "compare")
4314 (set_attr "length" "1")])
4316 (define_insn "*cmphi"
4318 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4319 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4320 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4323 switch (which_alternative)
4327 return avr_out_tsthi (insn, operands, NULL);
4330 return "cp %A0,%A1\;cpc %B0,%B1";
4333 return reg_unused_after (insn, operands[0])
4334 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4335 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4338 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4341 return avr_out_compare (insn, operands, NULL);
4343 [(set_attr "cc" "compare")
4344 (set_attr "length" "1,2,2,3,4,2,4")
4345 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4347 (define_insn "*cmppsi"
4349 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4350 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4351 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4354 switch (which_alternative)
4357 return avr_out_tstpsi (insn, operands, NULL);
4360 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4363 return reg_unused_after (insn, operands[0])
4364 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4365 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4368 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4371 return avr_out_compare (insn, operands, NULL);
4373 [(set_attr "cc" "compare")
4374 (set_attr "length" "3,3,5,6,3,7")
4375 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4377 (define_insn "*cmpsi"
4379 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4380 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4381 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4384 if (0 == which_alternative)
4385 return avr_out_tstsi (insn, operands, NULL);
4386 else if (1 == which_alternative)
4387 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4389 return avr_out_compare (insn, operands, NULL);
4391 [(set_attr "cc" "compare")
4392 (set_attr "length" "4,4,4,5,8")
4393 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4396 ;; ----------------------------------------------------------------------
4397 ;; JUMP INSTRUCTIONS
4398 ;; ----------------------------------------------------------------------
4399 ;; Conditional jump instructions
4401 (define_expand "cbranchsi4"
4402 [(parallel [(set (cc0)
4403 (compare (match_operand:SI 1 "register_operand" "")
4404 (match_operand:SI 2 "nonmemory_operand" "")))
4405 (clobber (match_scratch:QI 4 ""))])
4408 (match_operator 0 "ordered_comparison_operator" [(cc0)
4410 (label_ref (match_operand 3 "" ""))
4414 (define_expand "cbranchpsi4"
4415 [(parallel [(set (cc0)
4416 (compare (match_operand:PSI 1 "register_operand" "")
4417 (match_operand:PSI 2 "nonmemory_operand" "")))
4418 (clobber (match_scratch:QI 4 ""))])
4420 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4422 (label_ref (match_operand 3 "" ""))
4426 (define_expand "cbranchhi4"
4427 [(parallel [(set (cc0)
4428 (compare (match_operand:HI 1 "register_operand" "")
4429 (match_operand:HI 2 "nonmemory_operand" "")))
4430 (clobber (match_scratch:QI 4 ""))])
4433 (match_operator 0 "ordered_comparison_operator" [(cc0)
4435 (label_ref (match_operand 3 "" ""))
4439 (define_expand "cbranchqi4"
4441 (compare (match_operand:QI 1 "register_operand" "")
4442 (match_operand:QI 2 "nonmemory_operand" "")))
4445 (match_operator 0 "ordered_comparison_operator" [(cc0)
4447 (label_ref (match_operand 3 "" ""))
4452 ;; Test a single bit in a QI/HI/SImode register.
4453 ;; Combine will create zero extract patterns for single bit tests.
4454 ;; permit any mode in source pattern by using VOIDmode.
4456 (define_insn "*sbrx_branch<mode>"
4459 (match_operator 0 "eqne_operator"
4461 (match_operand:VOID 1 "register_operand" "r")
4463 (match_operand 2 "const_int_operand" "n"))
4465 (label_ref (match_operand 3 "" ""))
4469 return avr_out_sbxx_branch (insn, operands);
4471 [(set (attr "length")
4472 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4473 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4475 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4478 (set_attr "cc" "clobber")])
4480 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4481 ;; or for old peepholes.
4482 ;; Fixme - bitwise Mask will not work for DImode
4484 (define_insn "*sbrx_and_branch<mode>"
4487 (match_operator 0 "eqne_operator"
4489 (match_operand:QISI 1 "register_operand" "r")
4490 (match_operand:QISI 2 "single_one_operand" "n"))
4492 (label_ref (match_operand 3 "" ""))
4496 HOST_WIDE_INT bitnumber;
4497 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4498 operands[2] = GEN_INT (bitnumber);
4499 return avr_out_sbxx_branch (insn, operands);
4501 [(set (attr "length")
4502 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4503 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4505 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4508 (set_attr "cc" "clobber")])
4510 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4512 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4514 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4515 (label_ref (match_operand 1 "" ""))
4518 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4522 (label_ref (match_dup 1))
4527 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4529 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4530 (label_ref (match_operand 1 "" ""))
4533 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4537 (label_ref (match_dup 1))
4542 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4544 (clobber (match_operand:HI 2 ""))])
4545 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4546 (label_ref (match_operand 1 "" ""))
4549 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4551 (label_ref (match_dup 1))
4556 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4558 (clobber (match_operand:HI 2 ""))])
4559 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4560 (label_ref (match_operand 1 "" ""))
4563 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4565 (label_ref (match_dup 1))
4570 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4572 (clobber (match_operand:SI 2 ""))])
4573 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4574 (label_ref (match_operand 1 "" ""))
4577 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4579 (label_ref (match_dup 1))
4581 "operands[2] = GEN_INT (-2147483647 - 1);")
4584 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4586 (clobber (match_operand:SI 2 ""))])
4587 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4588 (label_ref (match_operand 1 "" ""))
4591 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4593 (label_ref (match_dup 1))
4595 "operands[2] = GEN_INT (-2147483647 - 1);")
4597 ;; ************************************************************************
4598 ;; Implementation of conditional jumps here.
4599 ;; Compare with 0 (test) jumps
4600 ;; ************************************************************************
4602 (define_insn "branch"
4604 (if_then_else (match_operator 1 "simple_comparison_operator"
4607 (label_ref (match_operand 0 "" ""))
4611 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4613 [(set_attr "type" "branch")
4614 (set_attr "cc" "clobber")])
4617 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4618 ;; or optimized in the remainder.
4620 (define_insn "branch_unspec"
4622 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4625 (label_ref (match_operand 0 "" ""))
4627 ] UNSPEC_IDENTITY))]
4630 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4632 [(set_attr "type" "branch")
4633 (set_attr "cc" "none")])
4635 ;; ****************************************************************
4636 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4637 ;; Convert them all to proper jumps.
4638 ;; ****************************************************************/
4640 (define_insn "difficult_branch"
4642 (if_then_else (match_operator 1 "difficult_comparison_operator"
4645 (label_ref (match_operand 0 "" ""))
4649 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4651 [(set_attr "type" "branch1")
4652 (set_attr "cc" "clobber")])
4656 (define_insn "rvbranch"
4658 (if_then_else (match_operator 1 "simple_comparison_operator"
4662 (label_ref (match_operand 0 "" ""))))]
4665 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4667 [(set_attr "type" "branch1")
4668 (set_attr "cc" "clobber")])
4670 (define_insn "difficult_rvbranch"
4672 (if_then_else (match_operator 1 "difficult_comparison_operator"
4676 (label_ref (match_operand 0 "" ""))))]
4679 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4681 [(set_attr "type" "branch")
4682 (set_attr "cc" "clobber")])
4684 ;; **************************************************************************
4685 ;; Unconditional and other jump instructions.
4689 (label_ref (match_operand 0 "" "")))]
4692 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4696 [(set (attr "length")
4697 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4698 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4701 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4702 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4705 (set_attr "cc" "none")])
4709 (define_expand "call"
4710 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4711 (match_operand:HI 1 "general_operand" ""))
4712 (use (const_int 0))])]
4713 ;; Operand 1 not used on the AVR.
4714 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4718 (define_expand "sibcall"
4719 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4720 (match_operand:HI 1 "general_operand" ""))
4721 (use (const_int 1))])]
4722 ;; Operand 1 not used on the AVR.
4723 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4729 (define_expand "call_value"
4730 [(parallel[(set (match_operand 0 "register_operand" "")
4731 (call (match_operand:HI 1 "call_insn_operand" "")
4732 (match_operand:HI 2 "general_operand" "")))
4733 (use (const_int 0))])]
4734 ;; Operand 2 not used on the AVR.
4735 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4739 (define_expand "sibcall_value"
4740 [(parallel[(set (match_operand 0 "register_operand" "")
4741 (call (match_operand:HI 1 "call_insn_operand" "")
4742 (match_operand:HI 2 "general_operand" "")))
4743 (use (const_int 1))])]
4744 ;; Operand 2 not used on the AVR.
4745 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4749 (define_insn "call_insn"
4750 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4751 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4752 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4753 ;; Operand 1 not used on the AVR.
4754 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4761 [(set_attr "cc" "clobber")
4762 (set_attr "length" "1,*,1,*")
4763 (set_attr "adjust_len" "*,call,*,call")])
4765 (define_insn "call_value_insn"
4766 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4767 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4768 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4769 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4770 ;; Operand 2 not used on the AVR.
4771 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4778 [(set_attr "cc" "clobber")
4779 (set_attr "length" "1,*,1,*")
4780 (set_attr "adjust_len" "*,call,*,call")])
4786 [(set_attr "cc" "none")
4787 (set_attr "length" "1")])
4791 (define_expand "indirect_jump"
4793 (match_operand:HI 0 "nonmemory_operand" ""))]
4796 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4798 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4803 (define_insn "*indirect_jump"
4805 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4811 push %A0\;push %B0\;ret
4813 [(set_attr "length" "1,2,1,3,1")
4814 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4815 (set_attr "cc" "none")])
4818 ;; For entries in jump table see avr_output_addr_vec_elt.
4821 ;; "rjmp .L<n>" instructions for <= 8K devices
4822 ;; ".word gs(.L<n>)" addresses for > 8K devices
4823 (define_insn "*tablejump"
4825 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4827 (use (label_ref (match_operand 1 "" "")))
4828 (clobber (match_dup 0))]
4832 push %A0\;push %B0\;ret
4834 [(set_attr "length" "1,3,2")
4835 (set_attr "isa" "rjmp,rjmp,jmp")
4836 (set_attr "cc" "none,none,clobber")])
4839 (define_expand "casesi"
4841 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4842 (match_operand:HI 1 "register_operand" "")))
4843 (parallel [(set (cc0)
4844 (compare (match_dup 6)
4845 (match_operand:HI 2 "register_operand" "")))
4846 (clobber (match_scratch:QI 9 ""))])
4849 (if_then_else (gtu (cc0)
4851 (label_ref (match_operand 4 "" ""))
4855 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4857 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4858 (use (label_ref (match_dup 3)))
4859 (clobber (match_dup 6))])]
4862 operands[6] = gen_reg_rtx (HImode);
4866 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4867 ;; This instruction sets Z flag
4870 [(set (cc0) (const_int 0))]
4873 [(set_attr "length" "1")
4874 (set_attr "cc" "compare")])
4876 ;; Clear/set/test a single bit in I/O address space.
4879 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4880 (and:QI (mem:QI (match_dup 0))
4881 (match_operand:QI 1 "single_zero_operand" "n")))]
4884 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4885 return "cbi %i0,%2";
4887 [(set_attr "length" "1")
4888 (set_attr "cc" "none")])
4891 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4892 (ior:QI (mem:QI (match_dup 0))
4893 (match_operand:QI 1 "single_one_operand" "n")))]
4896 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4897 return "sbi %i0,%2";
4899 [(set_attr "length" "1")
4900 (set_attr "cc" "none")])
4902 ;; Lower half of the I/O space - use sbic/sbis directly.
4903 (define_insn "*sbix_branch"
4906 (match_operator 0 "eqne_operator"
4908 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4910 (match_operand 2 "const_int_operand" "n"))
4912 (label_ref (match_operand 3 "" ""))
4916 return avr_out_sbxx_branch (insn, operands);
4918 [(set (attr "length")
4919 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4920 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4922 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4925 (set_attr "cc" "clobber")])
4927 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4928 (define_insn "*sbix_branch_bit7"
4931 (match_operator 0 "gelt_operator"
4932 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4934 (label_ref (match_operand 2 "" ""))
4938 operands[3] = operands[2];
4939 operands[2] = GEN_INT (7);
4940 return avr_out_sbxx_branch (insn, operands);
4942 [(set (attr "length")
4943 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4944 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4946 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4949 (set_attr "cc" "clobber")])
4951 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4952 (define_insn "*sbix_branch_tmp"
4955 (match_operator 0 "eqne_operator"
4957 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4959 (match_operand 2 "const_int_operand" "n"))
4961 (label_ref (match_operand 3 "" ""))
4965 return avr_out_sbxx_branch (insn, operands);
4967 [(set (attr "length")
4968 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4969 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4971 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4974 (set_attr "cc" "clobber")])
4976 (define_insn "*sbix_branch_tmp_bit7"
4979 (match_operator 0 "gelt_operator"
4980 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4982 (label_ref (match_operand 2 "" ""))
4986 operands[3] = operands[2];
4987 operands[2] = GEN_INT (7);
4988 return avr_out_sbxx_branch (insn, operands);
4990 [(set (attr "length")
4991 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4992 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4994 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4997 (set_attr "cc" "clobber")])
4999 ;; ************************* Peepholes ********************************
5001 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5002 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5003 (plus:SI (match_dup 0)
5005 (clobber (scratch:QI))])
5006 (parallel [(set (cc0)
5007 (compare (match_dup 0)
5009 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5011 (if_then_else (eqne (cc0)
5013 (label_ref (match_operand 2 "" ""))
5020 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5021 output_asm_insn ("sbiw %0,1" CR_TAB
5022 "sbc %C0,__zero_reg__" CR_TAB
5023 "sbc %D0,__zero_reg__", operands);
5025 output_asm_insn ("subi %A0,1" CR_TAB
5026 "sbc %B0,__zero_reg__" CR_TAB
5027 "sbc %C0,__zero_reg__" CR_TAB
5028 "sbc %D0,__zero_reg__", operands);
5030 jump_mode = avr_jump_mode (operands[2], insn);
5031 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5032 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5036 case 1: return "%1 %2";
5037 case 2: return "%1 .+2\;rjmp %2";
5038 case 3: return "%1 .+4\;jmp %2";
5045 (define_peephole ; "*dec-and-branchhi!=-1"
5046 [(set (match_operand:HI 0 "d_register_operand" "")
5047 (plus:HI (match_dup 0)
5049 (parallel [(set (cc0)
5050 (compare (match_dup 0)
5052 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5054 (if_then_else (eqne (cc0)
5056 (label_ref (match_operand 2 "" ""))
5063 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5064 output_asm_insn ("sbiw %0,1", operands);
5066 output_asm_insn ("subi %A0,1" CR_TAB
5067 "sbc %B0,__zero_reg__", operands);
5069 jump_mode = avr_jump_mode (operands[2], insn);
5070 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5071 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5075 case 1: return "%1 %2";
5076 case 2: return "%1 .+2\;rjmp %2";
5077 case 3: return "%1 .+4\;jmp %2";
5084 ;; Same as above but with clobber flavour of addhi3
5085 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5086 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5087 (plus:HI (match_dup 0)
5089 (clobber (scratch:QI))])
5090 (parallel [(set (cc0)
5091 (compare (match_dup 0)
5093 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5095 (if_then_else (eqne (cc0)
5097 (label_ref (match_operand 2 "" ""))
5104 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5105 output_asm_insn ("sbiw %0,1", operands);
5107 output_asm_insn ("subi %A0,1" CR_TAB
5108 "sbc %B0,__zero_reg__", operands);
5110 jump_mode = avr_jump_mode (operands[2], insn);
5111 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5112 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5116 case 1: return "%1 %2";
5117 case 2: return "%1 .+2\;rjmp %2";
5118 case 3: return "%1 .+4\;jmp %2";
5125 ;; Same as above but with clobber flavour of addhi3
5126 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5127 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5128 (plus:HI (match_dup 0)
5130 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5131 (parallel [(set (cc0)
5132 (compare (match_dup 0)
5134 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5136 (if_then_else (eqne (cc0)
5138 (label_ref (match_operand 2 "" ""))
5145 output_asm_insn ("ldi %3,1" CR_TAB
5147 "sbc %B0,__zero_reg__", operands);
5149 jump_mode = avr_jump_mode (operands[2], insn);
5150 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5151 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5155 case 1: return "%1 %2";
5156 case 2: return "%1 .+2\;rjmp %2";
5157 case 3: return "%1 .+4\;jmp %2";
5164 (define_peephole ; "*dec-and-branchqi!=-1"
5165 [(set (match_operand:QI 0 "d_register_operand" "")
5166 (plus:QI (match_dup 0)
5169 (compare (match_dup 0)
5172 (if_then_else (eqne (cc0)
5174 (label_ref (match_operand 1 "" ""))
5181 cc_status.value1 = operands[0];
5182 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5184 output_asm_insn ("subi %A0,1", operands);
5186 jump_mode = avr_jump_mode (operands[1], insn);
5187 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5188 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5192 case 1: return "%0 %1";
5193 case 2: return "%0 .+2\;rjmp %1";
5194 case 3: return "%0 .+4\;jmp %1";
5202 (define_peephole ; "*cpse.eq"
5204 (compare (match_operand:QI 1 "register_operand" "r,r")
5205 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
5207 (if_then_else (eq (cc0)
5209 (label_ref (match_operand 0 "" ""))
5211 "jump_over_one_insn_p (insn, operands[0])"
5214 cpse %1,__zero_reg__")
5216 ;; This peephole avoids code like
5219 ;; BREQ .+2 ; branch
5222 ;; Notice that the peephole is always shorter than cmpqi + branch.
5223 ;; The reason to write it as peephole is that sequences like
5228 ;; shall not be superseeded. With a respective combine pattern
5229 ;; the latter sequence would be
5232 ;; CPSE Rm, __zero_reg__
5235 ;; and thus longer and slower and not easy to be rolled back.
5237 (define_peephole ; "*cpse.ne"
5239 (compare (match_operand:QI 1 "register_operand" "")
5240 (match_operand:QI 2 "reg_or_0_operand" "")))
5242 (if_then_else (ne (cc0)
5244 (label_ref (match_operand 0 "" ""))
5247 || !avr_current_device->errata_skip"
5249 if (operands[2] == const0_rtx)
5250 operands[2] = zero_reg_rtx;
5252 return 3 == avr_jump_mode (operands[0], insn)
5253 ? "cpse %1,%2\;jmp %0"
5254 : "cpse %1,%2\;rjmp %0";
5257 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5258 ;;prologue/epilogue support instructions
5260 (define_insn "popqi"
5261 [(set (match_operand:QI 0 "register_operand" "=r")
5262 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5265 [(set_attr "cc" "none")
5266 (set_attr "length" "1")])
5268 ;; Enable Interrupts
5269 (define_expand "enable_interrupt"
5270 [(clobber (const_int 0))]
5273 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5274 MEM_VOLATILE_P (mem) = 1;
5275 emit_insn (gen_cli_sei (const1_rtx, mem));
5279 ;; Disable Interrupts
5280 (define_expand "disable_interrupt"
5281 [(clobber (const_int 0))]
5284 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5285 MEM_VOLATILE_P (mem) = 1;
5286 emit_insn (gen_cli_sei (const0_rtx, mem));
5290 (define_insn "cli_sei"
5291 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5292 UNSPECV_ENABLE_IRQS)
5293 (set (match_operand:BLK 1 "" "")
5294 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))]
5299 [(set_attr "length" "1")
5300 (set_attr "cc" "none")])
5302 ;; Library prologue saves
5303 (define_insn "call_prologue_saves"
5304 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5305 (match_operand:HI 0 "immediate_operand" "i,i")
5306 (set (reg:HI REG_SP)
5307 (minus:HI (reg:HI REG_SP)
5308 (match_operand:HI 1 "immediate_operand" "i,i")))
5309 (use (reg:HI REG_X))
5310 (clobber (reg:HI REG_Z))]
5312 "ldi r30,lo8(gs(1f))
5314 %~jmp __prologue_saves__+((18 - %0) * 2)
5316 [(set_attr "length" "5,6")
5317 (set_attr "cc" "clobber")
5318 (set_attr "isa" "rjmp,jmp")])
5320 ; epilogue restores using library
5321 (define_insn "epilogue_restores"
5322 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5324 (plus:HI (reg:HI REG_Y)
5325 (match_operand:HI 0 "immediate_operand" "i,i")))
5326 (set (reg:HI REG_SP)
5327 (plus:HI (reg:HI REG_Y)
5329 (clobber (reg:QI REG_Z))]
5332 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5333 [(set_attr "length" "2,3")
5334 (set_attr "cc" "clobber")
5335 (set_attr "isa" "rjmp,jmp")])
5338 (define_insn "return"
5340 "reload_completed && avr_simple_epilogue ()"
5342 [(set_attr "cc" "none")
5343 (set_attr "length" "1")])
5345 (define_insn "return_from_epilogue"
5349 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5350 && !cfun->machine->is_naked)"
5352 [(set_attr "cc" "none")
5353 (set_attr "length" "1")])
5355 (define_insn "return_from_interrupt_epilogue"
5359 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5360 && !cfun->machine->is_naked)"
5362 [(set_attr "cc" "none")
5363 (set_attr "length" "1")])
5365 (define_insn "return_from_naked_epilogue"
5369 && cfun->machine->is_naked)"
5371 [(set_attr "cc" "none")
5372 (set_attr "length" "0")])
5374 (define_expand "prologue"
5382 (define_expand "epilogue"
5386 expand_epilogue (false /* sibcall_p */);
5390 (define_expand "sibcall_epilogue"
5394 expand_epilogue (true /* sibcall_p */);
5398 ;; Some instructions resp. instruction sequences available
5401 (define_insn "delay_cycles_1"
5402 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5404 UNSPECV_DELAY_CYCLES)
5405 (set (match_operand:BLK 1 "" "")
5406 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
5407 (clobber (match_scratch:QI 2 "=&d"))]
5412 [(set_attr "length" "3")
5413 (set_attr "cc" "clobber")])
5415 (define_insn "delay_cycles_2"
5416 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5418 UNSPECV_DELAY_CYCLES)
5419 (set (match_operand:BLK 1 "" "")
5420 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
5421 (clobber (match_scratch:HI 2 "=&w"))]
5427 [(set_attr "length" "4")
5428 (set_attr "cc" "clobber")])
5430 (define_insn "delay_cycles_3"
5431 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5433 UNSPECV_DELAY_CYCLES)
5434 (set (match_operand:BLK 1 "" "")
5435 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
5436 (clobber (match_scratch:QI 2 "=&d"))
5437 (clobber (match_scratch:QI 3 "=&d"))
5438 (clobber (match_scratch:QI 4 "=&d"))]
5447 [(set_attr "length" "7")
5448 (set_attr "cc" "clobber")])
5450 (define_insn "delay_cycles_4"
5451 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5453 UNSPECV_DELAY_CYCLES)
5454 (set (match_operand:BLK 1 "" "")
5455 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))
5456 (clobber (match_scratch:QI 2 "=&d"))
5457 (clobber (match_scratch:QI 3 "=&d"))
5458 (clobber (match_scratch:QI 4 "=&d"))
5459 (clobber (match_scratch:QI 5 "=&d"))]
5470 [(set_attr "length" "9")
5471 (set_attr "cc" "clobber")])
5474 ;; __builtin_avr_insert_bits
5476 (define_insn "insert_bits"
5477 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5478 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5479 (match_operand:QI 2 "register_operand" "r ,r ,r")
5480 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5481 UNSPEC_INSERT_BITS))]
5484 return avr_out_insert_bits (operands, NULL);
5486 [(set_attr "adjust_len" "insert_bits")
5487 (set_attr "cc" "clobber")])
5490 ;; __builtin_avr_flash_segment
5492 ;; Just a helper for the next "official" expander.
5494 (define_expand "flash_segment1"
5495 [(set (match_operand:QI 0 "register_operand" "")
5496 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5499 (compare (match_dup 0)
5502 (if_then_else (ge (cc0)
5504 (label_ref (match_operand 2 "" ""))
5509 (define_expand "flash_segment"
5510 [(parallel [(match_operand:QI 0 "register_operand" "")
5511 (match_operand:PSI 1 "register_operand" "")])]
5514 rtx label = gen_label_rtx ();
5515 emit (gen_flash_segment1 (operands[0], operands[1], label));
5520 ;; Actually, it's too late now to work out address spaces known at compiletime.
5521 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5522 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5523 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5525 (define_insn_and_split "*split.flash_segment"
5526 [(set (match_operand:QI 0 "register_operand" "=d")
5527 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5528 (match_operand:HI 2 "register_operand" "r"))
5531 { gcc_unreachable(); }
5539 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5540 ;; better 8-bit parity recognition.
5542 (define_expand "parityhi2"
5543 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5544 (parity:HI (match_operand:HI 1 "register_operand" "")))
5545 (clobber (reg:HI 24))])])
5547 (define_insn_and_split "*parityhi2"
5548 [(set (match_operand:HI 0 "register_operand" "=r")
5549 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5550 (clobber (reg:HI 24))]
5552 { gcc_unreachable(); }
5557 (parity:HI (reg:HI 24)))
5561 (define_insn_and_split "*parityqihi2"
5562 [(set (match_operand:HI 0 "register_operand" "=r")
5563 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5564 (clobber (reg:HI 24))]
5566 { gcc_unreachable(); }
5571 (zero_extend:HI (parity:QI (reg:QI 24))))
5575 (define_expand "paritysi2"
5577 (match_operand:SI 1 "register_operand" ""))
5579 (truncate:HI (parity:SI (reg:SI 22))))
5582 (set (match_operand:SI 0 "register_operand" "")
5583 (zero_extend:SI (match_dup 2)))]
5586 operands[2] = gen_reg_rtx (HImode);
5589 (define_insn "*parityhi2.libgcc"
5591 (parity:HI (reg:HI 24)))]
5593 "%~call __parityhi2"
5594 [(set_attr "type" "xcall")
5595 (set_attr "cc" "clobber")])
5597 (define_insn "*parityqihi2.libgcc"
5599 (zero_extend:HI (parity:QI (reg:QI 24))))]
5601 "%~call __parityqi2"
5602 [(set_attr "type" "xcall")
5603 (set_attr "cc" "clobber")])
5605 (define_insn "*paritysihi2.libgcc"
5607 (truncate:HI (parity:SI (reg:SI 22))))]
5609 "%~call __paritysi2"
5610 [(set_attr "type" "xcall")
5611 (set_attr "cc" "clobber")])
5616 (define_expand "popcounthi2"
5618 (match_operand:HI 1 "register_operand" ""))
5620 (popcount:HI (reg:HI 24)))
5621 (set (match_operand:HI 0 "register_operand" "")
5626 (define_expand "popcountsi2"
5628 (match_operand:SI 1 "register_operand" ""))
5630 (truncate:HI (popcount:SI (reg:SI 22))))
5633 (set (match_operand:SI 0 "register_operand" "")
5634 (zero_extend:SI (match_dup 2)))]
5637 operands[2] = gen_reg_rtx (HImode);
5640 (define_insn "*popcounthi2.libgcc"
5642 (popcount:HI (reg:HI 24)))]
5644 "%~call __popcounthi2"
5645 [(set_attr "type" "xcall")
5646 (set_attr "cc" "clobber")])
5648 (define_insn "*popcountsi2.libgcc"
5650 (truncate:HI (popcount:SI (reg:SI 22))))]
5652 "%~call __popcountsi2"
5653 [(set_attr "type" "xcall")
5654 (set_attr "cc" "clobber")])
5656 (define_insn "*popcountqi2.libgcc"
5658 (popcount:QI (reg:QI 24)))]
5660 "%~call __popcountqi2"
5661 [(set_attr "type" "xcall")
5662 (set_attr "cc" "clobber")])
5664 (define_insn_and_split "*popcountqihi2.libgcc"
5666 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5671 (popcount:QI (reg:QI 24)))
5676 ;; Count Leading Zeros
5678 (define_expand "clzhi2"
5680 (match_operand:HI 1 "register_operand" ""))
5681 (parallel [(set (reg:HI 24)
5682 (clz:HI (reg:HI 24)))
5683 (clobber (reg:QI 26))])
5684 (set (match_operand:HI 0 "register_operand" "")
5689 (define_expand "clzsi2"
5691 (match_operand:SI 1 "register_operand" ""))
5692 (parallel [(set (reg:HI 24)
5693 (truncate:HI (clz:SI (reg:SI 22))))
5694 (clobber (reg:QI 26))])
5697 (set (match_operand:SI 0 "register_operand" "")
5698 (zero_extend:SI (match_dup 2)))]
5701 operands[2] = gen_reg_rtx (HImode);
5704 (define_insn "*clzhi2.libgcc"
5706 (clz:HI (reg:HI 24)))
5707 (clobber (reg:QI 26))]
5710 [(set_attr "type" "xcall")
5711 (set_attr "cc" "clobber")])
5713 (define_insn "*clzsihi2.libgcc"
5715 (truncate:HI (clz:SI (reg:SI 22))))
5716 (clobber (reg:QI 26))]
5719 [(set_attr "type" "xcall")
5720 (set_attr "cc" "clobber")])
5722 ;; Count Trailing Zeros
5724 (define_expand "ctzhi2"
5726 (match_operand:HI 1 "register_operand" ""))
5727 (parallel [(set (reg:HI 24)
5728 (ctz:HI (reg:HI 24)))
5729 (clobber (reg:QI 26))])
5730 (set (match_operand:HI 0 "register_operand" "")
5735 (define_expand "ctzsi2"
5737 (match_operand:SI 1 "register_operand" ""))
5738 (parallel [(set (reg:HI 24)
5739 (truncate:HI (ctz:SI (reg:SI 22))))
5740 (clobber (reg:QI 22))
5741 (clobber (reg:QI 26))])
5744 (set (match_operand:SI 0 "register_operand" "")
5745 (zero_extend:SI (match_dup 2)))]
5748 operands[2] = gen_reg_rtx (HImode);
5751 (define_insn "*ctzhi2.libgcc"
5753 (ctz:HI (reg:HI 24)))
5754 (clobber (reg:QI 26))]
5757 [(set_attr "type" "xcall")
5758 (set_attr "cc" "clobber")])
5760 (define_insn "*ctzsihi2.libgcc"
5762 (truncate:HI (ctz:SI (reg:SI 22))))
5763 (clobber (reg:QI 22))
5764 (clobber (reg:QI 26))]
5767 [(set_attr "type" "xcall")
5768 (set_attr "cc" "clobber")])
5772 (define_expand "ffshi2"
5774 (match_operand:HI 1 "register_operand" ""))
5775 (parallel [(set (reg:HI 24)
5776 (ffs:HI (reg:HI 24)))
5777 (clobber (reg:QI 26))])
5778 (set (match_operand:HI 0 "register_operand" "")
5783 (define_expand "ffssi2"
5785 (match_operand:SI 1 "register_operand" ""))
5786 (parallel [(set (reg:HI 24)
5787 (truncate:HI (ffs:SI (reg:SI 22))))
5788 (clobber (reg:QI 22))
5789 (clobber (reg:QI 26))])
5792 (set (match_operand:SI 0 "register_operand" "")
5793 (zero_extend:SI (match_dup 2)))]
5796 operands[2] = gen_reg_rtx (HImode);
5799 (define_insn "*ffshi2.libgcc"
5801 (ffs:HI (reg:HI 24)))
5802 (clobber (reg:QI 26))]
5805 [(set_attr "type" "xcall")
5806 (set_attr "cc" "clobber")])
5808 (define_insn "*ffssihi2.libgcc"
5810 (truncate:HI (ffs:SI (reg:SI 22))))
5811 (clobber (reg:QI 22))
5812 (clobber (reg:QI 26))]
5815 [(set_attr "type" "xcall")
5816 (set_attr "cc" "clobber")])
5820 (define_insn "copysignsf3"
5821 [(set (match_operand:SF 0 "register_operand" "=r")
5822 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5823 (match_operand:SF 2 "register_operand" "r")]
5826 "bst %D2,7\;bld %D0,7"
5827 [(set_attr "length" "2")
5828 (set_attr "cc" "none")])
5830 ;; Swap Bytes (change byte-endianess)
5832 (define_expand "bswapsi2"
5834 (match_operand:SI 1 "register_operand" ""))
5836 (bswap:SI (reg:SI 22)))
5837 (set (match_operand:SI 0 "register_operand" "")
5842 (define_insn "*bswapsi2.libgcc"
5844 (bswap:SI (reg:SI 22)))]
5847 [(set_attr "type" "xcall")
5848 (set_attr "cc" "clobber")])
5853 ;; NOP taking 1 or 2 Ticks
5854 (define_expand "nopv"
5855 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5858 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))])]
5861 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5862 MEM_VOLATILE_P (operands[1]) = 1;
5865 (define_insn "*nopv"
5866 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5868 (set (match_operand:BLK 1 "" "")
5869 (unspec:BLK [(match_dup 1)] UNSPEC_MEMORY_BARRIER))]
5874 [(set_attr "length" "1")
5875 (set_attr "cc" "none")])
5878 (define_expand "sleep"
5879 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5881 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))])]
5884 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5885 MEM_VOLATILE_P (operands[0]) = 1;
5888 (define_insn "*sleep"
5889 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5890 (set (match_operand:BLK 0 "" "")
5891 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
5894 [(set_attr "length" "1")
5895 (set_attr "cc" "none")])
5898 (define_expand "wdr"
5899 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5901 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))])]
5904 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5905 MEM_VOLATILE_P (operands[0]) = 1;
5909 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5910 (set (match_operand:BLK 0 "" "")
5911 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))]
5914 [(set_attr "length" "1")
5915 (set_attr "cc" "none")])
5918 (define_expand "fmul"
5920 (match_operand:QI 1 "register_operand" ""))
5922 (match_operand:QI 2 "register_operand" ""))
5923 (parallel [(set (reg:HI 22)
5924 (unspec:HI [(reg:QI 24)
5925 (reg:QI 25)] UNSPEC_FMUL))
5926 (clobber (reg:HI 24))])
5927 (set (match_operand:HI 0 "register_operand" "")
5933 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5938 (define_insn "fmul_insn"
5939 [(set (match_operand:HI 0 "register_operand" "=r")
5940 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5941 (match_operand:QI 2 "register_operand" "a")]
5947 [(set_attr "length" "3")
5948 (set_attr "cc" "clobber")])
5950 (define_insn "*fmul.call"
5952 (unspec:HI [(reg:QI 24)
5953 (reg:QI 25)] UNSPEC_FMUL))
5954 (clobber (reg:HI 24))]
5957 [(set_attr "type" "xcall")
5958 (set_attr "cc" "clobber")])
5961 (define_expand "fmuls"
5963 (match_operand:QI 1 "register_operand" ""))
5965 (match_operand:QI 2 "register_operand" ""))
5966 (parallel [(set (reg:HI 22)
5967 (unspec:HI [(reg:QI 24)
5968 (reg:QI 25)] UNSPEC_FMULS))
5969 (clobber (reg:HI 24))])
5970 (set (match_operand:HI 0 "register_operand" "")
5976 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5981 (define_insn "fmuls_insn"
5982 [(set (match_operand:HI 0 "register_operand" "=r")
5983 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5984 (match_operand:QI 2 "register_operand" "a")]
5990 [(set_attr "length" "3")
5991 (set_attr "cc" "clobber")])
5993 (define_insn "*fmuls.call"
5995 (unspec:HI [(reg:QI 24)
5996 (reg:QI 25)] UNSPEC_FMULS))
5997 (clobber (reg:HI 24))]
6000 [(set_attr "type" "xcall")
6001 (set_attr "cc" "clobber")])
6004 (define_expand "fmulsu"
6006 (match_operand:QI 1 "register_operand" ""))
6008 (match_operand:QI 2 "register_operand" ""))
6009 (parallel [(set (reg:HI 22)
6010 (unspec:HI [(reg:QI 24)
6011 (reg:QI 25)] UNSPEC_FMULSU))
6012 (clobber (reg:HI 24))])
6013 (set (match_operand:HI 0 "register_operand" "")
6019 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6024 (define_insn "fmulsu_insn"
6025 [(set (match_operand:HI 0 "register_operand" "=r")
6026 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6027 (match_operand:QI 2 "register_operand" "a")]
6033 [(set_attr "length" "3")
6034 (set_attr "cc" "clobber")])
6036 (define_insn "*fmulsu.call"
6038 (unspec:HI [(reg:QI 24)
6039 (reg:QI 25)] UNSPEC_FMULSU))
6040 (clobber (reg:HI 24))]
6043 [(set_attr "type" "xcall")
6044 (set_attr "cc" "clobber")])
6047 ;; Some combiner patterns dealing with bits.
6050 ;; Move bit $3.0 into bit $0.$4
6051 (define_insn "*movbitqi.1-6.a"
6052 [(set (match_operand:QI 0 "register_operand" "=r")
6053 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6054 (match_operand:QI 2 "single_zero_operand" "n"))
6055 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6056 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6057 (match_operand:QI 5 "single_one_operand" "n"))))]
6058 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6059 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6060 "bst %3,0\;bld %0,%4"
6061 [(set_attr "length" "2")
6062 (set_attr "cc" "none")])
6064 ;; Move bit $3.0 into bit $0.$4
6065 ;; Variation of above. Unfortunately, there is no canonicalized representation
6066 ;; of moving around bits. So what we see here depends on how user writes down
6067 ;; bit manipulations.
6068 (define_insn "*movbitqi.1-6.b"
6069 [(set (match_operand:QI 0 "register_operand" "=r")
6070 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6071 (match_operand:QI 2 "single_zero_operand" "n"))
6072 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6074 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6075 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6076 "bst %3,0\;bld %0,%4"
6077 [(set_attr "length" "2")
6078 (set_attr "cc" "none")])
6080 ;; Move bit $3.0 into bit $0.0.
6081 ;; For bit 0, combiner generates slightly different pattern.
6082 (define_insn "*movbitqi.0"
6083 [(set (match_operand:QI 0 "register_operand" "=r")
6084 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6085 (match_operand:QI 2 "single_zero_operand" "n"))
6086 (and:QI (match_operand:QI 3 "register_operand" "r")
6088 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6089 "bst %3,0\;bld %0,0"
6090 [(set_attr "length" "2")
6091 (set_attr "cc" "none")])
6093 ;; Move bit $2.0 into bit $0.7.
6094 ;; For bit 7, combiner generates slightly different pattern
6095 (define_insn "*movbitqi.7"
6096 [(set (match_operand:QI 0 "register_operand" "=r")
6097 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6099 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6102 "bst %2,0\;bld %0,7"
6103 [(set_attr "length" "2")
6104 (set_attr "cc" "none")])
6106 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6107 ;; and input/output match. We provide a special pattern for this, because
6108 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6109 ;; operation on I/O is atomic.
6110 (define_insn "*insv.io"
6111 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6113 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6114 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6119 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6120 [(set_attr "length" "1,1,4")
6121 (set_attr "cc" "none")])
6123 (define_insn "*insv.not.io"
6124 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6126 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6127 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6129 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6130 [(set_attr "length" "4")
6131 (set_attr "cc" "none")])
6133 ;; The insv expander.
6134 ;; We only support 1-bit inserts
6135 (define_expand "insv"
6136 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6137 (match_operand:QI 1 "const1_operand" "") ; width
6138 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6139 (match_operand:QI 3 "nonmemory_operand" ""))]
6143 ;; Insert bit $2.0 into $0.$1
6144 (define_insn "*insv.reg"
6145 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6147 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6148 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6152 andi %0,lo8(~(1<<%1))
6156 [(set_attr "length" "2,1,1,2,2")
6157 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6160 ;; Some combine patterns that try to fix bad code when a value is composed
6161 ;; from byte parts like in PR27663.
6162 ;; The patterns give some release but the code still is not optimal,
6163 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6164 ;; That switch obfuscates things here and in many other places.
6166 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6167 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6168 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6169 [(set (match_operand:HISI 0 "register_operand" "=r")
6171 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6172 (match_operand:HISI 2 "register_operand" "0")))]
6177 (xior:QI (match_dup 3)
6180 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6183 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6184 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6185 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6186 [(set (match_operand:HISI 0 "register_operand" "=r")
6188 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6189 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6190 (match_operand:HISI 3 "register_operand" "0")))]
6191 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6193 "&& reload_completed"
6195 (xior:QI (match_dup 4)
6198 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6199 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6202 (define_expand "extzv"
6203 [(set (match_operand:QI 0 "register_operand" "")
6204 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6205 (match_operand:QI 2 "const1_operand" "")
6206 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6210 (define_insn "*extzv"
6211 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6212 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6214 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6218 mov %0,%1\;andi %0,1
6221 bst %1,%2\;clr %0\;bld %0,0"
6222 [(set_attr "length" "1,2,2,2,3")
6223 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6225 (define_insn_and_split "*extzv.qihi1"
6226 [(set (match_operand:HI 0 "register_operand" "=r")
6227 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6229 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6234 (zero_extract:QI (match_dup 1)
6240 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6241 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6244 (define_insn_and_split "*extzv.qihi2"
6245 [(set (match_operand:HI 0 "register_operand" "=r")
6247 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6249 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6254 (zero_extract:QI (match_dup 1)
6260 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6261 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6265 (include "avr-dimode.md")