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"
74 (define_c_enum "unspecv"
75 [UNSPECV_PROLOGUE_SAVES
76 UNSPECV_EPILOGUE_RESTORES
80 UNSPECV_MEMORY_BARRIER
88 (include "predicates.md")
89 (include "constraints.md")
91 ;; Condition code settings.
92 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
94 (const_string "none"))
96 (define_attr "type" "branch,branch1,arith,xcall"
97 (const_string "arith"))
99 ;; The size of instructions in bytes.
100 ;; XXX may depend from "cc"
102 (define_attr "length" ""
103 (cond [(eq_attr "type" "branch")
104 (if_then_else (and (ge (minus (pc) (match_dup 0))
106 (le (minus (pc) (match_dup 0))
109 (if_then_else (and (ge (minus (pc) (match_dup 0))
111 (le (minus (pc) (match_dup 0))
115 (eq_attr "type" "branch1")
116 (if_then_else (and (ge (minus (pc) (match_dup 0))
118 (le (minus (pc) (match_dup 0))
121 (if_then_else (and (ge (minus (pc) (match_dup 0))
123 (le (minus (pc) (match_dup 0))
127 (eq_attr "type" "xcall")
128 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
133 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
134 ;; Following insn attribute tells if and how the adjustment has to be
136 ;; no No adjustment needed; attribute "length" is fine.
137 ;; Otherwise do special processing depending on the attribute.
139 (define_attr "adjust_len"
140 "out_bitop, plus, addto_sp,
141 tsthi, tstpsi, tstsi, compare, compare64, call,
142 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
145 ashlqi, ashrqi, lshrqi,
146 ashlhi, ashrhi, lshrhi,
147 ashlsi, ashrsi, lshrsi,
148 ashlpsi, ashrpsi, lshrpsi,
153 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
155 ;; mov : ISA has no MOVW movw : ISA has MOVW
156 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
157 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
158 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
159 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
160 ;; no_xmega: non-XMEGA core xmega : XMEGA core
163 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
165 (const_string "standard"))
167 (define_attr "enabled" ""
168 (cond [(eq_attr "isa" "standard")
171 (and (eq_attr "isa" "mov")
172 (match_test "!AVR_HAVE_MOVW"))
175 (and (eq_attr "isa" "movw")
176 (match_test "AVR_HAVE_MOVW"))
179 (and (eq_attr "isa" "rjmp")
180 (match_test "!AVR_HAVE_JMP_CALL"))
183 (and (eq_attr "isa" "jmp")
184 (match_test "AVR_HAVE_JMP_CALL"))
187 (and (eq_attr "isa" "ijmp")
188 (match_test "!AVR_HAVE_EIJMP_EICALL"))
191 (and (eq_attr "isa" "eijmp")
192 (match_test "AVR_HAVE_EIJMP_EICALL"))
195 (and (eq_attr "isa" "lpm")
196 (match_test "!AVR_HAVE_LPMX"))
199 (and (eq_attr "isa" "lpmx")
200 (match_test "AVR_HAVE_LPMX"))
203 (and (eq_attr "isa" "elpm")
204 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
207 (and (eq_attr "isa" "elpmx")
208 (match_test "AVR_HAVE_ELPMX"))
211 (and (eq_attr "isa" "xmega")
212 (match_test "AVR_XMEGA"))
215 (and (eq_attr "isa" "no_xmega")
216 (match_test "!AVR_XMEGA"))
221 ;; Define mode iterators
222 (define_mode_iterator QIHI [QI HI])
223 (define_mode_iterator QIHI2 [QI HI])
224 (define_mode_iterator QISI [QI HI PSI SI])
225 (define_mode_iterator QIDI [QI HI PSI SI DI])
226 (define_mode_iterator HISI [HI PSI SI])
228 (define_mode_iterator ALL1 [QI QQ UQQ])
229 (define_mode_iterator ALL2 [HI HQ UHQ HA UHA])
230 (define_mode_iterator ALL4 [SI SQ USQ SA USA])
232 ;; All supported move-modes
233 (define_mode_iterator MOVMODE [QI QQ UQQ
238 ;; Supported ordered modes that are 2, 3, 4 bytes wide
239 (define_mode_iterator ORDERED234 [HI SI PSI
243 ;; Define code iterators
244 ;; Define two incarnations so that we can build the cross product.
245 (define_code_iterator any_extend [sign_extend zero_extend])
246 (define_code_iterator any_extend2 [sign_extend zero_extend])
248 (define_code_iterator xior [xor ior])
249 (define_code_iterator eqne [eq ne])
251 (define_code_iterator ss_addsub [ss_plus ss_minus])
252 (define_code_iterator us_addsub [us_plus us_minus])
253 (define_code_iterator ss_abs_neg [ss_abs ss_neg])
255 ;; Define code attributes
256 (define_code_attr extend_su
260 (define_code_attr extend_u
264 (define_code_attr extend_s
268 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
269 (define_code_attr mul_r_d
273 (define_code_attr abelian
274 [(ss_minus "") (us_minus "")
275 (ss_plus "%") (us_plus "%")])
277 ;; Map RTX code to its standard insn name
278 (define_code_attr code_stdname
285 (ss_plus "ssadd") (ss_minus "sssub") (ss_neg "ssneg") (ss_abs "ssabs")
286 (us_plus "usadd") (us_minus "ussub") (us_neg "usneg")
289 ;;========================================================================
290 ;; The following is used by nonlocal_goto and setjmp.
291 ;; The receiver pattern will create no instructions since internally
292 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
293 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
294 ;; The 'null' receiver also avoids problems with optimisation
295 ;; not recognising incoming jmp and removing code that resets frame_pointer.
296 ;; The code derived from builtins.c.
298 (define_expand "nonlocal_goto_receiver"
300 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
303 emit_move_insn (virtual_stack_vars_rtx,
304 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
305 gen_int_mode (STARTING_FRAME_OFFSET,
307 /* ; This might change the hard frame pointer in ways that aren't
308 ; apparent to early optimization passes, so force a clobber. */
309 emit_clobber (hard_frame_pointer_rtx);
314 ;; Defining nonlocal_goto_receiver means we must also define this.
315 ;; even though its function is identical to that in builtins.c
317 (define_expand "nonlocal_goto"
318 [(use (match_operand 0 "general_operand"))
319 (use (match_operand 1 "general_operand"))
320 (use (match_operand 2 "general_operand"))
321 (use (match_operand 3 "general_operand"))]
324 rtx r_label = copy_to_reg (operands[1]);
325 rtx r_fp = operands[3];
326 rtx r_sp = operands[2];
328 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
330 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
332 emit_move_insn (hard_frame_pointer_rtx, r_fp);
333 emit_stack_restore (SAVE_NONLOCAL, r_sp);
335 emit_use (hard_frame_pointer_rtx);
336 emit_use (stack_pointer_rtx);
338 emit_indirect_jump (r_label);
344 ;; "pushqq1" "pushuqq1"
345 (define_insn "push<mode>1"
346 [(set (mem:ALL1 (post_dec:HI (reg:HI REG_SP)))
347 (match_operand:ALL1 0 "reg_or_0_operand" "r,Y00"))]
352 [(set_attr "length" "1,1")])
354 ;; All modes for a multi-byte push. We must include complex modes here too,
355 ;; lest emit_single_push_insn "helpfully" create the auto-inc itself.
356 (define_mode_iterator MPUSH
365 (define_expand "push<mode>1"
366 [(match_operand:MPUSH 0 "" "")]
370 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
372 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
373 if (part != const0_rtx)
374 part = force_reg (QImode, part);
375 emit_insn (gen_pushqi1 (part));
380 ;; Notice a special-case when adding N to SP where N results in a
381 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
383 [(set (reg:HI REG_SP)
384 (match_operand:HI 0 "register_operand" ""))]
386 && frame_pointer_needed
387 && !cfun->calls_alloca
388 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
389 [(set (reg:HI REG_SP)
392 ;;========================================================================
395 ;; Secondary input reload from non-generic 16-bit address spaces
396 (define_insn "reload_in<mode>"
397 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
398 (match_operand:MOVMODE 1 "memory_operand" "m"))
399 (clobber (match_operand:QI 2 "d_register_operand" "=d"))]
401 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))"
403 return output_movqi (insn, operands, NULL);
405 [(set_attr "adjust_len" "mov8")
406 (set_attr "cc" "clobber")])
414 (define_expand "load<mode>_libgcc"
417 (set (reg:MOVMODE 22)
418 (match_operand:MOVMODE 1 "memory_operand" ""))
419 (set (match_operand:MOVMODE 0 "register_operand" "")
421 "avr_load_libgcc_p (operands[1])"
423 operands[3] = gen_rtx_REG (HImode, REG_Z);
424 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
425 operands[1] = replace_equiv_address (operands[1], operands[3]);
426 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
434 (define_insn "load_<mode>_libgcc"
435 [(set (reg:MOVMODE 22)
436 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
437 "avr_load_libgcc_p (operands[0])
438 && REG_P (XEXP (operands[0], 0))
439 && REG_Z == REGNO (XEXP (operands[0], 0))"
441 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
442 return "%~call __load_%0";
444 [(set_attr "length" "1,2")
445 (set_attr "isa" "rjmp,jmp")
446 (set_attr "cc" "clobber")])
450 ;; "xload8qq_A" "xload8uqq_A"
451 (define_insn_and_split "xload8<mode>_A"
452 [(set (match_operand:ALL1 0 "register_operand" "=r")
453 (match_operand:ALL1 1 "memory_operand" "m"))
454 (clobber (reg:HI REG_Z))]
455 "can_create_pseudo_p()
456 && !avr_xload_libgcc_p (<MODE>mode)
457 && avr_mem_memx_p (operands[1])
458 && REG_P (XEXP (operands[1], 0))"
459 { gcc_unreachable(); }
461 [(clobber (const_int 0))]
463 /* ; Split away the high part of the address. GCC's register allocator
464 ; in not able to allocate segment registers and reload the resulting
465 ; expressions. Notice that no address register can hold a PSImode. */
467 rtx insn, addr = XEXP (operands[1], 0);
468 rtx hi8 = gen_reg_rtx (QImode);
469 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
471 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
472 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
474 insn = emit_insn (gen_xload<mode>_8 (operands[0], hi8));
475 set_mem_addr_space (SET_SRC (single_set (insn)),
476 MEM_ADDR_SPACE (operands[1]));
480 ;; "xloadqi_A" "xloadqq_A" "xloaduqq_A"
481 ;; "xloadhi_A" "xloadhq_A" "xloaduhq_A" "xloadha_A" "xloaduha_A"
482 ;; "xloadsi_A" "xloadsq_A" "xloadusq_A" "xloadsa_A" "xloadusa_A"
485 (define_insn_and_split "xload<mode>_A"
486 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
487 (match_operand:MOVMODE 1 "memory_operand" "m"))
488 (clobber (reg:MOVMODE 22))
489 (clobber (reg:QI 21))
490 (clobber (reg:HI REG_Z))]
491 "can_create_pseudo_p()
492 && avr_mem_memx_p (operands[1])
493 && REG_P (XEXP (operands[1], 0))"
494 { gcc_unreachable(); }
496 [(clobber (const_int 0))]
498 rtx addr = XEXP (operands[1], 0);
499 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
500 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
501 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
504 /* Split the address to R21:Z */
505 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
506 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
508 /* Load with code from libgcc */
509 insn = emit_insn (gen_xload_<mode>_libgcc ());
510 set_mem_addr_space (SET_SRC (single_set (insn)), as);
512 /* Move to destination */
513 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
518 ;; Move value from address space memx to a register
519 ;; These insns must be prior to respective generic move insn.
522 ;; "xloadqq_8" "xloaduqq_8"
523 (define_insn "xload<mode>_8"
524 [(set (match_operand:ALL1 0 "register_operand" "=&r,r")
525 (mem:ALL1 (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
527 "!avr_xload_libgcc_p (<MODE>mode)"
529 return avr_out_xload (insn, operands, NULL);
531 [(set_attr "length" "4,4")
532 (set_attr "adjust_len" "*,xload")
533 (set_attr "isa" "lpmx,lpm")
534 (set_attr "cc" "none")])
536 ;; R21:Z : 24-bit source address
537 ;; R22 : 1-4 byte output
539 ;; "xload_qi_libgcc" "xload_qq_libgcc" "xload_uqq_libgcc"
540 ;; "xload_hi_libgcc" "xload_hq_libgcc" "xload_uhq_libgcc" "xload_ha_libgcc" "xload_uha_libgcc"
541 ;; "xload_si_libgcc" "xload_sq_libgcc" "xload_usq_libgcc" "xload_sa_libgcc" "xload_usa_libgcc"
543 ;; "xload_psi_libgcc"
544 (define_insn "xload_<mode>_libgcc"
545 [(set (reg:MOVMODE 22)
546 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
548 (clobber (reg:QI 21))
549 (clobber (reg:HI REG_Z))]
550 "avr_xload_libgcc_p (<MODE>mode)"
552 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
554 output_asm_insn ("%~call __xload_%0", &x_bytes);
557 [(set_attr "type" "xcall")
558 (set_attr "cc" "clobber")])
561 ;; General move expanders
563 ;; "movqi" "movqq" "movuqq"
564 ;; "movhi" "movhq" "movuhq" "movha" "movuha"
565 ;; "movsi" "movsq" "movusq" "movsa" "movusa"
568 (define_expand "mov<mode>"
569 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
570 (match_operand:MOVMODE 1 "general_operand" ""))]
573 rtx dest = operands[0];
574 rtx src = operands[1];
576 if (avr_mem_flash_p (dest))
579 /* One of the operands has to be in a register. */
580 if (!register_operand (dest, <MODE>mode)
581 && !reg_or_0_operand (src, <MODE>mode))
583 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
586 if (avr_mem_memx_p (src))
588 rtx addr = XEXP (src, 0);
591 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
593 if (!avr_xload_libgcc_p (<MODE>mode))
594 /* ; No <mode> here because gen_xload8<mode>_A only iterates over ALL1.
595 ; insn-emit does not depend on the mode, it's all about operands. */
596 emit_insn (gen_xload8qi_A (dest, src));
598 emit_insn (gen_xload<mode>_A (dest, src));
603 if (avr_load_libgcc_p (src))
605 /* For the small devices, do loads per libgcc call. */
606 emit_insn (gen_load<mode>_libgcc (dest, src));
611 ;;========================================================================
613 ;; The last alternative (any immediate constant to any register) is
614 ;; very expensive. It should be optimized by peephole2 if a scratch
615 ;; register is available, but then that register could just as well be
616 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
617 ;; are call-saved registers, and most of LD_REGS are call-used registers,
618 ;; so this may still be a win for registers live across function calls.
621 ;; "movqq_insn" "movuqq_insn"
622 (define_insn "mov<mode>_insn"
623 [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r")
624 (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))]
625 "register_operand (operands[0], <MODE>mode)
626 || reg_or_0_operand (operands[1], <MODE>mode)"
628 return output_movqi (insn, operands, NULL);
630 [(set_attr "length" "1,1,5,5,1,1,4")
631 (set_attr "adjust_len" "mov8")
632 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
634 ;; This is used in peephole2 to optimize loading immediate constants
635 ;; if a scratch register from LD_REGS happens to be available.
638 ;; "*reload_inqq" "*reload_inuqq"
639 (define_insn "*reload_in<mode>"
640 [(set (match_operand:ALL1 0 "register_operand" "=l")
641 (match_operand:ALL1 1 "const_operand" "i"))
642 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
646 [(set_attr "length" "2")
647 (set_attr "cc" "none")])
650 [(match_scratch:QI 2 "d")
651 (set (match_operand:ALL1 0 "l_register_operand" "")
652 (match_operand:ALL1 1 "const_operand" ""))]
653 ; No need for a clobber reg for 0x0, 0x01 or 0xff
654 "!satisfies_constraint_Y00 (operands[1])
655 && !satisfies_constraint_Y01 (operands[1])
656 && !satisfies_constraint_Ym1 (operands[1])"
657 [(parallel [(set (match_dup 0)
659 (clobber (match_dup 2))])])
661 ;;============================================================================
662 ;; move word (16 bit)
664 ;; Move register $1 to the Stack Pointer register SP.
665 ;; This insn is emit during function prologue/epilogue generation.
666 ;; $2 = 0: We know that IRQs are off
667 ;; $2 = 1: We know that IRQs are on
668 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
669 ;; $2 = -1: We don't know anything about IRQ on/off
670 ;; Always write SP via unspec, see PR50063
672 (define_insn "movhi_sp_r"
673 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
674 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
675 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
679 out %B0,%B1\;out %A0,%A1
680 cli\;out %B0,%B1\;sei\;out %A0,%A1
681 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
683 out %A0,%A1\;out %B0,%B1"
684 [(set_attr "length" "2,4,5,1,2")
685 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
686 (set_attr "cc" "none")])
689 [(match_scratch:QI 2 "d")
690 (set (match_operand:ALL2 0 "l_register_operand" "")
691 (match_operand:ALL2 1 "const_or_immediate_operand" ""))]
692 "operands[1] != CONST0_RTX (<MODE>mode)"
693 [(parallel [(set (match_dup 0)
695 (clobber (match_dup 2))])])
697 ;; '*' because it is not used in rtl generation, only in above peephole
699 ;; "*reload_inhq" "*reload_inuhq"
700 ;; "*reload_inha" "*reload_inuha"
701 (define_insn "*reload_in<mode>"
702 [(set (match_operand:ALL2 0 "l_register_operand" "=l")
703 (match_operand:ALL2 1 "immediate_operand" "i"))
704 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
707 return output_reload_inhi (operands, operands[2], NULL);
709 [(set_attr "length" "4")
710 (set_attr "adjust_len" "reload_in16")
711 (set_attr "cc" "clobber")])
714 ;; "*movhq" "*movuhq"
715 ;; "*movha" "*movuha"
716 (define_insn "*mov<mode>"
717 [(set (match_operand:ALL2 0 "nonimmediate_operand" "=r,r ,r,m ,d,*r,q,r")
718 (match_operand:ALL2 1 "nox_general_operand" "r,Y00,m,r Y00,i,i ,r,q"))]
719 "register_operand (operands[0], <MODE>mode)
720 || reg_or_0_operand (operands[1], <MODE>mode)"
722 return output_movhi (insn, operands, NULL);
724 [(set_attr "length" "2,2,6,7,2,6,5,2")
725 (set_attr "adjust_len" "mov16")
726 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
728 (define_peephole2 ; movw
729 [(set (match_operand:ALL1 0 "even_register_operand" "")
730 (match_operand:ALL1 1 "even_register_operand" ""))
731 (set (match_operand:ALL1 2 "odd_register_operand" "")
732 (match_operand:ALL1 3 "odd_register_operand" ""))]
734 && REGNO (operands[0]) == REGNO (operands[2]) - 1
735 && REGNO (operands[1]) == REGNO (operands[3]) - 1"
739 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
740 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
743 (define_peephole2 ; movw_r
744 [(set (match_operand:ALL1 0 "odd_register_operand" "")
745 (match_operand:ALL1 1 "odd_register_operand" ""))
746 (set (match_operand:ALL1 2 "even_register_operand" "")
747 (match_operand:ALL1 3 "even_register_operand" ""))]
749 && REGNO (operands[2]) == REGNO (operands[0]) - 1
750 && REGNO (operands[3]) == REGNO (operands[1]) - 1"
754 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
755 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
758 ;; For LPM loads from AS1 we split
762 ;; Z = Z - sizeof (R)
764 ;; so that the second instruction can be optimized out.
766 (define_split ; "split-lpmx"
767 [(set (match_operand:HISI 0 "register_operand" "")
768 (match_operand:HISI 1 "memory_operand" ""))]
774 (plus:HI (match_dup 3)
777 rtx addr = XEXP (operands[1], 0);
779 if (!avr_mem_flash_p (operands[1])
781 || reg_overlap_mentioned_p (addr, operands[0]))
786 operands[2] = replace_equiv_address (operands[1],
787 gen_rtx_POST_INC (Pmode, addr));
789 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
792 ;;==========================================================================
793 ;; xpointer move (24 bit)
795 (define_peephole2 ; *reload_inpsi
796 [(match_scratch:QI 2 "d")
797 (set (match_operand:PSI 0 "l_register_operand" "")
798 (match_operand:PSI 1 "immediate_operand" ""))
800 "operands[1] != const0_rtx
801 && operands[1] != constm1_rtx"
802 [(parallel [(set (match_dup 0)
804 (clobber (match_dup 2))])])
806 ;; '*' because it is not used in rtl generation.
807 (define_insn "*reload_inpsi"
808 [(set (match_operand:PSI 0 "register_operand" "=r")
809 (match_operand:PSI 1 "immediate_operand" "i"))
810 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
813 return avr_out_reload_inpsi (operands, operands[2], NULL);
815 [(set_attr "length" "6")
816 (set_attr "adjust_len" "reload_in24")
817 (set_attr "cc" "clobber")])
819 (define_insn "*movpsi"
820 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
821 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
822 "register_operand (operands[0], PSImode)
823 || register_operand (operands[1], PSImode)
824 || const0_rtx == operands[1]"
826 return avr_out_movpsi (insn, operands, NULL);
828 [(set_attr "length" "3,3,8,9,4,10")
829 (set_attr "adjust_len" "mov24")
830 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
832 ;;==========================================================================
833 ;; move double word (32 bit)
835 (define_peephole2 ; *reload_insi
836 [(match_scratch:QI 2 "d")
837 (set (match_operand:ALL4 0 "l_register_operand" "")
838 (match_operand:ALL4 1 "immediate_operand" ""))
840 "operands[1] != CONST0_RTX (<MODE>mode)"
841 [(parallel [(set (match_dup 0)
843 (clobber (match_dup 2))])])
845 ;; '*' because it is not used in rtl generation.
847 ;; "*reload_insq" "*reload_inusq"
848 ;; "*reload_insa" "*reload_inusa"
849 (define_insn "*reload_insi"
850 [(set (match_operand:ALL4 0 "register_operand" "=r")
851 (match_operand:ALL4 1 "immediate_operand" "n Ynn"))
852 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
855 return output_reload_insisf (operands, operands[2], NULL);
857 [(set_attr "length" "8")
858 (set_attr "adjust_len" "reload_in32")
859 (set_attr "cc" "clobber")])
863 ;; "*movsq" "*movusq"
864 ;; "*movsa" "*movusa"
865 (define_insn "*mov<mode>"
866 [(set (match_operand:ALL4 0 "nonimmediate_operand" "=r,r ,r ,Qm ,!d,r")
867 (match_operand:ALL4 1 "nox_general_operand" "r,Y00,Qm,r Y00,i ,i"))]
868 "register_operand (operands[0], <MODE>mode)
869 || reg_or_0_operand (operands[1], <MODE>mode)"
871 return output_movsisf (insn, operands, NULL);
873 [(set_attr "length" "4,4,8,9,4,10")
874 (set_attr "adjust_len" "mov32")
875 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
877 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
878 ;; move floating point numbers (32 bit)
880 (define_insn "*movsf"
881 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
882 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
883 "register_operand (operands[0], SFmode)
884 || reg_or_0_operand (operands[1], SFmode)"
886 return output_movsisf (insn, operands, NULL);
888 [(set_attr "length" "4,4,8,9,4,10")
889 (set_attr "adjust_len" "mov32")
890 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
892 (define_peephole2 ; *reload_insf
893 [(match_scratch:QI 2 "d")
894 (set (match_operand:SF 0 "l_register_operand" "")
895 (match_operand:SF 1 "const_double_operand" ""))
897 "operands[1] != CONST0_RTX (SFmode)"
898 [(parallel [(set (match_dup 0)
900 (clobber (match_dup 2))])])
902 ;; '*' because it is not used in rtl generation.
903 (define_insn "*reload_insf"
904 [(set (match_operand:SF 0 "register_operand" "=r")
905 (match_operand:SF 1 "const_double_operand" "F"))
906 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
909 return output_reload_insisf (operands, operands[2], NULL);
911 [(set_attr "length" "8")
912 (set_attr "adjust_len" "reload_in32")
913 (set_attr "cc" "clobber")])
915 ;;=========================================================================
916 ;; move string (like memcpy)
918 (define_expand "movmemhi"
919 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
920 (match_operand:BLK 1 "memory_operand" ""))
921 (use (match_operand:HI 2 "const_int_operand" ""))
922 (use (match_operand:HI 3 "const_int_operand" ""))])]
925 if (avr_emit_movmemhi (operands))
931 (define_mode_attr MOVMEM_r_d [(QI "r")
934 ;; $0 : Address Space
935 ;; $1, $2 : Loop register
936 ;; R30 : source address
937 ;; R26 : destination address
941 (define_insn "movmem_<mode>"
942 [(set (mem:BLK (reg:HI REG_X))
943 (mem:BLK (reg:HI REG_Z)))
944 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
946 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
947 (clobber (reg:HI REG_X))
948 (clobber (reg:HI REG_Z))
949 (clobber (reg:QI LPM_REGNO))
950 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
953 return avr_out_movmem (insn, operands, NULL);
955 [(set_attr "adjust_len" "movmem")
956 (set_attr "cc" "clobber")])
959 ;; $0 : Address Space
960 ;; $1 : RAMPZ RAM address
961 ;; R24 : #bytes and loop register
962 ;; R23:Z : 24-bit source address
963 ;; R26 : 16-bit destination address
967 (define_insn "movmemx_<mode>"
968 [(set (mem:BLK (reg:HI REG_X))
969 (mem:BLK (lo_sum:PSI (reg:QI 23)
971 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
974 (clobber (reg:HI REG_X))
975 (clobber (reg:HI REG_Z))
976 (clobber (reg:QI LPM_REGNO))
977 (clobber (reg:HI 24))
978 (clobber (reg:QI 23))
979 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
981 "%~call __movmemx_<mode>"
982 [(set_attr "type" "xcall")
983 (set_attr "cc" "clobber")])
986 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
987 ;; memset (%0, %2, %1)
989 (define_expand "setmemhi"
990 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
991 (match_operand 2 "const_int_operand" ""))
992 (use (match_operand:HI 1 "const_int_operand" ""))
993 (use (match_operand:HI 3 "const_int_operand" ""))
994 (clobber (match_scratch:HI 4 ""))
995 (clobber (match_dup 5))])]
999 enum machine_mode mode;
1001 /* If value to set is not zero, use the library routine. */
1002 if (operands[2] != const0_rtx)
1005 if (!CONST_INT_P (operands[1]))
1008 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
1009 operands[5] = gen_rtx_SCRATCH (mode);
1010 operands[1] = copy_to_mode_reg (mode,
1011 gen_int_mode (INTVAL (operands[1]), mode));
1012 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
1013 operands[0] = gen_rtx_MEM (BLKmode, addr0);
1017 (define_insn "*clrmemqi"
1018 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
1020 (use (match_operand:QI 1 "register_operand" "r"))
1021 (use (match_operand:QI 2 "const_int_operand" "n"))
1022 (clobber (match_scratch:HI 3 "=0"))
1023 (clobber (match_scratch:QI 4 "=&1"))]
1025 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
1026 [(set_attr "length" "3")
1027 (set_attr "cc" "clobber")])
1030 (define_insn "*clrmemhi"
1031 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
1033 (use (match_operand:HI 1 "register_operand" "!w,d"))
1034 (use (match_operand:HI 2 "const_int_operand" "n,n"))
1035 (clobber (match_scratch:HI 3 "=0,0"))
1036 (clobber (match_scratch:HI 4 "=&1,&1"))]
1039 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
1040 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
1041 [(set_attr "length" "3,4")
1042 (set_attr "cc" "clobber,clobber")])
1044 (define_expand "strlenhi"
1046 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
1047 (match_operand:QI 2 "const_int_operand" "")
1048 (match_operand:HI 3 "immediate_operand" "")]
1051 (plus:HI (match_dup 4)
1053 (parallel [(set (match_operand:HI 0 "register_operand" "")
1054 (minus:HI (match_dup 4)
1056 (clobber (scratch:QI))])]
1060 if (operands[2] != const0_rtx)
1062 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
1063 operands[1] = gen_rtx_MEM (BLKmode, addr);
1065 operands[4] = gen_reg_rtx (HImode);
1068 (define_insn "*strlenhi"
1069 [(set (match_operand:HI 0 "register_operand" "=e")
1070 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1072 (match_operand:HI 2 "immediate_operand" "i")]
1075 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1076 [(set_attr "length" "3")
1077 (set_attr "cc" "clobber")])
1079 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1083 ;; "addqq3" "adduqq3"
1084 (define_insn "add<mode>3"
1085 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1086 (plus:ALL1 (match_operand:ALL1 1 "register_operand" "%0,0 ,0 ,0 ,0 ,0")
1087 (match_operand:ALL1 2 "nonmemory_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1096 [(set_attr "length" "1,1,1,1,2,2")
1097 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1100 ;; "addhq3" "adduhq3"
1101 ;; "addha3" "adduha3"
1102 (define_expand "add<mode>3"
1103 [(set (match_operand:ALL2 0 "register_operand" "")
1104 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "")
1105 (match_operand:ALL2 2 "nonmemory_or_const_operand" "")))]
1108 if (CONST_INT_P (operands[2]))
1110 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1112 if (can_create_pseudo_p()
1113 && !stack_register_operand (operands[0], HImode)
1114 && !stack_register_operand (operands[1], HImode)
1115 && !d_register_operand (operands[0], HImode)
1116 && !d_register_operand (operands[1], HImode))
1118 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1123 if (CONST_FIXED_P (operands[2]))
1125 emit_insn (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
1131 (define_insn "*addhi3_zero_extend"
1132 [(set (match_operand:HI 0 "register_operand" "=r")
1133 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1134 (match_operand:HI 2 "register_operand" "0")))]
1136 "add %A0,%1\;adc %B0,__zero_reg__"
1137 [(set_attr "length" "2")
1138 (set_attr "cc" "set_n")])
1140 (define_insn "*addhi3_zero_extend1"
1141 [(set (match_operand:HI 0 "register_operand" "=r")
1142 (plus:HI (match_operand:HI 1 "register_operand" "0")
1143 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1145 "add %A0,%2\;adc %B0,__zero_reg__"
1146 [(set_attr "length" "2")
1147 (set_attr "cc" "set_n")])
1149 (define_insn "*addhi3.sign_extend1"
1150 [(set (match_operand:HI 0 "register_operand" "=r")
1151 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1152 (match_operand:HI 2 "register_operand" "0")))]
1155 return reg_overlap_mentioned_p (operands[0], operands[1])
1156 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1157 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1159 [(set_attr "length" "5")
1160 (set_attr "cc" "clobber")])
1162 (define_insn "*addhi3_sp"
1163 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1164 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1165 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1168 return avr_out_addto_sp (operands, NULL);
1170 [(set_attr "length" "6")
1171 (set_attr "adjust_len" "addto_sp")])
1174 ;; "*addhq3" "*adduhq3"
1175 ;; "*addha3" "*adduha3"
1176 (define_insn "*add<mode>3"
1177 [(set (match_operand:ALL2 0 "register_operand" "=?r,d,!w ,d")
1178 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0,0,0 ,0")
1179 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
1182 return avr_out_plus (insn, operands);
1184 [(set_attr "length" "2")
1185 (set_attr "adjust_len" "plus")
1186 (set_attr "cc" "plus")])
1188 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1189 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1190 ;; itself because that insn is special to reload.
1192 (define_peephole2 ; addhi3_clobber
1193 [(set (match_operand:ALL2 0 "d_register_operand" "")
1194 (match_operand:ALL2 1 "const_operand" ""))
1195 (set (match_operand:ALL2 2 "l_register_operand" "")
1196 (plus:ALL2 (match_dup 2)
1198 "peep2_reg_dead_p (2, operands[0])"
1199 [(parallel [(set (match_dup 2)
1200 (plus:ALL2 (match_dup 2)
1202 (clobber (match_dup 3))])]
1204 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
1207 ;; Same, but with reload to NO_LD_REGS
1208 ;; Combine *reload_inhi with *addhi3
1210 (define_peephole2 ; addhi3_clobber
1211 [(parallel [(set (match_operand:ALL2 0 "l_register_operand" "")
1212 (match_operand:ALL2 1 "const_operand" ""))
1213 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1214 (set (match_operand:ALL2 3 "l_register_operand" "")
1215 (plus:ALL2 (match_dup 3)
1217 "peep2_reg_dead_p (2, operands[0])"
1218 [(parallel [(set (match_dup 3)
1219 (plus:ALL2 (match_dup 3)
1221 (clobber (match_dup 2))])])
1224 ;; "addhq3_clobber" "adduhq3_clobber"
1225 ;; "addha3_clobber" "adduha3_clobber"
1226 (define_insn "add<mode>3_clobber"
1227 [(set (match_operand:ALL2 0 "register_operand" "=!w ,d ,r")
1228 (plus:ALL2 (match_operand:ALL2 1 "register_operand" "%0 ,0 ,0")
1229 (match_operand:ALL2 2 "const_operand" "IJ YIJ,n Ynn,n Ynn")))
1230 (clobber (match_scratch:QI 3 "=X ,X ,&d"))]
1233 return avr_out_plus (insn, operands);
1235 [(set_attr "length" "4")
1236 (set_attr "adjust_len" "plus")
1237 (set_attr "cc" "plus")])
1241 ;; "addsq3" "addusq3"
1242 ;; "addsa3" "addusa3"
1243 (define_insn "add<mode>3"
1244 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1245 (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
1246 (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
1247 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1250 return avr_out_plus (insn, operands);
1252 [(set_attr "length" "4")
1253 (set_attr "adjust_len" "plus")
1254 (set_attr "cc" "plus")])
1256 (define_insn "*addpsi3_zero_extend.qi"
1257 [(set (match_operand:PSI 0 "register_operand" "=r")
1258 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1259 (match_operand:PSI 2 "register_operand" "0")))]
1261 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1262 [(set_attr "length" "3")
1263 (set_attr "cc" "set_n")])
1265 (define_insn "*addpsi3_zero_extend.hi"
1266 [(set (match_operand:PSI 0 "register_operand" "=r")
1267 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1268 (match_operand:PSI 2 "register_operand" "0")))]
1270 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1271 [(set_attr "length" "3")
1272 (set_attr "cc" "set_n")])
1274 (define_insn "*addpsi3_sign_extend.hi"
1275 [(set (match_operand:PSI 0 "register_operand" "=r")
1276 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1277 (match_operand:PSI 2 "register_operand" "0")))]
1279 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1280 [(set_attr "length" "5")
1281 (set_attr "cc" "set_n")])
1283 (define_insn "*addsi3_zero_extend"
1284 [(set (match_operand:SI 0 "register_operand" "=r")
1285 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1286 (match_operand:SI 2 "register_operand" "0")))]
1288 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1289 [(set_attr "length" "4")
1290 (set_attr "cc" "set_n")])
1292 (define_insn "*addsi3_zero_extend.hi"
1293 [(set (match_operand:SI 0 "register_operand" "=r")
1294 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1295 (match_operand:SI 2 "register_operand" "0")))]
1297 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1298 [(set_attr "length" "4")
1299 (set_attr "cc" "set_n")])
1301 (define_insn "addpsi3"
1302 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1303 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1304 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1305 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1308 return avr_out_plus (insn, operands);
1310 [(set_attr "length" "3")
1311 (set_attr "adjust_len" "plus")
1312 (set_attr "cc" "plus")])
1314 (define_insn "subpsi3"
1315 [(set (match_operand:PSI 0 "register_operand" "=r")
1316 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1317 (match_operand:PSI 2 "register_operand" "r")))]
1319 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1320 [(set_attr "length" "3")
1321 (set_attr "cc" "set_czn")])
1323 (define_insn "*subpsi3_zero_extend.qi"
1324 [(set (match_operand:PSI 0 "register_operand" "=r")
1325 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1326 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1328 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1329 [(set_attr "length" "3")
1330 (set_attr "cc" "set_czn")])
1332 (define_insn "*subpsi3_zero_extend.hi"
1333 [(set (match_operand:PSI 0 "register_operand" "=r")
1334 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1335 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1337 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1338 [(set_attr "length" "3")
1339 (set_attr "cc" "set_czn")])
1341 (define_insn "*subpsi3_sign_extend.hi"
1342 [(set (match_operand:PSI 0 "register_operand" "=r")
1343 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1344 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1346 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1347 [(set_attr "length" "5")
1348 (set_attr "cc" "set_czn")])
1350 ;-----------------------------------------------------------------------------
1354 ;; "subqq3" "subuqq3"
1355 (define_insn "sub<mode>3"
1356 [(set (match_operand:ALL1 0 "register_operand" "=r,d ,r ,r ,r ,r")
1357 (minus:ALL1 (match_operand:ALL1 1 "register_operand" "0,0 ,0 ,0 ,0 ,0")
1358 (match_operand:ALL1 2 "nonmemory_or_const_operand" "r,n Ynn,Y01,Ym1,Y02,Ym2")))]
1367 [(set_attr "length" "1,1,1,1,2,2")
1368 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1371 ;; "subhq3" "subuhq3"
1372 ;; "subha3" "subuha3"
1373 (define_insn "sub<mode>3"
1374 [(set (match_operand:ALL2 0 "register_operand" "=r,d ,*r")
1375 (minus:ALL2 (match_operand:ALL2 1 "register_operand" "0,0 ,0")
1376 (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,i Ynn,Ynn")))
1377 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1380 return avr_out_plus (insn, operands);
1382 [(set_attr "adjust_len" "plus")
1383 (set_attr "cc" "plus")])
1385 (define_insn "*subhi3_zero_extend1"
1386 [(set (match_operand:HI 0 "register_operand" "=r")
1387 (minus:HI (match_operand:HI 1 "register_operand" "0")
1388 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1390 "sub %A0,%2\;sbc %B0,__zero_reg__"
1391 [(set_attr "length" "2")
1392 (set_attr "cc" "set_czn")])
1394 (define_insn "*subhi3.sign_extend2"
1395 [(set (match_operand:HI 0 "register_operand" "=r")
1396 (minus:HI (match_operand:HI 1 "register_operand" "0")
1397 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1400 return reg_overlap_mentioned_p (operands[0], operands[2])
1401 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1402 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1404 [(set_attr "length" "5")
1405 (set_attr "cc" "clobber")])
1408 ;; "subsq3" "subusq3"
1409 ;; "subsa3" "subusa3"
1410 (define_insn "sub<mode>3"
1411 [(set (match_operand:ALL4 0 "register_operand" "=r,d ,r")
1412 (minus:ALL4 (match_operand:ALL4 1 "register_operand" "0,0 ,0")
1413 (match_operand:ALL4 2 "nonmemory_or_const_operand" "r,n Ynn,Ynn")))
1414 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
1417 return avr_out_plus (insn, operands);
1419 [(set_attr "adjust_len" "plus")
1420 (set_attr "cc" "plus")])
1422 (define_insn "*subsi3_zero_extend"
1423 [(set (match_operand:SI 0 "register_operand" "=r")
1424 (minus:SI (match_operand:SI 1 "register_operand" "0")
1425 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1427 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1428 [(set_attr "length" "4")
1429 (set_attr "cc" "set_czn")])
1431 (define_insn "*subsi3_zero_extend.hi"
1432 [(set (match_operand:SI 0 "register_operand" "=r")
1433 (minus:SI (match_operand:SI 1 "register_operand" "0")
1434 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1436 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1437 [(set_attr "length" "4")
1438 (set_attr "cc" "set_czn")])
1440 ;******************************************************************************
1443 (define_expand "mulqi3"
1444 [(set (match_operand:QI 0 "register_operand" "")
1445 (mult:QI (match_operand:QI 1 "register_operand" "")
1446 (match_operand:QI 2 "register_operand" "")))]
1451 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1456 (define_insn "*mulqi3_enh"
1457 [(set (match_operand:QI 0 "register_operand" "=r")
1458 (mult:QI (match_operand:QI 1 "register_operand" "r")
1459 (match_operand:QI 2 "register_operand" "r")))]
1464 [(set_attr "length" "3")
1465 (set_attr "cc" "clobber")])
1467 (define_expand "mulqi3_call"
1468 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1469 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1470 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1471 (clobber (reg:QI 22))])
1472 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))])
1474 (define_insn "*mulqi3_call"
1475 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1476 (clobber (reg:QI 22))]
1479 [(set_attr "type" "xcall")
1480 (set_attr "cc" "clobber")])
1482 ;; "umulqi3_highpart"
1483 ;; "smulqi3_highpart"
1484 (define_insn "<extend_su>mulqi3_highpart"
1485 [(set (match_operand:QI 0 "register_operand" "=r")
1487 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1488 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1491 "mul<extend_s> %1,%2
1494 [(set_attr "length" "3")
1495 (set_attr "cc" "clobber")])
1498 ;; Used when expanding div or mod inline for some special values
1499 (define_insn "*subqi3.ashiftrt7"
1500 [(set (match_operand:QI 0 "register_operand" "=r")
1501 (minus:QI (match_operand:QI 1 "register_operand" "0")
1502 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1506 [(set_attr "length" "2")
1507 (set_attr "cc" "clobber")])
1509 (define_insn "*addqi3.lt0"
1510 [(set (match_operand:QI 0 "register_operand" "=r")
1511 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1513 (match_operand:QI 2 "register_operand" "0")))]
1516 [(set_attr "length" "2")
1517 (set_attr "cc" "clobber")])
1519 (define_insn "*addhi3.lt0"
1520 [(set (match_operand:HI 0 "register_operand" "=w,r")
1521 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1523 (match_operand:HI 2 "register_operand" "0,0")))
1524 (clobber (match_scratch:QI 3 "=X,&1"))]
1527 sbrc %1,7\;adiw %0,1
1528 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1529 [(set_attr "length" "2,3")
1530 (set_attr "cc" "clobber")])
1532 (define_insn "*addpsi3.lt0"
1533 [(set (match_operand:PSI 0 "register_operand" "=r")
1534 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1536 (match_operand:PSI 2 "register_operand" "0")))]
1538 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1539 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1540 [(set_attr "length" "5")
1541 (set_attr "cc" "clobber")])
1543 (define_insn "*addsi3.lt0"
1544 [(set (match_operand:SI 0 "register_operand" "=r")
1545 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1547 (match_operand:SI 2 "register_operand" "0")))]
1549 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1550 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1551 [(set_attr "length" "6")
1552 (set_attr "cc" "clobber")])
1554 (define_insn "*umulqihi3.call"
1556 (mult:HI (zero_extend:HI (reg:QI 22))
1557 (zero_extend:HI (reg:QI 24))))
1558 (clobber (reg:QI 21))
1559 (clobber (reg:HI 22))]
1561 "%~call __umulqihi3"
1562 [(set_attr "type" "xcall")
1563 (set_attr "cc" "clobber")])
1567 (define_insn "<extend_u>mulqihi3"
1568 [(set (match_operand:HI 0 "register_operand" "=r")
1569 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1570 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1572 "mul<extend_s> %1,%2
1575 [(set_attr "length" "3")
1576 (set_attr "cc" "clobber")])
1578 (define_insn "usmulqihi3"
1579 [(set (match_operand:HI 0 "register_operand" "=r")
1580 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1581 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1586 [(set_attr "length" "3")
1587 (set_attr "cc" "clobber")])
1589 ;; Above insn is not canonicalized by insn combine, so here is a version with
1590 ;; operands swapped.
1592 (define_insn "*sumulqihi3"
1593 [(set (match_operand:HI 0 "register_operand" "=r")
1594 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1595 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1600 [(set_attr "length" "3")
1601 (set_attr "cc" "clobber")])
1603 ;; One-extend operand 1
1605 (define_insn "*osmulqihi3"
1606 [(set (match_operand:HI 0 "register_operand" "=&r")
1607 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1608 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1614 [(set_attr "length" "4")
1615 (set_attr "cc" "clobber")])
1617 (define_insn "*oumulqihi3"
1618 [(set (match_operand:HI 0 "register_operand" "=&r")
1619 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1620 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1626 [(set_attr "length" "4")
1627 (set_attr "cc" "clobber")])
1629 ;******************************************************************************
1630 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1631 ;******************************************************************************
1633 (define_insn "*maddqi4"
1634 [(set (match_operand:QI 0 "register_operand" "=r")
1635 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1636 (match_operand:QI 2 "register_operand" "r"))
1637 (match_operand:QI 3 "register_operand" "0")))]
1643 [(set_attr "length" "4")
1644 (set_attr "cc" "clobber")])
1646 (define_insn "*msubqi4"
1647 [(set (match_operand:QI 0 "register_operand" "=r")
1648 (minus:QI (match_operand:QI 3 "register_operand" "0")
1649 (mult:QI (match_operand:QI 1 "register_operand" "r")
1650 (match_operand:QI 2 "register_operand" "r"))))]
1655 [(set_attr "length" "4")
1656 (set_attr "cc" "clobber")])
1658 (define_insn_and_split "*maddqi4.const"
1659 [(set (match_operand:QI 0 "register_operand" "=r")
1660 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1661 (match_operand:QI 2 "const_int_operand" "n"))
1662 (match_operand:QI 3 "register_operand" "0")))
1663 (clobber (match_scratch:QI 4 "=&d"))]
1666 "&& reload_completed"
1671 (plus:QI (mult:QI (match_dup 1)
1675 (define_insn_and_split "*msubqi4.const"
1676 [(set (match_operand:QI 0 "register_operand" "=r")
1677 (minus:QI (match_operand:QI 3 "register_operand" "0")
1678 (mult:QI (match_operand:QI 1 "register_operand" "r")
1679 (match_operand:QI 2 "const_int_operand" "n"))))
1680 (clobber (match_scratch:QI 4 "=&d"))]
1683 "&& reload_completed"
1688 (minus:QI (match_dup 3)
1689 (mult:QI (match_dup 1)
1693 ;******************************************************************************
1694 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1695 ;******************************************************************************
1697 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1700 ;; int foo (unsigned char z)
1702 ;; extern int aInt[];
1703 ;; return aInt[3*z+2];
1706 ;; because the constant +4 then is added explicitely instead of consuming it
1707 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1708 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1709 ;; The implementational effort is the same so we are fine with that approach.
1714 (define_insn "*<extend_u>maddqihi4"
1715 [(set (match_operand:HI 0 "register_operand" "=r")
1716 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1717 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1718 (match_operand:HI 3 "register_operand" "0")))]
1721 "mul<extend_s> %1,%2
1725 [(set_attr "length" "4")
1726 (set_attr "cc" "clobber")])
1730 (define_insn "*<extend_u>msubqihi4"
1731 [(set (match_operand:HI 0 "register_operand" "=r")
1732 (minus:HI (match_operand:HI 3 "register_operand" "0")
1733 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1734 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1736 "mul<extend_s> %1,%2
1740 [(set_attr "length" "4")
1741 (set_attr "cc" "clobber")])
1745 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1746 [(set (match_operand:HI 0 "register_operand" "=r")
1747 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1748 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1749 (match_operand:HI 3 "register_operand" "0")))]
1752 && <any_extend:CODE> != <any_extend2:CODE>"
1754 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1755 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1757 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1759 [(set_attr "length" "4")
1760 (set_attr "cc" "clobber")])
1764 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1765 [(set (match_operand:HI 0 "register_operand" "=r")
1766 (minus:HI (match_operand:HI 3 "register_operand" "0")
1767 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1768 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1771 && <any_extend:CODE> != <any_extend2:CODE>"
1773 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1774 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1776 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1778 [(set_attr "length" "4")
1779 (set_attr "cc" "clobber")])
1781 ;; Handle small constants
1783 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1784 ;; This is shorter, faster than MUL and has lower register pressure.
1786 (define_insn_and_split "*umaddqihi4.2"
1787 [(set (match_operand:HI 0 "register_operand" "=r")
1788 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1790 (match_operand:HI 2 "register_operand" "r")))]
1792 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1793 { gcc_unreachable(); }
1797 ; *addhi3_zero_extend
1799 (plus:HI (zero_extend:HI (match_dup 1))
1801 ; *addhi3_zero_extend
1803 (plus:HI (zero_extend:HI (match_dup 1))
1806 ;; "umaddqihi4.uconst"
1807 ;; "maddqihi4.sconst"
1808 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1809 [(set (match_operand:HI 0 "register_operand" "=r")
1810 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1811 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1812 (match_operand:HI 3 "register_operand" "0")))
1813 (clobber (match_scratch:QI 4 "=&d"))]
1816 "&& reload_completed"
1819 ; *umaddqihi4 resp. *maddqihi4
1821 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1822 (any_extend:HI (match_dup 4)))
1825 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1828 ;; "*umsubqihi4.uconst"
1829 ;; "*msubqihi4.sconst"
1830 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1831 [(set (match_operand:HI 0 "register_operand" "=r")
1832 (minus:HI (match_operand:HI 3 "register_operand" "0")
1833 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1834 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1835 (clobber (match_scratch:QI 4 "=&d"))]
1838 "&& reload_completed"
1841 ; *umsubqihi4 resp. *msubqihi4
1843 (minus:HI (match_dup 3)
1844 (mult:HI (any_extend:HI (match_dup 1))
1845 (any_extend:HI (match_dup 4)))))]
1847 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1850 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1851 ;; for MULT with power of 2 and skips trying MULT insn above.
1853 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1854 [(set (match_operand:HI 0 "register_operand" "=r")
1855 (minus:HI (match_operand:HI 3 "register_operand" "0")
1856 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1857 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1858 (clobber (match_scratch:QI 4 "=&d"))]
1861 "&& reload_completed"
1866 (minus:HI (match_dup 3)
1867 (mult:HI (zero_extend:HI (match_dup 1))
1868 (zero_extend:HI (match_dup 4)))))]
1870 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1873 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1874 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1875 ;; because this would require an extra pattern for just one value.
1877 (define_insn_and_split "*msubqihi4.sconst.ashift"
1878 [(set (match_operand:HI 0 "register_operand" "=r")
1879 (minus:HI (match_operand:HI 3 "register_operand" "0")
1880 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1881 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1882 (clobber (match_scratch:QI 4 "=&d"))]
1885 "&& reload_completed"
1890 (minus:HI (match_dup 3)
1891 (mult:HI (sign_extend:HI (match_dup 1))
1892 (sign_extend:HI (match_dup 4)))))]
1894 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1897 ;; For signed/unsigned combinations that require narrow constraint "a"
1898 ;; just provide a pattern if signed/unsigned combination is actually needed.
1900 (define_insn_and_split "*sumaddqihi4.uconst"
1901 [(set (match_operand:HI 0 "register_operand" "=r")
1902 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1903 (match_operand:HI 2 "u8_operand" "M"))
1904 (match_operand:HI 3 "register_operand" "0")))
1905 (clobber (match_scratch:QI 4 "=&a"))]
1907 && !s8_operand (operands[2], VOIDmode)"
1909 "&& reload_completed"
1914 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1915 (zero_extend:HI (match_dup 4)))
1918 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1921 (define_insn_and_split "*sumsubqihi4.uconst"
1922 [(set (match_operand:HI 0 "register_operand" "=r")
1923 (minus:HI (match_operand:HI 3 "register_operand" "0")
1924 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1925 (match_operand:HI 2 "u8_operand" "M"))))
1926 (clobber (match_scratch:QI 4 "=&a"))]
1928 && !s8_operand (operands[2], VOIDmode)"
1930 "&& reload_completed"
1935 (minus:HI (match_dup 3)
1936 (mult:HI (sign_extend:HI (match_dup 1))
1937 (zero_extend:HI (match_dup 4)))))]
1939 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1942 ;******************************************************************************
1943 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1944 ;******************************************************************************
1946 ;; "*muluqihi3.uconst"
1947 ;; "*mulsqihi3.sconst"
1948 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1949 [(set (match_operand:HI 0 "register_operand" "=r")
1950 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1951 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1952 (clobber (match_scratch:QI 3 "=&d"))]
1955 "&& reload_completed"
1958 ; umulqihi3 resp. mulqihi3
1960 (mult:HI (any_extend:HI (match_dup 1))
1961 (any_extend:HI (match_dup 3))))]
1963 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1966 (define_insn_and_split "*muluqihi3.sconst"
1967 [(set (match_operand:HI 0 "register_operand" "=r")
1968 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1969 (match_operand:HI 2 "s8_operand" "n")))
1970 (clobber (match_scratch:QI 3 "=&a"))]
1973 "&& reload_completed"
1978 (mult:HI (zero_extend:HI (match_dup 1))
1979 (sign_extend:HI (match_dup 3))))]
1981 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1984 (define_insn_and_split "*mulsqihi3.uconst"
1985 [(set (match_operand:HI 0 "register_operand" "=r")
1986 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1987 (match_operand:HI 2 "u8_operand" "M")))
1988 (clobber (match_scratch:QI 3 "=&a"))]
1991 "&& reload_completed"
1996 (mult:HI (zero_extend:HI (match_dup 3))
1997 (sign_extend:HI (match_dup 1))))]
1999 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2002 (define_insn_and_split "*mulsqihi3.oconst"
2003 [(set (match_operand:HI 0 "register_operand" "=&r")
2004 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2005 (match_operand:HI 2 "o8_operand" "n")))
2006 (clobber (match_scratch:QI 3 "=&a"))]
2009 "&& reload_completed"
2014 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
2015 (sign_extend:HI (match_dup 1))))]
2017 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
2020 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
2021 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
2022 ;; at that time. Fix that.
2024 (define_insn "*ashiftqihi2.signx.1"
2025 [(set (match_operand:HI 0 "register_operand" "=r,*r")
2026 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
2030 lsl %A0\;sbc %B0,%B0
2031 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
2032 [(set_attr "length" "2,3")
2033 (set_attr "cc" "clobber")])
2035 (define_insn_and_split "*ashifthi3.signx.const"
2036 [(set (match_operand:HI 0 "register_operand" "=r")
2037 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
2038 (match_operand:HI 2 "const_2_to_6_operand" "I")))
2039 (clobber (match_scratch:QI 3 "=&d"))]
2042 "&& reload_completed"
2047 (mult:HI (sign_extend:HI (match_dup 1))
2048 (sign_extend:HI (match_dup 3))))]
2050 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
2053 (define_insn_and_split "*ashifthi3.signx.const7"
2054 [(set (match_operand:HI 0 "register_operand" "=r")
2055 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2057 (clobber (match_scratch:QI 2 "=&a"))]
2060 "&& reload_completed"
2065 (mult:HI (zero_extend:HI (match_dup 2))
2066 (sign_extend:HI (match_dup 1))))]
2068 operands[3] = gen_int_mode (1 << 7, QImode);
2071 (define_insn_and_split "*ashifthi3.zerox.const"
2072 [(set (match_operand:HI 0 "register_operand" "=r")
2073 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2074 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2075 (clobber (match_scratch:QI 3 "=&d"))]
2078 "&& reload_completed"
2083 (mult:HI (zero_extend:HI (match_dup 1))
2084 (zero_extend:HI (match_dup 3))))]
2086 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2089 ;******************************************************************************
2090 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2091 ;******************************************************************************
2093 (define_insn "mulsqihi3"
2094 [(set (match_operand:HI 0 "register_operand" "=&r")
2095 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2096 (match_operand:HI 2 "register_operand" "a")))]
2103 [(set_attr "length" "5")
2104 (set_attr "cc" "clobber")])
2106 (define_insn "muluqihi3"
2107 [(set (match_operand:HI 0 "register_operand" "=&r")
2108 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2109 (match_operand:HI 2 "register_operand" "r")))]
2116 [(set_attr "length" "5")
2117 (set_attr "cc" "clobber")])
2119 ;; one-extend operand 1
2121 (define_insn "muloqihi3"
2122 [(set (match_operand:HI 0 "register_operand" "=&r")
2123 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2124 (match_operand:HI 2 "register_operand" "r")))]
2132 [(set_attr "length" "6")
2133 (set_attr "cc" "clobber")])
2135 ;******************************************************************************
2137 (define_expand "mulhi3"
2138 [(set (match_operand:HI 0 "register_operand" "")
2139 (mult:HI (match_operand:HI 1 "register_operand" "")
2140 (match_operand:HI 2 "register_or_s9_operand" "")))]
2145 if (!register_operand (operands[2], HImode))
2146 operands[2] = force_reg (HImode, operands[2]);
2148 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2152 /* For small constants we can do better by extending them on the fly.
2153 The constant can be loaded in one instruction and the widening
2154 multiplication is shorter. First try the unsigned variant because it
2155 allows constraint "d" instead of "a" for the signed version. */
2157 if (s9_operand (operands[2], HImode))
2159 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2161 if (u8_operand (operands[2], HImode))
2163 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2165 else if (s8_operand (operands[2], HImode))
2167 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2171 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2177 if (!register_operand (operands[2], HImode))
2178 operands[2] = force_reg (HImode, operands[2]);
2181 (define_insn "*mulhi3_enh"
2182 [(set (match_operand:HI 0 "register_operand" "=&r")
2183 (mult:HI (match_operand:HI 1 "register_operand" "r")
2184 (match_operand:HI 2 "register_operand" "r")))]
2187 return REGNO (operands[1]) == REGNO (operands[2])
2188 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2189 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2191 [(set_attr "length" "7")
2192 (set_attr "cc" "clobber")])
2194 (define_expand "mulhi3_call"
2195 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2196 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2197 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2198 (clobber (reg:HI 22))
2199 (clobber (reg:QI 21))])
2200 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))])
2202 (define_insn "*mulhi3_call"
2203 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2204 (clobber (reg:HI 22))
2205 (clobber (reg:QI 21))]
2208 [(set_attr "type" "xcall")
2209 (set_attr "cc" "clobber")])
2211 ;; To support widening multiplication with constant we postpone
2212 ;; expanding to the implicit library call until post combine and
2213 ;; prior to register allocation. Clobber all hard registers that
2214 ;; might be used by the (widening) multiply until it is split and
2215 ;; it's final register footprint is worked out.
2217 (define_expand "mulsi3"
2218 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2219 (mult:SI (match_operand:SI 1 "register_operand" "")
2220 (match_operand:SI 2 "nonmemory_operand" "")))
2221 (clobber (reg:HI 26))
2222 (clobber (reg:DI 18))])]
2225 if (u16_operand (operands[2], SImode))
2227 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2228 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2232 if (o16_operand (operands[2], SImode))
2234 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2235 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2240 (define_insn_and_split "*mulsi3"
2241 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2242 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2243 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2244 (clobber (reg:HI 26))
2245 (clobber (reg:DI 18))]
2246 "AVR_HAVE_MUL && !reload_completed"
2247 { gcc_unreachable(); }
2253 (parallel [(set (reg:SI 22)
2254 (mult:SI (reg:SI 22)
2256 (clobber (reg:HI 26))])
2260 if (u16_operand (operands[2], SImode))
2262 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2263 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2267 if (o16_operand (operands[2], SImode))
2269 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2270 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2277 (define_insn_and_split "mulu<mode>si3"
2278 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2279 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2280 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2281 (clobber (reg:HI 26))
2282 (clobber (reg:DI 18))]
2283 "AVR_HAVE_MUL && !reload_completed"
2284 { gcc_unreachable(); }
2291 (mult:SI (zero_extend:SI (reg:HI 26))
2296 /* Do the QI -> HI extension explicitely before the multiplication. */
2297 /* Do the HI -> SI extension implicitely and after the multiplication. */
2299 if (QImode == <MODE>mode)
2300 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2302 if (u16_operand (operands[2], SImode))
2304 operands[1] = force_reg (HImode, operands[1]);
2305 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2306 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2313 (define_insn_and_split "muls<mode>si3"
2314 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2315 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2316 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2317 (clobber (reg:HI 26))
2318 (clobber (reg:DI 18))]
2319 "AVR_HAVE_MUL && !reload_completed"
2320 { gcc_unreachable(); }
2327 (mult:SI (sign_extend:SI (reg:HI 26))
2332 /* Do the QI -> HI extension explicitely before the multiplication. */
2333 /* Do the HI -> SI extension implicitely and after the multiplication. */
2335 if (QImode == <MODE>mode)
2336 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2338 if (u16_operand (operands[2], SImode)
2339 || s16_operand (operands[2], SImode))
2341 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2343 operands[1] = force_reg (HImode, operands[1]);
2345 if (u16_operand (operands[2], SImode))
2346 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2348 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2354 ;; One-extend operand 1
2356 (define_insn_and_split "mulohisi3"
2357 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2358 (mult:SI (not:SI (zero_extend:SI
2359 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2360 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2361 (clobber (reg:HI 26))
2362 (clobber (reg:DI 18))]
2363 "AVR_HAVE_MUL && !reload_completed"
2364 { gcc_unreachable(); }
2371 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2378 (define_expand "<extend_u>mulhisi3"
2379 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2380 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2381 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2382 (clobber (reg:HI 26))
2383 (clobber (reg:DI 18))])]
2386 (define_expand "usmulhisi3"
2387 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2388 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2389 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2390 (clobber (reg:HI 26))
2391 (clobber (reg:DI 18))])]
2394 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2395 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2396 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2397 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2398 (define_insn_and_split
2399 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2400 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2401 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2402 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2403 (clobber (reg:HI 26))
2404 (clobber (reg:DI 18))]
2405 "AVR_HAVE_MUL && !reload_completed"
2406 { gcc_unreachable(); }
2413 (mult:SI (match_dup 3)
2418 rtx xop1 = operands[1];
2419 rtx xop2 = operands[2];
2421 /* Do the QI -> HI extension explicitely before the multiplication. */
2422 /* Do the HI -> SI extension implicitely and after the multiplication. */
2424 if (QImode == <QIHI:MODE>mode)
2425 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2427 if (QImode == <QIHI2:MODE>mode)
2428 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2430 if (<any_extend:CODE> == <any_extend2:CODE>
2431 || <any_extend:CODE> == ZERO_EXTEND)
2435 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2436 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2440 /* <any_extend:CODE> = SIGN_EXTEND */
2441 /* <any_extend2:CODE> = ZERO_EXTEND */
2445 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2446 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2450 ;; "smulhi3_highpart"
2451 ;; "umulhi3_highpart"
2452 (define_expand "<extend_su>mulhi3_highpart"
2454 (match_operand:HI 1 "nonmemory_operand" ""))
2456 (match_operand:HI 2 "nonmemory_operand" ""))
2457 (parallel [(set (reg:HI 24)
2458 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2459 (any_extend:SI (reg:HI 26)))
2461 (clobber (reg:HI 22))])
2462 (set (match_operand:HI 0 "register_operand" "")
2467 (define_insn "*mulsi3_call"
2469 (mult:SI (reg:SI 22)
2471 (clobber (reg:HI 26))]
2474 [(set_attr "type" "xcall")
2475 (set_attr "cc" "clobber")])
2478 ;; "*umulhisi3_call"
2479 (define_insn "*<extend_u>mulhisi3_call"
2481 (mult:SI (any_extend:SI (reg:HI 18))
2482 (any_extend:SI (reg:HI 26))))]
2484 "%~call __<extend_u>mulhisi3"
2485 [(set_attr "type" "xcall")
2486 (set_attr "cc" "clobber")])
2488 ;; "*umulhi3_highpart_call"
2489 ;; "*smulhi3_highpart_call"
2490 (define_insn "*<extend_su>mulhi3_highpart_call"
2492 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2493 (any_extend:SI (reg:HI 26)))
2495 (clobber (reg:HI 22))]
2497 "%~call __<extend_u>mulhisi3"
2498 [(set_attr "type" "xcall")
2499 (set_attr "cc" "clobber")])
2501 (define_insn "*usmulhisi3_call"
2503 (mult:SI (zero_extend:SI (reg:HI 18))
2504 (sign_extend:SI (reg:HI 26))))]
2506 "%~call __usmulhisi3"
2507 [(set_attr "type" "xcall")
2508 (set_attr "cc" "clobber")])
2510 (define_insn "*mul<extend_su>hisi3_call"
2512 (mult:SI (any_extend:SI (reg:HI 26))
2515 "%~call __mul<extend_su>hisi3"
2516 [(set_attr "type" "xcall")
2517 (set_attr "cc" "clobber")])
2519 (define_insn "*mulohisi3_call"
2521 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2524 "%~call __mulohisi3"
2525 [(set_attr "type" "xcall")
2526 (set_attr "cc" "clobber")])
2528 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2531 ;; Generate lib1funcs.S calls ourselves, because:
2532 ;; - we know exactly which registers are clobbered (for QI and HI
2533 ;; modes, some of the call-used registers are preserved)
2534 ;; - we get both the quotient and the remainder at no extra cost
2535 ;; - we split the patterns only after the first CSE passes because
2536 ;; CSE has problems to operate on hard regs.
2538 (define_insn_and_split "divmodqi4"
2539 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2540 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2541 (match_operand:QI 2 "pseudo_register_operand" "")))
2542 (set (match_operand:QI 3 "pseudo_register_operand" "")
2543 (mod:QI (match_dup 1) (match_dup 2)))
2544 (clobber (reg:QI 22))
2545 (clobber (reg:QI 23))
2546 (clobber (reg:QI 24))
2547 (clobber (reg:QI 25))])]
2549 "this divmodqi4 pattern should have been splitted;"
2551 [(set (reg:QI 24) (match_dup 1))
2552 (set (reg:QI 22) (match_dup 2))
2553 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2554 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2555 (clobber (reg:QI 22))
2556 (clobber (reg:QI 23))])
2557 (set (match_dup 0) (reg:QI 24))
2558 (set (match_dup 3) (reg:QI 25))])
2560 (define_insn "*divmodqi4_call"
2561 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2562 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2563 (clobber (reg:QI 22))
2564 (clobber (reg:QI 23))]
2566 "%~call __divmodqi4"
2567 [(set_attr "type" "xcall")
2568 (set_attr "cc" "clobber")])
2570 (define_insn_and_split "udivmodqi4"
2571 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2572 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2573 (match_operand:QI 2 "pseudo_register_operand" "")))
2574 (set (match_operand:QI 3 "pseudo_register_operand" "")
2575 (umod:QI (match_dup 1) (match_dup 2)))
2576 (clobber (reg:QI 22))
2577 (clobber (reg:QI 23))
2578 (clobber (reg:QI 24))
2579 (clobber (reg:QI 25))])]
2581 "this udivmodqi4 pattern should have been splitted;"
2583 [(set (reg:QI 24) (match_dup 1))
2584 (set (reg:QI 22) (match_dup 2))
2585 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2586 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2587 (clobber (reg:QI 23))])
2588 (set (match_dup 0) (reg:QI 24))
2589 (set (match_dup 3) (reg:QI 25))])
2591 (define_insn "*udivmodqi4_call"
2592 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2593 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2594 (clobber (reg:QI 23))]
2596 "%~call __udivmodqi4"
2597 [(set_attr "type" "xcall")
2598 (set_attr "cc" "clobber")])
2600 (define_insn_and_split "divmodhi4"
2601 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2602 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2603 (match_operand:HI 2 "pseudo_register_operand" "")))
2604 (set (match_operand:HI 3 "pseudo_register_operand" "")
2605 (mod:HI (match_dup 1) (match_dup 2)))
2606 (clobber (reg:QI 21))
2607 (clobber (reg:HI 22))
2608 (clobber (reg:HI 24))
2609 (clobber (reg:HI 26))])]
2611 "this should have been splitted;"
2613 [(set (reg:HI 24) (match_dup 1))
2614 (set (reg:HI 22) (match_dup 2))
2615 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2616 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2617 (clobber (reg:HI 26))
2618 (clobber (reg:QI 21))])
2619 (set (match_dup 0) (reg:HI 22))
2620 (set (match_dup 3) (reg:HI 24))])
2622 (define_insn "*divmodhi4_call"
2623 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2624 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2625 (clobber (reg:HI 26))
2626 (clobber (reg:QI 21))]
2628 "%~call __divmodhi4"
2629 [(set_attr "type" "xcall")
2630 (set_attr "cc" "clobber")])
2632 (define_insn_and_split "udivmodhi4"
2633 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2634 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2635 (match_operand:HI 2 "pseudo_register_operand" "")))
2636 (set (match_operand:HI 3 "pseudo_register_operand" "")
2637 (umod:HI (match_dup 1) (match_dup 2)))
2638 (clobber (reg:QI 21))
2639 (clobber (reg:HI 22))
2640 (clobber (reg:HI 24))
2641 (clobber (reg:HI 26))])]
2643 "this udivmodhi4 pattern should have been splitted.;"
2645 [(set (reg:HI 24) (match_dup 1))
2646 (set (reg:HI 22) (match_dup 2))
2647 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2648 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2649 (clobber (reg:HI 26))
2650 (clobber (reg:QI 21))])
2651 (set (match_dup 0) (reg:HI 22))
2652 (set (match_dup 3) (reg:HI 24))])
2654 (define_insn "*udivmodhi4_call"
2655 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2656 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2657 (clobber (reg:HI 26))
2658 (clobber (reg:QI 21))]
2660 "%~call __udivmodhi4"
2661 [(set_attr "type" "xcall")
2662 (set_attr "cc" "clobber")])
2664 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2667 ;; To support widening multiplication with constant we postpone
2668 ;; expanding to the implicit library call until post combine and
2669 ;; prior to register allocation. Clobber all hard registers that
2670 ;; might be used by the (widening) multiply until it is split and
2671 ;; it's final register footprint is worked out.
2673 (define_expand "mulpsi3"
2674 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2675 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2676 (match_operand:PSI 2 "nonmemory_operand" "")))
2677 (clobber (reg:HI 26))
2678 (clobber (reg:DI 18))])]
2681 if (s8_operand (operands[2], PSImode))
2683 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2684 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2689 (define_insn "*umulqihipsi3"
2690 [(set (match_operand:PSI 0 "register_operand" "=&r")
2691 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2692 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2701 [(set_attr "length" "7")
2702 (set_attr "cc" "clobber")])
2704 (define_insn "*umulhiqipsi3"
2705 [(set (match_operand:PSI 0 "register_operand" "=&r")
2706 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2707 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2715 adc %C0,__zero_reg__"
2716 [(set_attr "length" "7")
2717 (set_attr "cc" "clobber")])
2719 (define_insn_and_split "mulsqipsi3"
2720 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2721 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2722 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2723 (clobber (reg:HI 26))
2724 (clobber (reg:DI 18))]
2725 "AVR_HAVE_MUL && !reload_completed"
2726 { gcc_unreachable(); }
2733 (mult:PSI (sign_extend:PSI (reg:QI 25))
2738 (define_insn_and_split "*mulpsi3"
2739 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2740 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2741 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2742 (clobber (reg:HI 26))
2743 (clobber (reg:DI 18))]
2744 "AVR_HAVE_MUL && !reload_completed"
2745 { gcc_unreachable(); }
2751 (parallel [(set (reg:PSI 22)
2752 (mult:PSI (reg:PSI 22)
2754 (clobber (reg:QI 21))
2755 (clobber (reg:QI 25))
2756 (clobber (reg:HI 26))])
2760 if (s8_operand (operands[2], PSImode))
2762 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2763 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2768 (define_insn "*mulsqipsi3.libgcc"
2770 (mult:PSI (sign_extend:PSI (reg:QI 25))
2773 "%~call __mulsqipsi3"
2774 [(set_attr "type" "xcall")
2775 (set_attr "cc" "clobber")])
2777 (define_insn "*mulpsi3.libgcc"
2779 (mult:PSI (reg:PSI 22)
2781 (clobber (reg:QI 21))
2782 (clobber (reg:QI 25))
2783 (clobber (reg:HI 26))]
2786 [(set_attr "type" "xcall")
2787 (set_attr "cc" "clobber")])
2790 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2791 ;; 24-bit signed/unsigned division and modulo.
2792 ;; Notice that the libgcc implementation return the quotient in R22
2793 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2794 ;; implementation works the other way round.
2796 (define_insn_and_split "divmodpsi4"
2797 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2798 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2799 (match_operand:PSI 2 "pseudo_register_operand" "")))
2800 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2801 (mod:PSI (match_dup 1)
2803 (clobber (reg:DI 18))
2804 (clobber (reg:QI 26))])]
2806 { gcc_unreachable(); }
2808 [(set (reg:PSI 22) (match_dup 1))
2809 (set (reg:PSI 18) (match_dup 2))
2810 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2811 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2812 (clobber (reg:QI 21))
2813 (clobber (reg:QI 25))
2814 (clobber (reg:QI 26))])
2815 (set (match_dup 0) (reg:PSI 22))
2816 (set (match_dup 3) (reg:PSI 18))])
2818 (define_insn "*divmodpsi4_call"
2819 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2820 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2821 (clobber (reg:QI 21))
2822 (clobber (reg:QI 25))
2823 (clobber (reg:QI 26))]
2825 "%~call __divmodpsi4"
2826 [(set_attr "type" "xcall")
2827 (set_attr "cc" "clobber")])
2829 (define_insn_and_split "udivmodpsi4"
2830 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2831 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2832 (match_operand:PSI 2 "pseudo_register_operand" "")))
2833 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2834 (umod:PSI (match_dup 1)
2836 (clobber (reg:DI 18))
2837 (clobber (reg:QI 26))])]
2839 { gcc_unreachable(); }
2841 [(set (reg:PSI 22) (match_dup 1))
2842 (set (reg:PSI 18) (match_dup 2))
2843 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2844 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2845 (clobber (reg:QI 21))
2846 (clobber (reg:QI 25))
2847 (clobber (reg:QI 26))])
2848 (set (match_dup 0) (reg:PSI 22))
2849 (set (match_dup 3) (reg:PSI 18))])
2851 (define_insn "*udivmodpsi4_call"
2852 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2853 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2854 (clobber (reg:QI 21))
2855 (clobber (reg:QI 25))
2856 (clobber (reg:QI 26))]
2858 "%~call __udivmodpsi4"
2859 [(set_attr "type" "xcall")
2860 (set_attr "cc" "clobber")])
2862 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2864 (define_insn_and_split "divmodsi4"
2865 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2866 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2867 (match_operand:SI 2 "pseudo_register_operand" "")))
2868 (set (match_operand:SI 3 "pseudo_register_operand" "")
2869 (mod:SI (match_dup 1) (match_dup 2)))
2870 (clobber (reg:SI 18))
2871 (clobber (reg:SI 22))
2872 (clobber (reg:HI 26))
2873 (clobber (reg:HI 30))])]
2875 "this divmodsi4 pattern should have been splitted;"
2877 [(set (reg:SI 22) (match_dup 1))
2878 (set (reg:SI 18) (match_dup 2))
2879 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2880 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2881 (clobber (reg:HI 26))
2882 (clobber (reg:HI 30))])
2883 (set (match_dup 0) (reg:SI 18))
2884 (set (match_dup 3) (reg:SI 22))])
2886 (define_insn "*divmodsi4_call"
2887 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2888 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2889 (clobber (reg:HI 26))
2890 (clobber (reg:HI 30))]
2892 "%~call __divmodsi4"
2893 [(set_attr "type" "xcall")
2894 (set_attr "cc" "clobber")])
2896 (define_insn_and_split "udivmodsi4"
2897 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2898 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2899 (match_operand:SI 2 "pseudo_register_operand" "")))
2900 (set (match_operand:SI 3 "pseudo_register_operand" "")
2901 (umod:SI (match_dup 1) (match_dup 2)))
2902 (clobber (reg:SI 18))
2903 (clobber (reg:SI 22))
2904 (clobber (reg:HI 26))
2905 (clobber (reg:HI 30))])]
2907 "this udivmodsi4 pattern should have been splitted;"
2909 [(set (reg:SI 22) (match_dup 1))
2910 (set (reg:SI 18) (match_dup 2))
2911 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2912 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2913 (clobber (reg:HI 26))
2914 (clobber (reg:HI 30))])
2915 (set (match_dup 0) (reg:SI 18))
2916 (set (match_dup 3) (reg:SI 22))])
2918 (define_insn "*udivmodsi4_call"
2919 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2920 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2921 (clobber (reg:HI 26))
2922 (clobber (reg:HI 30))]
2924 "%~call __udivmodsi4"
2925 [(set_attr "type" "xcall")
2926 (set_attr "cc" "clobber")])
2928 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2931 (define_insn "andqi3"
2932 [(set (match_operand:QI 0 "register_operand" "=r,d")
2933 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2934 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2939 [(set_attr "length" "1,1")
2940 (set_attr "cc" "set_zn,set_zn")])
2942 (define_insn "andhi3"
2943 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2944 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2945 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2946 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2949 if (which_alternative == 0)
2950 return "and %A0,%A2\;and %B0,%B2";
2951 else if (which_alternative == 1)
2952 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2954 return avr_out_bitop (insn, operands, NULL);
2956 [(set_attr "length" "2,2,2,4,4")
2957 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2958 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2960 (define_insn "andpsi3"
2961 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2962 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2963 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2964 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2967 if (which_alternative == 0)
2968 return "and %A0,%A2" CR_TAB
2969 "and %B0,%B2" CR_TAB
2972 return avr_out_bitop (insn, operands, NULL);
2974 [(set_attr "length" "3,3,6,6")
2975 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2976 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2978 (define_insn "andsi3"
2979 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2980 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2981 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2982 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2985 if (which_alternative == 0)
2986 return "and %0,%2" CR_TAB
2987 "and %B0,%B2" CR_TAB
2988 "and %C0,%C2" CR_TAB
2991 return avr_out_bitop (insn, operands, NULL);
2993 [(set_attr "length" "4,4,8,8")
2994 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2995 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2997 (define_peephole2 ; andi
2998 [(set (match_operand:QI 0 "d_register_operand" "")
2999 (and:QI (match_dup 0)
3000 (match_operand:QI 1 "const_int_operand" "")))
3002 (and:QI (match_dup 0)
3003 (match_operand:QI 2 "const_int_operand" "")))]
3005 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3007 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
3010 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3013 (define_insn "iorqi3"
3014 [(set (match_operand:QI 0 "register_operand" "=r,d")
3015 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
3016 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
3021 [(set_attr "length" "1,1")
3022 (set_attr "cc" "set_zn,set_zn")])
3024 (define_insn "iorhi3"
3025 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
3026 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
3027 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
3028 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
3031 if (which_alternative == 0)
3032 return "or %A0,%A2\;or %B0,%B2";
3033 else if (which_alternative == 1)
3034 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
3036 return avr_out_bitop (insn, operands, NULL);
3038 [(set_attr "length" "2,2,2,4,4")
3039 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
3040 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
3042 (define_insn "iorpsi3"
3043 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
3044 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
3045 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
3046 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3049 if (which_alternative == 0)
3050 return "or %A0,%A2" CR_TAB
3054 return avr_out_bitop (insn, operands, NULL);
3056 [(set_attr "length" "3,3,6,6")
3057 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3058 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3060 (define_insn "iorsi3"
3061 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3062 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3063 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3064 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3067 if (which_alternative == 0)
3068 return "or %0,%2" CR_TAB
3073 return avr_out_bitop (insn, operands, NULL);
3075 [(set_attr "length" "4,4,8,8")
3076 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3077 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3079 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3082 (define_insn "xorqi3"
3083 [(set (match_operand:QI 0 "register_operand" "=r")
3084 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3085 (match_operand:QI 2 "register_operand" "r")))]
3088 [(set_attr "length" "1")
3089 (set_attr "cc" "set_zn")])
3091 (define_insn "xorhi3"
3092 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3093 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3094 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3095 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3098 if (which_alternative == 0)
3099 return "eor %A0,%A2\;eor %B0,%B2";
3101 return avr_out_bitop (insn, operands, NULL);
3103 [(set_attr "length" "2,2,4")
3104 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3105 (set_attr "cc" "set_n,clobber,clobber")])
3107 (define_insn "xorpsi3"
3108 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3109 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3110 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3111 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3114 if (which_alternative == 0)
3115 return "eor %A0,%A2" CR_TAB
3116 "eor %B0,%B2" CR_TAB
3119 return avr_out_bitop (insn, operands, NULL);
3121 [(set_attr "length" "3,6,6")
3122 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3123 (set_attr "cc" "set_n,clobber,clobber")])
3125 (define_insn "xorsi3"
3126 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3127 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3128 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3129 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3132 if (which_alternative == 0)
3133 return "eor %0,%2" CR_TAB
3134 "eor %B0,%B2" CR_TAB
3135 "eor %C0,%C2" CR_TAB
3138 return avr_out_bitop (insn, operands, NULL);
3140 [(set_attr "length" "4,8,8")
3141 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3142 (set_attr "cc" "set_n,clobber,clobber")])
3144 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3147 (define_expand "rotlqi3"
3148 [(set (match_operand:QI 0 "register_operand" "")
3149 (rotate:QI (match_operand:QI 1 "register_operand" "")
3150 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3153 if (!CONST_INT_P (operands[2]))
3156 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3159 ;; Expander used by __builtin_avr_swap
3160 (define_expand "rotlqi3_4"
3161 [(set (match_operand:QI 0 "register_operand" "")
3162 (rotate:QI (match_operand:QI 1 "register_operand" "")
3165 (define_insn "*rotlqi3"
3166 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3167 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3168 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3171 lsl %0\;adc %0,__zero_reg__
3172 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3173 swap %0\;bst %0,0\;ror %0\;bld %0,7
3175 swap %0\;lsl %0\;adc %0,__zero_reg__
3176 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3177 bst %0,0\;ror %0\;bld %0,7
3179 [(set_attr "length" "2,4,4,1,3,5,3,0")
3180 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3182 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3183 ;; a whole number of bytes. The split creates the appropriate moves and
3184 ;; considers all overlap situations.
3186 ;; HImode does not need scratch. Use attribute for this constraint.
3188 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3189 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3194 (define_expand "rotl<mode>3"
3195 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3196 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3197 (match_operand:VOID 2 "const_int_operand" "")))
3198 (clobber (match_dup 3))])]
3203 if (!CONST_INT_P (operands[2]))
3206 offset = INTVAL (operands[2]);
3208 if (0 == offset % 8)
3210 if (AVR_HAVE_MOVW && 0 == offset % 16)
3211 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3213 operands[3] = gen_rtx_SCRATCH (QImode);
3215 else if (offset == 1
3216 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3218 /*; Support rotate left/right by 1 */
3220 emit_move_insn (operands[0],
3221 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3228 (define_insn "*rotlhi2.1"
3229 [(set (match_operand:HI 0 "register_operand" "=r")
3230 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3233 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3234 [(set_attr "length" "3")
3235 (set_attr "cc" "clobber")])
3237 (define_insn "*rotlhi2.15"
3238 [(set (match_operand:HI 0 "register_operand" "=r")
3239 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3242 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3243 [(set_attr "length" "4")
3244 (set_attr "cc" "clobber")])
3246 (define_insn "*rotlpsi2.1"
3247 [(set (match_operand:PSI 0 "register_operand" "=r")
3248 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3251 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3252 [(set_attr "length" "4")
3253 (set_attr "cc" "clobber")])
3255 (define_insn "*rotlpsi2.23"
3256 [(set (match_operand:PSI 0 "register_operand" "=r")
3257 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3260 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3261 [(set_attr "length" "5")
3262 (set_attr "cc" "clobber")])
3264 (define_insn "*rotlsi2.1"
3265 [(set (match_operand:SI 0 "register_operand" "=r")
3266 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3269 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3270 [(set_attr "length" "5")
3271 (set_attr "cc" "clobber")])
3273 (define_insn "*rotlsi2.31"
3274 [(set (match_operand:SI 0 "register_operand" "=r")
3275 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3278 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3279 [(set_attr "length" "6")
3280 (set_attr "cc" "clobber")])
3282 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3283 ;; The best we can do is use early clobber alternative "#&r" so that
3284 ;; completely non-overlapping operands dont get a scratch but # so register
3285 ;; allocation does not prefer non-overlapping.
3288 ;; Split word aligned rotates using scratch that is mode dependent.
3292 (define_insn_and_split "*rotw<mode>"
3293 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3294 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3295 (match_operand 2 "const_int_operand" "n,n,n")))
3296 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3298 && CONST_INT_P (operands[2])
3299 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3300 && 0 == INTVAL (operands[2]) % 16"
3302 "&& reload_completed"
3305 avr_rotate_bytes (operands);
3310 ;; Split byte aligned rotates using scratch that is always QI mode.
3315 (define_insn_and_split "*rotb<mode>"
3316 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3317 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3318 (match_operand 2 "const_int_operand" "n,n,n")))
3319 (clobber (match_scratch:QI 3 "=<rotx>"))]
3320 "CONST_INT_P (operands[2])
3321 && (8 == INTVAL (operands[2]) % 16
3323 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3324 && 0 == INTVAL (operands[2]) % 16))"
3326 "&& reload_completed"
3329 avr_rotate_bytes (operands);
3334 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3335 ;; arithmetic shift left
3338 ;; "ashlqq3" "ashluqq3"
3339 (define_expand "ashl<mode>3"
3340 [(set (match_operand:ALL1 0 "register_operand" "")
3341 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "")
3342 (match_operand:QI 2 "nop_general_operand" "")))])
3344 (define_split ; ashlqi3_const4
3345 [(set (match_operand:ALL1 0 "d_register_operand" "")
3346 (ashift:ALL1 (match_dup 0)
3350 (rotate:QI (match_dup 1)
3353 (and:QI (match_dup 1)
3356 operands[1] = avr_to_int_mode (operands[0]);
3359 (define_split ; ashlqi3_const5
3360 [(set (match_operand:ALL1 0 "d_register_operand" "")
3361 (ashift:ALL1 (match_dup 0)
3364 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3365 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 1)))
3366 (set (match_dup 1) (and:QI (match_dup 1) (const_int -32)))]
3368 operands[1] = avr_to_int_mode (operands[0]);
3371 (define_split ; ashlqi3_const6
3372 [(set (match_operand:ALL1 0 "d_register_operand" "")
3373 (ashift:ALL1 (match_dup 0)
3376 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3377 (set (match_dup 1) (ashift:QI (match_dup 1) (const_int 2)))
3378 (set (match_dup 1) (and:QI (match_dup 1) (const_int -64)))]
3380 operands[1] = avr_to_int_mode (operands[0]);
3384 ;; "*ashlqq3" "*ashluqq3"
3385 (define_insn "*ashl<mode>3"
3386 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3387 (ashift:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3388 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3391 return ashlqi3_out (insn, operands, NULL);
3393 [(set_attr "length" "5,0,1,2,4,6,9")
3394 (set_attr "adjust_len" "ashlqi")
3395 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3397 (define_insn "ashl<mode>3"
3398 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3399 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3400 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3403 return ashlhi3_out (insn, operands, NULL);
3405 [(set_attr "length" "6,0,2,2,4,10,10")
3406 (set_attr "adjust_len" "ashlhi")
3407 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3410 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3411 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3415 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3416 [(set (match_operand:QI 0 "register_operand" "=r")
3417 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3418 (match_operand:QI 2 "register_operand" "r"))
3424 (ashift:QI (match_dup 1)
3427 ;; ??? Combiner does not recognize that it could split the following insn;
3428 ;; presumably because he has no register handy?
3430 ;; "*ashluqihiqi3.mem"
3431 ;; "*ashlsqihiqi3.mem"
3432 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3433 [(set (match_operand:QI 0 "memory_operand" "=m")
3434 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3435 (match_operand:QI 2 "register_operand" "r"))
3438 { gcc_unreachable(); }
3441 (ashift:QI (match_dup 1)
3446 operands[3] = gen_reg_rtx (QImode);
3451 (define_insn_and_split "*ashlhiqi3"
3452 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3453 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3454 (match_operand:QI 2 "register_operand" "r")) 0))]
3456 { gcc_unreachable(); }
3459 (ashift:QI (match_dup 3)
3464 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3465 operands[4] = gen_reg_rtx (QImode);
3468 ;; High part of 16-bit shift is unused after the instruction:
3469 ;; No need to compute it, map to 8-bit shift.
3472 [(set (match_operand:HI 0 "register_operand" "")
3473 (ashift:HI (match_dup 0)
3474 (match_operand:QI 1 "register_operand" "")))]
3477 (ashift:QI (match_dup 2)
3479 (clobber (match_dup 3))]
3481 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3483 if (!peep2_reg_dead_p (1, operands[3]))
3486 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3491 ;; "ashlsq3" "ashlusq3"
3492 ;; "ashlsa3" "ashlusa3"
3493 (define_insn "ashl<mode>3"
3494 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3495 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3496 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3499 return ashlsi3_out (insn, operands, NULL);
3501 [(set_attr "length" "8,0,4,4,8,10,12")
3502 (set_attr "adjust_len" "ashlsi")
3503 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3505 ;; Optimize if a scratch register from LD_REGS happens to be available.
3507 (define_peephole2 ; ashlqi3_l_const4
3508 [(set (match_operand:ALL1 0 "l_register_operand" "")
3509 (ashift:ALL1 (match_dup 0)
3511 (match_scratch:QI 1 "d")]
3513 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3514 (set (match_dup 1) (const_int -16))
3515 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3517 operands[2] = avr_to_int_mode (operands[0]);
3520 (define_peephole2 ; ashlqi3_l_const5
3521 [(set (match_operand:ALL1 0 "l_register_operand" "")
3522 (ashift:ALL1 (match_dup 0)
3524 (match_scratch:QI 1 "d")]
3526 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3527 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 1)))
3528 (set (match_dup 1) (const_int -32))
3529 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3531 operands[2] = avr_to_int_mode (operands[0]);
3534 (define_peephole2 ; ashlqi3_l_const6
3535 [(set (match_operand:ALL1 0 "l_register_operand" "")
3536 (ashift:ALL1 (match_dup 0)
3538 (match_scratch:QI 1 "d")]
3540 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3541 (set (match_dup 2) (ashift:QI (match_dup 2) (const_int 2)))
3542 (set (match_dup 1) (const_int -64))
3543 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3545 operands[2] = avr_to_int_mode (operands[0]);
3549 [(match_scratch:QI 3 "d")
3550 (set (match_operand:ALL2 0 "register_operand" "")
3551 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "")
3552 (match_operand:QI 2 "const_int_operand" "")))]
3554 [(parallel [(set (match_dup 0)
3555 (ashift:ALL2 (match_dup 1)
3557 (clobber (match_dup 3))])])
3560 ;; "*ashlhq3_const" "*ashluhq3_const"
3561 ;; "*ashlha3_const" "*ashluha3_const"
3562 (define_insn "*ashl<mode>3_const"
3563 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3564 (ashift:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3565 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3566 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3569 return ashlhi3_out (insn, operands, NULL);
3571 [(set_attr "length" "0,2,2,4,10")
3572 (set_attr "adjust_len" "ashlhi")
3573 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3576 [(match_scratch:QI 3 "d")
3577 (set (match_operand:ALL4 0 "register_operand" "")
3578 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "")
3579 (match_operand:QI 2 "const_int_operand" "")))]
3581 [(parallel [(set (match_dup 0)
3582 (ashift:ALL4 (match_dup 1)
3584 (clobber (match_dup 3))])])
3587 ;; "*ashlsq3_const" "*ashlusq3_const"
3588 ;; "*ashlsa3_const" "*ashlusa3_const"
3589 (define_insn "*ashl<mode>3_const"
3590 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3591 (ashift:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3592 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3593 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3596 return ashlsi3_out (insn, operands, NULL);
3598 [(set_attr "length" "0,4,4,10")
3599 (set_attr "adjust_len" "ashlsi")
3600 (set_attr "cc" "none,set_n,clobber,clobber")])
3602 (define_expand "ashlpsi3"
3603 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3604 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3605 (match_operand:QI 2 "nonmemory_operand" "")))
3606 (clobber (scratch:QI))])]
3610 && CONST_INT_P (operands[2]))
3612 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3614 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3615 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3618 else if (optimize_insn_for_speed_p ()
3619 && INTVAL (operands[2]) != 16
3620 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3622 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3623 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3629 (define_insn "*ashlpsi3"
3630 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3631 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3632 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3633 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3636 return avr_out_ashlpsi3 (insn, operands, NULL);
3638 [(set_attr "adjust_len" "ashlpsi")
3639 (set_attr "cc" "clobber")])
3641 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3642 ;; arithmetic shift right
3645 ;; "ashrqq3" "ashruqq3"
3646 (define_insn "ashr<mode>3"
3647 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,r ,r ,r")
3648 (ashiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3649 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3652 return ashrqi3_out (insn, operands, NULL);
3654 [(set_attr "length" "5,0,1,2,5,4,9")
3655 (set_attr "adjust_len" "ashrqi")
3656 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3659 ;; "ashrhq3" "ashruhq3"
3660 ;; "ashrha3" "ashruha3"
3661 (define_insn "ashr<mode>3"
3662 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3663 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3664 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3667 return ashrhi3_out (insn, operands, NULL);
3669 [(set_attr "length" "6,0,2,4,4,10,10")
3670 (set_attr "adjust_len" "ashrhi")
3671 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3673 (define_insn "ashrpsi3"
3674 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3675 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3676 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3677 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3680 return avr_out_ashrpsi3 (insn, operands, NULL);
3682 [(set_attr "adjust_len" "ashrpsi")
3683 (set_attr "cc" "clobber")])
3686 ;; "ashrsq3" "ashrusq3"
3687 ;; "ashrsa3" "ashrusa3"
3688 (define_insn "ashr<mode>3"
3689 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3690 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3691 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3694 return ashrsi3_out (insn, operands, NULL);
3696 [(set_attr "length" "8,0,4,6,8,10,12")
3697 (set_attr "adjust_len" "ashrsi")
3698 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3700 ;; Optimize if a scratch register from LD_REGS happens to be available.
3703 [(match_scratch:QI 3 "d")
3704 (set (match_operand:ALL2 0 "register_operand" "")
3705 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3706 (match_operand:QI 2 "const_int_operand" "")))]
3708 [(parallel [(set (match_dup 0)
3709 (ashiftrt:ALL2 (match_dup 1)
3711 (clobber (match_dup 3))])])
3714 ;; "*ashrhq3_const" "*ashruhq3_const"
3715 ;; "*ashrha3_const" "*ashruha3_const"
3716 (define_insn "*ashr<mode>3_const"
3717 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3718 (ashiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3719 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3720 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3723 return ashrhi3_out (insn, operands, NULL);
3725 [(set_attr "length" "0,2,4,4,10")
3726 (set_attr "adjust_len" "ashrhi")
3727 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3730 [(match_scratch:QI 3 "d")
3731 (set (match_operand:ALL4 0 "register_operand" "")
3732 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3733 (match_operand:QI 2 "const_int_operand" "")))]
3735 [(parallel [(set (match_dup 0)
3736 (ashiftrt:ALL4 (match_dup 1)
3738 (clobber (match_dup 3))])])
3741 ;; "*ashrsq3_const" "*ashrusq3_const"
3742 ;; "*ashrsa3_const" "*ashrusa3_const"
3743 (define_insn "*ashr<mode>3_const"
3744 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3745 (ashiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3746 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3747 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3750 return ashrsi3_out (insn, operands, NULL);
3752 [(set_attr "length" "0,4,4,10")
3753 (set_attr "adjust_len" "ashrsi")
3754 (set_attr "cc" "none,clobber,set_n,clobber")])
3756 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3757 ;; logical shift right
3760 ;; "lshrqq3 "lshruqq3"
3761 (define_expand "lshr<mode>3"
3762 [(set (match_operand:ALL1 0 "register_operand" "")
3763 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "")
3764 (match_operand:QI 2 "nop_general_operand" "")))])
3766 (define_split ; lshrqi3_const4
3767 [(set (match_operand:ALL1 0 "d_register_operand" "")
3768 (lshiftrt:ALL1 (match_dup 0)
3772 (rotate:QI (match_dup 1)
3775 (and:QI (match_dup 1)
3778 operands[1] = avr_to_int_mode (operands[0]);
3781 (define_split ; lshrqi3_const5
3782 [(set (match_operand:ALL1 0 "d_register_operand" "")
3783 (lshiftrt:ALL1 (match_dup 0)
3786 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3787 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 1)))
3788 (set (match_dup 1) (and:QI (match_dup 1) (const_int 7)))]
3790 operands[1] = avr_to_int_mode (operands[0]);
3793 (define_split ; lshrqi3_const6
3794 [(set (match_operand:QI 0 "d_register_operand" "")
3795 (lshiftrt:QI (match_dup 0)
3798 [(set (match_dup 1) (rotate:QI (match_dup 1) (const_int 4)))
3799 (set (match_dup 1) (lshiftrt:QI (match_dup 1) (const_int 2)))
3800 (set (match_dup 1) (and:QI (match_dup 1) (const_int 3)))]
3802 operands[1] = avr_to_int_mode (operands[0]);
3808 (define_insn "*lshr<mode>3"
3809 [(set (match_operand:ALL1 0 "register_operand" "=r,r,r,r,!d,r,r")
3810 (lshiftrt:ALL1 (match_operand:ALL1 1 "register_operand" "0,0,0,0,0 ,0,0")
3811 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3814 return lshrqi3_out (insn, operands, NULL);
3816 [(set_attr "length" "5,0,1,2,4,6,9")
3817 (set_attr "adjust_len" "lshrqi")
3818 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3821 ;; "lshrhq3" "lshruhq3"
3822 ;; "lshrha3" "lshruha3"
3823 (define_insn "lshr<mode>3"
3824 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r,r,r")
3825 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,0,r,0,0,0")
3826 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3829 return lshrhi3_out (insn, operands, NULL);
3831 [(set_attr "length" "6,0,2,2,4,10,10")
3832 (set_attr "adjust_len" "lshrhi")
3833 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3835 (define_insn "lshrpsi3"
3836 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3837 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3838 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3839 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3842 return avr_out_lshrpsi3 (insn, operands, NULL);
3844 [(set_attr "adjust_len" "lshrpsi")
3845 (set_attr "cc" "clobber")])
3848 ;; "lshrsq3" "lshrusq3"
3849 ;; "lshrsa3" "lshrusa3"
3850 (define_insn "lshr<mode>3"
3851 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r,r,r,r")
3852 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,0,r,0,0,0")
3853 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3856 return lshrsi3_out (insn, operands, NULL);
3858 [(set_attr "length" "8,0,4,4,8,10,12")
3859 (set_attr "adjust_len" "lshrsi")
3860 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3862 ;; Optimize if a scratch register from LD_REGS happens to be available.
3864 (define_peephole2 ; lshrqi3_l_const4
3865 [(set (match_operand:ALL1 0 "l_register_operand" "")
3866 (lshiftrt:ALL1 (match_dup 0)
3868 (match_scratch:QI 1 "d")]
3870 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3871 (set (match_dup 1) (const_int 15))
3872 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3874 operands[2] = avr_to_int_mode (operands[0]);
3877 (define_peephole2 ; lshrqi3_l_const5
3878 [(set (match_operand:ALL1 0 "l_register_operand" "")
3879 (lshiftrt:ALL1 (match_dup 0)
3881 (match_scratch:QI 1 "d")]
3883 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3884 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 1)))
3885 (set (match_dup 1) (const_int 7))
3886 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3888 operands[2] = avr_to_int_mode (operands[0]);
3891 (define_peephole2 ; lshrqi3_l_const6
3892 [(set (match_operand:ALL1 0 "l_register_operand" "")
3893 (lshiftrt:ALL1 (match_dup 0)
3895 (match_scratch:QI 1 "d")]
3897 [(set (match_dup 2) (rotate:QI (match_dup 2) (const_int 4)))
3898 (set (match_dup 2) (lshiftrt:QI (match_dup 2) (const_int 2)))
3899 (set (match_dup 1) (const_int 3))
3900 (set (match_dup 2) (and:QI (match_dup 2) (match_dup 1)))]
3902 operands[2] = avr_to_int_mode (operands[0]);
3906 [(match_scratch:QI 3 "d")
3907 (set (match_operand:ALL2 0 "register_operand" "")
3908 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "")
3909 (match_operand:QI 2 "const_int_operand" "")))]
3911 [(parallel [(set (match_dup 0)
3912 (lshiftrt:ALL2 (match_dup 1)
3914 (clobber (match_dup 3))])])
3917 ;; "*lshrhq3_const" "*lshruhq3_const"
3918 ;; "*lshrha3_const" "*lshruha3_const"
3919 (define_insn "*lshr<mode>3_const"
3920 [(set (match_operand:ALL2 0 "register_operand" "=r,r,r,r,r")
3921 (lshiftrt:ALL2 (match_operand:ALL2 1 "register_operand" "0,0,r,0,0")
3922 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3923 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3926 return lshrhi3_out (insn, operands, NULL);
3928 [(set_attr "length" "0,2,2,4,10")
3929 (set_attr "adjust_len" "lshrhi")
3930 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3933 [(match_scratch:QI 3 "d")
3934 (set (match_operand:ALL4 0 "register_operand" "")
3935 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "")
3936 (match_operand:QI 2 "const_int_operand" "")))]
3938 [(parallel [(set (match_dup 0)
3939 (lshiftrt:ALL4 (match_dup 1)
3941 (clobber (match_dup 3))])])
3944 ;; "*lshrsq3_const" "*lshrusq3_const"
3945 ;; "*lshrsa3_const" "*lshrusa3_const"
3946 (define_insn "*lshr<mode>3_const"
3947 [(set (match_operand:ALL4 0 "register_operand" "=r,r,r,r")
3948 (lshiftrt:ALL4 (match_operand:ALL4 1 "register_operand" "0,0,r,0")
3949 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3950 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3953 return lshrsi3_out (insn, operands, NULL);
3955 [(set_attr "length" "0,4,4,10")
3956 (set_attr "adjust_len" "lshrsi")
3957 (set_attr "cc" "none,clobber,clobber,clobber")])
3959 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3962 (define_insn "absqi2"
3963 [(set (match_operand:QI 0 "register_operand" "=r")
3964 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3968 [(set_attr "length" "2")
3969 (set_attr "cc" "clobber")])
3972 (define_insn "abssf2"
3973 [(set (match_operand:SF 0 "register_operand" "=d,r")
3974 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3979 [(set_attr "length" "1,2")
3980 (set_attr "cc" "set_n,clobber")])
3982 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3985 (define_insn "negqi2"
3986 [(set (match_operand:QI 0 "register_operand" "=r")
3987 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3990 [(set_attr "length" "1")
3991 (set_attr "cc" "set_zn")])
3993 (define_insn "*negqihi2"
3994 [(set (match_operand:HI 0 "register_operand" "=r")
3995 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3997 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3998 [(set_attr "length" "4")
3999 (set_attr "cc" "set_n")])
4001 (define_insn "neghi2"
4002 [(set (match_operand:HI 0 "register_operand" "=r,&r")
4003 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
4006 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
4007 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
4008 [(set_attr "length" "3,4")
4009 (set_attr "cc" "set_czn")])
4011 (define_insn "negpsi2"
4012 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
4013 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
4016 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
4017 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
4018 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
4019 [(set_attr "length" "5,6,6")
4020 (set_attr "cc" "set_czn,set_n,set_czn")])
4022 (define_insn "negsi2"
4023 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
4024 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
4027 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
4028 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
4029 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
4030 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
4031 [(set_attr "length" "7,8,8,7")
4032 (set_attr "isa" "*,*,mov,movw")
4033 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
4035 (define_insn "negsf2"
4036 [(set (match_operand:SF 0 "register_operand" "=d,r")
4037 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
4041 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
4042 [(set_attr "length" "1,4")
4043 (set_attr "cc" "set_n,set_n")])
4045 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4048 (define_insn "one_cmplqi2"
4049 [(set (match_operand:QI 0 "register_operand" "=r")
4050 (not:QI (match_operand:QI 1 "register_operand" "0")))]
4053 [(set_attr "length" "1")
4054 (set_attr "cc" "set_czn")])
4056 (define_insn "one_cmplhi2"
4057 [(set (match_operand:HI 0 "register_operand" "=r")
4058 (not:HI (match_operand:HI 1 "register_operand" "0")))]
4062 [(set_attr "length" "2")
4063 (set_attr "cc" "set_n")])
4065 (define_insn "one_cmplpsi2"
4066 [(set (match_operand:PSI 0 "register_operand" "=r")
4067 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
4069 "com %0\;com %B0\;com %C0"
4070 [(set_attr "length" "3")
4071 (set_attr "cc" "set_n")])
4073 (define_insn "one_cmplsi2"
4074 [(set (match_operand:SI 0 "register_operand" "=r")
4075 (not:SI (match_operand:SI 1 "register_operand" "0")))]
4081 [(set_attr "length" "4")
4082 (set_attr "cc" "set_n")])
4084 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4087 ;; We keep combiner from inserting hard registers into the input of sign- and
4088 ;; zero-extends. A hard register in the input operand is not wanted because
4089 ;; 32-bit multiply patterns clobber some hard registers and extends with a
4090 ;; hard register that overlaps these clobbers won't be combined to a widening
4091 ;; multiplication. There is no need for combine to propagate hard registers,
4092 ;; register allocation can do it just as well.
4094 (define_insn "extendqihi2"
4095 [(set (match_operand:HI 0 "register_operand" "=r,r")
4096 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4099 clr %B0\;sbrc %0,7\;com %B0
4100 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
4101 [(set_attr "length" "3,4")
4102 (set_attr "cc" "set_n,set_n")])
4104 (define_insn "extendqipsi2"
4105 [(set (match_operand:PSI 0 "register_operand" "=r,r")
4106 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4109 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
4110 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
4111 [(set_attr "length" "4,5")
4112 (set_attr "cc" "set_n,set_n")])
4114 (define_insn "extendqisi2"
4115 [(set (match_operand:SI 0 "register_operand" "=r,r")
4116 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
4119 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
4120 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
4121 [(set_attr "length" "5,6")
4122 (set_attr "cc" "set_n,set_n")])
4124 (define_insn "extendhipsi2"
4125 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
4126 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4129 clr %C0\;sbrc %B0,7\;com %C0
4130 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
4131 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
4132 [(set_attr "length" "3,5,4")
4133 (set_attr "isa" "*,mov,movw")
4134 (set_attr "cc" "set_n")])
4136 (define_insn "extendhisi2"
4137 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
4138 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
4141 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4142 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4143 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4144 [(set_attr "length" "4,6,5")
4145 (set_attr "isa" "*,mov,movw")
4146 (set_attr "cc" "set_n")])
4148 (define_insn "extendpsisi2"
4149 [(set (match_operand:SI 0 "register_operand" "=r")
4150 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4152 "clr %D0\;sbrc %C0,7\;com %D0"
4153 [(set_attr "length" "3")
4154 (set_attr "cc" "set_n")])
4156 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4159 (define_insn_and_split "zero_extendqihi2"
4160 [(set (match_operand:HI 0 "register_operand" "=r")
4161 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4165 [(set (match_dup 2) (match_dup 1))
4166 (set (match_dup 3) (const_int 0))]
4168 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4169 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4171 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4172 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4175 (define_insn_and_split "zero_extendqipsi2"
4176 [(set (match_operand:PSI 0 "register_operand" "=r")
4177 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4181 [(set (match_dup 2) (match_dup 1))
4182 (set (match_dup 3) (const_int 0))
4183 (set (match_dup 4) (const_int 0))]
4185 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4186 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4187 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4190 (define_insn_and_split "zero_extendqisi2"
4191 [(set (match_operand:SI 0 "register_operand" "=r")
4192 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4196 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4197 (set (match_dup 3) (const_int 0))]
4199 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4200 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4202 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4203 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4206 (define_insn_and_split "zero_extendhipsi2"
4207 [(set (match_operand:PSI 0 "register_operand" "=r")
4208 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4212 [(set (match_dup 2) (match_dup 1))
4213 (set (match_dup 3) (const_int 0))]
4215 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4216 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4219 (define_insn_and_split "n_extendhipsi2"
4220 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4221 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4222 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4223 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4227 [(set (match_dup 4) (match_dup 2))
4228 (set (match_dup 3) (match_dup 6))
4229 ; no-op move in the case where no scratch is needed
4230 (set (match_dup 5) (match_dup 3))]
4232 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4233 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4234 operands[6] = operands[1];
4236 if (GET_CODE (operands[3]) == SCRATCH)
4237 operands[3] = operands[5];
4240 (define_insn_and_split "zero_extendhisi2"
4241 [(set (match_operand:SI 0 "register_operand" "=r")
4242 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4246 [(set (match_dup 2) (match_dup 1))
4247 (set (match_dup 3) (const_int 0))]
4249 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4250 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4252 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4253 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4256 (define_insn_and_split "zero_extendpsisi2"
4257 [(set (match_operand:SI 0 "register_operand" "=r")
4258 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4262 [(set (match_dup 2) (match_dup 1))
4263 (set (match_dup 3) (const_int 0))]
4265 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4266 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4269 (define_insn_and_split "zero_extendqidi2"
4270 [(set (match_operand:DI 0 "register_operand" "=r")
4271 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4275 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4276 (set (match_dup 3) (const_int 0))]
4278 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4279 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4281 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4282 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4285 (define_insn_and_split "zero_extendhidi2"
4286 [(set (match_operand:DI 0 "register_operand" "=r")
4287 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4291 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4292 (set (match_dup 3) (const_int 0))]
4294 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4295 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4297 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4298 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4301 (define_insn_and_split "zero_extendsidi2"
4302 [(set (match_operand:DI 0 "register_operand" "=r")
4303 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4307 [(set (match_dup 2) (match_dup 1))
4308 (set (match_dup 3) (const_int 0))]
4310 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4311 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4313 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4314 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4317 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4320 ; Optimize negated tests into reverse compare if overflow is undefined.
4321 (define_insn "*negated_tstqi"
4323 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4325 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4326 "cp __zero_reg__,%0"
4327 [(set_attr "cc" "compare")
4328 (set_attr "length" "1")])
4330 (define_insn "*reversed_tstqi"
4332 (compare (const_int 0)
4333 (match_operand:QI 0 "register_operand" "r")))]
4335 "cp __zero_reg__,%0"
4336 [(set_attr "cc" "compare")
4337 (set_attr "length" "2")])
4339 (define_insn "*negated_tsthi"
4341 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4343 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4344 "cp __zero_reg__,%A0
4345 cpc __zero_reg__,%B0"
4346 [(set_attr "cc" "compare")
4347 (set_attr "length" "2")])
4349 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4350 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4351 (define_insn "*reversed_tsthi"
4353 (compare (const_int 0)
4354 (match_operand:HI 0 "register_operand" "r")))
4355 (clobber (match_scratch:QI 1 "=X"))]
4357 "cp __zero_reg__,%A0
4358 cpc __zero_reg__,%B0"
4359 [(set_attr "cc" "compare")
4360 (set_attr "length" "2")])
4362 (define_insn "*negated_tstpsi"
4364 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4366 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4367 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4368 [(set_attr "cc" "compare")
4369 (set_attr "length" "3")])
4371 (define_insn "*reversed_tstpsi"
4373 (compare (const_int 0)
4374 (match_operand:PSI 0 "register_operand" "r")))
4375 (clobber (match_scratch:QI 1 "=X"))]
4377 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4378 [(set_attr "cc" "compare")
4379 (set_attr "length" "3")])
4381 (define_insn "*negated_tstsi"
4383 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4385 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4386 "cp __zero_reg__,%A0
4387 cpc __zero_reg__,%B0
4388 cpc __zero_reg__,%C0
4389 cpc __zero_reg__,%D0"
4390 [(set_attr "cc" "compare")
4391 (set_attr "length" "4")])
4393 ;; "*reversed_tstsi"
4394 ;; "*reversed_tstsq" "*reversed_tstusq"
4395 ;; "*reversed_tstsa" "*reversed_tstusa"
4396 (define_insn "*reversed_tst<mode>"
4398 (compare (match_operand:ALL4 0 "const0_operand" "Y00")
4399 (match_operand:ALL4 1 "register_operand" "r")))
4400 (clobber (match_scratch:QI 2 "=X"))]
4402 "cp __zero_reg__,%A1
4403 cpc __zero_reg__,%B1
4404 cpc __zero_reg__,%C1
4405 cpc __zero_reg__,%D1"
4406 [(set_attr "cc" "compare")
4407 (set_attr "length" "4")])
4411 ;; "*cmpqq" "*cmpuqq"
4412 (define_insn "*cmp<mode>"
4414 (compare (match_operand:ALL1 0 "register_operand" "r ,r,d")
4415 (match_operand:ALL1 1 "nonmemory_operand" "Y00,r,i")))]
4421 [(set_attr "cc" "compare,compare,compare")
4422 (set_attr "length" "1,1,1")])
4424 (define_insn "*cmpqi_sign_extend"
4426 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4427 (match_operand:HI 1 "s8_operand" "n")))]
4430 [(set_attr "cc" "compare")
4431 (set_attr "length" "1")])
4434 ;; "*cmphq" "*cmpuhq"
4435 ;; "*cmpha" "*cmpuha"
4436 (define_insn "*cmp<mode>"
4438 (compare (match_operand:ALL2 0 "register_operand" "!w ,r ,r,d ,r ,d,r")
4439 (match_operand:ALL2 1 "nonmemory_operand" "Y00,Y00,r,s ,s ,M,n Ynn")))
4440 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d ,X,&d"))]
4443 switch (which_alternative)
4447 return avr_out_tsthi (insn, operands, NULL);
4450 return "cp %A0,%A1\;cpc %B0,%B1";
4453 if (<MODE>mode != HImode)
4455 return reg_unused_after (insn, operands[0])
4456 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4457 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4460 if (<MODE>mode != HImode)
4462 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4465 return avr_out_compare (insn, operands, NULL);
4467 [(set_attr "cc" "compare")
4468 (set_attr "length" "1,2,2,3,4,2,4")
4469 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4471 (define_insn "*cmppsi"
4473 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4474 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4475 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4478 switch (which_alternative)
4481 return avr_out_tstpsi (insn, operands, NULL);
4484 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4487 return reg_unused_after (insn, operands[0])
4488 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4489 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4492 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4495 return avr_out_compare (insn, operands, NULL);
4497 [(set_attr "cc" "compare")
4498 (set_attr "length" "3,3,5,6,3,7")
4499 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4502 ;; "*cmpsq" "*cmpusq"
4503 ;; "*cmpsa" "*cmpusa"
4504 (define_insn "*cmp<mode>"
4506 (compare (match_operand:ALL4 0 "register_operand" "r ,r ,d,r ,r")
4507 (match_operand:ALL4 1 "nonmemory_operand" "Y00,r ,M,M ,n Ynn")))
4508 (clobber (match_scratch:QI 2 "=X ,X ,X,&d,&d"))]
4511 if (0 == which_alternative)
4512 return avr_out_tstsi (insn, operands, NULL);
4513 else if (1 == which_alternative)
4514 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4516 return avr_out_compare (insn, operands, NULL);
4518 [(set_attr "cc" "compare")
4519 (set_attr "length" "4,4,4,5,8")
4520 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4523 ;; ----------------------------------------------------------------------
4524 ;; JUMP INSTRUCTIONS
4525 ;; ----------------------------------------------------------------------
4526 ;; Conditional jump instructions
4529 ;; "cbranchqq4" "cbranchuqq4"
4530 (define_expand "cbranch<mode>4"
4532 (compare (match_operand:ALL1 1 "register_operand" "")
4533 (match_operand:ALL1 2 "nonmemory_operand" "")))
4536 (match_operator 0 "ordered_comparison_operator" [(cc0)
4538 (label_ref (match_operand 3 "" ""))
4541 ;; "cbranchhi4" "cbranchhq4" "cbranchuhq4" "cbranchha4" "cbranchuha4"
4542 ;; "cbranchsi4" "cbranchsq4" "cbranchusq4" "cbranchsa4" "cbranchusa4"
4544 (define_expand "cbranch<mode>4"
4545 [(parallel [(set (cc0)
4546 (compare (match_operand:ORDERED234 1 "register_operand" "")
4547 (match_operand:ORDERED234 2 "nonmemory_operand" "")))
4548 (clobber (match_scratch:QI 4 ""))])
4551 (match_operator 0 "ordered_comparison_operator" [(cc0)
4553 (label_ref (match_operand 3 "" ""))
4557 ;; Test a single bit in a QI/HI/SImode register.
4558 ;; Combine will create zero extract patterns for single bit tests.
4559 ;; permit any mode in source pattern by using VOIDmode.
4561 (define_insn "*sbrx_branch<mode>"
4564 (match_operator 0 "eqne_operator"
4566 (match_operand:VOID 1 "register_operand" "r")
4568 (match_operand 2 "const_int_operand" "n"))
4570 (label_ref (match_operand 3 "" ""))
4574 return avr_out_sbxx_branch (insn, operands);
4576 [(set (attr "length")
4577 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4578 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4580 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4583 (set_attr "cc" "clobber")])
4585 ;; Same test based on bitwise AND. Keep this in case gcc changes patterns.
4586 ;; or for old peepholes.
4587 ;; Fixme - bitwise Mask will not work for DImode
4589 (define_insn "*sbrx_and_branch<mode>"
4592 (match_operator 0 "eqne_operator"
4594 (match_operand:QISI 1 "register_operand" "r")
4595 (match_operand:QISI 2 "single_one_operand" "n"))
4597 (label_ref (match_operand 3 "" ""))
4601 HOST_WIDE_INT bitnumber;
4602 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4603 operands[2] = GEN_INT (bitnumber);
4604 return avr_out_sbxx_branch (insn, operands);
4606 [(set (attr "length")
4607 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4608 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4610 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4613 (set_attr "cc" "clobber")])
4615 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4617 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4619 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4620 (label_ref (match_operand 1 "" ""))
4623 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4627 (label_ref (match_dup 1))
4631 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4633 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4634 (label_ref (match_operand 1 "" ""))
4637 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4641 (label_ref (match_dup 1))
4645 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4647 (clobber (match_operand:HI 2 ""))])
4648 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4649 (label_ref (match_operand 1 "" ""))
4652 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4654 (label_ref (match_dup 1))
4658 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4660 (clobber (match_operand:HI 2 ""))])
4661 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4662 (label_ref (match_operand 1 "" ""))
4665 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4667 (label_ref (match_dup 1))
4671 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4673 (clobber (match_operand:SI 2 ""))])
4674 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4675 (label_ref (match_operand 1 "" ""))
4678 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4680 (label_ref (match_dup 1))
4682 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4685 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4687 (clobber (match_operand:SI 2 ""))])
4688 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4689 (label_ref (match_operand 1 "" ""))
4692 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4694 (label_ref (match_dup 1))
4696 "operands[2] = gen_int_mode (-2147483647 - 1, SImode);")
4698 ;; ************************************************************************
4699 ;; Implementation of conditional jumps here.
4700 ;; Compare with 0 (test) jumps
4701 ;; ************************************************************************
4703 (define_insn "branch"
4705 (if_then_else (match_operator 1 "simple_comparison_operator"
4708 (label_ref (match_operand 0 "" ""))
4712 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4714 [(set_attr "type" "branch")
4715 (set_attr "cc" "clobber")])
4718 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4719 ;; or optimized in the remainder.
4721 (define_insn "branch_unspec"
4723 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4726 (label_ref (match_operand 0 "" ""))
4728 ] UNSPEC_IDENTITY))]
4731 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4733 [(set_attr "type" "branch")
4734 (set_attr "cc" "none")])
4736 ;; ****************************************************************
4737 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4738 ;; Convert them all to proper jumps.
4739 ;; ****************************************************************/
4741 (define_insn "difficult_branch"
4743 (if_then_else (match_operator 1 "difficult_comparison_operator"
4746 (label_ref (match_operand 0 "" ""))
4750 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4752 [(set_attr "type" "branch1")
4753 (set_attr "cc" "clobber")])
4757 (define_insn "rvbranch"
4759 (if_then_else (match_operator 1 "simple_comparison_operator"
4763 (label_ref (match_operand 0 "" ""))))]
4766 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4768 [(set_attr "type" "branch1")
4769 (set_attr "cc" "clobber")])
4771 (define_insn "difficult_rvbranch"
4773 (if_then_else (match_operator 1 "difficult_comparison_operator"
4777 (label_ref (match_operand 0 "" ""))))]
4780 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4782 [(set_attr "type" "branch")
4783 (set_attr "cc" "clobber")])
4785 ;; **************************************************************************
4786 ;; Unconditional and other jump instructions.
4790 (label_ref (match_operand 0 "" "")))]
4793 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4797 [(set (attr "length")
4798 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4799 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4802 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4803 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4806 (set_attr "cc" "none")])
4810 ;; Operand 1 not used on the AVR.
4811 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4812 (define_expand "call"
4813 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4814 (match_operand:HI 1 "general_operand" ""))
4815 (use (const_int 0))])])
4817 ;; Operand 1 not used on the AVR.
4818 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4819 (define_expand "sibcall"
4820 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4821 (match_operand:HI 1 "general_operand" ""))
4822 (use (const_int 1))])])
4826 ;; Operand 2 not used on the AVR.
4827 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4828 (define_expand "call_value"
4829 [(parallel[(set (match_operand 0 "register_operand" "")
4830 (call (match_operand:HI 1 "call_insn_operand" "")
4831 (match_operand:HI 2 "general_operand" "")))
4832 (use (const_int 0))])])
4834 ;; Operand 2 not used on the AVR.
4835 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4836 (define_expand "sibcall_value"
4837 [(parallel[(set (match_operand 0 "register_operand" "")
4838 (call (match_operand:HI 1 "call_insn_operand" "")
4839 (match_operand:HI 2 "general_operand" "")))
4840 (use (const_int 1))])])
4842 (define_insn "call_insn"
4843 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4844 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4845 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4846 ;; Operand 1 not used on the AVR.
4847 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4854 [(set_attr "cc" "clobber")
4855 (set_attr "length" "1,*,1,*")
4856 (set_attr "adjust_len" "*,call,*,call")])
4858 (define_insn "call_value_insn"
4859 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4860 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4861 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4862 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4863 ;; Operand 2 not used on the AVR.
4864 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4871 [(set_attr "cc" "clobber")
4872 (set_attr "length" "1,*,1,*")
4873 (set_attr "adjust_len" "*,call,*,call")])
4879 [(set_attr "cc" "none")
4880 (set_attr "length" "1")])
4884 (define_expand "indirect_jump"
4886 (match_operand:HI 0 "nonmemory_operand" ""))]
4889 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4891 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4896 (define_insn "*indirect_jump"
4898 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4904 push %A0\;push %B0\;ret
4906 [(set_attr "length" "1,2,1,3,1")
4907 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4908 (set_attr "cc" "none")])
4911 ;; For entries in jump table see avr_output_addr_vec_elt.
4914 ;; "rjmp .L<n>" instructions for <= 8K devices
4915 ;; ".word gs(.L<n>)" addresses for > 8K devices
4916 (define_insn "*tablejump"
4918 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4920 (use (label_ref (match_operand 1 "" "")))
4921 (clobber (match_dup 0))]
4925 push %A0\;push %B0\;ret
4927 [(set_attr "length" "1,3,2")
4928 (set_attr "isa" "rjmp,rjmp,jmp")
4929 (set_attr "cc" "none,none,clobber")])
4932 (define_expand "casesi"
4933 [(parallel [(set (match_dup 6)
4934 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4935 (match_operand:HI 1 "register_operand" "")))
4936 (clobber (scratch:QI))])
4937 (parallel [(set (cc0)
4938 (compare (match_dup 6)
4939 (match_operand:HI 2 "register_operand" "")))
4940 (clobber (match_scratch:QI 9 ""))])
4943 (if_then_else (gtu (cc0)
4945 (label_ref (match_operand 4 "" ""))
4949 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4951 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4952 (use (label_ref (match_dup 3)))
4953 (clobber (match_dup 6))])]
4956 operands[6] = gen_reg_rtx (HImode);
4960 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4961 ;; This instruction sets Z flag
4964 [(set (cc0) (const_int 0))]
4967 [(set_attr "length" "1")
4968 (set_attr "cc" "compare")])
4970 ;; Clear/set/test a single bit in I/O address space.
4973 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4974 (and:QI (mem:QI (match_dup 0))
4975 (match_operand:QI 1 "single_zero_operand" "n")))]
4978 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4979 return "cbi %i0,%2";
4981 [(set_attr "length" "1")
4982 (set_attr "cc" "none")])
4985 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4986 (ior:QI (mem:QI (match_dup 0))
4987 (match_operand:QI 1 "single_one_operand" "n")))]
4990 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4991 return "sbi %i0,%2";
4993 [(set_attr "length" "1")
4994 (set_attr "cc" "none")])
4996 ;; Lower half of the I/O space - use sbic/sbis directly.
4997 (define_insn "*sbix_branch"
5000 (match_operator 0 "eqne_operator"
5002 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
5004 (match_operand 2 "const_int_operand" "n"))
5006 (label_ref (match_operand 3 "" ""))
5010 return avr_out_sbxx_branch (insn, operands);
5012 [(set (attr "length")
5013 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5014 (le (minus (pc) (match_dup 3)) (const_int 2046)))
5016 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5019 (set_attr "cc" "clobber")])
5021 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
5022 (define_insn "*sbix_branch_bit7"
5025 (match_operator 0 "gelt_operator"
5026 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
5028 (label_ref (match_operand 2 "" ""))
5032 operands[3] = operands[2];
5033 operands[2] = GEN_INT (7);
5034 return avr_out_sbxx_branch (insn, operands);
5036 [(set (attr "length")
5037 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5038 (le (minus (pc) (match_dup 2)) (const_int 2046)))
5040 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5043 (set_attr "cc" "clobber")])
5045 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
5046 (define_insn "*sbix_branch_tmp"
5049 (match_operator 0 "eqne_operator"
5051 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
5053 (match_operand 2 "const_int_operand" "n"))
5055 (label_ref (match_operand 3 "" ""))
5059 return avr_out_sbxx_branch (insn, operands);
5061 [(set (attr "length")
5062 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
5063 (le (minus (pc) (match_dup 3)) (const_int 2045)))
5065 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5068 (set_attr "cc" "clobber")])
5070 (define_insn "*sbix_branch_tmp_bit7"
5073 (match_operator 0 "gelt_operator"
5074 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
5076 (label_ref (match_operand 2 "" ""))
5080 operands[3] = operands[2];
5081 operands[2] = GEN_INT (7);
5082 return avr_out_sbxx_branch (insn, operands);
5084 [(set (attr "length")
5085 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
5086 (le (minus (pc) (match_dup 2)) (const_int 2045)))
5088 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
5091 (set_attr "cc" "clobber")])
5093 ;; ************************* Peepholes ********************************
5095 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
5096 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
5097 (plus:SI (match_dup 0)
5099 (clobber (scratch:QI))])
5100 (parallel [(set (cc0)
5101 (compare (match_dup 0)
5103 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5105 (if_then_else (eqne (cc0)
5107 (label_ref (match_operand 2 "" ""))
5114 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5115 output_asm_insn ("sbiw %0,1" CR_TAB
5116 "sbc %C0,__zero_reg__" CR_TAB
5117 "sbc %D0,__zero_reg__", operands);
5119 output_asm_insn ("subi %A0,1" CR_TAB
5120 "sbc %B0,__zero_reg__" CR_TAB
5121 "sbc %C0,__zero_reg__" CR_TAB
5122 "sbc %D0,__zero_reg__", operands);
5124 jump_mode = avr_jump_mode (operands[2], insn);
5125 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5126 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5130 case 1: return "%1 %2";
5131 case 2: return "%1 .+2\;rjmp %2";
5132 case 3: return "%1 .+4\;jmp %2";
5139 (define_peephole ; "*dec-and-branchhi!=-1"
5140 [(set (match_operand:HI 0 "d_register_operand" "")
5141 (plus:HI (match_dup 0)
5143 (parallel [(set (cc0)
5144 (compare (match_dup 0)
5146 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5148 (if_then_else (eqne (cc0)
5150 (label_ref (match_operand 2 "" ""))
5157 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5158 output_asm_insn ("sbiw %0,1", operands);
5160 output_asm_insn ("subi %A0,1" CR_TAB
5161 "sbc %B0,__zero_reg__", operands);
5163 jump_mode = avr_jump_mode (operands[2], insn);
5164 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5165 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5169 case 1: return "%1 %2";
5170 case 2: return "%1 .+2\;rjmp %2";
5171 case 3: return "%1 .+4\;jmp %2";
5178 ;; Same as above but with clobber flavour of addhi3
5179 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5180 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5181 (plus:HI (match_dup 0)
5183 (clobber (scratch:QI))])
5184 (parallel [(set (cc0)
5185 (compare (match_dup 0)
5187 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5189 (if_then_else (eqne (cc0)
5191 (label_ref (match_operand 2 "" ""))
5198 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5199 output_asm_insn ("sbiw %0,1", operands);
5201 output_asm_insn ("subi %A0,1" CR_TAB
5202 "sbc %B0,__zero_reg__", operands);
5204 jump_mode = avr_jump_mode (operands[2], insn);
5205 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5206 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5210 case 1: return "%1 %2";
5211 case 2: return "%1 .+2\;rjmp %2";
5212 case 3: return "%1 .+4\;jmp %2";
5219 ;; Same as above but with clobber flavour of addhi3
5220 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5221 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5222 (plus:HI (match_dup 0)
5224 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5225 (parallel [(set (cc0)
5226 (compare (match_dup 0)
5228 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5230 (if_then_else (eqne (cc0)
5232 (label_ref (match_operand 2 "" ""))
5239 output_asm_insn ("ldi %3,1" CR_TAB
5241 "sbc %B0,__zero_reg__", operands);
5243 jump_mode = avr_jump_mode (operands[2], insn);
5244 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5245 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5249 case 1: return "%1 %2";
5250 case 2: return "%1 .+2\;rjmp %2";
5251 case 3: return "%1 .+4\;jmp %2";
5258 (define_peephole ; "*dec-and-branchqi!=-1"
5259 [(set (match_operand:QI 0 "d_register_operand" "")
5260 (plus:QI (match_dup 0)
5263 (compare (match_dup 0)
5266 (if_then_else (eqne (cc0)
5268 (label_ref (match_operand 1 "" ""))
5275 cc_status.value1 = operands[0];
5276 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5278 output_asm_insn ("subi %A0,1", operands);
5280 jump_mode = avr_jump_mode (operands[1], insn);
5281 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5282 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5286 case 1: return "%0 %1";
5287 case 2: return "%0 .+2\;rjmp %1";
5288 case 3: return "%0 .+4\;jmp %1";
5296 (define_peephole ; "*cpse.eq"
5298 (compare (match_operand:ALL1 1 "register_operand" "r,r")
5299 (match_operand:ALL1 2 "reg_or_0_operand" "r,Y00")))
5301 (if_then_else (eq (cc0)
5303 (label_ref (match_operand 0 "" ""))
5305 "jump_over_one_insn_p (insn, operands[0])"
5308 cpse %1,__zero_reg__")
5310 ;; This peephole avoids code like
5313 ;; BREQ .+2 ; branch
5316 ;; Notice that the peephole is always shorter than cmpqi + branch.
5317 ;; The reason to write it as peephole is that sequences like
5322 ;; shall not be superseeded. With a respective combine pattern
5323 ;; the latter sequence would be
5326 ;; CPSE Rm, __zero_reg__
5329 ;; and thus longer and slower and not easy to be rolled back.
5331 (define_peephole ; "*cpse.ne"
5333 (compare (match_operand:ALL1 1 "register_operand" "")
5334 (match_operand:ALL1 2 "reg_or_0_operand" "")))
5336 (if_then_else (ne (cc0)
5338 (label_ref (match_operand 0 "" ""))
5341 || !avr_current_device->errata_skip"
5343 if (operands[2] == CONST0_RTX (<MODE>mode))
5344 operands[2] = zero_reg_rtx;
5346 return 3 == avr_jump_mode (operands[0], insn)
5347 ? "cpse %1,%2\;jmp %0"
5348 : "cpse %1,%2\;rjmp %0";
5351 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5352 ;;prologue/epilogue support instructions
5354 (define_insn "popqi"
5355 [(set (match_operand:QI 0 "register_operand" "=r")
5356 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5359 [(set_attr "cc" "none")
5360 (set_attr "length" "1")])
5362 ;; Enable Interrupts
5363 (define_expand "enable_interrupt"
5364 [(clobber (const_int 0))]
5367 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5368 MEM_VOLATILE_P (mem) = 1;
5369 emit_insn (gen_cli_sei (const1_rtx, mem));
5373 ;; Disable Interrupts
5374 (define_expand "disable_interrupt"
5375 [(clobber (const_int 0))]
5378 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5379 MEM_VOLATILE_P (mem) = 1;
5380 emit_insn (gen_cli_sei (const0_rtx, mem));
5384 (define_insn "cli_sei"
5385 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "L,P")]
5386 UNSPECV_ENABLE_IRQS)
5387 (set (match_operand:BLK 1 "" "")
5388 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5393 [(set_attr "length" "1")
5394 (set_attr "cc" "none")])
5396 ;; Library prologue saves
5397 (define_insn "call_prologue_saves"
5398 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5399 (match_operand:HI 0 "immediate_operand" "i,i")
5400 (set (reg:HI REG_SP)
5401 (minus:HI (reg:HI REG_SP)
5402 (match_operand:HI 1 "immediate_operand" "i,i")))
5403 (use (reg:HI REG_X))
5404 (clobber (reg:HI REG_Z))]
5406 "ldi r30,lo8(gs(1f))
5408 %~jmp __prologue_saves__+((18 - %0) * 2)
5410 [(set_attr "length" "5,6")
5411 (set_attr "cc" "clobber")
5412 (set_attr "isa" "rjmp,jmp")])
5414 ; epilogue restores using library
5415 (define_insn "epilogue_restores"
5416 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5418 (plus:HI (reg:HI REG_Y)
5419 (match_operand:HI 0 "immediate_operand" "i,i")))
5420 (set (reg:HI REG_SP)
5421 (plus:HI (reg:HI REG_Y)
5423 (clobber (reg:QI REG_Z))]
5426 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5427 [(set_attr "length" "2,3")
5428 (set_attr "cc" "clobber")
5429 (set_attr "isa" "rjmp,jmp")])
5432 (define_insn "return"
5434 "reload_completed && avr_simple_epilogue ()"
5436 [(set_attr "cc" "none")
5437 (set_attr "length" "1")])
5439 (define_insn "return_from_epilogue"
5443 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5444 && !cfun->machine->is_naked"
5446 [(set_attr "cc" "none")
5447 (set_attr "length" "1")])
5449 (define_insn "return_from_interrupt_epilogue"
5453 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5454 && !cfun->machine->is_naked"
5456 [(set_attr "cc" "none")
5457 (set_attr "length" "1")])
5459 (define_insn "return_from_naked_epilogue"
5463 && cfun->machine->is_naked"
5465 [(set_attr "cc" "none")
5466 (set_attr "length" "0")])
5468 (define_expand "prologue"
5476 (define_expand "epilogue"
5480 expand_epilogue (false /* sibcall_p */);
5484 (define_expand "sibcall_epilogue"
5488 expand_epilogue (true /* sibcall_p */);
5492 ;; Some instructions resp. instruction sequences available
5495 (define_insn "delay_cycles_1"
5496 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5498 UNSPECV_DELAY_CYCLES)
5499 (set (match_operand:BLK 1 "" "")
5500 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5501 (clobber (match_scratch:QI 2 "=&d"))]
5506 [(set_attr "length" "3")
5507 (set_attr "cc" "clobber")])
5509 (define_insn "delay_cycles_2"
5510 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5512 UNSPECV_DELAY_CYCLES)
5513 (set (match_operand:BLK 1 "" "")
5514 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5515 (clobber (match_scratch:HI 2 "=&w"))]
5521 [(set_attr "length" "4")
5522 (set_attr "cc" "clobber")])
5524 (define_insn "delay_cycles_3"
5525 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5527 UNSPECV_DELAY_CYCLES)
5528 (set (match_operand:BLK 1 "" "")
5529 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5530 (clobber (match_scratch:QI 2 "=&d"))
5531 (clobber (match_scratch:QI 3 "=&d"))
5532 (clobber (match_scratch:QI 4 "=&d"))]
5541 [(set_attr "length" "7")
5542 (set_attr "cc" "clobber")])
5544 (define_insn "delay_cycles_4"
5545 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5547 UNSPECV_DELAY_CYCLES)
5548 (set (match_operand:BLK 1 "" "")
5549 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))
5550 (clobber (match_scratch:QI 2 "=&d"))
5551 (clobber (match_scratch:QI 3 "=&d"))
5552 (clobber (match_scratch:QI 4 "=&d"))
5553 (clobber (match_scratch:QI 5 "=&d"))]
5564 [(set_attr "length" "9")
5565 (set_attr "cc" "clobber")])
5568 ;; __builtin_avr_insert_bits
5570 (define_insn "insert_bits"
5571 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5572 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5573 (match_operand:QI 2 "register_operand" "r ,r ,r")
5574 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5575 UNSPEC_INSERT_BITS))]
5578 return avr_out_insert_bits (operands, NULL);
5580 [(set_attr "adjust_len" "insert_bits")
5581 (set_attr "cc" "clobber")])
5584 ;; __builtin_avr_flash_segment
5586 ;; Just a helper for the next "official" expander.
5588 (define_expand "flash_segment1"
5589 [(set (match_operand:QI 0 "register_operand" "")
5590 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5593 (compare (match_dup 0)
5596 (if_then_else (ge (cc0)
5598 (label_ref (match_operand 2 "" ""))
5603 (define_expand "flash_segment"
5604 [(parallel [(match_operand:QI 0 "register_operand" "")
5605 (match_operand:PSI 1 "register_operand" "")])]
5608 rtx label = gen_label_rtx ();
5609 emit (gen_flash_segment1 (operands[0], operands[1], label));
5614 ;; Actually, it's too late now to work out address spaces known at compiletime.
5615 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5616 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5617 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5619 (define_insn_and_split "*split.flash_segment"
5620 [(set (match_operand:QI 0 "register_operand" "=d")
5621 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5622 (match_operand:HI 2 "register_operand" "r"))
5625 { gcc_unreachable(); }
5633 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5634 ;; better 8-bit parity recognition.
5636 (define_expand "parityhi2"
5637 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5638 (parity:HI (match_operand:HI 1 "register_operand" "")))
5639 (clobber (reg:HI 24))])])
5641 (define_insn_and_split "*parityhi2"
5642 [(set (match_operand:HI 0 "register_operand" "=r")
5643 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5644 (clobber (reg:HI 24))]
5646 { gcc_unreachable(); }
5651 (parity:HI (reg:HI 24)))
5655 (define_insn_and_split "*parityqihi2"
5656 [(set (match_operand:HI 0 "register_operand" "=r")
5657 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5658 (clobber (reg:HI 24))]
5660 { gcc_unreachable(); }
5665 (zero_extend:HI (parity:QI (reg:QI 24))))
5669 (define_expand "paritysi2"
5671 (match_operand:SI 1 "register_operand" ""))
5673 (truncate:HI (parity:SI (reg:SI 22))))
5676 (set (match_operand:SI 0 "register_operand" "")
5677 (zero_extend:SI (match_dup 2)))]
5680 operands[2] = gen_reg_rtx (HImode);
5683 (define_insn "*parityhi2.libgcc"
5685 (parity:HI (reg:HI 24)))]
5687 "%~call __parityhi2"
5688 [(set_attr "type" "xcall")
5689 (set_attr "cc" "clobber")])
5691 (define_insn "*parityqihi2.libgcc"
5693 (zero_extend:HI (parity:QI (reg:QI 24))))]
5695 "%~call __parityqi2"
5696 [(set_attr "type" "xcall")
5697 (set_attr "cc" "clobber")])
5699 (define_insn "*paritysihi2.libgcc"
5701 (truncate:HI (parity:SI (reg:SI 22))))]
5703 "%~call __paritysi2"
5704 [(set_attr "type" "xcall")
5705 (set_attr "cc" "clobber")])
5710 (define_expand "popcounthi2"
5712 (match_operand:HI 1 "register_operand" ""))
5714 (popcount:HI (reg:HI 24)))
5715 (set (match_operand:HI 0 "register_operand" "")
5720 (define_expand "popcountsi2"
5722 (match_operand:SI 1 "register_operand" ""))
5724 (truncate:HI (popcount:SI (reg:SI 22))))
5727 (set (match_operand:SI 0 "register_operand" "")
5728 (zero_extend:SI (match_dup 2)))]
5731 operands[2] = gen_reg_rtx (HImode);
5734 (define_insn "*popcounthi2.libgcc"
5736 (popcount:HI (reg:HI 24)))]
5738 "%~call __popcounthi2"
5739 [(set_attr "type" "xcall")
5740 (set_attr "cc" "clobber")])
5742 (define_insn "*popcountsi2.libgcc"
5744 (truncate:HI (popcount:SI (reg:SI 22))))]
5746 "%~call __popcountsi2"
5747 [(set_attr "type" "xcall")
5748 (set_attr "cc" "clobber")])
5750 (define_insn "*popcountqi2.libgcc"
5752 (popcount:QI (reg:QI 24)))]
5754 "%~call __popcountqi2"
5755 [(set_attr "type" "xcall")
5756 (set_attr "cc" "clobber")])
5758 (define_insn_and_split "*popcountqihi2.libgcc"
5760 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5765 (popcount:QI (reg:QI 24)))
5769 ;; Count Leading Zeros
5771 (define_expand "clzhi2"
5773 (match_operand:HI 1 "register_operand" ""))
5774 (parallel [(set (reg:HI 24)
5775 (clz:HI (reg:HI 24)))
5776 (clobber (reg:QI 26))])
5777 (set (match_operand:HI 0 "register_operand" "")
5780 (define_expand "clzsi2"
5782 (match_operand:SI 1 "register_operand" ""))
5783 (parallel [(set (reg:HI 24)
5784 (truncate:HI (clz:SI (reg:SI 22))))
5785 (clobber (reg:QI 26))])
5788 (set (match_operand:SI 0 "register_operand" "")
5789 (zero_extend:SI (match_dup 2)))]
5792 operands[2] = gen_reg_rtx (HImode);
5795 (define_insn "*clzhi2.libgcc"
5797 (clz:HI (reg:HI 24)))
5798 (clobber (reg:QI 26))]
5801 [(set_attr "type" "xcall")
5802 (set_attr "cc" "clobber")])
5804 (define_insn "*clzsihi2.libgcc"
5806 (truncate:HI (clz:SI (reg:SI 22))))
5807 (clobber (reg:QI 26))]
5810 [(set_attr "type" "xcall")
5811 (set_attr "cc" "clobber")])
5813 ;; Count Trailing Zeros
5815 (define_expand "ctzhi2"
5817 (match_operand:HI 1 "register_operand" ""))
5818 (parallel [(set (reg:HI 24)
5819 (ctz:HI (reg:HI 24)))
5820 (clobber (reg:QI 26))])
5821 (set (match_operand:HI 0 "register_operand" "")
5824 (define_expand "ctzsi2"
5826 (match_operand:SI 1 "register_operand" ""))
5827 (parallel [(set (reg:HI 24)
5828 (truncate:HI (ctz:SI (reg:SI 22))))
5829 (clobber (reg:QI 22))
5830 (clobber (reg:QI 26))])
5833 (set (match_operand:SI 0 "register_operand" "")
5834 (zero_extend:SI (match_dup 2)))]
5837 operands[2] = gen_reg_rtx (HImode);
5840 (define_insn "*ctzhi2.libgcc"
5842 (ctz:HI (reg:HI 24)))
5843 (clobber (reg:QI 26))]
5846 [(set_attr "type" "xcall")
5847 (set_attr "cc" "clobber")])
5849 (define_insn "*ctzsihi2.libgcc"
5851 (truncate:HI (ctz:SI (reg:SI 22))))
5852 (clobber (reg:QI 22))
5853 (clobber (reg:QI 26))]
5856 [(set_attr "type" "xcall")
5857 (set_attr "cc" "clobber")])
5861 (define_expand "ffshi2"
5863 (match_operand:HI 1 "register_operand" ""))
5864 (parallel [(set (reg:HI 24)
5865 (ffs:HI (reg:HI 24)))
5866 (clobber (reg:QI 26))])
5867 (set (match_operand:HI 0 "register_operand" "")
5870 (define_expand "ffssi2"
5872 (match_operand:SI 1 "register_operand" ""))
5873 (parallel [(set (reg:HI 24)
5874 (truncate:HI (ffs:SI (reg:SI 22))))
5875 (clobber (reg:QI 22))
5876 (clobber (reg:QI 26))])
5879 (set (match_operand:SI 0 "register_operand" "")
5880 (zero_extend:SI (match_dup 2)))]
5883 operands[2] = gen_reg_rtx (HImode);
5886 (define_insn "*ffshi2.libgcc"
5888 (ffs:HI (reg:HI 24)))
5889 (clobber (reg:QI 26))]
5892 [(set_attr "type" "xcall")
5893 (set_attr "cc" "clobber")])
5895 (define_insn "*ffssihi2.libgcc"
5897 (truncate:HI (ffs:SI (reg:SI 22))))
5898 (clobber (reg:QI 22))
5899 (clobber (reg:QI 26))]
5902 [(set_attr "type" "xcall")
5903 (set_attr "cc" "clobber")])
5907 (define_insn "copysignsf3"
5908 [(set (match_operand:SF 0 "register_operand" "=r")
5909 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5910 (match_operand:SF 2 "register_operand" "r")]
5913 "bst %D2,7\;bld %D0,7"
5914 [(set_attr "length" "2")
5915 (set_attr "cc" "none")])
5917 ;; Swap Bytes (change byte-endianess)
5919 (define_expand "bswapsi2"
5921 (match_operand:SI 1 "register_operand" ""))
5923 (bswap:SI (reg:SI 22)))
5924 (set (match_operand:SI 0 "register_operand" "")
5927 (define_insn "*bswapsi2.libgcc"
5929 (bswap:SI (reg:SI 22)))]
5932 [(set_attr "type" "xcall")
5933 (set_attr "cc" "clobber")])
5938 ;; NOP taking 1 or 2 Ticks
5939 (define_expand "nopv"
5940 [(parallel [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
5943 (unspec_volatile:BLK [(match_dup 1)]
5944 UNSPECV_MEMORY_BARRIER))])]
5947 operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5948 MEM_VOLATILE_P (operands[1]) = 1;
5951 (define_insn "*nopv"
5952 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5954 (set (match_operand:BLK 1 "" "")
5955 (unspec_volatile:BLK [(match_dup 1)] UNSPECV_MEMORY_BARRIER))]
5960 [(set_attr "length" "1")
5961 (set_attr "cc" "none")])
5964 (define_expand "sleep"
5965 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5967 (unspec_volatile:BLK [(match_dup 0)]
5968 UNSPECV_MEMORY_BARRIER))])]
5971 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5972 MEM_VOLATILE_P (operands[0]) = 1;
5975 (define_insn "*sleep"
5976 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)
5977 (set (match_operand:BLK 0 "" "")
5978 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
5981 [(set_attr "length" "1")
5982 (set_attr "cc" "none")])
5985 (define_expand "wdr"
5986 [(parallel [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5988 (unspec_volatile:BLK [(match_dup 0)]
5989 UNSPECV_MEMORY_BARRIER))])]
5992 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
5993 MEM_VOLATILE_P (operands[0]) = 1;
5997 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)
5998 (set (match_operand:BLK 0 "" "")
5999 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_MEMORY_BARRIER))]
6002 [(set_attr "length" "1")
6003 (set_attr "cc" "none")])
6006 (define_expand "fmul"
6008 (match_operand:QI 1 "register_operand" ""))
6010 (match_operand:QI 2 "register_operand" ""))
6011 (parallel [(set (reg:HI 22)
6012 (unspec:HI [(reg:QI 24)
6013 (reg:QI 25)] UNSPEC_FMUL))
6014 (clobber (reg:HI 24))])
6015 (set (match_operand:HI 0 "register_operand" "")
6021 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
6026 (define_insn "fmul_insn"
6027 [(set (match_operand:HI 0 "register_operand" "=r")
6028 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6029 (match_operand:QI 2 "register_operand" "a")]
6035 [(set_attr "length" "3")
6036 (set_attr "cc" "clobber")])
6038 (define_insn "*fmul.call"
6040 (unspec:HI [(reg:QI 24)
6041 (reg:QI 25)] UNSPEC_FMUL))
6042 (clobber (reg:HI 24))]
6045 [(set_attr "type" "xcall")
6046 (set_attr "cc" "clobber")])
6049 (define_expand "fmuls"
6051 (match_operand:QI 1 "register_operand" ""))
6053 (match_operand:QI 2 "register_operand" ""))
6054 (parallel [(set (reg:HI 22)
6055 (unspec:HI [(reg:QI 24)
6056 (reg:QI 25)] UNSPEC_FMULS))
6057 (clobber (reg:HI 24))])
6058 (set (match_operand:HI 0 "register_operand" "")
6064 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
6069 (define_insn "fmuls_insn"
6070 [(set (match_operand:HI 0 "register_operand" "=r")
6071 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6072 (match_operand:QI 2 "register_operand" "a")]
6078 [(set_attr "length" "3")
6079 (set_attr "cc" "clobber")])
6081 (define_insn "*fmuls.call"
6083 (unspec:HI [(reg:QI 24)
6084 (reg:QI 25)] UNSPEC_FMULS))
6085 (clobber (reg:HI 24))]
6088 [(set_attr "type" "xcall")
6089 (set_attr "cc" "clobber")])
6092 (define_expand "fmulsu"
6094 (match_operand:QI 1 "register_operand" ""))
6096 (match_operand:QI 2 "register_operand" ""))
6097 (parallel [(set (reg:HI 22)
6098 (unspec:HI [(reg:QI 24)
6099 (reg:QI 25)] UNSPEC_FMULSU))
6100 (clobber (reg:HI 24))])
6101 (set (match_operand:HI 0 "register_operand" "")
6107 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
6112 (define_insn "fmulsu_insn"
6113 [(set (match_operand:HI 0 "register_operand" "=r")
6114 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
6115 (match_operand:QI 2 "register_operand" "a")]
6121 [(set_attr "length" "3")
6122 (set_attr "cc" "clobber")])
6124 (define_insn "*fmulsu.call"
6126 (unspec:HI [(reg:QI 24)
6127 (reg:QI 25)] UNSPEC_FMULSU))
6128 (clobber (reg:HI 24))]
6131 [(set_attr "type" "xcall")
6132 (set_attr "cc" "clobber")])
6135 ;; Some combiner patterns dealing with bits.
6138 ;; Move bit $3.0 into bit $0.$4
6139 (define_insn "*movbitqi.1-6.a"
6140 [(set (match_operand:QI 0 "register_operand" "=r")
6141 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6142 (match_operand:QI 2 "single_zero_operand" "n"))
6143 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
6144 (match_operand:QI 4 "const_0_to_7_operand" "n"))
6145 (match_operand:QI 5 "single_one_operand" "n"))))]
6146 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
6147 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
6148 "bst %3,0\;bld %0,%4"
6149 [(set_attr "length" "2")
6150 (set_attr "cc" "none")])
6152 ;; Move bit $3.0 into bit $0.$4
6153 ;; Variation of above. Unfortunately, there is no canonicalized representation
6154 ;; of moving around bits. So what we see here depends on how user writes down
6155 ;; bit manipulations.
6156 (define_insn "*movbitqi.1-6.b"
6157 [(set (match_operand:QI 0 "register_operand" "=r")
6158 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6159 (match_operand:QI 2 "single_zero_operand" "n"))
6160 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
6162 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
6163 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6164 "bst %3,0\;bld %0,%4"
6165 [(set_attr "length" "2")
6166 (set_attr "cc" "none")])
6168 ;; Move bit $3.0 into bit $0.0.
6169 ;; For bit 0, combiner generates slightly different pattern.
6170 (define_insn "*movbitqi.0"
6171 [(set (match_operand:QI 0 "register_operand" "=r")
6172 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6173 (match_operand:QI 2 "single_zero_operand" "n"))
6174 (and:QI (match_operand:QI 3 "register_operand" "r")
6176 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
6177 "bst %3,0\;bld %0,0"
6178 [(set_attr "length" "2")
6179 (set_attr "cc" "none")])
6181 ;; Move bit $2.0 into bit $0.7.
6182 ;; For bit 7, combiner generates slightly different pattern
6183 (define_insn "*movbitqi.7"
6184 [(set (match_operand:QI 0 "register_operand" "=r")
6185 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6187 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6190 "bst %2,0\;bld %0,7"
6191 [(set_attr "length" "2")
6192 (set_attr "cc" "none")])
6194 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6195 ;; and input/output match. We provide a special pattern for this, because
6196 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6197 ;; operation on I/O is atomic.
6198 (define_insn "*insv.io"
6199 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6201 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6202 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6207 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6208 [(set_attr "length" "1,1,4")
6209 (set_attr "cc" "none")])
6211 (define_insn "*insv.not.io"
6212 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6214 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6215 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6217 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6218 [(set_attr "length" "4")
6219 (set_attr "cc" "none")])
6221 ;; The insv expander.
6222 ;; We only support 1-bit inserts
6223 (define_expand "insv"
6224 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6225 (match_operand:QI 1 "const1_operand" "") ; width
6226 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6227 (match_operand:QI 3 "nonmemory_operand" ""))]
6230 ;; Insert bit $2.0 into $0.$1
6231 (define_insn "*insv.reg"
6232 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6234 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6235 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6239 andi %0,lo8(~(1<<%1))
6243 [(set_attr "length" "2,1,1,2,2")
6244 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6247 ;; Some combine patterns that try to fix bad code when a value is composed
6248 ;; from byte parts like in PR27663.
6249 ;; The patterns give some release but the code still is not optimal,
6250 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6251 ;; That switch obfuscates things here and in many other places.
6253 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6254 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6255 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6256 [(set (match_operand:HISI 0 "register_operand" "=r")
6258 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6259 (match_operand:HISI 2 "register_operand" "0")))]
6264 (xior:QI (match_dup 3)
6267 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6270 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6271 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6272 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6273 [(set (match_operand:HISI 0 "register_operand" "=r")
6275 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6276 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6277 (match_operand:HISI 3 "register_operand" "0")))]
6278 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6280 "&& reload_completed"
6282 (xior:QI (match_dup 4)
6285 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6286 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6289 (define_expand "extzv"
6290 [(set (match_operand:QI 0 "register_operand" "")
6291 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6292 (match_operand:QI 2 "const1_operand" "")
6293 (match_operand:QI 3 "const_0_to_7_operand" "")))])
6295 (define_insn "*extzv"
6296 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6297 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6299 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6303 mov %0,%1\;andi %0,1
6306 bst %1,%2\;clr %0\;bld %0,0"
6307 [(set_attr "length" "1,2,2,2,3")
6308 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6310 (define_insn_and_split "*extzv.qihi1"
6311 [(set (match_operand:HI 0 "register_operand" "=r")
6312 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6314 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6319 (zero_extract:QI (match_dup 1)
6325 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6326 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6329 (define_insn_and_split "*extzv.qihi2"
6330 [(set (match_operand:HI 0 "register_operand" "=r")
6332 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6334 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6339 (zero_extract:QI (match_dup 1)
6345 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6346 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6350 ;; Fixed-point instructions
6351 (include "avr-fixed.md")
6353 ;; Operations on 64-bit registers
6354 (include "avr-dimode.md")