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 address 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"
75 (define_c_enum "unspecv"
76 [UNSPECV_PROLOGUE_SAVES
77 UNSPECV_EPILOGUE_RESTORES
81 UNSPECV_MEMORY_BARRIER
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,
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, plus, addto_sp,
142 tsthi, tstpsi, tstsi, compare, compare64, call,
143 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
145 xload, movmem, load_lpm,
146 ashlqi, ashrqi, lshrqi,
147 ashlhi, ashrhi, lshrhi,
148 ashlsi, ashrsi, lshrsi,
149 ashlpsi, ashrpsi, lshrpsi,
154 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
156 ;; mov : ISA has no MOVW movw : ISA has MOVW
157 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
158 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
159 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
160 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
161 ;; no_xmega: non-XMEGA core xmega : XMEGA core
164 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
166 (const_string "standard"))
168 (define_attr "enabled" ""
169 (cond [(eq_attr "isa" "standard")
172 (and (eq_attr "isa" "mov")
173 (match_test "!AVR_HAVE_MOVW"))
176 (and (eq_attr "isa" "movw")
177 (match_test "AVR_HAVE_MOVW"))
180 (and (eq_attr "isa" "rjmp")
181 (match_test "!AVR_HAVE_JMP_CALL"))
184 (and (eq_attr "isa" "jmp")
185 (match_test "AVR_HAVE_JMP_CALL"))
188 (and (eq_attr "isa" "ijmp")
189 (match_test "!AVR_HAVE_EIJMP_EICALL"))
192 (and (eq_attr "isa" "eijmp")
193 (match_test "AVR_HAVE_EIJMP_EICALL"))
196 (and (eq_attr "isa" "lpm")
197 (match_test "!AVR_HAVE_LPMX"))
200 (and (eq_attr "isa" "lpmx")
201 (match_test "AVR_HAVE_LPMX"))
204 (and (eq_attr "isa" "elpm")
205 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
208 (and (eq_attr "isa" "elpmx")
209 (match_test "AVR_HAVE_ELPMX"))
212 (and (eq_attr "isa" "xmega")
213 (match_test "AVR_XMEGA"))
216 (and (eq_attr "isa" "no_xmega")
217 (match_test "!AVR_XMEGA"))
222 ;; Define mode iterators
223 (define_mode_iterator QIHI [(QI "") (HI "")])
224 (define_mode_iterator QIHI2 [(QI "") (HI "")])
225 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
226 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
227 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
229 (define_mode_iterator ALL1 [(QI "") (QQ "") (UQQ "")])
230 (define_mode_iterator ALL2 [(HI "") (HQ "") (UHQ "") (HA "") (UHA "")])
231 (define_mode_iterator ALL4 [(SI "") (SQ "") (USQ "") (SA "") (USA "")])
233 ;; All supported move-modes
234 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")
236 (HQ "") (UHQ "") (HA "") (UHA "")
237 (SQ "") (USQ "") (SA "") (USA "")])
239 ;; Supported ordered modes that are 2, 3, 4 bytes wide
240 (define_mode_iterator ORDERED234 [(HI "") (SI "") (PSI "")
241 (HQ "") (UHQ "") (HA "") (UHA "")
242 (SQ "") (USQ "") (SA "") (USA "")])
244 ;; Define code iterators
245 ;; Define two incarnations so that we can build the cross product.
246 (define_code_iterator any_extend [sign_extend zero_extend])
247 (define_code_iterator any_extend2 [sign_extend zero_extend])
249 (define_code_iterator xior [xor ior])
250 (define_code_iterator eqne [eq ne])
252 (define_code_iterator ss_addsub [ss_plus ss_minus])
253 (define_code_iterator us_addsub [us_plus us_minus])
254 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
256 ;; Define code attributes
257 (define_code_attr extend_su
261 (define_code_attr extend_u
265 (define_code_attr extend_s
269 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
270 (define_code_attr mul_r_d
274 (define_code_attr abelian
275 [(ss_minus "") (us_minus "")
276 (ss_plus "%") (us_plus "%")])
278 ;; Map RTX code to its standard insn name
279 (define_code_attr code_stdname
286 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
287 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
290 ;;========================================================================
291 ;; The following is used by nonlocal_goto and setjmp.
292 ;; The receiver pattern will create no instructions since internally
293 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
294 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
295 ;; The 'null' receiver also avoids problems with optimisation
296 ;; not recognising incoming jmp and removing code that resets frame_pointer.
297 ;; The code derived from builtins.c.
299 (define_expand "nonlocal_goto_receiver"
301 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
304 emit_move_insn (virtual_stack_vars_rtx,
305 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
306 gen_int_mode (STARTING_FRAME_OFFSET,
308 /* This might change the hard frame pointer in ways that aren't
309 apparent to early optimization passes, so force a clobber. */
310 emit_clobber (hard_frame_pointer_rtx);
315 ;; Defining nonlocal_goto_receiver means we must also define this.
316 ;; even though its function is identical to that in builtins.c
318 (define_expand "nonlocal_goto"
319 [(use (match_operand 0 "general_operand"))
320 (use (match_operand 1 "general_operand"))
321 (use (match_operand 2 "general_operand"))
322 (use (match_operand 3 "general_operand"))]
325 rtx r_label = copy_to_reg (operands[1]);
326 rtx r_fp = operands[3];
327 rtx r_sp = operands[2];
329 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
331 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
333 emit_move_insn (hard_frame_pointer_rtx, r_fp);
334 emit_stack_restore (SAVE_NONLOCAL, r_sp);
336 emit_use (hard_frame_pointer_rtx);
337 emit_use (stack_pointer_rtx);
339 emit_indirect_jump (r_label);
345 ;; "pushqq1" "pushuqq1"
346 (define_insn "push<mode>1"
347 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
348 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
353 [(set_attr "length" "1,1")])
355 ;; All modes for a multi-byte push. We must include complex modes here too,
356 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
357 (define_mode_iterator MPUSH
364 (HA "") (UHA "") (HQ "") (UHQ "")
365 (SA "") (USA "") (SQ "") (USQ "")
366 (DA "") (UDA "") (DQ "") (UDQ "")
369 (define_expand "push<mode>1"
370 [(match_operand:MPUSH 0 "" "")]
374 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
376 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
377 if (part != const0_rtx)
378 part = force_reg (QImode, part);
379 emit_insn (gen_pushqi1 (part));
384 ;; Notice a special-case when adding N to SP where N results in a
385 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
387 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
389 && frame_pointer_needed
390 && !cfun->calls_alloca
391 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
392 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
395 ;;========================================================================
398 ;; Represent a load from __flash that needs libgcc support as UNSPEC.
399 ;; This is legal because we read from non-changing memory.
400 ;; For rationale see the FIXME below.
405 (define_insn "load_<mode>_libgcc"
406 [(set (reg:MOVMODE 22)
407 (unspec:MOVMODE [(reg:HI REG_Z)]
411 rtx n_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
412 output_asm_insn ("%~call __load_%0", &n_bytes);
415 [(set_attr "type" "xcall")
416 (set_attr "cc" "clobber")])
419 ;; Similar for inline reads from flash. We use UNSPEC instead
420 ;; of MEM for the same reason as above: PR52543.
421 ;; $1 contains the memory segment.
423 (define_insn "load_<mode>"
424 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
425 (unspec:MOVMODE [(reg:HI REG_Z)
426 (match_operand:QI 1 "reg_or_0_operand" "rL")]
428 "(CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
429 || (REG_P (operands[1]) && AVR_HAVE_ELPMX)"
431 return avr_load_lpm (insn, operands, NULL);
433 [(set_attr "adjust_len" "load_lpm")
434 (set_attr "cc" "clobber")])
437 ;; Similar to above for the complementary situation when there is no [E]LPMx.
438 ;; Clobber Z in that case.
440 (define_insn "load_<mode>_clobber"
441 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
442 (unspec:MOVMODE [(reg:HI REG_Z)
443 (match_operand:QI 1 "reg_or_0_operand" "rL")]
445 (clobber (reg:HI REG_Z))]
446 "!((CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
447 || (REG_P (operands[1]) && AVR_HAVE_ELPMX))"
449 return avr_load_lpm (insn, operands, NULL);
451 [(set_attr "adjust_len" "load_lpm")
452 (set_attr "cc" "clobber")])
456 ;; "xload8qq_A" "xload8uqq_A"
457 (define_insn_and_split "xload8<mode>_A"
458 [(set (match_operand:ALL1 0 "register_operand" "=r")
459 (match_operand:ALL1 1 "memory_operand" "m"))
460 (clobber (reg:HI REG_Z))]
461 "can_create_pseudo_p()
462 && !avr_xload_libgcc_p (<MODE>mode)
463 && avr_mem_memx_p (operands[1])
464 && REG_P (XEXP (operands[1], 0))"
465 { gcc_unreachable(); }
467 [(clobber (const_int 0))]
469 rtx insn, addr = XEXP (operands[1], 0);
470 rtx hi8 = gen_reg_rtx (QImode);
471 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
473 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
474 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
476 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
477 set_mem_addr_space (SET_SRC (single_set (insn)),
478 MEM_ADDR_SPACE (operands[1]));
482 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
483 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
484 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
487 (define_insn_and_split "xload<mode>_A"
488 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
489 (match_operand:MOVMODE 1 "memory_operand" "m"))
490 (clobber (reg:MOVMODE 22))
491 (clobber (reg:QI 21))
492 (clobber (reg:HI REG_Z))]
493 "can_create_pseudo_p()
494 && avr_mem_memx_p (operands[1])
495 && REG_P (XEXP (operands[1], 0))"
496 { gcc_unreachable(); }
498 [(clobber (const_int 0))]
500 rtx addr = XEXP (operands[1], 0);
501 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
502 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
503 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
506 /* Split the address to R21:Z */
507 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
508 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
510 /* Load with code from libgcc */
511 insn = emit_insn (gen_xload_<mode>_libgcc ());
512 set_mem_addr_space (SET_SRC (single_set (insn)), as);
514 /* Move to destination */
515 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
520 ;; Move value from address space memx to a register
521 ;; These insns must be prior to respective generic move insn.
524 ;; "xloadqq_8" "xloaduqq_8"
525 (define_insn "xload<mode>_8"
526 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
527 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
529 "!avr_xload_libgcc_p (<MODE>mode)"
531 return avr_out_xload (insn, operands, NULL);
533 [(set_attr "length" "4,4")
534 (set_attr "adjust_len" "*,xload")
535 (set_attr "isa" "lpmx,lpm")
536 (set_attr "cc" "none")])
538 ;; R21:Z : 24-bit source address
539 ;; R22 : 1-4 byte output
541 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
542 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
543 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
545 ;; "xload_psi_libgcc"
546 (define_insn "xload_<mode>_libgcc"
547 [(set (reg:MOVMODE 22)
548 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
550 (clobber (reg:QI 21))
551 (clobber (reg:HI REG_Z))]
552 "avr_xload_libgcc_p (<MODE>mode)"
554 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
556 output_asm_insn ("%~call __xload_%0", &x_bytes);
559 [(set_attr "type" "xcall")
560 (set_attr "cc" "clobber")])
563 ;; General move expanders
565 ;; "movqi" "movqq" "movuqq"
566 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
567 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
570 (define_expand "mov<mode>"
571 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
572 (match_operand:MOVMODE 1 "general_operand" ""))]
575 rtx dest = operands[0];
576 rtx src = operands[1];
578 if (avr_mem_flash_p (dest))
581 /* One of the operands has to be in a register. */
582 if (!register_operand (dest, <MODE>mode)
583 && !reg_or_0_operand (src, <MODE>mode))
585 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
588 if (avr_mem_memx_p (src))
590 rtx addr = XEXP (src, 0);
593 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
595 if (!avr_xload_libgcc_p (<MODE>mode))
596 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
597 ; insn-emit does not depend on the mode, it' all about operands. */
598 emit_insn (gen_xload8qi_A (dest, src));
600 emit_insn (gen_xload<mode>_A (dest, src));
605 /* For old devices without LPMx, prefer __flash loads per libcall. */
607 if (avr_load_libgcc_p (src))
609 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
610 force_reg (Pmode, XEXP (src, 0)));
612 emit_insn (gen_load_<mode>_libgcc ());
613 emit_move_insn (dest, gen_rtx_REG (<MODE>mode, 22));
617 /* ; FIXME: Hack around PR rtl-optimization/52543.
618 ; lower-subreg.c splits loads from the 16-bit address spaces which
619 ; causes code bloat because each load need his setting of RAMPZ.
620 ; Moreover, the split will happen in such a way that the loads don't
621 ; take advantage of POST_INC addressing. Thus, we use UNSPEC to
622 ; represent these loads instead. Notice that this is legitimate
623 ; because the memory content does not change: Loads from the same
624 ; address will yield the same value.
625 ; POST_INC addressing would make the addresses mode_dependent and could
626 ; work around that PR, too. However, notice that it is *not* legitimate
627 ; to expand to POST_INC at expand time: The following passes assert
628 ; that pre-/post-modify addressing is introduced by .auto_inc_dec and
629 ; does not exist before that pass. */
631 if (avr_mem_flash_p (src)
632 && (GET_MODE_SIZE (<MODE>mode) > 1
633 || MEM_ADDR_SPACE (src) != ADDR_SPACE_FLASH))
635 rtx xsegment = GEN_INT (avr_addrspace[MEM_ADDR_SPACE (src)].segment);
637 xsegment = const0_rtx;
638 if (xsegment != const0_rtx)
639 xsegment = force_reg (QImode, xsegment);
641 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
642 force_reg (Pmode, XEXP (src, 0)));
644 if ((CONST_INT_P (xsegment) && AVR_HAVE_LPMX)
645 || (REG_P (xsegment) && AVR_HAVE_ELPMX))
646 emit_insn (gen_load_<mode> (dest, xsegment));
648 emit_insn (gen_load_<mode>_clobber (dest, xsegment));
652 /* ; The only address-space for which we use plain MEM and reload
653 ; machinery are 1-byte loads from __flash. */
656 ;;========================================================================
658 ;; The last alternative (any immediate constant to any register) is
659 ;; very expensive. It should be optimized by peephole2 if a scratch
660 ;; register is available, but then that register could just as well be
661 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
662 ;; are call-saved registers, and most of LD_REGS are call-used registers,
663 ;; so this may still be a win for registers live across function calls.
666 ;; "movqq_insn" "movuqq_insn"
667 (define_insn "mov<mode>_insn"
668 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
669 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
670 "register_operand (operands[0], <MODE>mode)
671 || reg_or_0_operand (operands[1], <MODE>mode)"
673 return output_movqi (insn, operands, NULL);
675 [(set_attr "length" "1,1,5,5,1,1,4")
676 (set_attr "adjust_len" "mov8")
677 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
679 ;; This is used in peephole2 to optimize loading immediate constants
680 ;; if a scratch register from LD_REGS happens to be available.
683 ;; "*reload_inqq" "*reload_inuqq"
684 (define_insn "*reload_in<mode>"
685 [(set (match_operand:ALL1 0 "register_operand" "=l")
686 (match_operand:ALL1 1 "const_operand" "i"))
687 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
691 [(set_attr "length" "2")
692 (set_attr "cc" "none")])
695 [(match_scratch:QI 2 "d")
696 (set (match_operand:ALL1 0 "l_register_operand" "")
697 (match_operand:ALL1 1 "const_operand" ""))]
698 ; No need for a clobber reg for 0x0, 0x01 or 0xff
699 "!satisfies_constraint_Y00 (operands[1])
700 && !satisfies_constraint_Y01 (operands[1])
701 && !satisfies_constraint_Ym1 (operands[1])"
702 [(parallel [(set (match_dup 0)
704 (clobber (match_dup 2))])])
706 ;;============================================================================
707 ;; move word (16 bit)
709 ;; Move register $1 to the Stack Pointer register SP.
710 ;; This insn is emit during function prologue/epilogue generation.
711 ;; $2 = 0: We know that IRQs are off
712 ;; $2 = 1: We know that IRQs are on
713 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
714 ;; $2 = -1: We don't know anything about IRQ on/off
715 ;; Always write SP via unspec, see PR50063
717 (define_insn "movhi_sp_r"
718 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
719 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
720 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
724 out %B0,%B1\;out %A0,%A1
725 cli\;out %B0,%B1\;sei\;out %A0,%A1
726 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
728 out %A0,%A1\;out %B0,%B1"
729 [(set_attr "length" "2,4,5,1,2")
730 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
731 (set_attr "cc" "none")])
734 [(match_scratch:QI 2 "d")
735 (set (match_operand:ALL2 0 "l_register_operand" "")
736 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
737 "operands[1] != CONST0_RTX (<MODE>mode)"
738 [(parallel [(set (match_dup 0)
740 (clobber (match_dup 2))])])
742 ;; '*' because it is not used in rtl generation, only in above peephole
744 ;; "*reload_inhq" "*reload_inuhq"
745 ;; "*reload_inha" "*reload_inuha"
746 (define_insn "*reload_in<mode>"
747 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
748 (match_operand:ALL2 1 "immediate_operand" "i"))
749 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
752 return output_reload_inhi (operands, operands[2], NULL);
754 [(set_attr "length" "4")
755 (set_attr "adjust_len" "reload_in16")
756 (set_attr "cc" "clobber")])
759 ;; "*movhq" "*movuhq"
760 ;; "*movha" "*movuha"
761 (define_insn "*mov<mode>"
762 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
763 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
764 "register_operand (operands[0], <MODE>mode)
765 || reg_or_0_operand (operands[1], <MODE>mode)"
767 return output_movhi (insn, operands, NULL);
769 [(set_attr "length" "2,2,6,7,2,6,5,2")
770 (set_attr "adjust_len" "mov16")
771 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
773 (define_peephole2 ; movw
774 [(set (match_operand:ALL1 0 "even_register_operand" "")
775 (match_operand:ALL1 1 "even_register_operand" ""))
776 (set (match_operand:ALL1 2 "odd_register_operand" "")
777 (match_operand:ALL1 3 "odd_register_operand" ""))]
779 && REGNO (operands[0]) == REGNO (operands[2]) - 1
780 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
784 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
785 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
788 (define_peephole2 ; movw_r
789 [(set (match_operand:ALL1 0 "odd_register_operand" "")
790 (match_operand:ALL1 1 "odd_register_operand" ""))
791 (set (match_operand:ALL1 2 "even_register_operand" "")
792 (match_operand:ALL1 3 "even_register_operand" ""))]
794 && REGNO (operands[2]) == REGNO (operands[0]) - 1
795 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
799 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
800 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
803 ;;==========================================================================
804 ;; xpointer move (24 bit)
806 (define_peephole2 ; *reload_inpsi
807 [(match_scratch:QI 2 "d")
808 (set (match_operand:PSI 0 "l_register_operand" "")
809 (match_operand:PSI 1 "immediate_operand" ""))
811 "operands[1] != const0_rtx
812 && operands[1] != constm1_rtx"
813 [(parallel [(set (match_dup 0)
815 (clobber (match_dup 2))])]
818 ;; '*' because it is not used in rtl generation.
819 (define_insn "*reload_inpsi"
820 [(set (match_operand:PSI 0 "register_operand" "=r")
821 (match_operand:PSI 1 "immediate_operand" "i"))
822 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
825 return avr_out_reload_inpsi (operands, operands[2], NULL);
827 [(set_attr "length" "6")
828 (set_attr "adjust_len" "reload_in24")
829 (set_attr "cc" "clobber")])
831 (define_insn "*movpsi"
832 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
833 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
834 "register_operand (operands[0], PSImode)
835 || register_operand (operands[1], PSImode)
836 || const0_rtx == operands[1]"
838 return avr_out_movpsi (insn, operands, NULL);
840 [(set_attr "length" "3,3,8,9,4,10")
841 (set_attr "adjust_len" "mov24")
842 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
844 ;;==========================================================================
845 ;; move double word (32 bit)
847 (define_peephole2 ; *reload_insi
848 [(match_scratch:QI 2 "d")
849 (set (match_operand:ALL4 0 "l_register_operand" "")
850 (match_operand:ALL4 1 "immediate_operand" ""))
852 "operands[1] != CONST0_RTX (<MODE>mode)"
853 [(parallel [(set (match_dup 0)
855 (clobber (match_dup 2))])])
857 ;; '*' because it is not used in rtl generation.
859 ;; "*reload_insq" "*reload_inusq"
860 ;; "*reload_insa" "*reload_inusa"
861 (define_insn "*reload_insi"
862 [(set (match_operand:ALL4 0 "register_operand" "=r")
863 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
864 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
867 return output_reload_insisf (operands, operands[2], NULL);
869 [(set_attr "length" "8")
870 (set_attr "adjust_len" "reload_in32")
871 (set_attr "cc" "clobber")])
875 ;; "*movsq" "*movusq"
876 ;; "*movsa" "*movusa"
877 (define_insn "*mov<mode>"
878 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
879 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
880 "register_operand (operands[0], <MODE>mode)
881 || reg_or_0_operand (operands[1], <MODE>mode)"
883 return output_movsisf (insn, operands, NULL);
885 [(set_attr "length" "4,4,8,9,4,10")
886 (set_attr "adjust_len" "mov32")
887 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
889 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
890 ;; move floating point numbers (32 bit)
892 (define_insn "*movsf"
893 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
894 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
895 "register_operand (operands[0], SFmode)
896 || reg_or_0_operand (operands[1], SFmode)"
898 return output_movsisf (insn, operands, NULL);
900 [(set_attr "length" "4,4,8,9,4,10")
901 (set_attr "adjust_len" "mov32")
902 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
904 (define_peephole2 ; *reload_insf
905 [(match_scratch:QI 2 "d")
906 (set (match_operand:SF 0 "l_register_operand" "")
907 (match_operand:SF 1 "const_double_operand" ""))
909 "operands[1] != CONST0_RTX (SFmode)"
910 [(parallel [(set (match_dup 0)
912 (clobber (match_dup 2))])])
914 ;; '*' because it is not used in rtl generation.
915 (define_insn "*reload_insf"
916 [(set (match_operand:SF 0 "register_operand" "=r")
917 (match_operand:SF 1 "const_double_operand" "F"))
918 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
921 return output_reload_insisf (operands, operands[2], NULL);
923 [(set_attr "length" "8")
924 (set_attr "adjust_len" "reload_in32")
925 (set_attr "cc" "clobber")])
927 ;;=========================================================================
928 ;; move string (like memcpy)
930 (define_expand "movmemhi"
931 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
932 (match_operand:BLK 1 "memory_operand" ""))
933 (use (match_operand:HI 2 "const_int_operand" ""))
934 (use (match_operand:HI 3 "const_int_operand" ""))])]
937 if (avr_emit_movmemhi (operands))
943 (define_mode_attr MOVMEM_r_d [(QI "r")
946 ;; $0 : Address Space
947 ;; $1, $2 : Loop register
948 ;; R30 : source address
949 ;; R26 : destination address
953 (define_insn "movmem_<mode>"
954 [(set (mem:BLK (reg:HI REG_X))
955 (mem:BLK (reg:HI REG_Z)))
956 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
958 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
959 (clobber (reg:HI REG_X))
960 (clobber (reg:HI REG_Z))
961 (clobber (reg:QI LPM_REGNO))
962 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
965 return avr_out_movmem (insn, operands, NULL);
967 [(set_attr "adjust_len" "movmem")
968 (set_attr "cc" "clobber")])
971 ;; $0 : Address Space
972 ;; $1 : RAMPZ RAM address
973 ;; R24 : #bytes and loop register
974 ;; R23:Z : 24-bit source address
975 ;; R26 : 16-bit destination address
979 (define_insn "movmemx_<mode>"
980 [(set (mem:BLK (reg:HI REG_X))
981 (mem:BLK (lo_sum:PSI (reg:QI 23)
983 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
986 (clobber (reg:HI REG_X))
987 (clobber (reg:HI REG_Z))
988 (clobber (reg:QI LPM_REGNO))
989 (clobber (reg:HI 24))
990 (clobber (reg:QI 23))
991 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
993 "%~call __movmemx_<mode>"
994 [(set_attr "type" "xcall")
995 (set_attr "cc" "clobber")])
998 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
999 ;; memset (%0, %2, %1)
1001 (define_expand "setmemhi"
1002 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1003 (match_operand 2 "const_int_operand" ""))
1004 (use (match_operand:HI 1 "const_int_operand" ""))
1005 (use (match_operand:HI 3 "const_int_operand" ""))
1006 (clobber (match_scratch:HI 4 ""))
1007 (clobber (match_dup 5))])]
1011 enum machine_mode mode;
1013 /* If value to set is not zero, use the library routine. */
1014 if (operands[2] != const0_rtx)
1017 if (!CONST_INT_P (operands[1]))
1020 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1021 operands[5] = gen_rtx_SCRATCH (mode);
1022 operands[1] = copy_to_mode_reg (mode,
1023 gen_int_mode (INTVAL (operands[1]), mode));
1024 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1025 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1029 (define_insn "*clrmemqi"
1030 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1032 (use (match_operand:QI 1 "register_operand" "r"))
1033 (use (match_operand:QI 2 "const_int_operand" "n"))
1034 (clobber (match_scratch:HI 3 "=0"))
1035 (clobber (match_scratch:QI 4 "=&1"))]
1037 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1038 [(set_attr "length" "3")
1039 (set_attr "cc" "clobber")])
1042 (define_insn "*clrmemhi"
1043 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1045 (use (match_operand:HI 1 "register_operand" "!w,d"))
1046 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1047 (clobber (match_scratch:HI 3 "=0,0"))
1048 (clobber (match_scratch:HI 4 "=&1,&1"))]
1051 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1052 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1053 [(set_attr "length" "3,4")
1054 (set_attr "cc" "clobber,clobber")])
1056 (define_expand "strlenhi"
1058 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1059 (match_operand:QI 2 "const_int_operand" "")
1060 (match_operand:HI 3 "immediate_operand" "")]
1063 (plus:HI (match_dup 4)
1065 (parallel [(set (match_operand:HI 0 "register_operand" "")
1066 (minus:HI (match_dup 4)
1068 (clobber (scratch:QI))])]
1072 if (operands[2] != const0_rtx)
1074 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1075 operands[1] = gen_rtx_MEM (BLKmode, addr);
1077 operands[4] = gen_reg_rtx (HImode);
1080 (define_insn "*strlenhi"
1081 [(set (match_operand:HI 0 "register_operand" "=e")
1082 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1084 (match_operand:HI 2 "immediate_operand" "i")]
1087 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1088 [(set_attr "length" "3")
1089 (set_attr "cc" "clobber")])
1091 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1095 ;; "addqq3" "adduqq3"
1096 (define_insn "add<mode>3"
1097 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1098 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1099 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1108 [(set_attr "length" "1,1,1,1,2,2")
1109 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1112 ;; "addhq3" "adduhq3"
1113 ;; "addha3" "adduha3"
1114 (define_expand "add<mode>3"
1115 [(set (match_operand:ALL2 0 "register_operand" "")
1116 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1117 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1120 if (CONST_INT_P (operands[2]))
1122 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1124 if (can_create_pseudo_p()
1125 && !stack_register_operand (operands[0], HImode)
1126 && !stack_register_operand (operands[1], HImode)
1127 && !d_register_operand (operands[0], HImode)
1128 && !d_register_operand (operands[1], HImode))
1130 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1135 if (CONST_FIXED_P (operands[2]))
1137 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1143 (define_insn "*addhi3_zero_extend"
1144 [(set (match_operand:HI 0 "register_operand" "=r")
1145 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1146 (match_operand:HI 2 "register_operand" "0")))]
1148 "add %A0,%1\;adc %B0,__zero_reg__"
1149 [(set_attr "length" "2")
1150 (set_attr "cc" "set_n")])
1152 (define_insn "*addhi3_zero_extend1"
1153 [(set (match_operand:HI 0 "register_operand" "=r")
1154 (plus:HI (match_operand:HI 1 "register_operand" "0")
1155 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1157 "add %A0,%2\;adc %B0,__zero_reg__"
1158 [(set_attr "length" "2")
1159 (set_attr "cc" "set_n")])
1161 (define_insn "*addhi3.sign_extend1"
1162 [(set (match_operand:HI 0 "register_operand" "=r")
1163 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1164 (match_operand:HI 2 "register_operand" "0")))]
1167 return reg_overlap_mentioned_p (operands[0], operands[1])
1168 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1169 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1171 [(set_attr "length" "5")
1172 (set_attr "cc" "clobber")])
1174 (define_insn "*addhi3_sp"
1175 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1176 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1177 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1180 return avr_out_addto_sp (operands, NULL);
1182 [(set_attr "length" "6")
1183 (set_attr "adjust_len" "addto_sp")])
1186 ;; "*addhq3" "*adduhq3"
1187 ;; "*addha3" "*adduha3"
1188 (define_insn "*add<mode>3"
1189 [(set (match_operand:ALL2 0 "register_operand" "=r,d,!w ,d")
1190 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1191 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1194 return avr_out_plus (insn, operands);
1196 [(set_attr "length" "2")
1197 (set_attr "adjust_len" "plus")
1198 (set_attr "cc" "plus")])
1200 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1201 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1202 ;; itself because that insn is special to reload.
1204 (define_peephole2 ; addhi3_clobber
1205 [(set (match_operand:ALL2 0 "d_register_operand" "")
1206 (match_operand:ALL2 1 "const_operand" ""))
1207 (set (match_operand:ALL2 2 "l_register_operand" "")
1208 (plus:ALL2 (match_dup 2)
1210 "peep2_reg_dead_p (2, operands[0])"
1211 [(parallel [(set (match_dup 2)
1212 (plus:ALL2 (match_dup 2)
1214 (clobber (match_dup 3))])]
1216 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1219 ;; Same, but with reload to NO_LD_REGS
1220 ;; Combine *reload_inhi with *addhi3
1222 (define_peephole2 ; addhi3_clobber
1223 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1224 (match_operand:ALL2 1 "const_operand" ""))
1225 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1226 (set (match_operand:ALL2 3 "l_register_operand" "")
1227 (plus:ALL2 (match_dup 3)
1229 "peep2_reg_dead_p (2, operands[0])"
1230 [(parallel [(set (match_dup 3)
1231 (plus:ALL2 (match_dup 3)
1233 (clobber (match_dup 2))])])
1236 ;; "addhq3_clobber" "adduhq3_clobber"
1237 ;; "addha3_clobber" "adduha3_clobber"
1238 (define_insn "add<mode>3_clobber"
1239 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1240 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1241 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1242 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1245 return avr_out_plus (insn, operands);
1247 [(set_attr "length" "4")
1248 (set_attr "adjust_len" "plus")
1249 (set_attr "cc" "plus")])
1253 ;; "addsq3" "addusq3"
1254 ;; "addsa3" "addusa3"
1255 (define_insn "add<mode>3"
1256 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1257 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1258 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1259 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1262 return avr_out_plus (insn, operands);
1264 [(set_attr "length" "4")
1265 (set_attr "adjust_len" "plus")
1266 (set_attr "cc" "plus")])
1268 (define_insn "*addpsi3_zero_extend.qi"
1269 [(set (match_operand:PSI 0 "register_operand" "=r")
1270 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1271 (match_operand:PSI 2 "register_operand" "0")))]
1273 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1274 [(set_attr "length" "3")
1275 (set_attr "cc" "set_n")])
1277 (define_insn "*addpsi3_zero_extend.hi"
1278 [(set (match_operand:PSI 0 "register_operand" "=r")
1279 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1280 (match_operand:PSI 2 "register_operand" "0")))]
1282 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1283 [(set_attr "length" "3")
1284 (set_attr "cc" "set_n")])
1286 (define_insn "*addpsi3_sign_extend.hi"
1287 [(set (match_operand:PSI 0 "register_operand" "=r")
1288 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1289 (match_operand:PSI 2 "register_operand" "0")))]
1291 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1292 [(set_attr "length" "5")
1293 (set_attr "cc" "set_n")])
1295 (define_insn "*addsi3_zero_extend"
1296 [(set (match_operand:SI 0 "register_operand" "=r")
1297 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1298 (match_operand:SI 2 "register_operand" "0")))]
1300 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1301 [(set_attr "length" "4")
1302 (set_attr "cc" "set_n")])
1304 (define_insn "*addsi3_zero_extend.hi"
1305 [(set (match_operand:SI 0 "register_operand" "=r")
1306 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1307 (match_operand:SI 2 "register_operand" "0")))]
1309 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1310 [(set_attr "length" "4")
1311 (set_attr "cc" "set_n")])
1313 (define_insn "addpsi3"
1314 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1315 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1316 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1317 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1320 return avr_out_plus (insn, operands);
1322 [(set_attr "length" "3")
1323 (set_attr "adjust_len" "plus")
1324 (set_attr "cc" "plus")])
1326 (define_insn "subpsi3"
1327 [(set (match_operand:PSI 0 "register_operand" "=r")
1328 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1329 (match_operand:PSI 2 "register_operand" "r")))]
1331 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1332 [(set_attr "length" "3")
1333 (set_attr "cc" "set_czn")])
1335 (define_insn "*subpsi3_zero_extend.qi"
1336 [(set (match_operand:PSI 0 "register_operand" "=r")
1337 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1338 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1340 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1341 [(set_attr "length" "3")
1342 (set_attr "cc" "set_czn")])
1344 (define_insn "*subpsi3_zero_extend.hi"
1345 [(set (match_operand:PSI 0 "register_operand" "=r")
1346 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1347 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1349 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1350 [(set_attr "length" "3")
1351 (set_attr "cc" "set_czn")])
1353 (define_insn "*subpsi3_sign_extend.hi"
1354 [(set (match_operand:PSI 0 "register_operand" "=r")
1355 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1356 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1358 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1359 [(set_attr "length" "5")
1360 (set_attr "cc" "set_czn")])
1362 ;-----------------------------------------------------------------------------
1366 ;; "subqq3" "subuqq3"
1367 (define_insn "sub<mode>3"
1368 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1369 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1370 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1379 [(set_attr "length" "1,1,1,1,2,2")
1380 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1383 ;; "subhq3" "subuhq3"
1384 ;; "subha3" "subuha3"
1385 (define_insn "sub<mode>3"
1386 [(set (match_operand:ALL2 0 "register_operand" "=r,d ,*r")
1387 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1388 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1389 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1392 return avr_out_plus (insn, operands);
1394 [(set_attr "adjust_len" "plus")
1395 (set_attr "cc" "plus")])
1397 (define_insn "*subhi3_zero_extend1"
1398 [(set (match_operand:HI 0 "register_operand" "=r")
1399 (minus:HI (match_operand:HI 1 "register_operand" "0")
1400 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1402 "sub %A0,%2\;sbc %B0,__zero_reg__"
1403 [(set_attr "length" "2")
1404 (set_attr "cc" "set_czn")])
1406 (define_insn "*subhi3.sign_extend2"
1407 [(set (match_operand:HI 0 "register_operand" "=r")
1408 (minus:HI (match_operand:HI 1 "register_operand" "0")
1409 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1412 return reg_overlap_mentioned_p (operands[0], operands[2])
1413 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1414 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1416 [(set_attr "length" "5")
1417 (set_attr "cc" "clobber")])
1420 ;; "subsq3" "subusq3"
1421 ;; "subsa3" "subusa3"
1422 (define_insn "sub<mode>3"
1423 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1424 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1425 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1426 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1429 return avr_out_plus (insn, operands);
1431 [(set_attr "adjust_len" "plus")
1432 (set_attr "cc" "plus")])
1434 (define_insn "*subsi3_zero_extend"
1435 [(set (match_operand:SI 0 "register_operand" "=r")
1436 (minus:SI (match_operand:SI 1 "register_operand" "0")
1437 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1439 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1440 [(set_attr "length" "4")
1441 (set_attr "cc" "set_czn")])
1443 (define_insn "*subsi3_zero_extend.hi"
1444 [(set (match_operand:SI 0 "register_operand" "=r")
1445 (minus:SI (match_operand:SI 1 "register_operand" "0")
1446 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1448 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1449 [(set_attr "length" "4")
1450 (set_attr "cc" "set_czn")])
1452 ;******************************************************************************
1455 (define_expand "mulqi3"
1456 [(set (match_operand:QI 0 "register_operand" "")
1457 (mult:QI (match_operand:QI 1 "register_operand" "")
1458 (match_operand:QI 2 "register_operand" "")))]
1463 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1468 (define_insn "*mulqi3_enh"
1469 [(set (match_operand:QI 0 "register_operand" "=r")
1470 (mult:QI (match_operand:QI 1 "register_operand" "r")
1471 (match_operand:QI 2 "register_operand" "r")))]
1476 [(set_attr "length" "3")
1477 (set_attr "cc" "clobber")])
1479 (define_expand "mulqi3_call"
1480 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1481 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1482 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1483 (clobber (reg:QI 22))])
1484 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1488 (define_insn "*mulqi3_call"
1489 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1490 (clobber (reg:QI 22))]
1493 [(set_attr "type" "xcall")
1494 (set_attr "cc" "clobber")])
1496 ;; "umulqi3_highpart"
1497 ;; "smulqi3_highpart"
1498 (define_insn "<extend_su>mulqi3_highpart"
1499 [(set (match_operand:QI 0 "register_operand" "=r")
1501 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1502 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1505 "mul<extend_s> %1,%2
1508 [(set_attr "length" "3")
1509 (set_attr "cc" "clobber")])
1512 ;; Used when expanding div or mod inline for some special values
1513 (define_insn "*subqi3.ashiftrt7"
1514 [(set (match_operand:QI 0 "register_operand" "=r")
1515 (minus:QI (match_operand:QI 1 "register_operand" "0")
1516 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1520 [(set_attr "length" "2")
1521 (set_attr "cc" "clobber")])
1523 (define_insn "*addqi3.lt0"
1524 [(set (match_operand:QI 0 "register_operand" "=r")
1525 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1527 (match_operand:QI 2 "register_operand" "0")))]
1530 [(set_attr "length" "2")
1531 (set_attr "cc" "clobber")])
1533 (define_insn "*addhi3.lt0"
1534 [(set (match_operand:HI 0 "register_operand" "=w,r")
1535 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1537 (match_operand:HI 2 "register_operand" "0,0")))
1538 (clobber (match_scratch:QI 3 "=X,&1"))]
1541 sbrc %1,7\;adiw %0,1
1542 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1543 [(set_attr "length" "2,3")
1544 (set_attr "cc" "clobber")])
1546 (define_insn "*addpsi3.lt0"
1547 [(set (match_operand:PSI 0 "register_operand" "=r")
1548 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1550 (match_operand:PSI 2 "register_operand" "0")))]
1552 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1553 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1554 [(set_attr "length" "5")
1555 (set_attr "cc" "clobber")])
1557 (define_insn "*addsi3.lt0"
1558 [(set (match_operand:SI 0 "register_operand" "=r")
1559 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1561 (match_operand:SI 2 "register_operand" "0")))]
1563 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1564 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1565 [(set_attr "length" "6")
1566 (set_attr "cc" "clobber")])
1568 (define_insn "*umulqihi3.call"
1570 (mult:HI (zero_extend:HI (reg:QI 22))
1571 (zero_extend:HI (reg:QI 24))))
1572 (clobber (reg:QI 21))
1573 (clobber (reg:HI 22))]
1575 "%~call __umulqihi3"
1576 [(set_attr "type" "xcall")
1577 (set_attr "cc" "clobber")])
1581 (define_insn "<extend_u>mulqihi3"
1582 [(set (match_operand:HI 0 "register_operand" "=r")
1583 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1584 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1586 "mul<extend_s> %1,%2
1589 [(set_attr "length" "3")
1590 (set_attr "cc" "clobber")])
1592 (define_insn "usmulqihi3"
1593 [(set (match_operand:HI 0 "register_operand" "=r")
1594 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1595 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1600 [(set_attr "length" "3")
1601 (set_attr "cc" "clobber")])
1603 ;; Above insn is not canonicalized by insn combine, so here is a version with
1604 ;; operands swapped.
1606 (define_insn "*sumulqihi3"
1607 [(set (match_operand:HI 0 "register_operand" "=r")
1608 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1609 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1614 [(set_attr "length" "3")
1615 (set_attr "cc" "clobber")])
1617 ;; One-extend operand 1
1619 (define_insn "*osmulqihi3"
1620 [(set (match_operand:HI 0 "register_operand" "=&r")
1621 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1622 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1628 [(set_attr "length" "4")
1629 (set_attr "cc" "clobber")])
1631 (define_insn "*oumulqihi3"
1632 [(set (match_operand:HI 0 "register_operand" "=&r")
1633 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1634 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1640 [(set_attr "length" "4")
1641 (set_attr "cc" "clobber")])
1643 ;******************************************************************************
1644 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1645 ;******************************************************************************
1647 (define_insn "*maddqi4"
1648 [(set (match_operand:QI 0 "register_operand" "=r")
1649 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1650 (match_operand:QI 2 "register_operand" "r"))
1651 (match_operand:QI 3 "register_operand" "0")))]
1657 [(set_attr "length" "4")
1658 (set_attr "cc" "clobber")])
1660 (define_insn "*msubqi4"
1661 [(set (match_operand:QI 0 "register_operand" "=r")
1662 (minus:QI (match_operand:QI 3 "register_operand" "0")
1663 (mult:QI (match_operand:QI 1 "register_operand" "r")
1664 (match_operand:QI 2 "register_operand" "r"))))]
1669 [(set_attr "length" "4")
1670 (set_attr "cc" "clobber")])
1672 (define_insn_and_split "*maddqi4.const"
1673 [(set (match_operand:QI 0 "register_operand" "=r")
1674 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1675 (match_operand:QI 2 "const_int_operand" "n"))
1676 (match_operand:QI 3 "register_operand" "0")))
1677 (clobber (match_scratch:QI 4 "=&d"))]
1680 "&& reload_completed"
1685 (plus:QI (mult:QI (match_dup 1)
1690 (define_insn_and_split "*msubqi4.const"
1691 [(set (match_operand:QI 0 "register_operand" "=r")
1692 (minus:QI (match_operand:QI 3 "register_operand" "0")
1693 (mult:QI (match_operand:QI 1 "register_operand" "r")
1694 (match_operand:QI 2 "const_int_operand" "n"))))
1695 (clobber (match_scratch:QI 4 "=&d"))]
1698 "&& reload_completed"
1703 (minus:QI (match_dup 3)
1704 (mult:QI (match_dup 1)
1709 ;******************************************************************************
1710 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1711 ;******************************************************************************
1713 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1716 ;; int foo (unsigned char z)
1718 ;; extern int aInt[];
1719 ;; return aInt[3*z+2];
1722 ;; because the constant +4 then is added explicitely instead of consuming it
1723 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1724 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1725 ;; The implementational effort is the same so we are fine with that approach.
1730 (define_insn "*<extend_u>maddqihi4"
1731 [(set (match_operand:HI 0 "register_operand" "=r")
1732 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1733 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1734 (match_operand:HI 3 "register_operand" "0")))]
1737 "mul<extend_s> %1,%2
1741 [(set_attr "length" "4")
1742 (set_attr "cc" "clobber")])
1746 (define_insn "*<extend_u>msubqihi4"
1747 [(set (match_operand:HI 0 "register_operand" "=r")
1748 (minus:HI (match_operand:HI 3 "register_operand" "0")
1749 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1750 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1752 "mul<extend_s> %1,%2
1756 [(set_attr "length" "4")
1757 (set_attr "cc" "clobber")])
1761 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1762 [(set (match_operand:HI 0 "register_operand" "=r")
1763 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1764 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1765 (match_operand:HI 3 "register_operand" "0")))]
1768 && <any_extend:CODE> != <any_extend2:CODE>"
1770 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1771 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1773 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1775 [(set_attr "length" "4")
1776 (set_attr "cc" "clobber")])
1780 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1781 [(set (match_operand:HI 0 "register_operand" "=r")
1782 (minus:HI (match_operand:HI 3 "register_operand" "0")
1783 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1784 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1787 && <any_extend:CODE> != <any_extend2:CODE>"
1789 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1790 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1792 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1794 [(set_attr "length" "4")
1795 (set_attr "cc" "clobber")])
1797 ;; Handle small constants
1799 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1800 ;; This is shorter, faster than MUL and has lower register pressure.
1802 (define_insn_and_split "*umaddqihi4.2"
1803 [(set (match_operand:HI 0 "register_operand" "=r")
1804 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1806 (match_operand:HI 2 "register_operand" "r")))]
1808 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1809 { gcc_unreachable(); }
1813 ; *addhi3_zero_extend
1815 (plus:HI (zero_extend:HI (match_dup 1))
1817 ; *addhi3_zero_extend
1819 (plus:HI (zero_extend:HI (match_dup 1))
1822 ;; "umaddqihi4.uconst"
1823 ;; "maddqihi4.sconst"
1824 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1825 [(set (match_operand:HI 0 "register_operand" "=r")
1826 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1827 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1828 (match_operand:HI 3 "register_operand" "0")))
1829 (clobber (match_scratch:QI 4 "=&d"))]
1832 "&& reload_completed"
1835 ; *umaddqihi4 resp. *maddqihi4
1837 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1838 (any_extend:HI (match_dup 4)))
1841 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1844 ;; "*umsubqihi4.uconst"
1845 ;; "*msubqihi4.sconst"
1846 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1847 [(set (match_operand:HI 0 "register_operand" "=r")
1848 (minus:HI (match_operand:HI 3 "register_operand" "0")
1849 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1850 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1851 (clobber (match_scratch:QI 4 "=&d"))]
1854 "&& reload_completed"
1857 ; *umsubqihi4 resp. *msubqihi4
1859 (minus:HI (match_dup 3)
1860 (mult:HI (any_extend:HI (match_dup 1))
1861 (any_extend:HI (match_dup 4)))))]
1863 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1866 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1867 ;; for MULT with power of 2 and skips trying MULT insn above.
1869 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1870 [(set (match_operand:HI 0 "register_operand" "=r")
1871 (minus:HI (match_operand:HI 3 "register_operand" "0")
1872 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1873 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1874 (clobber (match_scratch:QI 4 "=&d"))]
1877 "&& reload_completed"
1882 (minus:HI (match_dup 3)
1883 (mult:HI (zero_extend:HI (match_dup 1))
1884 (zero_extend:HI (match_dup 4)))))]
1886 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1889 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1890 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1891 ;; because this would require an extra pattern for just one value.
1893 (define_insn_and_split "*msubqihi4.sconst.ashift"
1894 [(set (match_operand:HI 0 "register_operand" "=r")
1895 (minus:HI (match_operand:HI 3 "register_operand" "0")
1896 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1897 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1898 (clobber (match_scratch:QI 4 "=&d"))]
1901 "&& reload_completed"
1906 (minus:HI (match_dup 3)
1907 (mult:HI (sign_extend:HI (match_dup 1))
1908 (sign_extend:HI (match_dup 4)))))]
1910 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1913 ;; For signed/unsigned combinations that require narrow constraint "a"
1914 ;; just provide a pattern if signed/unsigned combination is actually needed.
1916 (define_insn_and_split "*sumaddqihi4.uconst"
1917 [(set (match_operand:HI 0 "register_operand" "=r")
1918 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1919 (match_operand:HI 2 "u8_operand" "M"))
1920 (match_operand:HI 3 "register_operand" "0")))
1921 (clobber (match_scratch:QI 4 "=&a"))]
1923 && !s8_operand (operands[2], VOIDmode)"
1925 "&& reload_completed"
1930 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1931 (zero_extend:HI (match_dup 4)))
1934 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1937 (define_insn_and_split "*sumsubqihi4.uconst"
1938 [(set (match_operand:HI 0 "register_operand" "=r")
1939 (minus:HI (match_operand:HI 3 "register_operand" "0")
1940 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1941 (match_operand:HI 2 "u8_operand" "M"))))
1942 (clobber (match_scratch:QI 4 "=&a"))]
1944 && !s8_operand (operands[2], VOIDmode)"
1946 "&& reload_completed"
1951 (minus:HI (match_dup 3)
1952 (mult:HI (sign_extend:HI (match_dup 1))
1953 (zero_extend:HI (match_dup 4)))))]
1955 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1958 ;******************************************************************************
1959 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1960 ;******************************************************************************
1962 ;; "*muluqihi3.uconst"
1963 ;; "*mulsqihi3.sconst"
1964 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1965 [(set (match_operand:HI 0 "register_operand" "=r")
1966 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1967 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1968 (clobber (match_scratch:QI 3 "=&d"))]
1971 "&& reload_completed"
1974 ; umulqihi3 resp. mulqihi3
1976 (mult:HI (any_extend:HI (match_dup 1))
1977 (any_extend:HI (match_dup 3))))]
1979 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1982 (define_insn_and_split "*muluqihi3.sconst"
1983 [(set (match_operand:HI 0 "register_operand" "=r")
1984 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1985 (match_operand:HI 2 "s8_operand" "n")))
1986 (clobber (match_scratch:QI 3 "=&a"))]
1989 "&& reload_completed"
1994 (mult:HI (zero_extend:HI (match_dup 1))
1995 (sign_extend:HI (match_dup 3))))]
1997 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2000 (define_insn_and_split "*mulsqihi3.uconst"
2001 [(set (match_operand:HI 0 "register_operand" "=r")
2002 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2003 (match_operand:HI 2 "u8_operand" "M")))
2004 (clobber (match_scratch:QI 3 "=&a"))]
2007 "&& reload_completed"
2012 (mult:HI (zero_extend:HI (match_dup 3))
2013 (sign_extend:HI (match_dup 1))))]
2015 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2018 (define_insn_and_split "*mulsqihi3.oconst"
2019 [(set (match_operand:HI 0 "register_operand" "=&r")
2020 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2021 (match_operand:HI 2 "o8_operand" "n")))
2022 (clobber (match_scratch:QI 3 "=&a"))]
2025 "&& reload_completed"
2030 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2031 (sign_extend:HI (match_dup 1))))]
2033 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2036 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2037 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2038 ;; at that time. Fix that.
2040 (define_insn "*ashiftqihi2.signx.1"
2041 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2042 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2046 lsl %A0\;sbc %B0,%B0
2047 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2048 [(set_attr "length" "2,3")
2049 (set_attr "cc" "clobber")])
2051 (define_insn_and_split "*ashifthi3.signx.const"
2052 [(set (match_operand:HI 0 "register_operand" "=r")
2053 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2054 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2055 (clobber (match_scratch:QI 3 "=&d"))]
2058 "&& reload_completed"
2063 (mult:HI (sign_extend:HI (match_dup 1))
2064 (sign_extend:HI (match_dup 3))))]
2066 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2069 (define_insn_and_split "*ashifthi3.signx.const7"
2070 [(set (match_operand:HI 0 "register_operand" "=r")
2071 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2073 (clobber (match_scratch:QI 2 "=&a"))]
2076 "&& reload_completed"
2081 (mult:HI (zero_extend:HI (match_dup 2))
2082 (sign_extend:HI (match_dup 1))))]
2084 operands[3] = gen_int_mode (1 << 7, QImode);
2087 (define_insn_and_split "*ashifthi3.zerox.const"
2088 [(set (match_operand:HI 0 "register_operand" "=r")
2089 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2090 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2091 (clobber (match_scratch:QI 3 "=&d"))]
2094 "&& reload_completed"
2099 (mult:HI (zero_extend:HI (match_dup 1))
2100 (zero_extend:HI (match_dup 3))))]
2102 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2105 ;******************************************************************************
2106 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2107 ;******************************************************************************
2109 (define_insn "mulsqihi3"
2110 [(set (match_operand:HI 0 "register_operand" "=&r")
2111 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2112 (match_operand:HI 2 "register_operand" "a")))]
2119 [(set_attr "length" "5")
2120 (set_attr "cc" "clobber")])
2122 (define_insn "muluqihi3"
2123 [(set (match_operand:HI 0 "register_operand" "=&r")
2124 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2125 (match_operand:HI 2 "register_operand" "r")))]
2132 [(set_attr "length" "5")
2133 (set_attr "cc" "clobber")])
2135 ;; one-extend operand 1
2137 (define_insn "muloqihi3"
2138 [(set (match_operand:HI 0 "register_operand" "=&r")
2139 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2140 (match_operand:HI 2 "register_operand" "r")))]
2148 [(set_attr "length" "6")
2149 (set_attr "cc" "clobber")])
2151 ;******************************************************************************
2153 (define_expand "mulhi3"
2154 [(set (match_operand:HI 0 "register_operand" "")
2155 (mult:HI (match_operand:HI 1 "register_operand" "")
2156 (match_operand:HI 2 "register_or_s9_operand" "")))]
2161 if (!register_operand (operands[2], HImode))
2162 operands[2] = force_reg (HImode, operands[2]);
2164 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2168 /* For small constants we can do better by extending them on the fly.
2169 The constant can be loaded in one instruction and the widening
2170 multiplication is shorter. First try the unsigned variant because it
2171 allows constraint "d" instead of "a" for the signed version. */
2173 if (s9_operand (operands[2], HImode))
2175 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2177 if (u8_operand (operands[2], HImode))
2179 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2181 else if (s8_operand (operands[2], HImode))
2183 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2187 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2193 if (!register_operand (operands[2], HImode))
2194 operands[2] = force_reg (HImode, operands[2]);
2197 (define_insn "*mulhi3_enh"
2198 [(set (match_operand:HI 0 "register_operand" "=&r")
2199 (mult:HI (match_operand:HI 1 "register_operand" "r")
2200 (match_operand:HI 2 "register_operand" "r")))]
2203 return REGNO (operands[1]) == REGNO (operands[2])
2204 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2205 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2207 [(set_attr "length" "7")
2208 (set_attr "cc" "clobber")])
2210 (define_expand "mulhi3_call"
2211 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2212 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2213 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2214 (clobber (reg:HI 22))
2215 (clobber (reg:QI 21))])
2216 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2220 (define_insn "*mulhi3_call"
2221 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2222 (clobber (reg:HI 22))
2223 (clobber (reg:QI 21))]
2226 [(set_attr "type" "xcall")
2227 (set_attr "cc" "clobber")])
2229 ;; To support widening multiplication with constant we postpone
2230 ;; expanding to the implicit library call until post combine and
2231 ;; prior to register allocation. Clobber all hard registers that
2232 ;; might be used by the (widening) multiply until it is split and
2233 ;; it's final register footprint is worked out.
2235 (define_expand "mulsi3"
2236 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2237 (mult:SI (match_operand:SI 1 "register_operand" "")
2238 (match_operand:SI 2 "nonmemory_operand" "")))
2239 (clobber (reg:HI 26))
2240 (clobber (reg:DI 18))])]
2243 if (u16_operand (operands[2], SImode))
2245 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2246 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2250 if (o16_operand (operands[2], SImode))
2252 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2253 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2258 (define_insn_and_split "*mulsi3"
2259 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2260 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2261 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2262 (clobber (reg:HI 26))
2263 (clobber (reg:DI 18))]
2264 "AVR_HAVE_MUL && !reload_completed"
2265 { gcc_unreachable(); }
2271 (parallel [(set (reg:SI 22)
2272 (mult:SI (reg:SI 22)
2274 (clobber (reg:HI 26))])
2278 if (u16_operand (operands[2], SImode))
2280 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2281 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2285 if (o16_operand (operands[2], SImode))
2287 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2288 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2295 (define_insn_and_split "mulu<mode>si3"
2296 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2297 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2298 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2299 (clobber (reg:HI 26))
2300 (clobber (reg:DI 18))]
2301 "AVR_HAVE_MUL && !reload_completed"
2302 { gcc_unreachable(); }
2309 (mult:SI (zero_extend:SI (reg:HI 26))
2314 /* Do the QI -> HI extension explicitely before the multiplication. */
2315 /* Do the HI -> SI extension implicitely and after the multiplication. */
2317 if (QImode == <MODE>mode)
2318 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2320 if (u16_operand (operands[2], SImode))
2322 operands[1] = force_reg (HImode, operands[1]);
2323 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2324 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2331 (define_insn_and_split "muls<mode>si3"
2332 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2333 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2334 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2335 (clobber (reg:HI 26))
2336 (clobber (reg:DI 18))]
2337 "AVR_HAVE_MUL && !reload_completed"
2338 { gcc_unreachable(); }
2345 (mult:SI (sign_extend:SI (reg:HI 26))
2350 /* Do the QI -> HI extension explicitely before the multiplication. */
2351 /* Do the HI -> SI extension implicitely and after the multiplication. */
2353 if (QImode == <MODE>mode)
2354 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2356 if (u16_operand (operands[2], SImode)
2357 || s16_operand (operands[2], SImode))
2359 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2361 operands[1] = force_reg (HImode, operands[1]);
2363 if (u16_operand (operands[2], SImode))
2364 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2366 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2372 ;; One-extend operand 1
2374 (define_insn_and_split "mulohisi3"
2375 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2376 (mult:SI (not:SI (zero_extend:SI
2377 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2378 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2379 (clobber (reg:HI 26))
2380 (clobber (reg:DI 18))]
2381 "AVR_HAVE_MUL && !reload_completed"
2382 { gcc_unreachable(); }
2389 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2397 (define_expand "<extend_u>mulhisi3"
2398 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2399 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2400 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2401 (clobber (reg:HI 26))
2402 (clobber (reg:DI 18))])]
2406 (define_expand "usmulhisi3"
2407 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2408 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2409 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2410 (clobber (reg:HI 26))
2411 (clobber (reg:DI 18))])]
2415 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2416 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2417 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2418 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2419 (define_insn_and_split
2420 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2421 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2422 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2423 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2424 (clobber (reg:HI 26))
2425 (clobber (reg:DI 18))]
2426 "AVR_HAVE_MUL && !reload_completed"
2427 { gcc_unreachable(); }
2434 (mult:SI (match_dup 3)
2439 rtx xop1 = operands[1];
2440 rtx xop2 = operands[2];
2442 /* Do the QI -> HI extension explicitely before the multiplication. */
2443 /* Do the HI -> SI extension implicitely and after the multiplication. */
2445 if (QImode == <QIHI:MODE>mode)
2446 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2448 if (QImode == <QIHI2:MODE>mode)
2449 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2451 if (<any_extend:CODE> == <any_extend2:CODE>
2452 || <any_extend:CODE> == ZERO_EXTEND)
2456 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2457 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2461 /* <any_extend:CODE> = SIGN_EXTEND */
2462 /* <any_extend2:CODE> = ZERO_EXTEND */
2466 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2467 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2471 ;; "smulhi3_highpart"
2472 ;; "umulhi3_highpart"
2473 (define_expand "<extend_su>mulhi3_highpart"
2475 (match_operand:HI 1 "nonmemory_operand" ""))
2477 (match_operand:HI 2 "nonmemory_operand" ""))
2478 (parallel [(set (reg:HI 24)
2479 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2480 (any_extend:SI (reg:HI 26)))
2482 (clobber (reg:HI 22))])
2483 (set (match_operand:HI 0 "register_operand" "")
2489 (define_insn "*mulsi3_call"
2491 (mult:SI (reg:SI 22)
2493 (clobber (reg:HI 26))]
2496 [(set_attr "type" "xcall")
2497 (set_attr "cc" "clobber")])
2500 ;; "*umulhisi3_call"
2501 (define_insn "*<extend_u>mulhisi3_call"
2503 (mult:SI (any_extend:SI (reg:HI 18))
2504 (any_extend:SI (reg:HI 26))))]
2506 "%~call __<extend_u>mulhisi3"
2507 [(set_attr "type" "xcall")
2508 (set_attr "cc" "clobber")])
2510 ;; "*umulhi3_highpart_call"
2511 ;; "*smulhi3_highpart_call"
2512 (define_insn "*<extend_su>mulhi3_highpart_call"
2514 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2515 (any_extend:SI (reg:HI 26)))
2517 (clobber (reg:HI 22))]
2519 "%~call __<extend_u>mulhisi3"
2520 [(set_attr "type" "xcall")
2521 (set_attr "cc" "clobber")])
2523 (define_insn "*usmulhisi3_call"
2525 (mult:SI (zero_extend:SI (reg:HI 18))
2526 (sign_extend:SI (reg:HI 26))))]
2528 "%~call __usmulhisi3"
2529 [(set_attr "type" "xcall")
2530 (set_attr "cc" "clobber")])
2532 (define_insn "*mul<extend_su>hisi3_call"
2534 (mult:SI (any_extend:SI (reg:HI 26))
2537 "%~call __mul<extend_su>hisi3"
2538 [(set_attr "type" "xcall")
2539 (set_attr "cc" "clobber")])
2541 (define_insn "*mulohisi3_call"
2543 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2546 "%~call __mulohisi3"
2547 [(set_attr "type" "xcall")
2548 (set_attr "cc" "clobber")])
2550 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2553 ;; Generate lib1funcs.S calls ourselves, because:
2554 ;; - we know exactly which registers are clobbered (for QI and HI
2555 ;; modes, some of the call-used registers are preserved)
2556 ;; - we get both the quotient and the remainder at no extra cost
2557 ;; - we split the patterns only after the first CSE passes because
2558 ;; CSE has problems to operate on hard regs.
2560 (define_insn_and_split "divmodqi4"
2561 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2562 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2563 (match_operand:QI 2 "pseudo_register_operand" "")))
2564 (set (match_operand:QI 3 "pseudo_register_operand" "")
2565 (mod:QI (match_dup 1) (match_dup 2)))
2566 (clobber (reg:QI 22))
2567 (clobber (reg:QI 23))
2568 (clobber (reg:QI 24))
2569 (clobber (reg:QI 25))])]
2571 "this divmodqi4 pattern should have been splitted;"
2573 [(set (reg:QI 24) (match_dup 1))
2574 (set (reg:QI 22) (match_dup 2))
2575 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2576 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2577 (clobber (reg:QI 22))
2578 (clobber (reg:QI 23))])
2579 (set (match_dup 0) (reg:QI 24))
2580 (set (match_dup 3) (reg:QI 25))]
2583 (define_insn "*divmodqi4_call"
2584 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2585 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2586 (clobber (reg:QI 22))
2587 (clobber (reg:QI 23))]
2589 "%~call __divmodqi4"
2590 [(set_attr "type" "xcall")
2591 (set_attr "cc" "clobber")])
2593 (define_insn_and_split "udivmodqi4"
2594 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2595 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2596 (match_operand:QI 2 "pseudo_register_operand" "")))
2597 (set (match_operand:QI 3 "pseudo_register_operand" "")
2598 (umod:QI (match_dup 1) (match_dup 2)))
2599 (clobber (reg:QI 22))
2600 (clobber (reg:QI 23))
2601 (clobber (reg:QI 24))
2602 (clobber (reg:QI 25))])]
2604 "this udivmodqi4 pattern should have been splitted;"
2606 [(set (reg:QI 24) (match_dup 1))
2607 (set (reg:QI 22) (match_dup 2))
2608 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2609 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2610 (clobber (reg:QI 23))])
2611 (set (match_dup 0) (reg:QI 24))
2612 (set (match_dup 3) (reg:QI 25))]
2615 (define_insn "*udivmodqi4_call"
2616 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2617 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2618 (clobber (reg:QI 23))]
2620 "%~call __udivmodqi4"
2621 [(set_attr "type" "xcall")
2622 (set_attr "cc" "clobber")])
2624 (define_insn_and_split "divmodhi4"
2625 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2626 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2627 (match_operand:HI 2 "pseudo_register_operand" "")))
2628 (set (match_operand:HI 3 "pseudo_register_operand" "")
2629 (mod:HI (match_dup 1) (match_dup 2)))
2630 (clobber (reg:QI 21))
2631 (clobber (reg:HI 22))
2632 (clobber (reg:HI 24))
2633 (clobber (reg:HI 26))])]
2635 "this should have been splitted;"
2637 [(set (reg:HI 24) (match_dup 1))
2638 (set (reg:HI 22) (match_dup 2))
2639 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2640 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2641 (clobber (reg:HI 26))
2642 (clobber (reg:QI 21))])
2643 (set (match_dup 0) (reg:HI 22))
2644 (set (match_dup 3) (reg:HI 24))]
2647 (define_insn "*divmodhi4_call"
2648 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2649 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2650 (clobber (reg:HI 26))
2651 (clobber (reg:QI 21))]
2653 "%~call __divmodhi4"
2654 [(set_attr "type" "xcall")
2655 (set_attr "cc" "clobber")])
2657 (define_insn_and_split "udivmodhi4"
2658 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2659 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2660 (match_operand:HI 2 "pseudo_register_operand" "")))
2661 (set (match_operand:HI 3 "pseudo_register_operand" "")
2662 (umod:HI (match_dup 1) (match_dup 2)))
2663 (clobber (reg:QI 21))
2664 (clobber (reg:HI 22))
2665 (clobber (reg:HI 24))
2666 (clobber (reg:HI 26))])]
2668 "this udivmodhi4 pattern should have been splitted.;"
2670 [(set (reg:HI 24) (match_dup 1))
2671 (set (reg:HI 22) (match_dup 2))
2672 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2673 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2674 (clobber (reg:HI 26))
2675 (clobber (reg:QI 21))])
2676 (set (match_dup 0) (reg:HI 22))
2677 (set (match_dup 3) (reg:HI 24))]
2680 (define_insn "*udivmodhi4_call"
2681 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2682 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2683 (clobber (reg:HI 26))
2684 (clobber (reg:QI 21))]
2686 "%~call __udivmodhi4"
2687 [(set_attr "type" "xcall")
2688 (set_attr "cc" "clobber")])
2690 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2693 ;; To support widening multiplication with constant we postpone
2694 ;; expanding to the implicit library call until post combine and
2695 ;; prior to register allocation. Clobber all hard registers that
2696 ;; might be used by the (widening) multiply until it is split and
2697 ;; it's final register footprint is worked out.
2699 (define_expand "mulpsi3"
2700 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2701 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2702 (match_operand:PSI 2 "nonmemory_operand" "")))
2703 (clobber (reg:HI 26))
2704 (clobber (reg:DI 18))])]
2707 if (s8_operand (operands[2], PSImode))
2709 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2710 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2715 (define_insn "*umulqihipsi3"
2716 [(set (match_operand:PSI 0 "register_operand" "=&r")
2717 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2718 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2727 [(set_attr "length" "7")
2728 (set_attr "cc" "clobber")])
2730 (define_insn "*umulhiqipsi3"
2731 [(set (match_operand:PSI 0 "register_operand" "=&r")
2732 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2733 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2741 adc %C0,__zero_reg__"
2742 [(set_attr "length" "7")
2743 (set_attr "cc" "clobber")])
2745 (define_insn_and_split "mulsqipsi3"
2746 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2747 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2748 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2749 (clobber (reg:HI 26))
2750 (clobber (reg:DI 18))]
2751 "AVR_HAVE_MUL && !reload_completed"
2752 { gcc_unreachable(); }
2759 (mult:PSI (sign_extend:PSI (reg:QI 25))
2764 (define_insn_and_split "*mulpsi3"
2765 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2766 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2767 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2768 (clobber (reg:HI 26))
2769 (clobber (reg:DI 18))]
2770 "AVR_HAVE_MUL && !reload_completed"
2771 { gcc_unreachable(); }
2777 (parallel [(set (reg:PSI 22)
2778 (mult:PSI (reg:PSI 22)
2780 (clobber (reg:QI 21))
2781 (clobber (reg:QI 25))
2782 (clobber (reg:HI 26))])
2786 if (s8_operand (operands[2], PSImode))
2788 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2789 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2794 (define_insn "*mulsqipsi3.libgcc"
2796 (mult:PSI (sign_extend:PSI (reg:QI 25))
2799 "%~call __mulsqipsi3"
2800 [(set_attr "type" "xcall")
2801 (set_attr "cc" "clobber")])
2803 (define_insn "*mulpsi3.libgcc"
2805 (mult:PSI (reg:PSI 22)
2807 (clobber (reg:QI 21))
2808 (clobber (reg:QI 25))
2809 (clobber (reg:HI 26))]
2812 [(set_attr "type" "xcall")
2813 (set_attr "cc" "clobber")])
2816 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2817 ;; 24-bit signed/unsigned division and modulo.
2818 ;; Notice that the libgcc implementation return the quotient in R22
2819 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2820 ;; implementation works the other way round.
2822 (define_insn_and_split "divmodpsi4"
2823 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2824 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2825 (match_operand:PSI 2 "pseudo_register_operand" "")))
2826 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2827 (mod:PSI (match_dup 1)
2829 (clobber (reg:DI 18))
2830 (clobber (reg:QI 26))])]
2832 { gcc_unreachable(); }
2834 [(set (reg:PSI 22) (match_dup 1))
2835 (set (reg:PSI 18) (match_dup 2))
2836 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2837 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2838 (clobber (reg:QI 21))
2839 (clobber (reg:QI 25))
2840 (clobber (reg:QI 26))])
2841 (set (match_dup 0) (reg:PSI 22))
2842 (set (match_dup 3) (reg:PSI 18))])
2844 (define_insn "*divmodpsi4_call"
2845 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2846 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2847 (clobber (reg:QI 21))
2848 (clobber (reg:QI 25))
2849 (clobber (reg:QI 26))]
2851 "%~call __divmodpsi4"
2852 [(set_attr "type" "xcall")
2853 (set_attr "cc" "clobber")])
2855 (define_insn_and_split "udivmodpsi4"
2856 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2857 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2858 (match_operand:PSI 2 "pseudo_register_operand" "")))
2859 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2860 (umod:PSI (match_dup 1)
2862 (clobber (reg:DI 18))
2863 (clobber (reg:QI 26))])]
2865 { gcc_unreachable(); }
2867 [(set (reg:PSI 22) (match_dup 1))
2868 (set (reg:PSI 18) (match_dup 2))
2869 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2870 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2871 (clobber (reg:QI 21))
2872 (clobber (reg:QI 25))
2873 (clobber (reg:QI 26))])
2874 (set (match_dup 0) (reg:PSI 22))
2875 (set (match_dup 3) (reg:PSI 18))])
2877 (define_insn "*udivmodpsi4_call"
2878 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2879 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2880 (clobber (reg:QI 21))
2881 (clobber (reg:QI 25))
2882 (clobber (reg:QI 26))]
2884 "%~call __udivmodpsi4"
2885 [(set_attr "type" "xcall")
2886 (set_attr "cc" "clobber")])
2888 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2890 (define_insn_and_split "divmodsi4"
2891 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2892 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2893 (match_operand:SI 2 "pseudo_register_operand" "")))
2894 (set (match_operand:SI 3 "pseudo_register_operand" "")
2895 (mod:SI (match_dup 1) (match_dup 2)))
2896 (clobber (reg:SI 18))
2897 (clobber (reg:SI 22))
2898 (clobber (reg:HI 26))
2899 (clobber (reg:HI 30))])]
2901 "this divmodsi4 pattern should have been splitted;"
2903 [(set (reg:SI 22) (match_dup 1))
2904 (set (reg:SI 18) (match_dup 2))
2905 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2906 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2907 (clobber (reg:HI 26))
2908 (clobber (reg:HI 30))])
2909 (set (match_dup 0) (reg:SI 18))
2910 (set (match_dup 3) (reg:SI 22))]
2913 (define_insn "*divmodsi4_call"
2914 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2915 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2916 (clobber (reg:HI 26))
2917 (clobber (reg:HI 30))]
2919 "%~call __divmodsi4"
2920 [(set_attr "type" "xcall")
2921 (set_attr "cc" "clobber")])
2923 (define_insn_and_split "udivmodsi4"
2924 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2925 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2926 (match_operand:SI 2 "pseudo_register_operand" "")))
2927 (set (match_operand:SI 3 "pseudo_register_operand" "")
2928 (umod:SI (match_dup 1) (match_dup 2)))
2929 (clobber (reg:SI 18))
2930 (clobber (reg:SI 22))
2931 (clobber (reg:HI 26))
2932 (clobber (reg:HI 30))])]
2934 "this udivmodsi4 pattern should have been splitted;"
2936 [(set (reg:SI 22) (match_dup 1))
2937 (set (reg:SI 18) (match_dup 2))
2938 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2939 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2940 (clobber (reg:HI 26))
2941 (clobber (reg:HI 30))])
2942 (set (match_dup 0) (reg:SI 18))
2943 (set (match_dup 3) (reg:SI 22))]
2946 (define_insn "*udivmodsi4_call"
2947 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2948 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2949 (clobber (reg:HI 26))
2950 (clobber (reg:HI 30))]
2952 "%~call __udivmodsi4"
2953 [(set_attr "type" "xcall")
2954 (set_attr "cc" "clobber")])
2956 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2959 (define_insn "andqi3"
2960 [(set (match_operand:QI 0 "register_operand" "=r,d")
2961 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2962 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2967 [(set_attr "length" "1,1")
2968 (set_attr "cc" "set_zn,set_zn")])
2970 (define_insn "andhi3"
2971 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2972 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2973 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2974 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2977 if (which_alternative == 0)
2978 return "and %A0,%A2\;and %B0,%B2";
2979 else if (which_alternative == 1)
2980 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2982 return avr_out_bitop (insn, operands, NULL);
2984 [(set_attr "length" "2,2,2,4,4")
2985 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2986 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2988 (define_insn "andpsi3"
2989 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2990 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2991 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2992 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2995 if (which_alternative == 0)
2996 return "and %A0,%A2" CR_TAB
2997 "and %B0,%B2" CR_TAB
3000 return avr_out_bitop (insn, operands, NULL);
3002 [(set_attr "length" "3,3,6,6")
3003 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3004 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3006 (define_insn "andsi3"
3007 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3008 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3009 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
3010 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3013 if (which_alternative == 0)
3014 return "and %0,%2" CR_TAB
3015 "and %B0,%B2" CR_TAB
3016 "and %C0,%C2" CR_TAB
3019 return avr_out_bitop (insn, operands, NULL);
3021 [(set_attr "length" "4,4,8,8")
3022 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3023 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3025 (define_peephole2 ; andi
3026 [(set (match_operand:QI 0 "d_register_operand" "")
3027 (and:QI (match_dup 0)
3028 (match_operand:QI 1 "const_int_operand" "")))
3030 (and:QI (match_dup 0)
3031 (match_operand:QI 2 "const_int_operand" "")))]
3033 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3035 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3038 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3041 (define_insn "iorqi3"
3042 [(set (match_operand:QI 0 "register_operand" "=r,d")
3043 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3044 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3049 [(set_attr "length" "1,1")
3050 (set_attr "cc" "set_zn,set_zn")])
3052 (define_insn "iorhi3"
3053 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
3054 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3055 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3056 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3059 if (which_alternative == 0)
3060 return "or %A0,%A2\;or %B0,%B2";
3061 else if (which_alternative == 1)
3062 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3064 return avr_out_bitop (insn, operands, NULL);
3066 [(set_attr "length" "2,2,2,4,4")
3067 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3068 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3070 (define_insn "iorpsi3"
3071 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3072 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3073 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3074 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3077 if (which_alternative == 0)
3078 return "or %A0,%A2" CR_TAB
3082 return avr_out_bitop (insn, operands, NULL);
3084 [(set_attr "length" "3,3,6,6")
3085 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3086 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3088 (define_insn "iorsi3"
3089 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3090 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3091 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3092 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3095 if (which_alternative == 0)
3096 return "or %0,%2" CR_TAB
3101 return avr_out_bitop (insn, operands, NULL);
3103 [(set_attr "length" "4,4,8,8")
3104 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3105 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3107 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3110 (define_insn "xorqi3"
3111 [(set (match_operand:QI 0 "register_operand" "=r")
3112 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3113 (match_operand:QI 2 "register_operand" "r")))]
3116 [(set_attr "length" "1")
3117 (set_attr "cc" "set_zn")])
3119 (define_insn "xorhi3"
3120 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3121 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3122 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3123 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3126 if (which_alternative == 0)
3127 return "eor %A0,%A2\;eor %B0,%B2";
3129 return avr_out_bitop (insn, operands, NULL);
3131 [(set_attr "length" "2,2,4")
3132 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3133 (set_attr "cc" "set_n,clobber,clobber")])
3135 (define_insn "xorpsi3"
3136 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3137 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3138 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3139 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3142 if (which_alternative == 0)
3143 return "eor %A0,%A2" CR_TAB
3144 "eor %B0,%B2" CR_TAB
3147 return avr_out_bitop (insn, operands, NULL);
3149 [(set_attr "length" "3,6,6")
3150 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3151 (set_attr "cc" "set_n,clobber,clobber")])
3153 (define_insn "xorsi3"
3154 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3155 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3156 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3157 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3160 if (which_alternative == 0)
3161 return "eor %0,%2" CR_TAB
3162 "eor %B0,%B2" CR_TAB
3163 "eor %C0,%C2" CR_TAB
3166 return avr_out_bitop (insn, operands, NULL);
3168 [(set_attr "length" "4,8,8")
3169 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3170 (set_attr "cc" "set_n,clobber,clobber")])
3172 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3175 (define_expand "rotlqi3"
3176 [(set (match_operand:QI 0 "register_operand" "")
3177 (rotate:QI (match_operand:QI 1 "register_operand" "")
3178 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3181 if (!CONST_INT_P (operands[2]))
3184 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3187 ;; Expander used by __builtin_avr_swap
3188 (define_expand "rotlqi3_4"
3189 [(set (match_operand:QI 0 "register_operand" "")
3190 (rotate:QI (match_operand:QI 1 "register_operand" "")
3193 (define_insn "*rotlqi3"
3194 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3195 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3196 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3199 lsl %0\;adc %0,__zero_reg__
3200 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3201 swap %0\;bst %0,0\;ror %0\;bld %0,7
3203 swap %0\;lsl %0\;adc %0,__zero_reg__
3204 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3205 bst %0,0\;ror %0\;bld %0,7
3207 [(set_attr "length" "2,4,4,1,3,5,3,0")
3208 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3210 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3211 ;; a whole number of bytes. The split creates the appropriate moves and
3212 ;; considers all overlap situations.
3214 ;; HImode does not need scratch. Use attribute for this constraint.
3216 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3217 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3222 (define_expand "rotl<mode>3"
3223 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3224 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3225 (match_operand:VOID 2 "const_int_operand" "")))
3226 (clobber (match_dup 3))])]
3231 if (!CONST_INT_P (operands[2]))
3234 offset = INTVAL (operands[2]);
3236 if (0 == offset % 8)
3238 if (AVR_HAVE_MOVW && 0 == offset % 16)
3239 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3241 operands[3] = gen_rtx_SCRATCH (QImode);
3243 else if (offset == 1
3244 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3246 /*; Support rotate left/right by 1 */
3248 emit_move_insn (operands[0],
3249 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3256 (define_insn "*rotlhi2.1"
3257 [(set (match_operand:HI 0 "register_operand" "=r")
3258 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3261 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3262 [(set_attr "length" "3")
3263 (set_attr "cc" "clobber")])
3265 (define_insn "*rotlhi2.15"
3266 [(set (match_operand:HI 0 "register_operand" "=r")
3267 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3270 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3271 [(set_attr "length" "4")
3272 (set_attr "cc" "clobber")])
3274 (define_insn "*rotlpsi2.1"
3275 [(set (match_operand:PSI 0 "register_operand" "=r")
3276 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3279 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3280 [(set_attr "length" "4")
3281 (set_attr "cc" "clobber")])
3283 (define_insn "*rotlpsi2.23"
3284 [(set (match_operand:PSI 0 "register_operand" "=r")
3285 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3288 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3289 [(set_attr "length" "5")
3290 (set_attr "cc" "clobber")])
3292 (define_insn "*rotlsi2.1"
3293 [(set (match_operand:SI 0 "register_operand" "=r")
3294 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3297 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3298 [(set_attr "length" "5")
3299 (set_attr "cc" "clobber")])
3301 (define_insn "*rotlsi2.31"
3302 [(set (match_operand:SI 0 "register_operand" "=r")
3303 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3306 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3307 [(set_attr "length" "6")
3308 (set_attr "cc" "clobber")])
3310 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3311 ;; The best we can do is use early clobber alternative "#&r" so that
3312 ;; completely non-overlapping operands dont get a scratch but # so register
3313 ;; allocation does not prefer non-overlapping.
3316 ;; Split word aligned rotates using scratch that is mode dependent.
3320 (define_insn_and_split "*rotw<mode>"
3321 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3322 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3323 (match_operand 2 "const_int_operand" "n,n,n")))
3324 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3326 && CONST_INT_P (operands[2])
3327 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3328 && 0 == INTVAL (operands[2]) % 16"
3330 "&& reload_completed"
3333 avr_rotate_bytes (operands);
3338 ;; Split byte aligned rotates using scratch that is always QI mode.
3343 (define_insn_and_split "*rotb<mode>"
3344 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3345 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3346 (match_operand 2 "const_int_operand" "n,n,n")))
3347 (clobber (match_scratch:QI 3 "=<rotx>"))]
3348 "CONST_INT_P (operands[2])
3349 && (8 == INTVAL (operands[2]) % 16
3351 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3352 && 0 == INTVAL (operands[2]) % 16))"
3354 "&& reload_completed"
3357 avr_rotate_bytes (operands);
3362 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3363 ;; arithmetic shift left
3366 ;; "ashlqq3" "ashluqq3"
3367 (define_expand "ashl<mode>3"
3368 [(set (match_operand:ALL1 0 "register_operand" "")
3369 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3370 (match_operand:QI 2 "nop_general_operand" "")))])
3372 (define_split ; ashlqi3_const4
3373 [(set (match_operand:ALL1 0 "d_register_operand" "")
3374 (ashift:ALL1 (match_dup 0)
3378 (rotate:QI (match_dup 1)
3381 (and:QI (match_dup 1)
3384 operands[1] = avr_to_int_mode (operands[0]);
3387 (define_split ; ashlqi3_const5
3388 [(set (match_operand:ALL1 0 "d_register_operand" "")
3389 (ashift:ALL1 (match_dup 0)
3392 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3393 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3394 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3396 operands[1] = avr_to_int_mode (operands[0]);
3399 (define_split ; ashlqi3_const6
3400 [(set (match_operand:ALL1 0 "d_register_operand" "")
3401 (ashift:ALL1 (match_dup 0)
3404 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3405 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3406 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3408 operands[1] = avr_to_int_mode (operands[0]);
3412 ;; "*ashlqq3" "*ashluqq3"
3413 (define_insn "*ashl<mode>3"
3414 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3415 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3416 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3419 return ashlqi3_out (insn, operands, NULL);
3421 [(set_attr "length" "5,0,1,2,4,6,9")
3422 (set_attr "adjust_len" "ashlqi")
3423 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3425 (define_insn "ashl<mode>3"
3426 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3427 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3428 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3431 return ashlhi3_out (insn, operands, NULL);
3433 [(set_attr "length" "6,0,2,2,4,10,10")
3434 (set_attr "adjust_len" "ashlhi")
3435 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3438 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3439 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3443 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3444 [(set (match_operand:QI 0 "register_operand" "=r")
3445 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3446 (match_operand:QI 2 "register_operand" "r"))
3452 (ashift:QI (match_dup 1)
3455 ;; ??? Combiner does not recognize that it could split the following insn;
3456 ;; presumably because he has no register handy?
3458 ;; "*ashluqihiqi3.mem"
3459 ;; "*ashlsqihiqi3.mem"
3460 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3461 [(set (match_operand:QI 0 "memory_operand" "=m")
3462 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3463 (match_operand:QI 2 "register_operand" "r"))
3466 { gcc_unreachable(); }
3469 (ashift:QI (match_dup 1)
3474 operands[3] = gen_reg_rtx (QImode);
3479 (define_insn_and_split "*ashlhiqi3"
3480 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3481 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3482 (match_operand:QI 2 "register_operand" "r")) 0))]
3484 { gcc_unreachable(); }
3487 (ashift:QI (match_dup 3)
3492 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3493 operands[4] = gen_reg_rtx (QImode);
3496 ;; High part of 16-bit shift is unused after the instruction:
3497 ;; No need to compute it, map to 8-bit shift.
3500 [(set (match_operand:HI 0 "register_operand" "")
3501 (ashift:HI (match_dup 0)
3502 (match_operand:QI 1 "register_operand" "")))]
3505 (ashift:QI (match_dup 2)
3507 (clobber (match_dup 3))]
3509 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3511 if (!peep2_reg_dead_p (1, operands[3]))
3514 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3519 ;; "ashlsq3" "ashlusq3"
3520 ;; "ashlsa3" "ashlusa3"
3521 (define_insn "ashl<mode>3"
3522 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3523 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3524 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3527 return ashlsi3_out (insn, operands, NULL);
3529 [(set_attr "length" "8,0,4,4,8,10,12")
3530 (set_attr "adjust_len" "ashlsi")
3531 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3533 ;; Optimize if a scratch register from LD_REGS happens to be available.
3535 (define_peephole2 ; ashlqi3_l_const4
3536 [(set (match_operand:ALL1 0 "l_register_operand" "")
3537 (ashift:ALL1 (match_dup 0)
3539 (match_scratch:QI 1 "d")]
3541 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3542 (set (match_dup 1) (const_int -16))
3543 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3545 operands[2] = avr_to_int_mode (operands[0]);
3548 (define_peephole2 ; ashlqi3_l_const5
3549 [(set (match_operand:ALL1 0 "l_register_operand" "")
3550 (ashift:ALL1 (match_dup 0)
3552 (match_scratch:QI 1 "d")]
3554 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3555 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3556 (set (match_dup 1) (const_int -32))
3557 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3559 operands[2] = avr_to_int_mode (operands[0]);
3562 (define_peephole2 ; ashlqi3_l_const6
3563 [(set (match_operand:ALL1 0 "l_register_operand" "")
3564 (ashift:ALL1 (match_dup 0)
3566 (match_scratch:QI 1 "d")]
3568 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3569 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3570 (set (match_dup 1) (const_int -64))
3571 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3573 operands[2] = avr_to_int_mode (operands[0]);
3577 [(match_scratch:QI 3 "d")
3578 (set (match_operand:ALL2 0 "register_operand" "")
3579 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3580 (match_operand:QI 2 "const_int_operand" "")))]
3582 [(parallel [(set (match_dup 0)
3583 (ashift:ALL2 (match_dup 1)
3585 (clobber (match_dup 3))])])
3588 ;; "*ashlhq3_const" "*ashluhq3_const"
3589 ;; "*ashlha3_const" "*ashluha3_const"
3590 (define_insn "*ashl<mode>3_const"
3591 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3592 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3593 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3594 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3597 return ashlhi3_out (insn, operands, NULL);
3599 [(set_attr "length" "0,2,2,4,10")
3600 (set_attr "adjust_len" "ashlhi")
3601 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3604 [(match_scratch:QI 3 "d")
3605 (set (match_operand:ALL4 0 "register_operand" "")
3606 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3607 (match_operand:QI 2 "const_int_operand" "")))]
3609 [(parallel [(set (match_dup 0)
3610 (ashift:ALL4 (match_dup 1)
3612 (clobber (match_dup 3))])]
3616 ;; "*ashlsq3_const" "*ashlusq3_const"
3617 ;; "*ashlsa3_const" "*ashlusa3_const"
3618 (define_insn "*ashl<mode>3_const"
3619 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3620 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3621 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3622 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3625 return ashlsi3_out (insn, operands, NULL);
3627 [(set_attr "length" "0,4,4,10")
3628 (set_attr "adjust_len" "ashlsi")
3629 (set_attr "cc" "none,set_n,clobber,clobber")])
3631 (define_expand "ashlpsi3"
3632 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3633 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3634 (match_operand:QI 2 "nonmemory_operand" "")))
3635 (clobber (scratch:QI))])]
3639 && CONST_INT_P (operands[2]))
3641 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3643 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3644 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3647 else if (optimize_insn_for_speed_p ()
3648 && INTVAL (operands[2]) != 16
3649 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3651 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3652 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3658 (define_insn "*ashlpsi3"
3659 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3660 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3661 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3662 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3665 return avr_out_ashlpsi3 (insn, operands, NULL);
3667 [(set_attr "adjust_len" "ashlpsi")
3668 (set_attr "cc" "clobber")])
3670 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3671 ;; arithmetic shift right
3674 ;; "ashrqq3" "ashruqq3"
3675 (define_insn "ashr<mode>3"
3676 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3677 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3678 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3681 return ashrqi3_out (insn, operands, NULL);
3683 [(set_attr "length" "5,0,1,2,5,4,9")
3684 (set_attr "adjust_len" "ashrqi")
3685 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3688 ;; "ashrhq3" "ashruhq3"
3689 ;; "ashrha3" "ashruha3"
3690 (define_insn "ashr<mode>3"
3691 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3692 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3693 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3696 return ashrhi3_out (insn, operands, NULL);
3698 [(set_attr "length" "6,0,2,4,4,10,10")
3699 (set_attr "adjust_len" "ashrhi")
3700 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3702 (define_insn "ashrpsi3"
3703 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3704 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3705 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3706 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3709 return avr_out_ashrpsi3 (insn, operands, NULL);
3711 [(set_attr "adjust_len" "ashrpsi")
3712 (set_attr "cc" "clobber")])
3715 ;; "ashrsq3" "ashrusq3"
3716 ;; "ashrsa3" "ashrusa3"
3717 (define_insn "ashr<mode>3"
3718 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3719 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3720 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3723 return ashrsi3_out (insn, operands, NULL);
3725 [(set_attr "length" "8,0,4,6,8,10,12")
3726 (set_attr "adjust_len" "ashrsi")
3727 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3729 ;; Optimize if a scratch register from LD_REGS happens to be available.
3732 [(match_scratch:QI 3 "d")
3733 (set (match_operand:ALL2 0 "register_operand" "")
3734 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3735 (match_operand:QI 2 "const_int_operand" "")))]
3737 [(parallel [(set (match_dup 0)
3738 (ashiftrt:ALL2 (match_dup 1)
3740 (clobber (match_dup 3))])])
3743 ;; "*ashrhq3_const" "*ashruhq3_const"
3744 ;; "*ashrha3_const" "*ashruha3_const"
3745 (define_insn "*ashr<mode>3_const"
3746 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3747 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3748 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3749 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3752 return ashrhi3_out (insn, operands, NULL);
3754 [(set_attr "length" "0,2,4,4,10")
3755 (set_attr "adjust_len" "ashrhi")
3756 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3759 [(match_scratch:QI 3 "d")
3760 (set (match_operand:ALL4 0 "register_operand" "")
3761 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3762 (match_operand:QI 2 "const_int_operand" "")))]
3764 [(parallel [(set (match_dup 0)
3765 (ashiftrt:ALL4 (match_dup 1)
3767 (clobber (match_dup 3))])])
3770 ;; "*ashrsq3_const" "*ashrusq3_const"
3771 ;; "*ashrsa3_const" "*ashrusa3_const"
3772 (define_insn "*ashr<mode>3_const"
3773 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3774 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3775 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3776 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3779 return ashrsi3_out (insn, operands, NULL);
3781 [(set_attr "length" "0,4,4,10")
3782 (set_attr "adjust_len" "ashrsi")
3783 (set_attr "cc" "none,clobber,set_n,clobber")])
3785 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3786 ;; logical shift right
3789 ;; "lshrqq3 "lshruqq3"
3790 (define_expand "lshr<mode>3"
3791 [(set (match_operand:ALL1 0 "register_operand" "")
3792 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3793 (match_operand:QI 2 "nop_general_operand" "")))])
3795 (define_split ; lshrqi3_const4
3796 [(set (match_operand:ALL1 0 "d_register_operand" "")
3797 (lshiftrt:ALL1 (match_dup 0)
3801 (rotate:QI (match_dup 1)
3804 (and:QI (match_dup 1)
3807 operands[1] = avr_to_int_mode (operands[0]);
3810 (define_split ; lshrqi3_const5
3811 [(set (match_operand:ALL1 0 "d_register_operand" "")
3812 (lshiftrt:ALL1 (match_dup 0)
3815 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3816 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3817 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3819 operands[1] = avr_to_int_mode (operands[0]);
3822 (define_split ; lshrqi3_const6
3823 [(set (match_operand:QI 0 "d_register_operand" "")
3824 (lshiftrt:QI (match_dup 0)
3827 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3828 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3829 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3831 operands[1] = avr_to_int_mode (operands[0]);
3837 (define_insn "*lshr<mode>3"
3838 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3839 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3840 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3843 return lshrqi3_out (insn, operands, NULL);
3845 [(set_attr "length" "5,0,1,2,4,6,9")
3846 (set_attr "adjust_len" "lshrqi")
3847 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3850 ;; "lshrhq3" "lshruhq3"
3851 ;; "lshrha3" "lshruha3"
3852 (define_insn "lshr<mode>3"
3853 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3854 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3855 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3858 return lshrhi3_out (insn, operands, NULL);
3860 [(set_attr "length" "6,0,2,2,4,10,10")
3861 (set_attr "adjust_len" "lshrhi")
3862 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3864 (define_insn "lshrpsi3"
3865 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3866 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3867 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3868 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3871 return avr_out_lshrpsi3 (insn, operands, NULL);
3873 [(set_attr "adjust_len" "lshrpsi")
3874 (set_attr "cc" "clobber")])
3877 ;; "lshrsq3" "lshrusq3"
3878 ;; "lshrsa3" "lshrusa3"
3879 (define_insn "lshr<mode>3"
3880 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3881 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3882 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3885 return lshrsi3_out (insn, operands, NULL);
3887 [(set_attr "length" "8,0,4,4,8,10,12")
3888 (set_attr "adjust_len" "lshrsi")
3889 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3891 ;; Optimize if a scratch register from LD_REGS happens to be available.
3893 (define_peephole2 ; lshrqi3_l_const4
3894 [(set (match_operand:ALL1 0 "l_register_operand" "")
3895 (lshiftrt:ALL1 (match_dup 0)
3897 (match_scratch:QI 1 "d")]
3899 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3900 (set (match_dup 1) (const_int 15))
3901 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3903 operands[2] = avr_to_int_mode (operands[0]);
3906 (define_peephole2 ; lshrqi3_l_const5
3907 [(set (match_operand:ALL1 0 "l_register_operand" "")
3908 (lshiftrt:ALL1 (match_dup 0)
3910 (match_scratch:QI 1 "d")]
3912 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3913 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3914 (set (match_dup 1) (const_int 7))
3915 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3917 operands[2] = avr_to_int_mode (operands[0]);
3920 (define_peephole2 ; lshrqi3_l_const6
3921 [(set (match_operand:ALL1 0 "l_register_operand" "")
3922 (lshiftrt:ALL1 (match_dup 0)
3924 (match_scratch:QI 1 "d")]
3926 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3927 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3928 (set (match_dup 1) (const_int 3))
3929 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3931 operands[2] = avr_to_int_mode (operands[0]);
3935 [(match_scratch:QI 3 "d")
3936 (set (match_operand:ALL2 0 "register_operand" "")
3937 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3938 (match_operand:QI 2 "const_int_operand" "")))]
3940 [(parallel [(set (match_dup 0)
3941 (lshiftrt:ALL2 (match_dup 1)
3943 (clobber (match_dup 3))])])
3946 ;; "*lshrhq3_const" "*lshruhq3_const"
3947 ;; "*lshrha3_const" "*lshruha3_const"
3948 (define_insn "*lshr<mode>3_const"
3949 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3950 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3951 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3952 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3955 return lshrhi3_out (insn, operands, NULL);
3957 [(set_attr "length" "0,2,2,4,10")
3958 (set_attr "adjust_len" "lshrhi")
3959 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3962 [(match_scratch:QI 3 "d")
3963 (set (match_operand:ALL4 0 "register_operand" "")
3964 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3965 (match_operand:QI 2 "const_int_operand" "")))]
3967 [(parallel [(set (match_dup 0)
3968 (lshiftrt:ALL4 (match_dup 1)
3970 (clobber (match_dup 3))])])
3973 ;; "*lshrsq3_const" "*lshrusq3_const"
3974 ;; "*lshrsa3_const" "*lshrusa3_const"
3975 (define_insn "*lshr<mode>3_const"
3976 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3977 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3978 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3979 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3982 return lshrsi3_out (insn, operands, NULL);
3984 [(set_attr "length" "0,4,4,10")
3985 (set_attr "adjust_len" "lshrsi")
3986 (set_attr "cc" "none,clobber,clobber,clobber")])
3988 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3991 (define_insn "absqi2"
3992 [(set (match_operand:QI 0 "register_operand" "=r")
3993 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3997 [(set_attr "length" "2")
3998 (set_attr "cc" "clobber")])
4001 (define_insn "abssf2"
4002 [(set (match_operand:SF 0 "register_operand" "=d,r")
4003 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4008 [(set_attr "length" "1,2")
4009 (set_attr "cc" "set_n,clobber")])
4011 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
4014 (define_insn "negqi2"
4015 [(set (match_operand:QI 0 "register_operand" "=r")
4016 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4019 [(set_attr "length" "1")
4020 (set_attr "cc" "set_zn")])
4022 (define_insn "*negqihi2"
4023 [(set (match_operand:HI 0 "register_operand" "=r")
4024 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4026 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4027 [(set_attr "length" "4")
4028 (set_attr "cc" "set_n")])
4030 (define_insn "neghi2"
4031 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4032 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4035 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4036 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4037 [(set_attr "length" "3,4")
4038 (set_attr "cc" "set_czn")])
4040 (define_insn "negpsi2"
4041 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4042 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4045 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4046 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4047 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4048 [(set_attr "length" "5,6,6")
4049 (set_attr "cc" "set_czn,set_n,set_czn")])
4051 (define_insn "negsi2"
4052 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4053 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4056 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4057 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4058 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4059 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4060 [(set_attr "length" "7,8,8,7")
4061 (set_attr "isa" "*,*,mov,movw")
4062 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4064 (define_insn "negsf2"
4065 [(set (match_operand:SF 0 "register_operand" "=d,r")
4066 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4070 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4071 [(set_attr "length" "1,4")
4072 (set_attr "cc" "set_n,set_n")])
4074 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4077 (define_insn "one_cmplqi2"
4078 [(set (match_operand:QI 0 "register_operand" "=r")
4079 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4082 [(set_attr "length" "1")
4083 (set_attr "cc" "set_czn")])
4085 (define_insn "one_cmplhi2"
4086 [(set (match_operand:HI 0 "register_operand" "=r")
4087 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4091 [(set_attr "length" "2")
4092 (set_attr "cc" "set_n")])
4094 (define_insn "one_cmplpsi2"
4095 [(set (match_operand:PSI 0 "register_operand" "=r")
4096 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4098 "com %0\;com %B0\;com %C0"
4099 [(set_attr "length" "3")
4100 (set_attr "cc" "set_n")])
4102 (define_insn "one_cmplsi2"
4103 [(set (match_operand:SI 0 "register_operand" "=r")
4104 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4110 [(set_attr "length" "4")
4111 (set_attr "cc" "set_n")])
4113 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4116 ;; We keep combiner from inserting hard registers into the input of sign- and
4117 ;; zero-extends. A hard register in the input operand is not wanted because
4118 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4119 ;; hard register that overlaps these clobbers won't be combined to a widening
4120 ;; multiplication. There is no need for combine to propagate hard registers,
4121 ;; register allocation can do it just as well.
4123 (define_insn "extendqihi2"
4124 [(set (match_operand:HI 0 "register_operand" "=r,r")
4125 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4128 clr %B0\;sbrc %0,7\;com %B0
4129 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4130 [(set_attr "length" "3,4")
4131 (set_attr "cc" "set_n,set_n")])
4133 (define_insn "extendqipsi2"
4134 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4135 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4138 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4139 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4140 [(set_attr "length" "4,5")
4141 (set_attr "cc" "set_n,set_n")])
4143 (define_insn "extendqisi2"
4144 [(set (match_operand:SI 0 "register_operand" "=r,r")
4145 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4148 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4149 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4150 [(set_attr "length" "5,6")
4151 (set_attr "cc" "set_n,set_n")])
4153 (define_insn "extendhipsi2"
4154 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4155 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4158 clr %C0\;sbrc %B0,7\;com %C0
4159 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4160 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4161 [(set_attr "length" "3,5,4")
4162 (set_attr "isa" "*,mov,movw")
4163 (set_attr "cc" "set_n")])
4165 (define_insn "extendhisi2"
4166 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4167 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4170 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4171 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4172 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4173 [(set_attr "length" "4,6,5")
4174 (set_attr "isa" "*,mov,movw")
4175 (set_attr "cc" "set_n")])
4177 (define_insn "extendpsisi2"
4178 [(set (match_operand:SI 0 "register_operand" "=r")
4179 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4181 "clr %D0\;sbrc %C0,7\;com %D0"
4182 [(set_attr "length" "3")
4183 (set_attr "cc" "set_n")])
4185 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4188 (define_insn_and_split "zero_extendqihi2"
4189 [(set (match_operand:HI 0 "register_operand" "=r")
4190 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4194 [(set (match_dup 2) (match_dup 1))
4195 (set (match_dup 3) (const_int 0))]
4197 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4198 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4200 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4201 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4204 (define_insn_and_split "zero_extendqipsi2"
4205 [(set (match_operand:PSI 0 "register_operand" "=r")
4206 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4210 [(set (match_dup 2) (match_dup 1))
4211 (set (match_dup 3) (const_int 0))
4212 (set (match_dup 4) (const_int 0))]
4214 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4215 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4216 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4219 (define_insn_and_split "zero_extendqisi2"
4220 [(set (match_operand:SI 0 "register_operand" "=r")
4221 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4225 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4226 (set (match_dup 3) (const_int 0))]
4228 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4229 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4231 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4232 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4235 (define_insn_and_split "zero_extendhipsi2"
4236 [(set (match_operand:PSI 0 "register_operand" "=r")
4237 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4241 [(set (match_dup 2) (match_dup 1))
4242 (set (match_dup 3) (const_int 0))]
4244 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4245 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4248 (define_insn_and_split "n_extendhipsi2"
4249 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4250 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4251 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4252 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4256 [(set (match_dup 4) (match_dup 2))
4257 (set (match_dup 3) (match_dup 6))
4258 ; no-op move in the case where no scratch is needed
4259 (set (match_dup 5) (match_dup 3))]
4261 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4262 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4263 operands[6] = operands[1];
4265 if (GET_CODE (operands[3]) == SCRATCH)
4266 operands[3] = operands[5];
4269 (define_insn_and_split "zero_extendhisi2"
4270 [(set (match_operand:SI 0 "register_operand" "=r")
4271 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4275 [(set (match_dup 2) (match_dup 1))
4276 (set (match_dup 3) (const_int 0))]
4278 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4279 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4281 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4282 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4285 (define_insn_and_split "zero_extendpsisi2"
4286 [(set (match_operand:SI 0 "register_operand" "=r")
4287 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4291 [(set (match_dup 2) (match_dup 1))
4292 (set (match_dup 3) (const_int 0))]
4294 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4295 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4298 (define_insn_and_split "zero_extendqidi2"
4299 [(set (match_operand:DI 0 "register_operand" "=r")
4300 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4304 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4305 (set (match_dup 3) (const_int 0))]
4307 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4308 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4310 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4311 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4314 (define_insn_and_split "zero_extendhidi2"
4315 [(set (match_operand:DI 0 "register_operand" "=r")
4316 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4320 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4321 (set (match_dup 3) (const_int 0))]
4323 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4324 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4326 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4327 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4330 (define_insn_and_split "zero_extendsidi2"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4336 [(set (match_dup 2) (match_dup 1))
4337 (set (match_dup 3) (const_int 0))]
4339 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4340 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4342 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4343 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4346 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4349 ; Optimize negated tests into reverse compare if overflow is undefined.
4350 (define_insn "*negated_tstqi"
4352 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4354 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4355 "cp __zero_reg__,%0"
4356 [(set_attr "cc" "compare")
4357 (set_attr "length" "1")])
4359 (define_insn "*reversed_tstqi"
4361 (compare (const_int 0)
4362 (match_operand:QI 0 "register_operand" "r")))]
4364 "cp __zero_reg__,%0"
4365 [(set_attr "cc" "compare")
4366 (set_attr "length" "2")])
4368 (define_insn "*negated_tsthi"
4370 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4372 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4373 "cp __zero_reg__,%A0
4374 cpc __zero_reg__,%B0"
4375 [(set_attr "cc" "compare")
4376 (set_attr "length" "2")])
4378 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4379 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4380 (define_insn "*reversed_tsthi"
4382 (compare (const_int 0)
4383 (match_operand:HI 0 "register_operand" "r")))
4384 (clobber (match_scratch:QI 1 "=X"))]
4386 "cp __zero_reg__,%A0
4387 cpc __zero_reg__,%B0"
4388 [(set_attr "cc" "compare")
4389 (set_attr "length" "2")])
4391 (define_insn "*negated_tstpsi"
4393 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4395 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4396 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4397 [(set_attr "cc" "compare")
4398 (set_attr "length" "3")])
4400 (define_insn "*reversed_tstpsi"
4402 (compare (const_int 0)
4403 (match_operand:PSI 0 "register_operand" "r")))
4404 (clobber (match_scratch:QI 1 "=X"))]
4406 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4407 [(set_attr "cc" "compare")
4408 (set_attr "length" "3")])
4410 (define_insn "*negated_tstsi"
4412 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4414 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4415 "cp __zero_reg__,%A0
4416 cpc __zero_reg__,%B0
4417 cpc __zero_reg__,%C0
4418 cpc __zero_reg__,%D0"
4419 [(set_attr "cc" "compare")
4420 (set_attr "length" "4")])
4422 ;; "*reversed_tstsi"
4423 ;; "*reversed_tstsq" "*reversed_tstusq"
4424 ;; "*reversed_tstsa" "*reversed_tstusa"
4425 (define_insn "*reversed_tst<mode>"
4427 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4428 (match_operand:ALL4 1 "register_operand" "r")))
4429 (clobber (match_scratch:QI 2 "=X"))]
4431 "cp __zero_reg__,%A1
4432 cpc __zero_reg__,%B1
4433 cpc __zero_reg__,%C1
4434 cpc __zero_reg__,%D1"
4435 [(set_attr "cc" "compare")
4436 (set_attr "length" "4")])
4440 ;; "*cmpqq" "*cmpuqq"
4441 (define_insn "*cmp<mode>"
4443 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4444 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4450 [(set_attr "cc" "compare,compare,compare")
4451 (set_attr "length" "1,1,1")])
4453 (define_insn "*cmpqi_sign_extend"
4455 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4456 (match_operand:HI 1 "s8_operand" "n")))]
4459 [(set_attr "cc" "compare")
4460 (set_attr "length" "1")])
4463 ;; "*cmphq" "*cmpuhq"
4464 ;; "*cmpha" "*cmpuha"
4465 (define_insn "*cmp<mode>"
4467 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4468 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4469 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4472 switch (which_alternative)
4476 return avr_out_tsthi (insn, operands, NULL);
4479 return "cp %A0,%A1\;cpc %B0,%B1";
4482 if (<MODE>mode != HImode)
4484 return reg_unused_after (insn, operands[0])
4485 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4486 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4489 if (<MODE>mode != HImode)
4491 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4494 return avr_out_compare (insn, operands, NULL);
4496 [(set_attr "cc" "compare")
4497 (set_attr "length" "1,2,2,3,4,2,4")
4498 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4500 (define_insn "*cmppsi"
4502 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4503 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4504 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4507 switch (which_alternative)
4510 return avr_out_tstpsi (insn, operands, NULL);
4513 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4516 return reg_unused_after (insn, operands[0])
4517 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4518 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4521 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4524 return avr_out_compare (insn, operands, NULL);
4526 [(set_attr "cc" "compare")
4527 (set_attr "length" "3,3,5,6,3,7")
4528 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4531 ;; "*cmpsq" "*cmpusq"
4532 ;; "*cmpsa" "*cmpusa"
4533 (define_insn "*cmp<mode>"
4535 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4536 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4537 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4540 if (0 == which_alternative)
4541 return avr_out_tstsi (insn, operands, NULL);
4542 else if (1 == which_alternative)
4543 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4545 return avr_out_compare (insn, operands, NULL);
4547 [(set_attr "cc" "compare")
4548 (set_attr "length" "4,4,4,5,8")
4549 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4552 ;; ----------------------------------------------------------------------
4553 ;; JUMP INSTRUCTIONS
4554 ;; ----------------------------------------------------------------------
4555 ;; Conditional jump instructions
4558 ;; "cbranchqq4" "cbranchuqq4"
4559 (define_expand "cbranch<mode>4"
4561 (compare (match_operand:ALL1 1 "register_operand" "")
4562 (match_operand:ALL1 2 "nonmemory_operand" "")))
4565 (match_operator 0 "ordered_comparison_operator" [(cc0)
4567 (label_ref (match_operand 3 "" ""))
4570 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4571 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4573 (define_expand "cbranch<mode>4"
4574 [(parallel [(set (cc0)
4575 (compare (match_operand:ORDERED234 1 "register_operand" "")
4576 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4577 (clobber (match_scratch:QI 4 ""))])
4580 (match_operator 0 "ordered_comparison_operator" [(cc0)
4582 (label_ref (match_operand 3 "" ""))
4586 ;; Test a single bit in a QI/HI/SImode register.
4587 ;; Combine will create zero extract patterns for single bit tests.
4588 ;; permit any mode in source pattern by using VOIDmode.
4590 (define_insn "*sbrx_branch<mode>"
4593 (match_operator 0 "eqne_operator"
4595 (match_operand:VOID 1 "register_operand" "r")
4597 (match_operand 2 "const_int_operand" "n"))
4599 (label_ref (match_operand 3 "" ""))
4603 return avr_out_sbxx_branch (insn, operands);
4605 [(set (attr "length")
4606 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4607 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4609 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4612 (set_attr "cc" "clobber")])
4614 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4615 ;; or for old peepholes.
4616 ;; Fixme - bitwise Mask will not work for DImode
4618 (define_insn "*sbrx_and_branch<mode>"
4621 (match_operator 0 "eqne_operator"
4623 (match_operand:QISI 1 "register_operand" "r")
4624 (match_operand:QISI 2 "single_one_operand" "n"))
4626 (label_ref (match_operand 3 "" ""))
4630 HOST_WIDE_INT bitnumber;
4631 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4632 operands[2] = GEN_INT (bitnumber);
4633 return avr_out_sbxx_branch (insn, operands);
4635 [(set (attr "length")
4636 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4637 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4639 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4642 (set_attr "cc" "clobber")])
4644 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4646 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4648 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4649 (label_ref (match_operand 1 "" ""))
4652 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4656 (label_ref (match_dup 1))
4661 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4663 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4664 (label_ref (match_operand 1 "" ""))
4667 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4671 (label_ref (match_dup 1))
4676 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4678 (clobber (match_operand:HI 2 ""))])
4679 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4680 (label_ref (match_operand 1 "" ""))
4683 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4685 (label_ref (match_dup 1))
4690 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4692 (clobber (match_operand:HI 2 ""))])
4693 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4694 (label_ref (match_operand 1 "" ""))
4697 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4699 (label_ref (match_dup 1))
4704 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4706 (clobber (match_operand:SI 2 ""))])
4707 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4708 (label_ref (match_operand 1 "" ""))
4711 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4713 (label_ref (match_dup 1))
4715 "operands[2] = GEN_INT (-2147483647 - 1);")
4718 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4720 (clobber (match_operand:SI 2 ""))])
4721 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4722 (label_ref (match_operand 1 "" ""))
4725 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4727 (label_ref (match_dup 1))
4729 "operands[2] = GEN_INT (-2147483647 - 1);")
4731 ;; ************************************************************************
4732 ;; Implementation of conditional jumps here.
4733 ;; Compare with 0 (test) jumps
4734 ;; ************************************************************************
4736 (define_insn "branch"
4738 (if_then_else (match_operator 1 "simple_comparison_operator"
4741 (label_ref (match_operand 0 "" ""))
4745 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4747 [(set_attr "type" "branch")
4748 (set_attr "cc" "clobber")])
4751 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4752 ;; or optimized in the remainder.
4754 (define_insn "branch_unspec"
4756 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4759 (label_ref (match_operand 0 "" ""))
4761 ] UNSPEC_IDENTITY))]
4764 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4766 [(set_attr "type" "branch")
4767 (set_attr "cc" "none")])
4769 ;; ****************************************************************
4770 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4771 ;; Convert them all to proper jumps.
4772 ;; ****************************************************************/
4774 (define_insn "difficult_branch"
4776 (if_then_else (match_operator 1 "difficult_comparison_operator"
4779 (label_ref (match_operand 0 "" ""))
4783 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4785 [(set_attr "type" "branch1")
4786 (set_attr "cc" "clobber")])
4790 (define_insn "rvbranch"
4792 (if_then_else (match_operator 1 "simple_comparison_operator"
4796 (label_ref (match_operand 0 "" ""))))]
4799 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4801 [(set_attr "type" "branch1")
4802 (set_attr "cc" "clobber")])
4804 (define_insn "difficult_rvbranch"
4806 (if_then_else (match_operator 1 "difficult_comparison_operator"
4810 (label_ref (match_operand 0 "" ""))))]
4813 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4815 [(set_attr "type" "branch")
4816 (set_attr "cc" "clobber")])
4818 ;; **************************************************************************
4819 ;; Unconditional and other jump instructions.
4823 (label_ref (match_operand 0 "" "")))]
4826 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4830 [(set (attr "length")
4831 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4832 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4835 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4836 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4839 (set_attr "cc" "none")])
4843 (define_expand "call"
4844 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4845 (match_operand:HI 1 "general_operand" ""))
4846 (use (const_int 0))])]
4847 ;; Operand 1 not used on the AVR.
4848 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4852 (define_expand "sibcall"
4853 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4854 (match_operand:HI 1 "general_operand" ""))
4855 (use (const_int 1))])]
4856 ;; Operand 1 not used on the AVR.
4857 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4863 (define_expand "call_value"
4864 [(parallel[(set (match_operand 0 "register_operand" "")
4865 (call (match_operand:HI 1 "call_insn_operand" "")
4866 (match_operand:HI 2 "general_operand" "")))
4867 (use (const_int 0))])]
4868 ;; Operand 2 not used on the AVR.
4869 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4873 (define_expand "sibcall_value"
4874 [(parallel[(set (match_operand 0 "register_operand" "")
4875 (call (match_operand:HI 1 "call_insn_operand" "")
4876 (match_operand:HI 2 "general_operand" "")))
4877 (use (const_int 1))])]
4878 ;; Operand 2 not used on the AVR.
4879 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4883 (define_insn "call_insn"
4884 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4885 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4886 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4887 ;; Operand 1 not used on the AVR.
4888 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4895 [(set_attr "cc" "clobber")
4896 (set_attr "length" "1,*,1,*")
4897 (set_attr "adjust_len" "*,call,*,call")])
4899 (define_insn "call_value_insn"
4900 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4901 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4902 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4903 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4904 ;; Operand 2 not used on the AVR.
4905 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4912 [(set_attr "cc" "clobber")
4913 (set_attr "length" "1,*,1,*")
4914 (set_attr "adjust_len" "*,call,*,call")])
4920 [(set_attr "cc" "none")
4921 (set_attr "length" "1")])
4925 (define_expand "indirect_jump"
4927 (match_operand:HI 0 "nonmemory_operand" ""))]
4930 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4932 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4937 (define_insn "*indirect_jump"
4939 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4945 push %A0\;push %B0\;ret
4947 [(set_attr "length" "1,2,1,3,1")
4948 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4949 (set_attr "cc" "none")])
4952 ;; For entries in jump table see avr_output_addr_vec_elt.
4955 ;; "rjmp .L<n>" instructions for <= 8K devices
4956 ;; ".word gs(.L<n>)" addresses for > 8K devices
4957 (define_insn "*tablejump"
4959 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4961 (use (label_ref (match_operand 1 "" "")))
4962 (clobber (match_dup 0))]
4966 push %A0\;push %B0\;ret
4968 [(set_attr "length" "1,3,2")
4969 (set_attr "isa" "rjmp,rjmp,jmp")
4970 (set_attr "cc" "none,none,clobber")])
4973 (define_expand "casesi"
4974 [(parallel [(set (match_dup 6)
4975 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4976 (match_operand:HI 1 "register_operand" "")))
4977 (clobber (scratch:QI))])
4978 (parallel [(set (cc0)
4979 (compare (match_dup 6)
4980 (match_operand:HI 2 "register_operand" "")))
4981 (clobber (match_scratch:QI 9 ""))])
4984 (if_then_else (gtu (cc0)
4986 (label_ref (match_operand 4 "" ""))
4990 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4992 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4993 (use (label_ref (match_dup 3)))
4994 (clobber (match_dup 6))])]
4997 operands[6] = gen_reg_rtx (HImode);
5001 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5002 ;; This instruction sets Z flag
5005 [(set (cc0) (const_int 0))]
5008 [(set_attr "length" "1")
5009 (set_attr "cc" "compare")])
5011 ;; Clear/set/test a single bit in I/O address space.
5014 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5015 (and:QI (mem:QI (match_dup 0))
5016 (match_operand:QI 1 "single_zero_operand" "n")))]
5019 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5020 return "cbi %i0,%2";
5022 [(set_attr "length" "1")
5023 (set_attr "cc" "none")])
5026 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5027 (ior:QI (mem:QI (match_dup 0))
5028 (match_operand:QI 1 "single_one_operand" "n")))]
5031 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5032 return "sbi %i0,%2";
5034 [(set_attr "length" "1")
5035 (set_attr "cc" "none")])
5037 ;; Lower half of the I/O space - use sbic/sbis directly.
5038 (define_insn "*sbix_branch"
5041 (match_operator 0 "eqne_operator"
5043 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5045 (match_operand 2 "const_int_operand" "n"))
5047 (label_ref (match_operand 3 "" ""))
5051 return avr_out_sbxx_branch (insn, operands);
5053 [(set (attr "length")
5054 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5055 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5057 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5060 (set_attr "cc" "clobber")])
5062 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5063 (define_insn "*sbix_branch_bit7"
5066 (match_operator 0 "gelt_operator"
5067 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5069 (label_ref (match_operand 2 "" ""))
5073 operands[3] = operands[2];
5074 operands[2] = GEN_INT (7);
5075 return avr_out_sbxx_branch (insn, operands);
5077 [(set (attr "length")
5078 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5079 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5081 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5084 (set_attr "cc" "clobber")])
5086 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5087 (define_insn "*sbix_branch_tmp"
5090 (match_operator 0 "eqne_operator"
5092 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5094 (match_operand 2 "const_int_operand" "n"))
5096 (label_ref (match_operand 3 "" ""))
5100 return avr_out_sbxx_branch (insn, operands);
5102 [(set (attr "length")
5103 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5104 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5106 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5109 (set_attr "cc" "clobber")])
5111 (define_insn "*sbix_branch_tmp_bit7"
5114 (match_operator 0 "gelt_operator"
5115 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5117 (label_ref (match_operand 2 "" ""))
5121 operands[3] = operands[2];
5122 operands[2] = GEN_INT (7);
5123 return avr_out_sbxx_branch (insn, operands);
5125 [(set (attr "length")
5126 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5127 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5129 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5132 (set_attr "cc" "clobber")])
5134 ;; ************************* Peepholes ********************************
5136 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5137 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5138 (plus:SI (match_dup 0)
5140 (clobber (scratch:QI))])
5141 (parallel [(set (cc0)
5142 (compare (match_dup 0)
5144 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5146 (if_then_else (eqne (cc0)
5148 (label_ref (match_operand 2 "" ""))
5155 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5156 output_asm_insn ("sbiw %0,1" CR_TAB
5157 "sbc %C0,__zero_reg__" CR_TAB
5158 "sbc %D0,__zero_reg__", operands);
5160 output_asm_insn ("subi %A0,1" CR_TAB
5161 "sbc %B0,__zero_reg__" CR_TAB
5162 "sbc %C0,__zero_reg__" CR_TAB
5163 "sbc %D0,__zero_reg__", operands);
5165 jump_mode = avr_jump_mode (operands[2], insn);
5166 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5167 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5171 case 1: return "%1 %2";
5172 case 2: return "%1 .+2\;rjmp %2";
5173 case 3: return "%1 .+4\;jmp %2";
5180 (define_peephole ; "*dec-and-branchhi!=-1"
5181 [(set (match_operand:HI 0 "d_register_operand" "")
5182 (plus:HI (match_dup 0)
5184 (parallel [(set (cc0)
5185 (compare (match_dup 0)
5187 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5189 (if_then_else (eqne (cc0)
5191 (label_ref (match_operand 2 "" ""))
5198 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5199 output_asm_insn ("sbiw %0,1", operands);
5201 output_asm_insn ("subi %A0,1" CR_TAB
5202 "sbc %B0,__zero_reg__", operands);
5204 jump_mode = avr_jump_mode (operands[2], insn);
5205 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5206 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5210 case 1: return "%1 %2";
5211 case 2: return "%1 .+2\;rjmp %2";
5212 case 3: return "%1 .+4\;jmp %2";
5219 ;; Same as above but with clobber flavour of addhi3
5220 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5221 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5222 (plus:HI (match_dup 0)
5224 (clobber (scratch:QI))])
5225 (parallel [(set (cc0)
5226 (compare (match_dup 0)
5228 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5230 (if_then_else (eqne (cc0)
5232 (label_ref (match_operand 2 "" ""))
5239 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5240 output_asm_insn ("sbiw %0,1", operands);
5242 output_asm_insn ("subi %A0,1" CR_TAB
5243 "sbc %B0,__zero_reg__", operands);
5245 jump_mode = avr_jump_mode (operands[2], insn);
5246 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5247 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5251 case 1: return "%1 %2";
5252 case 2: return "%1 .+2\;rjmp %2";
5253 case 3: return "%1 .+4\;jmp %2";
5260 ;; Same as above but with clobber flavour of addhi3
5261 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5262 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5263 (plus:HI (match_dup 0)
5265 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5266 (parallel [(set (cc0)
5267 (compare (match_dup 0)
5269 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5271 (if_then_else (eqne (cc0)
5273 (label_ref (match_operand 2 "" ""))
5280 output_asm_insn ("ldi %3,1" CR_TAB
5282 "sbc %B0,__zero_reg__", operands);
5284 jump_mode = avr_jump_mode (operands[2], insn);
5285 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5286 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5290 case 1: return "%1 %2";
5291 case 2: return "%1 .+2\;rjmp %2";
5292 case 3: return "%1 .+4\;jmp %2";
5299 (define_peephole ; "*dec-and-branchqi!=-1"
5300 [(set (match_operand:QI 0 "d_register_operand" "")
5301 (plus:QI (match_dup 0)
5304 (compare (match_dup 0)
5307 (if_then_else (eqne (cc0)
5309 (label_ref (match_operand 1 "" ""))
5316 cc_status.value1 = operands[0];
5317 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5319 output_asm_insn ("subi %A0,1", operands);
5321 jump_mode = avr_jump_mode (operands[1], insn);
5322 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5323 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5327 case 1: return "%0 %1";
5328 case 2: return "%0 .+2\;rjmp %1";
5329 case 3: return "%0 .+4\;jmp %1";
5337 (define_peephole ; "*cpse.eq"
5339 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5340 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5342 (if_then_else (eq (cc0)
5344 (label_ref (match_operand 0 "" ""))
5346 "jump_over_one_insn_p (insn, operands[0])"
5349 cpse %1,__zero_reg__")
5351 ;; This peephole avoids code like
5354 ;; BREQ .+2 ; branch
5357 ;; Notice that the peephole is always shorter than cmpqi + branch.
5358 ;; The reason to write it as peephole is that sequences like
5363 ;; shall not be superseeded. With a respective combine pattern
5364 ;; the latter sequence would be
5367 ;; CPSE Rm, __zero_reg__
5370 ;; and thus longer and slower and not easy to be rolled back.
5372 (define_peephole ; "*cpse.ne"
5374 (compare (match_operand:ALL1 1 "register_operand" "")
5375 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5377 (if_then_else (ne (cc0)
5379 (label_ref (match_operand 0 "" ""))
5382 || !avr_current_device->errata_skip"
5384 if (operands[2] == CONST0_RTX (<MODE>mode))
5385 operands[2] = zero_reg_rtx;
5387 return 3 == avr_jump_mode (operands[0], insn)
5388 ? "cpse %1,%2\;jmp %0"
5389 : "cpse %1,%2\;rjmp %0";
5392 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5393 ;;prologue/epilogue support instructions
5395 (define_insn "popqi"
5396 [(set (match_operand:QI 0 "register_operand" "=r")
5397 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5400 [(set_attr "cc" "none")
5401 (set_attr "length" "1")])
5403 ;; Enable Interrupts
5404 (define_expand "enable_interrupt"
5405 [(clobber (const_int 0))]
5408 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5409 MEM_VOLATILE_P (mem) = 1;
5410 emit_insn (gen_cli_sei (const1_rtx, mem));
5414 ;; Disable Interrupts
5415 (define_expand "disable_interrupt"
5416 [(clobber (const_int 0))]
5419 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5420 MEM_VOLATILE_P (mem) = 1;
5421 emit_insn (gen_cli_sei (const0_rtx, mem));
5425 (define_insn "cli_sei"
5426 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5427 UNSPECV_ENABLE_IRQS)
5428 (set (match_operand:BLK 1 "" "")
5429 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5434 [(set_attr "length" "1")
5435 (set_attr "cc" "none")])
5437 ;; Library prologue saves
5438 (define_insn "call_prologue_saves"
5439 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5440 (match_operand:HI 0 "immediate_operand" "i,i")
5441 (set (reg:HI REG_SP)
5442 (minus:HI (reg:HI REG_SP)
5443 (match_operand:HI 1 "immediate_operand" "i,i")))
5444 (use (reg:HI REG_X))
5445 (clobber (reg:HI REG_Z))]
5447 "ldi r30,lo8(gs(1f))
5449 %~jmp __prologue_saves__+((18 - %0) * 2)
5451 [(set_attr "length" "5,6")
5452 (set_attr "cc" "clobber")
5453 (set_attr "isa" "rjmp,jmp")])
5455 ; epilogue restores using library
5456 (define_insn "epilogue_restores"
5457 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5459 (plus:HI (reg:HI REG_Y)
5460 (match_operand:HI 0 "immediate_operand" "i,i")))
5461 (set (reg:HI REG_SP)
5462 (plus:HI (reg:HI REG_Y)
5464 (clobber (reg:QI REG_Z))]
5467 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5468 [(set_attr "length" "2,3")
5469 (set_attr "cc" "clobber")
5470 (set_attr "isa" "rjmp,jmp")])
5473 (define_insn "return"
5475 "reload_completed && avr_simple_epilogue ()"
5477 [(set_attr "cc" "none")
5478 (set_attr "length" "1")])
5480 (define_insn "return_from_epilogue"
5484 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5485 && !cfun->machine->is_naked)"
5487 [(set_attr "cc" "none")
5488 (set_attr "length" "1")])
5490 (define_insn "return_from_interrupt_epilogue"
5494 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5495 && !cfun->machine->is_naked)"
5497 [(set_attr "cc" "none")
5498 (set_attr "length" "1")])
5500 (define_insn "return_from_naked_epilogue"
5504 && cfun->machine->is_naked)"
5506 [(set_attr "cc" "none")
5507 (set_attr "length" "0")])
5509 (define_expand "prologue"
5517 (define_expand "epilogue"
5521 expand_epilogue (false /* sibcall_p */);
5525 (define_expand "sibcall_epilogue"
5529 expand_epilogue (true /* sibcall_p */);
5533 ;; Some instructions resp. instruction sequences available
5536 (define_insn "delay_cycles_1"
5537 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5539 UNSPECV_DELAY_CYCLES)
5540 (set (match_operand:BLK 1 "" "")
5541 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5542 (clobber (match_scratch:QI 2 "=&d"))]
5547 [(set_attr "length" "3")
5548 (set_attr "cc" "clobber")])
5550 (define_insn "delay_cycles_2"
5551 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5553 UNSPECV_DELAY_CYCLES)
5554 (set (match_operand:BLK 1 "" "")
5555 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5556 (clobber (match_scratch:HI 2 "=&w"))]
5562 [(set_attr "length" "4")
5563 (set_attr "cc" "clobber")])
5565 (define_insn "delay_cycles_3"
5566 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5568 UNSPECV_DELAY_CYCLES)
5569 (set (match_operand:BLK 1 "" "")
5570 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5571 (clobber (match_scratch:QI 2 "=&d"))
5572 (clobber (match_scratch:QI 3 "=&d"))
5573 (clobber (match_scratch:QI 4 "=&d"))]
5582 [(set_attr "length" "7")
5583 (set_attr "cc" "clobber")])
5585 (define_insn "delay_cycles_4"
5586 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5588 UNSPECV_DELAY_CYCLES)
5589 (set (match_operand:BLK 1 "" "")
5590 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5591 (clobber (match_scratch:QI 2 "=&d"))
5592 (clobber (match_scratch:QI 3 "=&d"))
5593 (clobber (match_scratch:QI 4 "=&d"))
5594 (clobber (match_scratch:QI 5 "=&d"))]
5605 [(set_attr "length" "9")
5606 (set_attr "cc" "clobber")])
5609 ;; __builtin_avr_insert_bits
5611 (define_insn "insert_bits"
5612 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5613 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5614 (match_operand:QI 2 "register_operand" "r ,r ,r")
5615 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5616 UNSPEC_INSERT_BITS))]
5619 return avr_out_insert_bits (operands, NULL);
5621 [(set_attr "adjust_len" "insert_bits")
5622 (set_attr "cc" "clobber")])
5625 ;; __builtin_avr_flash_segment
5627 ;; Just a helper for the next "official" expander.
5629 (define_expand "flash_segment1"
5630 [(set (match_operand:QI 0 "register_operand" "")
5631 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5634 (compare (match_dup 0)
5637 (if_then_else (ge (cc0)
5639 (label_ref (match_operand 2 "" ""))
5644 (define_expand "flash_segment"
5645 [(parallel [(match_operand:QI 0 "register_operand" "")
5646 (match_operand:PSI 1 "register_operand" "")])]
5649 rtx label = gen_label_rtx ();
5650 emit (gen_flash_segment1 (operands[0], operands[1], label));
5655 ;; Actually, it's too late now to work out address spaces known at compiletime.
5656 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5657 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5658 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5660 (define_insn_and_split "*split.flash_segment"
5661 [(set (match_operand:QI 0 "register_operand" "=d")
5662 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5663 (match_operand:HI 2 "register_operand" "r"))
5666 { gcc_unreachable(); }
5674 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5675 ;; better 8-bit parity recognition.
5677 (define_expand "parityhi2"
5678 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5679 (parity:HI (match_operand:HI 1 "register_operand" "")))
5680 (clobber (reg:HI 24))])])
5682 (define_insn_and_split "*parityhi2"
5683 [(set (match_operand:HI 0 "register_operand" "=r")
5684 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5685 (clobber (reg:HI 24))]
5687 { gcc_unreachable(); }
5692 (parity:HI (reg:HI 24)))
5696 (define_insn_and_split "*parityqihi2"
5697 [(set (match_operand:HI 0 "register_operand" "=r")
5698 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5699 (clobber (reg:HI 24))]
5701 { gcc_unreachable(); }
5706 (zero_extend:HI (parity:QI (reg:QI 24))))
5710 (define_expand "paritysi2"
5712 (match_operand:SI 1 "register_operand" ""))
5714 (truncate:HI (parity:SI (reg:SI 22))))
5717 (set (match_operand:SI 0 "register_operand" "")
5718 (zero_extend:SI (match_dup 2)))]
5721 operands[2] = gen_reg_rtx (HImode);
5724 (define_insn "*parityhi2.libgcc"
5726 (parity:HI (reg:HI 24)))]
5728 "%~call __parityhi2"
5729 [(set_attr "type" "xcall")
5730 (set_attr "cc" "clobber")])
5732 (define_insn "*parityqihi2.libgcc"
5734 (zero_extend:HI (parity:QI (reg:QI 24))))]
5736 "%~call __parityqi2"
5737 [(set_attr "type" "xcall")
5738 (set_attr "cc" "clobber")])
5740 (define_insn "*paritysihi2.libgcc"
5742 (truncate:HI (parity:SI (reg:SI 22))))]
5744 "%~call __paritysi2"
5745 [(set_attr "type" "xcall")
5746 (set_attr "cc" "clobber")])
5751 (define_expand "popcounthi2"
5753 (match_operand:HI 1 "register_operand" ""))
5755 (popcount:HI (reg:HI 24)))
5756 (set (match_operand:HI 0 "register_operand" "")
5761 (define_expand "popcountsi2"
5763 (match_operand:SI 1 "register_operand" ""))
5765 (truncate:HI (popcount:SI (reg:SI 22))))
5768 (set (match_operand:SI 0 "register_operand" "")
5769 (zero_extend:SI (match_dup 2)))]
5772 operands[2] = gen_reg_rtx (HImode);
5775 (define_insn "*popcounthi2.libgcc"
5777 (popcount:HI (reg:HI 24)))]
5779 "%~call __popcounthi2"
5780 [(set_attr "type" "xcall")
5781 (set_attr "cc" "clobber")])
5783 (define_insn "*popcountsi2.libgcc"
5785 (truncate:HI (popcount:SI (reg:SI 22))))]
5787 "%~call __popcountsi2"
5788 [(set_attr "type" "xcall")
5789 (set_attr "cc" "clobber")])
5791 (define_insn "*popcountqi2.libgcc"
5793 (popcount:QI (reg:QI 24)))]
5795 "%~call __popcountqi2"
5796 [(set_attr "type" "xcall")
5797 (set_attr "cc" "clobber")])
5799 (define_insn_and_split "*popcountqihi2.libgcc"
5801 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5806 (popcount:QI (reg:QI 24)))
5811 ;; Count Leading Zeros
5813 (define_expand "clzhi2"
5815 (match_operand:HI 1 "register_operand" ""))
5816 (parallel [(set (reg:HI 24)
5817 (clz:HI (reg:HI 24)))
5818 (clobber (reg:QI 26))])
5819 (set (match_operand:HI 0 "register_operand" "")
5824 (define_expand "clzsi2"
5826 (match_operand:SI 1 "register_operand" ""))
5827 (parallel [(set (reg:HI 24)
5828 (truncate:HI (clz:SI (reg:SI 22))))
5829 (clobber (reg:QI 26))])
5832 (set (match_operand:SI 0 "register_operand" "")
5833 (zero_extend:SI (match_dup 2)))]
5836 operands[2] = gen_reg_rtx (HImode);
5839 (define_insn "*clzhi2.libgcc"
5841 (clz:HI (reg:HI 24)))
5842 (clobber (reg:QI 26))]
5845 [(set_attr "type" "xcall")
5846 (set_attr "cc" "clobber")])
5848 (define_insn "*clzsihi2.libgcc"
5850 (truncate:HI (clz:SI (reg:SI 22))))
5851 (clobber (reg:QI 26))]
5854 [(set_attr "type" "xcall")
5855 (set_attr "cc" "clobber")])
5857 ;; Count Trailing Zeros
5859 (define_expand "ctzhi2"
5861 (match_operand:HI 1 "register_operand" ""))
5862 (parallel [(set (reg:HI 24)
5863 (ctz:HI (reg:HI 24)))
5864 (clobber (reg:QI 26))])
5865 (set (match_operand:HI 0 "register_operand" "")
5870 (define_expand "ctzsi2"
5872 (match_operand:SI 1 "register_operand" ""))
5873 (parallel [(set (reg:HI 24)
5874 (truncate:HI (ctz:SI (reg:SI 22))))
5875 (clobber (reg:QI 22))
5876 (clobber (reg:QI 26))])
5879 (set (match_operand:SI 0 "register_operand" "")
5880 (zero_extend:SI (match_dup 2)))]
5883 operands[2] = gen_reg_rtx (HImode);
5886 (define_insn "*ctzhi2.libgcc"
5888 (ctz:HI (reg:HI 24)))
5889 (clobber (reg:QI 26))]
5892 [(set_attr "type" "xcall")
5893 (set_attr "cc" "clobber")])
5895 (define_insn "*ctzsihi2.libgcc"
5897 (truncate:HI (ctz:SI (reg:SI 22))))
5898 (clobber (reg:QI 22))
5899 (clobber (reg:QI 26))]
5902 [(set_attr "type" "xcall")
5903 (set_attr "cc" "clobber")])
5907 (define_expand "ffshi2"
5909 (match_operand:HI 1 "register_operand" ""))
5910 (parallel [(set (reg:HI 24)
5911 (ffs:HI (reg:HI 24)))
5912 (clobber (reg:QI 26))])
5913 (set (match_operand:HI 0 "register_operand" "")
5918 (define_expand "ffssi2"
5920 (match_operand:SI 1 "register_operand" ""))
5921 (parallel [(set (reg:HI 24)
5922 (truncate:HI (ffs:SI (reg:SI 22))))
5923 (clobber (reg:QI 22))
5924 (clobber (reg:QI 26))])
5927 (set (match_operand:SI 0 "register_operand" "")
5928 (zero_extend:SI (match_dup 2)))]
5931 operands[2] = gen_reg_rtx (HImode);
5934 (define_insn "*ffshi2.libgcc"
5936 (ffs:HI (reg:HI 24)))
5937 (clobber (reg:QI 26))]
5940 [(set_attr "type" "xcall")
5941 (set_attr "cc" "clobber")])
5943 (define_insn "*ffssihi2.libgcc"
5945 (truncate:HI (ffs:SI (reg:SI 22))))
5946 (clobber (reg:QI 22))
5947 (clobber (reg:QI 26))]
5950 [(set_attr "type" "xcall")
5951 (set_attr "cc" "clobber")])
5955 (define_insn "copysignsf3"
5956 [(set (match_operand:SF 0 "register_operand" "=r")
5957 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5958 (match_operand:SF 2 "register_operand" "r")]
5961 "bst %D2,7\;bld %D0,7"
5962 [(set_attr "length" "2")
5963 (set_attr "cc" "none")])
5965 ;; Swap Bytes (change byte-endianess)
5967 (define_expand "bswapsi2"
5969 (match_operand:SI 1 "register_operand" ""))
5971 (bswap:SI (reg:SI 22)))
5972 (set (match_operand:SI 0 "register_operand" "")
5977 (define_insn "*bswapsi2.libgcc"
5979 (bswap:SI (reg:SI 22)))]
5982 [(set_attr "type" "xcall")
5983 (set_attr "cc" "clobber")])
5988 ;; NOP taking 1 or 2 Ticks
5989 (define_expand "nopv"
5990 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5993 (unspec_volatile:BLK [(match_dup 1)]
5994 UNSPECV_MEMORY_BARRIER))])]
5997 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5998 MEM_VOLATILE_P (operands[1]) = 1;
6001 (define_insn "*nopv"
6002 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6004 (set (match_operand:BLK 1 "" "")
6005 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6010 [(set_attr "length" "1")
6011 (set_attr "cc" "none")])
6014 (define_expand "sleep"
6015 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6017 (unspec_volatile:BLK [(match_dup 0)]
6018 UNSPECV_MEMORY_BARRIER))])]
6021 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6022 MEM_VOLATILE_P (operands[0]) = 1;
6025 (define_insn "*sleep"
6026 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6027 (set (match_operand:BLK 0 "" "")
6028 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6031 [(set_attr "length" "1")
6032 (set_attr "cc" "none")])
6035 (define_expand "wdr"
6036 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6038 (unspec_volatile:BLK [(match_dup 0)]
6039 UNSPECV_MEMORY_BARRIER))])]
6042 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6043 MEM_VOLATILE_P (operands[0]) = 1;
6047 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6048 (set (match_operand:BLK 0 "" "")
6049 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6052 [(set_attr "length" "1")
6053 (set_attr "cc" "none")])
6056 (define_expand "fmul"
6058 (match_operand:QI 1 "register_operand" ""))
6060 (match_operand:QI 2 "register_operand" ""))
6061 (parallel [(set (reg:HI 22)
6062 (unspec:HI [(reg:QI 24)
6063 (reg:QI 25)] UNSPEC_FMUL))
6064 (clobber (reg:HI 24))])
6065 (set (match_operand:HI 0 "register_operand" "")
6071 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6076 (define_insn "fmul_insn"
6077 [(set (match_operand:HI 0 "register_operand" "=r")
6078 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6079 (match_operand:QI 2 "register_operand" "a")]
6085 [(set_attr "length" "3")
6086 (set_attr "cc" "clobber")])
6088 (define_insn "*fmul.call"
6090 (unspec:HI [(reg:QI 24)
6091 (reg:QI 25)] UNSPEC_FMUL))
6092 (clobber (reg:HI 24))]
6095 [(set_attr "type" "xcall")
6096 (set_attr "cc" "clobber")])
6099 (define_expand "fmuls"
6101 (match_operand:QI 1 "register_operand" ""))
6103 (match_operand:QI 2 "register_operand" ""))
6104 (parallel [(set (reg:HI 22)
6105 (unspec:HI [(reg:QI 24)
6106 (reg:QI 25)] UNSPEC_FMULS))
6107 (clobber (reg:HI 24))])
6108 (set (match_operand:HI 0 "register_operand" "")
6114 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6119 (define_insn "fmuls_insn"
6120 [(set (match_operand:HI 0 "register_operand" "=r")
6121 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6122 (match_operand:QI 2 "register_operand" "a")]
6128 [(set_attr "length" "3")
6129 (set_attr "cc" "clobber")])
6131 (define_insn "*fmuls.call"
6133 (unspec:HI [(reg:QI 24)
6134 (reg:QI 25)] UNSPEC_FMULS))
6135 (clobber (reg:HI 24))]
6138 [(set_attr "type" "xcall")
6139 (set_attr "cc" "clobber")])
6142 (define_expand "fmulsu"
6144 (match_operand:QI 1 "register_operand" ""))
6146 (match_operand:QI 2 "register_operand" ""))
6147 (parallel [(set (reg:HI 22)
6148 (unspec:HI [(reg:QI 24)
6149 (reg:QI 25)] UNSPEC_FMULSU))
6150 (clobber (reg:HI 24))])
6151 (set (match_operand:HI 0 "register_operand" "")
6157 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6162 (define_insn "fmulsu_insn"
6163 [(set (match_operand:HI 0 "register_operand" "=r")
6164 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6165 (match_operand:QI 2 "register_operand" "a")]
6171 [(set_attr "length" "3")
6172 (set_attr "cc" "clobber")])
6174 (define_insn "*fmulsu.call"
6176 (unspec:HI [(reg:QI 24)
6177 (reg:QI 25)] UNSPEC_FMULSU))
6178 (clobber (reg:HI 24))]
6181 [(set_attr "type" "xcall")
6182 (set_attr "cc" "clobber")])
6185 ;; Some combiner patterns dealing with bits.
6188 ;; Move bit $3.0 into bit $0.$4
6189 (define_insn "*movbitqi.1-6.a"
6190 [(set (match_operand:QI 0 "register_operand" "=r")
6191 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6192 (match_operand:QI 2 "single_zero_operand" "n"))
6193 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6194 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6195 (match_operand:QI 5 "single_one_operand" "n"))))]
6196 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6197 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6198 "bst %3,0\;bld %0,%4"
6199 [(set_attr "length" "2")
6200 (set_attr "cc" "none")])
6202 ;; Move bit $3.0 into bit $0.$4
6203 ;; Variation of above. Unfortunately, there is no canonicalized representation
6204 ;; of moving around bits. So what we see here depends on how user writes down
6205 ;; bit manipulations.
6206 (define_insn "*movbitqi.1-6.b"
6207 [(set (match_operand:QI 0 "register_operand" "=r")
6208 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6209 (match_operand:QI 2 "single_zero_operand" "n"))
6210 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6212 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6213 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6214 "bst %3,0\;bld %0,%4"
6215 [(set_attr "length" "2")
6216 (set_attr "cc" "none")])
6218 ;; Move bit $3.0 into bit $0.0.
6219 ;; For bit 0, combiner generates slightly different pattern.
6220 (define_insn "*movbitqi.0"
6221 [(set (match_operand:QI 0 "register_operand" "=r")
6222 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6223 (match_operand:QI 2 "single_zero_operand" "n"))
6224 (and:QI (match_operand:QI 3 "register_operand" "r")
6226 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6227 "bst %3,0\;bld %0,0"
6228 [(set_attr "length" "2")
6229 (set_attr "cc" "none")])
6231 ;; Move bit $2.0 into bit $0.7.
6232 ;; For bit 7, combiner generates slightly different pattern
6233 (define_insn "*movbitqi.7"
6234 [(set (match_operand:QI 0 "register_operand" "=r")
6235 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6237 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6240 "bst %2,0\;bld %0,7"
6241 [(set_attr "length" "2")
6242 (set_attr "cc" "none")])
6244 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6245 ;; and input/output match. We provide a special pattern for this, because
6246 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6247 ;; operation on I/O is atomic.
6248 (define_insn "*insv.io"
6249 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6251 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6252 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6257 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6258 [(set_attr "length" "1,1,4")
6259 (set_attr "cc" "none")])
6261 (define_insn "*insv.not.io"
6262 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6264 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6265 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6267 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6268 [(set_attr "length" "4")
6269 (set_attr "cc" "none")])
6271 ;; The insv expander.
6272 ;; We only support 1-bit inserts
6273 (define_expand "insv"
6274 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6275 (match_operand:QI 1 "const1_operand" "") ; width
6276 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6277 (match_operand:QI 3 "nonmemory_operand" ""))]
6281 ;; Insert bit $2.0 into $0.$1
6282 (define_insn "*insv.reg"
6283 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6285 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6286 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6290 andi %0,lo8(~(1<<%1))
6294 [(set_attr "length" "2,1,1,2,2")
6295 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6298 ;; Some combine patterns that try to fix bad code when a value is composed
6299 ;; from byte parts like in PR27663.
6300 ;; The patterns give some release but the code still is not optimal,
6301 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6302 ;; That switch obfuscates things here and in many other places.
6304 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6305 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6306 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6307 [(set (match_operand:HISI 0 "register_operand" "=r")
6309 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6310 (match_operand:HISI 2 "register_operand" "0")))]
6315 (xior:QI (match_dup 3)
6318 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6321 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6322 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6323 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6324 [(set (match_operand:HISI 0 "register_operand" "=r")
6326 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6327 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6328 (match_operand:HISI 3 "register_operand" "0")))]
6329 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6331 "&& reload_completed"
6333 (xior:QI (match_dup 4)
6336 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6337 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6340 (define_expand "extzv"
6341 [(set (match_operand:QI 0 "register_operand" "")
6342 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6343 (match_operand:QI 2 "const1_operand" "")
6344 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6348 (define_insn "*extzv"
6349 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6350 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6352 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6356 mov %0,%1\;andi %0,1
6359 bst %1,%2\;clr %0\;bld %0,0"
6360 [(set_attr "length" "1,2,2,2,3")
6361 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6363 (define_insn_and_split "*extzv.qihi1"
6364 [(set (match_operand:HI 0 "register_operand" "=r")
6365 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6367 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6372 (zero_extract:QI (match_dup 1)
6378 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6379 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6382 (define_insn_and_split "*extzv.qihi2"
6383 [(set (match_operand:HI 0 "register_operand" "=r")
6385 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6387 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6392 (zero_extract:QI (match_dup 1)
6398 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6399 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6403 ;; Fixed-point instructions
6404 (include "avr-fixed.md")
6406 ;; Operations on 64-bit registers
6407 (include "avr-dimode.md")