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,
94 out_plus, out_plus_noclobber,ldi,minus"
95 (const_string "none"))
97 (define_attr "type" "branch,branch1,arith,xcall"
98 (const_string "arith"))
100 ;; The size of instructions in bytes.
101 ;; XXX may depend from "cc"
103 (define_attr "length" ""
104 (cond [(eq_attr "type" "branch")
105 (if_then_else (and (ge (minus (pc) (match_dup 0))
107 (le (minus (pc) (match_dup 0))
110 (if_then_else (and (ge (minus (pc) (match_dup 0))
112 (le (minus (pc) (match_dup 0))
116 (eq_attr "type" "branch1")
117 (if_then_else (and (ge (minus (pc) (match_dup 0))
119 (le (minus (pc) (match_dup 0))
122 (if_then_else (and (ge (minus (pc) (match_dup 0))
124 (le (minus (pc) (match_dup 0))
128 (eq_attr "type" "xcall")
129 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
134 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
135 ;; Following insn attribute tells if and how the adjustment has to be
137 ;; no No adjustment needed; attribute "length" is fine.
138 ;; Otherwise do special processing depending on the attribute.
140 (define_attr "adjust_len"
141 "out_bitop, out_plus, out_plus_noclobber, plus64, addto_sp,
143 tsthi, tstpsi, tstsi, compare, compare64, call,
144 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
146 xload, movmem, load_lpm,
147 ashlqi, ashrqi, lshrqi,
148 ashlhi, ashrhi, lshrhi,
149 ashlsi, ashrsi, lshrsi,
150 ashlpsi, ashrpsi, lshrpsi,
155 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
157 ;; mov : ISA has no MOVW movw : ISA has MOVW
158 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
159 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
160 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
161 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
162 ;; no_xmega: non-XMEGA core xmega : XMEGA core
165 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
167 (const_string "standard"))
169 (define_attr "enabled" ""
170 (cond [(eq_attr "isa" "standard")
173 (and (eq_attr "isa" "mov")
174 (match_test "!AVR_HAVE_MOVW"))
177 (and (eq_attr "isa" "movw")
178 (match_test "AVR_HAVE_MOVW"))
181 (and (eq_attr "isa" "rjmp")
182 (match_test "!AVR_HAVE_JMP_CALL"))
185 (and (eq_attr "isa" "jmp")
186 (match_test "AVR_HAVE_JMP_CALL"))
189 (and (eq_attr "isa" "ijmp")
190 (match_test "!AVR_HAVE_EIJMP_EICALL"))
193 (and (eq_attr "isa" "eijmp")
194 (match_test "AVR_HAVE_EIJMP_EICALL"))
197 (and (eq_attr "isa" "lpm")
198 (match_test "!AVR_HAVE_LPMX"))
201 (and (eq_attr "isa" "lpmx")
202 (match_test "AVR_HAVE_LPMX"))
205 (and (eq_attr "isa" "elpm")
206 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
209 (and (eq_attr "isa" "elpmx")
210 (match_test "AVR_HAVE_ELPMX"))
213 (and (eq_attr "isa" "xmega")
214 (match_test "AVR_XMEGA"))
217 (and (eq_attr "isa" "no_xmega")
218 (match_test "!AVR_XMEGA"))
223 ;; Define mode iterators
224 (define_mode_iterator QIHI [(QI "") (HI "")])
225 (define_mode_iterator QIHI2 [(QI "") (HI "")])
226 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
227 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
228 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
230 (define_mode_iterator ALL1 [(QI "") (QQ "") (UQQ "")])
231 (define_mode_iterator ALL2 [(HI "") (HQ "") (UHQ "") (HA "") (UHA "")])
232 (define_mode_iterator ALL4 [(SI "") (SQ "") (USQ "") (SA "") (USA "")])
234 ;; All supported move-modes
235 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")
237 (HQ "") (UHQ "") (HA "") (UHA "")
238 (SQ "") (USQ "") (SA "") (USA "")])
240 ;; Supported ordered modes that are 2, 3, 4 bytes wide
241 (define_mode_iterator ORDERED234 [(HI "") (SI "") (PSI "")
242 (HQ "") (UHQ "") (HA "") (UHA "")
243 (SQ "") (USQ "") (SA "") (USA "")])
245 ;; Define code iterators
246 ;; Define two incarnations so that we can build the cross product.
247 (define_code_iterator any_extend [sign_extend zero_extend])
248 (define_code_iterator any_extend2 [sign_extend zero_extend])
250 (define_code_iterator xior [xor ior])
251 (define_code_iterator eqne [eq ne])
253 ;; Define code attributes
254 (define_code_attr extend_su
258 (define_code_attr extend_u
262 (define_code_attr extend_s
266 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
267 (define_code_attr mul_r_d
271 ;; Map RTX code to its standard insn name
272 (define_code_attr code_stdname
280 ;;========================================================================
281 ;; The following is used by nonlocal_goto and setjmp.
282 ;; The receiver pattern will create no instructions since internally
283 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
284 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
285 ;; The 'null' receiver also avoids problems with optimisation
286 ;; not recognising incoming jmp and removing code that resets frame_pointer.
287 ;; The code derived from builtins.c.
289 (define_expand "nonlocal_goto_receiver"
291 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
294 emit_move_insn (virtual_stack_vars_rtx,
295 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
296 gen_int_mode (STARTING_FRAME_OFFSET,
298 /* This might change the hard frame pointer in ways that aren't
299 apparent to early optimization passes, so force a clobber. */
300 emit_clobber (hard_frame_pointer_rtx);
305 ;; Defining nonlocal_goto_receiver means we must also define this.
306 ;; even though its function is identical to that in builtins.c
308 (define_expand "nonlocal_goto"
309 [(use (match_operand 0 "general_operand"))
310 (use (match_operand 1 "general_operand"))
311 (use (match_operand 2 "general_operand"))
312 (use (match_operand 3 "general_operand"))]
315 rtx r_label = copy_to_reg (operands[1]);
316 rtx r_fp = operands[3];
317 rtx r_sp = operands[2];
319 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
321 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
323 emit_move_insn (hard_frame_pointer_rtx, r_fp);
324 emit_stack_restore (SAVE_NONLOCAL, r_sp);
326 emit_use (hard_frame_pointer_rtx);
327 emit_use (stack_pointer_rtx);
329 emit_indirect_jump (r_label);
335 ;; "pushqq1" "pushuqq1"
336 (define_insn "push<mode>1"
337 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
338 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
343 [(set_attr "length" "1,1")])
345 ;; All modes for a multi-byte push. We must include complex modes here too,
346 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
347 (define_mode_iterator MPUSH
354 (HA "") (UHA "") (HQ "") (UHQ "")
355 (SA "") (USA "") (SQ "") (USQ "")
356 (DA "") (UDA "") (DQ "") (UDQ "")
359 (define_expand "push<mode>1"
360 [(match_operand:MPUSH 0 "" "")]
364 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
366 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
367 if (part != const0_rtx)
368 part = force_reg (QImode, part);
369 emit_insn (gen_pushqi1 (part));
374 ;; Notice a special-case when adding N to SP where N results in a
375 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
377 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
379 && frame_pointer_needed
380 && !cfun->calls_alloca
381 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
382 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
385 ;;========================================================================
388 ;; Represent a load from __flash that needs libgcc support as UNSPEC.
389 ;; This is legal because we read from non-changing memory.
390 ;; For rationale see the FIXME below.
395 (define_insn "load_<mode>_libgcc"
396 [(set (reg:MOVMODE 22)
397 (unspec:MOVMODE [(reg:HI REG_Z)]
401 rtx n_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
402 output_asm_insn ("%~call __load_%0", &n_bytes);
405 [(set_attr "type" "xcall")
406 (set_attr "cc" "clobber")])
409 ;; Similar for inline reads from flash. We use UNSPEC instead
410 ;; of MEM for the same reason as above: PR52543.
411 ;; $1 contains the memory segment.
413 (define_insn "load_<mode>"
414 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
415 (unspec:MOVMODE [(reg:HI REG_Z)
416 (match_operand:QI 1 "reg_or_0_operand" "rL")]
418 "(CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
419 || (REG_P (operands[1]) && AVR_HAVE_ELPMX)"
421 return avr_load_lpm (insn, operands, NULL);
423 [(set_attr "adjust_len" "load_lpm")
424 (set_attr "cc" "clobber")])
427 ;; Similar to above for the complementary situation when there is no [E]LPMx.
428 ;; Clobber Z in that case.
430 (define_insn "load_<mode>_clobber"
431 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
432 (unspec:MOVMODE [(reg:HI REG_Z)
433 (match_operand:QI 1 "reg_or_0_operand" "rL")]
435 (clobber (reg:HI REG_Z))]
436 "!((CONST_INT_P (operands[1]) && AVR_HAVE_LPMX)
437 || (REG_P (operands[1]) && AVR_HAVE_ELPMX))"
439 return avr_load_lpm (insn, operands, NULL);
441 [(set_attr "adjust_len" "load_lpm")
442 (set_attr "cc" "clobber")])
446 ;; "xload8qq_A" "xload8uqq_A"
447 (define_insn_and_split "xload8<mode>_A"
448 [(set (match_operand:ALL1 0 "register_operand" "=r")
449 (match_operand:ALL1 1 "memory_operand" "m"))
450 (clobber (reg:HI REG_Z))]
451 "can_create_pseudo_p()
452 && !avr_xload_libgcc_p (<MODE>mode)
453 && avr_mem_memx_p (operands[1])
454 && REG_P (XEXP (operands[1], 0))"
455 { gcc_unreachable(); }
457 [(clobber (const_int 0))]
459 rtx insn, addr = XEXP (operands[1], 0);
460 rtx hi8 = gen_reg_rtx (QImode);
461 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
463 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
464 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
466 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
467 set_mem_addr_space (SET_SRC (single_set (insn)),
468 MEM_ADDR_SPACE (operands[1]));
472 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
473 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
474 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
477 (define_insn_and_split "xload<mode>_A"
478 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
479 (match_operand:MOVMODE 1 "memory_operand" "m"))
480 (clobber (reg:MOVMODE 22))
481 (clobber (reg:QI 21))
482 (clobber (reg:HI REG_Z))]
483 "can_create_pseudo_p()
484 && avr_mem_memx_p (operands[1])
485 && REG_P (XEXP (operands[1], 0))"
486 { gcc_unreachable(); }
488 [(clobber (const_int 0))]
490 rtx addr = XEXP (operands[1], 0);
491 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
492 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
493 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
496 /* Split the address to R21:Z */
497 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
498 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
500 /* Load with code from libgcc */
501 insn = emit_insn (gen_xload_<mode>_libgcc ());
502 set_mem_addr_space (SET_SRC (single_set (insn)), as);
504 /* Move to destination */
505 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
510 ;; Move value from address space memx to a register
511 ;; These insns must be prior to respective generic move insn.
514 ;; "xloadqq_8" "xloaduqq_8"
515 (define_insn "xload<mode>_8"
516 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
517 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
519 "!avr_xload_libgcc_p (<MODE>mode)"
521 return avr_out_xload (insn, operands, NULL);
523 [(set_attr "length" "4,4")
524 (set_attr "adjust_len" "*,xload")
525 (set_attr "isa" "lpmx,lpm")
526 (set_attr "cc" "none")])
528 ;; R21:Z : 24-bit source address
529 ;; R22 : 1-4 byte output
531 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
532 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
533 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
535 ;; "xload_psi_libgcc"
536 (define_insn "xload_<mode>_libgcc"
537 [(set (reg:MOVMODE 22)
538 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
540 (clobber (reg:QI 21))
541 (clobber (reg:HI REG_Z))]
542 "avr_xload_libgcc_p (<MODE>mode)"
544 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
546 output_asm_insn ("%~call __xload_%0", &x_bytes);
549 [(set_attr "type" "xcall")
550 (set_attr "cc" "clobber")])
553 ;; General move expanders
555 ;; "movqi" "movqq" "movuqq"
556 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
557 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
560 (define_expand "mov<mode>"
561 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
562 (match_operand:MOVMODE 1 "general_operand" ""))]
565 rtx dest = operands[0];
566 rtx src = operands[1];
568 if (avr_mem_flash_p (dest))
571 /* One of the operands has to be in a register. */
572 if (!register_operand (dest, <MODE>mode)
573 && !reg_or_0_operand (src, <MODE>mode))
575 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
578 if (avr_mem_memx_p (src))
580 rtx addr = XEXP (src, 0);
583 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
585 if (!avr_xload_libgcc_p (<MODE>mode))
586 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
587 ; insn-emit does not depend on the mode, it' all about operands. */
588 emit_insn (gen_xload8qi_A (dest, src));
590 emit_insn (gen_xload<mode>_A (dest, src));
595 /* For old devices without LPMx, prefer __flash loads per libcall. */
597 if (avr_load_libgcc_p (src))
599 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
600 force_reg (Pmode, XEXP (src, 0)));
602 emit_insn (gen_load_<mode>_libgcc ());
603 emit_move_insn (dest, gen_rtx_REG (<MODE>mode, 22));
607 /* ; FIXME: Hack around PR rtl-optimization/52543.
608 ; lower-subreg.c splits loads from the 16-bit address spaces which
609 ; causes code bloat because each load need his setting of RAMPZ.
610 ; Moreover, the split will happen in such a way that the loads don't
611 ; take advantage of POST_INC addressing. Thus, we use UNSPEC to
612 ; represent these loads instead. Notice that this is legitimate
613 ; because the memory content does not change: Loads from the same
614 ; address will yield the same value.
615 ; POST_INC addressing would make the addresses mode_dependent and could
616 ; work around that PR, too. However, notice that it is *not* legitimate
617 ; to expand to POST_INC at expand time: The following passes assert
618 ; that pre-/post-modify addressing is introduced by .auto_inc_dec and
619 ; does not exist before that pass. */
621 if (avr_mem_flash_p (src)
622 && (GET_MODE_SIZE (<MODE>mode) > 1
623 || MEM_ADDR_SPACE (src) != ADDR_SPACE_FLASH))
625 rtx xsegment = GEN_INT (avr_addrspace[MEM_ADDR_SPACE (src)].segment);
627 xsegment = const0_rtx;
628 if (xsegment != const0_rtx)
629 xsegment = force_reg (QImode, xsegment);
631 emit_move_insn (gen_rtx_REG (Pmode, REG_Z),
632 force_reg (Pmode, XEXP (src, 0)));
634 if ((CONST_INT_P (xsegment) && AVR_HAVE_LPMX)
635 || (REG_P (xsegment) && AVR_HAVE_ELPMX))
636 emit_insn (gen_load_<mode> (dest, xsegment));
638 emit_insn (gen_load_<mode>_clobber (dest, xsegment));
642 /* ; The only address-space for which we use plain MEM and reload
643 ; machinery are 1-byte loads from __flash. */
646 ;;========================================================================
648 ;; The last alternative (any immediate constant to any register) is
649 ;; very expensive. It should be optimized by peephole2 if a scratch
650 ;; register is available, but then that register could just as well be
651 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
652 ;; are call-saved registers, and most of LD_REGS are call-used registers,
653 ;; so this may still be a win for registers live across function calls.
656 ;; "movqq_insn" "movuqq_insn"
657 (define_insn "mov<mode>_insn"
658 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
659 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
660 "register_operand (operands[0], <MODE>mode)
661 || reg_or_0_operand (operands[1], <MODE>mode)"
663 return output_movqi (insn, operands, NULL);
665 [(set_attr "length" "1,1,5,5,1,1,4")
666 (set_attr "adjust_len" "mov8")
667 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
669 ;; This is used in peephole2 to optimize loading immediate constants
670 ;; if a scratch register from LD_REGS happens to be available.
673 ;; "*reload_inqq" "*reload_inuqq"
674 (define_insn "*reload_in<mode>"
675 [(set (match_operand:ALL1 0 "register_operand" "=l")
676 (match_operand:ALL1 1 "const_operand" "i"))
677 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
681 [(set_attr "length" "2")
682 (set_attr "cc" "none")])
685 [(match_scratch:QI 2 "d")
686 (set (match_operand:ALL1 0 "l_register_operand" "")
687 (match_operand:ALL1 1 "const_operand" ""))]
688 ; No need for a clobber reg for 0x0, 0x01 or 0xff
689 "!satisfies_constraint_Y00 (operands[1])
690 && !satisfies_constraint_Y01 (operands[1])
691 && !satisfies_constraint_Ym1 (operands[1])"
692 [(parallel [(set (match_dup 0)
694 (clobber (match_dup 2))])])
696 ;;============================================================================
697 ;; move word (16 bit)
699 ;; Move register $1 to the Stack Pointer register SP.
700 ;; This insn is emit during function prologue/epilogue generation.
701 ;; $2 = 0: We know that IRQs are off
702 ;; $2 = 1: We know that IRQs are on
703 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
704 ;; $2 = -1: We don't know anything about IRQ on/off
705 ;; Always write SP via unspec, see PR50063
707 (define_insn "movhi_sp_r"
708 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
709 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
710 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
714 out %B0,%B1\;out %A0,%A1
715 cli\;out %B0,%B1\;sei\;out %A0,%A1
716 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
718 out %A0,%A1\;out %B0,%B1"
719 [(set_attr "length" "2,4,5,1,2")
720 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
721 (set_attr "cc" "none")])
724 [(match_scratch:QI 2 "d")
725 (set (match_operand:ALL2 0 "l_register_operand" "")
726 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
727 "operands[1] != CONST0_RTX (<MODE>mode)"
728 [(parallel [(set (match_dup 0)
730 (clobber (match_dup 2))])])
732 ;; '*' because it is not used in rtl generation, only in above peephole
734 ;; "*reload_inhq" "*reload_inuhq"
735 ;; "*reload_inha" "*reload_inuha"
736 (define_insn "*reload_in<mode>"
737 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
738 (match_operand:ALL2 1 "immediate_operand" "i"))
739 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
742 return output_reload_inhi (operands, operands[2], NULL);
744 [(set_attr "length" "4")
745 (set_attr "adjust_len" "reload_in16")
746 (set_attr "cc" "clobber")])
749 ;; "*movhq" "*movuhq"
750 ;; "*movha" "*movuha"
751 (define_insn "*mov<mode>"
752 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
753 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
754 "register_operand (operands[0], <MODE>mode)
755 || reg_or_0_operand (operands[1], <MODE>mode)"
757 return output_movhi (insn, operands, NULL);
759 [(set_attr "length" "2,2,6,7,2,6,5,2")
760 (set_attr "adjust_len" "mov16")
761 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
763 (define_peephole2 ; movw
764 [(set (match_operand:ALL1 0 "even_register_operand" "")
765 (match_operand:ALL1 1 "even_register_operand" ""))
766 (set (match_operand:ALL1 2 "odd_register_operand" "")
767 (match_operand:ALL1 3 "odd_register_operand" ""))]
769 && REGNO (operands[0]) == REGNO (operands[2]) - 1
770 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
774 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
775 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
778 (define_peephole2 ; movw_r
779 [(set (match_operand:ALL1 0 "odd_register_operand" "")
780 (match_operand:ALL1 1 "odd_register_operand" ""))
781 (set (match_operand:ALL1 2 "even_register_operand" "")
782 (match_operand:ALL1 3 "even_register_operand" ""))]
784 && REGNO (operands[2]) == REGNO (operands[0]) - 1
785 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
789 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
790 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
793 ;;==========================================================================
794 ;; xpointer move (24 bit)
796 (define_peephole2 ; *reload_inpsi
797 [(match_scratch:QI 2 "d")
798 (set (match_operand:PSI 0 "l_register_operand" "")
799 (match_operand:PSI 1 "immediate_operand" ""))
801 "operands[1] != const0_rtx
802 && operands[1] != constm1_rtx"
803 [(parallel [(set (match_dup 0)
805 (clobber (match_dup 2))])]
808 ;; '*' because it is not used in rtl generation.
809 (define_insn "*reload_inpsi"
810 [(set (match_operand:PSI 0 "register_operand" "=r")
811 (match_operand:PSI 1 "immediate_operand" "i"))
812 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
815 return avr_out_reload_inpsi (operands, operands[2], NULL);
817 [(set_attr "length" "6")
818 (set_attr "adjust_len" "reload_in24")
819 (set_attr "cc" "clobber")])
821 (define_insn "*movpsi"
822 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
823 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
824 "register_operand (operands[0], PSImode)
825 || register_operand (operands[1], PSImode)
826 || const0_rtx == operands[1]"
828 return avr_out_movpsi (insn, operands, NULL);
830 [(set_attr "length" "3,3,8,9,4,10")
831 (set_attr "adjust_len" "mov24")
832 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
834 ;;==========================================================================
835 ;; move double word (32 bit)
837 (define_peephole2 ; *reload_insi
838 [(match_scratch:QI 2 "d")
839 (set (match_operand:ALL4 0 "l_register_operand" "")
840 (match_operand:ALL4 1 "immediate_operand" ""))
842 "operands[1] != CONST0_RTX (<MODE>mode)"
843 [(parallel [(set (match_dup 0)
845 (clobber (match_dup 2))])])
847 ;; '*' because it is not used in rtl generation.
849 ;; "*reload_insq" "*reload_inusq"
850 ;; "*reload_insa" "*reload_inusa"
851 (define_insn "*reload_insi"
852 [(set (match_operand:ALL4 0 "register_operand" "=r")
853 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
854 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
857 return output_reload_insisf (operands, operands[2], NULL);
859 [(set_attr "length" "8")
860 (set_attr "adjust_len" "reload_in32")
861 (set_attr "cc" "clobber")])
865 ;; "*movsq" "*movusq"
866 ;; "*movsa" "*movusa"
867 (define_insn "*mov<mode>"
868 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
869 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
870 "register_operand (operands[0], <MODE>mode)
871 || reg_or_0_operand (operands[1], <MODE>mode)"
873 return output_movsisf (insn, operands, NULL);
875 [(set_attr "length" "4,4,8,9,4,10")
876 (set_attr "adjust_len" "mov32")
877 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
879 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
880 ;; move floating point numbers (32 bit)
882 (define_insn "*movsf"
883 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
884 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
885 "register_operand (operands[0], SFmode)
886 || reg_or_0_operand (operands[1], SFmode)"
888 return output_movsisf (insn, operands, NULL);
890 [(set_attr "length" "4,4,8,9,4,10")
891 (set_attr "adjust_len" "mov32")
892 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
894 (define_peephole2 ; *reload_insf
895 [(match_scratch:QI 2 "d")
896 (set (match_operand:SF 0 "l_register_operand" "")
897 (match_operand:SF 1 "const_double_operand" ""))
899 "operands[1] != CONST0_RTX (SFmode)"
900 [(parallel [(set (match_dup 0)
902 (clobber (match_dup 2))])])
904 ;; '*' because it is not used in rtl generation.
905 (define_insn "*reload_insf"
906 [(set (match_operand:SF 0 "register_operand" "=r")
907 (match_operand:SF 1 "const_double_operand" "F"))
908 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
911 return output_reload_insisf (operands, operands[2], NULL);
913 [(set_attr "length" "8")
914 (set_attr "adjust_len" "reload_in32")
915 (set_attr "cc" "clobber")])
917 ;;=========================================================================
918 ;; move string (like memcpy)
920 (define_expand "movmemhi"
921 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
922 (match_operand:BLK 1 "memory_operand" ""))
923 (use (match_operand:HI 2 "const_int_operand" ""))
924 (use (match_operand:HI 3 "const_int_operand" ""))])]
927 if (avr_emit_movmemhi (operands))
933 (define_mode_attr MOVMEM_r_d [(QI "r")
936 ;; $0 : Address Space
937 ;; $1, $2 : Loop register
938 ;; R30 : source address
939 ;; R26 : destination address
943 (define_insn "movmem_<mode>"
944 [(set (mem:BLK (reg:HI REG_X))
945 (mem:BLK (reg:HI REG_Z)))
946 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
948 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
949 (clobber (reg:HI REG_X))
950 (clobber (reg:HI REG_Z))
951 (clobber (reg:QI LPM_REGNO))
952 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
955 return avr_out_movmem (insn, operands, NULL);
957 [(set_attr "adjust_len" "movmem")
958 (set_attr "cc" "clobber")])
961 ;; $0 : Address Space
962 ;; $1 : RAMPZ RAM address
963 ;; R24 : #bytes and loop register
964 ;; R23:Z : 24-bit source address
965 ;; R26 : 16-bit destination address
969 (define_insn "movmemx_<mode>"
970 [(set (mem:BLK (reg:HI REG_X))
971 (mem:BLK (lo_sum:PSI (reg:QI 23)
973 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
976 (clobber (reg:HI REG_X))
977 (clobber (reg:HI REG_Z))
978 (clobber (reg:QI LPM_REGNO))
979 (clobber (reg:HI 24))
980 (clobber (reg:QI 23))
981 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
983 "%~call __movmemx_<mode>"
984 [(set_attr "type" "xcall")
985 (set_attr "cc" "clobber")])
988 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
989 ;; memset (%0, %2, %1)
991 (define_expand "setmemhi"
992 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
993 (match_operand 2 "const_int_operand" ""))
994 (use (match_operand:HI 1 "const_int_operand" ""))
995 (use (match_operand:HI 3 "const_int_operand" ""))
996 (clobber (match_scratch:HI 4 ""))
997 (clobber (match_dup 5))])]
1001 enum machine_mode mode;
1003 /* If value to set is not zero, use the library routine. */
1004 if (operands[2] != const0_rtx)
1007 if (!CONST_INT_P (operands[1]))
1010 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1011 operands[5] = gen_rtx_SCRATCH (mode);
1012 operands[1] = copy_to_mode_reg (mode,
1013 gen_int_mode (INTVAL (operands[1]), mode));
1014 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1015 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1019 (define_insn "*clrmemqi"
1020 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1022 (use (match_operand:QI 1 "register_operand" "r"))
1023 (use (match_operand:QI 2 "const_int_operand" "n"))
1024 (clobber (match_scratch:HI 3 "=0"))
1025 (clobber (match_scratch:QI 4 "=&1"))]
1027 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1028 [(set_attr "length" "3")
1029 (set_attr "cc" "clobber")])
1032 (define_insn "*clrmemhi"
1033 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1035 (use (match_operand:HI 1 "register_operand" "!w,d"))
1036 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1037 (clobber (match_scratch:HI 3 "=0,0"))
1038 (clobber (match_scratch:HI 4 "=&1,&1"))]
1041 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1042 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1043 [(set_attr "length" "3,4")
1044 (set_attr "cc" "clobber,clobber")])
1046 (define_expand "strlenhi"
1048 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1049 (match_operand:QI 2 "const_int_operand" "")
1050 (match_operand:HI 3 "immediate_operand" "")]
1053 (plus:HI (match_dup 4)
1055 (parallel [(set (match_operand:HI 0 "register_operand" "")
1056 (minus:HI (match_dup 4)
1058 (clobber (scratch:QI))])]
1062 if (operands[2] != const0_rtx)
1064 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1065 operands[1] = gen_rtx_MEM (BLKmode, addr);
1067 operands[4] = gen_reg_rtx (HImode);
1070 (define_insn "*strlenhi"
1071 [(set (match_operand:HI 0 "register_operand" "=e")
1072 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1074 (match_operand:HI 2 "immediate_operand" "i")]
1077 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1078 [(set_attr "length" "3")
1079 (set_attr "cc" "clobber")])
1081 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1085 ;; "addqq3" "adduqq3"
1086 (define_insn "add<mode>3"
1087 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1088 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1089 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1098 [(set_attr "length" "1,1,1,1,2,2")
1099 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1102 ;; "addhq3" "adduhq3"
1103 ;; "addha3" "adduha3"
1104 (define_expand "add<mode>3"
1105 [(set (match_operand:ALL2 0 "register_operand" "")
1106 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1107 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1110 if (CONST_INT_P (operands[2]))
1112 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1114 if (can_create_pseudo_p()
1115 && !stack_register_operand (operands[0], HImode)
1116 && !stack_register_operand (operands[1], HImode)
1117 && !d_register_operand (operands[0], HImode)
1118 && !d_register_operand (operands[1], HImode))
1120 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1125 if (CONST_FIXED == GET_CODE (operands[2]))
1127 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1133 (define_insn "*addhi3_zero_extend"
1134 [(set (match_operand:HI 0 "register_operand" "=r")
1135 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1136 (match_operand:HI 2 "register_operand" "0")))]
1138 "add %A0,%1\;adc %B0,__zero_reg__"
1139 [(set_attr "length" "2")
1140 (set_attr "cc" "set_n")])
1142 (define_insn "*addhi3_zero_extend1"
1143 [(set (match_operand:HI 0 "register_operand" "=r")
1144 (plus:HI (match_operand:HI 1 "register_operand" "0")
1145 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1147 "add %A0,%2\;adc %B0,__zero_reg__"
1148 [(set_attr "length" "2")
1149 (set_attr "cc" "set_n")])
1151 (define_insn "*addhi3.sign_extend1"
1152 [(set (match_operand:HI 0 "register_operand" "=r")
1153 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1154 (match_operand:HI 2 "register_operand" "0")))]
1157 return reg_overlap_mentioned_p (operands[0], operands[1])
1158 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1159 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1161 [(set_attr "length" "5")
1162 (set_attr "cc" "clobber")])
1164 (define_insn "*addhi3_sp"
1165 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1166 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1167 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1170 return avr_out_addto_sp (operands, NULL);
1172 [(set_attr "length" "6")
1173 (set_attr "adjust_len" "addto_sp")])
1176 ;; "*addhq3" "*adduhq3"
1177 ;; "*addha3" "*adduha3"
1178 (define_insn "*add<mode>3"
1179 [(set (match_operand:ALL2 0 "register_operand" "=r,d,!w ,d")
1180 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1181 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1184 if (REG_P (operands[2]))
1185 return "add %A0,%A2\;adc %B0,%B2";
1186 else if (CONST_INT_P (operands[2])
1187 || CONST_FIXED == GET_CODE (operands[2]))
1188 return avr_out_plus_noclobber (operands, NULL, NULL);
1190 return "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))";
1192 [(set_attr "length" "2,2,2,2")
1193 (set_attr "adjust_len" "*,*,out_plus_noclobber,out_plus_noclobber")
1194 (set_attr "cc" "set_n,set_czn,out_plus_noclobber,out_plus_noclobber")])
1196 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1197 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1198 ;; itself because that insn is special to reload.
1200 (define_peephole2 ; addhi3_clobber
1201 [(set (match_operand:ALL2 0 "d_register_operand" "")
1202 (match_operand:ALL2 1 "const_operand" ""))
1203 (set (match_operand:ALL2 2 "l_register_operand" "")
1204 (plus:ALL2 (match_dup 2)
1206 "peep2_reg_dead_p (2, operands[0])"
1207 [(parallel [(set (match_dup 2)
1208 (plus:ALL2 (match_dup 2)
1210 (clobber (match_dup 3))])]
1212 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1215 ;; Same, but with reload to NO_LD_REGS
1216 ;; Combine *reload_inhi with *addhi3
1218 (define_peephole2 ; addhi3_clobber
1219 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1220 (match_operand:ALL2 1 "const_operand" ""))
1221 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1222 (set (match_operand:ALL2 3 "l_register_operand" "")
1223 (plus:ALL2 (match_dup 3)
1225 "peep2_reg_dead_p (2, operands[0])"
1226 [(parallel [(set (match_dup 3)
1227 (plus:ALL2 (match_dup 3)
1229 (clobber (match_dup 2))])])
1232 ;; "addhq3_clobber" "adduhq3_clobber"
1233 ;; "addha3_clobber" "adduha3_clobber"
1234 (define_insn "add<mode>3_clobber"
1235 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1236 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1237 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1238 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1241 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1243 return avr_out_plus (operands, NULL, NULL);
1245 [(set_attr "length" "4")
1246 (set_attr "adjust_len" "out_plus")
1247 (set_attr "cc" "out_plus")])
1251 ;; "addsq3" "addusq3"
1252 ;; "addsa3" "addusa3"
1253 (define_insn "add<mode>3"
1254 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1255 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1256 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1257 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1260 if (REG_P (operands[2]))
1261 return "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2";
1263 return avr_out_plus (operands, NULL, NULL);
1265 [(set_attr "length" "4,4,8")
1266 (set_attr "adjust_len" "*,out_plus,out_plus")
1267 (set_attr "cc" "set_n,out_plus,out_plus")])
1269 (define_insn "*addpsi3_zero_extend.qi"
1270 [(set (match_operand:PSI 0 "register_operand" "=r")
1271 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1272 (match_operand:PSI 2 "register_operand" "0")))]
1274 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1275 [(set_attr "length" "3")
1276 (set_attr "cc" "set_n")])
1278 (define_insn "*addpsi3_zero_extend.hi"
1279 [(set (match_operand:PSI 0 "register_operand" "=r")
1280 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1281 (match_operand:PSI 2 "register_operand" "0")))]
1283 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1284 [(set_attr "length" "3")
1285 (set_attr "cc" "set_n")])
1287 (define_insn "*addpsi3_sign_extend.hi"
1288 [(set (match_operand:PSI 0 "register_operand" "=r")
1289 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1290 (match_operand:PSI 2 "register_operand" "0")))]
1292 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1293 [(set_attr "length" "5")
1294 (set_attr "cc" "set_n")])
1296 (define_insn "*addsi3_zero_extend"
1297 [(set (match_operand:SI 0 "register_operand" "=r")
1298 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1299 (match_operand:SI 2 "register_operand" "0")))]
1301 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1302 [(set_attr "length" "4")
1303 (set_attr "cc" "set_n")])
1305 (define_insn "*addsi3_zero_extend.hi"
1306 [(set (match_operand:SI 0 "register_operand" "=r")
1307 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1308 (match_operand:SI 2 "register_operand" "0")))]
1310 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1311 [(set_attr "length" "4")
1312 (set_attr "cc" "set_n")])
1314 (define_insn "addpsi3"
1315 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1316 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1317 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1318 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1321 static const char * const asm_code[] =
1323 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1324 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1329 if (*asm_code[which_alternative])
1330 return asm_code[which_alternative];
1332 return avr_out_plus (operands, NULL, NULL);
1334 [(set_attr "length" "3,3,3,6")
1335 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1336 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1338 (define_insn "subpsi3"
1339 [(set (match_operand:PSI 0 "register_operand" "=r")
1340 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1341 (match_operand:PSI 2 "register_operand" "r")))]
1343 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1344 [(set_attr "length" "3")
1345 (set_attr "cc" "set_czn")])
1347 (define_insn "*subpsi3_zero_extend.qi"
1348 [(set (match_operand:PSI 0 "register_operand" "=r")
1349 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1350 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1352 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1353 [(set_attr "length" "3")
1354 (set_attr "cc" "set_czn")])
1356 (define_insn "*subpsi3_zero_extend.hi"
1357 [(set (match_operand:PSI 0 "register_operand" "=r")
1358 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1359 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1361 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1362 [(set_attr "length" "3")
1363 (set_attr "cc" "set_czn")])
1365 (define_insn "*subpsi3_sign_extend.hi"
1366 [(set (match_operand:PSI 0 "register_operand" "=r")
1367 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1368 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1370 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1371 [(set_attr "length" "5")
1372 (set_attr "cc" "set_czn")])
1374 ;-----------------------------------------------------------------------------
1378 ;; "subqq3" "subuqq3"
1379 (define_insn "sub<mode>3"
1380 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1381 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1382 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1391 [(set_attr "length" "1,1,1,1,2,2")
1392 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1395 ;; "subhq3" "subuhq3"
1396 ;; "subha3" "subuha3"
1397 (define_insn "sub<mode>3"
1398 [(set (match_operand:ALL2 0 "register_operand" "=r,d ,*r")
1399 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1400 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1401 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1404 return avr_out_minus (operands, NULL, NULL);
1406 [(set_attr "adjust_len" "minus")
1407 (set_attr "cc" "minus")])
1409 (define_insn "*subhi3_zero_extend1"
1410 [(set (match_operand:HI 0 "register_operand" "=r")
1411 (minus:HI (match_operand:HI 1 "register_operand" "0")
1412 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1414 "sub %A0,%2\;sbc %B0,__zero_reg__"
1415 [(set_attr "length" "2")
1416 (set_attr "cc" "set_czn")])
1418 (define_insn "*subhi3.sign_extend2"
1419 [(set (match_operand:HI 0 "register_operand" "=r")
1420 (minus:HI (match_operand:HI 1 "register_operand" "0")
1421 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1424 return reg_overlap_mentioned_p (operands[0], operands[2])
1425 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1426 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1428 [(set_attr "length" "5")
1429 (set_attr "cc" "clobber")])
1432 ;; "subsq3" "subusq3"
1433 ;; "subsa3" "subusa3"
1434 (define_insn "sub<mode>3"
1435 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1436 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1437 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1438 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1441 if (REG_P (operands[2]))
1442 return "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2";
1444 return avr_out_minus (operands, NULL, NULL);
1446 [(set_attr "length" "4")
1447 (set_attr "adjust_len" "*,minus,minus")
1448 (set_attr "cc" "set_czn")])
1450 (define_insn "*subsi3_zero_extend"
1451 [(set (match_operand:SI 0 "register_operand" "=r")
1452 (minus:SI (match_operand:SI 1 "register_operand" "0")
1453 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1455 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1456 [(set_attr "length" "4")
1457 (set_attr "cc" "set_czn")])
1459 (define_insn "*subsi3_zero_extend.hi"
1460 [(set (match_operand:SI 0 "register_operand" "=r")
1461 (minus:SI (match_operand:SI 1 "register_operand" "0")
1462 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1464 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1465 [(set_attr "length" "4")
1466 (set_attr "cc" "set_czn")])
1468 ;******************************************************************************
1471 (define_expand "mulqi3"
1472 [(set (match_operand:QI 0 "register_operand" "")
1473 (mult:QI (match_operand:QI 1 "register_operand" "")
1474 (match_operand:QI 2 "register_operand" "")))]
1479 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1484 (define_insn "*mulqi3_enh"
1485 [(set (match_operand:QI 0 "register_operand" "=r")
1486 (mult:QI (match_operand:QI 1 "register_operand" "r")
1487 (match_operand:QI 2 "register_operand" "r")))]
1492 [(set_attr "length" "3")
1493 (set_attr "cc" "clobber")])
1495 (define_expand "mulqi3_call"
1496 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1497 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1498 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1499 (clobber (reg:QI 22))])
1500 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1504 (define_insn "*mulqi3_call"
1505 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1506 (clobber (reg:QI 22))]
1509 [(set_attr "type" "xcall")
1510 (set_attr "cc" "clobber")])
1512 ;; "umulqi3_highpart"
1513 ;; "smulqi3_highpart"
1514 (define_insn "<extend_su>mulqi3_highpart"
1515 [(set (match_operand:QI 0 "register_operand" "=r")
1517 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1518 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1521 "mul<extend_s> %1,%2
1524 [(set_attr "length" "3")
1525 (set_attr "cc" "clobber")])
1528 ;; Used when expanding div or mod inline for some special values
1529 (define_insn "*subqi3.ashiftrt7"
1530 [(set (match_operand:QI 0 "register_operand" "=r")
1531 (minus:QI (match_operand:QI 1 "register_operand" "0")
1532 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1536 [(set_attr "length" "2")
1537 (set_attr "cc" "clobber")])
1539 (define_insn "*addqi3.lt0"
1540 [(set (match_operand:QI 0 "register_operand" "=r")
1541 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1543 (match_operand:QI 2 "register_operand" "0")))]
1546 [(set_attr "length" "2")
1547 (set_attr "cc" "clobber")])
1549 (define_insn "*addhi3.lt0"
1550 [(set (match_operand:HI 0 "register_operand" "=w,r")
1551 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1553 (match_operand:HI 2 "register_operand" "0,0")))
1554 (clobber (match_scratch:QI 3 "=X,&1"))]
1557 sbrc %1,7\;adiw %0,1
1558 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1559 [(set_attr "length" "2,3")
1560 (set_attr "cc" "clobber")])
1562 (define_insn "*addpsi3.lt0"
1563 [(set (match_operand:PSI 0 "register_operand" "=r")
1564 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1566 (match_operand:PSI 2 "register_operand" "0")))]
1568 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1569 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1570 [(set_attr "length" "5")
1571 (set_attr "cc" "clobber")])
1573 (define_insn "*addsi3.lt0"
1574 [(set (match_operand:SI 0 "register_operand" "=r")
1575 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1577 (match_operand:SI 2 "register_operand" "0")))]
1579 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1580 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1581 [(set_attr "length" "6")
1582 (set_attr "cc" "clobber")])
1584 (define_insn "*umulqihi3.call"
1586 (mult:HI (zero_extend:HI (reg:QI 22))
1587 (zero_extend:HI (reg:QI 24))))
1588 (clobber (reg:QI 21))
1589 (clobber (reg:HI 22))]
1591 "%~call __umulqihi3"
1592 [(set_attr "type" "xcall")
1593 (set_attr "cc" "clobber")])
1597 (define_insn "<extend_u>mulqihi3"
1598 [(set (match_operand:HI 0 "register_operand" "=r")
1599 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1600 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1602 "mul<extend_s> %1,%2
1605 [(set_attr "length" "3")
1606 (set_attr "cc" "clobber")])
1608 (define_insn "usmulqihi3"
1609 [(set (match_operand:HI 0 "register_operand" "=r")
1610 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1611 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1616 [(set_attr "length" "3")
1617 (set_attr "cc" "clobber")])
1619 ;; Above insn is not canonicalized by insn combine, so here is a version with
1620 ;; operands swapped.
1622 (define_insn "*sumulqihi3"
1623 [(set (match_operand:HI 0 "register_operand" "=r")
1624 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1625 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1630 [(set_attr "length" "3")
1631 (set_attr "cc" "clobber")])
1633 ;; One-extend operand 1
1635 (define_insn "*osmulqihi3"
1636 [(set (match_operand:HI 0 "register_operand" "=&r")
1637 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1638 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1644 [(set_attr "length" "4")
1645 (set_attr "cc" "clobber")])
1647 (define_insn "*oumulqihi3"
1648 [(set (match_operand:HI 0 "register_operand" "=&r")
1649 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1650 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1656 [(set_attr "length" "4")
1657 (set_attr "cc" "clobber")])
1659 ;******************************************************************************
1660 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1661 ;******************************************************************************
1663 (define_insn "*maddqi4"
1664 [(set (match_operand:QI 0 "register_operand" "=r")
1665 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1666 (match_operand:QI 2 "register_operand" "r"))
1667 (match_operand:QI 3 "register_operand" "0")))]
1673 [(set_attr "length" "4")
1674 (set_attr "cc" "clobber")])
1676 (define_insn "*msubqi4"
1677 [(set (match_operand:QI 0 "register_operand" "=r")
1678 (minus:QI (match_operand:QI 3 "register_operand" "0")
1679 (mult:QI (match_operand:QI 1 "register_operand" "r")
1680 (match_operand:QI 2 "register_operand" "r"))))]
1685 [(set_attr "length" "4")
1686 (set_attr "cc" "clobber")])
1688 (define_insn_and_split "*maddqi4.const"
1689 [(set (match_operand:QI 0 "register_operand" "=r")
1690 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1691 (match_operand:QI 2 "const_int_operand" "n"))
1692 (match_operand:QI 3 "register_operand" "0")))
1693 (clobber (match_scratch:QI 4 "=&d"))]
1696 "&& reload_completed"
1701 (plus:QI (mult:QI (match_dup 1)
1706 (define_insn_and_split "*msubqi4.const"
1707 [(set (match_operand:QI 0 "register_operand" "=r")
1708 (minus:QI (match_operand:QI 3 "register_operand" "0")
1709 (mult:QI (match_operand:QI 1 "register_operand" "r")
1710 (match_operand:QI 2 "const_int_operand" "n"))))
1711 (clobber (match_scratch:QI 4 "=&d"))]
1714 "&& reload_completed"
1719 (minus:QI (match_dup 3)
1720 (mult:QI (match_dup 1)
1725 ;******************************************************************************
1726 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1727 ;******************************************************************************
1729 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1732 ;; int foo (unsigned char z)
1734 ;; extern int aInt[];
1735 ;; return aInt[3*z+2];
1738 ;; because the constant +4 then is added explicitely instead of consuming it
1739 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1740 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1741 ;; The implementational effort is the same so we are fine with that approach.
1746 (define_insn "*<extend_u>maddqihi4"
1747 [(set (match_operand:HI 0 "register_operand" "=r")
1748 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1749 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1750 (match_operand:HI 3 "register_operand" "0")))]
1753 "mul<extend_s> %1,%2
1757 [(set_attr "length" "4")
1758 (set_attr "cc" "clobber")])
1762 (define_insn "*<extend_u>msubqihi4"
1763 [(set (match_operand:HI 0 "register_operand" "=r")
1764 (minus:HI (match_operand:HI 3 "register_operand" "0")
1765 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1766 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1768 "mul<extend_s> %1,%2
1772 [(set_attr "length" "4")
1773 (set_attr "cc" "clobber")])
1777 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1778 [(set (match_operand:HI 0 "register_operand" "=r")
1779 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1780 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1781 (match_operand:HI 3 "register_operand" "0")))]
1784 && <any_extend:CODE> != <any_extend2:CODE>"
1786 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1787 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1789 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1791 [(set_attr "length" "4")
1792 (set_attr "cc" "clobber")])
1796 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1797 [(set (match_operand:HI 0 "register_operand" "=r")
1798 (minus:HI (match_operand:HI 3 "register_operand" "0")
1799 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1800 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1803 && <any_extend:CODE> != <any_extend2:CODE>"
1805 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1806 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1808 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1810 [(set_attr "length" "4")
1811 (set_attr "cc" "clobber")])
1813 ;; Handle small constants
1815 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1816 ;; This is shorter, faster than MUL and has lower register pressure.
1818 (define_insn_and_split "*umaddqihi4.2"
1819 [(set (match_operand:HI 0 "register_operand" "=r")
1820 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1822 (match_operand:HI 2 "register_operand" "r")))]
1824 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1825 { gcc_unreachable(); }
1829 ; *addhi3_zero_extend
1831 (plus:HI (zero_extend:HI (match_dup 1))
1833 ; *addhi3_zero_extend
1835 (plus:HI (zero_extend:HI (match_dup 1))
1838 ;; "umaddqihi4.uconst"
1839 ;; "maddqihi4.sconst"
1840 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1841 [(set (match_operand:HI 0 "register_operand" "=r")
1842 (plus:HI (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 (match_operand:HI 3 "register_operand" "0")))
1845 (clobber (match_scratch:QI 4 "=&d"))]
1848 "&& reload_completed"
1851 ; *umaddqihi4 resp. *maddqihi4
1853 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1854 (any_extend:HI (match_dup 4)))
1857 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1860 ;; "*umsubqihi4.uconst"
1861 ;; "*msubqihi4.sconst"
1862 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1863 [(set (match_operand:HI 0 "register_operand" "=r")
1864 (minus:HI (match_operand:HI 3 "register_operand" "0")
1865 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1866 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1867 (clobber (match_scratch:QI 4 "=&d"))]
1870 "&& reload_completed"
1873 ; *umsubqihi4 resp. *msubqihi4
1875 (minus:HI (match_dup 3)
1876 (mult:HI (any_extend:HI (match_dup 1))
1877 (any_extend:HI (match_dup 4)))))]
1879 operands[2] = gen_int_mode (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.
1885 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1886 [(set (match_operand:HI 0 "register_operand" "=r")
1887 (minus:HI (match_operand:HI 3 "register_operand" "0")
1888 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1889 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1890 (clobber (match_scratch:QI 4 "=&d"))]
1893 "&& reload_completed"
1898 (minus:HI (match_dup 3)
1899 (mult:HI (zero_extend:HI (match_dup 1))
1900 (zero_extend:HI (match_dup 4)))))]
1902 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1905 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1906 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1907 ;; because this would require an extra pattern for just one value.
1909 (define_insn_and_split "*msubqihi4.sconst.ashift"
1910 [(set (match_operand:HI 0 "register_operand" "=r")
1911 (minus:HI (match_operand:HI 3 "register_operand" "0")
1912 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1913 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1914 (clobber (match_scratch:QI 4 "=&d"))]
1917 "&& reload_completed"
1922 (minus:HI (match_dup 3)
1923 (mult:HI (sign_extend:HI (match_dup 1))
1924 (sign_extend:HI (match_dup 4)))))]
1926 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1929 ;; For signed/unsigned combinations that require narrow constraint "a"
1930 ;; just provide a pattern if signed/unsigned combination is actually needed.
1932 (define_insn_and_split "*sumaddqihi4.uconst"
1933 [(set (match_operand:HI 0 "register_operand" "=r")
1934 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1935 (match_operand:HI 2 "u8_operand" "M"))
1936 (match_operand:HI 3 "register_operand" "0")))
1937 (clobber (match_scratch:QI 4 "=&a"))]
1939 && !s8_operand (operands[2], VOIDmode)"
1941 "&& reload_completed"
1946 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1947 (zero_extend:HI (match_dup 4)))
1950 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1953 (define_insn_and_split "*sumsubqihi4.uconst"
1954 [(set (match_operand:HI 0 "register_operand" "=r")
1955 (minus:HI (match_operand:HI 3 "register_operand" "0")
1956 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1957 (match_operand:HI 2 "u8_operand" "M"))))
1958 (clobber (match_scratch:QI 4 "=&a"))]
1960 && !s8_operand (operands[2], VOIDmode)"
1962 "&& reload_completed"
1967 (minus:HI (match_dup 3)
1968 (mult:HI (sign_extend:HI (match_dup 1))
1969 (zero_extend:HI (match_dup 4)))))]
1971 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1974 ;******************************************************************************
1975 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1976 ;******************************************************************************
1978 ;; "*muluqihi3.uconst"
1979 ;; "*mulsqihi3.sconst"
1980 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1981 [(set (match_operand:HI 0 "register_operand" "=r")
1982 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1983 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1984 (clobber (match_scratch:QI 3 "=&d"))]
1987 "&& reload_completed"
1990 ; umulqihi3 resp. mulqihi3
1992 (mult:HI (any_extend:HI (match_dup 1))
1993 (any_extend:HI (match_dup 3))))]
1995 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1998 (define_insn_and_split "*muluqihi3.sconst"
1999 [(set (match_operand:HI 0 "register_operand" "=r")
2000 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
2001 (match_operand:HI 2 "s8_operand" "n")))
2002 (clobber (match_scratch:QI 3 "=&a"))]
2005 "&& reload_completed"
2010 (mult:HI (zero_extend:HI (match_dup 1))
2011 (sign_extend:HI (match_dup 3))))]
2013 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2016 (define_insn_and_split "*mulsqihi3.uconst"
2017 [(set (match_operand:HI 0 "register_operand" "=r")
2018 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2019 (match_operand:HI 2 "u8_operand" "M")))
2020 (clobber (match_scratch:QI 3 "=&a"))]
2023 "&& reload_completed"
2028 (mult:HI (zero_extend:HI (match_dup 3))
2029 (sign_extend:HI (match_dup 1))))]
2031 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2034 (define_insn_and_split "*mulsqihi3.oconst"
2035 [(set (match_operand:HI 0 "register_operand" "=&r")
2036 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2037 (match_operand:HI 2 "o8_operand" "n")))
2038 (clobber (match_scratch:QI 3 "=&a"))]
2041 "&& reload_completed"
2046 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2047 (sign_extend:HI (match_dup 1))))]
2049 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2052 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2053 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2054 ;; at that time. Fix that.
2056 (define_insn "*ashiftqihi2.signx.1"
2057 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2058 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2062 lsl %A0\;sbc %B0,%B0
2063 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2064 [(set_attr "length" "2,3")
2065 (set_attr "cc" "clobber")])
2067 (define_insn_and_split "*ashifthi3.signx.const"
2068 [(set (match_operand:HI 0 "register_operand" "=r")
2069 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2070 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2071 (clobber (match_scratch:QI 3 "=&d"))]
2074 "&& reload_completed"
2079 (mult:HI (sign_extend:HI (match_dup 1))
2080 (sign_extend:HI (match_dup 3))))]
2082 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2085 (define_insn_and_split "*ashifthi3.signx.const7"
2086 [(set (match_operand:HI 0 "register_operand" "=r")
2087 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2089 (clobber (match_scratch:QI 2 "=&a"))]
2092 "&& reload_completed"
2097 (mult:HI (zero_extend:HI (match_dup 2))
2098 (sign_extend:HI (match_dup 1))))]
2100 operands[3] = gen_int_mode (1 << 7, QImode);
2103 (define_insn_and_split "*ashifthi3.zerox.const"
2104 [(set (match_operand:HI 0 "register_operand" "=r")
2105 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2106 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2107 (clobber (match_scratch:QI 3 "=&d"))]
2110 "&& reload_completed"
2115 (mult:HI (zero_extend:HI (match_dup 1))
2116 (zero_extend:HI (match_dup 3))))]
2118 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2121 ;******************************************************************************
2122 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2123 ;******************************************************************************
2125 (define_insn "mulsqihi3"
2126 [(set (match_operand:HI 0 "register_operand" "=&r")
2127 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2128 (match_operand:HI 2 "register_operand" "a")))]
2135 [(set_attr "length" "5")
2136 (set_attr "cc" "clobber")])
2138 (define_insn "muluqihi3"
2139 [(set (match_operand:HI 0 "register_operand" "=&r")
2140 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2141 (match_operand:HI 2 "register_operand" "r")))]
2148 [(set_attr "length" "5")
2149 (set_attr "cc" "clobber")])
2151 ;; one-extend operand 1
2153 (define_insn "muloqihi3"
2154 [(set (match_operand:HI 0 "register_operand" "=&r")
2155 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2156 (match_operand:HI 2 "register_operand" "r")))]
2164 [(set_attr "length" "6")
2165 (set_attr "cc" "clobber")])
2167 ;******************************************************************************
2169 (define_expand "mulhi3"
2170 [(set (match_operand:HI 0 "register_operand" "")
2171 (mult:HI (match_operand:HI 1 "register_operand" "")
2172 (match_operand:HI 2 "register_or_s9_operand" "")))]
2177 if (!register_operand (operands[2], HImode))
2178 operands[2] = force_reg (HImode, operands[2]);
2180 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2184 /* For small constants we can do better by extending them on the fly.
2185 The constant can be loaded in one instruction and the widening
2186 multiplication is shorter. First try the unsigned variant because it
2187 allows constraint "d" instead of "a" for the signed version. */
2189 if (s9_operand (operands[2], HImode))
2191 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2193 if (u8_operand (operands[2], HImode))
2195 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2197 else if (s8_operand (operands[2], HImode))
2199 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2203 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2209 if (!register_operand (operands[2], HImode))
2210 operands[2] = force_reg (HImode, operands[2]);
2213 (define_insn "*mulhi3_enh"
2214 [(set (match_operand:HI 0 "register_operand" "=&r")
2215 (mult:HI (match_operand:HI 1 "register_operand" "r")
2216 (match_operand:HI 2 "register_operand" "r")))]
2219 return REGNO (operands[1]) == REGNO (operands[2])
2220 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2221 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2223 [(set_attr "length" "7")
2224 (set_attr "cc" "clobber")])
2226 (define_expand "mulhi3_call"
2227 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2228 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2229 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2230 (clobber (reg:HI 22))
2231 (clobber (reg:QI 21))])
2232 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2236 (define_insn "*mulhi3_call"
2237 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2238 (clobber (reg:HI 22))
2239 (clobber (reg:QI 21))]
2242 [(set_attr "type" "xcall")
2243 (set_attr "cc" "clobber")])
2245 ;; To support widening multiplication with constant we postpone
2246 ;; expanding to the implicit library call until post combine and
2247 ;; prior to register allocation. Clobber all hard registers that
2248 ;; might be used by the (widening) multiply until it is split and
2249 ;; it's final register footprint is worked out.
2251 (define_expand "mulsi3"
2252 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2253 (mult:SI (match_operand:SI 1 "register_operand" "")
2254 (match_operand:SI 2 "nonmemory_operand" "")))
2255 (clobber (reg:HI 26))
2256 (clobber (reg:DI 18))])]
2259 if (u16_operand (operands[2], SImode))
2261 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2262 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2266 if (o16_operand (operands[2], SImode))
2268 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2269 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2274 (define_insn_and_split "*mulsi3"
2275 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2276 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2277 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2278 (clobber (reg:HI 26))
2279 (clobber (reg:DI 18))]
2280 "AVR_HAVE_MUL && !reload_completed"
2281 { gcc_unreachable(); }
2287 (parallel [(set (reg:SI 22)
2288 (mult:SI (reg:SI 22)
2290 (clobber (reg:HI 26))])
2294 if (u16_operand (operands[2], SImode))
2296 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2297 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2301 if (o16_operand (operands[2], SImode))
2303 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2304 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2311 (define_insn_and_split "mulu<mode>si3"
2312 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2313 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2314 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2315 (clobber (reg:HI 26))
2316 (clobber (reg:DI 18))]
2317 "AVR_HAVE_MUL && !reload_completed"
2318 { gcc_unreachable(); }
2325 (mult:SI (zero_extend:SI (reg:HI 26))
2330 /* Do the QI -> HI extension explicitely before the multiplication. */
2331 /* Do the HI -> SI extension implicitely and after the multiplication. */
2333 if (QImode == <MODE>mode)
2334 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2336 if (u16_operand (operands[2], SImode))
2338 operands[1] = force_reg (HImode, operands[1]);
2339 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2340 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2347 (define_insn_and_split "muls<mode>si3"
2348 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2349 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2350 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2351 (clobber (reg:HI 26))
2352 (clobber (reg:DI 18))]
2353 "AVR_HAVE_MUL && !reload_completed"
2354 { gcc_unreachable(); }
2361 (mult:SI (sign_extend:SI (reg:HI 26))
2366 /* Do the QI -> HI extension explicitely before the multiplication. */
2367 /* Do the HI -> SI extension implicitely and after the multiplication. */
2369 if (QImode == <MODE>mode)
2370 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2372 if (u16_operand (operands[2], SImode)
2373 || s16_operand (operands[2], SImode))
2375 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2377 operands[1] = force_reg (HImode, operands[1]);
2379 if (u16_operand (operands[2], SImode))
2380 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2382 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2388 ;; One-extend operand 1
2390 (define_insn_and_split "mulohisi3"
2391 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2392 (mult:SI (not:SI (zero_extend:SI
2393 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2394 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2395 (clobber (reg:HI 26))
2396 (clobber (reg:DI 18))]
2397 "AVR_HAVE_MUL && !reload_completed"
2398 { gcc_unreachable(); }
2405 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2413 (define_expand "<extend_u>mulhisi3"
2414 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2415 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2416 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2417 (clobber (reg:HI 26))
2418 (clobber (reg:DI 18))])]
2422 (define_expand "usmulhisi3"
2423 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2424 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2425 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2426 (clobber (reg:HI 26))
2427 (clobber (reg:DI 18))])]
2431 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2432 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2433 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2434 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2435 (define_insn_and_split
2436 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2437 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2438 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2439 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2440 (clobber (reg:HI 26))
2441 (clobber (reg:DI 18))]
2442 "AVR_HAVE_MUL && !reload_completed"
2443 { gcc_unreachable(); }
2450 (mult:SI (match_dup 3)
2455 rtx xop1 = operands[1];
2456 rtx xop2 = operands[2];
2458 /* Do the QI -> HI extension explicitely before the multiplication. */
2459 /* Do the HI -> SI extension implicitely and after the multiplication. */
2461 if (QImode == <QIHI:MODE>mode)
2462 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2464 if (QImode == <QIHI2:MODE>mode)
2465 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2467 if (<any_extend:CODE> == <any_extend2:CODE>
2468 || <any_extend:CODE> == ZERO_EXTEND)
2472 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2473 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2477 /* <any_extend:CODE> = SIGN_EXTEND */
2478 /* <any_extend2:CODE> = ZERO_EXTEND */
2482 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2483 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2487 ;; "smulhi3_highpart"
2488 ;; "umulhi3_highpart"
2489 (define_expand "<extend_su>mulhi3_highpart"
2491 (match_operand:HI 1 "nonmemory_operand" ""))
2493 (match_operand:HI 2 "nonmemory_operand" ""))
2494 (parallel [(set (reg:HI 24)
2495 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2496 (any_extend:SI (reg:HI 26)))
2498 (clobber (reg:HI 22))])
2499 (set (match_operand:HI 0 "register_operand" "")
2505 (define_insn "*mulsi3_call"
2507 (mult:SI (reg:SI 22)
2509 (clobber (reg:HI 26))]
2512 [(set_attr "type" "xcall")
2513 (set_attr "cc" "clobber")])
2516 ;; "*umulhisi3_call"
2517 (define_insn "*<extend_u>mulhisi3_call"
2519 (mult:SI (any_extend:SI (reg:HI 18))
2520 (any_extend:SI (reg:HI 26))))]
2522 "%~call __<extend_u>mulhisi3"
2523 [(set_attr "type" "xcall")
2524 (set_attr "cc" "clobber")])
2526 ;; "*umulhi3_highpart_call"
2527 ;; "*smulhi3_highpart_call"
2528 (define_insn "*<extend_su>mulhi3_highpart_call"
2530 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2531 (any_extend:SI (reg:HI 26)))
2533 (clobber (reg:HI 22))]
2535 "%~call __<extend_u>mulhisi3"
2536 [(set_attr "type" "xcall")
2537 (set_attr "cc" "clobber")])
2539 (define_insn "*usmulhisi3_call"
2541 (mult:SI (zero_extend:SI (reg:HI 18))
2542 (sign_extend:SI (reg:HI 26))))]
2544 "%~call __usmulhisi3"
2545 [(set_attr "type" "xcall")
2546 (set_attr "cc" "clobber")])
2548 (define_insn "*mul<extend_su>hisi3_call"
2550 (mult:SI (any_extend:SI (reg:HI 26))
2553 "%~call __mul<extend_su>hisi3"
2554 [(set_attr "type" "xcall")
2555 (set_attr "cc" "clobber")])
2557 (define_insn "*mulohisi3_call"
2559 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2562 "%~call __mulohisi3"
2563 [(set_attr "type" "xcall")
2564 (set_attr "cc" "clobber")])
2566 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2569 ;; Generate lib1funcs.S calls ourselves, because:
2570 ;; - we know exactly which registers are clobbered (for QI and HI
2571 ;; modes, some of the call-used registers are preserved)
2572 ;; - we get both the quotient and the remainder at no extra cost
2573 ;; - we split the patterns only after the first CSE passes because
2574 ;; CSE has problems to operate on hard regs.
2576 (define_insn_and_split "divmodqi4"
2577 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2578 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2579 (match_operand:QI 2 "pseudo_register_operand" "")))
2580 (set (match_operand:QI 3 "pseudo_register_operand" "")
2581 (mod:QI (match_dup 1) (match_dup 2)))
2582 (clobber (reg:QI 22))
2583 (clobber (reg:QI 23))
2584 (clobber (reg:QI 24))
2585 (clobber (reg:QI 25))])]
2587 "this divmodqi4 pattern should have been splitted;"
2589 [(set (reg:QI 24) (match_dup 1))
2590 (set (reg:QI 22) (match_dup 2))
2591 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2592 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2593 (clobber (reg:QI 22))
2594 (clobber (reg:QI 23))])
2595 (set (match_dup 0) (reg:QI 24))
2596 (set (match_dup 3) (reg:QI 25))]
2599 (define_insn "*divmodqi4_call"
2600 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2601 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2602 (clobber (reg:QI 22))
2603 (clobber (reg:QI 23))]
2605 "%~call __divmodqi4"
2606 [(set_attr "type" "xcall")
2607 (set_attr "cc" "clobber")])
2609 (define_insn_and_split "udivmodqi4"
2610 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2611 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2612 (match_operand:QI 2 "pseudo_register_operand" "")))
2613 (set (match_operand:QI 3 "pseudo_register_operand" "")
2614 (umod:QI (match_dup 1) (match_dup 2)))
2615 (clobber (reg:QI 22))
2616 (clobber (reg:QI 23))
2617 (clobber (reg:QI 24))
2618 (clobber (reg:QI 25))])]
2620 "this udivmodqi4 pattern should have been splitted;"
2622 [(set (reg:QI 24) (match_dup 1))
2623 (set (reg:QI 22) (match_dup 2))
2624 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2625 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2626 (clobber (reg:QI 23))])
2627 (set (match_dup 0) (reg:QI 24))
2628 (set (match_dup 3) (reg:QI 25))]
2631 (define_insn "*udivmodqi4_call"
2632 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2633 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2634 (clobber (reg:QI 23))]
2636 "%~call __udivmodqi4"
2637 [(set_attr "type" "xcall")
2638 (set_attr "cc" "clobber")])
2640 (define_insn_and_split "divmodhi4"
2641 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2642 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2643 (match_operand:HI 2 "pseudo_register_operand" "")))
2644 (set (match_operand:HI 3 "pseudo_register_operand" "")
2645 (mod:HI (match_dup 1) (match_dup 2)))
2646 (clobber (reg:QI 21))
2647 (clobber (reg:HI 22))
2648 (clobber (reg:HI 24))
2649 (clobber (reg:HI 26))])]
2651 "this should have been splitted;"
2653 [(set (reg:HI 24) (match_dup 1))
2654 (set (reg:HI 22) (match_dup 2))
2655 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2656 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2657 (clobber (reg:HI 26))
2658 (clobber (reg:QI 21))])
2659 (set (match_dup 0) (reg:HI 22))
2660 (set (match_dup 3) (reg:HI 24))]
2663 (define_insn "*divmodhi4_call"
2664 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2665 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2666 (clobber (reg:HI 26))
2667 (clobber (reg:QI 21))]
2669 "%~call __divmodhi4"
2670 [(set_attr "type" "xcall")
2671 (set_attr "cc" "clobber")])
2673 (define_insn_and_split "udivmodhi4"
2674 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2675 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2676 (match_operand:HI 2 "pseudo_register_operand" "")))
2677 (set (match_operand:HI 3 "pseudo_register_operand" "")
2678 (umod:HI (match_dup 1) (match_dup 2)))
2679 (clobber (reg:QI 21))
2680 (clobber (reg:HI 22))
2681 (clobber (reg:HI 24))
2682 (clobber (reg:HI 26))])]
2684 "this udivmodhi4 pattern should have been splitted.;"
2686 [(set (reg:HI 24) (match_dup 1))
2687 (set (reg:HI 22) (match_dup 2))
2688 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2689 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2690 (clobber (reg:HI 26))
2691 (clobber (reg:QI 21))])
2692 (set (match_dup 0) (reg:HI 22))
2693 (set (match_dup 3) (reg:HI 24))]
2696 (define_insn "*udivmodhi4_call"
2697 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2698 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2699 (clobber (reg:HI 26))
2700 (clobber (reg:QI 21))]
2702 "%~call __udivmodhi4"
2703 [(set_attr "type" "xcall")
2704 (set_attr "cc" "clobber")])
2706 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2709 ;; To support widening multiplication with constant we postpone
2710 ;; expanding to the implicit library call until post combine and
2711 ;; prior to register allocation. Clobber all hard registers that
2712 ;; might be used by the (widening) multiply until it is split and
2713 ;; it's final register footprint is worked out.
2715 (define_expand "mulpsi3"
2716 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2717 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2718 (match_operand:PSI 2 "nonmemory_operand" "")))
2719 (clobber (reg:HI 26))
2720 (clobber (reg:DI 18))])]
2723 if (s8_operand (operands[2], PSImode))
2725 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2726 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2731 (define_insn "*umulqihipsi3"
2732 [(set (match_operand:PSI 0 "register_operand" "=&r")
2733 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2734 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2743 [(set_attr "length" "7")
2744 (set_attr "cc" "clobber")])
2746 (define_insn "*umulhiqipsi3"
2747 [(set (match_operand:PSI 0 "register_operand" "=&r")
2748 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2749 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2757 adc %C0,__zero_reg__"
2758 [(set_attr "length" "7")
2759 (set_attr "cc" "clobber")])
2761 (define_insn_and_split "mulsqipsi3"
2762 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2763 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2764 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2765 (clobber (reg:HI 26))
2766 (clobber (reg:DI 18))]
2767 "AVR_HAVE_MUL && !reload_completed"
2768 { gcc_unreachable(); }
2775 (mult:PSI (sign_extend:PSI (reg:QI 25))
2780 (define_insn_and_split "*mulpsi3"
2781 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2782 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2783 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2784 (clobber (reg:HI 26))
2785 (clobber (reg:DI 18))]
2786 "AVR_HAVE_MUL && !reload_completed"
2787 { gcc_unreachable(); }
2793 (parallel [(set (reg:PSI 22)
2794 (mult:PSI (reg:PSI 22)
2796 (clobber (reg:QI 21))
2797 (clobber (reg:QI 25))
2798 (clobber (reg:HI 26))])
2802 if (s8_operand (operands[2], PSImode))
2804 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2805 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2810 (define_insn "*mulsqipsi3.libgcc"
2812 (mult:PSI (sign_extend:PSI (reg:QI 25))
2815 "%~call __mulsqipsi3"
2816 [(set_attr "type" "xcall")
2817 (set_attr "cc" "clobber")])
2819 (define_insn "*mulpsi3.libgcc"
2821 (mult:PSI (reg:PSI 22)
2823 (clobber (reg:QI 21))
2824 (clobber (reg:QI 25))
2825 (clobber (reg:HI 26))]
2828 [(set_attr "type" "xcall")
2829 (set_attr "cc" "clobber")])
2832 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2833 ;; 24-bit signed/unsigned division and modulo.
2834 ;; Notice that the libgcc implementation return the quotient in R22
2835 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2836 ;; implementation works the other way round.
2838 (define_insn_and_split "divmodpsi4"
2839 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2840 (div: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 (mod: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) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2853 (set (reg:PSI 18) (mod: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 "*divmodpsi4_call"
2861 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2862 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2863 (clobber (reg:QI 21))
2864 (clobber (reg:QI 25))
2865 (clobber (reg:QI 26))]
2867 "%~call __divmodpsi4"
2868 [(set_attr "type" "xcall")
2869 (set_attr "cc" "clobber")])
2871 (define_insn_and_split "udivmodpsi4"
2872 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2873 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2874 (match_operand:PSI 2 "pseudo_register_operand" "")))
2875 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2876 (umod:PSI (match_dup 1)
2878 (clobber (reg:DI 18))
2879 (clobber (reg:QI 26))])]
2881 { gcc_unreachable(); }
2883 [(set (reg:PSI 22) (match_dup 1))
2884 (set (reg:PSI 18) (match_dup 2))
2885 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2886 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2887 (clobber (reg:QI 21))
2888 (clobber (reg:QI 25))
2889 (clobber (reg:QI 26))])
2890 (set (match_dup 0) (reg:PSI 22))
2891 (set (match_dup 3) (reg:PSI 18))])
2893 (define_insn "*udivmodpsi4_call"
2894 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2895 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2896 (clobber (reg:QI 21))
2897 (clobber (reg:QI 25))
2898 (clobber (reg:QI 26))]
2900 "%~call __udivmodpsi4"
2901 [(set_attr "type" "xcall")
2902 (set_attr "cc" "clobber")])
2904 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2906 (define_insn_and_split "divmodsi4"
2907 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2908 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2909 (match_operand:SI 2 "pseudo_register_operand" "")))
2910 (set (match_operand:SI 3 "pseudo_register_operand" "")
2911 (mod:SI (match_dup 1) (match_dup 2)))
2912 (clobber (reg:SI 18))
2913 (clobber (reg:SI 22))
2914 (clobber (reg:HI 26))
2915 (clobber (reg:HI 30))])]
2917 "this divmodsi4 pattern should have been splitted;"
2919 [(set (reg:SI 22) (match_dup 1))
2920 (set (reg:SI 18) (match_dup 2))
2921 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2922 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2923 (clobber (reg:HI 26))
2924 (clobber (reg:HI 30))])
2925 (set (match_dup 0) (reg:SI 18))
2926 (set (match_dup 3) (reg:SI 22))]
2929 (define_insn "*divmodsi4_call"
2930 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2931 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2932 (clobber (reg:HI 26))
2933 (clobber (reg:HI 30))]
2935 "%~call __divmodsi4"
2936 [(set_attr "type" "xcall")
2937 (set_attr "cc" "clobber")])
2939 (define_insn_and_split "udivmodsi4"
2940 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2941 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2942 (match_operand:SI 2 "pseudo_register_operand" "")))
2943 (set (match_operand:SI 3 "pseudo_register_operand" "")
2944 (umod:SI (match_dup 1) (match_dup 2)))
2945 (clobber (reg:SI 18))
2946 (clobber (reg:SI 22))
2947 (clobber (reg:HI 26))
2948 (clobber (reg:HI 30))])]
2950 "this udivmodsi4 pattern should have been splitted;"
2952 [(set (reg:SI 22) (match_dup 1))
2953 (set (reg:SI 18) (match_dup 2))
2954 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2955 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2956 (clobber (reg:HI 26))
2957 (clobber (reg:HI 30))])
2958 (set (match_dup 0) (reg:SI 18))
2959 (set (match_dup 3) (reg:SI 22))]
2962 (define_insn "*udivmodsi4_call"
2963 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2964 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2965 (clobber (reg:HI 26))
2966 (clobber (reg:HI 30))]
2968 "%~call __udivmodsi4"
2969 [(set_attr "type" "xcall")
2970 (set_attr "cc" "clobber")])
2972 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2975 (define_insn "andqi3"
2976 [(set (match_operand:QI 0 "register_operand" "=r,d")
2977 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2978 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2983 [(set_attr "length" "1,1")
2984 (set_attr "cc" "set_zn,set_zn")])
2986 (define_insn "andhi3"
2987 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2988 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2989 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2990 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2993 if (which_alternative == 0)
2994 return "and %A0,%A2\;and %B0,%B2";
2995 else if (which_alternative == 1)
2996 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2998 return avr_out_bitop (insn, operands, NULL);
3000 [(set_attr "length" "2,2,2,4,4")
3001 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3002 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3004 (define_insn "andpsi3"
3005 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3006 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3007 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
3008 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3011 if (which_alternative == 0)
3012 return "and %A0,%A2" CR_TAB
3013 "and %B0,%B2" CR_TAB
3016 return avr_out_bitop (insn, operands, NULL);
3018 [(set_attr "length" "3,3,6,6")
3019 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3020 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3022 (define_insn "andsi3"
3023 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3024 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3025 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
3026 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3029 if (which_alternative == 0)
3030 return "and %0,%2" CR_TAB
3031 "and %B0,%B2" CR_TAB
3032 "and %C0,%C2" CR_TAB
3035 return avr_out_bitop (insn, operands, NULL);
3037 [(set_attr "length" "4,4,8,8")
3038 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3039 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3041 (define_peephole2 ; andi
3042 [(set (match_operand:QI 0 "d_register_operand" "")
3043 (and:QI (match_dup 0)
3044 (match_operand:QI 1 "const_int_operand" "")))
3046 (and:QI (match_dup 0)
3047 (match_operand:QI 2 "const_int_operand" "")))]
3049 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3051 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3054 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3057 (define_insn "iorqi3"
3058 [(set (match_operand:QI 0 "register_operand" "=r,d")
3059 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3060 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3065 [(set_attr "length" "1,1")
3066 (set_attr "cc" "set_zn,set_zn")])
3068 (define_insn "iorhi3"
3069 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
3070 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3071 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3072 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3075 if (which_alternative == 0)
3076 return "or %A0,%A2\;or %B0,%B2";
3077 else if (which_alternative == 1)
3078 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3080 return avr_out_bitop (insn, operands, NULL);
3082 [(set_attr "length" "2,2,2,4,4")
3083 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3084 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3086 (define_insn "iorpsi3"
3087 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3088 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3089 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3090 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3093 if (which_alternative == 0)
3094 return "or %A0,%A2" CR_TAB
3098 return avr_out_bitop (insn, operands, NULL);
3100 [(set_attr "length" "3,3,6,6")
3101 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3102 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3104 (define_insn "iorsi3"
3105 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3106 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3107 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3108 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3111 if (which_alternative == 0)
3112 return "or %0,%2" CR_TAB
3117 return avr_out_bitop (insn, operands, NULL);
3119 [(set_attr "length" "4,4,8,8")
3120 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3121 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3123 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3126 (define_insn "xorqi3"
3127 [(set (match_operand:QI 0 "register_operand" "=r")
3128 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3129 (match_operand:QI 2 "register_operand" "r")))]
3132 [(set_attr "length" "1")
3133 (set_attr "cc" "set_zn")])
3135 (define_insn "xorhi3"
3136 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3137 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3138 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3139 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3142 if (which_alternative == 0)
3143 return "eor %A0,%A2\;eor %B0,%B2";
3145 return avr_out_bitop (insn, operands, NULL);
3147 [(set_attr "length" "2,2,4")
3148 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3149 (set_attr "cc" "set_n,clobber,clobber")])
3151 (define_insn "xorpsi3"
3152 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3153 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3154 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3155 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3158 if (which_alternative == 0)
3159 return "eor %A0,%A2" CR_TAB
3160 "eor %B0,%B2" CR_TAB
3163 return avr_out_bitop (insn, operands, NULL);
3165 [(set_attr "length" "3,6,6")
3166 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3167 (set_attr "cc" "set_n,clobber,clobber")])
3169 (define_insn "xorsi3"
3170 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3171 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3172 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3173 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3176 if (which_alternative == 0)
3177 return "eor %0,%2" CR_TAB
3178 "eor %B0,%B2" CR_TAB
3179 "eor %C0,%C2" CR_TAB
3182 return avr_out_bitop (insn, operands, NULL);
3184 [(set_attr "length" "4,8,8")
3185 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3186 (set_attr "cc" "set_n,clobber,clobber")])
3188 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3191 (define_expand "rotlqi3"
3192 [(set (match_operand:QI 0 "register_operand" "")
3193 (rotate:QI (match_operand:QI 1 "register_operand" "")
3194 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3197 if (!CONST_INT_P (operands[2]))
3200 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3203 ;; Expander used by __builtin_avr_swap
3204 (define_expand "rotlqi3_4"
3205 [(set (match_operand:QI 0 "register_operand" "")
3206 (rotate:QI (match_operand:QI 1 "register_operand" "")
3209 (define_insn "*rotlqi3"
3210 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3211 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3212 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3215 lsl %0\;adc %0,__zero_reg__
3216 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3217 swap %0\;bst %0,0\;ror %0\;bld %0,7
3219 swap %0\;lsl %0\;adc %0,__zero_reg__
3220 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3221 bst %0,0\;ror %0\;bld %0,7
3223 [(set_attr "length" "2,4,4,1,3,5,3,0")
3224 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3226 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3227 ;; a whole number of bytes. The split creates the appropriate moves and
3228 ;; considers all overlap situations.
3230 ;; HImode does not need scratch. Use attribute for this constraint.
3232 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3233 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3238 (define_expand "rotl<mode>3"
3239 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3240 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3241 (match_operand:VOID 2 "const_int_operand" "")))
3242 (clobber (match_dup 3))])]
3247 if (!CONST_INT_P (operands[2]))
3250 offset = INTVAL (operands[2]);
3252 if (0 == offset % 8)
3254 if (AVR_HAVE_MOVW && 0 == offset % 16)
3255 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3257 operands[3] = gen_rtx_SCRATCH (QImode);
3259 else if (offset == 1
3260 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3262 /*; Support rotate left/right by 1 */
3264 emit_move_insn (operands[0],
3265 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3272 (define_insn "*rotlhi2.1"
3273 [(set (match_operand:HI 0 "register_operand" "=r")
3274 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3277 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3278 [(set_attr "length" "3")
3279 (set_attr "cc" "clobber")])
3281 (define_insn "*rotlhi2.15"
3282 [(set (match_operand:HI 0 "register_operand" "=r")
3283 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3286 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3287 [(set_attr "length" "4")
3288 (set_attr "cc" "clobber")])
3290 (define_insn "*rotlpsi2.1"
3291 [(set (match_operand:PSI 0 "register_operand" "=r")
3292 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3295 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3296 [(set_attr "length" "4")
3297 (set_attr "cc" "clobber")])
3299 (define_insn "*rotlpsi2.23"
3300 [(set (match_operand:PSI 0 "register_operand" "=r")
3301 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3304 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3305 [(set_attr "length" "5")
3306 (set_attr "cc" "clobber")])
3308 (define_insn "*rotlsi2.1"
3309 [(set (match_operand:SI 0 "register_operand" "=r")
3310 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3313 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3314 [(set_attr "length" "5")
3315 (set_attr "cc" "clobber")])
3317 (define_insn "*rotlsi2.31"
3318 [(set (match_operand:SI 0 "register_operand" "=r")
3319 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3322 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3323 [(set_attr "length" "6")
3324 (set_attr "cc" "clobber")])
3326 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3327 ;; The best we can do is use early clobber alternative "#&r" so that
3328 ;; completely non-overlapping operands dont get a scratch but # so register
3329 ;; allocation does not prefer non-overlapping.
3332 ;; Split word aligned rotates using scratch that is mode dependent.
3336 (define_insn_and_split "*rotw<mode>"
3337 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3338 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3339 (match_operand 2 "const_int_operand" "n,n,n")))
3340 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3342 && CONST_INT_P (operands[2])
3343 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3344 && 0 == INTVAL (operands[2]) % 16"
3346 "&& reload_completed"
3349 avr_rotate_bytes (operands);
3354 ;; Split byte aligned rotates using scratch that is always QI mode.
3359 (define_insn_and_split "*rotb<mode>"
3360 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3361 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3362 (match_operand 2 "const_int_operand" "n,n,n")))
3363 (clobber (match_scratch:QI 3 "=<rotx>"))]
3364 "CONST_INT_P (operands[2])
3365 && (8 == INTVAL (operands[2]) % 16
3367 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3368 && 0 == INTVAL (operands[2]) % 16))"
3370 "&& reload_completed"
3373 avr_rotate_bytes (operands);
3378 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3379 ;; arithmetic shift left
3382 ;; "ashlqq3" "ashluqq3"
3383 (define_expand "ashl<mode>3"
3384 [(set (match_operand:ALL1 0 "register_operand" "")
3385 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3386 (match_operand:QI 2 "nop_general_operand" "")))])
3388 (define_split ; ashlqi3_const4
3389 [(set (match_operand:ALL1 0 "d_register_operand" "")
3390 (ashift:ALL1 (match_dup 0)
3394 (rotate:QI (match_dup 1)
3397 (and:QI (match_dup 1)
3400 operands[1] = avr_to_int_mode (operands[0]);
3403 (define_split ; ashlqi3_const5
3404 [(set (match_operand:ALL1 0 "d_register_operand" "")
3405 (ashift:ALL1 (match_dup 0)
3408 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3409 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3410 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3412 operands[1] = avr_to_int_mode (operands[0]);
3415 (define_split ; ashlqi3_const6
3416 [(set (match_operand:ALL1 0 "d_register_operand" "")
3417 (ashift:ALL1 (match_dup 0)
3420 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3421 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3422 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3424 operands[1] = avr_to_int_mode (operands[0]);
3428 ;; "*ashlqq3" "*ashluqq3"
3429 (define_insn "*ashl<mode>3"
3430 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3431 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3432 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3435 return ashlqi3_out (insn, operands, NULL);
3437 [(set_attr "length" "5,0,1,2,4,6,9")
3438 (set_attr "adjust_len" "ashlqi")
3439 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3441 (define_insn "ashl<mode>3"
3442 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3443 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3444 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3447 return ashlhi3_out (insn, operands, NULL);
3449 [(set_attr "length" "6,0,2,2,4,10,10")
3450 (set_attr "adjust_len" "ashlhi")
3451 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3454 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3455 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3459 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3460 [(set (match_operand:QI 0 "register_operand" "=r")
3461 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3462 (match_operand:QI 2 "register_operand" "r"))
3468 (ashift:QI (match_dup 1)
3471 ;; ??? Combiner does not recognize that it could split the following insn;
3472 ;; presumably because he has no register handy?
3474 ;; "*ashluqihiqi3.mem"
3475 ;; "*ashlsqihiqi3.mem"
3476 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3477 [(set (match_operand:QI 0 "memory_operand" "=m")
3478 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3479 (match_operand:QI 2 "register_operand" "r"))
3482 { gcc_unreachable(); }
3485 (ashift:QI (match_dup 1)
3490 operands[3] = gen_reg_rtx (QImode);
3495 (define_insn_and_split "*ashlhiqi3"
3496 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3497 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3498 (match_operand:QI 2 "register_operand" "r")) 0))]
3500 { gcc_unreachable(); }
3503 (ashift:QI (match_dup 3)
3508 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3509 operands[4] = gen_reg_rtx (QImode);
3512 ;; High part of 16-bit shift is unused after the instruction:
3513 ;; No need to compute it, map to 8-bit shift.
3516 [(set (match_operand:HI 0 "register_operand" "")
3517 (ashift:HI (match_dup 0)
3518 (match_operand:QI 1 "register_operand" "")))]
3521 (ashift:QI (match_dup 2)
3523 (clobber (match_dup 3))]
3525 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3527 if (!peep2_reg_dead_p (1, operands[3]))
3530 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3535 ;; "ashlsq3" "ashlusq3"
3536 ;; "ashlsa3" "ashlusa3"
3537 (define_insn "ashl<mode>3"
3538 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3539 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3540 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3543 return ashlsi3_out (insn, operands, NULL);
3545 [(set_attr "length" "8,0,4,4,8,10,12")
3546 (set_attr "adjust_len" "ashlsi")
3547 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3549 ;; Optimize if a scratch register from LD_REGS happens to be available.
3551 (define_peephole2 ; ashlqi3_l_const4
3552 [(set (match_operand:ALL1 0 "l_register_operand" "")
3553 (ashift:ALL1 (match_dup 0)
3555 (match_scratch:QI 1 "d")]
3557 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3558 (set (match_dup 1) (const_int -16))
3559 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3561 operands[2] = avr_to_int_mode (operands[0]);
3564 (define_peephole2 ; ashlqi3_l_const5
3565 [(set (match_operand:ALL1 0 "l_register_operand" "")
3566 (ashift:ALL1 (match_dup 0)
3568 (match_scratch:QI 1 "d")]
3570 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3571 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3572 (set (match_dup 1) (const_int -32))
3573 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3575 operands[2] = avr_to_int_mode (operands[0]);
3578 (define_peephole2 ; ashlqi3_l_const6
3579 [(set (match_operand:ALL1 0 "l_register_operand" "")
3580 (ashift:ALL1 (match_dup 0)
3582 (match_scratch:QI 1 "d")]
3584 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3585 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3586 (set (match_dup 1) (const_int -64))
3587 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3589 operands[2] = avr_to_int_mode (operands[0]);
3593 [(match_scratch:QI 3 "d")
3594 (set (match_operand:ALL2 0 "register_operand" "")
3595 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3596 (match_operand:QI 2 "const_int_operand" "")))]
3598 [(parallel [(set (match_dup 0)
3599 (ashift:ALL2 (match_dup 1)
3601 (clobber (match_dup 3))])])
3604 ;; "*ashlhq3_const" "*ashluhq3_const"
3605 ;; "*ashlha3_const" "*ashluha3_const"
3606 (define_insn "*ashl<mode>3_const"
3607 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3608 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3609 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3610 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3613 return ashlhi3_out (insn, operands, NULL);
3615 [(set_attr "length" "0,2,2,4,10")
3616 (set_attr "adjust_len" "ashlhi")
3617 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3620 [(match_scratch:QI 3 "d")
3621 (set (match_operand:ALL4 0 "register_operand" "")
3622 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3623 (match_operand:QI 2 "const_int_operand" "")))]
3625 [(parallel [(set (match_dup 0)
3626 (ashift:ALL4 (match_dup 1)
3628 (clobber (match_dup 3))])]
3632 ;; "*ashlsq3_const" "*ashlusq3_const"
3633 ;; "*ashlsa3_const" "*ashlusa3_const"
3634 (define_insn "*ashl<mode>3_const"
3635 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3636 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3637 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3638 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3641 return ashlsi3_out (insn, operands, NULL);
3643 [(set_attr "length" "0,4,4,10")
3644 (set_attr "adjust_len" "ashlsi")
3645 (set_attr "cc" "none,set_n,clobber,clobber")])
3647 (define_expand "ashlpsi3"
3648 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3649 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3650 (match_operand:QI 2 "nonmemory_operand" "")))
3651 (clobber (scratch:QI))])]
3655 && CONST_INT_P (operands[2]))
3657 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3659 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3660 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3663 else if (optimize_insn_for_speed_p ()
3664 && INTVAL (operands[2]) != 16
3665 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3667 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3668 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3674 (define_insn "*ashlpsi3"
3675 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3676 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3677 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3678 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3681 return avr_out_ashlpsi3 (insn, operands, NULL);
3683 [(set_attr "adjust_len" "ashlpsi")
3684 (set_attr "cc" "clobber")])
3686 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3687 ;; arithmetic shift right
3690 ;; "ashrqq3" "ashruqq3"
3691 (define_insn "ashr<mode>3"
3692 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3693 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3694 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3697 return ashrqi3_out (insn, operands, NULL);
3699 [(set_attr "length" "5,0,1,2,5,4,9")
3700 (set_attr "adjust_len" "ashrqi")
3701 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3704 ;; "ashrhq3" "ashruhq3"
3705 ;; "ashrha3" "ashruha3"
3706 (define_insn "ashr<mode>3"
3707 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3708 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3709 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3712 return ashrhi3_out (insn, operands, NULL);
3714 [(set_attr "length" "6,0,2,4,4,10,10")
3715 (set_attr "adjust_len" "ashrhi")
3716 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3718 (define_insn "ashrpsi3"
3719 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3720 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3721 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3722 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3725 return avr_out_ashrpsi3 (insn, operands, NULL);
3727 [(set_attr "adjust_len" "ashrpsi")
3728 (set_attr "cc" "clobber")])
3731 ;; "ashrsq3" "ashrusq3"
3732 ;; "ashrsa3" "ashrusa3"
3733 (define_insn "ashr<mode>3"
3734 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3735 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3736 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3739 return ashrsi3_out (insn, operands, NULL);
3741 [(set_attr "length" "8,0,4,6,8,10,12")
3742 (set_attr "adjust_len" "ashrsi")
3743 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3745 ;; Optimize if a scratch register from LD_REGS happens to be available.
3748 [(match_scratch:QI 3 "d")
3749 (set (match_operand:ALL2 0 "register_operand" "")
3750 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3751 (match_operand:QI 2 "const_int_operand" "")))]
3753 [(parallel [(set (match_dup 0)
3754 (ashiftrt:ALL2 (match_dup 1)
3756 (clobber (match_dup 3))])])
3759 ;; "*ashrhq3_const" "*ashruhq3_const"
3760 ;; "*ashrha3_const" "*ashruha3_const"
3761 (define_insn "*ashr<mode>3_const"
3762 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3763 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3764 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3765 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3768 return ashrhi3_out (insn, operands, NULL);
3770 [(set_attr "length" "0,2,4,4,10")
3771 (set_attr "adjust_len" "ashrhi")
3772 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3775 [(match_scratch:QI 3 "d")
3776 (set (match_operand:ALL4 0 "register_operand" "")
3777 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3778 (match_operand:QI 2 "const_int_operand" "")))]
3780 [(parallel [(set (match_dup 0)
3781 (ashiftrt:ALL4 (match_dup 1)
3783 (clobber (match_dup 3))])])
3786 ;; "*ashrsq3_const" "*ashrusq3_const"
3787 ;; "*ashrsa3_const" "*ashrusa3_const"
3788 (define_insn "*ashr<mode>3_const"
3789 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3790 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3791 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3792 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3795 return ashrsi3_out (insn, operands, NULL);
3797 [(set_attr "length" "0,4,4,10")
3798 (set_attr "adjust_len" "ashrsi")
3799 (set_attr "cc" "none,clobber,set_n,clobber")])
3801 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3802 ;; logical shift right
3805 ;; "lshrqq3 "lshruqq3"
3806 (define_expand "lshr<mode>3"
3807 [(set (match_operand:ALL1 0 "register_operand" "")
3808 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3809 (match_operand:QI 2 "nop_general_operand" "")))])
3811 (define_split ; lshrqi3_const4
3812 [(set (match_operand:ALL1 0 "d_register_operand" "")
3813 (lshiftrt:ALL1 (match_dup 0)
3817 (rotate:QI (match_dup 1)
3820 (and:QI (match_dup 1)
3823 operands[1] = avr_to_int_mode (operands[0]);
3826 (define_split ; lshrqi3_const5
3827 [(set (match_operand:ALL1 0 "d_register_operand" "")
3828 (lshiftrt:ALL1 (match_dup 0)
3831 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3832 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3833 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3835 operands[1] = avr_to_int_mode (operands[0]);
3838 (define_split ; lshrqi3_const6
3839 [(set (match_operand:QI 0 "d_register_operand" "")
3840 (lshiftrt:QI (match_dup 0)
3843 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3844 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3845 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3847 operands[1] = avr_to_int_mode (operands[0]);
3853 (define_insn "*lshr<mode>3"
3854 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3855 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3856 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3859 return lshrqi3_out (insn, operands, NULL);
3861 [(set_attr "length" "5,0,1,2,4,6,9")
3862 (set_attr "adjust_len" "lshrqi")
3863 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3866 ;; "lshrhq3" "lshruhq3"
3867 ;; "lshrha3" "lshruha3"
3868 (define_insn "lshr<mode>3"
3869 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3870 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3871 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3874 return lshrhi3_out (insn, operands, NULL);
3876 [(set_attr "length" "6,0,2,2,4,10,10")
3877 (set_attr "adjust_len" "lshrhi")
3878 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3880 (define_insn "lshrpsi3"
3881 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3882 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3883 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3884 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3887 return avr_out_lshrpsi3 (insn, operands, NULL);
3889 [(set_attr "adjust_len" "lshrpsi")
3890 (set_attr "cc" "clobber")])
3893 ;; "lshrsq3" "lshrusq3"
3894 ;; "lshrsa3" "lshrusa3"
3895 (define_insn "lshr<mode>3"
3896 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3897 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3898 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3901 return lshrsi3_out (insn, operands, NULL);
3903 [(set_attr "length" "8,0,4,4,8,10,12")
3904 (set_attr "adjust_len" "lshrsi")
3905 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3907 ;; Optimize if a scratch register from LD_REGS happens to be available.
3909 (define_peephole2 ; lshrqi3_l_const4
3910 [(set (match_operand:ALL1 0 "l_register_operand" "")
3911 (lshiftrt:ALL1 (match_dup 0)
3913 (match_scratch:QI 1 "d")]
3915 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3916 (set (match_dup 1) (const_int 15))
3917 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3919 operands[2] = avr_to_int_mode (operands[0]);
3922 (define_peephole2 ; lshrqi3_l_const5
3923 [(set (match_operand:ALL1 0 "l_register_operand" "")
3924 (lshiftrt:ALL1 (match_dup 0)
3926 (match_scratch:QI 1 "d")]
3928 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3929 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3930 (set (match_dup 1) (const_int 7))
3931 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3933 operands[2] = avr_to_int_mode (operands[0]);
3936 (define_peephole2 ; lshrqi3_l_const6
3937 [(set (match_operand:ALL1 0 "l_register_operand" "")
3938 (lshiftrt:ALL1 (match_dup 0)
3940 (match_scratch:QI 1 "d")]
3942 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3943 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3944 (set (match_dup 1) (const_int 3))
3945 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3947 operands[2] = avr_to_int_mode (operands[0]);
3951 [(match_scratch:QI 3 "d")
3952 (set (match_operand:ALL2 0 "register_operand" "")
3953 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3954 (match_operand:QI 2 "const_int_operand" "")))]
3956 [(parallel [(set (match_dup 0)
3957 (lshiftrt:ALL2 (match_dup 1)
3959 (clobber (match_dup 3))])])
3962 ;; "*lshrhq3_const" "*lshruhq3_const"
3963 ;; "*lshrha3_const" "*lshruha3_const"
3964 (define_insn "*lshr<mode>3_const"
3965 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3966 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3967 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3968 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3971 return lshrhi3_out (insn, operands, NULL);
3973 [(set_attr "length" "0,2,2,4,10")
3974 (set_attr "adjust_len" "lshrhi")
3975 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3978 [(match_scratch:QI 3 "d")
3979 (set (match_operand:ALL4 0 "register_operand" "")
3980 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3981 (match_operand:QI 2 "const_int_operand" "")))]
3983 [(parallel [(set (match_dup 0)
3984 (lshiftrt:ALL4 (match_dup 1)
3986 (clobber (match_dup 3))])])
3989 ;; "*lshrsq3_const" "*lshrusq3_const"
3990 ;; "*lshrsa3_const" "*lshrusa3_const"
3991 (define_insn "*lshr<mode>3_const"
3992 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3993 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3994 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3995 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3998 return lshrsi3_out (insn, operands, NULL);
4000 [(set_attr "length" "0,4,4,10")
4001 (set_attr "adjust_len" "lshrsi")
4002 (set_attr "cc" "none,clobber,clobber,clobber")])
4004 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
4007 (define_insn "absqi2"
4008 [(set (match_operand:QI 0 "register_operand" "=r")
4009 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
4013 [(set_attr "length" "2")
4014 (set_attr "cc" "clobber")])
4017 (define_insn "abssf2"
4018 [(set (match_operand:SF 0 "register_operand" "=d,r")
4019 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
4024 [(set_attr "length" "1,2")
4025 (set_attr "cc" "set_n,clobber")])
4027 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
4030 (define_insn "negqi2"
4031 [(set (match_operand:QI 0 "register_operand" "=r")
4032 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
4035 [(set_attr "length" "1")
4036 (set_attr "cc" "set_zn")])
4038 (define_insn "*negqihi2"
4039 [(set (match_operand:HI 0 "register_operand" "=r")
4040 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
4042 "clr %B0\;neg %A0\;brge .+2\;com %B0"
4043 [(set_attr "length" "4")
4044 (set_attr "cc" "set_n")])
4046 (define_insn "neghi2"
4047 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4048 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4051 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4052 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4053 [(set_attr "length" "3,4")
4054 (set_attr "cc" "set_czn")])
4056 (define_insn "negpsi2"
4057 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4058 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4061 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4062 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4063 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4064 [(set_attr "length" "5,6,6")
4065 (set_attr "cc" "set_czn,set_n,set_czn")])
4067 (define_insn "negsi2"
4068 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4069 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4072 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4073 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4074 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4075 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4076 [(set_attr "length" "7,8,8,7")
4077 (set_attr "isa" "*,*,mov,movw")
4078 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4080 (define_insn "negsf2"
4081 [(set (match_operand:SF 0 "register_operand" "=d,r")
4082 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4086 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4087 [(set_attr "length" "1,4")
4088 (set_attr "cc" "set_n,set_n")])
4090 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4093 (define_insn "one_cmplqi2"
4094 [(set (match_operand:QI 0 "register_operand" "=r")
4095 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4098 [(set_attr "length" "1")
4099 (set_attr "cc" "set_czn")])
4101 (define_insn "one_cmplhi2"
4102 [(set (match_operand:HI 0 "register_operand" "=r")
4103 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4107 [(set_attr "length" "2")
4108 (set_attr "cc" "set_n")])
4110 (define_insn "one_cmplpsi2"
4111 [(set (match_operand:PSI 0 "register_operand" "=r")
4112 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4114 "com %0\;com %B0\;com %C0"
4115 [(set_attr "length" "3")
4116 (set_attr "cc" "set_n")])
4118 (define_insn "one_cmplsi2"
4119 [(set (match_operand:SI 0 "register_operand" "=r")
4120 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4126 [(set_attr "length" "4")
4127 (set_attr "cc" "set_n")])
4129 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4132 ;; We keep combiner from inserting hard registers into the input of sign- and
4133 ;; zero-extends. A hard register in the input operand is not wanted because
4134 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4135 ;; hard register that overlaps these clobbers won't be combined to a widening
4136 ;; multiplication. There is no need for combine to propagate hard registers,
4137 ;; register allocation can do it just as well.
4139 (define_insn "extendqihi2"
4140 [(set (match_operand:HI 0 "register_operand" "=r,r")
4141 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4144 clr %B0\;sbrc %0,7\;com %B0
4145 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4146 [(set_attr "length" "3,4")
4147 (set_attr "cc" "set_n,set_n")])
4149 (define_insn "extendqipsi2"
4150 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4151 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4154 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4155 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4156 [(set_attr "length" "4,5")
4157 (set_attr "cc" "set_n,set_n")])
4159 (define_insn "extendqisi2"
4160 [(set (match_operand:SI 0 "register_operand" "=r,r")
4161 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4164 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4165 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4166 [(set_attr "length" "5,6")
4167 (set_attr "cc" "set_n,set_n")])
4169 (define_insn "extendhipsi2"
4170 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4171 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4174 clr %C0\;sbrc %B0,7\;com %C0
4175 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4176 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4177 [(set_attr "length" "3,5,4")
4178 (set_attr "isa" "*,mov,movw")
4179 (set_attr "cc" "set_n")])
4181 (define_insn "extendhisi2"
4182 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4183 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4186 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4187 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4188 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4189 [(set_attr "length" "4,6,5")
4190 (set_attr "isa" "*,mov,movw")
4191 (set_attr "cc" "set_n")])
4193 (define_insn "extendpsisi2"
4194 [(set (match_operand:SI 0 "register_operand" "=r")
4195 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4197 "clr %D0\;sbrc %C0,7\;com %D0"
4198 [(set_attr "length" "3")
4199 (set_attr "cc" "set_n")])
4201 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4204 (define_insn_and_split "zero_extendqihi2"
4205 [(set (match_operand:HI 0 "register_operand" "=r")
4206 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4210 [(set (match_dup 2) (match_dup 1))
4211 (set (match_dup 3) (const_int 0))]
4213 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4214 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4216 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4217 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4220 (define_insn_and_split "zero_extendqipsi2"
4221 [(set (match_operand:PSI 0 "register_operand" "=r")
4222 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4226 [(set (match_dup 2) (match_dup 1))
4227 (set (match_dup 3) (const_int 0))
4228 (set (match_dup 4) (const_int 0))]
4230 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4231 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4232 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4235 (define_insn_and_split "zero_extendqisi2"
4236 [(set (match_operand:SI 0 "register_operand" "=r")
4237 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4241 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4242 (set (match_dup 3) (const_int 0))]
4244 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4245 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4247 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4248 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4251 (define_insn_and_split "zero_extendhipsi2"
4252 [(set (match_operand:PSI 0 "register_operand" "=r")
4253 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4257 [(set (match_dup 2) (match_dup 1))
4258 (set (match_dup 3) (const_int 0))]
4260 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4261 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4264 (define_insn_and_split "n_extendhipsi2"
4265 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4266 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4267 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4268 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4272 [(set (match_dup 4) (match_dup 2))
4273 (set (match_dup 3) (match_dup 6))
4274 ; no-op move in the case where no scratch is needed
4275 (set (match_dup 5) (match_dup 3))]
4277 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4278 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4279 operands[6] = operands[1];
4281 if (GET_CODE (operands[3]) == SCRATCH)
4282 operands[3] = operands[5];
4285 (define_insn_and_split "zero_extendhisi2"
4286 [(set (match_operand:SI 0 "register_operand" "=r")
4287 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4291 [(set (match_dup 2) (match_dup 1))
4292 (set (match_dup 3) (const_int 0))]
4294 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4295 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4297 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4298 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4301 (define_insn_and_split "zero_extendpsisi2"
4302 [(set (match_operand:SI 0 "register_operand" "=r")
4303 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4307 [(set (match_dup 2) (match_dup 1))
4308 (set (match_dup 3) (const_int 0))]
4310 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4311 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4314 (define_insn_and_split "zero_extendqidi2"
4315 [(set (match_operand:DI 0 "register_operand" "=r")
4316 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4320 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4321 (set (match_dup 3) (const_int 0))]
4323 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4324 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4326 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4327 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4330 (define_insn_and_split "zero_extendhidi2"
4331 [(set (match_operand:DI 0 "register_operand" "=r")
4332 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4336 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4337 (set (match_dup 3) (const_int 0))]
4339 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4340 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4342 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4343 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4346 (define_insn_and_split "zero_extendsidi2"
4347 [(set (match_operand:DI 0 "register_operand" "=r")
4348 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4352 [(set (match_dup 2) (match_dup 1))
4353 (set (match_dup 3) (const_int 0))]
4355 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4356 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4358 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4359 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4362 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4365 ; Optimize negated tests into reverse compare if overflow is undefined.
4366 (define_insn "*negated_tstqi"
4368 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4370 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4371 "cp __zero_reg__,%0"
4372 [(set_attr "cc" "compare")
4373 (set_attr "length" "1")])
4375 (define_insn "*reversed_tstqi"
4377 (compare (const_int 0)
4378 (match_operand:QI 0 "register_operand" "r")))]
4380 "cp __zero_reg__,%0"
4381 [(set_attr "cc" "compare")
4382 (set_attr "length" "2")])
4384 (define_insn "*negated_tsthi"
4386 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4388 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4389 "cp __zero_reg__,%A0
4390 cpc __zero_reg__,%B0"
4391 [(set_attr "cc" "compare")
4392 (set_attr "length" "2")])
4394 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4395 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4396 (define_insn "*reversed_tsthi"
4398 (compare (const_int 0)
4399 (match_operand:HI 0 "register_operand" "r")))
4400 (clobber (match_scratch:QI 1 "=X"))]
4402 "cp __zero_reg__,%A0
4403 cpc __zero_reg__,%B0"
4404 [(set_attr "cc" "compare")
4405 (set_attr "length" "2")])
4407 (define_insn "*negated_tstpsi"
4409 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4411 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4412 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4413 [(set_attr "cc" "compare")
4414 (set_attr "length" "3")])
4416 (define_insn "*reversed_tstpsi"
4418 (compare (const_int 0)
4419 (match_operand:PSI 0 "register_operand" "r")))
4420 (clobber (match_scratch:QI 1 "=X"))]
4422 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4423 [(set_attr "cc" "compare")
4424 (set_attr "length" "3")])
4426 (define_insn "*negated_tstsi"
4428 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4430 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4431 "cp __zero_reg__,%A0
4432 cpc __zero_reg__,%B0
4433 cpc __zero_reg__,%C0
4434 cpc __zero_reg__,%D0"
4435 [(set_attr "cc" "compare")
4436 (set_attr "length" "4")])
4438 ;; "*reversed_tstsi"
4439 ;; "*reversed_tstsq" "*reversed_tstusq"
4440 ;; "*reversed_tstsa" "*reversed_tstusa"
4441 (define_insn "*reversed_tst<mode>"
4443 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4444 (match_operand:ALL4 1 "register_operand" "r")))
4445 (clobber (match_scratch:QI 2 "=X"))]
4447 "cp __zero_reg__,%A1
4448 cpc __zero_reg__,%B1
4449 cpc __zero_reg__,%C1
4450 cpc __zero_reg__,%D1"
4451 [(set_attr "cc" "compare")
4452 (set_attr "length" "4")])
4456 ;; "*cmpqq" "*cmpuqq"
4457 (define_insn "*cmp<mode>"
4459 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4460 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4466 [(set_attr "cc" "compare,compare,compare")
4467 (set_attr "length" "1,1,1")])
4469 (define_insn "*cmpqi_sign_extend"
4471 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4472 (match_operand:HI 1 "s8_operand" "n")))]
4475 [(set_attr "cc" "compare")
4476 (set_attr "length" "1")])
4479 ;; "*cmphq" "*cmpuhq"
4480 ;; "*cmpha" "*cmpuha"
4481 (define_insn "*cmp<mode>"
4483 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4484 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4485 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4488 switch (which_alternative)
4492 return avr_out_tsthi (insn, operands, NULL);
4495 return "cp %A0,%A1\;cpc %B0,%B1";
4498 if (<MODE>mode != HImode)
4500 return reg_unused_after (insn, operands[0])
4501 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4502 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4505 if (<MODE>mode != HImode)
4507 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4510 return avr_out_compare (insn, operands, NULL);
4512 [(set_attr "cc" "compare")
4513 (set_attr "length" "1,2,2,3,4,2,4")
4514 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4516 (define_insn "*cmppsi"
4518 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4519 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4520 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4523 switch (which_alternative)
4526 return avr_out_tstpsi (insn, operands, NULL);
4529 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4532 return reg_unused_after (insn, operands[0])
4533 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4534 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4537 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4540 return avr_out_compare (insn, operands, NULL);
4542 [(set_attr "cc" "compare")
4543 (set_attr "length" "3,3,5,6,3,7")
4544 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4547 ;; "*cmpsq" "*cmpusq"
4548 ;; "*cmpsa" "*cmpusa"
4549 (define_insn "*cmp<mode>"
4551 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4552 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4553 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4556 if (0 == which_alternative)
4557 return avr_out_tstsi (insn, operands, NULL);
4558 else if (1 == which_alternative)
4559 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4561 return avr_out_compare (insn, operands, NULL);
4563 [(set_attr "cc" "compare")
4564 (set_attr "length" "4,4,4,5,8")
4565 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4568 ;; ----------------------------------------------------------------------
4569 ;; JUMP INSTRUCTIONS
4570 ;; ----------------------------------------------------------------------
4571 ;; Conditional jump instructions
4574 ;; "cbranchqq4" "cbranchuqq4"
4575 (define_expand "cbranch<mode>4"
4577 (compare (match_operand:ALL1 1 "register_operand" "")
4578 (match_operand:ALL1 2 "nonmemory_operand" "")))
4581 (match_operator 0 "ordered_comparison_operator" [(cc0)
4583 (label_ref (match_operand 3 "" ""))
4586 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4587 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4589 (define_expand "cbranch<mode>4"
4590 [(parallel [(set (cc0)
4591 (compare (match_operand:ORDERED234 1 "register_operand" "")
4592 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4593 (clobber (match_scratch:QI 4 ""))])
4596 (match_operator 0 "ordered_comparison_operator" [(cc0)
4598 (label_ref (match_operand 3 "" ""))
4602 ;; Test a single bit in a QI/HI/SImode register.
4603 ;; Combine will create zero extract patterns for single bit tests.
4604 ;; permit any mode in source pattern by using VOIDmode.
4606 (define_insn "*sbrx_branch<mode>"
4609 (match_operator 0 "eqne_operator"
4611 (match_operand:VOID 1 "register_operand" "r")
4613 (match_operand 2 "const_int_operand" "n"))
4615 (label_ref (match_operand 3 "" ""))
4619 return avr_out_sbxx_branch (insn, operands);
4621 [(set (attr "length")
4622 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4623 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4625 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4628 (set_attr "cc" "clobber")])
4630 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4631 ;; or for old peepholes.
4632 ;; Fixme - bitwise Mask will not work for DImode
4634 (define_insn "*sbrx_and_branch<mode>"
4637 (match_operator 0 "eqne_operator"
4639 (match_operand:QISI 1 "register_operand" "r")
4640 (match_operand:QISI 2 "single_one_operand" "n"))
4642 (label_ref (match_operand 3 "" ""))
4646 HOST_WIDE_INT bitnumber;
4647 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4648 operands[2] = GEN_INT (bitnumber);
4649 return avr_out_sbxx_branch (insn, operands);
4651 [(set (attr "length")
4652 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4653 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4655 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4658 (set_attr "cc" "clobber")])
4660 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4662 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4664 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4665 (label_ref (match_operand 1 "" ""))
4668 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4672 (label_ref (match_dup 1))
4677 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4679 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4680 (label_ref (match_operand 1 "" ""))
4683 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4687 (label_ref (match_dup 1))
4692 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4694 (clobber (match_operand:HI 2 ""))])
4695 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4696 (label_ref (match_operand 1 "" ""))
4699 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4701 (label_ref (match_dup 1))
4706 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4708 (clobber (match_operand:HI 2 ""))])
4709 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4710 (label_ref (match_operand 1 "" ""))
4713 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4715 (label_ref (match_dup 1))
4720 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4722 (clobber (match_operand:SI 2 ""))])
4723 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4724 (label_ref (match_operand 1 "" ""))
4727 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4729 (label_ref (match_dup 1))
4731 "operands[2] = GEN_INT (-2147483647 - 1);")
4734 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4736 (clobber (match_operand:SI 2 ""))])
4737 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4738 (label_ref (match_operand 1 "" ""))
4741 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4743 (label_ref (match_dup 1))
4745 "operands[2] = GEN_INT (-2147483647 - 1);")
4747 ;; ************************************************************************
4748 ;; Implementation of conditional jumps here.
4749 ;; Compare with 0 (test) jumps
4750 ;; ************************************************************************
4752 (define_insn "branch"
4754 (if_then_else (match_operator 1 "simple_comparison_operator"
4757 (label_ref (match_operand 0 "" ""))
4761 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4763 [(set_attr "type" "branch")
4764 (set_attr "cc" "clobber")])
4767 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4768 ;; or optimized in the remainder.
4770 (define_insn "branch_unspec"
4772 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4775 (label_ref (match_operand 0 "" ""))
4777 ] UNSPEC_IDENTITY))]
4780 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4782 [(set_attr "type" "branch")
4783 (set_attr "cc" "none")])
4785 ;; ****************************************************************
4786 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4787 ;; Convert them all to proper jumps.
4788 ;; ****************************************************************/
4790 (define_insn "difficult_branch"
4792 (if_then_else (match_operator 1 "difficult_comparison_operator"
4795 (label_ref (match_operand 0 "" ""))
4799 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4801 [(set_attr "type" "branch1")
4802 (set_attr "cc" "clobber")])
4806 (define_insn "rvbranch"
4808 (if_then_else (match_operator 1 "simple_comparison_operator"
4812 (label_ref (match_operand 0 "" ""))))]
4815 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4817 [(set_attr "type" "branch1")
4818 (set_attr "cc" "clobber")])
4820 (define_insn "difficult_rvbranch"
4822 (if_then_else (match_operator 1 "difficult_comparison_operator"
4826 (label_ref (match_operand 0 "" ""))))]
4829 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4831 [(set_attr "type" "branch")
4832 (set_attr "cc" "clobber")])
4834 ;; **************************************************************************
4835 ;; Unconditional and other jump instructions.
4839 (label_ref (match_operand 0 "" "")))]
4842 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4846 [(set (attr "length")
4847 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4848 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4851 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4852 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4855 (set_attr "cc" "none")])
4859 (define_expand "call"
4860 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4861 (match_operand:HI 1 "general_operand" ""))
4862 (use (const_int 0))])]
4863 ;; Operand 1 not used on the AVR.
4864 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4868 (define_expand "sibcall"
4869 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4870 (match_operand:HI 1 "general_operand" ""))
4871 (use (const_int 1))])]
4872 ;; Operand 1 not used on the AVR.
4873 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4879 (define_expand "call_value"
4880 [(parallel[(set (match_operand 0 "register_operand" "")
4881 (call (match_operand:HI 1 "call_insn_operand" "")
4882 (match_operand:HI 2 "general_operand" "")))
4883 (use (const_int 0))])]
4884 ;; Operand 2 not used on the AVR.
4885 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4889 (define_expand "sibcall_value"
4890 [(parallel[(set (match_operand 0 "register_operand" "")
4891 (call (match_operand:HI 1 "call_insn_operand" "")
4892 (match_operand:HI 2 "general_operand" "")))
4893 (use (const_int 1))])]
4894 ;; Operand 2 not used on the AVR.
4895 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4899 (define_insn "call_insn"
4900 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4901 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4902 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4903 ;; Operand 1 not used on the AVR.
4904 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4911 [(set_attr "cc" "clobber")
4912 (set_attr "length" "1,*,1,*")
4913 (set_attr "adjust_len" "*,call,*,call")])
4915 (define_insn "call_value_insn"
4916 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4917 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4918 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4919 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4920 ;; Operand 2 not used on the AVR.
4921 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4928 [(set_attr "cc" "clobber")
4929 (set_attr "length" "1,*,1,*")
4930 (set_attr "adjust_len" "*,call,*,call")])
4936 [(set_attr "cc" "none")
4937 (set_attr "length" "1")])
4941 (define_expand "indirect_jump"
4943 (match_operand:HI 0 "nonmemory_operand" ""))]
4946 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4948 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4953 (define_insn "*indirect_jump"
4955 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4961 push %A0\;push %B0\;ret
4963 [(set_attr "length" "1,2,1,3,1")
4964 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4965 (set_attr "cc" "none")])
4968 ;; For entries in jump table see avr_output_addr_vec_elt.
4971 ;; "rjmp .L<n>" instructions for <= 8K devices
4972 ;; ".word gs(.L<n>)" addresses for > 8K devices
4973 (define_insn "*tablejump"
4975 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4977 (use (label_ref (match_operand 1 "" "")))
4978 (clobber (match_dup 0))]
4982 push %A0\;push %B0\;ret
4984 [(set_attr "length" "1,3,2")
4985 (set_attr "isa" "rjmp,rjmp,jmp")
4986 (set_attr "cc" "none,none,clobber")])
4989 (define_expand "casesi"
4990 [(parallel [(set (match_dup 6)
4991 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4992 (match_operand:HI 1 "register_operand" "")))
4993 (clobber (scratch:QI))])
4994 (parallel [(set (cc0)
4995 (compare (match_dup 6)
4996 (match_operand:HI 2 "register_operand" "")))
4997 (clobber (match_scratch:QI 9 ""))])
5000 (if_then_else (gtu (cc0)
5002 (label_ref (match_operand 4 "" ""))
5006 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
5008 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
5009 (use (label_ref (match_dup 3)))
5010 (clobber (match_dup 6))])]
5013 operands[6] = gen_reg_rtx (HImode);
5017 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5018 ;; This instruction sets Z flag
5021 [(set (cc0) (const_int 0))]
5024 [(set_attr "length" "1")
5025 (set_attr "cc" "compare")])
5027 ;; Clear/set/test a single bit in I/O address space.
5030 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5031 (and:QI (mem:QI (match_dup 0))
5032 (match_operand:QI 1 "single_zero_operand" "n")))]
5035 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
5036 return "cbi %i0,%2";
5038 [(set_attr "length" "1")
5039 (set_attr "cc" "none")])
5042 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5043 (ior:QI (mem:QI (match_dup 0))
5044 (match_operand:QI 1 "single_one_operand" "n")))]
5047 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
5048 return "sbi %i0,%2";
5050 [(set_attr "length" "1")
5051 (set_attr "cc" "none")])
5053 ;; Lower half of the I/O space - use sbic/sbis directly.
5054 (define_insn "*sbix_branch"
5057 (match_operator 0 "eqne_operator"
5059 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5061 (match_operand 2 "const_int_operand" "n"))
5063 (label_ref (match_operand 3 "" ""))
5067 return avr_out_sbxx_branch (insn, operands);
5069 [(set (attr "length")
5070 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5071 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5073 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5076 (set_attr "cc" "clobber")])
5078 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5079 (define_insn "*sbix_branch_bit7"
5082 (match_operator 0 "gelt_operator"
5083 [(mem:QI (match_operand 1 "low_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 2046)))
5097 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5100 (set_attr "cc" "clobber")])
5102 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5103 (define_insn "*sbix_branch_tmp"
5106 (match_operator 0 "eqne_operator"
5108 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5110 (match_operand 2 "const_int_operand" "n"))
5112 (label_ref (match_operand 3 "" ""))
5116 return avr_out_sbxx_branch (insn, operands);
5118 [(set (attr "length")
5119 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5120 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5122 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5125 (set_attr "cc" "clobber")])
5127 (define_insn "*sbix_branch_tmp_bit7"
5130 (match_operator 0 "gelt_operator"
5131 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5133 (label_ref (match_operand 2 "" ""))
5137 operands[3] = operands[2];
5138 operands[2] = GEN_INT (7);
5139 return avr_out_sbxx_branch (insn, operands);
5141 [(set (attr "length")
5142 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5143 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5145 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5148 (set_attr "cc" "clobber")])
5150 ;; ************************* Peepholes ********************************
5152 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5153 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5154 (plus:SI (match_dup 0)
5156 (clobber (scratch:QI))])
5157 (parallel [(set (cc0)
5158 (compare (match_dup 0)
5160 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5162 (if_then_else (eqne (cc0)
5164 (label_ref (match_operand 2 "" ""))
5171 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5172 output_asm_insn ("sbiw %0,1" CR_TAB
5173 "sbc %C0,__zero_reg__" CR_TAB
5174 "sbc %D0,__zero_reg__", operands);
5176 output_asm_insn ("subi %A0,1" CR_TAB
5177 "sbc %B0,__zero_reg__" CR_TAB
5178 "sbc %C0,__zero_reg__" CR_TAB
5179 "sbc %D0,__zero_reg__", operands);
5181 jump_mode = avr_jump_mode (operands[2], insn);
5182 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5183 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5187 case 1: return "%1 %2";
5188 case 2: return "%1 .+2\;rjmp %2";
5189 case 3: return "%1 .+4\;jmp %2";
5196 (define_peephole ; "*dec-and-branchhi!=-1"
5197 [(set (match_operand:HI 0 "d_register_operand" "")
5198 (plus:HI (match_dup 0)
5200 (parallel [(set (cc0)
5201 (compare (match_dup 0)
5203 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5205 (if_then_else (eqne (cc0)
5207 (label_ref (match_operand 2 "" ""))
5214 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5215 output_asm_insn ("sbiw %0,1", operands);
5217 output_asm_insn ("subi %A0,1" CR_TAB
5218 "sbc %B0,__zero_reg__", operands);
5220 jump_mode = avr_jump_mode (operands[2], insn);
5221 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5222 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5226 case 1: return "%1 %2";
5227 case 2: return "%1 .+2\;rjmp %2";
5228 case 3: return "%1 .+4\;jmp %2";
5235 ;; Same as above but with clobber flavour of addhi3
5236 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5237 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5238 (plus:HI (match_dup 0)
5240 (clobber (scratch:QI))])
5241 (parallel [(set (cc0)
5242 (compare (match_dup 0)
5244 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5246 (if_then_else (eqne (cc0)
5248 (label_ref (match_operand 2 "" ""))
5255 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5256 output_asm_insn ("sbiw %0,1", operands);
5258 output_asm_insn ("subi %A0,1" CR_TAB
5259 "sbc %B0,__zero_reg__", operands);
5261 jump_mode = avr_jump_mode (operands[2], insn);
5262 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5263 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5267 case 1: return "%1 %2";
5268 case 2: return "%1 .+2\;rjmp %2";
5269 case 3: return "%1 .+4\;jmp %2";
5276 ;; Same as above but with clobber flavour of addhi3
5277 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5278 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5279 (plus:HI (match_dup 0)
5281 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5282 (parallel [(set (cc0)
5283 (compare (match_dup 0)
5285 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5287 (if_then_else (eqne (cc0)
5289 (label_ref (match_operand 2 "" ""))
5296 output_asm_insn ("ldi %3,1" CR_TAB
5298 "sbc %B0,__zero_reg__", operands);
5300 jump_mode = avr_jump_mode (operands[2], insn);
5301 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5302 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5306 case 1: return "%1 %2";
5307 case 2: return "%1 .+2\;rjmp %2";
5308 case 3: return "%1 .+4\;jmp %2";
5315 (define_peephole ; "*dec-and-branchqi!=-1"
5316 [(set (match_operand:QI 0 "d_register_operand" "")
5317 (plus:QI (match_dup 0)
5320 (compare (match_dup 0)
5323 (if_then_else (eqne (cc0)
5325 (label_ref (match_operand 1 "" ""))
5332 cc_status.value1 = operands[0];
5333 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5335 output_asm_insn ("subi %A0,1", operands);
5337 jump_mode = avr_jump_mode (operands[1], insn);
5338 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5339 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5343 case 1: return "%0 %1";
5344 case 2: return "%0 .+2\;rjmp %1";
5345 case 3: return "%0 .+4\;jmp %1";
5353 (define_peephole ; "*cpse.eq"
5355 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5356 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5358 (if_then_else (eq (cc0)
5360 (label_ref (match_operand 0 "" ""))
5362 "jump_over_one_insn_p (insn, operands[0])"
5365 cpse %1,__zero_reg__")
5367 ;; This peephole avoids code like
5370 ;; BREQ .+2 ; branch
5373 ;; Notice that the peephole is always shorter than cmpqi + branch.
5374 ;; The reason to write it as peephole is that sequences like
5379 ;; shall not be superseeded. With a respective combine pattern
5380 ;; the latter sequence would be
5383 ;; CPSE Rm, __zero_reg__
5386 ;; and thus longer and slower and not easy to be rolled back.
5388 (define_peephole ; "*cpse.ne"
5390 (compare (match_operand:ALL1 1 "register_operand" "")
5391 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5393 (if_then_else (ne (cc0)
5395 (label_ref (match_operand 0 "" ""))
5398 || !avr_current_device->errata_skip"
5400 if (operands[2] == CONST0_RTX (<MODE>mode))
5401 operands[2] = zero_reg_rtx;
5403 return 3 == avr_jump_mode (operands[0], insn)
5404 ? "cpse %1,%2\;jmp %0"
5405 : "cpse %1,%2\;rjmp %0";
5408 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5409 ;;prologue/epilogue support instructions
5411 (define_insn "popqi"
5412 [(set (match_operand:QI 0 "register_operand" "=r")
5413 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5416 [(set_attr "cc" "none")
5417 (set_attr "length" "1")])
5419 ;; Enable Interrupts
5420 (define_expand "enable_interrupt"
5421 [(clobber (const_int 0))]
5424 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5425 MEM_VOLATILE_P (mem) = 1;
5426 emit_insn (gen_cli_sei (const1_rtx, mem));
5430 ;; Disable Interrupts
5431 (define_expand "disable_interrupt"
5432 [(clobber (const_int 0))]
5435 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5436 MEM_VOLATILE_P (mem) = 1;
5437 emit_insn (gen_cli_sei (const0_rtx, mem));
5441 (define_insn "cli_sei"
5442 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5443 UNSPECV_ENABLE_IRQS)
5444 (set (match_operand:BLK 1 "" "")
5445 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5450 [(set_attr "length" "1")
5451 (set_attr "cc" "none")])
5453 ;; Library prologue saves
5454 (define_insn "call_prologue_saves"
5455 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5456 (match_operand:HI 0 "immediate_operand" "i,i")
5457 (set (reg:HI REG_SP)
5458 (minus:HI (reg:HI REG_SP)
5459 (match_operand:HI 1 "immediate_operand" "i,i")))
5460 (use (reg:HI REG_X))
5461 (clobber (reg:HI REG_Z))]
5463 "ldi r30,lo8(gs(1f))
5465 %~jmp __prologue_saves__+((18 - %0) * 2)
5467 [(set_attr "length" "5,6")
5468 (set_attr "cc" "clobber")
5469 (set_attr "isa" "rjmp,jmp")])
5471 ; epilogue restores using library
5472 (define_insn "epilogue_restores"
5473 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5475 (plus:HI (reg:HI REG_Y)
5476 (match_operand:HI 0 "immediate_operand" "i,i")))
5477 (set (reg:HI REG_SP)
5478 (plus:HI (reg:HI REG_Y)
5480 (clobber (reg:QI REG_Z))]
5483 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5484 [(set_attr "length" "2,3")
5485 (set_attr "cc" "clobber")
5486 (set_attr "isa" "rjmp,jmp")])
5489 (define_insn "return"
5491 "reload_completed && avr_simple_epilogue ()"
5493 [(set_attr "cc" "none")
5494 (set_attr "length" "1")])
5496 (define_insn "return_from_epilogue"
5500 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5501 && !cfun->machine->is_naked)"
5503 [(set_attr "cc" "none")
5504 (set_attr "length" "1")])
5506 (define_insn "return_from_interrupt_epilogue"
5510 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5511 && !cfun->machine->is_naked)"
5513 [(set_attr "cc" "none")
5514 (set_attr "length" "1")])
5516 (define_insn "return_from_naked_epilogue"
5520 && cfun->machine->is_naked)"
5522 [(set_attr "cc" "none")
5523 (set_attr "length" "0")])
5525 (define_expand "prologue"
5533 (define_expand "epilogue"
5537 expand_epilogue (false /* sibcall_p */);
5541 (define_expand "sibcall_epilogue"
5545 expand_epilogue (true /* sibcall_p */);
5549 ;; Some instructions resp. instruction sequences available
5552 (define_insn "delay_cycles_1"
5553 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5555 UNSPECV_DELAY_CYCLES)
5556 (set (match_operand:BLK 1 "" "")
5557 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5558 (clobber (match_scratch:QI 2 "=&d"))]
5563 [(set_attr "length" "3")
5564 (set_attr "cc" "clobber")])
5566 (define_insn "delay_cycles_2"
5567 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5569 UNSPECV_DELAY_CYCLES)
5570 (set (match_operand:BLK 1 "" "")
5571 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5572 (clobber (match_scratch:HI 2 "=&w"))]
5578 [(set_attr "length" "4")
5579 (set_attr "cc" "clobber")])
5581 (define_insn "delay_cycles_3"
5582 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5584 UNSPECV_DELAY_CYCLES)
5585 (set (match_operand:BLK 1 "" "")
5586 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5587 (clobber (match_scratch:QI 2 "=&d"))
5588 (clobber (match_scratch:QI 3 "=&d"))
5589 (clobber (match_scratch:QI 4 "=&d"))]
5598 [(set_attr "length" "7")
5599 (set_attr "cc" "clobber")])
5601 (define_insn "delay_cycles_4"
5602 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5604 UNSPECV_DELAY_CYCLES)
5605 (set (match_operand:BLK 1 "" "")
5606 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5607 (clobber (match_scratch:QI 2 "=&d"))
5608 (clobber (match_scratch:QI 3 "=&d"))
5609 (clobber (match_scratch:QI 4 "=&d"))
5610 (clobber (match_scratch:QI 5 "=&d"))]
5621 [(set_attr "length" "9")
5622 (set_attr "cc" "clobber")])
5625 ;; __builtin_avr_insert_bits
5627 (define_insn "insert_bits"
5628 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5629 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5630 (match_operand:QI 2 "register_operand" "r ,r ,r")
5631 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5632 UNSPEC_INSERT_BITS))]
5635 return avr_out_insert_bits (operands, NULL);
5637 [(set_attr "adjust_len" "insert_bits")
5638 (set_attr "cc" "clobber")])
5641 ;; __builtin_avr_flash_segment
5643 ;; Just a helper for the next "official" expander.
5645 (define_expand "flash_segment1"
5646 [(set (match_operand:QI 0 "register_operand" "")
5647 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5650 (compare (match_dup 0)
5653 (if_then_else (ge (cc0)
5655 (label_ref (match_operand 2 "" ""))
5660 (define_expand "flash_segment"
5661 [(parallel [(match_operand:QI 0 "register_operand" "")
5662 (match_operand:PSI 1 "register_operand" "")])]
5665 rtx label = gen_label_rtx ();
5666 emit (gen_flash_segment1 (operands[0], operands[1], label));
5671 ;; Actually, it's too late now to work out address spaces known at compiletime.
5672 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5673 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5674 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5676 (define_insn_and_split "*split.flash_segment"
5677 [(set (match_operand:QI 0 "register_operand" "=d")
5678 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5679 (match_operand:HI 2 "register_operand" "r"))
5682 { gcc_unreachable(); }
5690 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5691 ;; better 8-bit parity recognition.
5693 (define_expand "parityhi2"
5694 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5695 (parity:HI (match_operand:HI 1 "register_operand" "")))
5696 (clobber (reg:HI 24))])])
5698 (define_insn_and_split "*parityhi2"
5699 [(set (match_operand:HI 0 "register_operand" "=r")
5700 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5701 (clobber (reg:HI 24))]
5703 { gcc_unreachable(); }
5708 (parity:HI (reg:HI 24)))
5712 (define_insn_and_split "*parityqihi2"
5713 [(set (match_operand:HI 0 "register_operand" "=r")
5714 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5715 (clobber (reg:HI 24))]
5717 { gcc_unreachable(); }
5722 (zero_extend:HI (parity:QI (reg:QI 24))))
5726 (define_expand "paritysi2"
5728 (match_operand:SI 1 "register_operand" ""))
5730 (truncate:HI (parity:SI (reg:SI 22))))
5733 (set (match_operand:SI 0 "register_operand" "")
5734 (zero_extend:SI (match_dup 2)))]
5737 operands[2] = gen_reg_rtx (HImode);
5740 (define_insn "*parityhi2.libgcc"
5742 (parity:HI (reg:HI 24)))]
5744 "%~call __parityhi2"
5745 [(set_attr "type" "xcall")
5746 (set_attr "cc" "clobber")])
5748 (define_insn "*parityqihi2.libgcc"
5750 (zero_extend:HI (parity:QI (reg:QI 24))))]
5752 "%~call __parityqi2"
5753 [(set_attr "type" "xcall")
5754 (set_attr "cc" "clobber")])
5756 (define_insn "*paritysihi2.libgcc"
5758 (truncate:HI (parity:SI (reg:SI 22))))]
5760 "%~call __paritysi2"
5761 [(set_attr "type" "xcall")
5762 (set_attr "cc" "clobber")])
5767 (define_expand "popcounthi2"
5769 (match_operand:HI 1 "register_operand" ""))
5771 (popcount:HI (reg:HI 24)))
5772 (set (match_operand:HI 0 "register_operand" "")
5777 (define_expand "popcountsi2"
5779 (match_operand:SI 1 "register_operand" ""))
5781 (truncate:HI (popcount:SI (reg:SI 22))))
5784 (set (match_operand:SI 0 "register_operand" "")
5785 (zero_extend:SI (match_dup 2)))]
5788 operands[2] = gen_reg_rtx (HImode);
5791 (define_insn "*popcounthi2.libgcc"
5793 (popcount:HI (reg:HI 24)))]
5795 "%~call __popcounthi2"
5796 [(set_attr "type" "xcall")
5797 (set_attr "cc" "clobber")])
5799 (define_insn "*popcountsi2.libgcc"
5801 (truncate:HI (popcount:SI (reg:SI 22))))]
5803 "%~call __popcountsi2"
5804 [(set_attr "type" "xcall")
5805 (set_attr "cc" "clobber")])
5807 (define_insn "*popcountqi2.libgcc"
5809 (popcount:QI (reg:QI 24)))]
5811 "%~call __popcountqi2"
5812 [(set_attr "type" "xcall")
5813 (set_attr "cc" "clobber")])
5815 (define_insn_and_split "*popcountqihi2.libgcc"
5817 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5822 (popcount:QI (reg:QI 24)))
5827 ;; Count Leading Zeros
5829 (define_expand "clzhi2"
5831 (match_operand:HI 1 "register_operand" ""))
5832 (parallel [(set (reg:HI 24)
5833 (clz:HI (reg:HI 24)))
5834 (clobber (reg:QI 26))])
5835 (set (match_operand:HI 0 "register_operand" "")
5840 (define_expand "clzsi2"
5842 (match_operand:SI 1 "register_operand" ""))
5843 (parallel [(set (reg:HI 24)
5844 (truncate:HI (clz:SI (reg:SI 22))))
5845 (clobber (reg:QI 26))])
5848 (set (match_operand:SI 0 "register_operand" "")
5849 (zero_extend:SI (match_dup 2)))]
5852 operands[2] = gen_reg_rtx (HImode);
5855 (define_insn "*clzhi2.libgcc"
5857 (clz:HI (reg:HI 24)))
5858 (clobber (reg:QI 26))]
5861 [(set_attr "type" "xcall")
5862 (set_attr "cc" "clobber")])
5864 (define_insn "*clzsihi2.libgcc"
5866 (truncate:HI (clz:SI (reg:SI 22))))
5867 (clobber (reg:QI 26))]
5870 [(set_attr "type" "xcall")
5871 (set_attr "cc" "clobber")])
5873 ;; Count Trailing Zeros
5875 (define_expand "ctzhi2"
5877 (match_operand:HI 1 "register_operand" ""))
5878 (parallel [(set (reg:HI 24)
5879 (ctz:HI (reg:HI 24)))
5880 (clobber (reg:QI 26))])
5881 (set (match_operand:HI 0 "register_operand" "")
5886 (define_expand "ctzsi2"
5888 (match_operand:SI 1 "register_operand" ""))
5889 (parallel [(set (reg:HI 24)
5890 (truncate:HI (ctz:SI (reg:SI 22))))
5891 (clobber (reg:QI 22))
5892 (clobber (reg:QI 26))])
5895 (set (match_operand:SI 0 "register_operand" "")
5896 (zero_extend:SI (match_dup 2)))]
5899 operands[2] = gen_reg_rtx (HImode);
5902 (define_insn "*ctzhi2.libgcc"
5904 (ctz:HI (reg:HI 24)))
5905 (clobber (reg:QI 26))]
5908 [(set_attr "type" "xcall")
5909 (set_attr "cc" "clobber")])
5911 (define_insn "*ctzsihi2.libgcc"
5913 (truncate:HI (ctz:SI (reg:SI 22))))
5914 (clobber (reg:QI 22))
5915 (clobber (reg:QI 26))]
5918 [(set_attr "type" "xcall")
5919 (set_attr "cc" "clobber")])
5923 (define_expand "ffshi2"
5925 (match_operand:HI 1 "register_operand" ""))
5926 (parallel [(set (reg:HI 24)
5927 (ffs:HI (reg:HI 24)))
5928 (clobber (reg:QI 26))])
5929 (set (match_operand:HI 0 "register_operand" "")
5934 (define_expand "ffssi2"
5936 (match_operand:SI 1 "register_operand" ""))
5937 (parallel [(set (reg:HI 24)
5938 (truncate:HI (ffs:SI (reg:SI 22))))
5939 (clobber (reg:QI 22))
5940 (clobber (reg:QI 26))])
5943 (set (match_operand:SI 0 "register_operand" "")
5944 (zero_extend:SI (match_dup 2)))]
5947 operands[2] = gen_reg_rtx (HImode);
5950 (define_insn "*ffshi2.libgcc"
5952 (ffs:HI (reg:HI 24)))
5953 (clobber (reg:QI 26))]
5956 [(set_attr "type" "xcall")
5957 (set_attr "cc" "clobber")])
5959 (define_insn "*ffssihi2.libgcc"
5961 (truncate:HI (ffs:SI (reg:SI 22))))
5962 (clobber (reg:QI 22))
5963 (clobber (reg:QI 26))]
5966 [(set_attr "type" "xcall")
5967 (set_attr "cc" "clobber")])
5971 (define_insn "copysignsf3"
5972 [(set (match_operand:SF 0 "register_operand" "=r")
5973 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5974 (match_operand:SF 2 "register_operand" "r")]
5977 "bst %D2,7\;bld %D0,7"
5978 [(set_attr "length" "2")
5979 (set_attr "cc" "none")])
5981 ;; Swap Bytes (change byte-endianess)
5983 (define_expand "bswapsi2"
5985 (match_operand:SI 1 "register_operand" ""))
5987 (bswap:SI (reg:SI 22)))
5988 (set (match_operand:SI 0 "register_operand" "")
5993 (define_insn "*bswapsi2.libgcc"
5995 (bswap:SI (reg:SI 22)))]
5998 [(set_attr "type" "xcall")
5999 (set_attr "cc" "clobber")])
6004 ;; NOP taking 1 or 2 Ticks
6005 (define_expand "nopv"
6006 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
6009 (unspec_volatile:BLK [(match_dup 1)]
6010 UNSPECV_MEMORY_BARRIER))])]
6013 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6014 MEM_VOLATILE_P (operands[1]) = 1;
6017 (define_insn "*nopv"
6018 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
6020 (set (match_operand:BLK 1 "" "")
6021 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
6026 [(set_attr "length" "1")
6027 (set_attr "cc" "none")])
6030 (define_expand "sleep"
6031 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6033 (unspec_volatile:BLK [(match_dup 0)]
6034 UNSPECV_MEMORY_BARRIER))])]
6037 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6038 MEM_VOLATILE_P (operands[0]) = 1;
6041 (define_insn "*sleep"
6042 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
6043 (set (match_operand:BLK 0 "" "")
6044 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6047 [(set_attr "length" "1")
6048 (set_attr "cc" "none")])
6051 (define_expand "wdr"
6052 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6054 (unspec_volatile:BLK [(match_dup 0)]
6055 UNSPECV_MEMORY_BARRIER))])]
6058 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6059 MEM_VOLATILE_P (operands[0]) = 1;
6063 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
6064 (set (match_operand:BLK 0 "" "")
6065 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6068 [(set_attr "length" "1")
6069 (set_attr "cc" "none")])
6072 (define_expand "fmul"
6074 (match_operand:QI 1 "register_operand" ""))
6076 (match_operand:QI 2 "register_operand" ""))
6077 (parallel [(set (reg:HI 22)
6078 (unspec:HI [(reg:QI 24)
6079 (reg:QI 25)] UNSPEC_FMUL))
6080 (clobber (reg:HI 24))])
6081 (set (match_operand:HI 0 "register_operand" "")
6087 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6092 (define_insn "fmul_insn"
6093 [(set (match_operand:HI 0 "register_operand" "=r")
6094 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6095 (match_operand:QI 2 "register_operand" "a")]
6101 [(set_attr "length" "3")
6102 (set_attr "cc" "clobber")])
6104 (define_insn "*fmul.call"
6106 (unspec:HI [(reg:QI 24)
6107 (reg:QI 25)] UNSPEC_FMUL))
6108 (clobber (reg:HI 24))]
6111 [(set_attr "type" "xcall")
6112 (set_attr "cc" "clobber")])
6115 (define_expand "fmuls"
6117 (match_operand:QI 1 "register_operand" ""))
6119 (match_operand:QI 2 "register_operand" ""))
6120 (parallel [(set (reg:HI 22)
6121 (unspec:HI [(reg:QI 24)
6122 (reg:QI 25)] UNSPEC_FMULS))
6123 (clobber (reg:HI 24))])
6124 (set (match_operand:HI 0 "register_operand" "")
6130 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6135 (define_insn "fmuls_insn"
6136 [(set (match_operand:HI 0 "register_operand" "=r")
6137 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6138 (match_operand:QI 2 "register_operand" "a")]
6144 [(set_attr "length" "3")
6145 (set_attr "cc" "clobber")])
6147 (define_insn "*fmuls.call"
6149 (unspec:HI [(reg:QI 24)
6150 (reg:QI 25)] UNSPEC_FMULS))
6151 (clobber (reg:HI 24))]
6154 [(set_attr "type" "xcall")
6155 (set_attr "cc" "clobber")])
6158 (define_expand "fmulsu"
6160 (match_operand:QI 1 "register_operand" ""))
6162 (match_operand:QI 2 "register_operand" ""))
6163 (parallel [(set (reg:HI 22)
6164 (unspec:HI [(reg:QI 24)
6165 (reg:QI 25)] UNSPEC_FMULSU))
6166 (clobber (reg:HI 24))])
6167 (set (match_operand:HI 0 "register_operand" "")
6173 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6178 (define_insn "fmulsu_insn"
6179 [(set (match_operand:HI 0 "register_operand" "=r")
6180 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6181 (match_operand:QI 2 "register_operand" "a")]
6187 [(set_attr "length" "3")
6188 (set_attr "cc" "clobber")])
6190 (define_insn "*fmulsu.call"
6192 (unspec:HI [(reg:QI 24)
6193 (reg:QI 25)] UNSPEC_FMULSU))
6194 (clobber (reg:HI 24))]
6197 [(set_attr "type" "xcall")
6198 (set_attr "cc" "clobber")])
6201 ;; Some combiner patterns dealing with bits.
6204 ;; Move bit $3.0 into bit $0.$4
6205 (define_insn "*movbitqi.1-6.a"
6206 [(set (match_operand:QI 0 "register_operand" "=r")
6207 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6208 (match_operand:QI 2 "single_zero_operand" "n"))
6209 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6210 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6211 (match_operand:QI 5 "single_one_operand" "n"))))]
6212 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6213 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6214 "bst %3,0\;bld %0,%4"
6215 [(set_attr "length" "2")
6216 (set_attr "cc" "none")])
6218 ;; Move bit $3.0 into bit $0.$4
6219 ;; Variation of above. Unfortunately, there is no canonicalized representation
6220 ;; of moving around bits. So what we see here depends on how user writes down
6221 ;; bit manipulations.
6222 (define_insn "*movbitqi.1-6.b"
6223 [(set (match_operand:QI 0 "register_operand" "=r")
6224 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6225 (match_operand:QI 2 "single_zero_operand" "n"))
6226 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6228 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6229 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6230 "bst %3,0\;bld %0,%4"
6231 [(set_attr "length" "2")
6232 (set_attr "cc" "none")])
6234 ;; Move bit $3.0 into bit $0.0.
6235 ;; For bit 0, combiner generates slightly different pattern.
6236 (define_insn "*movbitqi.0"
6237 [(set (match_operand:QI 0 "register_operand" "=r")
6238 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6239 (match_operand:QI 2 "single_zero_operand" "n"))
6240 (and:QI (match_operand:QI 3 "register_operand" "r")
6242 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6243 "bst %3,0\;bld %0,0"
6244 [(set_attr "length" "2")
6245 (set_attr "cc" "none")])
6247 ;; Move bit $2.0 into bit $0.7.
6248 ;; For bit 7, combiner generates slightly different pattern
6249 (define_insn "*movbitqi.7"
6250 [(set (match_operand:QI 0 "register_operand" "=r")
6251 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6253 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6256 "bst %2,0\;bld %0,7"
6257 [(set_attr "length" "2")
6258 (set_attr "cc" "none")])
6260 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6261 ;; and input/output match. We provide a special pattern for this, because
6262 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6263 ;; operation on I/O is atomic.
6264 (define_insn "*insv.io"
6265 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6267 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6268 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6273 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6274 [(set_attr "length" "1,1,4")
6275 (set_attr "cc" "none")])
6277 (define_insn "*insv.not.io"
6278 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6280 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6281 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6283 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6284 [(set_attr "length" "4")
6285 (set_attr "cc" "none")])
6287 ;; The insv expander.
6288 ;; We only support 1-bit inserts
6289 (define_expand "insv"
6290 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6291 (match_operand:QI 1 "const1_operand" "") ; width
6292 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6293 (match_operand:QI 3 "nonmemory_operand" ""))]
6297 ;; Insert bit $2.0 into $0.$1
6298 (define_insn "*insv.reg"
6299 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6301 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6302 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6306 andi %0,lo8(~(1<<%1))
6310 [(set_attr "length" "2,1,1,2,2")
6311 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6314 ;; Some combine patterns that try to fix bad code when a value is composed
6315 ;; from byte parts like in PR27663.
6316 ;; The patterns give some release but the code still is not optimal,
6317 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6318 ;; That switch obfuscates things here and in many other places.
6320 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6321 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6322 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6323 [(set (match_operand:HISI 0 "register_operand" "=r")
6325 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6326 (match_operand:HISI 2 "register_operand" "0")))]
6331 (xior:QI (match_dup 3)
6334 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6337 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6338 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6339 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6340 [(set (match_operand:HISI 0 "register_operand" "=r")
6342 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6343 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6344 (match_operand:HISI 3 "register_operand" "0")))]
6345 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6347 "&& reload_completed"
6349 (xior:QI (match_dup 4)
6352 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6353 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6356 (define_expand "extzv"
6357 [(set (match_operand:QI 0 "register_operand" "")
6358 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6359 (match_operand:QI 2 "const1_operand" "")
6360 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6364 (define_insn "*extzv"
6365 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6366 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6368 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6372 mov %0,%1\;andi %0,1
6375 bst %1,%2\;clr %0\;bld %0,0"
6376 [(set_attr "length" "1,2,2,2,3")
6377 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6379 (define_insn_and_split "*extzv.qihi1"
6380 [(set (match_operand:HI 0 "register_operand" "=r")
6381 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6383 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6388 (zero_extract:QI (match_dup 1)
6394 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6395 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6398 (define_insn_and_split "*extzv.qihi2"
6399 [(set (match_operand:HI 0 "register_operand" "=r")
6401 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6403 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6408 (zero_extract:QI (match_dup 1)
6414 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6415 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6419 ;; Fixed-point instructions
6420 (include "avr-fixed.md")
6422 ;; Operations on 64-bit registers
6423 (include "avr-dimode.md")