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 QQ UQQ
239 ;; Supported ordered modes that are 2, 3, 4 bytes wide
240 (define_mode_iterator ORDERED234 [HI SI PSI
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
366 (define_expand "push<mode>1"
367 [(match_operand:MPUSH 0 "" "")]
371 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
373 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
374 if (part != const0_rtx)
375 part = force_reg (QImode, part);
376 emit_insn (gen_pushqi1 (part));
381 ;; Notice a special-case when adding N to SP where N results in a
382 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
384 [(set (reg:HI REG_SP)
385 (match_operand:HI 0 "register_operand" ""))]
387 && frame_pointer_needed
388 && !cfun->calls_alloca
389 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
390 [(set (reg:HI REG_SP)
393 ;;========================================================================
396 ;; Represent a load from __flash that needs libgcc support as UNSPEC.
397 ;; This is legal because we read from non-changing memory.
398 ;; For rationale see the FIXME below.
403 (define_insn "load_<mode>_libgcc"
404 [(set (reg:MOVMODE 22)
405 (unspec:MOVMODE [(reg:HI REG_Z)]
409 rtx n_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
410 output_asm_insn ("%~call __load_%0", &n_bytes);
413 [(set_attr "type" "xcall")
414 (set_attr "cc" "clobber")])
417 ;; Similar for inline reads from flash. We use UNSPEC instead
418 ;; of MEM for the same reason as above: PR52543.
419 ;; $1 contains the memory segment.
421 (define_insn "load_<mode>"
422 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
423 (unspec:MOVMODE [(reg:HI REG_Z)
424 (match_operand:QI 1 "reg_or_0_operand" "rL")]
426 "(CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
427 || (REG_P (operands[1]) && AVR_HAVE_ELPMX)"
429 return avr_load_lpm (insn, operands, NULL);
431 [(set_attr "adjust_len" "load_lpm")
432 (set_attr "cc" "clobber")])
435 ;; Similar to above for the complementary situation when there is no [E]LPMx.
436 ;; Clobber Z in that case.
438 (define_insn "load_<mode>_clobber"
439 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
440 (unspec:MOVMODE [(reg:HI REG_Z)
441 (match_operand:QI 1 "reg_or_0_operand" "rL")]
443 (clobber (reg:HI REG_Z))]
444 "!((CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
445 || (REG_P (operands[1]) && AVR_HAVE_ELPMX))"
447 return avr_load_lpm (insn, operands, NULL);
449 [(set_attr "adjust_len" "load_lpm")
450 (set_attr "cc" "clobber")])
454 ;; "xload8qq_A" "xload8uqq_A"
455 (define_insn_and_split "xload8<mode>_A"
456 [(set (match_operand:ALL1 0 "register_operand" "=r")
457 (match_operand:ALL1 1 "memory_operand" "m"))
458 (clobber (reg:HI REG_Z))]
459 "can_create_pseudo_p()
460 && !avr_xload_libgcc_p (<MODE>mode)
461 && avr_mem_memx_p (operands[1])
462 && REG_P (XEXP (operands[1], 0))"
463 { gcc_unreachable(); }
465 [(clobber (const_int 0))]
467 rtx insn, addr = XEXP (operands[1], 0);
468 rtx hi8 = gen_reg_rtx (QImode);
469 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
471 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
472 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
474 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
475 set_mem_addr_space (SET_SRC (single_set (insn)),
476 MEM_ADDR_SPACE (operands[1]));
480 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
481 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
482 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
485 (define_insn_and_split "xload<mode>_A"
486 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
487 (match_operand:MOVMODE 1 "memory_operand" "m"))
488 (clobber (reg:MOVMODE 22))
489 (clobber (reg:QI 21))
490 (clobber (reg:HI REG_Z))]
491 "can_create_pseudo_p()
492 && avr_mem_memx_p (operands[1])
493 && REG_P (XEXP (operands[1], 0))"
494 { gcc_unreachable(); }
496 [(clobber (const_int 0))]
498 rtx addr = XEXP (operands[1], 0);
499 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
500 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
501 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
504 /* Split the address to R21:Z */
505 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
506 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
508 /* Load with code from libgcc */
509 insn = emit_insn (gen_xload_<mode>_libgcc ());
510 set_mem_addr_space (SET_SRC (single_set (insn)), as);
512 /* Move to destination */
513 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
518 ;; Move value from address space memx to a register
519 ;; These insns must be prior to respective generic move insn.
522 ;; "xloadqq_8" "xloaduqq_8"
523 (define_insn "xload<mode>_8"
524 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
525 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
527 "!avr_xload_libgcc_p (<MODE>mode)"
529 return avr_out_xload (insn, operands, NULL);
531 [(set_attr "length" "4,4")
532 (set_attr "adjust_len" "*,xload")
533 (set_attr "isa" "lpmx,lpm")
534 (set_attr "cc" "none")])
536 ;; R21:Z : 24-bit source address
537 ;; R22 : 1-4 byte output
539 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
540 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
541 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
543 ;; "xload_psi_libgcc"
544 (define_insn "xload_<mode>_libgcc"
545 [(set (reg:MOVMODE 22)
546 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
548 (clobber (reg:QI 21))
549 (clobber (reg:HI REG_Z))]
550 "avr_xload_libgcc_p (<MODE>mode)"
552 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
554 output_asm_insn ("%~call __xload_%0", &x_bytes);
557 [(set_attr "type" "xcall")
558 (set_attr "cc" "clobber")])
561 ;; General move expanders
563 ;; "movqi" "movqq" "movuqq"
564 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
565 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
568 (define_expand "mov<mode>"
569 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
570 (match_operand:MOVMODE 1 "general_operand" ""))]
573 rtx dest = operands[0];
574 rtx src = operands[1];
576 if (avr_mem_flash_p (dest))
579 /* One of the operands has to be in a register. */
580 if (!register_operand (dest, <MODE>mode)
581 && !reg_or_0_operand (src, <MODE>mode))
583 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
586 if (avr_mem_memx_p (src))
588 rtx addr = XEXP (src, 0);
591 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
593 if (!avr_xload_libgcc_p (<MODE>mode))
594 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
595 ; insn-emit does not depend on the mode, it' all about operands. */
596 emit_insn (gen_xload8qi_A (dest, src));
598 emit_insn (gen_xload<mode>_A (dest, src));
603 /* For old devices without LPMx, prefer __flash loads per libcall. */
605 if (avr_load_libgcc_p (src))
607 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
608 force_reg (Pmode, XEXP (src, 0)));
610 emit_insn (gen_load_<mode>_libgcc ());
611 emit_move_insn (dest, gen_rtx_REG (<MODE>mode, 22));
615 /* ; FIXME: Hack around PR rtl-optimization/52543.
616 ; lower-subreg.c splits loads from the 16-bit address spaces which
617 ; causes code bloat because each load need his setting of RAMPZ.
618 ; Moreover, the split will happen in such a way that the loads don't
619 ; take advantage of POST_INC addressing. Thus, we use UNSPEC to
620 ; represent these loads instead. Notice that this is legitimate
621 ; because the memory content does not change: Loads from the same
622 ; address will yield the same value.
623 ; POST_INC addressing would make the addresses mode_dependent and could
624 ; work around that PR, too. However, notice that it is *not* legitimate
625 ; to expand to POST_INC at expand time: The following passes assert
626 ; that pre-/post-modify addressing is introduced by .auto_inc_dec and
627 ; does not exist before that pass. */
629 if (avr_mem_flash_p (src)
630 && (GET_MODE_SIZE (<MODE>mode) > 1
631 || MEM_ADDR_SPACE (src) != ADDR_SPACE_FLASH))
633 rtx xsegment = GEN_INT (avr_addrspace[MEM_ADDR_SPACE (src)].segment);
635 xsegment = const0_rtx;
636 if (xsegment != const0_rtx)
637 xsegment = force_reg (QImode, xsegment);
639 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
640 force_reg (Pmode, XEXP (src, 0)));
642 if ((CONST_INT_P (xsegment) && AVR_HAVE_LPMX)
643 || (REG_P (xsegment) && AVR_HAVE_ELPMX))
644 emit_insn (gen_load_<mode> (dest, xsegment));
646 emit_insn (gen_load_<mode>_clobber (dest, xsegment));
650 /* ; The only address-space for which we use plain MEM and reload
651 ; machinery are 1-byte loads from __flash. */
654 ;;========================================================================
656 ;; The last alternative (any immediate constant to any register) is
657 ;; very expensive. It should be optimized by peephole2 if a scratch
658 ;; register is available, but then that register could just as well be
659 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
660 ;; are call-saved registers, and most of LD_REGS are call-used registers,
661 ;; so this may still be a win for registers live across function calls.
664 ;; "movqq_insn" "movuqq_insn"
665 (define_insn "mov<mode>_insn"
666 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
667 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
668 "register_operand (operands[0], <MODE>mode)
669 || reg_or_0_operand (operands[1], <MODE>mode)"
671 return output_movqi (insn, operands, NULL);
673 [(set_attr "length" "1,1,5,5,1,1,4")
674 (set_attr "adjust_len" "mov8")
675 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
677 ;; This is used in peephole2 to optimize loading immediate constants
678 ;; if a scratch register from LD_REGS happens to be available.
681 ;; "*reload_inqq" "*reload_inuqq"
682 (define_insn "*reload_in<mode>"
683 [(set (match_operand:ALL1 0 "register_operand" "=l")
684 (match_operand:ALL1 1 "const_operand" "i"))
685 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
689 [(set_attr "length" "2")
690 (set_attr "cc" "none")])
693 [(match_scratch:QI 2 "d")
694 (set (match_operand:ALL1 0 "l_register_operand" "")
695 (match_operand:ALL1 1 "const_operand" ""))]
696 ; No need for a clobber reg for 0x0, 0x01 or 0xff
697 "!satisfies_constraint_Y00 (operands[1])
698 && !satisfies_constraint_Y01 (operands[1])
699 && !satisfies_constraint_Ym1 (operands[1])"
700 [(parallel [(set (match_dup 0)
702 (clobber (match_dup 2))])])
704 ;;============================================================================
705 ;; move word (16 bit)
707 ;; Move register $1 to the Stack Pointer register SP.
708 ;; This insn is emit during function prologue/epilogue generation.
709 ;; $2 = 0: We know that IRQs are off
710 ;; $2 = 1: We know that IRQs are on
711 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
712 ;; $2 = -1: We don't know anything about IRQ on/off
713 ;; Always write SP via unspec, see PR50063
715 (define_insn "movhi_sp_r"
716 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
717 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
718 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
722 out %B0,%B1\;out %A0,%A1
723 cli\;out %B0,%B1\;sei\;out %A0,%A1
724 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
726 out %A0,%A1\;out %B0,%B1"
727 [(set_attr "length" "2,4,5,1,2")
728 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
729 (set_attr "cc" "none")])
732 [(match_scratch:QI 2 "d")
733 (set (match_operand:ALL2 0 "l_register_operand" "")
734 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
735 "operands[1] != CONST0_RTX (<MODE>mode)"
736 [(parallel [(set (match_dup 0)
738 (clobber (match_dup 2))])])
740 ;; '*' because it is not used in rtl generation, only in above peephole
742 ;; "*reload_inhq" "*reload_inuhq"
743 ;; "*reload_inha" "*reload_inuha"
744 (define_insn "*reload_in<mode>"
745 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
746 (match_operand:ALL2 1 "immediate_operand" "i"))
747 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
750 return output_reload_inhi (operands, operands[2], NULL);
752 [(set_attr "length" "4")
753 (set_attr "adjust_len" "reload_in16")
754 (set_attr "cc" "clobber")])
757 ;; "*movhq" "*movuhq"
758 ;; "*movha" "*movuha"
759 (define_insn "*mov<mode>"
760 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
761 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
762 "register_operand (operands[0], <MODE>mode)
763 || reg_or_0_operand (operands[1], <MODE>mode)"
765 return output_movhi (insn, operands, NULL);
767 [(set_attr "length" "2,2,6,7,2,6,5,2")
768 (set_attr "adjust_len" "mov16")
769 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
771 (define_peephole2 ; movw
772 [(set (match_operand:ALL1 0 "even_register_operand" "")
773 (match_operand:ALL1 1 "even_register_operand" ""))
774 (set (match_operand:ALL1 2 "odd_register_operand" "")
775 (match_operand:ALL1 3 "odd_register_operand" ""))]
777 && REGNO (operands[0]) == REGNO (operands[2]) - 1
778 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
782 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
783 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
786 (define_peephole2 ; movw_r
787 [(set (match_operand:ALL1 0 "odd_register_operand" "")
788 (match_operand:ALL1 1 "odd_register_operand" ""))
789 (set (match_operand:ALL1 2 "even_register_operand" "")
790 (match_operand:ALL1 3 "even_register_operand" ""))]
792 && REGNO (operands[2]) == REGNO (operands[0]) - 1
793 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
797 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
798 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
801 ;;==========================================================================
802 ;; xpointer move (24 bit)
804 (define_peephole2 ; *reload_inpsi
805 [(match_scratch:QI 2 "d")
806 (set (match_operand:PSI 0 "l_register_operand" "")
807 (match_operand:PSI 1 "immediate_operand" ""))
809 "operands[1] != const0_rtx
810 && operands[1] != constm1_rtx"
811 [(parallel [(set (match_dup 0)
813 (clobber (match_dup 2))])])
815 ;; '*' because it is not used in rtl generation.
816 (define_insn "*reload_inpsi"
817 [(set (match_operand:PSI 0 "register_operand" "=r")
818 (match_operand:PSI 1 "immediate_operand" "i"))
819 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
822 return avr_out_reload_inpsi (operands, operands[2], NULL);
824 [(set_attr "length" "6")
825 (set_attr "adjust_len" "reload_in24")
826 (set_attr "cc" "clobber")])
828 (define_insn "*movpsi"
829 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
830 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
831 "register_operand (operands[0], PSImode)
832 || register_operand (operands[1], PSImode)
833 || const0_rtx == operands[1]"
835 return avr_out_movpsi (insn, operands, NULL);
837 [(set_attr "length" "3,3,8,9,4,10")
838 (set_attr "adjust_len" "mov24")
839 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
841 ;;==========================================================================
842 ;; move double word (32 bit)
844 (define_peephole2 ; *reload_insi
845 [(match_scratch:QI 2 "d")
846 (set (match_operand:ALL4 0 "l_register_operand" "")
847 (match_operand:ALL4 1 "immediate_operand" ""))
849 "operands[1] != CONST0_RTX (<MODE>mode)"
850 [(parallel [(set (match_dup 0)
852 (clobber (match_dup 2))])])
854 ;; '*' because it is not used in rtl generation.
856 ;; "*reload_insq" "*reload_inusq"
857 ;; "*reload_insa" "*reload_inusa"
858 (define_insn "*reload_insi"
859 [(set (match_operand:ALL4 0 "register_operand" "=r")
860 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
861 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
864 return output_reload_insisf (operands, operands[2], NULL);
866 [(set_attr "length" "8")
867 (set_attr "adjust_len" "reload_in32")
868 (set_attr "cc" "clobber")])
872 ;; "*movsq" "*movusq"
873 ;; "*movsa" "*movusa"
874 (define_insn "*mov<mode>"
875 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
876 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
877 "register_operand (operands[0], <MODE>mode)
878 || reg_or_0_operand (operands[1], <MODE>mode)"
880 return output_movsisf (insn, operands, NULL);
882 [(set_attr "length" "4,4,8,9,4,10")
883 (set_attr "adjust_len" "mov32")
884 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
886 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
887 ;; move floating point numbers (32 bit)
889 (define_insn "*movsf"
890 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
891 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
892 "register_operand (operands[0], SFmode)
893 || reg_or_0_operand (operands[1], SFmode)"
895 return output_movsisf (insn, operands, NULL);
897 [(set_attr "length" "4,4,8,9,4,10")
898 (set_attr "adjust_len" "mov32")
899 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
901 (define_peephole2 ; *reload_insf
902 [(match_scratch:QI 2 "d")
903 (set (match_operand:SF 0 "l_register_operand" "")
904 (match_operand:SF 1 "const_double_operand" ""))
906 "operands[1] != CONST0_RTX (SFmode)"
907 [(parallel [(set (match_dup 0)
909 (clobber (match_dup 2))])])
911 ;; '*' because it is not used in rtl generation.
912 (define_insn "*reload_insf"
913 [(set (match_operand:SF 0 "register_operand" "=r")
914 (match_operand:SF 1 "const_double_operand" "F"))
915 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
918 return output_reload_insisf (operands, operands[2], NULL);
920 [(set_attr "length" "8")
921 (set_attr "adjust_len" "reload_in32")
922 (set_attr "cc" "clobber")])
924 ;;=========================================================================
925 ;; move string (like memcpy)
927 (define_expand "movmemhi"
928 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
929 (match_operand:BLK 1 "memory_operand" ""))
930 (use (match_operand:HI 2 "const_int_operand" ""))
931 (use (match_operand:HI 3 "const_int_operand" ""))])]
934 if (avr_emit_movmemhi (operands))
940 (define_mode_attr MOVMEM_r_d [(QI "r")
943 ;; $0 : Address Space
944 ;; $1, $2 : Loop register
945 ;; R30 : source address
946 ;; R26 : destination address
950 (define_insn "movmem_<mode>"
951 [(set (mem:BLK (reg:HI REG_X))
952 (mem:BLK (reg:HI REG_Z)))
953 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
955 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
956 (clobber (reg:HI REG_X))
957 (clobber (reg:HI REG_Z))
958 (clobber (reg:QI LPM_REGNO))
959 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
962 return avr_out_movmem (insn, operands, NULL);
964 [(set_attr "adjust_len" "movmem")
965 (set_attr "cc" "clobber")])
968 ;; $0 : Address Space
969 ;; $1 : RAMPZ RAM address
970 ;; R24 : #bytes and loop register
971 ;; R23:Z : 24-bit source address
972 ;; R26 : 16-bit destination address
976 (define_insn "movmemx_<mode>"
977 [(set (mem:BLK (reg:HI REG_X))
978 (mem:BLK (lo_sum:PSI (reg:QI 23)
980 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
983 (clobber (reg:HI REG_X))
984 (clobber (reg:HI REG_Z))
985 (clobber (reg:QI LPM_REGNO))
986 (clobber (reg:HI 24))
987 (clobber (reg:QI 23))
988 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
990 "%~call __movmemx_<mode>"
991 [(set_attr "type" "xcall")
992 (set_attr "cc" "clobber")])
995 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
996 ;; memset (%0, %2, %1)
998 (define_expand "setmemhi"
999 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
1000 (match_operand 2 "const_int_operand" ""))
1001 (use (match_operand:HI 1 "const_int_operand" ""))
1002 (use (match_operand:HI 3 "const_int_operand" ""))
1003 (clobber (match_scratch:HI 4 ""))
1004 (clobber (match_dup 5))])]
1008 enum machine_mode mode;
1010 /* If value to set is not zero, use the library routine. */
1011 if (operands[2] != const0_rtx)
1014 if (!CONST_INT_P (operands[1]))
1017 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1018 operands[5] = gen_rtx_SCRATCH (mode);
1019 operands[1] = copy_to_mode_reg (mode,
1020 gen_int_mode (INTVAL (operands[1]), mode));
1021 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1022 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1026 (define_insn "*clrmemqi"
1027 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1029 (use (match_operand:QI 1 "register_operand" "r"))
1030 (use (match_operand:QI 2 "const_int_operand" "n"))
1031 (clobber (match_scratch:HI 3 "=0"))
1032 (clobber (match_scratch:QI 4 "=&1"))]
1034 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1035 [(set_attr "length" "3")
1036 (set_attr "cc" "clobber")])
1039 (define_insn "*clrmemhi"
1040 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1042 (use (match_operand:HI 1 "register_operand" "!w,d"))
1043 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1044 (clobber (match_scratch:HI 3 "=0,0"))
1045 (clobber (match_scratch:HI 4 "=&1,&1"))]
1048 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1049 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1050 [(set_attr "length" "3,4")
1051 (set_attr "cc" "clobber,clobber")])
1053 (define_expand "strlenhi"
1055 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1056 (match_operand:QI 2 "const_int_operand" "")
1057 (match_operand:HI 3 "immediate_operand" "")]
1060 (plus:HI (match_dup 4)
1062 (parallel [(set (match_operand:HI 0 "register_operand" "")
1063 (minus:HI (match_dup 4)
1065 (clobber (scratch:QI))])]
1069 if (operands[2] != const0_rtx)
1071 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1072 operands[1] = gen_rtx_MEM (BLKmode, addr);
1074 operands[4] = gen_reg_rtx (HImode);
1077 (define_insn "*strlenhi"
1078 [(set (match_operand:HI 0 "register_operand" "=e")
1079 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1081 (match_operand:HI 2 "immediate_operand" "i")]
1084 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1085 [(set_attr "length" "3")
1086 (set_attr "cc" "clobber")])
1088 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1092 ;; "addqq3" "adduqq3"
1093 (define_insn "add<mode>3"
1094 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1095 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1096 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1105 [(set_attr "length" "1,1,1,1,2,2")
1106 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1109 ;; "addhq3" "adduhq3"
1110 ;; "addha3" "adduha3"
1111 (define_expand "add<mode>3"
1112 [(set (match_operand:ALL2 0 "register_operand" "")
1113 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1114 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1117 if (CONST_INT_P (operands[2]))
1119 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1121 if (can_create_pseudo_p()
1122 && !stack_register_operand (operands[0], HImode)
1123 && !stack_register_operand (operands[1], HImode)
1124 && !d_register_operand (operands[0], HImode)
1125 && !d_register_operand (operands[1], HImode))
1127 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1132 if (CONST_FIXED_P (operands[2]))
1134 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1140 (define_insn "*addhi3_zero_extend"
1141 [(set (match_operand:HI 0 "register_operand" "=r")
1142 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1143 (match_operand:HI 2 "register_operand" "0")))]
1145 "add %A0,%1\;adc %B0,__zero_reg__"
1146 [(set_attr "length" "2")
1147 (set_attr "cc" "set_n")])
1149 (define_insn "*addhi3_zero_extend1"
1150 [(set (match_operand:HI 0 "register_operand" "=r")
1151 (plus:HI (match_operand:HI 1 "register_operand" "0")
1152 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1154 "add %A0,%2\;adc %B0,__zero_reg__"
1155 [(set_attr "length" "2")
1156 (set_attr "cc" "set_n")])
1158 (define_insn "*addhi3.sign_extend1"
1159 [(set (match_operand:HI 0 "register_operand" "=r")
1160 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1161 (match_operand:HI 2 "register_operand" "0")))]
1164 return reg_overlap_mentioned_p (operands[0], operands[1])
1165 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1166 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1168 [(set_attr "length" "5")
1169 (set_attr "cc" "clobber")])
1171 (define_insn "*addhi3_sp"
1172 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1173 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1174 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1177 return avr_out_addto_sp (operands, NULL);
1179 [(set_attr "length" "6")
1180 (set_attr "adjust_len" "addto_sp")])
1183 ;; "*addhq3" "*adduhq3"
1184 ;; "*addha3" "*adduha3"
1185 (define_insn "*add<mode>3"
1186 [(set (match_operand:ALL2 0 "register_operand" "=?r,d,!w ,d")
1187 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1188 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1191 return avr_out_plus (insn, operands);
1193 [(set_attr "length" "2")
1194 (set_attr "adjust_len" "plus")
1195 (set_attr "cc" "plus")])
1197 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1198 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1199 ;; itself because that insn is special to reload.
1201 (define_peephole2 ; addhi3_clobber
1202 [(set (match_operand:ALL2 0 "d_register_operand" "")
1203 (match_operand:ALL2 1 "const_operand" ""))
1204 (set (match_operand:ALL2 2 "l_register_operand" "")
1205 (plus:ALL2 (match_dup 2)
1207 "peep2_reg_dead_p (2, operands[0])"
1208 [(parallel [(set (match_dup 2)
1209 (plus:ALL2 (match_dup 2)
1211 (clobber (match_dup 3))])]
1213 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1216 ;; Same, but with reload to NO_LD_REGS
1217 ;; Combine *reload_inhi with *addhi3
1219 (define_peephole2 ; addhi3_clobber
1220 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1221 (match_operand:ALL2 1 "const_operand" ""))
1222 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1223 (set (match_operand:ALL2 3 "l_register_operand" "")
1224 (plus:ALL2 (match_dup 3)
1226 "peep2_reg_dead_p (2, operands[0])"
1227 [(parallel [(set (match_dup 3)
1228 (plus:ALL2 (match_dup 3)
1230 (clobber (match_dup 2))])])
1233 ;; "addhq3_clobber" "adduhq3_clobber"
1234 ;; "addha3_clobber" "adduha3_clobber"
1235 (define_insn "add<mode>3_clobber"
1236 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1237 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1238 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1239 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1242 return avr_out_plus (insn, operands);
1244 [(set_attr "length" "4")
1245 (set_attr "adjust_len" "plus")
1246 (set_attr "cc" "plus")])
1250 ;; "addsq3" "addusq3"
1251 ;; "addsa3" "addusa3"
1252 (define_insn "add<mode>3"
1253 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1254 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1255 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1256 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1259 return avr_out_plus (insn, operands);
1261 [(set_attr "length" "4")
1262 (set_attr "adjust_len" "plus")
1263 (set_attr "cc" "plus")])
1265 (define_insn "*addpsi3_zero_extend.qi"
1266 [(set (match_operand:PSI 0 "register_operand" "=r")
1267 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1268 (match_operand:PSI 2 "register_operand" "0")))]
1270 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1271 [(set_attr "length" "3")
1272 (set_attr "cc" "set_n")])
1274 (define_insn "*addpsi3_zero_extend.hi"
1275 [(set (match_operand:PSI 0 "register_operand" "=r")
1276 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1277 (match_operand:PSI 2 "register_operand" "0")))]
1279 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1280 [(set_attr "length" "3")
1281 (set_attr "cc" "set_n")])
1283 (define_insn "*addpsi3_sign_extend.hi"
1284 [(set (match_operand:PSI 0 "register_operand" "=r")
1285 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1286 (match_operand:PSI 2 "register_operand" "0")))]
1288 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1289 [(set_attr "length" "5")
1290 (set_attr "cc" "set_n")])
1292 (define_insn "*addsi3_zero_extend"
1293 [(set (match_operand:SI 0 "register_operand" "=r")
1294 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1295 (match_operand:SI 2 "register_operand" "0")))]
1297 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1298 [(set_attr "length" "4")
1299 (set_attr "cc" "set_n")])
1301 (define_insn "*addsi3_zero_extend.hi"
1302 [(set (match_operand:SI 0 "register_operand" "=r")
1303 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1304 (match_operand:SI 2 "register_operand" "0")))]
1306 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1307 [(set_attr "length" "4")
1308 (set_attr "cc" "set_n")])
1310 (define_insn "addpsi3"
1311 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1312 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1313 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1314 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1317 return avr_out_plus (insn, operands);
1319 [(set_attr "length" "3")
1320 (set_attr "adjust_len" "plus")
1321 (set_attr "cc" "plus")])
1323 (define_insn "subpsi3"
1324 [(set (match_operand:PSI 0 "register_operand" "=r")
1325 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1326 (match_operand:PSI 2 "register_operand" "r")))]
1328 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1329 [(set_attr "length" "3")
1330 (set_attr "cc" "set_czn")])
1332 (define_insn "*subpsi3_zero_extend.qi"
1333 [(set (match_operand:PSI 0 "register_operand" "=r")
1334 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1335 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1337 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1338 [(set_attr "length" "3")
1339 (set_attr "cc" "set_czn")])
1341 (define_insn "*subpsi3_zero_extend.hi"
1342 [(set (match_operand:PSI 0 "register_operand" "=r")
1343 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1344 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1346 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1347 [(set_attr "length" "3")
1348 (set_attr "cc" "set_czn")])
1350 (define_insn "*subpsi3_sign_extend.hi"
1351 [(set (match_operand:PSI 0 "register_operand" "=r")
1352 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1353 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1355 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1356 [(set_attr "length" "5")
1357 (set_attr "cc" "set_czn")])
1359 ;-----------------------------------------------------------------------------
1363 ;; "subqq3" "subuqq3"
1364 (define_insn "sub<mode>3"
1365 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1366 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1367 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1376 [(set_attr "length" "1,1,1,1,2,2")
1377 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1380 ;; "subhq3" "subuhq3"
1381 ;; "subha3" "subuha3"
1382 (define_insn "sub<mode>3"
1383 [(set (match_operand:ALL2 0 "register_operand" "=r,d ,*r")
1384 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1385 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1386 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1389 return avr_out_plus (insn, operands);
1391 [(set_attr "adjust_len" "plus")
1392 (set_attr "cc" "plus")])
1394 (define_insn "*subhi3_zero_extend1"
1395 [(set (match_operand:HI 0 "register_operand" "=r")
1396 (minus:HI (match_operand:HI 1 "register_operand" "0")
1397 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1399 "sub %A0,%2\;sbc %B0,__zero_reg__"
1400 [(set_attr "length" "2")
1401 (set_attr "cc" "set_czn")])
1403 (define_insn "*subhi3.sign_extend2"
1404 [(set (match_operand:HI 0 "register_operand" "=r")
1405 (minus:HI (match_operand:HI 1 "register_operand" "0")
1406 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1409 return reg_overlap_mentioned_p (operands[0], operands[2])
1410 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1411 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1413 [(set_attr "length" "5")
1414 (set_attr "cc" "clobber")])
1417 ;; "subsq3" "subusq3"
1418 ;; "subsa3" "subusa3"
1419 (define_insn "sub<mode>3"
1420 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1421 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1422 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1423 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1426 return avr_out_plus (insn, operands);
1428 [(set_attr "adjust_len" "plus")
1429 (set_attr "cc" "plus")])
1431 (define_insn "*subsi3_zero_extend"
1432 [(set (match_operand:SI 0 "register_operand" "=r")
1433 (minus:SI (match_operand:SI 1 "register_operand" "0")
1434 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1436 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1437 [(set_attr "length" "4")
1438 (set_attr "cc" "set_czn")])
1440 (define_insn "*subsi3_zero_extend.hi"
1441 [(set (match_operand:SI 0 "register_operand" "=r")
1442 (minus:SI (match_operand:SI 1 "register_operand" "0")
1443 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1445 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1446 [(set_attr "length" "4")
1447 (set_attr "cc" "set_czn")])
1449 ;******************************************************************************
1452 (define_expand "mulqi3"
1453 [(set (match_operand:QI 0 "register_operand" "")
1454 (mult:QI (match_operand:QI 1 "register_operand" "")
1455 (match_operand:QI 2 "register_operand" "")))]
1460 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1465 (define_insn "*mulqi3_enh"
1466 [(set (match_operand:QI 0 "register_operand" "=r")
1467 (mult:QI (match_operand:QI 1 "register_operand" "r")
1468 (match_operand:QI 2 "register_operand" "r")))]
1473 [(set_attr "length" "3")
1474 (set_attr "cc" "clobber")])
1476 (define_expand "mulqi3_call"
1477 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1478 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1479 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1480 (clobber (reg:QI 22))])
1481 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1483 (define_insn "*mulqi3_call"
1484 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1485 (clobber (reg:QI 22))]
1488 [(set_attr "type" "xcall")
1489 (set_attr "cc" "clobber")])
1491 ;; "umulqi3_highpart"
1492 ;; "smulqi3_highpart"
1493 (define_insn "<extend_su>mulqi3_highpart"
1494 [(set (match_operand:QI 0 "register_operand" "=r")
1496 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1497 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1500 "mul<extend_s> %1,%2
1503 [(set_attr "length" "3")
1504 (set_attr "cc" "clobber")])
1507 ;; Used when expanding div or mod inline for some special values
1508 (define_insn "*subqi3.ashiftrt7"
1509 [(set (match_operand:QI 0 "register_operand" "=r")
1510 (minus:QI (match_operand:QI 1 "register_operand" "0")
1511 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1515 [(set_attr "length" "2")
1516 (set_attr "cc" "clobber")])
1518 (define_insn "*addqi3.lt0"
1519 [(set (match_operand:QI 0 "register_operand" "=r")
1520 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1522 (match_operand:QI 2 "register_operand" "0")))]
1525 [(set_attr "length" "2")
1526 (set_attr "cc" "clobber")])
1528 (define_insn "*addhi3.lt0"
1529 [(set (match_operand:HI 0 "register_operand" "=w,r")
1530 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1532 (match_operand:HI 2 "register_operand" "0,0")))
1533 (clobber (match_scratch:QI 3 "=X,&1"))]
1536 sbrc %1,7\;adiw %0,1
1537 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1538 [(set_attr "length" "2,3")
1539 (set_attr "cc" "clobber")])
1541 (define_insn "*addpsi3.lt0"
1542 [(set (match_operand:PSI 0 "register_operand" "=r")
1543 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1545 (match_operand:PSI 2 "register_operand" "0")))]
1547 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1548 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1549 [(set_attr "length" "5")
1550 (set_attr "cc" "clobber")])
1552 (define_insn "*addsi3.lt0"
1553 [(set (match_operand:SI 0 "register_operand" "=r")
1554 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1556 (match_operand:SI 2 "register_operand" "0")))]
1558 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1559 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1560 [(set_attr "length" "6")
1561 (set_attr "cc" "clobber")])
1563 (define_insn "*umulqihi3.call"
1565 (mult:HI (zero_extend:HI (reg:QI 22))
1566 (zero_extend:HI (reg:QI 24))))
1567 (clobber (reg:QI 21))
1568 (clobber (reg:HI 22))]
1570 "%~call __umulqihi3"
1571 [(set_attr "type" "xcall")
1572 (set_attr "cc" "clobber")])
1576 (define_insn "<extend_u>mulqihi3"
1577 [(set (match_operand:HI 0 "register_operand" "=r")
1578 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1579 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1581 "mul<extend_s> %1,%2
1584 [(set_attr "length" "3")
1585 (set_attr "cc" "clobber")])
1587 (define_insn "usmulqihi3"
1588 [(set (match_operand:HI 0 "register_operand" "=r")
1589 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1590 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1595 [(set_attr "length" "3")
1596 (set_attr "cc" "clobber")])
1598 ;; Above insn is not canonicalized by insn combine, so here is a version with
1599 ;; operands swapped.
1601 (define_insn "*sumulqihi3"
1602 [(set (match_operand:HI 0 "register_operand" "=r")
1603 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1604 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1609 [(set_attr "length" "3")
1610 (set_attr "cc" "clobber")])
1612 ;; One-extend operand 1
1614 (define_insn "*osmulqihi3"
1615 [(set (match_operand:HI 0 "register_operand" "=&r")
1616 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1617 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1623 [(set_attr "length" "4")
1624 (set_attr "cc" "clobber")])
1626 (define_insn "*oumulqihi3"
1627 [(set (match_operand:HI 0 "register_operand" "=&r")
1628 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1629 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1635 [(set_attr "length" "4")
1636 (set_attr "cc" "clobber")])
1638 ;******************************************************************************
1639 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1640 ;******************************************************************************
1642 (define_insn "*maddqi4"
1643 [(set (match_operand:QI 0 "register_operand" "=r")
1644 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1645 (match_operand:QI 2 "register_operand" "r"))
1646 (match_operand:QI 3 "register_operand" "0")))]
1652 [(set_attr "length" "4")
1653 (set_attr "cc" "clobber")])
1655 (define_insn "*msubqi4"
1656 [(set (match_operand:QI 0 "register_operand" "=r")
1657 (minus:QI (match_operand:QI 3 "register_operand" "0")
1658 (mult:QI (match_operand:QI 1 "register_operand" "r")
1659 (match_operand:QI 2 "register_operand" "r"))))]
1664 [(set_attr "length" "4")
1665 (set_attr "cc" "clobber")])
1667 (define_insn_and_split "*maddqi4.const"
1668 [(set (match_operand:QI 0 "register_operand" "=r")
1669 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1670 (match_operand:QI 2 "const_int_operand" "n"))
1671 (match_operand:QI 3 "register_operand" "0")))
1672 (clobber (match_scratch:QI 4 "=&d"))]
1675 "&& reload_completed"
1680 (plus:QI (mult:QI (match_dup 1)
1684 (define_insn_and_split "*msubqi4.const"
1685 [(set (match_operand:QI 0 "register_operand" "=r")
1686 (minus:QI (match_operand:QI 3 "register_operand" "0")
1687 (mult:QI (match_operand:QI 1 "register_operand" "r")
1688 (match_operand:QI 2 "const_int_operand" "n"))))
1689 (clobber (match_scratch:QI 4 "=&d"))]
1692 "&& reload_completed"
1697 (minus:QI (match_dup 3)
1698 (mult:QI (match_dup 1)
1702 ;******************************************************************************
1703 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1704 ;******************************************************************************
1706 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1709 ;; int foo (unsigned char z)
1711 ;; extern int aInt[];
1712 ;; return aInt[3*z+2];
1715 ;; because the constant +4 then is added explicitely instead of consuming it
1716 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1717 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1718 ;; The implementational effort is the same so we are fine with that approach.
1723 (define_insn "*<extend_u>maddqihi4"
1724 [(set (match_operand:HI 0 "register_operand" "=r")
1725 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1726 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1727 (match_operand:HI 3 "register_operand" "0")))]
1730 "mul<extend_s> %1,%2
1734 [(set_attr "length" "4")
1735 (set_attr "cc" "clobber")])
1739 (define_insn "*<extend_u>msubqihi4"
1740 [(set (match_operand:HI 0 "register_operand" "=r")
1741 (minus:HI (match_operand:HI 3 "register_operand" "0")
1742 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1743 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1745 "mul<extend_s> %1,%2
1749 [(set_attr "length" "4")
1750 (set_attr "cc" "clobber")])
1754 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1755 [(set (match_operand:HI 0 "register_operand" "=r")
1756 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1757 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1758 (match_operand:HI 3 "register_operand" "0")))]
1761 && <any_extend:CODE> != <any_extend2:CODE>"
1763 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1764 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1766 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1768 [(set_attr "length" "4")
1769 (set_attr "cc" "clobber")])
1773 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1774 [(set (match_operand:HI 0 "register_operand" "=r")
1775 (minus:HI (match_operand:HI 3 "register_operand" "0")
1776 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1777 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1780 && <any_extend:CODE> != <any_extend2:CODE>"
1782 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1783 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1785 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1787 [(set_attr "length" "4")
1788 (set_attr "cc" "clobber")])
1790 ;; Handle small constants
1792 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1793 ;; This is shorter, faster than MUL and has lower register pressure.
1795 (define_insn_and_split "*umaddqihi4.2"
1796 [(set (match_operand:HI 0 "register_operand" "=r")
1797 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1799 (match_operand:HI 2 "register_operand" "r")))]
1801 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1802 { gcc_unreachable(); }
1806 ; *addhi3_zero_extend
1808 (plus:HI (zero_extend:HI (match_dup 1))
1810 ; *addhi3_zero_extend
1812 (plus:HI (zero_extend:HI (match_dup 1))
1815 ;; "umaddqihi4.uconst"
1816 ;; "maddqihi4.sconst"
1817 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1818 [(set (match_operand:HI 0 "register_operand" "=r")
1819 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1820 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1821 (match_operand:HI 3 "register_operand" "0")))
1822 (clobber (match_scratch:QI 4 "=&d"))]
1825 "&& reload_completed"
1828 ; *umaddqihi4 resp. *maddqihi4
1830 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1831 (any_extend:HI (match_dup 4)))
1834 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1837 ;; "*umsubqihi4.uconst"
1838 ;; "*msubqihi4.sconst"
1839 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1840 [(set (match_operand:HI 0 "register_operand" "=r")
1841 (minus:HI (match_operand:HI 3 "register_operand" "0")
1842 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1843 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1844 (clobber (match_scratch:QI 4 "=&d"))]
1847 "&& reload_completed"
1850 ; *umsubqihi4 resp. *msubqihi4
1852 (minus:HI (match_dup 3)
1853 (mult:HI (any_extend:HI (match_dup 1))
1854 (any_extend:HI (match_dup 4)))))]
1856 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1859 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1860 ;; for MULT with power of 2 and skips trying MULT insn above.
1862 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1863 [(set (match_operand:HI 0 "register_operand" "=r")
1864 (minus:HI (match_operand:HI 3 "register_operand" "0")
1865 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1866 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1867 (clobber (match_scratch:QI 4 "=&d"))]
1870 "&& reload_completed"
1875 (minus:HI (match_dup 3)
1876 (mult:HI (zero_extend:HI (match_dup 1))
1877 (zero_extend:HI (match_dup 4)))))]
1879 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1882 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1883 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1884 ;; because this would require an extra pattern for just one value.
1886 (define_insn_and_split "*msubqihi4.sconst.ashift"
1887 [(set (match_operand:HI 0 "register_operand" "=r")
1888 (minus:HI (match_operand:HI 3 "register_operand" "0")
1889 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1890 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1891 (clobber (match_scratch:QI 4 "=&d"))]
1894 "&& reload_completed"
1899 (minus:HI (match_dup 3)
1900 (mult:HI (sign_extend:HI (match_dup 1))
1901 (sign_extend:HI (match_dup 4)))))]
1903 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1906 ;; For signed/unsigned combinations that require narrow constraint "a"
1907 ;; just provide a pattern if signed/unsigned combination is actually needed.
1909 (define_insn_and_split "*sumaddqihi4.uconst"
1910 [(set (match_operand:HI 0 "register_operand" "=r")
1911 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1912 (match_operand:HI 2 "u8_operand" "M"))
1913 (match_operand:HI 3 "register_operand" "0")))
1914 (clobber (match_scratch:QI 4 "=&a"))]
1916 && !s8_operand (operands[2], VOIDmode)"
1918 "&& reload_completed"
1923 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1924 (zero_extend:HI (match_dup 4)))
1927 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1930 (define_insn_and_split "*sumsubqihi4.uconst"
1931 [(set (match_operand:HI 0 "register_operand" "=r")
1932 (minus:HI (match_operand:HI 3 "register_operand" "0")
1933 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1934 (match_operand:HI 2 "u8_operand" "M"))))
1935 (clobber (match_scratch:QI 4 "=&a"))]
1937 && !s8_operand (operands[2], VOIDmode)"
1939 "&& reload_completed"
1944 (minus:HI (match_dup 3)
1945 (mult:HI (sign_extend:HI (match_dup 1))
1946 (zero_extend:HI (match_dup 4)))))]
1948 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1951 ;******************************************************************************
1952 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1953 ;******************************************************************************
1955 ;; "*muluqihi3.uconst"
1956 ;; "*mulsqihi3.sconst"
1957 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1958 [(set (match_operand:HI 0 "register_operand" "=r")
1959 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1960 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1961 (clobber (match_scratch:QI 3 "=&d"))]
1964 "&& reload_completed"
1967 ; umulqihi3 resp. mulqihi3
1969 (mult:HI (any_extend:HI (match_dup 1))
1970 (any_extend:HI (match_dup 3))))]
1972 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1975 (define_insn_and_split "*muluqihi3.sconst"
1976 [(set (match_operand:HI 0 "register_operand" "=r")
1977 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1978 (match_operand:HI 2 "s8_operand" "n")))
1979 (clobber (match_scratch:QI 3 "=&a"))]
1982 "&& reload_completed"
1987 (mult:HI (zero_extend:HI (match_dup 1))
1988 (sign_extend:HI (match_dup 3))))]
1990 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1993 (define_insn_and_split "*mulsqihi3.uconst"
1994 [(set (match_operand:HI 0 "register_operand" "=r")
1995 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1996 (match_operand:HI 2 "u8_operand" "M")))
1997 (clobber (match_scratch:QI 3 "=&a"))]
2000 "&& reload_completed"
2005 (mult:HI (zero_extend:HI (match_dup 3))
2006 (sign_extend:HI (match_dup 1))))]
2008 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2011 (define_insn_and_split "*mulsqihi3.oconst"
2012 [(set (match_operand:HI 0 "register_operand" "=&r")
2013 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2014 (match_operand:HI 2 "o8_operand" "n")))
2015 (clobber (match_scratch:QI 3 "=&a"))]
2018 "&& reload_completed"
2023 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2024 (sign_extend:HI (match_dup 1))))]
2026 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2029 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2030 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2031 ;; at that time. Fix that.
2033 (define_insn "*ashiftqihi2.signx.1"
2034 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2035 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2039 lsl %A0\;sbc %B0,%B0
2040 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2041 [(set_attr "length" "2,3")
2042 (set_attr "cc" "clobber")])
2044 (define_insn_and_split "*ashifthi3.signx.const"
2045 [(set (match_operand:HI 0 "register_operand" "=r")
2046 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2047 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2048 (clobber (match_scratch:QI 3 "=&d"))]
2051 "&& reload_completed"
2056 (mult:HI (sign_extend:HI (match_dup 1))
2057 (sign_extend:HI (match_dup 3))))]
2059 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2062 (define_insn_and_split "*ashifthi3.signx.const7"
2063 [(set (match_operand:HI 0 "register_operand" "=r")
2064 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2066 (clobber (match_scratch:QI 2 "=&a"))]
2069 "&& reload_completed"
2074 (mult:HI (zero_extend:HI (match_dup 2))
2075 (sign_extend:HI (match_dup 1))))]
2077 operands[3] = gen_int_mode (1 << 7, QImode);
2080 (define_insn_and_split "*ashifthi3.zerox.const"
2081 [(set (match_operand:HI 0 "register_operand" "=r")
2082 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2083 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2084 (clobber (match_scratch:QI 3 "=&d"))]
2087 "&& reload_completed"
2092 (mult:HI (zero_extend:HI (match_dup 1))
2093 (zero_extend:HI (match_dup 3))))]
2095 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2098 ;******************************************************************************
2099 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2100 ;******************************************************************************
2102 (define_insn "mulsqihi3"
2103 [(set (match_operand:HI 0 "register_operand" "=&r")
2104 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2105 (match_operand:HI 2 "register_operand" "a")))]
2112 [(set_attr "length" "5")
2113 (set_attr "cc" "clobber")])
2115 (define_insn "muluqihi3"
2116 [(set (match_operand:HI 0 "register_operand" "=&r")
2117 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2118 (match_operand:HI 2 "register_operand" "r")))]
2125 [(set_attr "length" "5")
2126 (set_attr "cc" "clobber")])
2128 ;; one-extend operand 1
2130 (define_insn "muloqihi3"
2131 [(set (match_operand:HI 0 "register_operand" "=&r")
2132 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2133 (match_operand:HI 2 "register_operand" "r")))]
2141 [(set_attr "length" "6")
2142 (set_attr "cc" "clobber")])
2144 ;******************************************************************************
2146 (define_expand "mulhi3"
2147 [(set (match_operand:HI 0 "register_operand" "")
2148 (mult:HI (match_operand:HI 1 "register_operand" "")
2149 (match_operand:HI 2 "register_or_s9_operand" "")))]
2154 if (!register_operand (operands[2], HImode))
2155 operands[2] = force_reg (HImode, operands[2]);
2157 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2161 /* For small constants we can do better by extending them on the fly.
2162 The constant can be loaded in one instruction and the widening
2163 multiplication is shorter. First try the unsigned variant because it
2164 allows constraint "d" instead of "a" for the signed version. */
2166 if (s9_operand (operands[2], HImode))
2168 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2170 if (u8_operand (operands[2], HImode))
2172 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2174 else if (s8_operand (operands[2], HImode))
2176 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2180 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2186 if (!register_operand (operands[2], HImode))
2187 operands[2] = force_reg (HImode, operands[2]);
2190 (define_insn "*mulhi3_enh"
2191 [(set (match_operand:HI 0 "register_operand" "=&r")
2192 (mult:HI (match_operand:HI 1 "register_operand" "r")
2193 (match_operand:HI 2 "register_operand" "r")))]
2196 return REGNO (operands[1]) == REGNO (operands[2])
2197 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2198 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2200 [(set_attr "length" "7")
2201 (set_attr "cc" "clobber")])
2203 (define_expand "mulhi3_call"
2204 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2205 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2206 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2207 (clobber (reg:HI 22))
2208 (clobber (reg:QI 21))])
2209 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2211 (define_insn "*mulhi3_call"
2212 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2213 (clobber (reg:HI 22))
2214 (clobber (reg:QI 21))]
2217 [(set_attr "type" "xcall")
2218 (set_attr "cc" "clobber")])
2220 ;; To support widening multiplication with constant we postpone
2221 ;; expanding to the implicit library call until post combine and
2222 ;; prior to register allocation. Clobber all hard registers that
2223 ;; might be used by the (widening) multiply until it is split and
2224 ;; it's final register footprint is worked out.
2226 (define_expand "mulsi3"
2227 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2228 (mult:SI (match_operand:SI 1 "register_operand" "")
2229 (match_operand:SI 2 "nonmemory_operand" "")))
2230 (clobber (reg:HI 26))
2231 (clobber (reg:DI 18))])]
2234 if (u16_operand (operands[2], SImode))
2236 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2237 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2241 if (o16_operand (operands[2], SImode))
2243 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2244 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2249 (define_insn_and_split "*mulsi3"
2250 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2251 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2252 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2253 (clobber (reg:HI 26))
2254 (clobber (reg:DI 18))]
2255 "AVR_HAVE_MUL && !reload_completed"
2256 { gcc_unreachable(); }
2262 (parallel [(set (reg:SI 22)
2263 (mult:SI (reg:SI 22)
2265 (clobber (reg:HI 26))])
2269 if (u16_operand (operands[2], SImode))
2271 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2272 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2276 if (o16_operand (operands[2], SImode))
2278 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2279 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2286 (define_insn_and_split "mulu<mode>si3"
2287 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2288 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2289 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2290 (clobber (reg:HI 26))
2291 (clobber (reg:DI 18))]
2292 "AVR_HAVE_MUL && !reload_completed"
2293 { gcc_unreachable(); }
2300 (mult:SI (zero_extend:SI (reg:HI 26))
2305 /* Do the QI -> HI extension explicitely before the multiplication. */
2306 /* Do the HI -> SI extension implicitely and after the multiplication. */
2308 if (QImode == <MODE>mode)
2309 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2311 if (u16_operand (operands[2], SImode))
2313 operands[1] = force_reg (HImode, operands[1]);
2314 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2315 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2322 (define_insn_and_split "muls<mode>si3"
2323 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2324 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2325 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2326 (clobber (reg:HI 26))
2327 (clobber (reg:DI 18))]
2328 "AVR_HAVE_MUL && !reload_completed"
2329 { gcc_unreachable(); }
2336 (mult:SI (sign_extend:SI (reg:HI 26))
2341 /* Do the QI -> HI extension explicitely before the multiplication. */
2342 /* Do the HI -> SI extension implicitely and after the multiplication. */
2344 if (QImode == <MODE>mode)
2345 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2347 if (u16_operand (operands[2], SImode)
2348 || s16_operand (operands[2], SImode))
2350 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2352 operands[1] = force_reg (HImode, operands[1]);
2354 if (u16_operand (operands[2], SImode))
2355 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2357 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2363 ;; One-extend operand 1
2365 (define_insn_and_split "mulohisi3"
2366 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2367 (mult:SI (not:SI (zero_extend:SI
2368 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2369 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2370 (clobber (reg:HI 26))
2371 (clobber (reg:DI 18))]
2372 "AVR_HAVE_MUL && !reload_completed"
2373 { gcc_unreachable(); }
2380 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2387 (define_expand "<extend_u>mulhisi3"
2388 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2389 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2390 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2391 (clobber (reg:HI 26))
2392 (clobber (reg:DI 18))])]
2395 (define_expand "usmulhisi3"
2396 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2397 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2398 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2399 (clobber (reg:HI 26))
2400 (clobber (reg:DI 18))])]
2403 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2404 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2405 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2406 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2407 (define_insn_and_split
2408 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2409 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2410 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2411 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2412 (clobber (reg:HI 26))
2413 (clobber (reg:DI 18))]
2414 "AVR_HAVE_MUL && !reload_completed"
2415 { gcc_unreachable(); }
2422 (mult:SI (match_dup 3)
2427 rtx xop1 = operands[1];
2428 rtx xop2 = operands[2];
2430 /* Do the QI -> HI extension explicitely before the multiplication. */
2431 /* Do the HI -> SI extension implicitely and after the multiplication. */
2433 if (QImode == <QIHI:MODE>mode)
2434 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2436 if (QImode == <QIHI2:MODE>mode)
2437 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2439 if (<any_extend:CODE> == <any_extend2:CODE>
2440 || <any_extend:CODE> == ZERO_EXTEND)
2444 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2445 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2449 /* <any_extend:CODE> = SIGN_EXTEND */
2450 /* <any_extend2:CODE> = ZERO_EXTEND */
2454 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2455 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2459 ;; "smulhi3_highpart"
2460 ;; "umulhi3_highpart"
2461 (define_expand "<extend_su>mulhi3_highpart"
2463 (match_operand:HI 1 "nonmemory_operand" ""))
2465 (match_operand:HI 2 "nonmemory_operand" ""))
2466 (parallel [(set (reg:HI 24)
2467 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2468 (any_extend:SI (reg:HI 26)))
2470 (clobber (reg:HI 22))])
2471 (set (match_operand:HI 0 "register_operand" "")
2476 (define_insn "*mulsi3_call"
2478 (mult:SI (reg:SI 22)
2480 (clobber (reg:HI 26))]
2483 [(set_attr "type" "xcall")
2484 (set_attr "cc" "clobber")])
2487 ;; "*umulhisi3_call"
2488 (define_insn "*<extend_u>mulhisi3_call"
2490 (mult:SI (any_extend:SI (reg:HI 18))
2491 (any_extend:SI (reg:HI 26))))]
2493 "%~call __<extend_u>mulhisi3"
2494 [(set_attr "type" "xcall")
2495 (set_attr "cc" "clobber")])
2497 ;; "*umulhi3_highpart_call"
2498 ;; "*smulhi3_highpart_call"
2499 (define_insn "*<extend_su>mulhi3_highpart_call"
2501 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2502 (any_extend:SI (reg:HI 26)))
2504 (clobber (reg:HI 22))]
2506 "%~call __<extend_u>mulhisi3"
2507 [(set_attr "type" "xcall")
2508 (set_attr "cc" "clobber")])
2510 (define_insn "*usmulhisi3_call"
2512 (mult:SI (zero_extend:SI (reg:HI 18))
2513 (sign_extend:SI (reg:HI 26))))]
2515 "%~call __usmulhisi3"
2516 [(set_attr "type" "xcall")
2517 (set_attr "cc" "clobber")])
2519 (define_insn "*mul<extend_su>hisi3_call"
2521 (mult:SI (any_extend:SI (reg:HI 26))
2524 "%~call __mul<extend_su>hisi3"
2525 [(set_attr "type" "xcall")
2526 (set_attr "cc" "clobber")])
2528 (define_insn "*mulohisi3_call"
2530 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2533 "%~call __mulohisi3"
2534 [(set_attr "type" "xcall")
2535 (set_attr "cc" "clobber")])
2537 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2540 ;; Generate lib1funcs.S calls ourselves, because:
2541 ;; - we know exactly which registers are clobbered (for QI and HI
2542 ;; modes, some of the call-used registers are preserved)
2543 ;; - we get both the quotient and the remainder at no extra cost
2544 ;; - we split the patterns only after the first CSE passes because
2545 ;; CSE has problems to operate on hard regs.
2547 (define_insn_and_split "divmodqi4"
2548 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2549 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2550 (match_operand:QI 2 "pseudo_register_operand" "")))
2551 (set (match_operand:QI 3 "pseudo_register_operand" "")
2552 (mod:QI (match_dup 1) (match_dup 2)))
2553 (clobber (reg:QI 22))
2554 (clobber (reg:QI 23))
2555 (clobber (reg:QI 24))
2556 (clobber (reg:QI 25))])]
2558 "this divmodqi4 pattern should have been splitted;"
2560 [(set (reg:QI 24) (match_dup 1))
2561 (set (reg:QI 22) (match_dup 2))
2562 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2563 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2564 (clobber (reg:QI 22))
2565 (clobber (reg:QI 23))])
2566 (set (match_dup 0) (reg:QI 24))
2567 (set (match_dup 3) (reg:QI 25))])
2569 (define_insn "*divmodqi4_call"
2570 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2571 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2572 (clobber (reg:QI 22))
2573 (clobber (reg:QI 23))]
2575 "%~call __divmodqi4"
2576 [(set_attr "type" "xcall")
2577 (set_attr "cc" "clobber")])
2579 (define_insn_and_split "udivmodqi4"
2580 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2581 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2582 (match_operand:QI 2 "pseudo_register_operand" "")))
2583 (set (match_operand:QI 3 "pseudo_register_operand" "")
2584 (umod:QI (match_dup 1) (match_dup 2)))
2585 (clobber (reg:QI 22))
2586 (clobber (reg:QI 23))
2587 (clobber (reg:QI 24))
2588 (clobber (reg:QI 25))])]
2590 "this udivmodqi4 pattern should have been splitted;"
2592 [(set (reg:QI 24) (match_dup 1))
2593 (set (reg:QI 22) (match_dup 2))
2594 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2595 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2596 (clobber (reg:QI 23))])
2597 (set (match_dup 0) (reg:QI 24))
2598 (set (match_dup 3) (reg:QI 25))])
2600 (define_insn "*udivmodqi4_call"
2601 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2602 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2603 (clobber (reg:QI 23))]
2605 "%~call __udivmodqi4"
2606 [(set_attr "type" "xcall")
2607 (set_attr "cc" "clobber")])
2609 (define_insn_and_split "divmodhi4"
2610 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2611 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2612 (match_operand:HI 2 "pseudo_register_operand" "")))
2613 (set (match_operand:HI 3 "pseudo_register_operand" "")
2614 (mod:HI (match_dup 1) (match_dup 2)))
2615 (clobber (reg:QI 21))
2616 (clobber (reg:HI 22))
2617 (clobber (reg:HI 24))
2618 (clobber (reg:HI 26))])]
2620 "this should have been splitted;"
2622 [(set (reg:HI 24) (match_dup 1))
2623 (set (reg:HI 22) (match_dup 2))
2624 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2625 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2626 (clobber (reg:HI 26))
2627 (clobber (reg:QI 21))])
2628 (set (match_dup 0) (reg:HI 22))
2629 (set (match_dup 3) (reg:HI 24))])
2631 (define_insn "*divmodhi4_call"
2632 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2633 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2634 (clobber (reg:HI 26))
2635 (clobber (reg:QI 21))]
2637 "%~call __divmodhi4"
2638 [(set_attr "type" "xcall")
2639 (set_attr "cc" "clobber")])
2641 (define_insn_and_split "udivmodhi4"
2642 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2643 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2644 (match_operand:HI 2 "pseudo_register_operand" "")))
2645 (set (match_operand:HI 3 "pseudo_register_operand" "")
2646 (umod:HI (match_dup 1) (match_dup 2)))
2647 (clobber (reg:QI 21))
2648 (clobber (reg:HI 22))
2649 (clobber (reg:HI 24))
2650 (clobber (reg:HI 26))])]
2652 "this udivmodhi4 pattern should have been splitted.;"
2654 [(set (reg:HI 24) (match_dup 1))
2655 (set (reg:HI 22) (match_dup 2))
2656 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2657 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2658 (clobber (reg:HI 26))
2659 (clobber (reg:QI 21))])
2660 (set (match_dup 0) (reg:HI 22))
2661 (set (match_dup 3) (reg:HI 24))])
2663 (define_insn "*udivmodhi4_call"
2664 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2665 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2666 (clobber (reg:HI 26))
2667 (clobber (reg:QI 21))]
2669 "%~call __udivmodhi4"
2670 [(set_attr "type" "xcall")
2671 (set_attr "cc" "clobber")])
2673 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2676 ;; To support widening multiplication with constant we postpone
2677 ;; expanding to the implicit library call until post combine and
2678 ;; prior to register allocation. Clobber all hard registers that
2679 ;; might be used by the (widening) multiply until it is split and
2680 ;; it's final register footprint is worked out.
2682 (define_expand "mulpsi3"
2683 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2684 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2685 (match_operand:PSI 2 "nonmemory_operand" "")))
2686 (clobber (reg:HI 26))
2687 (clobber (reg:DI 18))])]
2690 if (s8_operand (operands[2], PSImode))
2692 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2693 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2698 (define_insn "*umulqihipsi3"
2699 [(set (match_operand:PSI 0 "register_operand" "=&r")
2700 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2701 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2710 [(set_attr "length" "7")
2711 (set_attr "cc" "clobber")])
2713 (define_insn "*umulhiqipsi3"
2714 [(set (match_operand:PSI 0 "register_operand" "=&r")
2715 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2716 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2724 adc %C0,__zero_reg__"
2725 [(set_attr "length" "7")
2726 (set_attr "cc" "clobber")])
2728 (define_insn_and_split "mulsqipsi3"
2729 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2730 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2731 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2732 (clobber (reg:HI 26))
2733 (clobber (reg:DI 18))]
2734 "AVR_HAVE_MUL && !reload_completed"
2735 { gcc_unreachable(); }
2742 (mult:PSI (sign_extend:PSI (reg:QI 25))
2747 (define_insn_and_split "*mulpsi3"
2748 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2749 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2750 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2751 (clobber (reg:HI 26))
2752 (clobber (reg:DI 18))]
2753 "AVR_HAVE_MUL && !reload_completed"
2754 { gcc_unreachable(); }
2760 (parallel [(set (reg:PSI 22)
2761 (mult:PSI (reg:PSI 22)
2763 (clobber (reg:QI 21))
2764 (clobber (reg:QI 25))
2765 (clobber (reg:HI 26))])
2769 if (s8_operand (operands[2], PSImode))
2771 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2772 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2777 (define_insn "*mulsqipsi3.libgcc"
2779 (mult:PSI (sign_extend:PSI (reg:QI 25))
2782 "%~call __mulsqipsi3"
2783 [(set_attr "type" "xcall")
2784 (set_attr "cc" "clobber")])
2786 (define_insn "*mulpsi3.libgcc"
2788 (mult:PSI (reg:PSI 22)
2790 (clobber (reg:QI 21))
2791 (clobber (reg:QI 25))
2792 (clobber (reg:HI 26))]
2795 [(set_attr "type" "xcall")
2796 (set_attr "cc" "clobber")])
2799 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2800 ;; 24-bit signed/unsigned division and modulo.
2801 ;; Notice that the libgcc implementation return the quotient in R22
2802 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2803 ;; implementation works the other way round.
2805 (define_insn_and_split "divmodpsi4"
2806 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2807 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2808 (match_operand:PSI 2 "pseudo_register_operand" "")))
2809 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2810 (mod:PSI (match_dup 1)
2812 (clobber (reg:DI 18))
2813 (clobber (reg:QI 26))])]
2815 { gcc_unreachable(); }
2817 [(set (reg:PSI 22) (match_dup 1))
2818 (set (reg:PSI 18) (match_dup 2))
2819 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2820 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2821 (clobber (reg:QI 21))
2822 (clobber (reg:QI 25))
2823 (clobber (reg:QI 26))])
2824 (set (match_dup 0) (reg:PSI 22))
2825 (set (match_dup 3) (reg:PSI 18))])
2827 (define_insn "*divmodpsi4_call"
2828 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2829 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2830 (clobber (reg:QI 21))
2831 (clobber (reg:QI 25))
2832 (clobber (reg:QI 26))]
2834 "%~call __divmodpsi4"
2835 [(set_attr "type" "xcall")
2836 (set_attr "cc" "clobber")])
2838 (define_insn_and_split "udivmodpsi4"
2839 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2840 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2841 (match_operand:PSI 2 "pseudo_register_operand" "")))
2842 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2843 (umod:PSI (match_dup 1)
2845 (clobber (reg:DI 18))
2846 (clobber (reg:QI 26))])]
2848 { gcc_unreachable(); }
2850 [(set (reg:PSI 22) (match_dup 1))
2851 (set (reg:PSI 18) (match_dup 2))
2852 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2853 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2854 (clobber (reg:QI 21))
2855 (clobber (reg:QI 25))
2856 (clobber (reg:QI 26))])
2857 (set (match_dup 0) (reg:PSI 22))
2858 (set (match_dup 3) (reg:PSI 18))])
2860 (define_insn "*udivmodpsi4_call"
2861 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2862 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2863 (clobber (reg:QI 21))
2864 (clobber (reg:QI 25))
2865 (clobber (reg:QI 26))]
2867 "%~call __udivmodpsi4"
2868 [(set_attr "type" "xcall")
2869 (set_attr "cc" "clobber")])
2871 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2873 (define_insn_and_split "divmodsi4"
2874 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2875 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2876 (match_operand:SI 2 "pseudo_register_operand" "")))
2877 (set (match_operand:SI 3 "pseudo_register_operand" "")
2878 (mod:SI (match_dup 1) (match_dup 2)))
2879 (clobber (reg:SI 18))
2880 (clobber (reg:SI 22))
2881 (clobber (reg:HI 26))
2882 (clobber (reg:HI 30))])]
2884 "this divmodsi4 pattern should have been splitted;"
2886 [(set (reg:SI 22) (match_dup 1))
2887 (set (reg:SI 18) (match_dup 2))
2888 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2889 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2890 (clobber (reg:HI 26))
2891 (clobber (reg:HI 30))])
2892 (set (match_dup 0) (reg:SI 18))
2893 (set (match_dup 3) (reg:SI 22))])
2895 (define_insn "*divmodsi4_call"
2896 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2897 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2898 (clobber (reg:HI 26))
2899 (clobber (reg:HI 30))]
2901 "%~call __divmodsi4"
2902 [(set_attr "type" "xcall")
2903 (set_attr "cc" "clobber")])
2905 (define_insn_and_split "udivmodsi4"
2906 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2907 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2908 (match_operand:SI 2 "pseudo_register_operand" "")))
2909 (set (match_operand:SI 3 "pseudo_register_operand" "")
2910 (umod:SI (match_dup 1) (match_dup 2)))
2911 (clobber (reg:SI 18))
2912 (clobber (reg:SI 22))
2913 (clobber (reg:HI 26))
2914 (clobber (reg:HI 30))])]
2916 "this udivmodsi4 pattern should have been splitted;"
2918 [(set (reg:SI 22) (match_dup 1))
2919 (set (reg:SI 18) (match_dup 2))
2920 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2921 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2922 (clobber (reg:HI 26))
2923 (clobber (reg:HI 30))])
2924 (set (match_dup 0) (reg:SI 18))
2925 (set (match_dup 3) (reg:SI 22))])
2927 (define_insn "*udivmodsi4_call"
2928 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2929 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2930 (clobber (reg:HI 26))
2931 (clobber (reg:HI 30))]
2933 "%~call __udivmodsi4"
2934 [(set_attr "type" "xcall")
2935 (set_attr "cc" "clobber")])
2937 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2940 (define_insn "andqi3"
2941 [(set (match_operand:QI 0 "register_operand" "=r,d")
2942 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2943 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2948 [(set_attr "length" "1,1")
2949 (set_attr "cc" "set_zn,set_zn")])
2951 (define_insn "andhi3"
2952 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2953 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2954 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2955 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2958 if (which_alternative == 0)
2959 return "and %A0,%A2\;and %B0,%B2";
2960 else if (which_alternative == 1)
2961 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2963 return avr_out_bitop (insn, operands, NULL);
2965 [(set_attr "length" "2,2,2,4,4")
2966 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2967 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2969 (define_insn "andpsi3"
2970 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2971 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2972 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2973 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2976 if (which_alternative == 0)
2977 return "and %A0,%A2" CR_TAB
2978 "and %B0,%B2" CR_TAB
2981 return avr_out_bitop (insn, operands, NULL);
2983 [(set_attr "length" "3,3,6,6")
2984 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2985 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2987 (define_insn "andsi3"
2988 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2989 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2990 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2991 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2994 if (which_alternative == 0)
2995 return "and %0,%2" CR_TAB
2996 "and %B0,%B2" CR_TAB
2997 "and %C0,%C2" CR_TAB
3000 return avr_out_bitop (insn, operands, NULL);
3002 [(set_attr "length" "4,4,8,8")
3003 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3004 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3006 (define_peephole2 ; andi
3007 [(set (match_operand:QI 0 "d_register_operand" "")
3008 (and:QI (match_dup 0)
3009 (match_operand:QI 1 "const_int_operand" "")))
3011 (and:QI (match_dup 0)
3012 (match_operand:QI 2 "const_int_operand" "")))]
3014 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3016 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3019 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3022 (define_insn "iorqi3"
3023 [(set (match_operand:QI 0 "register_operand" "=r,d")
3024 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3025 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3030 [(set_attr "length" "1,1")
3031 (set_attr "cc" "set_zn,set_zn")])
3033 (define_insn "iorhi3"
3034 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
3035 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3036 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3037 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3040 if (which_alternative == 0)
3041 return "or %A0,%A2\;or %B0,%B2";
3042 else if (which_alternative == 1)
3043 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3045 return avr_out_bitop (insn, operands, NULL);
3047 [(set_attr "length" "2,2,2,4,4")
3048 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3049 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3051 (define_insn "iorpsi3"
3052 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3053 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3054 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3055 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3058 if (which_alternative == 0)
3059 return "or %A0,%A2" CR_TAB
3063 return avr_out_bitop (insn, operands, NULL);
3065 [(set_attr "length" "3,3,6,6")
3066 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3067 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3069 (define_insn "iorsi3"
3070 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3071 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3072 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3073 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3076 if (which_alternative == 0)
3077 return "or %0,%2" CR_TAB
3082 return avr_out_bitop (insn, operands, NULL);
3084 [(set_attr "length" "4,4,8,8")
3085 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3086 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3088 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3091 (define_insn "xorqi3"
3092 [(set (match_operand:QI 0 "register_operand" "=r")
3093 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3094 (match_operand:QI 2 "register_operand" "r")))]
3097 [(set_attr "length" "1")
3098 (set_attr "cc" "set_zn")])
3100 (define_insn "xorhi3"
3101 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3102 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3103 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3104 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3107 if (which_alternative == 0)
3108 return "eor %A0,%A2\;eor %B0,%B2";
3110 return avr_out_bitop (insn, operands, NULL);
3112 [(set_attr "length" "2,2,4")
3113 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3114 (set_attr "cc" "set_n,clobber,clobber")])
3116 (define_insn "xorpsi3"
3117 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3118 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3119 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3120 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3123 if (which_alternative == 0)
3124 return "eor %A0,%A2" CR_TAB
3125 "eor %B0,%B2" CR_TAB
3128 return avr_out_bitop (insn, operands, NULL);
3130 [(set_attr "length" "3,6,6")
3131 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3132 (set_attr "cc" "set_n,clobber,clobber")])
3134 (define_insn "xorsi3"
3135 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3136 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3137 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3138 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3141 if (which_alternative == 0)
3142 return "eor %0,%2" CR_TAB
3143 "eor %B0,%B2" CR_TAB
3144 "eor %C0,%C2" CR_TAB
3147 return avr_out_bitop (insn, operands, NULL);
3149 [(set_attr "length" "4,8,8")
3150 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3151 (set_attr "cc" "set_n,clobber,clobber")])
3153 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3156 (define_expand "rotlqi3"
3157 [(set (match_operand:QI 0 "register_operand" "")
3158 (rotate:QI (match_operand:QI 1 "register_operand" "")
3159 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3162 if (!CONST_INT_P (operands[2]))
3165 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3168 ;; Expander used by __builtin_avr_swap
3169 (define_expand "rotlqi3_4"
3170 [(set (match_operand:QI 0 "register_operand" "")
3171 (rotate:QI (match_operand:QI 1 "register_operand" "")
3174 (define_insn "*rotlqi3"
3175 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3176 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3177 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3180 lsl %0\;adc %0,__zero_reg__
3181 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3182 swap %0\;bst %0,0\;ror %0\;bld %0,7
3184 swap %0\;lsl %0\;adc %0,__zero_reg__
3185 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3186 bst %0,0\;ror %0\;bld %0,7
3188 [(set_attr "length" "2,4,4,1,3,5,3,0")
3189 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3191 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3192 ;; a whole number of bytes. The split creates the appropriate moves and
3193 ;; considers all overlap situations.
3195 ;; HImode does not need scratch. Use attribute for this constraint.
3197 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3198 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3203 (define_expand "rotl<mode>3"
3204 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3205 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3206 (match_operand:VOID 2 "const_int_operand" "")))
3207 (clobber (match_dup 3))])]
3212 if (!CONST_INT_P (operands[2]))
3215 offset = INTVAL (operands[2]);
3217 if (0 == offset % 8)
3219 if (AVR_HAVE_MOVW && 0 == offset % 16)
3220 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3222 operands[3] = gen_rtx_SCRATCH (QImode);
3224 else if (offset == 1
3225 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3227 /*; Support rotate left/right by 1 */
3229 emit_move_insn (operands[0],
3230 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3237 (define_insn "*rotlhi2.1"
3238 [(set (match_operand:HI 0 "register_operand" "=r")
3239 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3242 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3243 [(set_attr "length" "3")
3244 (set_attr "cc" "clobber")])
3246 (define_insn "*rotlhi2.15"
3247 [(set (match_operand:HI 0 "register_operand" "=r")
3248 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3251 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3252 [(set_attr "length" "4")
3253 (set_attr "cc" "clobber")])
3255 (define_insn "*rotlpsi2.1"
3256 [(set (match_operand:PSI 0 "register_operand" "=r")
3257 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3260 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3261 [(set_attr "length" "4")
3262 (set_attr "cc" "clobber")])
3264 (define_insn "*rotlpsi2.23"
3265 [(set (match_operand:PSI 0 "register_operand" "=r")
3266 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3269 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3270 [(set_attr "length" "5")
3271 (set_attr "cc" "clobber")])
3273 (define_insn "*rotlsi2.1"
3274 [(set (match_operand:SI 0 "register_operand" "=r")
3275 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3278 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3279 [(set_attr "length" "5")
3280 (set_attr "cc" "clobber")])
3282 (define_insn "*rotlsi2.31"
3283 [(set (match_operand:SI 0 "register_operand" "=r")
3284 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3287 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3288 [(set_attr "length" "6")
3289 (set_attr "cc" "clobber")])
3291 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3292 ;; The best we can do is use early clobber alternative "#&r" so that
3293 ;; completely non-overlapping operands dont get a scratch but # so register
3294 ;; allocation does not prefer non-overlapping.
3297 ;; Split word aligned rotates using scratch that is mode dependent.
3301 (define_insn_and_split "*rotw<mode>"
3302 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3303 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3304 (match_operand 2 "const_int_operand" "n,n,n")))
3305 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3307 && CONST_INT_P (operands[2])
3308 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3309 && 0 == INTVAL (operands[2]) % 16"
3311 "&& reload_completed"
3314 avr_rotate_bytes (operands);
3319 ;; Split byte aligned rotates using scratch that is always QI mode.
3324 (define_insn_and_split "*rotb<mode>"
3325 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3326 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3327 (match_operand 2 "const_int_operand" "n,n,n")))
3328 (clobber (match_scratch:QI 3 "=<rotx>"))]
3329 "CONST_INT_P (operands[2])
3330 && (8 == INTVAL (operands[2]) % 16
3332 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3333 && 0 == INTVAL (operands[2]) % 16))"
3335 "&& reload_completed"
3338 avr_rotate_bytes (operands);
3343 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3344 ;; arithmetic shift left
3347 ;; "ashlqq3" "ashluqq3"
3348 (define_expand "ashl<mode>3"
3349 [(set (match_operand:ALL1 0 "register_operand" "")
3350 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3351 (match_operand:QI 2 "nop_general_operand" "")))])
3353 (define_split ; ashlqi3_const4
3354 [(set (match_operand:ALL1 0 "d_register_operand" "")
3355 (ashift:ALL1 (match_dup 0)
3359 (rotate:QI (match_dup 1)
3362 (and:QI (match_dup 1)
3365 operands[1] = avr_to_int_mode (operands[0]);
3368 (define_split ; ashlqi3_const5
3369 [(set (match_operand:ALL1 0 "d_register_operand" "")
3370 (ashift:ALL1 (match_dup 0)
3373 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3374 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3375 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3377 operands[1] = avr_to_int_mode (operands[0]);
3380 (define_split ; ashlqi3_const6
3381 [(set (match_operand:ALL1 0 "d_register_operand" "")
3382 (ashift:ALL1 (match_dup 0)
3385 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3386 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3387 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3389 operands[1] = avr_to_int_mode (operands[0]);
3393 ;; "*ashlqq3" "*ashluqq3"
3394 (define_insn "*ashl<mode>3"
3395 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3396 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3397 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3400 return ashlqi3_out (insn, operands, NULL);
3402 [(set_attr "length" "5,0,1,2,4,6,9")
3403 (set_attr "adjust_len" "ashlqi")
3404 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3406 (define_insn "ashl<mode>3"
3407 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3408 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3409 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3412 return ashlhi3_out (insn, operands, NULL);
3414 [(set_attr "length" "6,0,2,2,4,10,10")
3415 (set_attr "adjust_len" "ashlhi")
3416 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3419 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3420 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3424 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3425 [(set (match_operand:QI 0 "register_operand" "=r")
3426 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3427 (match_operand:QI 2 "register_operand" "r"))
3433 (ashift:QI (match_dup 1)
3436 ;; ??? Combiner does not recognize that it could split the following insn;
3437 ;; presumably because he has no register handy?
3439 ;; "*ashluqihiqi3.mem"
3440 ;; "*ashlsqihiqi3.mem"
3441 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3442 [(set (match_operand:QI 0 "memory_operand" "=m")
3443 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3444 (match_operand:QI 2 "register_operand" "r"))
3447 { gcc_unreachable(); }
3450 (ashift:QI (match_dup 1)
3455 operands[3] = gen_reg_rtx (QImode);
3460 (define_insn_and_split "*ashlhiqi3"
3461 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3462 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3463 (match_operand:QI 2 "register_operand" "r")) 0))]
3465 { gcc_unreachable(); }
3468 (ashift:QI (match_dup 3)
3473 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3474 operands[4] = gen_reg_rtx (QImode);
3477 ;; High part of 16-bit shift is unused after the instruction:
3478 ;; No need to compute it, map to 8-bit shift.
3481 [(set (match_operand:HI 0 "register_operand" "")
3482 (ashift:HI (match_dup 0)
3483 (match_operand:QI 1 "register_operand" "")))]
3486 (ashift:QI (match_dup 2)
3488 (clobber (match_dup 3))]
3490 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3492 if (!peep2_reg_dead_p (1, operands[3]))
3495 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3500 ;; "ashlsq3" "ashlusq3"
3501 ;; "ashlsa3" "ashlusa3"
3502 (define_insn "ashl<mode>3"
3503 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3504 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3505 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3508 return ashlsi3_out (insn, operands, NULL);
3510 [(set_attr "length" "8,0,4,4,8,10,12")
3511 (set_attr "adjust_len" "ashlsi")
3512 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3514 ;; Optimize if a scratch register from LD_REGS happens to be available.
3516 (define_peephole2 ; ashlqi3_l_const4
3517 [(set (match_operand:ALL1 0 "l_register_operand" "")
3518 (ashift:ALL1 (match_dup 0)
3520 (match_scratch:QI 1 "d")]
3522 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3523 (set (match_dup 1) (const_int -16))
3524 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3526 operands[2] = avr_to_int_mode (operands[0]);
3529 (define_peephole2 ; ashlqi3_l_const5
3530 [(set (match_operand:ALL1 0 "l_register_operand" "")
3531 (ashift:ALL1 (match_dup 0)
3533 (match_scratch:QI 1 "d")]
3535 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3536 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3537 (set (match_dup 1) (const_int -32))
3538 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3540 operands[2] = avr_to_int_mode (operands[0]);
3543 (define_peephole2 ; ashlqi3_l_const6
3544 [(set (match_operand:ALL1 0 "l_register_operand" "")
3545 (ashift:ALL1 (match_dup 0)
3547 (match_scratch:QI 1 "d")]
3549 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3550 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3551 (set (match_dup 1) (const_int -64))
3552 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3554 operands[2] = avr_to_int_mode (operands[0]);
3558 [(match_scratch:QI 3 "d")
3559 (set (match_operand:ALL2 0 "register_operand" "")
3560 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3561 (match_operand:QI 2 "const_int_operand" "")))]
3563 [(parallel [(set (match_dup 0)
3564 (ashift:ALL2 (match_dup 1)
3566 (clobber (match_dup 3))])])
3569 ;; "*ashlhq3_const" "*ashluhq3_const"
3570 ;; "*ashlha3_const" "*ashluha3_const"
3571 (define_insn "*ashl<mode>3_const"
3572 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3573 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3574 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3575 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3578 return ashlhi3_out (insn, operands, NULL);
3580 [(set_attr "length" "0,2,2,4,10")
3581 (set_attr "adjust_len" "ashlhi")
3582 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3585 [(match_scratch:QI 3 "d")
3586 (set (match_operand:ALL4 0 "register_operand" "")
3587 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3588 (match_operand:QI 2 "const_int_operand" "")))]
3590 [(parallel [(set (match_dup 0)
3591 (ashift:ALL4 (match_dup 1)
3593 (clobber (match_dup 3))])])
3596 ;; "*ashlsq3_const" "*ashlusq3_const"
3597 ;; "*ashlsa3_const" "*ashlusa3_const"
3598 (define_insn "*ashl<mode>3_const"
3599 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3600 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3601 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3602 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3605 return ashlsi3_out (insn, operands, NULL);
3607 [(set_attr "length" "0,4,4,10")
3608 (set_attr "adjust_len" "ashlsi")
3609 (set_attr "cc" "none,set_n,clobber,clobber")])
3611 (define_expand "ashlpsi3"
3612 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3613 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3614 (match_operand:QI 2 "nonmemory_operand" "")))
3615 (clobber (scratch:QI))])]
3619 && CONST_INT_P (operands[2]))
3621 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3623 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3624 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3627 else if (optimize_insn_for_speed_p ()
3628 && INTVAL (operands[2]) != 16
3629 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3631 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3632 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3638 (define_insn "*ashlpsi3"
3639 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3640 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3641 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3642 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3645 return avr_out_ashlpsi3 (insn, operands, NULL);
3647 [(set_attr "adjust_len" "ashlpsi")
3648 (set_attr "cc" "clobber")])
3650 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3651 ;; arithmetic shift right
3654 ;; "ashrqq3" "ashruqq3"
3655 (define_insn "ashr<mode>3"
3656 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3657 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3658 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3661 return ashrqi3_out (insn, operands, NULL);
3663 [(set_attr "length" "5,0,1,2,5,4,9")
3664 (set_attr "adjust_len" "ashrqi")
3665 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3668 ;; "ashrhq3" "ashruhq3"
3669 ;; "ashrha3" "ashruha3"
3670 (define_insn "ashr<mode>3"
3671 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3672 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3673 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3676 return ashrhi3_out (insn, operands, NULL);
3678 [(set_attr "length" "6,0,2,4,4,10,10")
3679 (set_attr "adjust_len" "ashrhi")
3680 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3682 (define_insn "ashrpsi3"
3683 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3684 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3685 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3686 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3689 return avr_out_ashrpsi3 (insn, operands, NULL);
3691 [(set_attr "adjust_len" "ashrpsi")
3692 (set_attr "cc" "clobber")])
3695 ;; "ashrsq3" "ashrusq3"
3696 ;; "ashrsa3" "ashrusa3"
3697 (define_insn "ashr<mode>3"
3698 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3699 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3700 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3703 return ashrsi3_out (insn, operands, NULL);
3705 [(set_attr "length" "8,0,4,6,8,10,12")
3706 (set_attr "adjust_len" "ashrsi")
3707 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3709 ;; Optimize if a scratch register from LD_REGS happens to be available.
3712 [(match_scratch:QI 3 "d")
3713 (set (match_operand:ALL2 0 "register_operand" "")
3714 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3715 (match_operand:QI 2 "const_int_operand" "")))]
3717 [(parallel [(set (match_dup 0)
3718 (ashiftrt:ALL2 (match_dup 1)
3720 (clobber (match_dup 3))])])
3723 ;; "*ashrhq3_const" "*ashruhq3_const"
3724 ;; "*ashrha3_const" "*ashruha3_const"
3725 (define_insn "*ashr<mode>3_const"
3726 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3727 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3728 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3729 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3732 return ashrhi3_out (insn, operands, NULL);
3734 [(set_attr "length" "0,2,4,4,10")
3735 (set_attr "adjust_len" "ashrhi")
3736 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3739 [(match_scratch:QI 3 "d")
3740 (set (match_operand:ALL4 0 "register_operand" "")
3741 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3742 (match_operand:QI 2 "const_int_operand" "")))]
3744 [(parallel [(set (match_dup 0)
3745 (ashiftrt:ALL4 (match_dup 1)
3747 (clobber (match_dup 3))])])
3750 ;; "*ashrsq3_const" "*ashrusq3_const"
3751 ;; "*ashrsa3_const" "*ashrusa3_const"
3752 (define_insn "*ashr<mode>3_const"
3753 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3754 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3755 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3756 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3759 return ashrsi3_out (insn, operands, NULL);
3761 [(set_attr "length" "0,4,4,10")
3762 (set_attr "adjust_len" "ashrsi")
3763 (set_attr "cc" "none,clobber,set_n,clobber")])
3765 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3766 ;; logical shift right
3769 ;; "lshrqq3 "lshruqq3"
3770 (define_expand "lshr<mode>3"
3771 [(set (match_operand:ALL1 0 "register_operand" "")
3772 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3773 (match_operand:QI 2 "nop_general_operand" "")))])
3775 (define_split ; lshrqi3_const4
3776 [(set (match_operand:ALL1 0 "d_register_operand" "")
3777 (lshiftrt:ALL1 (match_dup 0)
3781 (rotate:QI (match_dup 1)
3784 (and:QI (match_dup 1)
3787 operands[1] = avr_to_int_mode (operands[0]);
3790 (define_split ; lshrqi3_const5
3791 [(set (match_operand:ALL1 0 "d_register_operand" "")
3792 (lshiftrt:ALL1 (match_dup 0)
3795 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3796 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3797 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3799 operands[1] = avr_to_int_mode (operands[0]);
3802 (define_split ; lshrqi3_const6
3803 [(set (match_operand:QI 0 "d_register_operand" "")
3804 (lshiftrt:QI (match_dup 0)
3807 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3808 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3809 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3811 operands[1] = avr_to_int_mode (operands[0]);
3817 (define_insn "*lshr<mode>3"
3818 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3819 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3820 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3823 return lshrqi3_out (insn, operands, NULL);
3825 [(set_attr "length" "5,0,1,2,4,6,9")
3826 (set_attr "adjust_len" "lshrqi")
3827 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3830 ;; "lshrhq3" "lshruhq3"
3831 ;; "lshrha3" "lshruha3"
3832 (define_insn "lshr<mode>3"
3833 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3834 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3835 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3838 return lshrhi3_out (insn, operands, NULL);
3840 [(set_attr "length" "6,0,2,2,4,10,10")
3841 (set_attr "adjust_len" "lshrhi")
3842 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3844 (define_insn "lshrpsi3"
3845 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3846 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3847 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3848 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3851 return avr_out_lshrpsi3 (insn, operands, NULL);
3853 [(set_attr "adjust_len" "lshrpsi")
3854 (set_attr "cc" "clobber")])
3857 ;; "lshrsq3" "lshrusq3"
3858 ;; "lshrsa3" "lshrusa3"
3859 (define_insn "lshr<mode>3"
3860 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3861 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3862 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3865 return lshrsi3_out (insn, operands, NULL);
3867 [(set_attr "length" "8,0,4,4,8,10,12")
3868 (set_attr "adjust_len" "lshrsi")
3869 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3871 ;; Optimize if a scratch register from LD_REGS happens to be available.
3873 (define_peephole2 ; lshrqi3_l_const4
3874 [(set (match_operand:ALL1 0 "l_register_operand" "")
3875 (lshiftrt:ALL1 (match_dup 0)
3877 (match_scratch:QI 1 "d")]
3879 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3880 (set (match_dup 1) (const_int 15))
3881 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3883 operands[2] = avr_to_int_mode (operands[0]);
3886 (define_peephole2 ; lshrqi3_l_const5
3887 [(set (match_operand:ALL1 0 "l_register_operand" "")
3888 (lshiftrt:ALL1 (match_dup 0)
3890 (match_scratch:QI 1 "d")]
3892 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3893 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3894 (set (match_dup 1) (const_int 7))
3895 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3897 operands[2] = avr_to_int_mode (operands[0]);
3900 (define_peephole2 ; lshrqi3_l_const6
3901 [(set (match_operand:ALL1 0 "l_register_operand" "")
3902 (lshiftrt:ALL1 (match_dup 0)
3904 (match_scratch:QI 1 "d")]
3906 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3907 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3908 (set (match_dup 1) (const_int 3))
3909 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3911 operands[2] = avr_to_int_mode (operands[0]);
3915 [(match_scratch:QI 3 "d")
3916 (set (match_operand:ALL2 0 "register_operand" "")
3917 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3918 (match_operand:QI 2 "const_int_operand" "")))]
3920 [(parallel [(set (match_dup 0)
3921 (lshiftrt:ALL2 (match_dup 1)
3923 (clobber (match_dup 3))])])
3926 ;; "*lshrhq3_const" "*lshruhq3_const"
3927 ;; "*lshrha3_const" "*lshruha3_const"
3928 (define_insn "*lshr<mode>3_const"
3929 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3930 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3931 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3932 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3935 return lshrhi3_out (insn, operands, NULL);
3937 [(set_attr "length" "0,2,2,4,10")
3938 (set_attr "adjust_len" "lshrhi")
3939 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3942 [(match_scratch:QI 3 "d")
3943 (set (match_operand:ALL4 0 "register_operand" "")
3944 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3945 (match_operand:QI 2 "const_int_operand" "")))]
3947 [(parallel [(set (match_dup 0)
3948 (lshiftrt:ALL4 (match_dup 1)
3950 (clobber (match_dup 3))])])
3953 ;; "*lshrsq3_const" "*lshrusq3_const"
3954 ;; "*lshrsa3_const" "*lshrusa3_const"
3955 (define_insn "*lshr<mode>3_const"
3956 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3957 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3958 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3959 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3962 return lshrsi3_out (insn, operands, NULL);
3964 [(set_attr "length" "0,4,4,10")
3965 (set_attr "adjust_len" "lshrsi")
3966 (set_attr "cc" "none,clobber,clobber,clobber")])
3968 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3971 (define_insn "absqi2"
3972 [(set (match_operand:QI 0 "register_operand" "=r")
3973 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3977 [(set_attr "length" "2")
3978 (set_attr "cc" "clobber")])
3981 (define_insn "abssf2"
3982 [(set (match_operand:SF 0 "register_operand" "=d,r")
3983 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3988 [(set_attr "length" "1,2")
3989 (set_attr "cc" "set_n,clobber")])
3991 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3994 (define_insn "negqi2"
3995 [(set (match_operand:QI 0 "register_operand" "=r")
3996 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3999 [(set_attr "length" "1")
4000 (set_attr "cc" "set_zn")])
4002 (define_insn "*negqihi2"
4003 [(set (match_operand:HI 0 "register_operand" "=r")
4004 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4006 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4007 [(set_attr "length" "4")
4008 (set_attr "cc" "set_n")])
4010 (define_insn "neghi2"
4011 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4012 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4015 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4016 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4017 [(set_attr "length" "3,4")
4018 (set_attr "cc" "set_czn")])
4020 (define_insn "negpsi2"
4021 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4022 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4025 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4026 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4027 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4028 [(set_attr "length" "5,6,6")
4029 (set_attr "cc" "set_czn,set_n,set_czn")])
4031 (define_insn "negsi2"
4032 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4033 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4036 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4037 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4038 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4039 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4040 [(set_attr "length" "7,8,8,7")
4041 (set_attr "isa" "*,*,mov,movw")
4042 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4044 (define_insn "negsf2"
4045 [(set (match_operand:SF 0 "register_operand" "=d,r")
4046 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4050 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4051 [(set_attr "length" "1,4")
4052 (set_attr "cc" "set_n,set_n")])
4054 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4057 (define_insn "one_cmplqi2"
4058 [(set (match_operand:QI 0 "register_operand" "=r")
4059 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4062 [(set_attr "length" "1")
4063 (set_attr "cc" "set_czn")])
4065 (define_insn "one_cmplhi2"
4066 [(set (match_operand:HI 0 "register_operand" "=r")
4067 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4071 [(set_attr "length" "2")
4072 (set_attr "cc" "set_n")])
4074 (define_insn "one_cmplpsi2"
4075 [(set (match_operand:PSI 0 "register_operand" "=r")
4076 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4078 "com %0\;com %B0\;com %C0"
4079 [(set_attr "length" "3")
4080 (set_attr "cc" "set_n")])
4082 (define_insn "one_cmplsi2"
4083 [(set (match_operand:SI 0 "register_operand" "=r")
4084 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4090 [(set_attr "length" "4")
4091 (set_attr "cc" "set_n")])
4093 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4096 ;; We keep combiner from inserting hard registers into the input of sign- and
4097 ;; zero-extends. A hard register in the input operand is not wanted because
4098 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4099 ;; hard register that overlaps these clobbers won't be combined to a widening
4100 ;; multiplication. There is no need for combine to propagate hard registers,
4101 ;; register allocation can do it just as well.
4103 (define_insn "extendqihi2"
4104 [(set (match_operand:HI 0 "register_operand" "=r,r")
4105 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4108 clr %B0\;sbrc %0,7\;com %B0
4109 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4110 [(set_attr "length" "3,4")
4111 (set_attr "cc" "set_n,set_n")])
4113 (define_insn "extendqipsi2"
4114 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4115 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4118 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4119 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4120 [(set_attr "length" "4,5")
4121 (set_attr "cc" "set_n,set_n")])
4123 (define_insn "extendqisi2"
4124 [(set (match_operand:SI 0 "register_operand" "=r,r")
4125 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4128 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4129 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4130 [(set_attr "length" "5,6")
4131 (set_attr "cc" "set_n,set_n")])
4133 (define_insn "extendhipsi2"
4134 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4135 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4138 clr %C0\;sbrc %B0,7\;com %C0
4139 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4140 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4141 [(set_attr "length" "3,5,4")
4142 (set_attr "isa" "*,mov,movw")
4143 (set_attr "cc" "set_n")])
4145 (define_insn "extendhisi2"
4146 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4147 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4150 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4151 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4152 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4153 [(set_attr "length" "4,6,5")
4154 (set_attr "isa" "*,mov,movw")
4155 (set_attr "cc" "set_n")])
4157 (define_insn "extendpsisi2"
4158 [(set (match_operand:SI 0 "register_operand" "=r")
4159 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4161 "clr %D0\;sbrc %C0,7\;com %D0"
4162 [(set_attr "length" "3")
4163 (set_attr "cc" "set_n")])
4165 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4168 (define_insn_and_split "zero_extendqihi2"
4169 [(set (match_operand:HI 0 "register_operand" "=r")
4170 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4174 [(set (match_dup 2) (match_dup 1))
4175 (set (match_dup 3) (const_int 0))]
4177 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4178 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4180 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4181 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4184 (define_insn_and_split "zero_extendqipsi2"
4185 [(set (match_operand:PSI 0 "register_operand" "=r")
4186 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4190 [(set (match_dup 2) (match_dup 1))
4191 (set (match_dup 3) (const_int 0))
4192 (set (match_dup 4) (const_int 0))]
4194 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4195 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4196 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4199 (define_insn_and_split "zero_extendqisi2"
4200 [(set (match_operand:SI 0 "register_operand" "=r")
4201 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4205 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4206 (set (match_dup 3) (const_int 0))]
4208 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4209 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4211 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4212 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4215 (define_insn_and_split "zero_extendhipsi2"
4216 [(set (match_operand:PSI 0 "register_operand" "=r")
4217 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4221 [(set (match_dup 2) (match_dup 1))
4222 (set (match_dup 3) (const_int 0))]
4224 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4225 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4228 (define_insn_and_split "n_extendhipsi2"
4229 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4230 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4231 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4232 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4236 [(set (match_dup 4) (match_dup 2))
4237 (set (match_dup 3) (match_dup 6))
4238 ; no-op move in the case where no scratch is needed
4239 (set (match_dup 5) (match_dup 3))]
4241 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4242 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4243 operands[6] = operands[1];
4245 if (GET_CODE (operands[3]) == SCRATCH)
4246 operands[3] = operands[5];
4249 (define_insn_and_split "zero_extendhisi2"
4250 [(set (match_operand:SI 0 "register_operand" "=r")
4251 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4255 [(set (match_dup 2) (match_dup 1))
4256 (set (match_dup 3) (const_int 0))]
4258 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4259 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4261 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4262 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4265 (define_insn_and_split "zero_extendpsisi2"
4266 [(set (match_operand:SI 0 "register_operand" "=r")
4267 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4271 [(set (match_dup 2) (match_dup 1))
4272 (set (match_dup 3) (const_int 0))]
4274 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4275 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4278 (define_insn_and_split "zero_extendqidi2"
4279 [(set (match_operand:DI 0 "register_operand" "=r")
4280 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4284 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4285 (set (match_dup 3) (const_int 0))]
4287 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4288 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4290 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4291 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4294 (define_insn_and_split "zero_extendhidi2"
4295 [(set (match_operand:DI 0 "register_operand" "=r")
4296 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4300 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4301 (set (match_dup 3) (const_int 0))]
4303 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4304 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4306 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4307 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4310 (define_insn_and_split "zero_extendsidi2"
4311 [(set (match_operand:DI 0 "register_operand" "=r")
4312 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4316 [(set (match_dup 2) (match_dup 1))
4317 (set (match_dup 3) (const_int 0))]
4319 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4320 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4322 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4323 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4326 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4329 ; Optimize negated tests into reverse compare if overflow is undefined.
4330 (define_insn "*negated_tstqi"
4332 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4334 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4335 "cp __zero_reg__,%0"
4336 [(set_attr "cc" "compare")
4337 (set_attr "length" "1")])
4339 (define_insn "*reversed_tstqi"
4341 (compare (const_int 0)
4342 (match_operand:QI 0 "register_operand" "r")))]
4344 "cp __zero_reg__,%0"
4345 [(set_attr "cc" "compare")
4346 (set_attr "length" "2")])
4348 (define_insn "*negated_tsthi"
4350 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4352 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4353 "cp __zero_reg__,%A0
4354 cpc __zero_reg__,%B0"
4355 [(set_attr "cc" "compare")
4356 (set_attr "length" "2")])
4358 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4359 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4360 (define_insn "*reversed_tsthi"
4362 (compare (const_int 0)
4363 (match_operand:HI 0 "register_operand" "r")))
4364 (clobber (match_scratch:QI 1 "=X"))]
4366 "cp __zero_reg__,%A0
4367 cpc __zero_reg__,%B0"
4368 [(set_attr "cc" "compare")
4369 (set_attr "length" "2")])
4371 (define_insn "*negated_tstpsi"
4373 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4375 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4376 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4377 [(set_attr "cc" "compare")
4378 (set_attr "length" "3")])
4380 (define_insn "*reversed_tstpsi"
4382 (compare (const_int 0)
4383 (match_operand:PSI 0 "register_operand" "r")))
4384 (clobber (match_scratch:QI 1 "=X"))]
4386 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4387 [(set_attr "cc" "compare")
4388 (set_attr "length" "3")])
4390 (define_insn "*negated_tstsi"
4392 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4394 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4395 "cp __zero_reg__,%A0
4396 cpc __zero_reg__,%B0
4397 cpc __zero_reg__,%C0
4398 cpc __zero_reg__,%D0"
4399 [(set_attr "cc" "compare")
4400 (set_attr "length" "4")])
4402 ;; "*reversed_tstsi"
4403 ;; "*reversed_tstsq" "*reversed_tstusq"
4404 ;; "*reversed_tstsa" "*reversed_tstusa"
4405 (define_insn "*reversed_tst<mode>"
4407 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4408 (match_operand:ALL4 1 "register_operand" "r")))
4409 (clobber (match_scratch:QI 2 "=X"))]
4411 "cp __zero_reg__,%A1
4412 cpc __zero_reg__,%B1
4413 cpc __zero_reg__,%C1
4414 cpc __zero_reg__,%D1"
4415 [(set_attr "cc" "compare")
4416 (set_attr "length" "4")])
4420 ;; "*cmpqq" "*cmpuqq"
4421 (define_insn "*cmp<mode>"
4423 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4424 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4430 [(set_attr "cc" "compare,compare,compare")
4431 (set_attr "length" "1,1,1")])
4433 (define_insn "*cmpqi_sign_extend"
4435 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4436 (match_operand:HI 1 "s8_operand" "n")))]
4439 [(set_attr "cc" "compare")
4440 (set_attr "length" "1")])
4443 ;; "*cmphq" "*cmpuhq"
4444 ;; "*cmpha" "*cmpuha"
4445 (define_insn "*cmp<mode>"
4447 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4448 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4449 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4452 switch (which_alternative)
4456 return avr_out_tsthi (insn, operands, NULL);
4459 return "cp %A0,%A1\;cpc %B0,%B1";
4462 if (<MODE>mode != HImode)
4464 return reg_unused_after (insn, operands[0])
4465 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4466 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4469 if (<MODE>mode != HImode)
4471 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4474 return avr_out_compare (insn, operands, NULL);
4476 [(set_attr "cc" "compare")
4477 (set_attr "length" "1,2,2,3,4,2,4")
4478 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4480 (define_insn "*cmppsi"
4482 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4483 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4484 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4487 switch (which_alternative)
4490 return avr_out_tstpsi (insn, operands, NULL);
4493 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4496 return reg_unused_after (insn, operands[0])
4497 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4498 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4501 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4504 return avr_out_compare (insn, operands, NULL);
4506 [(set_attr "cc" "compare")
4507 (set_attr "length" "3,3,5,6,3,7")
4508 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4511 ;; "*cmpsq" "*cmpusq"
4512 ;; "*cmpsa" "*cmpusa"
4513 (define_insn "*cmp<mode>"
4515 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4516 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4517 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4520 if (0 == which_alternative)
4521 return avr_out_tstsi (insn, operands, NULL);
4522 else if (1 == which_alternative)
4523 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4525 return avr_out_compare (insn, operands, NULL);
4527 [(set_attr "cc" "compare")
4528 (set_attr "length" "4,4,4,5,8")
4529 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4532 ;; ----------------------------------------------------------------------
4533 ;; JUMP INSTRUCTIONS
4534 ;; ----------------------------------------------------------------------
4535 ;; Conditional jump instructions
4538 ;; "cbranchqq4" "cbranchuqq4"
4539 (define_expand "cbranch<mode>4"
4541 (compare (match_operand:ALL1 1 "register_operand" "")
4542 (match_operand:ALL1 2 "nonmemory_operand" "")))
4545 (match_operator 0 "ordered_comparison_operator" [(cc0)
4547 (label_ref (match_operand 3 "" ""))
4550 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4551 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4553 (define_expand "cbranch<mode>4"
4554 [(parallel [(set (cc0)
4555 (compare (match_operand:ORDERED234 1 "register_operand" "")
4556 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4557 (clobber (match_scratch:QI 4 ""))])
4560 (match_operator 0 "ordered_comparison_operator" [(cc0)
4562 (label_ref (match_operand 3 "" ""))
4566 ;; Test a single bit in a QI/HI/SImode register.
4567 ;; Combine will create zero extract patterns for single bit tests.
4568 ;; permit any mode in source pattern by using VOIDmode.
4570 (define_insn "*sbrx_branch<mode>"
4573 (match_operator 0 "eqne_operator"
4575 (match_operand:VOID 1 "register_operand" "r")
4577 (match_operand 2 "const_int_operand" "n"))
4579 (label_ref (match_operand 3 "" ""))
4583 return avr_out_sbxx_branch (insn, operands);
4585 [(set (attr "length")
4586 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4587 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4589 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4592 (set_attr "cc" "clobber")])
4594 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4595 ;; or for old peepholes.
4596 ;; Fixme - bitwise Mask will not work for DImode
4598 (define_insn "*sbrx_and_branch<mode>"
4601 (match_operator 0 "eqne_operator"
4603 (match_operand:QISI 1 "register_operand" "r")
4604 (match_operand:QISI 2 "single_one_operand" "n"))
4606 (label_ref (match_operand 3 "" ""))
4610 HOST_WIDE_INT bitnumber;
4611 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4612 operands[2] = GEN_INT (bitnumber);
4613 return avr_out_sbxx_branch (insn, operands);
4615 [(set (attr "length")
4616 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4617 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4619 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4622 (set_attr "cc" "clobber")])
4624 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4626 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4628 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4629 (label_ref (match_operand 1 "" ""))
4632 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4636 (label_ref (match_dup 1))
4640 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4642 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4643 (label_ref (match_operand 1 "" ""))
4646 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4650 (label_ref (match_dup 1))
4654 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4656 (clobber (match_operand:HI 2 ""))])
4657 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4658 (label_ref (match_operand 1 "" ""))
4661 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4663 (label_ref (match_dup 1))
4667 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4669 (clobber (match_operand:HI 2 ""))])
4670 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4671 (label_ref (match_operand 1 "" ""))
4674 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4676 (label_ref (match_dup 1))
4680 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4682 (clobber (match_operand:SI 2 ""))])
4683 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4684 (label_ref (match_operand 1 "" ""))
4687 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4689 (label_ref (match_dup 1))
4691 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4694 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4696 (clobber (match_operand:SI 2 ""))])
4697 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4698 (label_ref (match_operand 1 "" ""))
4701 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4703 (label_ref (match_dup 1))
4705 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4707 ;; ************************************************************************
4708 ;; Implementation of conditional jumps here.
4709 ;; Compare with 0 (test) jumps
4710 ;; ************************************************************************
4712 (define_insn "branch"
4714 (if_then_else (match_operator 1 "simple_comparison_operator"
4717 (label_ref (match_operand 0 "" ""))
4721 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4723 [(set_attr "type" "branch")
4724 (set_attr "cc" "clobber")])
4727 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4728 ;; or optimized in the remainder.
4730 (define_insn "branch_unspec"
4732 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4735 (label_ref (match_operand 0 "" ""))
4737 ] UNSPEC_IDENTITY))]
4740 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4742 [(set_attr "type" "branch")
4743 (set_attr "cc" "none")])
4745 ;; ****************************************************************
4746 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4747 ;; Convert them all to proper jumps.
4748 ;; ****************************************************************/
4750 (define_insn "difficult_branch"
4752 (if_then_else (match_operator 1 "difficult_comparison_operator"
4755 (label_ref (match_operand 0 "" ""))
4759 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4761 [(set_attr "type" "branch1")
4762 (set_attr "cc" "clobber")])
4766 (define_insn "rvbranch"
4768 (if_then_else (match_operator 1 "simple_comparison_operator"
4772 (label_ref (match_operand 0 "" ""))))]
4775 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4777 [(set_attr "type" "branch1")
4778 (set_attr "cc" "clobber")])
4780 (define_insn "difficult_rvbranch"
4782 (if_then_else (match_operator 1 "difficult_comparison_operator"
4786 (label_ref (match_operand 0 "" ""))))]
4789 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4791 [(set_attr "type" "branch")
4792 (set_attr "cc" "clobber")])
4794 ;; **************************************************************************
4795 ;; Unconditional and other jump instructions.
4799 (label_ref (match_operand 0 "" "")))]
4802 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4806 [(set (attr "length")
4807 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4808 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4811 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4812 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4815 (set_attr "cc" "none")])
4819 ;; Operand 1 not used on the AVR.
4820 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4821 (define_expand "call"
4822 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4823 (match_operand:HI 1 "general_operand" ""))
4824 (use (const_int 0))])])
4826 ;; Operand 1 not used on the AVR.
4827 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4828 (define_expand "sibcall"
4829 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4830 (match_operand:HI 1 "general_operand" ""))
4831 (use (const_int 1))])])
4835 ;; Operand 2 not used on the AVR.
4836 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4837 (define_expand "call_value"
4838 [(parallel[(set (match_operand 0 "register_operand" "")
4839 (call (match_operand:HI 1 "call_insn_operand" "")
4840 (match_operand:HI 2 "general_operand" "")))
4841 (use (const_int 0))])])
4843 ;; Operand 2 not used on the AVR.
4844 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4845 (define_expand "sibcall_value"
4846 [(parallel[(set (match_operand 0 "register_operand" "")
4847 (call (match_operand:HI 1 "call_insn_operand" "")
4848 (match_operand:HI 2 "general_operand" "")))
4849 (use (const_int 1))])])
4851 (define_insn "call_insn"
4852 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4853 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4854 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4855 ;; Operand 1 not used on the AVR.
4856 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4863 [(set_attr "cc" "clobber")
4864 (set_attr "length" "1,*,1,*")
4865 (set_attr "adjust_len" "*,call,*,call")])
4867 (define_insn "call_value_insn"
4868 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4869 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4870 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4871 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4872 ;; Operand 2 not used on the AVR.
4873 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4880 [(set_attr "cc" "clobber")
4881 (set_attr "length" "1,*,1,*")
4882 (set_attr "adjust_len" "*,call,*,call")])
4888 [(set_attr "cc" "none")
4889 (set_attr "length" "1")])
4893 (define_expand "indirect_jump"
4895 (match_operand:HI 0 "nonmemory_operand" ""))]
4898 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4900 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4905 (define_insn "*indirect_jump"
4907 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4913 push %A0\;push %B0\;ret
4915 [(set_attr "length" "1,2,1,3,1")
4916 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4917 (set_attr "cc" "none")])
4920 ;; For entries in jump table see avr_output_addr_vec_elt.
4923 ;; "rjmp .L<n>" instructions for <= 8K devices
4924 ;; ".word gs(.L<n>)" addresses for > 8K devices
4925 (define_insn "*tablejump"
4927 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4929 (use (label_ref (match_operand 1 "" "")))
4930 (clobber (match_dup 0))]
4934 push %A0\;push %B0\;ret
4936 [(set_attr "length" "1,3,2")
4937 (set_attr "isa" "rjmp,rjmp,jmp")
4938 (set_attr "cc" "none,none,clobber")])
4941 (define_expand "casesi"
4942 [(parallel [(set (match_dup 6)
4943 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4944 (match_operand:HI 1 "register_operand" "")))
4945 (clobber (scratch:QI))])
4946 (parallel [(set (cc0)
4947 (compare (match_dup 6)
4948 (match_operand:HI 2 "register_operand" "")))
4949 (clobber (match_scratch:QI 9 ""))])
4952 (if_then_else (gtu (cc0)
4954 (label_ref (match_operand 4 "" ""))
4958 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4960 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4961 (use (label_ref (match_dup 3)))
4962 (clobber (match_dup 6))])]
4965 operands[6] = gen_reg_rtx (HImode);
4969 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4970 ;; This instruction sets Z flag
4973 [(set (cc0) (const_int 0))]
4976 [(set_attr "length" "1")
4977 (set_attr "cc" "compare")])
4979 ;; Clear/set/test a single bit in I/O address space.
4982 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4983 (and:QI (mem:QI (match_dup 0))
4984 (match_operand:QI 1 "single_zero_operand" "n")))]
4987 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4988 return "cbi %i0,%2";
4990 [(set_attr "length" "1")
4991 (set_attr "cc" "none")])
4994 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4995 (ior:QI (mem:QI (match_dup 0))
4996 (match_operand:QI 1 "single_one_operand" "n")))]
4999 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5000 return "sbi %i0,%2";
5002 [(set_attr "length" "1")
5003 (set_attr "cc" "none")])
5005 ;; Lower half of the I/O space - use sbic/sbis directly.
5006 (define_insn "*sbix_branch"
5009 (match_operator 0 "eqne_operator"
5011 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5013 (match_operand 2 "const_int_operand" "n"))
5015 (label_ref (match_operand 3 "" ""))
5019 return avr_out_sbxx_branch (insn, operands);
5021 [(set (attr "length")
5022 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5023 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5025 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5028 (set_attr "cc" "clobber")])
5030 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5031 (define_insn "*sbix_branch_bit7"
5034 (match_operator 0 "gelt_operator"
5035 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5037 (label_ref (match_operand 2 "" ""))
5041 operands[3] = operands[2];
5042 operands[2] = GEN_INT (7);
5043 return avr_out_sbxx_branch (insn, operands);
5045 [(set (attr "length")
5046 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5047 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5049 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5052 (set_attr "cc" "clobber")])
5054 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5055 (define_insn "*sbix_branch_tmp"
5058 (match_operator 0 "eqne_operator"
5060 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5062 (match_operand 2 "const_int_operand" "n"))
5064 (label_ref (match_operand 3 "" ""))
5068 return avr_out_sbxx_branch (insn, operands);
5070 [(set (attr "length")
5071 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5072 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5074 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5077 (set_attr "cc" "clobber")])
5079 (define_insn "*sbix_branch_tmp_bit7"
5082 (match_operator 0 "gelt_operator"
5083 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5085 (label_ref (match_operand 2 "" ""))
5089 operands[3] = operands[2];
5090 operands[2] = GEN_INT (7);
5091 return avr_out_sbxx_branch (insn, operands);
5093 [(set (attr "length")
5094 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5095 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5097 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5100 (set_attr "cc" "clobber")])
5102 ;; ************************* Peepholes ********************************
5104 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5105 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5106 (plus:SI (match_dup 0)
5108 (clobber (scratch:QI))])
5109 (parallel [(set (cc0)
5110 (compare (match_dup 0)
5112 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5114 (if_then_else (eqne (cc0)
5116 (label_ref (match_operand 2 "" ""))
5123 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5124 output_asm_insn ("sbiw %0,1" CR_TAB
5125 "sbc %C0,__zero_reg__" CR_TAB
5126 "sbc %D0,__zero_reg__", operands);
5128 output_asm_insn ("subi %A0,1" CR_TAB
5129 "sbc %B0,__zero_reg__" CR_TAB
5130 "sbc %C0,__zero_reg__" CR_TAB
5131 "sbc %D0,__zero_reg__", operands);
5133 jump_mode = avr_jump_mode (operands[2], insn);
5134 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5135 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5139 case 1: return "%1 %2";
5140 case 2: return "%1 .+2\;rjmp %2";
5141 case 3: return "%1 .+4\;jmp %2";
5148 (define_peephole ; "*dec-and-branchhi!=-1"
5149 [(set (match_operand:HI 0 "d_register_operand" "")
5150 (plus:HI (match_dup 0)
5152 (parallel [(set (cc0)
5153 (compare (match_dup 0)
5155 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5157 (if_then_else (eqne (cc0)
5159 (label_ref (match_operand 2 "" ""))
5166 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5167 output_asm_insn ("sbiw %0,1", operands);
5169 output_asm_insn ("subi %A0,1" CR_TAB
5170 "sbc %B0,__zero_reg__", operands);
5172 jump_mode = avr_jump_mode (operands[2], insn);
5173 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5174 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5178 case 1: return "%1 %2";
5179 case 2: return "%1 .+2\;rjmp %2";
5180 case 3: return "%1 .+4\;jmp %2";
5187 ;; Same as above but with clobber flavour of addhi3
5188 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5189 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5190 (plus:HI (match_dup 0)
5192 (clobber (scratch:QI))])
5193 (parallel [(set (cc0)
5194 (compare (match_dup 0)
5196 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5198 (if_then_else (eqne (cc0)
5200 (label_ref (match_operand 2 "" ""))
5207 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5208 output_asm_insn ("sbiw %0,1", operands);
5210 output_asm_insn ("subi %A0,1" CR_TAB
5211 "sbc %B0,__zero_reg__", operands);
5213 jump_mode = avr_jump_mode (operands[2], insn);
5214 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5215 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5219 case 1: return "%1 %2";
5220 case 2: return "%1 .+2\;rjmp %2";
5221 case 3: return "%1 .+4\;jmp %2";
5228 ;; Same as above but with clobber flavour of addhi3
5229 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5230 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5231 (plus:HI (match_dup 0)
5233 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5234 (parallel [(set (cc0)
5235 (compare (match_dup 0)
5237 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5239 (if_then_else (eqne (cc0)
5241 (label_ref (match_operand 2 "" ""))
5248 output_asm_insn ("ldi %3,1" CR_TAB
5250 "sbc %B0,__zero_reg__", operands);
5252 jump_mode = avr_jump_mode (operands[2], insn);
5253 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5254 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5258 case 1: return "%1 %2";
5259 case 2: return "%1 .+2\;rjmp %2";
5260 case 3: return "%1 .+4\;jmp %2";
5267 (define_peephole ; "*dec-and-branchqi!=-1"
5268 [(set (match_operand:QI 0 "d_register_operand" "")
5269 (plus:QI (match_dup 0)
5272 (compare (match_dup 0)
5275 (if_then_else (eqne (cc0)
5277 (label_ref (match_operand 1 "" ""))
5284 cc_status.value1 = operands[0];
5285 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5287 output_asm_insn ("subi %A0,1", operands);
5289 jump_mode = avr_jump_mode (operands[1], insn);
5290 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5291 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5295 case 1: return "%0 %1";
5296 case 2: return "%0 .+2\;rjmp %1";
5297 case 3: return "%0 .+4\;jmp %1";
5305 (define_peephole ; "*cpse.eq"
5307 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5308 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5310 (if_then_else (eq (cc0)
5312 (label_ref (match_operand 0 "" ""))
5314 "jump_over_one_insn_p (insn, operands[0])"
5317 cpse %1,__zero_reg__")
5319 ;; This peephole avoids code like
5322 ;; BREQ .+2 ; branch
5325 ;; Notice that the peephole is always shorter than cmpqi + branch.
5326 ;; The reason to write it as peephole is that sequences like
5331 ;; shall not be superseeded. With a respective combine pattern
5332 ;; the latter sequence would be
5335 ;; CPSE Rm, __zero_reg__
5338 ;; and thus longer and slower and not easy to be rolled back.
5340 (define_peephole ; "*cpse.ne"
5342 (compare (match_operand:ALL1 1 "register_operand" "")
5343 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5345 (if_then_else (ne (cc0)
5347 (label_ref (match_operand 0 "" ""))
5350 || !avr_current_device->errata_skip"
5352 if (operands[2] == CONST0_RTX (<MODE>mode))
5353 operands[2] = zero_reg_rtx;
5355 return 3 == avr_jump_mode (operands[0], insn)
5356 ? "cpse %1,%2\;jmp %0"
5357 : "cpse %1,%2\;rjmp %0";
5360 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5361 ;;prologue/epilogue support instructions
5363 (define_insn "popqi"
5364 [(set (match_operand:QI 0 "register_operand" "=r")
5365 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5368 [(set_attr "cc" "none")
5369 (set_attr "length" "1")])
5371 ;; Enable Interrupts
5372 (define_expand "enable_interrupt"
5373 [(clobber (const_int 0))]
5376 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5377 MEM_VOLATILE_P (mem) = 1;
5378 emit_insn (gen_cli_sei (const1_rtx, mem));
5382 ;; Disable Interrupts
5383 (define_expand "disable_interrupt"
5384 [(clobber (const_int 0))]
5387 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5388 MEM_VOLATILE_P (mem) = 1;
5389 emit_insn (gen_cli_sei (const0_rtx, mem));
5393 (define_insn "cli_sei"
5394 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5395 UNSPECV_ENABLE_IRQS)
5396 (set (match_operand:BLK 1 "" "")
5397 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5402 [(set_attr "length" "1")
5403 (set_attr "cc" "none")])
5405 ;; Library prologue saves
5406 (define_insn "call_prologue_saves"
5407 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5408 (match_operand:HI 0 "immediate_operand" "i,i")
5409 (set (reg:HI REG_SP)
5410 (minus:HI (reg:HI REG_SP)
5411 (match_operand:HI 1 "immediate_operand" "i,i")))
5412 (use (reg:HI REG_X))
5413 (clobber (reg:HI REG_Z))]
5415 "ldi r30,lo8(gs(1f))
5417 %~jmp __prologue_saves__+((18 - %0) * 2)
5419 [(set_attr "length" "5,6")
5420 (set_attr "cc" "clobber")
5421 (set_attr "isa" "rjmp,jmp")])
5423 ; epilogue restores using library
5424 (define_insn "epilogue_restores"
5425 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5427 (plus:HI (reg:HI REG_Y)
5428 (match_operand:HI 0 "immediate_operand" "i,i")))
5429 (set (reg:HI REG_SP)
5430 (plus:HI (reg:HI REG_Y)
5432 (clobber (reg:QI REG_Z))]
5435 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5436 [(set_attr "length" "2,3")
5437 (set_attr "cc" "clobber")
5438 (set_attr "isa" "rjmp,jmp")])
5441 (define_insn "return"
5443 "reload_completed && avr_simple_epilogue ()"
5445 [(set_attr "cc" "none")
5446 (set_attr "length" "1")])
5448 (define_insn "return_from_epilogue"
5452 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5453 && !cfun->machine->is_naked"
5455 [(set_attr "cc" "none")
5456 (set_attr "length" "1")])
5458 (define_insn "return_from_interrupt_epilogue"
5462 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5463 && !cfun->machine->is_naked"
5465 [(set_attr "cc" "none")
5466 (set_attr "length" "1")])
5468 (define_insn "return_from_naked_epilogue"
5472 && cfun->machine->is_naked"
5474 [(set_attr "cc" "none")
5475 (set_attr "length" "0")])
5477 (define_expand "prologue"
5485 (define_expand "epilogue"
5489 expand_epilogue (false /* sibcall_p */);
5493 (define_expand "sibcall_epilogue"
5497 expand_epilogue (true /* sibcall_p */);
5501 ;; Some instructions resp. instruction sequences available
5504 (define_insn "delay_cycles_1"
5505 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5507 UNSPECV_DELAY_CYCLES)
5508 (set (match_operand:BLK 1 "" "")
5509 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5510 (clobber (match_scratch:QI 2 "=&d"))]
5515 [(set_attr "length" "3")
5516 (set_attr "cc" "clobber")])
5518 (define_insn "delay_cycles_2"
5519 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5521 UNSPECV_DELAY_CYCLES)
5522 (set (match_operand:BLK 1 "" "")
5523 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5524 (clobber (match_scratch:HI 2 "=&w"))]
5530 [(set_attr "length" "4")
5531 (set_attr "cc" "clobber")])
5533 (define_insn "delay_cycles_3"
5534 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5536 UNSPECV_DELAY_CYCLES)
5537 (set (match_operand:BLK 1 "" "")
5538 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5539 (clobber (match_scratch:QI 2 "=&d"))
5540 (clobber (match_scratch:QI 3 "=&d"))
5541 (clobber (match_scratch:QI 4 "=&d"))]
5550 [(set_attr "length" "7")
5551 (set_attr "cc" "clobber")])
5553 (define_insn "delay_cycles_4"
5554 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5556 UNSPECV_DELAY_CYCLES)
5557 (set (match_operand:BLK 1 "" "")
5558 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5559 (clobber (match_scratch:QI 2 "=&d"))
5560 (clobber (match_scratch:QI 3 "=&d"))
5561 (clobber (match_scratch:QI 4 "=&d"))
5562 (clobber (match_scratch:QI 5 "=&d"))]
5573 [(set_attr "length" "9")
5574 (set_attr "cc" "clobber")])
5577 ;; __builtin_avr_insert_bits
5579 (define_insn "insert_bits"
5580 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5581 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5582 (match_operand:QI 2 "register_operand" "r ,r ,r")
5583 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5584 UNSPEC_INSERT_BITS))]
5587 return avr_out_insert_bits (operands, NULL);
5589 [(set_attr "adjust_len" "insert_bits")
5590 (set_attr "cc" "clobber")])
5593 ;; __builtin_avr_flash_segment
5595 ;; Just a helper for the next "official" expander.
5597 (define_expand "flash_segment1"
5598 [(set (match_operand:QI 0 "register_operand" "")
5599 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5602 (compare (match_dup 0)
5605 (if_then_else (ge (cc0)
5607 (label_ref (match_operand 2 "" ""))
5612 (define_expand "flash_segment"
5613 [(parallel [(match_operand:QI 0 "register_operand" "")
5614 (match_operand:PSI 1 "register_operand" "")])]
5617 rtx label = gen_label_rtx ();
5618 emit (gen_flash_segment1 (operands[0], operands[1], label));
5623 ;; Actually, it's too late now to work out address spaces known at compiletime.
5624 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5625 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5626 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5628 (define_insn_and_split "*split.flash_segment"
5629 [(set (match_operand:QI 0 "register_operand" "=d")
5630 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5631 (match_operand:HI 2 "register_operand" "r"))
5634 { gcc_unreachable(); }
5642 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5643 ;; better 8-bit parity recognition.
5645 (define_expand "parityhi2"
5646 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5647 (parity:HI (match_operand:HI 1 "register_operand" "")))
5648 (clobber (reg:HI 24))])])
5650 (define_insn_and_split "*parityhi2"
5651 [(set (match_operand:HI 0 "register_operand" "=r")
5652 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5653 (clobber (reg:HI 24))]
5655 { gcc_unreachable(); }
5660 (parity:HI (reg:HI 24)))
5664 (define_insn_and_split "*parityqihi2"
5665 [(set (match_operand:HI 0 "register_operand" "=r")
5666 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5667 (clobber (reg:HI 24))]
5669 { gcc_unreachable(); }
5674 (zero_extend:HI (parity:QI (reg:QI 24))))
5678 (define_expand "paritysi2"
5680 (match_operand:SI 1 "register_operand" ""))
5682 (truncate:HI (parity:SI (reg:SI 22))))
5685 (set (match_operand:SI 0 "register_operand" "")
5686 (zero_extend:SI (match_dup 2)))]
5689 operands[2] = gen_reg_rtx (HImode);
5692 (define_insn "*parityhi2.libgcc"
5694 (parity:HI (reg:HI 24)))]
5696 "%~call __parityhi2"
5697 [(set_attr "type" "xcall")
5698 (set_attr "cc" "clobber")])
5700 (define_insn "*parityqihi2.libgcc"
5702 (zero_extend:HI (parity:QI (reg:QI 24))))]
5704 "%~call __parityqi2"
5705 [(set_attr "type" "xcall")
5706 (set_attr "cc" "clobber")])
5708 (define_insn "*paritysihi2.libgcc"
5710 (truncate:HI (parity:SI (reg:SI 22))))]
5712 "%~call __paritysi2"
5713 [(set_attr "type" "xcall")
5714 (set_attr "cc" "clobber")])
5719 (define_expand "popcounthi2"
5721 (match_operand:HI 1 "register_operand" ""))
5723 (popcount:HI (reg:HI 24)))
5724 (set (match_operand:HI 0 "register_operand" "")
5729 (define_expand "popcountsi2"
5731 (match_operand:SI 1 "register_operand" ""))
5733 (truncate:HI (popcount:SI (reg:SI 22))))
5736 (set (match_operand:SI 0 "register_operand" "")
5737 (zero_extend:SI (match_dup 2)))]
5740 operands[2] = gen_reg_rtx (HImode);
5743 (define_insn "*popcounthi2.libgcc"
5745 (popcount:HI (reg:HI 24)))]
5747 "%~call __popcounthi2"
5748 [(set_attr "type" "xcall")
5749 (set_attr "cc" "clobber")])
5751 (define_insn "*popcountsi2.libgcc"
5753 (truncate:HI (popcount:SI (reg:SI 22))))]
5755 "%~call __popcountsi2"
5756 [(set_attr "type" "xcall")
5757 (set_attr "cc" "clobber")])
5759 (define_insn "*popcountqi2.libgcc"
5761 (popcount:QI (reg:QI 24)))]
5763 "%~call __popcountqi2"
5764 [(set_attr "type" "xcall")
5765 (set_attr "cc" "clobber")])
5767 (define_insn_and_split "*popcountqihi2.libgcc"
5769 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5774 (popcount:QI (reg:QI 24)))
5778 ;; Count Leading Zeros
5780 (define_expand "clzhi2"
5782 (match_operand:HI 1 "register_operand" ""))
5783 (parallel [(set (reg:HI 24)
5784 (clz:HI (reg:HI 24)))
5785 (clobber (reg:QI 26))])
5786 (set (match_operand:HI 0 "register_operand" "")
5789 (define_expand "clzsi2"
5791 (match_operand:SI 1 "register_operand" ""))
5792 (parallel [(set (reg:HI 24)
5793 (truncate:HI (clz:SI (reg:SI 22))))
5794 (clobber (reg:QI 26))])
5797 (set (match_operand:SI 0 "register_operand" "")
5798 (zero_extend:SI (match_dup 2)))]
5801 operands[2] = gen_reg_rtx (HImode);
5804 (define_insn "*clzhi2.libgcc"
5806 (clz:HI (reg:HI 24)))
5807 (clobber (reg:QI 26))]
5810 [(set_attr "type" "xcall")
5811 (set_attr "cc" "clobber")])
5813 (define_insn "*clzsihi2.libgcc"
5815 (truncate:HI (clz:SI (reg:SI 22))))
5816 (clobber (reg:QI 26))]
5819 [(set_attr "type" "xcall")
5820 (set_attr "cc" "clobber")])
5822 ;; Count Trailing Zeros
5824 (define_expand "ctzhi2"
5826 (match_operand:HI 1 "register_operand" ""))
5827 (parallel [(set (reg:HI 24)
5828 (ctz:HI (reg:HI 24)))
5829 (clobber (reg:QI 26))])
5830 (set (match_operand:HI 0 "register_operand" "")
5833 (define_expand "ctzsi2"
5835 (match_operand:SI 1 "register_operand" ""))
5836 (parallel [(set (reg:HI 24)
5837 (truncate:HI (ctz:SI (reg:SI 22))))
5838 (clobber (reg:QI 22))
5839 (clobber (reg:QI 26))])
5842 (set (match_operand:SI 0 "register_operand" "")
5843 (zero_extend:SI (match_dup 2)))]
5846 operands[2] = gen_reg_rtx (HImode);
5849 (define_insn "*ctzhi2.libgcc"
5851 (ctz:HI (reg:HI 24)))
5852 (clobber (reg:QI 26))]
5855 [(set_attr "type" "xcall")
5856 (set_attr "cc" "clobber")])
5858 (define_insn "*ctzsihi2.libgcc"
5860 (truncate:HI (ctz:SI (reg:SI 22))))
5861 (clobber (reg:QI 22))
5862 (clobber (reg:QI 26))]
5865 [(set_attr "type" "xcall")
5866 (set_attr "cc" "clobber")])
5870 (define_expand "ffshi2"
5872 (match_operand:HI 1 "register_operand" ""))
5873 (parallel [(set (reg:HI 24)
5874 (ffs:HI (reg:HI 24)))
5875 (clobber (reg:QI 26))])
5876 (set (match_operand:HI 0 "register_operand" "")
5879 (define_expand "ffssi2"
5881 (match_operand:SI 1 "register_operand" ""))
5882 (parallel [(set (reg:HI 24)
5883 (truncate:HI (ffs:SI (reg:SI 22))))
5884 (clobber (reg:QI 22))
5885 (clobber (reg:QI 26))])
5888 (set (match_operand:SI 0 "register_operand" "")
5889 (zero_extend:SI (match_dup 2)))]
5892 operands[2] = gen_reg_rtx (HImode);
5895 (define_insn "*ffshi2.libgcc"
5897 (ffs:HI (reg:HI 24)))
5898 (clobber (reg:QI 26))]
5901 [(set_attr "type" "xcall")
5902 (set_attr "cc" "clobber")])
5904 (define_insn "*ffssihi2.libgcc"
5906 (truncate:HI (ffs:SI (reg:SI 22))))
5907 (clobber (reg:QI 22))
5908 (clobber (reg:QI 26))]
5911 [(set_attr "type" "xcall")
5912 (set_attr "cc" "clobber")])
5916 (define_insn "copysignsf3"
5917 [(set (match_operand:SF 0 "register_operand" "=r")
5918 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5919 (match_operand:SF 2 "register_operand" "r")]
5922 "bst %D2,7\;bld %D0,7"
5923 [(set_attr "length" "2")
5924 (set_attr "cc" "none")])
5926 ;; Swap Bytes (change byte-endianess)
5928 (define_expand "bswapsi2"
5930 (match_operand:SI 1 "register_operand" ""))
5932 (bswap:SI (reg:SI 22)))
5933 (set (match_operand:SI 0 "register_operand" "")
5936 (define_insn "*bswapsi2.libgcc"
5938 (bswap:SI (reg:SI 22)))]
5941 [(set_attr "type" "xcall")
5942 (set_attr "cc" "clobber")])
5947 ;; NOP taking 1 or 2 Ticks
5948 (define_expand "nopv"
5949 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5952 (unspec_volatile:BLK [(match_dup 1)]
5953 UNSPECV_MEMORY_BARRIER))])]
5956 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5957 MEM_VOLATILE_P (operands[1]) = 1;
5960 (define_insn "*nopv"
5961 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5963 (set (match_operand:BLK 1 "" "")
5964 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5969 [(set_attr "length" "1")
5970 (set_attr "cc" "none")])
5973 (define_expand "sleep"
5974 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5976 (unspec_volatile:BLK [(match_dup 0)]
5977 UNSPECV_MEMORY_BARRIER))])]
5980 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5981 MEM_VOLATILE_P (operands[0]) = 1;
5984 (define_insn "*sleep"
5985 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5986 (set (match_operand:BLK 0 "" "")
5987 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
5990 [(set_attr "length" "1")
5991 (set_attr "cc" "none")])
5994 (define_expand "wdr"
5995 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5997 (unspec_volatile:BLK [(match_dup 0)]
5998 UNSPECV_MEMORY_BARRIER))])]
6001 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6002 MEM_VOLATILE_P (operands[0]) = 1;
6006 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6007 (set (match_operand:BLK 0 "" "")
6008 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6011 [(set_attr "length" "1")
6012 (set_attr "cc" "none")])
6015 (define_expand "fmul"
6017 (match_operand:QI 1 "register_operand" ""))
6019 (match_operand:QI 2 "register_operand" ""))
6020 (parallel [(set (reg:HI 22)
6021 (unspec:HI [(reg:QI 24)
6022 (reg:QI 25)] UNSPEC_FMUL))
6023 (clobber (reg:HI 24))])
6024 (set (match_operand:HI 0 "register_operand" "")
6030 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6035 (define_insn "fmul_insn"
6036 [(set (match_operand:HI 0 "register_operand" "=r")
6037 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6038 (match_operand:QI 2 "register_operand" "a")]
6044 [(set_attr "length" "3")
6045 (set_attr "cc" "clobber")])
6047 (define_insn "*fmul.call"
6049 (unspec:HI [(reg:QI 24)
6050 (reg:QI 25)] UNSPEC_FMUL))
6051 (clobber (reg:HI 24))]
6054 [(set_attr "type" "xcall")
6055 (set_attr "cc" "clobber")])
6058 (define_expand "fmuls"
6060 (match_operand:QI 1 "register_operand" ""))
6062 (match_operand:QI 2 "register_operand" ""))
6063 (parallel [(set (reg:HI 22)
6064 (unspec:HI [(reg:QI 24)
6065 (reg:QI 25)] UNSPEC_FMULS))
6066 (clobber (reg:HI 24))])
6067 (set (match_operand:HI 0 "register_operand" "")
6073 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6078 (define_insn "fmuls_insn"
6079 [(set (match_operand:HI 0 "register_operand" "=r")
6080 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6081 (match_operand:QI 2 "register_operand" "a")]
6087 [(set_attr "length" "3")
6088 (set_attr "cc" "clobber")])
6090 (define_insn "*fmuls.call"
6092 (unspec:HI [(reg:QI 24)
6093 (reg:QI 25)] UNSPEC_FMULS))
6094 (clobber (reg:HI 24))]
6097 [(set_attr "type" "xcall")
6098 (set_attr "cc" "clobber")])
6101 (define_expand "fmulsu"
6103 (match_operand:QI 1 "register_operand" ""))
6105 (match_operand:QI 2 "register_operand" ""))
6106 (parallel [(set (reg:HI 22)
6107 (unspec:HI [(reg:QI 24)
6108 (reg:QI 25)] UNSPEC_FMULSU))
6109 (clobber (reg:HI 24))])
6110 (set (match_operand:HI 0 "register_operand" "")
6116 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6121 (define_insn "fmulsu_insn"
6122 [(set (match_operand:HI 0 "register_operand" "=r")
6123 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6124 (match_operand:QI 2 "register_operand" "a")]
6130 [(set_attr "length" "3")
6131 (set_attr "cc" "clobber")])
6133 (define_insn "*fmulsu.call"
6135 (unspec:HI [(reg:QI 24)
6136 (reg:QI 25)] UNSPEC_FMULSU))
6137 (clobber (reg:HI 24))]
6140 [(set_attr "type" "xcall")
6141 (set_attr "cc" "clobber")])
6144 ;; Some combiner patterns dealing with bits.
6147 ;; Move bit $3.0 into bit $0.$4
6148 (define_insn "*movbitqi.1-6.a"
6149 [(set (match_operand:QI 0 "register_operand" "=r")
6150 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6151 (match_operand:QI 2 "single_zero_operand" "n"))
6152 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6153 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6154 (match_operand:QI 5 "single_one_operand" "n"))))]
6155 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6156 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6157 "bst %3,0\;bld %0,%4"
6158 [(set_attr "length" "2")
6159 (set_attr "cc" "none")])
6161 ;; Move bit $3.0 into bit $0.$4
6162 ;; Variation of above. Unfortunately, there is no canonicalized representation
6163 ;; of moving around bits. So what we see here depends on how user writes down
6164 ;; bit manipulations.
6165 (define_insn "*movbitqi.1-6.b"
6166 [(set (match_operand:QI 0 "register_operand" "=r")
6167 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6168 (match_operand:QI 2 "single_zero_operand" "n"))
6169 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6171 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6172 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6173 "bst %3,0\;bld %0,%4"
6174 [(set_attr "length" "2")
6175 (set_attr "cc" "none")])
6177 ;; Move bit $3.0 into bit $0.0.
6178 ;; For bit 0, combiner generates slightly different pattern.
6179 (define_insn "*movbitqi.0"
6180 [(set (match_operand:QI 0 "register_operand" "=r")
6181 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6182 (match_operand:QI 2 "single_zero_operand" "n"))
6183 (and:QI (match_operand:QI 3 "register_operand" "r")
6185 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6186 "bst %3,0\;bld %0,0"
6187 [(set_attr "length" "2")
6188 (set_attr "cc" "none")])
6190 ;; Move bit $2.0 into bit $0.7.
6191 ;; For bit 7, combiner generates slightly different pattern
6192 (define_insn "*movbitqi.7"
6193 [(set (match_operand:QI 0 "register_operand" "=r")
6194 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6196 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6199 "bst %2,0\;bld %0,7"
6200 [(set_attr "length" "2")
6201 (set_attr "cc" "none")])
6203 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6204 ;; and input/output match. We provide a special pattern for this, because
6205 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6206 ;; operation on I/O is atomic.
6207 (define_insn "*insv.io"
6208 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6210 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6211 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6216 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6217 [(set_attr "length" "1,1,4")
6218 (set_attr "cc" "none")])
6220 (define_insn "*insv.not.io"
6221 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6223 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6224 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6226 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6227 [(set_attr "length" "4")
6228 (set_attr "cc" "none")])
6230 ;; The insv expander.
6231 ;; We only support 1-bit inserts
6232 (define_expand "insv"
6233 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6234 (match_operand:QI 1 "const1_operand" "") ; width
6235 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6236 (match_operand:QI 3 "nonmemory_operand" ""))]
6239 ;; Insert bit $2.0 into $0.$1
6240 (define_insn "*insv.reg"
6241 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6243 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6244 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6248 andi %0,lo8(~(1<<%1))
6252 [(set_attr "length" "2,1,1,2,2")
6253 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6256 ;; Some combine patterns that try to fix bad code when a value is composed
6257 ;; from byte parts like in PR27663.
6258 ;; The patterns give some release but the code still is not optimal,
6259 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6260 ;; That switch obfuscates things here and in many other places.
6262 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6263 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6264 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6265 [(set (match_operand:HISI 0 "register_operand" "=r")
6267 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6268 (match_operand:HISI 2 "register_operand" "0")))]
6273 (xior:QI (match_dup 3)
6276 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6279 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6280 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6281 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6282 [(set (match_operand:HISI 0 "register_operand" "=r")
6284 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6285 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6286 (match_operand:HISI 3 "register_operand" "0")))]
6287 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6289 "&& reload_completed"
6291 (xior:QI (match_dup 4)
6294 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6295 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6298 (define_expand "extzv"
6299 [(set (match_operand:QI 0 "register_operand" "")
6300 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6301 (match_operand:QI 2 "const1_operand" "")
6302 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6304 (define_insn "*extzv"
6305 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6306 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6308 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6312 mov %0,%1\;andi %0,1
6315 bst %1,%2\;clr %0\;bld %0,0"
6316 [(set_attr "length" "1,2,2,2,3")
6317 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6319 (define_insn_and_split "*extzv.qihi1"
6320 [(set (match_operand:HI 0 "register_operand" "=r")
6321 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6323 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6328 (zero_extract:QI (match_dup 1)
6334 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6335 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6338 (define_insn_and_split "*extzv.qihi2"
6339 [(set (match_operand:HI 0 "register_operand" "=r")
6341 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6343 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6348 (zero_extract:QI (match_dup 1)
6354 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6355 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6359 ;; Fixed-point instructions
6360 (include "avr-fixed.md")
6362 ;; Operations on 64-bit registers
6363 (include "avr-dimode.md")