1 ;; Machine description for GNU compiler,
2 ;; for ATMEL AVR micro controllers.
3 ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
4 ;; 2009, 2010, 2011 Free Software Foundation, Inc.
5 ;; Contributed by Denis Chertykov (chertykov@gmail.com)
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;; Special characters after '%':
24 ;; A No effect (add 0).
25 ;; B Add 1 to REG number, MEM address or CONST_INT.
28 ;; j Branch condition.
29 ;; k Reverse branch condition.
30 ;;..m..Constant Direct Data memory address.
31 ;; i Print the SFR address quivalent of a CONST_INT or a CONST_INT
32 ;; RAM address. The resulting addres is suitable to be used in IN/OUT.
33 ;; o Displacement for (mem (plus (reg) (const_int))) operands.
34 ;; p POST_INC or PRE_DEC address as a pointer (X, Y, Z)
35 ;; r POST_INC or PRE_DEC address as a register (r26, r28, r30)
36 ;; T/T Print operand suitable for BLD/BST instruction, i.e. register and
37 ;; bit number. This gets 2 operands: The first %T gets a REG_P and
38 ;; just cashes the operand for the next %T. The second %T gets
39 ;; a CONST_INT that represents a bit position.
40 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
41 ;; "%T0%T1" it will print "r19,5".
42 ;; Notice that you must not write a comma between %T0 and %T1.
43 ;; T/t Similar to above, but don't print the comma and the bit number.
44 ;; Example: With %0 = (reg:HI 18) and %1 = (const_int 13)
45 ;; "%T0%t1" it will print "r19".
46 ;;..x..Constant Direct Program memory address.
47 ;; ~ Output 'r' if not AVR_HAVE_JMP_CALL.
48 ;; ! Output 'e' if AVR_HAVE_EIJMP_EICALL.
57 (LPM_REGNO 0) ; implicit target register of LPM
58 (TMP_REGNO 0) ; temporary register r0
59 (ZERO_REGNO 1) ; zero register r1
62 (define_c_enum "unspec"
74 (define_c_enum "unspecv"
75 [UNSPECV_PROLOGUE_SAVES
76 UNSPECV_EPILOGUE_RESTORES
87 (include "predicates.md")
88 (include "constraints.md")
90 ;; Condition code settings.
91 (define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber,
92 out_plus, out_plus_noclobber,ldi"
93 (const_string "none"))
95 (define_attr "type" "branch,branch1,arith,xcall"
96 (const_string "arith"))
98 ;; The size of instructions in bytes.
99 ;; XXX may depend from "cc"
101 (define_attr "length" ""
102 (cond [(eq_attr "type" "branch")
103 (if_then_else (and (ge (minus (pc) (match_dup 0))
105 (le (minus (pc) (match_dup 0))
108 (if_then_else (and (ge (minus (pc) (match_dup 0))
110 (le (minus (pc) (match_dup 0))
114 (eq_attr "type" "branch1")
115 (if_then_else (and (ge (minus (pc) (match_dup 0))
117 (le (minus (pc) (match_dup 0))
120 (if_then_else (and (ge (minus (pc) (match_dup 0))
122 (le (minus (pc) (match_dup 0))
126 (eq_attr "type" "xcall")
127 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
132 ;; Lengths of several insns are adjusted in avr.c:adjust_insn_length().
133 ;; Following insn attribute tells if and how the adjustment has to be
135 ;; no No adjustment needed; attribute "length" is fine.
136 ;; Otherwise do special processing depending on the attribute.
138 (define_attr "adjust_len"
139 "out_bitop, out_plus, out_plus_noclobber, plus64, addto_sp,
140 tsthi, tstpsi, tstsi, compare, compare64, call,
141 mov8, mov16, mov24, mov32, reload_in16, reload_in24, reload_in32,
143 ashlqi, ashrqi, lshrqi,
144 ashlhi, ashrhi, lshrhi,
145 ashlsi, ashrsi, lshrsi,
146 ashlpsi, ashrpsi, lshrpsi,
151 ;; Flavours of instruction set architecture (ISA), used in enabled attribute
153 ;; mov : ISA has no MOVW movw : ISA has MOVW
154 ;; rjmp : ISA has no CALL/JMP jmp : ISA has CALL/JMP
155 ;; ijmp : ISA has no EICALL/EIJMP eijmp : ISA has EICALL/EIJMP
156 ;; lpm : ISA has no LPMX lpmx : ISA has LPMX
157 ;; elpm : ISA has ELPM but no ELPMX elpmx : ISA has ELPMX
158 ;; no_xmega: non-XMEGA core xmega : XMEGA core
161 "mov,movw, rjmp,jmp, ijmp,eijmp, lpm,lpmx, elpm,elpmx, no_xmega,xmega,
163 (const_string "standard"))
165 (define_attr "enabled" ""
166 (cond [(eq_attr "isa" "standard")
169 (and (eq_attr "isa" "mov")
170 (match_test "!AVR_HAVE_MOVW"))
173 (and (eq_attr "isa" "movw")
174 (match_test "AVR_HAVE_MOVW"))
177 (and (eq_attr "isa" "rjmp")
178 (match_test "!AVR_HAVE_JMP_CALL"))
181 (and (eq_attr "isa" "jmp")
182 (match_test "AVR_HAVE_JMP_CALL"))
185 (and (eq_attr "isa" "ijmp")
186 (match_test "!AVR_HAVE_EIJMP_EICALL"))
189 (and (eq_attr "isa" "eijmp")
190 (match_test "AVR_HAVE_EIJMP_EICALL"))
193 (and (eq_attr "isa" "lpm")
194 (match_test "!AVR_HAVE_LPMX"))
197 (and (eq_attr "isa" "lpmx")
198 (match_test "AVR_HAVE_LPMX"))
201 (and (eq_attr "isa" "elpm")
202 (match_test "AVR_HAVE_ELPM && !AVR_HAVE_ELPMX"))
205 (and (eq_attr "isa" "elpmx")
206 (match_test "AVR_HAVE_ELPMX"))
209 (and (eq_attr "isa" "xmega")
210 (match_test "AVR_XMEGA"))
213 (and (eq_attr "isa" "no_xmega")
214 (match_test "!AVR_XMEGA"))
219 ;; Define mode iterators
220 (define_mode_iterator QIHI [(QI "") (HI "")])
221 (define_mode_iterator QIHI2 [(QI "") (HI "")])
222 (define_mode_iterator QISI [(QI "") (HI "") (PSI "") (SI "")])
223 (define_mode_iterator QIDI [(QI "") (HI "") (PSI "") (SI "") (DI "")])
224 (define_mode_iterator HISI [(HI "") (PSI "") (SI "")])
226 ;; All supported move-modes
227 (define_mode_iterator MOVMODE [(QI "") (HI "") (SI "") (SF "") (PSI "")])
229 ;; Define code iterators
230 ;; Define two incarnations so that we can build the cross product.
231 (define_code_iterator any_extend [sign_extend zero_extend])
232 (define_code_iterator any_extend2 [sign_extend zero_extend])
234 (define_code_iterator xior [xor ior])
235 (define_code_iterator eqne [eq ne])
237 ;; Define code attributes
238 (define_code_attr extend_su
242 (define_code_attr extend_u
246 (define_code_attr extend_s
250 ;; Constrain input operand of widening multiply, i.e. MUL resp. MULS.
251 (define_code_attr mul_r_d
255 ;; Map RTX code to its standard insn name
256 (define_code_attr code_stdname
264 ;;========================================================================
265 ;; The following is used by nonlocal_goto and setjmp.
266 ;; The receiver pattern will create no instructions since internally
267 ;; virtual_stack_vars = hard_frame_pointer + 1 so the RTL become R28=R28
268 ;; This avoids creating add/sub offsets in frame_pointer save/resore.
269 ;; The 'null' receiver also avoids problems with optimisation
270 ;; not recognising incoming jmp and removing code that resets frame_pointer.
271 ;; The code derived from builtins.c.
273 (define_expand "nonlocal_goto_receiver"
275 (unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
278 emit_move_insn (virtual_stack_vars_rtx,
279 gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
280 gen_int_mode (STARTING_FRAME_OFFSET,
282 /* This might change the hard frame pointer in ways that aren't
283 apparent to early optimization passes, so force a clobber. */
284 emit_clobber (hard_frame_pointer_rtx);
289 ;; Defining nonlocal_goto_receiver means we must also define this.
290 ;; even though its function is identical to that in builtins.c
292 (define_expand "nonlocal_goto"
293 [(use (match_operand 0 "general_operand"))
294 (use (match_operand 1 "general_operand"))
295 (use (match_operand 2 "general_operand"))
296 (use (match_operand 3 "general_operand"))]
299 rtx r_label = copy_to_reg (operands[1]);
300 rtx r_fp = operands[3];
301 rtx r_sp = operands[2];
303 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
305 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
307 emit_move_insn (hard_frame_pointer_rtx, r_fp);
308 emit_stack_restore (SAVE_NONLOCAL, r_sp);
310 emit_use (hard_frame_pointer_rtx);
311 emit_use (stack_pointer_rtx);
313 emit_indirect_jump (r_label);
318 (define_insn "pushqi1"
319 [(set (mem:QI (post_dec:HI (reg:HI REG_SP)))
320 (match_operand:QI 0 "reg_or_0_operand" "r,L"))]
325 [(set_attr "length" "1,1")])
327 ;; All modes for a multi-byte push. We must include complex modes here too,
328 ;; lest emit_single_push_insn "helpfully " create the auto-inc itself.
329 (define_mode_iterator MPUSH
337 (define_expand "push<mode>1"
338 [(match_operand:MPUSH 0 "" "")]
342 for (i = GET_MODE_SIZE (<MODE>mode) - 1; i >= 0; --i)
344 rtx part = simplify_gen_subreg (QImode, operands[0], <MODE>mode, i);
345 if (part != const0_rtx)
346 part = force_reg (QImode, part);
347 emit_insn (gen_pushqi1 (part));
352 ;; Notice a special-case when adding N to SP where N results in a
353 ;; zero REG_ARGS_SIZE. This is equivalent to a move from FP.
355 [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))]
357 && frame_pointer_needed
358 && !cfun->calls_alloca
359 && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)"
360 [(set (reg:HI REG_SP) (reg:HI REG_Y))]
363 ;;========================================================================
366 (define_expand "load<mode>_libgcc"
369 (set (reg:MOVMODE 22)
370 (match_operand:MOVMODE 1 "memory_operand" ""))
371 (set (match_operand:MOVMODE 0 "register_operand" "")
373 "avr_load_libgcc_p (operands[1])"
375 operands[3] = gen_rtx_REG (HImode, REG_Z);
376 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
377 operands[1] = replace_equiv_address (operands[1], operands[3]);
378 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
381 (define_insn "load_<mode>_libgcc"
382 [(set (reg:MOVMODE 22)
383 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
384 "avr_load_libgcc_p (operands[0])
385 && REG_P (XEXP (operands[0], 0))
386 && REG_Z == REGNO (XEXP (operands[0], 0))"
388 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
389 return "%~call __load_%0";
391 [(set_attr "length" "1,2")
392 (set_attr "isa" "rjmp,jmp")
393 (set_attr "cc" "clobber")])
396 (define_insn_and_split "xload8_A"
397 [(set (match_operand:QI 0 "register_operand" "=r")
398 (match_operand:QI 1 "memory_operand" "m"))
399 (clobber (reg:HI REG_Z))]
400 "can_create_pseudo_p()
401 && !avr_xload_libgcc_p (QImode)
402 && avr_mem_memx_p (operands[1])
403 && REG_P (XEXP (operands[1], 0))"
404 { gcc_unreachable(); }
406 [(clobber (const_int 0))]
408 rtx insn, addr = XEXP (operands[1], 0);
409 rtx hi8 = gen_reg_rtx (QImode);
410 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
412 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
413 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
415 insn = emit_insn (gen_xload_8 (operands[0], hi8));
416 set_mem_addr_space (SET_SRC (single_set (insn)),
417 MEM_ADDR_SPACE (operands[1]));
421 (define_insn_and_split "xload<mode>_A"
422 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
423 (match_operand:MOVMODE 1 "memory_operand" "m"))
424 (clobber (reg:QI 21))
425 (clobber (reg:HI REG_Z))]
426 "can_create_pseudo_p()
427 && avr_mem_memx_p (operands[1])
428 && REG_P (XEXP (operands[1], 0))"
429 { gcc_unreachable(); }
431 [(clobber (const_int 0))]
433 rtx addr = XEXP (operands[1], 0);
434 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
435 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
436 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
439 /* Split the address to R21:Z */
440 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
441 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
443 /* Load with code from libgcc */
444 insn = emit_insn (gen_xload_<mode>_libgcc ());
445 set_mem_addr_space (SET_SRC (single_set (insn)), as);
447 /* Move to destination */
448 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
453 ;; Move value from address space memx to a register
454 ;; These insns must be prior to respective generic move insn.
456 (define_insn "xload_8"
457 [(set (match_operand:QI 0 "register_operand" "=&r,r")
458 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
460 "!avr_xload_libgcc_p (QImode)"
462 return avr_out_xload (insn, operands, NULL);
464 [(set_attr "length" "3,4")
465 (set_attr "adjust_len" "*,xload")
466 (set_attr "isa" "lpmx,lpm")
467 (set_attr "cc" "none")])
469 ;; R21:Z : 24-bit source address
470 ;; R22 : 1-4 byte output
474 ;; "xload_psi_libgcc"
477 (define_insn "xload_<mode>_libgcc"
478 [(set (reg:MOVMODE 22)
479 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
481 (clobber (reg:QI 21))
482 (clobber (reg:HI REG_Z))]
483 "avr_xload_libgcc_p (<MODE>mode)"
485 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
487 output_asm_insn ("%~call __xload_%0", &x_bytes);
490 [(set_attr "type" "xcall")
491 (set_attr "cc" "clobber")])
494 ;; General move expanders
501 (define_expand "mov<mode>"
502 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
503 (match_operand:MOVMODE 1 "general_operand" ""))]
506 rtx dest = operands[0];
507 rtx src = operands[1];
509 if (avr_mem_flash_p (dest))
512 /* One of the operands has to be in a register. */
513 if (!register_operand (dest, <MODE>mode)
514 && !(register_operand (src, <MODE>mode)
515 || src == CONST0_RTX (<MODE>mode)))
517 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
520 if (avr_mem_memx_p (src))
522 rtx addr = XEXP (src, 0);
525 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
527 if (!avr_xload_libgcc_p (<MODE>mode))
528 emit_insn (gen_xload8_A (dest, src));
530 emit_insn (gen_xload<mode>_A (dest, src));
535 if (avr_load_libgcc_p (src))
537 /* For the small devices, do loads per libgcc call. */
538 emit_insn (gen_load<mode>_libgcc (dest, src));
543 ;;========================================================================
545 ;; The last alternative (any immediate constant to any register) is
546 ;; very expensive. It should be optimized by peephole2 if a scratch
547 ;; register is available, but then that register could just as well be
548 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
549 ;; are call-saved registers, and most of LD_REGS are call-used registers,
550 ;; so this may still be a win for registers live across function calls.
552 (define_insn "movqi_insn"
553 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
554 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
555 "register_operand (operands[0], QImode)
556 || register_operand (operands[1], QImode)
557 || const0_rtx == operands[1]"
559 return output_movqi (insn, operands, NULL);
561 [(set_attr "length" "1,1,5,5,1,1,4")
562 (set_attr "adjust_len" "mov8")
563 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
565 ;; This is used in peephole2 to optimize loading immediate constants
566 ;; if a scratch register from LD_REGS happens to be available.
568 (define_insn "*reload_inqi"
569 [(set (match_operand:QI 0 "register_operand" "=l")
570 (match_operand:QI 1 "immediate_operand" "i"))
571 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
575 [(set_attr "length" "2")
576 (set_attr "cc" "none")])
579 [(match_scratch:QI 2 "d")
580 (set (match_operand:QI 0 "l_register_operand" "")
581 (match_operand:QI 1 "immediate_operand" ""))]
582 "(operands[1] != const0_rtx
583 && operands[1] != const1_rtx
584 && operands[1] != constm1_rtx)"
585 [(parallel [(set (match_dup 0) (match_dup 1))
586 (clobber (match_dup 2))])]
589 ;;============================================================================
590 ;; move word (16 bit)
592 ;; Move register $1 to the Stack Pointer register SP.
593 ;; This insn is emit during function prologue/epilogue generation.
594 ;; $2 = 0: We know that IRQs are off
595 ;; $2 = 1: We know that IRQs are on
596 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
597 ;; $2 = -1: We don't know anything about IRQ on/off
598 ;; Always write SP via unspec, see PR50063
600 (define_insn "movhi_sp_r"
601 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
602 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
603 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
607 out %B0,%B1\;out %A0,%A1
608 cli\;out %B0,%B1\;sei\;out %A0,%A1
609 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
611 out %A0,%A1\;out %B0,%B1"
612 [(set_attr "length" "2,4,5,1,2")
613 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
614 (set_attr "cc" "none")])
617 [(match_scratch:QI 2 "d")
618 (set (match_operand:HI 0 "l_register_operand" "")
619 (match_operand:HI 1 "immediate_operand" ""))]
620 "(operands[1] != const0_rtx
621 && operands[1] != constm1_rtx)"
622 [(parallel [(set (match_dup 0) (match_dup 1))
623 (clobber (match_dup 2))])]
626 ;; '*' because it is not used in rtl generation, only in above peephole
627 (define_insn "*reload_inhi"
628 [(set (match_operand:HI 0 "register_operand" "=r")
629 (match_operand:HI 1 "immediate_operand" "i"))
630 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
633 return output_reload_inhi (operands, operands[2], NULL);
635 [(set_attr "length" "4")
636 (set_attr "adjust_len" "reload_in16")
637 (set_attr "cc" "none")])
639 (define_insn "*movhi"
640 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
641 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
642 "register_operand (operands[0], HImode)
643 || register_operand (operands[1], HImode)
644 || const0_rtx == operands[1]"
646 return output_movhi (insn, operands, NULL);
648 [(set_attr "length" "2,2,6,7,2,6,5,2")
649 (set_attr "adjust_len" "mov16")
650 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
652 (define_peephole2 ; movw
653 [(set (match_operand:QI 0 "even_register_operand" "")
654 (match_operand:QI 1 "even_register_operand" ""))
655 (set (match_operand:QI 2 "odd_register_operand" "")
656 (match_operand:QI 3 "odd_register_operand" ""))]
658 && REGNO (operands[0]) == REGNO (operands[2]) - 1
659 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
660 [(set (match_dup 4) (match_dup 5))]
662 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
663 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
666 (define_peephole2 ; movw_r
667 [(set (match_operand:QI 0 "odd_register_operand" "")
668 (match_operand:QI 1 "odd_register_operand" ""))
669 (set (match_operand:QI 2 "even_register_operand" "")
670 (match_operand:QI 3 "even_register_operand" ""))]
672 && REGNO (operands[2]) == REGNO (operands[0]) - 1
673 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
674 [(set (match_dup 4) (match_dup 5))]
676 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
677 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
680 ;; For LPM loads from AS1 we split
684 ;; Z = Z - sizeof (R)
686 ;; so that the second instruction can be optimized out.
688 (define_split ; "split-lpmx"
689 [(set (match_operand:HISI 0 "register_operand" "")
690 (match_operand:HISI 1 "memory_operand" ""))]
696 (plus:HI (match_dup 3)
699 rtx addr = XEXP (operands[1], 0);
701 if (!avr_mem_flash_p (operands[1])
703 || reg_overlap_mentioned_p (addr, operands[0]))
708 operands[2] = replace_equiv_address (operands[1],
709 gen_rtx_POST_INC (Pmode, addr));
711 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
714 ;;==========================================================================
715 ;; xpointer move (24 bit)
717 (define_peephole2 ; *reload_inpsi
718 [(match_scratch:QI 2 "d")
719 (set (match_operand:PSI 0 "l_register_operand" "")
720 (match_operand:PSI 1 "immediate_operand" ""))
722 "operands[1] != const0_rtx
723 && operands[1] != constm1_rtx"
724 [(parallel [(set (match_dup 0)
726 (clobber (match_dup 2))])]
729 ;; '*' because it is not used in rtl generation.
730 (define_insn "*reload_inpsi"
731 [(set (match_operand:PSI 0 "register_operand" "=r")
732 (match_operand:PSI 1 "immediate_operand" "i"))
733 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
736 return avr_out_reload_inpsi (operands, operands[2], NULL);
738 [(set_attr "length" "6")
739 (set_attr "adjust_len" "reload_in24")
740 (set_attr "cc" "clobber")])
742 (define_insn "*movpsi"
743 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
744 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
745 "register_operand (operands[0], PSImode)
746 || register_operand (operands[1], PSImode)
747 || const0_rtx == operands[1]"
749 return avr_out_movpsi (insn, operands, NULL);
751 [(set_attr "length" "3,3,8,9,4,10")
752 (set_attr "adjust_len" "mov24")
753 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
755 ;;==========================================================================
756 ;; move double word (32 bit)
758 (define_peephole2 ; *reload_insi
759 [(match_scratch:QI 2 "d")
760 (set (match_operand:SI 0 "l_register_operand" "")
761 (match_operand:SI 1 "const_int_operand" ""))
763 "(operands[1] != const0_rtx
764 && operands[1] != constm1_rtx)"
765 [(parallel [(set (match_dup 0) (match_dup 1))
766 (clobber (match_dup 2))])]
769 ;; '*' because it is not used in rtl generation.
770 (define_insn "*reload_insi"
771 [(set (match_operand:SI 0 "register_operand" "=r")
772 (match_operand:SI 1 "const_int_operand" "n"))
773 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
776 return output_reload_insisf (operands, operands[2], NULL);
778 [(set_attr "length" "8")
779 (set_attr "adjust_len" "reload_in32")
780 (set_attr "cc" "clobber")])
783 (define_insn "*movsi"
784 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
785 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
786 "register_operand (operands[0], SImode)
787 || register_operand (operands[1], SImode)
788 || const0_rtx == operands[1]"
790 return output_movsisf (insn, operands, NULL);
792 [(set_attr "length" "4,4,8,9,4,10")
793 (set_attr "adjust_len" "mov32")
794 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
796 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
797 ;; move floating point numbers (32 bit)
799 (define_insn "*movsf"
800 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
801 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
802 "register_operand (operands[0], SFmode)
803 || register_operand (operands[1], SFmode)
804 || operands[1] == CONST0_RTX (SFmode)"
806 return output_movsisf (insn, operands, NULL);
808 [(set_attr "length" "4,4,8,9,4,10")
809 (set_attr "adjust_len" "mov32")
810 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
812 (define_peephole2 ; *reload_insf
813 [(match_scratch:QI 2 "d")
814 (set (match_operand:SF 0 "l_register_operand" "")
815 (match_operand:SF 1 "const_double_operand" ""))
817 "operands[1] != CONST0_RTX (SFmode)"
818 [(parallel [(set (match_dup 0)
820 (clobber (match_dup 2))])]
823 ;; '*' because it is not used in rtl generation.
824 (define_insn "*reload_insf"
825 [(set (match_operand:SF 0 "register_operand" "=r")
826 (match_operand:SF 1 "const_double_operand" "F"))
827 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
830 return output_reload_insisf (operands, operands[2], NULL);
832 [(set_attr "length" "8")
833 (set_attr "adjust_len" "reload_in32")
834 (set_attr "cc" "clobber")])
836 ;;=========================================================================
837 ;; move string (like memcpy)
839 (define_expand "movmemhi"
840 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
841 (match_operand:BLK 1 "memory_operand" ""))
842 (use (match_operand:HI 2 "const_int_operand" ""))
843 (use (match_operand:HI 3 "const_int_operand" ""))])]
846 if (avr_emit_movmemhi (operands))
852 (define_mode_attr MOVMEM_r_d [(QI "r")
855 ;; $0 : Address Space
856 ;; $1, $2 : Loop register
857 ;; R30 : source address
858 ;; R26 : destination address
862 (define_insn "movmem_<mode>"
863 [(set (mem:BLK (reg:HI REG_X))
864 (mem:BLK (reg:HI REG_Z)))
865 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
867 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
868 (clobber (reg:HI REG_X))
869 (clobber (reg:HI REG_Z))
870 (clobber (reg:QI LPM_REGNO))
871 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
874 return avr_out_movmem (insn, operands, NULL);
876 [(set_attr "adjust_len" "movmem")
877 (set_attr "cc" "clobber")])
880 ;; $0 : Address Space
881 ;; $1 : RAMPZ RAM address
882 ;; R24 : #bytes and loop register
883 ;; R23:Z : 24-bit source address
884 ;; R26 : 16-bit destination address
888 (define_insn "movmemx_<mode>"
889 [(set (mem:BLK (reg:HI REG_X))
890 (mem:BLK (lo_sum:PSI (reg:QI 23)
892 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
895 (clobber (reg:HI REG_X))
896 (clobber (reg:HI REG_Z))
897 (clobber (reg:QI LPM_REGNO))
898 (clobber (reg:HI 24))
899 (clobber (reg:QI 23))
900 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
902 "%~call __movmemx_<mode>"
903 [(set_attr "type" "xcall")
904 (set_attr "cc" "clobber")])
907 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
908 ;; memset (%0, %2, %1)
910 (define_expand "setmemhi"
911 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
912 (match_operand 2 "const_int_operand" ""))
913 (use (match_operand:HI 1 "const_int_operand" ""))
914 (use (match_operand:HI 3 "const_int_operand" ""))
915 (clobber (match_scratch:HI 4 ""))
916 (clobber (match_dup 5))])]
920 enum machine_mode mode;
922 /* If value to set is not zero, use the library routine. */
923 if (operands[2] != const0_rtx)
926 if (!CONST_INT_P (operands[1]))
929 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
930 operands[5] = gen_rtx_SCRATCH (mode);
931 operands[1] = copy_to_mode_reg (mode,
932 gen_int_mode (INTVAL (operands[1]), mode));
933 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
934 operands[0] = gen_rtx_MEM (BLKmode, addr0);
938 (define_insn "*clrmemqi"
939 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
941 (use (match_operand:QI 1 "register_operand" "r"))
942 (use (match_operand:QI 2 "const_int_operand" "n"))
943 (clobber (match_scratch:HI 3 "=0"))
944 (clobber (match_scratch:QI 4 "=&1"))]
946 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
947 [(set_attr "length" "3")
948 (set_attr "cc" "clobber")])
951 (define_insn "*clrmemhi"
952 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
954 (use (match_operand:HI 1 "register_operand" "!w,d"))
955 (use (match_operand:HI 2 "const_int_operand" "n,n"))
956 (clobber (match_scratch:HI 3 "=0,0"))
957 (clobber (match_scratch:HI 4 "=&1,&1"))]
960 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
961 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
962 [(set_attr "length" "3,4")
963 (set_attr "cc" "clobber,clobber")])
965 (define_expand "strlenhi"
967 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
968 (match_operand:QI 2 "const_int_operand" "")
969 (match_operand:HI 3 "immediate_operand" "")]
972 (plus:HI (match_dup 4)
974 (set (match_operand:HI 0 "register_operand" "")
975 (minus:HI (match_dup 4)
980 if (operands[2] != const0_rtx)
982 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
983 operands[1] = gen_rtx_MEM (BLKmode, addr);
985 operands[4] = gen_reg_rtx (HImode);
988 (define_insn "*strlenhi"
989 [(set (match_operand:HI 0 "register_operand" "=e")
990 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
992 (match_operand:HI 2 "immediate_operand" "i")]
995 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
996 [(set_attr "length" "3")
997 (set_attr "cc" "clobber")])
999 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1002 (define_insn "addqi3"
1003 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
1004 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
1005 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1014 [(set_attr "length" "1,1,1,1,2,2")
1015 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1018 (define_expand "addhi3"
1019 [(set (match_operand:HI 0 "register_operand" "")
1020 (plus:HI (match_operand:HI 1 "register_operand" "")
1021 (match_operand:HI 2 "nonmemory_operand" "")))]
1024 if (CONST_INT_P (operands[2]))
1026 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1028 if (can_create_pseudo_p()
1029 && !stack_register_operand (operands[0], HImode)
1030 && !stack_register_operand (operands[1], HImode)
1031 && !d_register_operand (operands[0], HImode)
1032 && !d_register_operand (operands[1], HImode))
1034 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1041 (define_insn "*addhi3_zero_extend"
1042 [(set (match_operand:HI 0 "register_operand" "=r")
1043 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1044 (match_operand:HI 2 "register_operand" "0")))]
1046 "add %A0,%1\;adc %B0,__zero_reg__"
1047 [(set_attr "length" "2")
1048 (set_attr "cc" "set_n")])
1050 (define_insn "*addhi3_zero_extend1"
1051 [(set (match_operand:HI 0 "register_operand" "=r")
1052 (plus:HI (match_operand:HI 1 "register_operand" "0")
1053 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1055 "add %A0,%2\;adc %B0,__zero_reg__"
1056 [(set_attr "length" "2")
1057 (set_attr "cc" "set_n")])
1059 (define_insn "*addhi3.sign_extend1"
1060 [(set (match_operand:HI 0 "register_operand" "=r")
1061 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1062 (match_operand:HI 2 "register_operand" "0")))]
1065 return reg_overlap_mentioned_p (operands[0], operands[1])
1066 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1067 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1069 [(set_attr "length" "5")
1070 (set_attr "cc" "clobber")])
1072 (define_insn "*addhi3_sp"
1073 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1074 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1075 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1078 return avr_out_addto_sp (operands, NULL);
1080 [(set_attr "length" "6")
1081 (set_attr "adjust_len" "addto_sp")])
1083 (define_insn "*addhi3"
1084 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1085 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1086 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1089 static const char * const asm_code[] =
1091 "add %A0,%A2\;adc %B0,%B2",
1092 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1096 if (*asm_code[which_alternative])
1097 return asm_code[which_alternative];
1099 return avr_out_plus_noclobber (operands, NULL, NULL);
1101 [(set_attr "length" "2,2,2")
1102 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1103 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1105 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1106 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1107 ;; itself because that insn is special to reload.
1109 (define_peephole2 ; addhi3_clobber
1110 [(set (match_operand:HI 0 "d_register_operand" "")
1111 (match_operand:HI 1 "const_int_operand" ""))
1112 (set (match_operand:HI 2 "l_register_operand" "")
1113 (plus:HI (match_dup 2)
1115 "peep2_reg_dead_p (2, operands[0])"
1116 [(parallel [(set (match_dup 2)
1117 (plus:HI (match_dup 2)
1119 (clobber (match_dup 3))])]
1121 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1124 ;; Same, but with reload to NO_LD_REGS
1125 ;; Combine *reload_inhi with *addhi3
1127 (define_peephole2 ; addhi3_clobber
1128 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1129 (match_operand:HI 1 "const_int_operand" ""))
1130 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1131 (set (match_operand:HI 3 "l_register_operand" "")
1132 (plus:HI (match_dup 3)
1134 "peep2_reg_dead_p (2, operands[0])"
1135 [(parallel [(set (match_dup 3)
1136 (plus:HI (match_dup 3)
1138 (clobber (match_dup 2))])])
1140 (define_insn "addhi3_clobber"
1141 [(set (match_operand:HI 0 "register_operand" "=d,l")
1142 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1143 (match_operand:HI 2 "const_int_operand" "n,n")))
1144 (clobber (match_scratch:QI 3 "=X,&d"))]
1147 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1149 return avr_out_plus (operands, NULL, NULL);
1151 [(set_attr "length" "4")
1152 (set_attr "adjust_len" "out_plus")
1153 (set_attr "cc" "out_plus")])
1156 (define_insn "addsi3"
1157 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1158 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1159 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1160 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1163 static const char * const asm_code[] =
1165 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1166 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1171 if (*asm_code[which_alternative])
1172 return asm_code[which_alternative];
1174 return avr_out_plus (operands, NULL, NULL);
1176 [(set_attr "length" "4,4,4,8")
1177 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1178 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1180 (define_insn "*addpsi3_zero_extend.qi"
1181 [(set (match_operand:PSI 0 "register_operand" "=r")
1182 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1183 (match_operand:PSI 2 "register_operand" "0")))]
1185 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1186 [(set_attr "length" "3")
1187 (set_attr "cc" "set_n")])
1189 (define_insn "*addpsi3_zero_extend.hi"
1190 [(set (match_operand:PSI 0 "register_operand" "=r")
1191 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1192 (match_operand:PSI 2 "register_operand" "0")))]
1194 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1195 [(set_attr "length" "3")
1196 (set_attr "cc" "set_n")])
1198 (define_insn "*addpsi3_sign_extend.hi"
1199 [(set (match_operand:PSI 0 "register_operand" "=r")
1200 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1201 (match_operand:PSI 2 "register_operand" "0")))]
1203 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1204 [(set_attr "length" "5")
1205 (set_attr "cc" "set_n")])
1207 (define_insn "*addsi3_zero_extend"
1208 [(set (match_operand:SI 0 "register_operand" "=r")
1209 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1210 (match_operand:SI 2 "register_operand" "0")))]
1212 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1213 [(set_attr "length" "4")
1214 (set_attr "cc" "set_n")])
1216 (define_insn "*addsi3_zero_extend.hi"
1217 [(set (match_operand:SI 0 "register_operand" "=r")
1218 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1219 (match_operand:SI 2 "register_operand" "0")))]
1221 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1222 [(set_attr "length" "4")
1223 (set_attr "cc" "set_n")])
1225 (define_insn "addpsi3"
1226 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1227 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1228 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1229 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1232 static const char * const asm_code[] =
1234 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1235 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1240 if (*asm_code[which_alternative])
1241 return asm_code[which_alternative];
1243 return avr_out_plus (operands, NULL, NULL);
1245 [(set_attr "length" "3,3,3,6")
1246 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1247 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1249 (define_insn "subpsi3"
1250 [(set (match_operand:PSI 0 "register_operand" "=r")
1251 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1252 (match_operand:PSI 2 "register_operand" "r")))]
1254 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1255 [(set_attr "length" "3")
1256 (set_attr "cc" "set_czn")])
1258 (define_insn "*subpsi3_zero_extend.qi"
1259 [(set (match_operand:PSI 0 "register_operand" "=r")
1260 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1261 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1263 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1264 [(set_attr "length" "3")
1265 (set_attr "cc" "set_czn")])
1267 (define_insn "*subpsi3_zero_extend.hi"
1268 [(set (match_operand:PSI 0 "register_operand" "=r")
1269 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1270 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1272 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1273 [(set_attr "length" "3")
1274 (set_attr "cc" "set_czn")])
1276 (define_insn "*subpsi3_sign_extend.hi"
1277 [(set (match_operand:PSI 0 "register_operand" "=r")
1278 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1279 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1281 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1282 [(set_attr "length" "5")
1283 (set_attr "cc" "set_czn")])
1285 ;-----------------------------------------------------------------------------
1287 (define_insn "subqi3"
1288 [(set (match_operand:QI 0 "register_operand" "=r,d")
1289 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1290 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1295 [(set_attr "length" "1,1")
1296 (set_attr "cc" "set_czn,set_czn")])
1298 (define_insn "subhi3"
1299 [(set (match_operand:HI 0 "register_operand" "=r,d")
1300 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1301 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1304 sub %A0,%A2\;sbc %B0,%B2
1305 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1306 [(set_attr "length" "2,2")
1307 (set_attr "cc" "set_czn,set_czn")])
1309 (define_insn "*subhi3_zero_extend1"
1310 [(set (match_operand:HI 0 "register_operand" "=r")
1311 (minus:HI (match_operand:HI 1 "register_operand" "0")
1312 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1314 "sub %A0,%2\;sbc %B0,__zero_reg__"
1315 [(set_attr "length" "2")
1316 (set_attr "cc" "set_czn")])
1318 (define_insn "*subhi3.sign_extend2"
1319 [(set (match_operand:HI 0 "register_operand" "=r")
1320 (minus:HI (match_operand:HI 1 "register_operand" "0")
1321 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1324 return reg_overlap_mentioned_p (operands[0], operands[2])
1325 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1326 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1328 [(set_attr "length" "5")
1329 (set_attr "cc" "clobber")])
1331 (define_insn "subsi3"
1332 [(set (match_operand:SI 0 "register_operand" "=r")
1333 (minus:SI (match_operand:SI 1 "register_operand" "0")
1334 (match_operand:SI 2 "register_operand" "r")))]
1336 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1337 [(set_attr "length" "4")
1338 (set_attr "cc" "set_czn")])
1340 (define_insn "*subsi3_zero_extend"
1341 [(set (match_operand:SI 0 "register_operand" "=r")
1342 (minus:SI (match_operand:SI 1 "register_operand" "0")
1343 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1345 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1346 [(set_attr "length" "4")
1347 (set_attr "cc" "set_czn")])
1349 (define_insn "*subsi3_zero_extend.hi"
1350 [(set (match_operand:SI 0 "register_operand" "=r")
1351 (minus:SI (match_operand:SI 1 "register_operand" "0")
1352 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1354 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1355 [(set_attr "length" "4")
1356 (set_attr "cc" "set_czn")])
1358 ;******************************************************************************
1361 (define_expand "mulqi3"
1362 [(set (match_operand:QI 0 "register_operand" "")
1363 (mult:QI (match_operand:QI 1 "register_operand" "")
1364 (match_operand:QI 2 "register_operand" "")))]
1369 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1374 (define_insn "*mulqi3_enh"
1375 [(set (match_operand:QI 0 "register_operand" "=r")
1376 (mult:QI (match_operand:QI 1 "register_operand" "r")
1377 (match_operand:QI 2 "register_operand" "r")))]
1382 [(set_attr "length" "3")
1383 (set_attr "cc" "clobber")])
1385 (define_expand "mulqi3_call"
1386 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1387 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1388 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1389 (clobber (reg:QI 22))])
1390 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1394 (define_insn "*mulqi3_call"
1395 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1396 (clobber (reg:QI 22))]
1399 [(set_attr "type" "xcall")
1400 (set_attr "cc" "clobber")])
1402 ;; "umulqi3_highpart"
1403 ;; "smulqi3_highpart"
1404 (define_insn "<extend_su>mulqi3_highpart"
1405 [(set (match_operand:QI 0 "register_operand" "=r")
1407 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1408 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1411 "mul<extend_s> %1,%2
1414 [(set_attr "length" "3")
1415 (set_attr "cc" "clobber")])
1418 ;; Used when expanding div or mod inline for some special values
1419 (define_insn "*subqi3.ashiftrt7"
1420 [(set (match_operand:QI 0 "register_operand" "=r")
1421 (minus:QI (match_operand:QI 1 "register_operand" "0")
1422 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1426 [(set_attr "length" "2")
1427 (set_attr "cc" "clobber")])
1429 (define_insn "*addqi3.lt0"
1430 [(set (match_operand:QI 0 "register_operand" "=r")
1431 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1433 (match_operand:QI 2 "register_operand" "0")))]
1436 [(set_attr "length" "2")
1437 (set_attr "cc" "clobber")])
1439 (define_insn "*addhi3.lt0"
1440 [(set (match_operand:HI 0 "register_operand" "=w,r")
1441 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1443 (match_operand:HI 2 "register_operand" "0,0")))
1444 (clobber (match_scratch:QI 3 "=X,&1"))]
1447 sbrc %1,7\;adiw %0,1
1448 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1449 [(set_attr "length" "2,3")
1450 (set_attr "cc" "clobber")])
1452 (define_insn "*addpsi3.lt0"
1453 [(set (match_operand:PSI 0 "register_operand" "=r")
1454 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1456 (match_operand:PSI 2 "register_operand" "0")))]
1458 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1459 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1460 [(set_attr "length" "5")
1461 (set_attr "cc" "clobber")])
1463 (define_insn "*addsi3.lt0"
1464 [(set (match_operand:SI 0 "register_operand" "=r")
1465 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1467 (match_operand:SI 2 "register_operand" "0")))]
1469 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1470 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1471 [(set_attr "length" "6")
1472 (set_attr "cc" "clobber")])
1477 (define_insn "<extend_u>mulqihi3"
1478 [(set (match_operand:HI 0 "register_operand" "=r")
1479 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1480 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1482 "mul<extend_s> %1,%2
1485 [(set_attr "length" "3")
1486 (set_attr "cc" "clobber")])
1488 (define_insn "usmulqihi3"
1489 [(set (match_operand:HI 0 "register_operand" "=r")
1490 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1491 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1496 [(set_attr "length" "3")
1497 (set_attr "cc" "clobber")])
1499 ;; Above insn is not canonicalized by insn combine, so here is a version with
1500 ;; operands swapped.
1502 (define_insn "*sumulqihi3"
1503 [(set (match_operand:HI 0 "register_operand" "=r")
1504 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1505 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1510 [(set_attr "length" "3")
1511 (set_attr "cc" "clobber")])
1513 ;; One-extend operand 1
1515 (define_insn "*osmulqihi3"
1516 [(set (match_operand:HI 0 "register_operand" "=&r")
1517 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1518 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1524 [(set_attr "length" "4")
1525 (set_attr "cc" "clobber")])
1527 (define_insn "*oumulqihi3"
1528 [(set (match_operand:HI 0 "register_operand" "=&r")
1529 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1530 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1536 [(set_attr "length" "4")
1537 (set_attr "cc" "clobber")])
1539 ;******************************************************************************
1540 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1541 ;******************************************************************************
1543 (define_insn "*maddqi4"
1544 [(set (match_operand:QI 0 "register_operand" "=r")
1545 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1546 (match_operand:QI 2 "register_operand" "r"))
1547 (match_operand:QI 3 "register_operand" "0")))]
1553 [(set_attr "length" "4")
1554 (set_attr "cc" "clobber")])
1556 (define_insn "*msubqi4"
1557 [(set (match_operand:QI 0 "register_operand" "=r")
1558 (minus:QI (match_operand:QI 3 "register_operand" "0")
1559 (mult:QI (match_operand:QI 1 "register_operand" "r")
1560 (match_operand:QI 2 "register_operand" "r"))))]
1565 [(set_attr "length" "4")
1566 (set_attr "cc" "clobber")])
1568 (define_insn_and_split "*maddqi4.const"
1569 [(set (match_operand:QI 0 "register_operand" "=r")
1570 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1571 (match_operand:QI 2 "const_int_operand" "n"))
1572 (match_operand:QI 3 "register_operand" "0")))
1573 (clobber (match_scratch:QI 4 "=&d"))]
1576 "&& reload_completed"
1581 (plus:QI (mult:QI (match_dup 1)
1586 (define_insn_and_split "*msubqi4.const"
1587 [(set (match_operand:QI 0 "register_operand" "=r")
1588 (minus:QI (match_operand:QI 3 "register_operand" "0")
1589 (mult:QI (match_operand:QI 1 "register_operand" "r")
1590 (match_operand:QI 2 "const_int_operand" "n"))))
1591 (clobber (match_scratch:QI 4 "=&d"))]
1594 "&& reload_completed"
1599 (minus:QI (match_dup 3)
1600 (mult:QI (match_dup 1)
1605 ;******************************************************************************
1606 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1607 ;******************************************************************************
1609 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1612 ;; int foo (unsigned char z)
1614 ;; extern int aInt[];
1615 ;; return aInt[3*z+2];
1618 ;; because the constant +4 then is added explicitely instead of consuming it
1619 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1620 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1621 ;; The implementational effort is the same so we are fine with that approach.
1626 (define_insn "*<extend_u>maddqihi4"
1627 [(set (match_operand:HI 0 "register_operand" "=r")
1628 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1629 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1630 (match_operand:HI 3 "register_operand" "0")))]
1633 "mul<extend_s> %1,%2
1637 [(set_attr "length" "4")
1638 (set_attr "cc" "clobber")])
1642 (define_insn "*<extend_u>msubqihi4"
1643 [(set (match_operand:HI 0 "register_operand" "=r")
1644 (minus:HI (match_operand:HI 3 "register_operand" "0")
1645 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1646 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1648 "mul<extend_s> %1,%2
1652 [(set_attr "length" "4")
1653 (set_attr "cc" "clobber")])
1657 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1658 [(set (match_operand:HI 0 "register_operand" "=r")
1659 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1660 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1661 (match_operand:HI 3 "register_operand" "0")))]
1664 && <any_extend:CODE> != <any_extend2:CODE>"
1666 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1667 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1669 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1671 [(set_attr "length" "4")
1672 (set_attr "cc" "clobber")])
1676 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1677 [(set (match_operand:HI 0 "register_operand" "=r")
1678 (minus:HI (match_operand:HI 3 "register_operand" "0")
1679 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1680 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1683 && <any_extend:CODE> != <any_extend2:CODE>"
1685 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1686 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1688 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1690 [(set_attr "length" "4")
1691 (set_attr "cc" "clobber")])
1693 ;; Handle small constants
1695 ;; "umaddqihi4.uconst"
1696 ;; "maddqihi4.sconst"
1697 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1698 [(set (match_operand:HI 0 "register_operand" "=r")
1699 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1700 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1701 (match_operand:HI 3 "register_operand" "0")))
1702 (clobber (match_scratch:QI 4 "=&d"))]
1705 "&& reload_completed"
1708 ; *umaddqihi4 resp. *maddqihi4
1710 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1711 (any_extend:HI (match_dup 4)))
1714 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1717 ;; "*umsubqihi4.uconst"
1718 ;; "*msubqihi4.sconst"
1719 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1720 [(set (match_operand:HI 0 "register_operand" "=r")
1721 (minus:HI (match_operand:HI 3 "register_operand" "0")
1722 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1723 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1724 (clobber (match_scratch:QI 4 "=&d"))]
1727 "&& reload_completed"
1730 ; *umsubqihi4 resp. *msubqihi4
1732 (minus:HI (match_dup 3)
1733 (mult:HI (any_extend:HI (match_dup 1))
1734 (any_extend:HI (match_dup 4)))))]
1736 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1739 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1740 ;; for MULT with power of 2 and skips trying MULT insn above.
1742 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1743 [(set (match_operand:HI 0 "register_operand" "=r")
1744 (minus:HI (match_operand:HI 3 "register_operand" "0")
1745 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1746 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1747 (clobber (match_scratch:QI 4 "=&d"))]
1750 "&& reload_completed"
1755 (minus:HI (match_dup 3)
1756 (mult:HI (zero_extend:HI (match_dup 1))
1757 (zero_extend:HI (match_dup 4)))))]
1759 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1762 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1763 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1764 ;; because this would require an extra pattern for just one value.
1766 (define_insn_and_split "*msubqihi4.sconst.ashift"
1767 [(set (match_operand:HI 0 "register_operand" "=r")
1768 (minus:HI (match_operand:HI 3 "register_operand" "0")
1769 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1770 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1771 (clobber (match_scratch:QI 4 "=&d"))]
1774 "&& reload_completed"
1779 (minus:HI (match_dup 3)
1780 (mult:HI (sign_extend:HI (match_dup 1))
1781 (sign_extend:HI (match_dup 4)))))]
1783 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1786 ;; For signed/unsigned combinations that require narrow constraint "a"
1787 ;; just provide a pattern if signed/unsigned combination is actually needed.
1789 (define_insn_and_split "*sumaddqihi4.uconst"
1790 [(set (match_operand:HI 0 "register_operand" "=r")
1791 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1792 (match_operand:HI 2 "u8_operand" "M"))
1793 (match_operand:HI 3 "register_operand" "0")))
1794 (clobber (match_scratch:QI 4 "=&a"))]
1796 && !s8_operand (operands[2], VOIDmode)"
1798 "&& reload_completed"
1803 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1804 (zero_extend:HI (match_dup 4)))
1807 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1810 (define_insn_and_split "*sumsubqihi4.uconst"
1811 [(set (match_operand:HI 0 "register_operand" "=r")
1812 (minus:HI (match_operand:HI 3 "register_operand" "0")
1813 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1814 (match_operand:HI 2 "u8_operand" "M"))))
1815 (clobber (match_scratch:QI 4 "=&a"))]
1817 && !s8_operand (operands[2], VOIDmode)"
1819 "&& reload_completed"
1824 (minus:HI (match_dup 3)
1825 (mult:HI (sign_extend:HI (match_dup 1))
1826 (zero_extend:HI (match_dup 4)))))]
1828 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1831 ;******************************************************************************
1832 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1833 ;******************************************************************************
1835 ;; "*muluqihi3.uconst"
1836 ;; "*mulsqihi3.sconst"
1837 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1838 [(set (match_operand:HI 0 "register_operand" "=r")
1839 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1840 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1841 (clobber (match_scratch:QI 3 "=&d"))]
1844 "&& reload_completed"
1847 ; umulqihi3 resp. mulqihi3
1849 (mult:HI (any_extend:HI (match_dup 1))
1850 (any_extend:HI (match_dup 3))))]
1852 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1855 (define_insn_and_split "*muluqihi3.sconst"
1856 [(set (match_operand:HI 0 "register_operand" "=r")
1857 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1858 (match_operand:HI 2 "s8_operand" "n")))
1859 (clobber (match_scratch:QI 3 "=&a"))]
1862 "&& reload_completed"
1867 (mult:HI (zero_extend:HI (match_dup 1))
1868 (sign_extend:HI (match_dup 3))))]
1870 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1873 (define_insn_and_split "*mulsqihi3.uconst"
1874 [(set (match_operand:HI 0 "register_operand" "=r")
1875 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1876 (match_operand:HI 2 "u8_operand" "M")))
1877 (clobber (match_scratch:QI 3 "=&a"))]
1880 "&& reload_completed"
1885 (mult:HI (zero_extend:HI (match_dup 3))
1886 (sign_extend:HI (match_dup 1))))]
1888 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1891 (define_insn_and_split "*mulsqihi3.oconst"
1892 [(set (match_operand:HI 0 "register_operand" "=&r")
1893 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1894 (match_operand:HI 2 "o8_operand" "n")))
1895 (clobber (match_scratch:QI 3 "=&a"))]
1898 "&& reload_completed"
1903 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1904 (sign_extend:HI (match_dup 1))))]
1906 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1909 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1910 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1911 ;; at that time. Fix that.
1913 (define_insn "*ashiftqihi2.signx.1"
1914 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1915 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1919 lsl %A0\;sbc %B0,%B0
1920 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1921 [(set_attr "length" "2,3")
1922 (set_attr "cc" "clobber")])
1924 (define_insn_and_split "*ashifthi3.signx.const"
1925 [(set (match_operand:HI 0 "register_operand" "=r")
1926 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1927 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1928 (clobber (match_scratch:QI 3 "=&d"))]
1931 "&& reload_completed"
1936 (mult:HI (sign_extend:HI (match_dup 1))
1937 (sign_extend:HI (match_dup 3))))]
1939 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1942 (define_insn_and_split "*ashifthi3.signx.const7"
1943 [(set (match_operand:HI 0 "register_operand" "=r")
1944 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1946 (clobber (match_scratch:QI 2 "=&a"))]
1949 "&& reload_completed"
1954 (mult:HI (zero_extend:HI (match_dup 2))
1955 (sign_extend:HI (match_dup 1))))]
1957 operands[3] = gen_int_mode (1 << 7, QImode);
1960 (define_insn_and_split "*ashifthi3.zerox.const"
1961 [(set (match_operand:HI 0 "register_operand" "=r")
1962 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1963 (match_operand:HI 2 "const_2_to_7_operand" "I")))
1964 (clobber (match_scratch:QI 3 "=&d"))]
1967 "&& reload_completed"
1972 (mult:HI (zero_extend:HI (match_dup 1))
1973 (zero_extend:HI (match_dup 3))))]
1975 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1978 ;******************************************************************************
1979 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
1980 ;******************************************************************************
1982 (define_insn "mulsqihi3"
1983 [(set (match_operand:HI 0 "register_operand" "=&r")
1984 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1985 (match_operand:HI 2 "register_operand" "a")))]
1992 [(set_attr "length" "5")
1993 (set_attr "cc" "clobber")])
1995 (define_insn "muluqihi3"
1996 [(set (match_operand:HI 0 "register_operand" "=&r")
1997 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1998 (match_operand:HI 2 "register_operand" "r")))]
2005 [(set_attr "length" "5")
2006 (set_attr "cc" "clobber")])
2008 ;; one-extend operand 1
2010 (define_insn "muloqihi3"
2011 [(set (match_operand:HI 0 "register_operand" "=&r")
2012 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2013 (match_operand:HI 2 "register_operand" "r")))]
2021 [(set_attr "length" "6")
2022 (set_attr "cc" "clobber")])
2024 ;******************************************************************************
2026 (define_expand "mulhi3"
2027 [(set (match_operand:HI 0 "register_operand" "")
2028 (mult:HI (match_operand:HI 1 "register_operand" "")
2029 (match_operand:HI 2 "register_or_s9_operand" "")))]
2034 if (!register_operand (operands[2], HImode))
2035 operands[2] = force_reg (HImode, operands[2]);
2037 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2041 /* For small constants we can do better by extending them on the fly.
2042 The constant can be loaded in one instruction and the widening
2043 multiplication is shorter. First try the unsigned variant because it
2044 allows constraint "d" instead of "a" for the signed version. */
2046 if (s9_operand (operands[2], HImode))
2048 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2050 if (u8_operand (operands[2], HImode))
2052 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2054 else if (s8_operand (operands[2], HImode))
2056 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2060 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2066 if (!register_operand (operands[2], HImode))
2067 operands[2] = force_reg (HImode, operands[2]);
2070 (define_insn "*mulhi3_enh"
2071 [(set (match_operand:HI 0 "register_operand" "=&r")
2072 (mult:HI (match_operand:HI 1 "register_operand" "r")
2073 (match_operand:HI 2 "register_operand" "r")))]
2076 return REGNO (operands[1]) == REGNO (operands[2])
2077 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2078 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2080 [(set_attr "length" "7")
2081 (set_attr "cc" "clobber")])
2083 (define_expand "mulhi3_call"
2084 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2085 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2086 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2087 (clobber (reg:HI 22))
2088 (clobber (reg:QI 21))])
2089 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2093 (define_insn "*mulhi3_call"
2094 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2095 (clobber (reg:HI 22))
2096 (clobber (reg:QI 21))]
2099 [(set_attr "type" "xcall")
2100 (set_attr "cc" "clobber")])
2102 ;; To support widening multiplication with constant we postpone
2103 ;; expanding to the implicit library call until post combine and
2104 ;; prior to register allocation. Clobber all hard registers that
2105 ;; might be used by the (widening) multiply until it is split and
2106 ;; it's final register footprint is worked out.
2108 (define_expand "mulsi3"
2109 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2110 (mult:SI (match_operand:SI 1 "register_operand" "")
2111 (match_operand:SI 2 "nonmemory_operand" "")))
2112 (clobber (reg:HI 26))
2113 (clobber (reg:DI 18))])]
2116 if (u16_operand (operands[2], SImode))
2118 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2119 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2123 if (o16_operand (operands[2], SImode))
2125 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2126 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2131 (define_insn_and_split "*mulsi3"
2132 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2133 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2134 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2135 (clobber (reg:HI 26))
2136 (clobber (reg:DI 18))]
2137 "AVR_HAVE_MUL && !reload_completed"
2138 { gcc_unreachable(); }
2144 (parallel [(set (reg:SI 22)
2145 (mult:SI (reg:SI 22)
2147 (clobber (reg:HI 26))])
2151 if (u16_operand (operands[2], SImode))
2153 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2154 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2158 if (o16_operand (operands[2], SImode))
2160 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2161 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2168 (define_insn_and_split "mulu<mode>si3"
2169 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2170 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2171 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2172 (clobber (reg:HI 26))
2173 (clobber (reg:DI 18))]
2174 "AVR_HAVE_MUL && !reload_completed"
2175 { gcc_unreachable(); }
2182 (mult:SI (zero_extend:SI (reg:HI 26))
2187 /* Do the QI -> HI extension explicitely before the multiplication. */
2188 /* Do the HI -> SI extension implicitely and after the multiplication. */
2190 if (QImode == <MODE>mode)
2191 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2193 if (u16_operand (operands[2], SImode))
2195 operands[1] = force_reg (HImode, operands[1]);
2196 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2197 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2204 (define_insn_and_split "muls<mode>si3"
2205 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2206 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2207 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2208 (clobber (reg:HI 26))
2209 (clobber (reg:DI 18))]
2210 "AVR_HAVE_MUL && !reload_completed"
2211 { gcc_unreachable(); }
2218 (mult:SI (sign_extend:SI (reg:HI 26))
2223 /* Do the QI -> HI extension explicitely before the multiplication. */
2224 /* Do the HI -> SI extension implicitely and after the multiplication. */
2226 if (QImode == <MODE>mode)
2227 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2229 if (u16_operand (operands[2], SImode)
2230 || s16_operand (operands[2], SImode))
2232 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2234 operands[1] = force_reg (HImode, operands[1]);
2236 if (u16_operand (operands[2], SImode))
2237 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2239 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2245 ;; One-extend operand 1
2247 (define_insn_and_split "mulohisi3"
2248 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2249 (mult:SI (not:SI (zero_extend:SI
2250 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2251 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2252 (clobber (reg:HI 26))
2253 (clobber (reg:DI 18))]
2254 "AVR_HAVE_MUL && !reload_completed"
2255 { gcc_unreachable(); }
2262 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2270 (define_expand "<extend_u>mulhisi3"
2271 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2272 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2273 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2274 (clobber (reg:HI 26))
2275 (clobber (reg:DI 18))])]
2279 (define_expand "usmulhisi3"
2280 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2281 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2282 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2283 (clobber (reg:HI 26))
2284 (clobber (reg:DI 18))])]
2288 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2289 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2290 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2291 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2292 (define_insn_and_split
2293 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2294 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2295 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2296 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2297 (clobber (reg:HI 26))
2298 (clobber (reg:DI 18))]
2299 "AVR_HAVE_MUL && !reload_completed"
2300 { gcc_unreachable(); }
2307 (mult:SI (match_dup 3)
2312 rtx xop1 = operands[1];
2313 rtx xop2 = operands[2];
2315 /* Do the QI -> HI extension explicitely before the multiplication. */
2316 /* Do the HI -> SI extension implicitely and after the multiplication. */
2318 if (QImode == <QIHI:MODE>mode)
2319 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2321 if (QImode == <QIHI2:MODE>mode)
2322 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2324 if (<any_extend:CODE> == <any_extend2:CODE>
2325 || <any_extend:CODE> == ZERO_EXTEND)
2329 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2330 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2334 /* <any_extend:CODE> = SIGN_EXTEND */
2335 /* <any_extend2:CODE> = ZERO_EXTEND */
2339 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2340 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2344 ;; "smulhi3_highpart"
2345 ;; "umulhi3_highpart"
2346 (define_expand "<extend_su>mulhi3_highpart"
2348 (match_operand:HI 1 "nonmemory_operand" ""))
2350 (match_operand:HI 2 "nonmemory_operand" ""))
2351 (parallel [(set (reg:HI 24)
2352 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2353 (any_extend:SI (reg:HI 26)))
2355 (clobber (reg:HI 22))])
2356 (set (match_operand:HI 0 "register_operand" "")
2362 (define_insn "*mulsi3_call"
2364 (mult:SI (reg:SI 22)
2366 (clobber (reg:HI 26))]
2369 [(set_attr "type" "xcall")
2370 (set_attr "cc" "clobber")])
2373 ;; "*umulhisi3_call"
2374 (define_insn "*<extend_u>mulhisi3_call"
2376 (mult:SI (any_extend:SI (reg:HI 18))
2377 (any_extend:SI (reg:HI 26))))]
2379 "%~call __<extend_u>mulhisi3"
2380 [(set_attr "type" "xcall")
2381 (set_attr "cc" "clobber")])
2383 ;; "*umulhi3_highpart_call"
2384 ;; "*smulhi3_highpart_call"
2385 (define_insn "*<extend_su>mulhi3_highpart_call"
2387 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2388 (any_extend:SI (reg:HI 26)))
2390 (clobber (reg:HI 22))]
2392 "%~call __<extend_u>mulhisi3"
2393 [(set_attr "type" "xcall")
2394 (set_attr "cc" "clobber")])
2396 (define_insn "*usmulhisi3_call"
2398 (mult:SI (zero_extend:SI (reg:HI 18))
2399 (sign_extend:SI (reg:HI 26))))]
2401 "%~call __usmulhisi3"
2402 [(set_attr "type" "xcall")
2403 (set_attr "cc" "clobber")])
2405 (define_insn "*mul<extend_su>hisi3_call"
2407 (mult:SI (any_extend:SI (reg:HI 26))
2410 "%~call __mul<extend_su>hisi3"
2411 [(set_attr "type" "xcall")
2412 (set_attr "cc" "clobber")])
2414 (define_insn "*mulohisi3_call"
2416 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2419 "%~call __mulohisi3"
2420 [(set_attr "type" "xcall")
2421 (set_attr "cc" "clobber")])
2423 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2426 ;; Generate lib1funcs.S calls ourselves, because:
2427 ;; - we know exactly which registers are clobbered (for QI and HI
2428 ;; modes, some of the call-used registers are preserved)
2429 ;; - we get both the quotient and the remainder at no extra cost
2430 ;; - we split the patterns only after the first CSE passes because
2431 ;; CSE has problems to operate on hard regs.
2433 (define_insn_and_split "divmodqi4"
2434 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2435 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2436 (match_operand:QI 2 "pseudo_register_operand" "")))
2437 (set (match_operand:QI 3 "pseudo_register_operand" "")
2438 (mod:QI (match_dup 1) (match_dup 2)))
2439 (clobber (reg:QI 22))
2440 (clobber (reg:QI 23))
2441 (clobber (reg:QI 24))
2442 (clobber (reg:QI 25))])]
2444 "this divmodqi4 pattern should have been splitted;"
2446 [(set (reg:QI 24) (match_dup 1))
2447 (set (reg:QI 22) (match_dup 2))
2448 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2449 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2450 (clobber (reg:QI 22))
2451 (clobber (reg:QI 23))])
2452 (set (match_dup 0) (reg:QI 24))
2453 (set (match_dup 3) (reg:QI 25))]
2456 (define_insn "*divmodqi4_call"
2457 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2458 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2459 (clobber (reg:QI 22))
2460 (clobber (reg:QI 23))]
2462 "%~call __divmodqi4"
2463 [(set_attr "type" "xcall")
2464 (set_attr "cc" "clobber")])
2466 (define_insn_and_split "udivmodqi4"
2467 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2468 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2469 (match_operand:QI 2 "pseudo_register_operand" "")))
2470 (set (match_operand:QI 3 "pseudo_register_operand" "")
2471 (umod:QI (match_dup 1) (match_dup 2)))
2472 (clobber (reg:QI 22))
2473 (clobber (reg:QI 23))
2474 (clobber (reg:QI 24))
2475 (clobber (reg:QI 25))])]
2477 "this udivmodqi4 pattern should have been splitted;"
2479 [(set (reg:QI 24) (match_dup 1))
2480 (set (reg:QI 22) (match_dup 2))
2481 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2482 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2483 (clobber (reg:QI 23))])
2484 (set (match_dup 0) (reg:QI 24))
2485 (set (match_dup 3) (reg:QI 25))]
2488 (define_insn "*udivmodqi4_call"
2489 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2490 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2491 (clobber (reg:QI 23))]
2493 "%~call __udivmodqi4"
2494 [(set_attr "type" "xcall")
2495 (set_attr "cc" "clobber")])
2497 (define_insn_and_split "divmodhi4"
2498 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2499 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2500 (match_operand:HI 2 "pseudo_register_operand" "")))
2501 (set (match_operand:HI 3 "pseudo_register_operand" "")
2502 (mod:HI (match_dup 1) (match_dup 2)))
2503 (clobber (reg:QI 21))
2504 (clobber (reg:HI 22))
2505 (clobber (reg:HI 24))
2506 (clobber (reg:HI 26))])]
2508 "this should have been splitted;"
2510 [(set (reg:HI 24) (match_dup 1))
2511 (set (reg:HI 22) (match_dup 2))
2512 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2513 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2514 (clobber (reg:HI 26))
2515 (clobber (reg:QI 21))])
2516 (set (match_dup 0) (reg:HI 22))
2517 (set (match_dup 3) (reg:HI 24))]
2520 (define_insn "*divmodhi4_call"
2521 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2522 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2523 (clobber (reg:HI 26))
2524 (clobber (reg:QI 21))]
2526 "%~call __divmodhi4"
2527 [(set_attr "type" "xcall")
2528 (set_attr "cc" "clobber")])
2530 (define_insn_and_split "udivmodhi4"
2531 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2532 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2533 (match_operand:HI 2 "pseudo_register_operand" "")))
2534 (set (match_operand:HI 3 "pseudo_register_operand" "")
2535 (umod:HI (match_dup 1) (match_dup 2)))
2536 (clobber (reg:QI 21))
2537 (clobber (reg:HI 22))
2538 (clobber (reg:HI 24))
2539 (clobber (reg:HI 26))])]
2541 "this udivmodhi4 pattern should have been splitted.;"
2543 [(set (reg:HI 24) (match_dup 1))
2544 (set (reg:HI 22) (match_dup 2))
2545 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2546 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2547 (clobber (reg:HI 26))
2548 (clobber (reg:QI 21))])
2549 (set (match_dup 0) (reg:HI 22))
2550 (set (match_dup 3) (reg:HI 24))]
2553 (define_insn "*udivmodhi4_call"
2554 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2555 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2556 (clobber (reg:HI 26))
2557 (clobber (reg:QI 21))]
2559 "%~call __udivmodhi4"
2560 [(set_attr "type" "xcall")
2561 (set_attr "cc" "clobber")])
2563 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2566 ;; To support widening multiplication with constant we postpone
2567 ;; expanding to the implicit library call until post combine and
2568 ;; prior to register allocation. Clobber all hard registers that
2569 ;; might be used by the (widening) multiply until it is split and
2570 ;; it's final register footprint is worked out.
2572 (define_expand "mulpsi3"
2573 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2574 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2575 (match_operand:PSI 2 "nonmemory_operand" "")))
2576 (clobber (reg:HI 26))
2577 (clobber (reg:DI 18))])]
2580 if (s8_operand (operands[2], PSImode))
2582 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2583 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2588 (define_insn "*umulqihipsi3"
2589 [(set (match_operand:PSI 0 "register_operand" "=&r")
2590 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2591 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2600 [(set_attr "length" "7")
2601 (set_attr "cc" "clobber")])
2603 (define_insn "*umulhiqipsi3"
2604 [(set (match_operand:PSI 0 "register_operand" "=&r")
2605 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2606 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2614 adc %C0,__zero_reg__"
2615 [(set_attr "length" "7")
2616 (set_attr "cc" "clobber")])
2618 (define_insn_and_split "mulsqipsi3"
2619 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2620 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2621 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2622 (clobber (reg:HI 26))
2623 (clobber (reg:DI 18))]
2624 "AVR_HAVE_MUL && !reload_completed"
2625 { gcc_unreachable(); }
2632 (mult:PSI (sign_extend:PSI (reg:QI 25))
2637 (define_insn_and_split "*mulpsi3"
2638 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2639 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2640 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2641 (clobber (reg:HI 26))
2642 (clobber (reg:DI 18))]
2643 "AVR_HAVE_MUL && !reload_completed"
2644 { gcc_unreachable(); }
2650 (parallel [(set (reg:PSI 22)
2651 (mult:PSI (reg:PSI 22)
2653 (clobber (reg:QI 21))
2654 (clobber (reg:QI 25))
2655 (clobber (reg:HI 26))])
2659 if (s8_operand (operands[2], PSImode))
2661 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2662 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2667 (define_insn "*mulsqipsi3.libgcc"
2669 (mult:PSI (sign_extend:PSI (reg:QI 25))
2672 "%~call __mulsqipsi3"
2673 [(set_attr "type" "xcall")
2674 (set_attr "cc" "clobber")])
2676 (define_insn "*mulpsi3.libgcc"
2678 (mult:PSI (reg:PSI 22)
2680 (clobber (reg:QI 21))
2681 (clobber (reg:QI 25))
2682 (clobber (reg:HI 26))]
2685 [(set_attr "type" "xcall")
2686 (set_attr "cc" "clobber")])
2689 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2690 ;; 24-bit signed/unsigned division and modulo.
2691 ;; Notice that the libgcc implementation return the quotient in R22
2692 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2693 ;; implementation works the other way round.
2695 (define_insn_and_split "divmodpsi4"
2696 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2697 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2698 (match_operand:PSI 2 "pseudo_register_operand" "")))
2699 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2700 (mod:PSI (match_dup 1)
2702 (clobber (reg:DI 18))
2703 (clobber (reg:QI 26))])]
2705 { gcc_unreachable(); }
2707 [(set (reg:PSI 22) (match_dup 1))
2708 (set (reg:PSI 18) (match_dup 2))
2709 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2710 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2711 (clobber (reg:QI 21))
2712 (clobber (reg:QI 25))
2713 (clobber (reg:QI 26))])
2714 (set (match_dup 0) (reg:PSI 22))
2715 (set (match_dup 3) (reg:PSI 18))])
2717 (define_insn "*divmodpsi4_call"
2718 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2719 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2720 (clobber (reg:QI 21))
2721 (clobber (reg:QI 25))
2722 (clobber (reg:QI 26))]
2724 "%~call __divmodpsi4"
2725 [(set_attr "type" "xcall")
2726 (set_attr "cc" "clobber")])
2728 (define_insn_and_split "udivmodpsi4"
2729 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2730 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2731 (match_operand:PSI 2 "pseudo_register_operand" "")))
2732 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2733 (umod:PSI (match_dup 1)
2735 (clobber (reg:DI 18))
2736 (clobber (reg:QI 26))])]
2738 { gcc_unreachable(); }
2740 [(set (reg:PSI 22) (match_dup 1))
2741 (set (reg:PSI 18) (match_dup 2))
2742 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2743 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2744 (clobber (reg:QI 21))
2745 (clobber (reg:QI 25))
2746 (clobber (reg:QI 26))])
2747 (set (match_dup 0) (reg:PSI 22))
2748 (set (match_dup 3) (reg:PSI 18))])
2750 (define_insn "*udivmodpsi4_call"
2751 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2752 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2753 (clobber (reg:QI 21))
2754 (clobber (reg:QI 25))
2755 (clobber (reg:QI 26))]
2757 "%~call __udivmodpsi4"
2758 [(set_attr "type" "xcall")
2759 (set_attr "cc" "clobber")])
2761 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2763 (define_insn_and_split "divmodsi4"
2764 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2765 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2766 (match_operand:SI 2 "pseudo_register_operand" "")))
2767 (set (match_operand:SI 3 "pseudo_register_operand" "")
2768 (mod:SI (match_dup 1) (match_dup 2)))
2769 (clobber (reg:SI 18))
2770 (clobber (reg:SI 22))
2771 (clobber (reg:HI 26))
2772 (clobber (reg:HI 30))])]
2774 "this divmodsi4 pattern should have been splitted;"
2776 [(set (reg:SI 22) (match_dup 1))
2777 (set (reg:SI 18) (match_dup 2))
2778 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2779 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2780 (clobber (reg:HI 26))
2781 (clobber (reg:HI 30))])
2782 (set (match_dup 0) (reg:SI 18))
2783 (set (match_dup 3) (reg:SI 22))]
2786 (define_insn "*divmodsi4_call"
2787 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2788 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2789 (clobber (reg:HI 26))
2790 (clobber (reg:HI 30))]
2792 "%~call __divmodsi4"
2793 [(set_attr "type" "xcall")
2794 (set_attr "cc" "clobber")])
2796 (define_insn_and_split "udivmodsi4"
2797 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2798 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2799 (match_operand:SI 2 "pseudo_register_operand" "")))
2800 (set (match_operand:SI 3 "pseudo_register_operand" "")
2801 (umod:SI (match_dup 1) (match_dup 2)))
2802 (clobber (reg:SI 18))
2803 (clobber (reg:SI 22))
2804 (clobber (reg:HI 26))
2805 (clobber (reg:HI 30))])]
2807 "this udivmodsi4 pattern should have been splitted;"
2809 [(set (reg:SI 22) (match_dup 1))
2810 (set (reg:SI 18) (match_dup 2))
2811 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2812 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2813 (clobber (reg:HI 26))
2814 (clobber (reg:HI 30))])
2815 (set (match_dup 0) (reg:SI 18))
2816 (set (match_dup 3) (reg:SI 22))]
2819 (define_insn "*udivmodsi4_call"
2820 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2821 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2822 (clobber (reg:HI 26))
2823 (clobber (reg:HI 30))]
2825 "%~call __udivmodsi4"
2826 [(set_attr "type" "xcall")
2827 (set_attr "cc" "clobber")])
2829 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2832 (define_insn "andqi3"
2833 [(set (match_operand:QI 0 "register_operand" "=r,d")
2834 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2835 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2840 [(set_attr "length" "1,1")
2841 (set_attr "cc" "set_zn,set_zn")])
2843 (define_insn "andhi3"
2844 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2845 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2846 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2847 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2850 if (which_alternative == 0)
2851 return "and %A0,%A2\;and %B0,%B2";
2852 else if (which_alternative == 1)
2853 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2855 return avr_out_bitop (insn, operands, NULL);
2857 [(set_attr "length" "2,2,2,4,4")
2858 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2859 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2861 (define_insn "andpsi3"
2862 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2863 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2864 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2865 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2868 if (which_alternative == 0)
2869 return "and %A0,%A2" CR_TAB
2870 "and %B0,%B2" CR_TAB
2873 return avr_out_bitop (insn, operands, NULL);
2875 [(set_attr "length" "3,3,6,6")
2876 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2877 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2879 (define_insn "andsi3"
2880 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2881 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2882 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2883 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2886 if (which_alternative == 0)
2887 return "and %0,%2" CR_TAB
2888 "and %B0,%B2" CR_TAB
2889 "and %C0,%C2" CR_TAB
2892 return avr_out_bitop (insn, operands, NULL);
2894 [(set_attr "length" "4,4,8,8")
2895 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2896 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2898 (define_peephole2 ; andi
2899 [(set (match_operand:QI 0 "d_register_operand" "")
2900 (and:QI (match_dup 0)
2901 (match_operand:QI 1 "const_int_operand" "")))
2903 (and:QI (match_dup 0)
2904 (match_operand:QI 2 "const_int_operand" "")))]
2906 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2908 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2911 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2914 (define_insn "iorqi3"
2915 [(set (match_operand:QI 0 "register_operand" "=r,d")
2916 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2917 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2922 [(set_attr "length" "1,1")
2923 (set_attr "cc" "set_zn,set_zn")])
2925 (define_insn "iorhi3"
2926 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2927 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2928 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2929 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2932 if (which_alternative == 0)
2933 return "or %A0,%A2\;or %B0,%B2";
2934 else if (which_alternative == 1)
2935 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2937 return avr_out_bitop (insn, operands, NULL);
2939 [(set_attr "length" "2,2,2,4,4")
2940 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2941 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2943 (define_insn "iorpsi3"
2944 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2945 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2946 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2947 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2950 if (which_alternative == 0)
2951 return "or %A0,%A2" CR_TAB
2955 return avr_out_bitop (insn, operands, NULL);
2957 [(set_attr "length" "3,3,6,6")
2958 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2959 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2961 (define_insn "iorsi3"
2962 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2963 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2964 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
2965 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2968 if (which_alternative == 0)
2969 return "or %0,%2" CR_TAB
2974 return avr_out_bitop (insn, operands, NULL);
2976 [(set_attr "length" "4,4,8,8")
2977 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2978 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2980 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2983 (define_insn "xorqi3"
2984 [(set (match_operand:QI 0 "register_operand" "=r")
2985 (xor:QI (match_operand:QI 1 "register_operand" "%0")
2986 (match_operand:QI 2 "register_operand" "r")))]
2989 [(set_attr "length" "1")
2990 (set_attr "cc" "set_zn")])
2992 (define_insn "xorhi3"
2993 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
2994 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
2995 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
2996 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
2999 if (which_alternative == 0)
3000 return "eor %A0,%A2\;eor %B0,%B2";
3002 return avr_out_bitop (insn, operands, NULL);
3004 [(set_attr "length" "2,2,4")
3005 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3006 (set_attr "cc" "set_n,clobber,clobber")])
3008 (define_insn "xorpsi3"
3009 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3010 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3011 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3012 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3015 if (which_alternative == 0)
3016 return "eor %A0,%A2" CR_TAB
3017 "eor %B0,%B2" CR_TAB
3020 return avr_out_bitop (insn, operands, NULL);
3022 [(set_attr "length" "3,6,6")
3023 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3024 (set_attr "cc" "set_n,clobber,clobber")])
3026 (define_insn "xorsi3"
3027 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3028 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3029 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3030 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3033 if (which_alternative == 0)
3034 return "eor %0,%2" CR_TAB
3035 "eor %B0,%B2" CR_TAB
3036 "eor %C0,%C2" CR_TAB
3039 return avr_out_bitop (insn, operands, NULL);
3041 [(set_attr "length" "4,8,8")
3042 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3043 (set_attr "cc" "set_n,clobber,clobber")])
3045 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3048 (define_expand "rotlqi3"
3049 [(set (match_operand:QI 0 "register_operand" "")
3050 (rotate:QI (match_operand:QI 1 "register_operand" "")
3051 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3054 if (!CONST_INT_P (operands[2]))
3057 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3060 ;; Expander used by __builtin_avr_swap
3061 (define_expand "rotlqi3_4"
3062 [(set (match_operand:QI 0 "register_operand" "")
3063 (rotate:QI (match_operand:QI 1 "register_operand" "")
3066 (define_insn "*rotlqi3"
3067 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3068 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3069 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3072 lsl %0\;adc %0,__zero_reg__
3073 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3074 swap %0\;bst %0,0\;ror %0\;bld %0,7
3076 swap %0\;lsl %0\;adc %0,__zero_reg__
3077 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3078 bst %0,0\;ror %0\;bld %0,7
3080 [(set_attr "length" "2,4,4,1,3,5,3,0")
3081 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3083 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3084 ;; a whole number of bytes. The split creates the appropriate moves and
3085 ;; considers all overlap situations.
3087 ;; HImode does not need scratch. Use attribute for this constraint.
3089 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3090 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3095 (define_expand "rotl<mode>3"
3096 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3097 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3098 (match_operand:VOID 2 "const_int_operand" "")))
3099 (clobber (match_dup 3))])]
3104 if (!CONST_INT_P (operands[2]))
3107 offset = INTVAL (operands[2]);
3109 if (0 == offset % 8)
3111 if (AVR_HAVE_MOVW && 0 == offset % 16)
3112 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3114 operands[3] = gen_rtx_SCRATCH (QImode);
3116 else if (offset == 1
3117 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3119 /*; Support rotate left/right by 1 */
3121 emit_move_insn (operands[0],
3122 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3129 (define_insn "*rotlhi2.1"
3130 [(set (match_operand:HI 0 "register_operand" "=r")
3131 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3134 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3135 [(set_attr "length" "3")
3136 (set_attr "cc" "clobber")])
3138 (define_insn "*rotlhi2.15"
3139 [(set (match_operand:HI 0 "register_operand" "=r")
3140 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3143 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3144 [(set_attr "length" "4")
3145 (set_attr "cc" "clobber")])
3147 (define_insn "*rotlpsi2.1"
3148 [(set (match_operand:PSI 0 "register_operand" "=r")
3149 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3152 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3153 [(set_attr "length" "4")
3154 (set_attr "cc" "clobber")])
3156 (define_insn "*rotlpsi2.23"
3157 [(set (match_operand:PSI 0 "register_operand" "=r")
3158 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3161 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3162 [(set_attr "length" "5")
3163 (set_attr "cc" "clobber")])
3165 (define_insn "*rotlsi2.1"
3166 [(set (match_operand:SI 0 "register_operand" "=r")
3167 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3170 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3171 [(set_attr "length" "5")
3172 (set_attr "cc" "clobber")])
3174 (define_insn "*rotlsi2.31"
3175 [(set (match_operand:SI 0 "register_operand" "=r")
3176 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3179 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3180 [(set_attr "length" "6")
3181 (set_attr "cc" "clobber")])
3183 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3184 ;; The best we can do is use early clobber alternative "#&r" so that
3185 ;; completely non-overlapping operands dont get a scratch but # so register
3186 ;; allocation does not prefer non-overlapping.
3189 ;; Split word aligned rotates using scratch that is mode dependent.
3193 (define_insn_and_split "*rotw<mode>"
3194 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3195 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3196 (match_operand 2 "const_int_operand" "n,n,n")))
3197 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3199 && CONST_INT_P (operands[2])
3200 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3201 && 0 == INTVAL (operands[2]) % 16"
3203 "&& reload_completed"
3206 avr_rotate_bytes (operands);
3211 ;; Split byte aligned rotates using scratch that is always QI mode.
3216 (define_insn_and_split "*rotb<mode>"
3217 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3218 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3219 (match_operand 2 "const_int_operand" "n,n,n")))
3220 (clobber (match_scratch:QI 3 "=<rotx>"))]
3221 "CONST_INT_P (operands[2])
3222 && (8 == INTVAL (operands[2]) % 16
3224 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3225 && 0 == INTVAL (operands[2]) % 16))"
3227 "&& reload_completed"
3230 avr_rotate_bytes (operands);
3235 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3236 ;; arithmetic shift left
3238 (define_expand "ashlqi3"
3239 [(set (match_operand:QI 0 "register_operand" "")
3240 (ashift:QI (match_operand:QI 1 "register_operand" "")
3241 (match_operand:QI 2 "nop_general_operand" "")))])
3243 (define_split ; ashlqi3_const4
3244 [(set (match_operand:QI 0 "d_register_operand" "")
3245 (ashift:QI (match_dup 0)
3248 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3249 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3252 (define_split ; ashlqi3_const5
3253 [(set (match_operand:QI 0 "d_register_operand" "")
3254 (ashift:QI (match_dup 0)
3257 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3258 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3259 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3262 (define_split ; ashlqi3_const6
3263 [(set (match_operand:QI 0 "d_register_operand" "")
3264 (ashift:QI (match_dup 0)
3267 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3268 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3269 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3272 (define_insn "*ashlqi3"
3273 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3274 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3275 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3278 return ashlqi3_out (insn, operands, NULL);
3280 [(set_attr "length" "5,0,1,2,4,6,9")
3281 (set_attr "adjust_len" "ashlqi")
3282 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3284 (define_insn "ashlhi3"
3285 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3286 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3287 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3290 return ashlhi3_out (insn, operands, NULL);
3292 [(set_attr "length" "6,0,2,2,4,10,10")
3293 (set_attr "adjust_len" "ashlhi")
3294 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3297 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3298 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3302 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3303 [(set (match_operand:QI 0 "register_operand" "=r")
3304 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3305 (match_operand:QI 2 "register_operand" "r"))
3311 (ashift:QI (match_dup 1)
3315 ;; ??? Combiner does not recognize that it could split the following insn;
3316 ;; presumably because he has no register handy?
3318 ;; "*ashluqihiqi3.mem"
3319 ;; "*ashlsqihiqi3.mem"
3320 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3321 [(set (match_operand:QI 0 "memory_operand" "=m")
3322 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3323 (match_operand:QI 2 "register_operand" "r"))
3326 { gcc_unreachable(); }
3329 (ashift:QI (match_dup 1)
3334 operands[3] = gen_reg_rtx (QImode);
3339 (define_insn_and_split "*ashlhiqi3"
3340 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3341 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3342 (match_operand:QI 2 "register_operand" "r")) 0))]
3344 { gcc_unreachable(); }
3347 (ashift:QI (match_dup 3)
3352 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3353 operands[4] = gen_reg_rtx (QImode);
3356 ;; High part of 16-bit shift is unused after the instruction:
3357 ;; No need to compute it, map to 8-bit shift.
3360 [(set (match_operand:HI 0 "register_operand" "")
3361 (ashift:HI (match_dup 0)
3362 (match_operand:QI 1 "register_operand" "")))]
3365 (ashift:QI (match_dup 2)
3367 (clobber (match_dup 3))]
3369 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3371 if (!peep2_reg_dead_p (1, operands[3]))
3374 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3378 (define_insn "ashlsi3"
3379 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3380 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3381 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3384 return ashlsi3_out (insn, operands, NULL);
3386 [(set_attr "length" "8,0,4,4,8,10,12")
3387 (set_attr "adjust_len" "ashlsi")
3388 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3390 ;; Optimize if a scratch register from LD_REGS happens to be available.
3392 (define_peephole2 ; ashlqi3_l_const4
3393 [(set (match_operand:QI 0 "l_register_operand" "")
3394 (ashift:QI (match_dup 0)
3396 (match_scratch:QI 1 "d")]
3398 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3399 (set (match_dup 1) (const_int -16))
3400 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3403 (define_peephole2 ; ashlqi3_l_const5
3404 [(set (match_operand:QI 0 "l_register_operand" "")
3405 (ashift:QI (match_dup 0)
3407 (match_scratch:QI 1 "d")]
3409 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3410 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3411 (set (match_dup 1) (const_int -32))
3412 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3415 (define_peephole2 ; ashlqi3_l_const6
3416 [(set (match_operand:QI 0 "l_register_operand" "")
3417 (ashift:QI (match_dup 0)
3419 (match_scratch:QI 1 "d")]
3421 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3422 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3423 (set (match_dup 1) (const_int -64))
3424 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3428 [(match_scratch:QI 3 "d")
3429 (set (match_operand:HI 0 "register_operand" "")
3430 (ashift:HI (match_operand:HI 1 "register_operand" "")
3431 (match_operand:QI 2 "const_int_operand" "")))]
3433 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3434 (clobber (match_dup 3))])]
3437 (define_insn "*ashlhi3_const"
3438 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3439 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3440 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3441 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3444 return ashlhi3_out (insn, operands, NULL);
3446 [(set_attr "length" "0,2,2,4,10")
3447 (set_attr "adjust_len" "ashlhi")
3448 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3451 [(match_scratch:QI 3 "d")
3452 (set (match_operand:SI 0 "register_operand" "")
3453 (ashift:SI (match_operand:SI 1 "register_operand" "")
3454 (match_operand:QI 2 "const_int_operand" "")))]
3456 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3457 (clobber (match_dup 3))])]
3460 (define_insn "*ashlsi3_const"
3461 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3462 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3463 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3464 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3467 return ashlsi3_out (insn, operands, NULL);
3469 [(set_attr "length" "0,4,4,10")
3470 (set_attr "adjust_len" "ashlsi")
3471 (set_attr "cc" "none,set_n,clobber,clobber")])
3473 (define_expand "ashlpsi3"
3474 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3475 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3476 (match_operand:QI 2 "nonmemory_operand" "")))
3477 (clobber (scratch:QI))])]
3481 && CONST_INT_P (operands[2]))
3483 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3485 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3486 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3489 else if (optimize_insn_for_speed_p ()
3490 && INTVAL (operands[2]) != 16
3491 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3493 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3494 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3500 (define_insn "*ashlpsi3"
3501 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3502 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3503 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3504 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3507 return avr_out_ashlpsi3 (insn, operands, NULL);
3509 [(set_attr "adjust_len" "ashlpsi")
3510 (set_attr "cc" "clobber")])
3512 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3513 ;; arithmetic shift right
3515 (define_insn "ashrqi3"
3516 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3517 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3518 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3521 return ashrqi3_out (insn, operands, NULL);
3523 [(set_attr "length" "5,0,1,2,5,4,9")
3524 (set_attr "adjust_len" "ashrqi")
3525 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3527 (define_insn "ashrhi3"
3528 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3529 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3530 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3533 return ashrhi3_out (insn, operands, NULL);
3535 [(set_attr "length" "6,0,2,4,4,10,10")
3536 (set_attr "adjust_len" "ashrhi")
3537 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3539 (define_insn "ashrpsi3"
3540 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3541 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3542 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3543 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3546 return avr_out_ashrpsi3 (insn, operands, NULL);
3548 [(set_attr "adjust_len" "ashrpsi")
3549 (set_attr "cc" "clobber")])
3551 (define_insn "ashrsi3"
3552 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3553 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3554 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3557 return ashrsi3_out (insn, operands, NULL);
3559 [(set_attr "length" "8,0,4,6,8,10,12")
3560 (set_attr "adjust_len" "ashrsi")
3561 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3563 ;; Optimize if a scratch register from LD_REGS happens to be available.
3566 [(match_scratch:QI 3 "d")
3567 (set (match_operand:HI 0 "register_operand" "")
3568 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3569 (match_operand:QI 2 "const_int_operand" "")))]
3571 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3572 (clobber (match_dup 3))])]
3575 (define_insn "*ashrhi3_const"
3576 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3577 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3578 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3579 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3582 return ashrhi3_out (insn, operands, NULL);
3584 [(set_attr "length" "0,2,4,4,10")
3585 (set_attr "adjust_len" "ashrhi")
3586 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3589 [(match_scratch:QI 3 "d")
3590 (set (match_operand:SI 0 "register_operand" "")
3591 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3592 (match_operand:QI 2 "const_int_operand" "")))]
3594 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3595 (clobber (match_dup 3))])]
3598 (define_insn "*ashrsi3_const"
3599 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3600 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3601 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3602 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3605 return ashrsi3_out (insn, operands, NULL);
3607 [(set_attr "length" "0,4,4,10")
3608 (set_attr "adjust_len" "ashrsi")
3609 (set_attr "cc" "none,clobber,set_n,clobber")])
3611 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3612 ;; logical shift right
3614 (define_expand "lshrqi3"
3615 [(set (match_operand:QI 0 "register_operand" "")
3616 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3617 (match_operand:QI 2 "nop_general_operand" "")))])
3619 (define_split ; lshrqi3_const4
3620 [(set (match_operand:QI 0 "d_register_operand" "")
3621 (lshiftrt:QI (match_dup 0)
3624 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3625 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3628 (define_split ; lshrqi3_const5
3629 [(set (match_operand:QI 0 "d_register_operand" "")
3630 (lshiftrt:QI (match_dup 0)
3633 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3634 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3635 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3638 (define_split ; lshrqi3_const6
3639 [(set (match_operand:QI 0 "d_register_operand" "")
3640 (lshiftrt:QI (match_dup 0)
3643 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3644 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3645 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3648 (define_insn "*lshrqi3"
3649 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3650 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3651 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3654 return lshrqi3_out (insn, operands, NULL);
3656 [(set_attr "length" "5,0,1,2,4,6,9")
3657 (set_attr "adjust_len" "lshrqi")
3658 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3660 (define_insn "lshrhi3"
3661 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3662 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3663 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3666 return lshrhi3_out (insn, operands, NULL);
3668 [(set_attr "length" "6,0,2,2,4,10,10")
3669 (set_attr "adjust_len" "lshrhi")
3670 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3672 (define_insn "lshrpsi3"
3673 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3674 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3675 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3676 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3679 return avr_out_lshrpsi3 (insn, operands, NULL);
3681 [(set_attr "adjust_len" "lshrpsi")
3682 (set_attr "cc" "clobber")])
3684 (define_insn "lshrsi3"
3685 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3686 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3687 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3690 return lshrsi3_out (insn, operands, NULL);
3692 [(set_attr "length" "8,0,4,4,8,10,12")
3693 (set_attr "adjust_len" "lshrsi")
3694 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3696 ;; Optimize if a scratch register from LD_REGS happens to be available.
3698 (define_peephole2 ; lshrqi3_l_const4
3699 [(set (match_operand:QI 0 "l_register_operand" "")
3700 (lshiftrt:QI (match_dup 0)
3702 (match_scratch:QI 1 "d")]
3704 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3705 (set (match_dup 1) (const_int 15))
3706 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3709 (define_peephole2 ; lshrqi3_l_const5
3710 [(set (match_operand:QI 0 "l_register_operand" "")
3711 (lshiftrt:QI (match_dup 0)
3713 (match_scratch:QI 1 "d")]
3715 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3716 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3717 (set (match_dup 1) (const_int 7))
3718 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3721 (define_peephole2 ; lshrqi3_l_const6
3722 [(set (match_operand:QI 0 "l_register_operand" "")
3723 (lshiftrt:QI (match_dup 0)
3725 (match_scratch:QI 1 "d")]
3727 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3728 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3729 (set (match_dup 1) (const_int 3))
3730 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3734 [(match_scratch:QI 3 "d")
3735 (set (match_operand:HI 0 "register_operand" "")
3736 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3737 (match_operand:QI 2 "const_int_operand" "")))]
3739 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3740 (clobber (match_dup 3))])]
3743 (define_insn "*lshrhi3_const"
3744 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3745 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3746 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3747 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3750 return lshrhi3_out (insn, operands, NULL);
3752 [(set_attr "length" "0,2,2,4,10")
3753 (set_attr "adjust_len" "lshrhi")
3754 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3757 [(match_scratch:QI 3 "d")
3758 (set (match_operand:SI 0 "register_operand" "")
3759 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3760 (match_operand:QI 2 "const_int_operand" "")))]
3762 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3763 (clobber (match_dup 3))])]
3766 (define_insn "*lshrsi3_const"
3767 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3768 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3769 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3770 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3773 return lshrsi3_out (insn, operands, NULL);
3775 [(set_attr "length" "0,4,4,10")
3776 (set_attr "adjust_len" "lshrsi")
3777 (set_attr "cc" "none,clobber,clobber,clobber")])
3779 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3782 (define_insn "absqi2"
3783 [(set (match_operand:QI 0 "register_operand" "=r")
3784 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3788 [(set_attr "length" "2")
3789 (set_attr "cc" "clobber")])
3792 (define_insn "abssf2"
3793 [(set (match_operand:SF 0 "register_operand" "=d,r")
3794 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3799 [(set_attr "length" "1,2")
3800 (set_attr "cc" "set_n,clobber")])
3802 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3805 (define_insn "negqi2"
3806 [(set (match_operand:QI 0 "register_operand" "=r")
3807 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3810 [(set_attr "length" "1")
3811 (set_attr "cc" "set_zn")])
3813 (define_insn "*negqihi2"
3814 [(set (match_operand:HI 0 "register_operand" "=r")
3815 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3817 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3818 [(set_attr "length" "4")
3819 (set_attr "cc" "set_n")])
3821 (define_insn "neghi2"
3822 [(set (match_operand:HI 0 "register_operand" "=r,&r")
3823 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
3826 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
3827 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3828 [(set_attr "length" "3,4")
3829 (set_attr "cc" "set_czn")])
3831 (define_insn "negpsi2"
3832 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3833 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3836 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3837 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3838 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3839 [(set_attr "length" "5,6,6")
3840 (set_attr "cc" "set_czn,set_n,set_czn")])
3842 (define_insn "negsi2"
3843 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3844 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3847 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3848 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3849 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3850 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3851 [(set_attr "length" "7,8,8,7")
3852 (set_attr "isa" "*,*,mov,movw")
3853 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3855 (define_insn "negsf2"
3856 [(set (match_operand:SF 0 "register_operand" "=d,r")
3857 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3861 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3862 [(set_attr "length" "1,4")
3863 (set_attr "cc" "set_n,set_n")])
3865 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3868 (define_insn "one_cmplqi2"
3869 [(set (match_operand:QI 0 "register_operand" "=r")
3870 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3873 [(set_attr "length" "1")
3874 (set_attr "cc" "set_czn")])
3876 (define_insn "one_cmplhi2"
3877 [(set (match_operand:HI 0 "register_operand" "=r")
3878 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3882 [(set_attr "length" "2")
3883 (set_attr "cc" "set_n")])
3885 (define_insn "one_cmplpsi2"
3886 [(set (match_operand:PSI 0 "register_operand" "=r")
3887 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3889 "com %0\;com %B0\;com %C0"
3890 [(set_attr "length" "3")
3891 (set_attr "cc" "set_n")])
3893 (define_insn "one_cmplsi2"
3894 [(set (match_operand:SI 0 "register_operand" "=r")
3895 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3901 [(set_attr "length" "4")
3902 (set_attr "cc" "set_n")])
3904 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3907 ;; We keep combiner from inserting hard registers into the input of sign- and
3908 ;; zero-extends. A hard register in the input operand is not wanted because
3909 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3910 ;; hard register that overlaps these clobbers won't be combined to a widening
3911 ;; multiplication. There is no need for combine to propagate hard registers,
3912 ;; register allocation can do it just as well.
3914 (define_insn "extendqihi2"
3915 [(set (match_operand:HI 0 "register_operand" "=r,r")
3916 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3919 clr %B0\;sbrc %0,7\;com %B0
3920 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3921 [(set_attr "length" "3,4")
3922 (set_attr "cc" "set_n,set_n")])
3924 (define_insn "extendqipsi2"
3925 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3926 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3929 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3930 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3931 [(set_attr "length" "4,5")
3932 (set_attr "cc" "set_n,set_n")])
3934 (define_insn "extendqisi2"
3935 [(set (match_operand:SI 0 "register_operand" "=r,r")
3936 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3939 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3940 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3941 [(set_attr "length" "5,6")
3942 (set_attr "cc" "set_n,set_n")])
3944 (define_insn "extendhipsi2"
3945 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3946 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3949 clr %C0\;sbrc %B0,7\;com %C0
3950 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3951 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3952 [(set_attr "length" "3,5,4")
3953 (set_attr "isa" "*,mov,movw")
3954 (set_attr "cc" "set_n")])
3956 (define_insn "extendhisi2"
3957 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3958 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3961 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3962 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
3963 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
3964 [(set_attr "length" "4,6,5")
3965 (set_attr "isa" "*,mov,movw")
3966 (set_attr "cc" "set_n")])
3968 (define_insn "extendpsisi2"
3969 [(set (match_operand:SI 0 "register_operand" "=r")
3970 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
3972 "clr %D0\;sbrc %C0,7\;com %D0"
3973 [(set_attr "length" "3")
3974 (set_attr "cc" "set_n")])
3976 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3979 (define_insn_and_split "zero_extendqihi2"
3980 [(set (match_operand:HI 0 "register_operand" "=r")
3981 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
3985 [(set (match_dup 2) (match_dup 1))
3986 (set (match_dup 3) (const_int 0))]
3988 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
3989 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
3991 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
3992 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
3995 (define_insn_and_split "zero_extendqipsi2"
3996 [(set (match_operand:PSI 0 "register_operand" "=r")
3997 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4001 [(set (match_dup 2) (match_dup 1))
4002 (set (match_dup 3) (const_int 0))
4003 (set (match_dup 4) (const_int 0))]
4005 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4006 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4007 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4010 (define_insn_and_split "zero_extendqisi2"
4011 [(set (match_operand:SI 0 "register_operand" "=r")
4012 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4016 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4017 (set (match_dup 3) (const_int 0))]
4019 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4020 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4022 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4023 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4026 (define_insn_and_split "zero_extendhipsi2"
4027 [(set (match_operand:PSI 0 "register_operand" "=r")
4028 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4032 [(set (match_dup 2) (match_dup 1))
4033 (set (match_dup 3) (const_int 0))]
4035 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4036 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4039 (define_insn_and_split "n_extendhipsi2"
4040 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4041 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4042 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4043 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4047 [(set (match_dup 4) (match_dup 2))
4048 (set (match_dup 3) (match_dup 6))
4049 ; no-op move in the case where no scratch is needed
4050 (set (match_dup 5) (match_dup 3))]
4052 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4053 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4054 operands[6] = operands[1];
4056 if (GET_CODE (operands[3]) == SCRATCH)
4057 operands[3] = operands[5];
4060 (define_insn_and_split "zero_extendhisi2"
4061 [(set (match_operand:SI 0 "register_operand" "=r")
4062 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4066 [(set (match_dup 2) (match_dup 1))
4067 (set (match_dup 3) (const_int 0))]
4069 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4070 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4072 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4073 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4076 (define_insn_and_split "zero_extendpsisi2"
4077 [(set (match_operand:SI 0 "register_operand" "=r")
4078 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4082 [(set (match_dup 2) (match_dup 1))
4083 (set (match_dup 3) (const_int 0))]
4085 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4086 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4089 (define_insn_and_split "zero_extendqidi2"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4095 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4096 (set (match_dup 3) (const_int 0))]
4098 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4099 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4101 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4102 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4105 (define_insn_and_split "zero_extendhidi2"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4111 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4112 (set (match_dup 3) (const_int 0))]
4114 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4115 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4117 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4118 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4121 (define_insn_and_split "zero_extendsidi2"
4122 [(set (match_operand:DI 0 "register_operand" "=r")
4123 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4127 [(set (match_dup 2) (match_dup 1))
4128 (set (match_dup 3) (const_int 0))]
4130 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4131 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4133 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4134 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4137 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4140 ; Optimize negated tests into reverse compare if overflow is undefined.
4141 (define_insn "*negated_tstqi"
4143 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4145 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4146 "cp __zero_reg__,%0"
4147 [(set_attr "cc" "compare")
4148 (set_attr "length" "1")])
4150 (define_insn "*reversed_tstqi"
4152 (compare (const_int 0)
4153 (match_operand:QI 0 "register_operand" "r")))]
4155 "cp __zero_reg__,%0"
4156 [(set_attr "cc" "compare")
4157 (set_attr "length" "2")])
4159 (define_insn "*negated_tsthi"
4161 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4163 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4164 "cp __zero_reg__,%A0
4165 cpc __zero_reg__,%B0"
4166 [(set_attr "cc" "compare")
4167 (set_attr "length" "2")])
4169 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4170 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4171 (define_insn "*reversed_tsthi"
4173 (compare (const_int 0)
4174 (match_operand:HI 0 "register_operand" "r")))
4175 (clobber (match_scratch:QI 1 "=X"))]
4177 "cp __zero_reg__,%A0
4178 cpc __zero_reg__,%B0"
4179 [(set_attr "cc" "compare")
4180 (set_attr "length" "2")])
4182 (define_insn "*negated_tstpsi"
4184 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4186 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4187 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4188 [(set_attr "cc" "compare")
4189 (set_attr "length" "3")])
4191 (define_insn "*reversed_tstpsi"
4193 (compare (const_int 0)
4194 (match_operand:PSI 0 "register_operand" "r")))
4195 (clobber (match_scratch:QI 1 "=X"))]
4197 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4198 [(set_attr "cc" "compare")
4199 (set_attr "length" "3")])
4201 (define_insn "*negated_tstsi"
4203 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4205 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4206 "cp __zero_reg__,%A0
4207 cpc __zero_reg__,%B0
4208 cpc __zero_reg__,%C0
4209 cpc __zero_reg__,%D0"
4210 [(set_attr "cc" "compare")
4211 (set_attr "length" "4")])
4213 (define_insn "*reversed_tstsi"
4215 (compare (const_int 0)
4216 (match_operand:SI 0 "register_operand" "r")))
4217 (clobber (match_scratch:QI 1 "=X"))]
4219 "cp __zero_reg__,%A0
4220 cpc __zero_reg__,%B0
4221 cpc __zero_reg__,%C0
4222 cpc __zero_reg__,%D0"
4223 [(set_attr "cc" "compare")
4224 (set_attr "length" "4")])
4227 (define_insn "*cmpqi"
4229 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4230 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4236 [(set_attr "cc" "compare,compare,compare")
4237 (set_attr "length" "1,1,1")])
4239 (define_insn "*cmpqi_sign_extend"
4241 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4242 (match_operand:HI 1 "s8_operand" "n")))]
4245 [(set_attr "cc" "compare")
4246 (set_attr "length" "1")])
4248 (define_insn "*cmphi"
4250 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4251 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4252 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4255 switch (which_alternative)
4259 return avr_out_tsthi (insn, operands, NULL);
4262 return "cp %A0,%A1\;cpc %B0,%B1";
4265 return reg_unused_after (insn, operands[0])
4266 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4267 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4270 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4273 return avr_out_compare (insn, operands, NULL);
4275 [(set_attr "cc" "compare")
4276 (set_attr "length" "1,2,2,3,4,2,4")
4277 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4279 (define_insn "*cmppsi"
4281 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4282 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4283 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4286 switch (which_alternative)
4289 return avr_out_tstpsi (insn, operands, NULL);
4292 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4295 return reg_unused_after (insn, operands[0])
4296 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4297 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4300 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4303 return avr_out_compare (insn, operands, NULL);
4305 [(set_attr "cc" "compare")
4306 (set_attr "length" "3,3,5,6,3,7")
4307 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4309 (define_insn "*cmpsi"
4311 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4312 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4313 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4316 if (0 == which_alternative)
4317 return avr_out_tstsi (insn, operands, NULL);
4318 else if (1 == which_alternative)
4319 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4321 return avr_out_compare (insn, operands, NULL);
4323 [(set_attr "cc" "compare")
4324 (set_attr "length" "4,4,4,5,8")
4325 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4328 ;; ----------------------------------------------------------------------
4329 ;; JUMP INSTRUCTIONS
4330 ;; ----------------------------------------------------------------------
4331 ;; Conditional jump instructions
4333 (define_expand "cbranchsi4"
4334 [(parallel [(set (cc0)
4335 (compare (match_operand:SI 1 "register_operand" "")
4336 (match_operand:SI 2 "nonmemory_operand" "")))
4337 (clobber (match_scratch:QI 4 ""))])
4340 (match_operator 0 "ordered_comparison_operator" [(cc0)
4342 (label_ref (match_operand 3 "" ""))
4346 (define_expand "cbranchpsi4"
4347 [(parallel [(set (cc0)
4348 (compare (match_operand:PSI 1 "register_operand" "")
4349 (match_operand:PSI 2 "nonmemory_operand" "")))
4350 (clobber (match_scratch:QI 4 ""))])
4352 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4354 (label_ref (match_operand 3 "" ""))
4358 (define_expand "cbranchhi4"
4359 [(parallel [(set (cc0)
4360 (compare (match_operand:HI 1 "register_operand" "")
4361 (match_operand:HI 2 "nonmemory_operand" "")))
4362 (clobber (match_scratch:QI 4 ""))])
4365 (match_operator 0 "ordered_comparison_operator" [(cc0)
4367 (label_ref (match_operand 3 "" ""))
4371 (define_expand "cbranchqi4"
4373 (compare (match_operand:QI 1 "register_operand" "")
4374 (match_operand:QI 2 "nonmemory_operand" "")))
4377 (match_operator 0 "ordered_comparison_operator" [(cc0)
4379 (label_ref (match_operand 3 "" ""))
4384 ;; Test a single bit in a QI/HI/SImode register.
4385 ;; Combine will create zero extract patterns for single bit tests.
4386 ;; permit any mode in source pattern by using VOIDmode.
4388 (define_insn "*sbrx_branch<mode>"
4391 (match_operator 0 "eqne_operator"
4393 (match_operand:VOID 1 "register_operand" "r")
4395 (match_operand 2 "const_int_operand" "n"))
4397 (label_ref (match_operand 3 "" ""))
4401 return avr_out_sbxx_branch (insn, operands);
4403 [(set (attr "length")
4404 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4405 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4407 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4410 (set_attr "cc" "clobber")])
4412 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4413 ;; or for old peepholes.
4414 ;; Fixme - bitwise Mask will not work for DImode
4416 (define_insn "*sbrx_and_branch<mode>"
4419 (match_operator 0 "eqne_operator"
4421 (match_operand:QISI 1 "register_operand" "r")
4422 (match_operand:QISI 2 "single_one_operand" "n"))
4424 (label_ref (match_operand 3 "" ""))
4428 HOST_WIDE_INT bitnumber;
4429 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4430 operands[2] = GEN_INT (bitnumber);
4431 return avr_out_sbxx_branch (insn, operands);
4433 [(set (attr "length")
4434 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4435 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4437 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4440 (set_attr "cc" "clobber")])
4442 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4444 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4446 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4447 (label_ref (match_operand 1 "" ""))
4450 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4454 (label_ref (match_dup 1))
4459 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4461 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4462 (label_ref (match_operand 1 "" ""))
4465 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4469 (label_ref (match_dup 1))
4474 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4476 (clobber (match_operand:HI 2 ""))])
4477 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4478 (label_ref (match_operand 1 "" ""))
4481 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4483 (label_ref (match_dup 1))
4488 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4490 (clobber (match_operand:HI 2 ""))])
4491 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4492 (label_ref (match_operand 1 "" ""))
4495 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4497 (label_ref (match_dup 1))
4502 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4504 (clobber (match_operand:SI 2 ""))])
4505 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4506 (label_ref (match_operand 1 "" ""))
4509 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4511 (label_ref (match_dup 1))
4513 "operands[2] = GEN_INT (-2147483647 - 1);")
4516 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4518 (clobber (match_operand:SI 2 ""))])
4519 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4520 (label_ref (match_operand 1 "" ""))
4523 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4525 (label_ref (match_dup 1))
4527 "operands[2] = GEN_INT (-2147483647 - 1);")
4529 ;; ************************************************************************
4530 ;; Implementation of conditional jumps here.
4531 ;; Compare with 0 (test) jumps
4532 ;; ************************************************************************
4534 (define_insn "branch"
4536 (if_then_else (match_operator 1 "simple_comparison_operator"
4539 (label_ref (match_operand 0 "" ""))
4543 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4545 [(set_attr "type" "branch")
4546 (set_attr "cc" "clobber")])
4549 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4550 ;; or optimized in the remainder.
4552 (define_insn "branch_unspec"
4554 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4557 (label_ref (match_operand 0 "" ""))
4559 ] UNSPEC_IDENTITY))]
4562 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4564 [(set_attr "type" "branch")
4565 (set_attr "cc" "none")])
4567 ;; ****************************************************************
4568 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4569 ;; Convert them all to proper jumps.
4570 ;; ****************************************************************/
4572 (define_insn "difficult_branch"
4574 (if_then_else (match_operator 1 "difficult_comparison_operator"
4577 (label_ref (match_operand 0 "" ""))
4581 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4583 [(set_attr "type" "branch1")
4584 (set_attr "cc" "clobber")])
4588 (define_insn "rvbranch"
4590 (if_then_else (match_operator 1 "simple_comparison_operator"
4594 (label_ref (match_operand 0 "" ""))))]
4597 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4599 [(set_attr "type" "branch1")
4600 (set_attr "cc" "clobber")])
4602 (define_insn "difficult_rvbranch"
4604 (if_then_else (match_operator 1 "difficult_comparison_operator"
4608 (label_ref (match_operand 0 "" ""))))]
4611 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4613 [(set_attr "type" "branch")
4614 (set_attr "cc" "clobber")])
4616 ;; **************************************************************************
4617 ;; Unconditional and other jump instructions.
4621 (label_ref (match_operand 0 "" "")))]
4624 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4628 [(set (attr "length")
4629 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4630 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4633 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4634 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4637 (set_attr "cc" "none")])
4641 (define_expand "call"
4642 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4643 (match_operand:HI 1 "general_operand" ""))
4644 (use (const_int 0))])]
4645 ;; Operand 1 not used on the AVR.
4646 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4650 (define_expand "sibcall"
4651 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4652 (match_operand:HI 1 "general_operand" ""))
4653 (use (const_int 1))])]
4654 ;; Operand 1 not used on the AVR.
4655 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4661 (define_expand "call_value"
4662 [(parallel[(set (match_operand 0 "register_operand" "")
4663 (call (match_operand:HI 1 "call_insn_operand" "")
4664 (match_operand:HI 2 "general_operand" "")))
4665 (use (const_int 0))])]
4666 ;; Operand 2 not used on the AVR.
4667 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4671 (define_expand "sibcall_value"
4672 [(parallel[(set (match_operand 0 "register_operand" "")
4673 (call (match_operand:HI 1 "call_insn_operand" "")
4674 (match_operand:HI 2 "general_operand" "")))
4675 (use (const_int 1))])]
4676 ;; Operand 2 not used on the AVR.
4677 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4681 (define_insn "call_insn"
4682 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4683 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4684 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4685 ;; Operand 1 not used on the AVR.
4686 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4693 [(set_attr "cc" "clobber")
4694 (set_attr "length" "1,*,1,*")
4695 (set_attr "adjust_len" "*,call,*,call")])
4697 (define_insn "call_value_insn"
4698 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4699 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4700 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4701 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4702 ;; Operand 2 not used on the AVR.
4703 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4710 [(set_attr "cc" "clobber")
4711 (set_attr "length" "1,*,1,*")
4712 (set_attr "adjust_len" "*,call,*,call")])
4718 [(set_attr "cc" "none")
4719 (set_attr "length" "1")])
4723 (define_expand "indirect_jump"
4725 (match_operand:HI 0 "nonmemory_operand" ""))]
4728 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4730 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4735 (define_insn "*indirect_jump"
4737 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4743 push %A0\;push %B0\;ret
4745 [(set_attr "length" "1,2,1,3,1")
4746 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4747 (set_attr "cc" "none")])
4750 ;; For entries in jump table see avr_output_addr_vec_elt.
4753 ;; "rjmp .L<n>" instructions for <= 8K devices
4754 ;; ".word gs(.L<n>)" addresses for > 8K devices
4755 (define_insn "*tablejump"
4757 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4759 (use (label_ref (match_operand 1 "" "")))
4760 (clobber (match_dup 0))]
4764 push %A0\;push %B0\;ret
4766 [(set_attr "length" "1,3,2")
4767 (set_attr "isa" "rjmp,rjmp,jmp")
4768 (set_attr "cc" "none,none,clobber")])
4771 (define_expand "casesi"
4773 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4774 (match_operand:HI 1 "register_operand" "")))
4775 (parallel [(set (cc0)
4776 (compare (match_dup 6)
4777 (match_operand:HI 2 "register_operand" "")))
4778 (clobber (match_scratch:QI 9 ""))])
4781 (if_then_else (gtu (cc0)
4783 (label_ref (match_operand 4 "" ""))
4787 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4789 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4790 (use (label_ref (match_dup 3)))
4791 (clobber (match_dup 6))])]
4794 operands[6] = gen_reg_rtx (HImode);
4798 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4799 ;; This instruction sets Z flag
4802 [(set (cc0) (const_int 0))]
4805 [(set_attr "length" "1")
4806 (set_attr "cc" "compare")])
4808 ;; Clear/set/test a single bit in I/O address space.
4811 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4812 (and:QI (mem:QI (match_dup 0))
4813 (match_operand:QI 1 "single_zero_operand" "n")))]
4816 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4817 return "cbi %i0,%2";
4819 [(set_attr "length" "1")
4820 (set_attr "cc" "none")])
4823 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4824 (ior:QI (mem:QI (match_dup 0))
4825 (match_operand:QI 1 "single_one_operand" "n")))]
4828 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4829 return "sbi %i0,%2";
4831 [(set_attr "length" "1")
4832 (set_attr "cc" "none")])
4834 ;; Lower half of the I/O space - use sbic/sbis directly.
4835 (define_insn "*sbix_branch"
4838 (match_operator 0 "eqne_operator"
4840 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4842 (match_operand 2 "const_int_operand" "n"))
4844 (label_ref (match_operand 3 "" ""))
4848 return avr_out_sbxx_branch (insn, operands);
4850 [(set (attr "length")
4851 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4852 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4854 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4857 (set_attr "cc" "clobber")])
4859 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4860 (define_insn "*sbix_branch_bit7"
4863 (match_operator 0 "gelt_operator"
4864 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4866 (label_ref (match_operand 2 "" ""))
4870 operands[3] = operands[2];
4871 operands[2] = GEN_INT (7);
4872 return avr_out_sbxx_branch (insn, operands);
4874 [(set (attr "length")
4875 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4876 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4878 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4881 (set_attr "cc" "clobber")])
4883 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4884 (define_insn "*sbix_branch_tmp"
4887 (match_operator 0 "eqne_operator"
4889 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4891 (match_operand 2 "const_int_operand" "n"))
4893 (label_ref (match_operand 3 "" ""))
4897 return avr_out_sbxx_branch (insn, operands);
4899 [(set (attr "length")
4900 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4901 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4903 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4906 (set_attr "cc" "clobber")])
4908 (define_insn "*sbix_branch_tmp_bit7"
4911 (match_operator 0 "gelt_operator"
4912 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4914 (label_ref (match_operand 2 "" ""))
4918 operands[3] = operands[2];
4919 operands[2] = GEN_INT (7);
4920 return avr_out_sbxx_branch (insn, operands);
4922 [(set (attr "length")
4923 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4924 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4926 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4929 (set_attr "cc" "clobber")])
4931 ;; ************************* Peepholes ********************************
4933 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
4934 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4935 (plus:SI (match_dup 0)
4937 (clobber (scratch:QI))])
4938 (parallel [(set (cc0)
4939 (compare (match_dup 0)
4941 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4943 (if_then_else (eqne (cc0)
4945 (label_ref (match_operand 2 "" ""))
4952 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4953 output_asm_insn ("sbiw %0,1" CR_TAB
4954 "sbc %C0,__zero_reg__" CR_TAB
4955 "sbc %D0,__zero_reg__", operands);
4957 output_asm_insn ("subi %A0,1" CR_TAB
4958 "sbc %B0,__zero_reg__" CR_TAB
4959 "sbc %C0,__zero_reg__" CR_TAB
4960 "sbc %D0,__zero_reg__", operands);
4962 jump_mode = avr_jump_mode (operands[2], insn);
4963 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
4964 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
4968 case 1: return "%1 %2";
4969 case 2: return "%1 .+2\;rjmp %2";
4970 case 3: return "%1 .+4\;jmp %2";
4977 (define_peephole ; "*dec-and-branchhi!=-1"
4978 [(set (match_operand:HI 0 "d_register_operand" "")
4979 (plus:HI (match_dup 0)
4981 (parallel [(set (cc0)
4982 (compare (match_dup 0)
4984 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4986 (if_then_else (eqne (cc0)
4988 (label_ref (match_operand 2 "" ""))
4995 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4996 output_asm_insn ("sbiw %0,1", operands);
4998 output_asm_insn ("subi %A0,1" CR_TAB
4999 "sbc %B0,__zero_reg__", operands);
5001 jump_mode = avr_jump_mode (operands[2], insn);
5002 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5003 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5007 case 1: return "%1 %2";
5008 case 2: return "%1 .+2\;rjmp %2";
5009 case 3: return "%1 .+4\;jmp %2";
5016 ;; Same as above but with clobber flavour of addhi3
5017 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5018 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5019 (plus:HI (match_dup 0)
5021 (clobber (scratch:QI))])
5022 (parallel [(set (cc0)
5023 (compare (match_dup 0)
5025 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5027 (if_then_else (eqne (cc0)
5029 (label_ref (match_operand 2 "" ""))
5036 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5037 output_asm_insn ("sbiw %0,1", operands);
5039 output_asm_insn ("subi %A0,1" CR_TAB
5040 "sbc %B0,__zero_reg__", operands);
5042 jump_mode = avr_jump_mode (operands[2], insn);
5043 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5044 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5048 case 1: return "%1 %2";
5049 case 2: return "%1 .+2\;rjmp %2";
5050 case 3: return "%1 .+4\;jmp %2";
5057 ;; Same as above but with clobber flavour of addhi3
5058 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5059 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5060 (plus:HI (match_dup 0)
5062 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5063 (parallel [(set (cc0)
5064 (compare (match_dup 0)
5066 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5068 (if_then_else (eqne (cc0)
5070 (label_ref (match_operand 2 "" ""))
5077 output_asm_insn ("ldi %3,1" CR_TAB
5079 "sbc %B0,__zero_reg__", operands);
5081 jump_mode = avr_jump_mode (operands[2], insn);
5082 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5083 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5087 case 1: return "%1 %2";
5088 case 2: return "%1 .+2\;rjmp %2";
5089 case 3: return "%1 .+4\;jmp %2";
5096 (define_peephole ; "*dec-and-branchqi!=-1"
5097 [(set (match_operand:QI 0 "d_register_operand" "")
5098 (plus:QI (match_dup 0)
5101 (compare (match_dup 0)
5104 (if_then_else (eqne (cc0)
5106 (label_ref (match_operand 1 "" ""))
5113 cc_status.value1 = operands[0];
5114 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5116 output_asm_insn ("subi %A0,1", operands);
5118 jump_mode = avr_jump_mode (operands[1], insn);
5119 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5120 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5124 case 1: return "%0 %1";
5125 case 2: return "%0 .+2\;rjmp %1";
5126 case 3: return "%0 .+4\;jmp %1";
5134 (define_peephole ; "*cpse.eq"
5136 (compare (match_operand:QI 1 "register_operand" "r,r")
5137 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
5139 (if_then_else (eq (cc0)
5141 (label_ref (match_operand 0 "" ""))
5143 "jump_over_one_insn_p (insn, operands[0])"
5146 cpse %1,__zero_reg__")
5148 ;; This peephole avoids code like
5151 ;; BREQ .+2 ; branch
5154 ;; Notice that the peephole is always shorter than cmpqi + branch.
5155 ;; The reason to write it as peephole is that sequences like
5160 ;; shall not be superseeded. With a respective combine pattern
5161 ;; the latter sequence would be
5164 ;; CPSE Rm, __zero_reg__
5167 ;; and thus longer and slower and not easy to be rolled back.
5169 (define_peephole ; "*cpse.ne"
5171 (compare (match_operand:QI 1 "register_operand" "")
5172 (match_operand:QI 2 "reg_or_0_operand" "")))
5174 (if_then_else (ne (cc0)
5176 (label_ref (match_operand 0 "" ""))
5179 || !avr_current_device->errata_skip"
5181 if (operands[2] == const0_rtx)
5182 operands[2] = zero_reg_rtx;
5184 return 3 == avr_jump_mode (operands[0], insn)
5185 ? "cpse %1,%2\;jmp %0"
5186 : "cpse %1,%2\;rjmp %0";
5189 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5190 ;;prologue/epilogue support instructions
5192 (define_insn "popqi"
5193 [(set (match_operand:QI 0 "register_operand" "=r")
5194 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5197 [(set_attr "cc" "none")
5198 (set_attr "length" "1")])
5200 ;; Enable Interrupts
5201 (define_insn "enable_interrupt"
5202 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
5205 [(set_attr "length" "1")
5206 (set_attr "cc" "none")])
5208 ;; Disable Interrupts
5209 (define_insn "disable_interrupt"
5210 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
5213 [(set_attr "length" "1")
5214 (set_attr "cc" "none")])
5216 ;; Library prologue saves
5217 (define_insn "call_prologue_saves"
5218 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5219 (match_operand:HI 0 "immediate_operand" "i,i")
5220 (set (reg:HI REG_SP)
5221 (minus:HI (reg:HI REG_SP)
5222 (match_operand:HI 1 "immediate_operand" "i,i")))
5223 (use (reg:HI REG_X))
5224 (clobber (reg:HI REG_Z))]
5226 "ldi r30,lo8(gs(1f))
5228 %~jmp __prologue_saves__+((18 - %0) * 2)
5230 [(set_attr "length" "5,6")
5231 (set_attr "cc" "clobber")
5232 (set_attr "isa" "rjmp,jmp")])
5234 ; epilogue restores using library
5235 (define_insn "epilogue_restores"
5236 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5238 (plus:HI (reg:HI REG_Y)
5239 (match_operand:HI 0 "immediate_operand" "i,i")))
5240 (set (reg:HI REG_SP)
5241 (plus:HI (reg:HI REG_Y)
5243 (clobber (reg:QI REG_Z))]
5246 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5247 [(set_attr "length" "2,3")
5248 (set_attr "cc" "clobber")
5249 (set_attr "isa" "rjmp,jmp")])
5252 (define_insn "return"
5254 "reload_completed && avr_simple_epilogue ()"
5256 [(set_attr "cc" "none")
5257 (set_attr "length" "1")])
5259 (define_insn "return_from_epilogue"
5263 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5264 && !cfun->machine->is_naked)"
5266 [(set_attr "cc" "none")
5267 (set_attr "length" "1")])
5269 (define_insn "return_from_interrupt_epilogue"
5273 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5274 && !cfun->machine->is_naked)"
5276 [(set_attr "cc" "none")
5277 (set_attr "length" "1")])
5279 (define_insn "return_from_naked_epilogue"
5283 && cfun->machine->is_naked)"
5285 [(set_attr "cc" "none")
5286 (set_attr "length" "0")])
5288 (define_expand "prologue"
5296 (define_expand "epilogue"
5300 expand_epilogue (false /* sibcall_p */);
5304 (define_expand "sibcall_epilogue"
5308 expand_epilogue (true /* sibcall_p */);
5312 ;; Some instructions resp. instruction sequences available
5315 (define_insn "delay_cycles_1"
5316 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5318 UNSPECV_DELAY_CYCLES)
5319 (clobber (match_scratch:QI 1 "=&d"))]
5324 [(set_attr "length" "3")
5325 (set_attr "cc" "clobber")])
5327 (define_insn "delay_cycles_2"
5328 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5330 UNSPECV_DELAY_CYCLES)
5331 (clobber (match_scratch:HI 1 "=&w"))]
5337 [(set_attr "length" "4")
5338 (set_attr "cc" "clobber")])
5340 (define_insn "delay_cycles_3"
5341 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5343 UNSPECV_DELAY_CYCLES)
5344 (clobber (match_scratch:QI 1 "=&d"))
5345 (clobber (match_scratch:QI 2 "=&d"))
5346 (clobber (match_scratch:QI 3 "=&d"))]
5355 [(set_attr "length" "7")
5356 (set_attr "cc" "clobber")])
5358 (define_insn "delay_cycles_4"
5359 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5361 UNSPECV_DELAY_CYCLES)
5362 (clobber (match_scratch:QI 1 "=&d"))
5363 (clobber (match_scratch:QI 2 "=&d"))
5364 (clobber (match_scratch:QI 3 "=&d"))
5365 (clobber (match_scratch:QI 4 "=&d"))]
5376 [(set_attr "length" "9")
5377 (set_attr "cc" "clobber")])
5380 ;; __builtin_avr_insert_bits
5382 (define_insn "insert_bits"
5383 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5384 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5385 (match_operand:QI 2 "register_operand" "r ,r ,r")
5386 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5387 UNSPEC_INSERT_BITS))]
5390 return avr_out_insert_bits (operands, NULL);
5392 [(set_attr "adjust_len" "insert_bits")
5393 (set_attr "cc" "clobber")])
5398 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5399 ;; better 8-bit parity recognition.
5401 (define_expand "parityhi2"
5402 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5403 (parity:HI (match_operand:HI 1 "register_operand" "")))
5404 (clobber (reg:HI 24))])])
5406 (define_insn_and_split "*parityhi2"
5407 [(set (match_operand:HI 0 "register_operand" "=r")
5408 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5409 (clobber (reg:HI 24))]
5411 { gcc_unreachable(); }
5416 (parity:HI (reg:HI 24)))
5420 (define_insn_and_split "*parityqihi2"
5421 [(set (match_operand:HI 0 "register_operand" "=r")
5422 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5423 (clobber (reg:HI 24))]
5425 { gcc_unreachable(); }
5430 (zero_extend:HI (parity:QI (reg:QI 24))))
5434 (define_expand "paritysi2"
5436 (match_operand:SI 1 "register_operand" ""))
5438 (truncate:HI (parity:SI (reg:SI 22))))
5441 (set (match_operand:SI 0 "register_operand" "")
5442 (zero_extend:SI (match_dup 2)))]
5445 operands[2] = gen_reg_rtx (HImode);
5448 (define_insn "*parityhi2.libgcc"
5450 (parity:HI (reg:HI 24)))]
5452 "%~call __parityhi2"
5453 [(set_attr "type" "xcall")
5454 (set_attr "cc" "clobber")])
5456 (define_insn "*parityqihi2.libgcc"
5458 (zero_extend:HI (parity:QI (reg:QI 24))))]
5460 "%~call __parityqi2"
5461 [(set_attr "type" "xcall")
5462 (set_attr "cc" "clobber")])
5464 (define_insn "*paritysihi2.libgcc"
5466 (truncate:HI (parity:SI (reg:SI 22))))]
5468 "%~call __paritysi2"
5469 [(set_attr "type" "xcall")
5470 (set_attr "cc" "clobber")])
5475 (define_expand "popcounthi2"
5477 (match_operand:HI 1 "register_operand" ""))
5479 (popcount:HI (reg:HI 24)))
5480 (set (match_operand:HI 0 "register_operand" "")
5485 (define_expand "popcountsi2"
5487 (match_operand:SI 1 "register_operand" ""))
5489 (truncate:HI (popcount:SI (reg:SI 22))))
5492 (set (match_operand:SI 0 "register_operand" "")
5493 (zero_extend:SI (match_dup 2)))]
5496 operands[2] = gen_reg_rtx (HImode);
5499 (define_insn "*popcounthi2.libgcc"
5501 (popcount:HI (reg:HI 24)))]
5503 "%~call __popcounthi2"
5504 [(set_attr "type" "xcall")
5505 (set_attr "cc" "clobber")])
5507 (define_insn "*popcountsi2.libgcc"
5509 (truncate:HI (popcount:SI (reg:SI 22))))]
5511 "%~call __popcountsi2"
5512 [(set_attr "type" "xcall")
5513 (set_attr "cc" "clobber")])
5515 (define_insn "*popcountqi2.libgcc"
5517 (popcount:QI (reg:QI 24)))]
5519 "%~call __popcountqi2"
5520 [(set_attr "type" "xcall")
5521 (set_attr "cc" "clobber")])
5523 (define_insn_and_split "*popcountqihi2.libgcc"
5525 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5530 (popcount:QI (reg:QI 24)))
5535 ;; Count Leading Zeros
5537 (define_expand "clzhi2"
5539 (match_operand:HI 1 "register_operand" ""))
5540 (parallel [(set (reg:HI 24)
5541 (clz:HI (reg:HI 24)))
5542 (clobber (reg:QI 26))])
5543 (set (match_operand:HI 0 "register_operand" "")
5548 (define_expand "clzsi2"
5550 (match_operand:SI 1 "register_operand" ""))
5551 (parallel [(set (reg:HI 24)
5552 (truncate:HI (clz:SI (reg:SI 22))))
5553 (clobber (reg:QI 26))])
5556 (set (match_operand:SI 0 "register_operand" "")
5557 (zero_extend:SI (match_dup 2)))]
5560 operands[2] = gen_reg_rtx (HImode);
5563 (define_insn "*clzhi2.libgcc"
5565 (clz:HI (reg:HI 24)))
5566 (clobber (reg:QI 26))]
5569 [(set_attr "type" "xcall")
5570 (set_attr "cc" "clobber")])
5572 (define_insn "*clzsihi2.libgcc"
5574 (truncate:HI (clz:SI (reg:SI 22))))
5575 (clobber (reg:QI 26))]
5578 [(set_attr "type" "xcall")
5579 (set_attr "cc" "clobber")])
5581 ;; Count Trailing Zeros
5583 (define_expand "ctzhi2"
5585 (match_operand:HI 1 "register_operand" ""))
5586 (parallel [(set (reg:HI 24)
5587 (ctz:HI (reg:HI 24)))
5588 (clobber (reg:QI 26))])
5589 (set (match_operand:HI 0 "register_operand" "")
5594 (define_expand "ctzsi2"
5596 (match_operand:SI 1 "register_operand" ""))
5597 (parallel [(set (reg:HI 24)
5598 (truncate:HI (ctz:SI (reg:SI 22))))
5599 (clobber (reg:QI 22))
5600 (clobber (reg:QI 26))])
5603 (set (match_operand:SI 0 "register_operand" "")
5604 (zero_extend:SI (match_dup 2)))]
5607 operands[2] = gen_reg_rtx (HImode);
5610 (define_insn "*ctzhi2.libgcc"
5612 (ctz:HI (reg:HI 24)))
5613 (clobber (reg:QI 26))]
5616 [(set_attr "type" "xcall")
5617 (set_attr "cc" "clobber")])
5619 (define_insn "*ctzsihi2.libgcc"
5621 (truncate:HI (ctz:SI (reg:SI 22))))
5622 (clobber (reg:QI 22))
5623 (clobber (reg:QI 26))]
5626 [(set_attr "type" "xcall")
5627 (set_attr "cc" "clobber")])
5631 (define_expand "ffshi2"
5633 (match_operand:HI 1 "register_operand" ""))
5634 (parallel [(set (reg:HI 24)
5635 (ffs:HI (reg:HI 24)))
5636 (clobber (reg:QI 26))])
5637 (set (match_operand:HI 0 "register_operand" "")
5642 (define_expand "ffssi2"
5644 (match_operand:SI 1 "register_operand" ""))
5645 (parallel [(set (reg:HI 24)
5646 (truncate:HI (ffs:SI (reg:SI 22))))
5647 (clobber (reg:QI 22))
5648 (clobber (reg:QI 26))])
5651 (set (match_operand:SI 0 "register_operand" "")
5652 (zero_extend:SI (match_dup 2)))]
5655 operands[2] = gen_reg_rtx (HImode);
5658 (define_insn "*ffshi2.libgcc"
5660 (ffs:HI (reg:HI 24)))
5661 (clobber (reg:QI 26))]
5664 [(set_attr "type" "xcall")
5665 (set_attr "cc" "clobber")])
5667 (define_insn "*ffssihi2.libgcc"
5669 (truncate:HI (ffs:SI (reg:SI 22))))
5670 (clobber (reg:QI 22))
5671 (clobber (reg:QI 26))]
5674 [(set_attr "type" "xcall")
5675 (set_attr "cc" "clobber")])
5679 (define_insn "copysignsf3"
5680 [(set (match_operand:SF 0 "register_operand" "=r")
5681 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5682 (match_operand:SF 2 "register_operand" "r")]
5685 "bst %D2,7\;bld %D0,7"
5686 [(set_attr "length" "2")
5687 (set_attr "cc" "none")])
5689 ;; Swap Bytes (change byte-endianess)
5691 (define_expand "bswapsi2"
5693 (match_operand:SI 1 "register_operand" ""))
5695 (bswap:SI (reg:SI 22)))
5696 (set (match_operand:SI 0 "register_operand" "")
5701 (define_insn "*bswapsi2.libgcc"
5703 (bswap:SI (reg:SI 22)))]
5706 [(set_attr "type" "xcall")
5707 (set_attr "cc" "clobber")])
5712 ;; NOP taking 1 or 2 Ticks
5714 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5720 [(set_attr "length" "1")
5721 (set_attr "cc" "none")])
5724 (define_insn "sleep"
5725 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5728 [(set_attr "length" "1")
5729 (set_attr "cc" "none")])
5733 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5736 [(set_attr "length" "1")
5737 (set_attr "cc" "none")])
5740 (define_expand "fmul"
5742 (match_operand:QI 1 "register_operand" ""))
5744 (match_operand:QI 2 "register_operand" ""))
5745 (parallel [(set (reg:HI 22)
5746 (unspec:HI [(reg:QI 24)
5747 (reg:QI 25)] UNSPEC_FMUL))
5748 (clobber (reg:HI 24))])
5749 (set (match_operand:HI 0 "register_operand" "")
5755 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5760 (define_insn "fmul_insn"
5761 [(set (match_operand:HI 0 "register_operand" "=r")
5762 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5763 (match_operand:QI 2 "register_operand" "a")]
5769 [(set_attr "length" "3")
5770 (set_attr "cc" "clobber")])
5772 (define_insn "*fmul.call"
5774 (unspec:HI [(reg:QI 24)
5775 (reg:QI 25)] UNSPEC_FMUL))
5776 (clobber (reg:HI 24))]
5779 [(set_attr "type" "xcall")
5780 (set_attr "cc" "clobber")])
5783 (define_expand "fmuls"
5785 (match_operand:QI 1 "register_operand" ""))
5787 (match_operand:QI 2 "register_operand" ""))
5788 (parallel [(set (reg:HI 22)
5789 (unspec:HI [(reg:QI 24)
5790 (reg:QI 25)] UNSPEC_FMULS))
5791 (clobber (reg:HI 24))])
5792 (set (match_operand:HI 0 "register_operand" "")
5798 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5803 (define_insn "fmuls_insn"
5804 [(set (match_operand:HI 0 "register_operand" "=r")
5805 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5806 (match_operand:QI 2 "register_operand" "a")]
5812 [(set_attr "length" "3")
5813 (set_attr "cc" "clobber")])
5815 (define_insn "*fmuls.call"
5817 (unspec:HI [(reg:QI 24)
5818 (reg:QI 25)] UNSPEC_FMULS))
5819 (clobber (reg:HI 24))]
5822 [(set_attr "type" "xcall")
5823 (set_attr "cc" "clobber")])
5826 (define_expand "fmulsu"
5828 (match_operand:QI 1 "register_operand" ""))
5830 (match_operand:QI 2 "register_operand" ""))
5831 (parallel [(set (reg:HI 22)
5832 (unspec:HI [(reg:QI 24)
5833 (reg:QI 25)] UNSPEC_FMULSU))
5834 (clobber (reg:HI 24))])
5835 (set (match_operand:HI 0 "register_operand" "")
5841 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5846 (define_insn "fmulsu_insn"
5847 [(set (match_operand:HI 0 "register_operand" "=r")
5848 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5849 (match_operand:QI 2 "register_operand" "a")]
5855 [(set_attr "length" "3")
5856 (set_attr "cc" "clobber")])
5858 (define_insn "*fmulsu.call"
5860 (unspec:HI [(reg:QI 24)
5861 (reg:QI 25)] UNSPEC_FMULSU))
5862 (clobber (reg:HI 24))]
5865 [(set_attr "type" "xcall")
5866 (set_attr "cc" "clobber")])
5869 ;; Some combiner patterns dealing with bits.
5872 ;; Move bit $3.0 into bit $0.$4
5873 (define_insn "*movbitqi.1-6.a"
5874 [(set (match_operand:QI 0 "register_operand" "=r")
5875 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5876 (match_operand:QI 2 "single_zero_operand" "n"))
5877 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5878 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5879 (match_operand:QI 5 "single_one_operand" "n"))))]
5880 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5881 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5882 "bst %3,0\;bld %0,%4"
5883 [(set_attr "length" "2")
5884 (set_attr "cc" "none")])
5886 ;; Move bit $3.0 into bit $0.$4
5887 ;; Variation of above. Unfortunately, there is no canonicalized representation
5888 ;; of moving around bits. So what we see here depends on how user writes down
5889 ;; bit manipulations.
5890 (define_insn "*movbitqi.1-6.b"
5891 [(set (match_operand:QI 0 "register_operand" "=r")
5892 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5893 (match_operand:QI 2 "single_zero_operand" "n"))
5894 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5896 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5897 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5898 "bst %3,0\;bld %0,%4"
5899 [(set_attr "length" "2")
5900 (set_attr "cc" "none")])
5902 ;; Move bit $3.0 into bit $0.0.
5903 ;; For bit 0, combiner generates slightly different pattern.
5904 (define_insn "*movbitqi.0"
5905 [(set (match_operand:QI 0 "register_operand" "=r")
5906 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5907 (match_operand:QI 2 "single_zero_operand" "n"))
5908 (and:QI (match_operand:QI 3 "register_operand" "r")
5910 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5911 "bst %3,0\;bld %0,0"
5912 [(set_attr "length" "2")
5913 (set_attr "cc" "none")])
5915 ;; Move bit $2.0 into bit $0.7.
5916 ;; For bit 7, combiner generates slightly different pattern
5917 (define_insn "*movbitqi.7"
5918 [(set (match_operand:QI 0 "register_operand" "=r")
5919 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5921 (ashift:QI (match_operand:QI 2 "register_operand" "r")
5924 "bst %2,0\;bld %0,7"
5925 [(set_attr "length" "2")
5926 (set_attr "cc" "none")])
5928 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
5929 ;; and input/output match. We provide a special pattern for this, because
5930 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
5931 ;; operation on I/O is atomic.
5932 (define_insn "*insv.io"
5933 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
5935 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
5936 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
5941 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
5942 [(set_attr "length" "1,1,4")
5943 (set_attr "cc" "none")])
5945 (define_insn "*insv.not.io"
5946 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
5948 (match_operand:QI 1 "const_0_to_7_operand" "n"))
5949 (not:QI (match_operand:QI 2 "register_operand" "r")))]
5951 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
5952 [(set_attr "length" "4")
5953 (set_attr "cc" "none")])
5955 ;; The insv expander.
5956 ;; We only support 1-bit inserts
5957 (define_expand "insv"
5958 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
5959 (match_operand:QI 1 "const1_operand" "") ; width
5960 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
5961 (match_operand:QI 3 "nonmemory_operand" ""))]
5965 ;; Insert bit $2.0 into $0.$1
5966 (define_insn "*insv.reg"
5967 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
5969 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
5970 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
5974 andi %0,lo8(~(1<<%1))
5978 [(set_attr "length" "2,1,1,2,2")
5979 (set_attr "cc" "none,set_zn,set_zn,none,none")])
5982 ;; Some combine patterns that try to fix bad code when a value is composed
5983 ;; from byte parts like in PR27663.
5984 ;; The patterns give some release but the code still is not optimal,
5985 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
5986 ;; That switch obfuscates things here and in many other places.
5988 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
5989 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
5990 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
5991 [(set (match_operand:HISI 0 "register_operand" "=r")
5993 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
5994 (match_operand:HISI 2 "register_operand" "0")))]
5999 (xior:QI (match_dup 3)
6002 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6005 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6006 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6007 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6008 [(set (match_operand:HISI 0 "register_operand" "=r")
6010 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6011 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6012 (match_operand:HISI 3 "register_operand" "0")))]
6013 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6015 "&& reload_completed"
6017 (xior:QI (match_dup 4)
6020 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6021 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6024 (define_expand "extzv"
6025 [(set (match_operand:QI 0 "register_operand" "")
6026 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6027 (match_operand:QI 2 "const1_operand" "")
6028 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6032 (define_insn "*extzv"
6033 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6034 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6036 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6040 mov %0,%1\;andi %0,1
6043 bst %1,%2\;clr %0\;bld %0,0"
6044 [(set_attr "length" "1,2,2,2,3")
6045 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6047 (define_insn_and_split "*extzv.qihi1"
6048 [(set (match_operand:HI 0 "register_operand" "=r")
6049 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6051 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6056 (zero_extract:QI (match_dup 1)
6062 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6063 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6066 (define_insn_and_split "*extzv.qihi2"
6067 [(set (match_operand:HI 0 "register_operand" "=r")
6069 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6071 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6076 (zero_extract:QI (match_dup 1)
6082 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6083 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6087 (include "avr-dimode.md")