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 ;;========================================================================
371 (define_expand "load<mode>_libgcc"
374 (set (reg:MOVMODE 22)
375 (match_operand:MOVMODE 1 "memory_operand" ""))
376 (set (match_operand:MOVMODE 0 "register_operand" "")
378 "avr_load_libgcc_p (operands[1])"
380 operands[3] = gen_rtx_REG (HImode, REG_Z);
381 operands[2] = force_operand (XEXP (operands[1], 0), NULL_RTX);
382 operands[1] = replace_equiv_address (operands[1], operands[3]);
383 set_mem_addr_space (operands[1], ADDR_SPACE_FLASH);
391 (define_insn "load_<mode>_libgcc"
392 [(set (reg:MOVMODE 22)
393 (match_operand:MOVMODE 0 "memory_operand" "m,m"))]
394 "avr_load_libgcc_p (operands[0])
395 && REG_P (XEXP (operands[0], 0))
396 && REG_Z == REGNO (XEXP (operands[0], 0))"
398 operands[0] = GEN_INT (GET_MODE_SIZE (<MODE>mode));
399 return "%~call __load_%0";
401 [(set_attr "length" "1,2")
402 (set_attr "isa" "rjmp,jmp")
403 (set_attr "cc" "clobber")])
406 (define_insn_and_split "xload8_A"
407 [(set (match_operand:QI 0 "register_operand" "=r")
408 (match_operand:QI 1 "memory_operand" "m"))
409 (clobber (reg:HI REG_Z))]
410 "can_create_pseudo_p()
411 && !avr_xload_libgcc_p (QImode)
412 && avr_mem_memx_p (operands[1])
413 && REG_P (XEXP (operands[1], 0))"
414 { gcc_unreachable(); }
416 [(clobber (const_int 0))]
418 rtx insn, addr = XEXP (operands[1], 0);
419 rtx hi8 = gen_reg_rtx (QImode);
420 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
422 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
423 emit_move_insn (hi8, simplify_gen_subreg (QImode, addr, PSImode, 2));
425 insn = emit_insn (gen_xload_8 (operands[0], hi8));
426 set_mem_addr_space (SET_SRC (single_set (insn)),
427 MEM_ADDR_SPACE (operands[1]));
436 (define_insn_and_split "xload<mode>_A"
437 [(set (match_operand:MOVMODE 0 "register_operand" "=r")
438 (match_operand:MOVMODE 1 "memory_operand" "m"))
439 (clobber (reg:QI 21))
440 (clobber (reg:HI REG_Z))]
441 "can_create_pseudo_p()
442 && avr_mem_memx_p (operands[1])
443 && REG_P (XEXP (operands[1], 0))"
444 { gcc_unreachable(); }
446 [(clobber (const_int 0))]
448 rtx addr = XEXP (operands[1], 0);
449 rtx reg_z = gen_rtx_REG (HImode, REG_Z);
450 rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
451 addr_space_t as = MEM_ADDR_SPACE (operands[1]);
454 /* Split the address to R21:Z */
455 emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
456 emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
458 /* Load with code from libgcc */
459 insn = emit_insn (gen_xload_<mode>_libgcc ());
460 set_mem_addr_space (SET_SRC (single_set (insn)), as);
462 /* Move to destination */
463 emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
468 ;; Move value from address space memx to a register
469 ;; These insns must be prior to respective generic move insn.
471 (define_insn "xload_8"
472 [(set (match_operand:QI 0 "register_operand" "=&r,r")
473 (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
475 "!avr_xload_libgcc_p (QImode)"
477 return avr_out_xload (insn, operands, NULL);
479 [(set_attr "length" "4,4")
480 (set_attr "adjust_len" "*,xload")
481 (set_attr "isa" "lpmx,lpm")
482 (set_attr "cc" "none")])
484 ;; R21:Z : 24-bit source address
485 ;; R22 : 1-4 byte output
489 ;; "xload_psi_libgcc"
492 (define_insn "xload_<mode>_libgcc"
493 [(set (reg:MOVMODE 22)
494 (mem:MOVMODE (lo_sum:PSI (reg:QI 21)
496 (clobber (reg:QI 21))
497 (clobber (reg:HI REG_Z))]
498 "avr_xload_libgcc_p (<MODE>mode)"
500 rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
502 output_asm_insn ("%~call __xload_%0", &x_bytes);
505 [(set_attr "type" "xcall")
506 (set_attr "cc" "clobber")])
509 ;; General move expanders
516 (define_expand "mov<mode>"
517 [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
518 (match_operand:MOVMODE 1 "general_operand" ""))]
521 rtx dest = operands[0];
522 rtx src = operands[1];
524 if (avr_mem_flash_p (dest))
527 /* One of the operands has to be in a register. */
528 if (!register_operand (dest, <MODE>mode)
529 && !(register_operand (src, <MODE>mode)
530 || src == CONST0_RTX (<MODE>mode)))
532 operands[1] = src = copy_to_mode_reg (<MODE>mode, src);
535 if (avr_mem_memx_p (src))
537 rtx addr = XEXP (src, 0);
540 src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
542 if (!avr_xload_libgcc_p (<MODE>mode))
543 emit_insn (gen_xload8_A (dest, src));
545 emit_insn (gen_xload<mode>_A (dest, src));
550 if (avr_load_libgcc_p (src))
552 /* For the small devices, do loads per libgcc call. */
553 emit_insn (gen_load<mode>_libgcc (dest, src));
558 ;;========================================================================
560 ;; The last alternative (any immediate constant to any register) is
561 ;; very expensive. It should be optimized by peephole2 if a scratch
562 ;; register is available, but then that register could just as well be
563 ;; allocated for the variable we are loading. But, most of NO_LD_REGS
564 ;; are call-saved registers, and most of LD_REGS are call-used registers,
565 ;; so this may still be a win for registers live across function calls.
567 (define_insn "movqi_insn"
568 [(set (match_operand:QI 0 "nonimmediate_operand" "=r ,d,Qm,r ,q,r,*r")
569 (match_operand:QI 1 "nox_general_operand" "rL,i,rL,Qm,r,q,i"))]
570 "register_operand (operands[0], QImode)
571 || register_operand (operands[1], QImode)
572 || const0_rtx == operands[1]"
574 return output_movqi (insn, operands, NULL);
576 [(set_attr "length" "1,1,5,5,1,1,4")
577 (set_attr "adjust_len" "mov8")
578 (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")])
580 ;; This is used in peephole2 to optimize loading immediate constants
581 ;; if a scratch register from LD_REGS happens to be available.
583 (define_insn "*reload_inqi"
584 [(set (match_operand:QI 0 "register_operand" "=l")
585 (match_operand:QI 1 "immediate_operand" "i"))
586 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
590 [(set_attr "length" "2")
591 (set_attr "cc" "none")])
594 [(match_scratch:QI 2 "d")
595 (set (match_operand:QI 0 "l_register_operand" "")
596 (match_operand:QI 1 "immediate_operand" ""))]
597 "(operands[1] != const0_rtx
598 && operands[1] != const1_rtx
599 && operands[1] != constm1_rtx)"
600 [(parallel [(set (match_dup 0) (match_dup 1))
601 (clobber (match_dup 2))])]
604 ;;============================================================================
605 ;; move word (16 bit)
607 ;; Move register $1 to the Stack Pointer register SP.
608 ;; This insn is emit during function prologue/epilogue generation.
609 ;; $2 = 0: We know that IRQs are off
610 ;; $2 = 1: We know that IRQs are on
611 ;; $2 = 2: SP has 8 bits only, IRQ state does not matter
612 ;; $2 = -1: We don't know anything about IRQ on/off
613 ;; Always write SP via unspec, see PR50063
615 (define_insn "movhi_sp_r"
616 [(set (match_operand:HI 0 "stack_register_operand" "=q,q,q,q,q")
617 (unspec_volatile:HI [(match_operand:HI 1 "register_operand" "r,r,r,r,r")
618 (match_operand:HI 2 "const_int_operand" "L,P,N,K,LPN")]
622 out %B0,%B1\;out %A0,%A1
623 cli\;out %B0,%B1\;sei\;out %A0,%A1
624 in __tmp_reg__,__SREG__\;cli\;out %B0,%B1\;out __SREG__,__tmp_reg__\;out %A0,%A1
626 out %A0,%A1\;out %B0,%B1"
627 [(set_attr "length" "2,4,5,1,2")
628 (set_attr "isa" "no_xmega,no_xmega,no_xmega,*,xmega")
629 (set_attr "cc" "none")])
632 [(match_scratch:QI 2 "d")
633 (set (match_operand:HI 0 "l_register_operand" "")
634 (match_operand:HI 1 "immediate_operand" ""))]
635 "(operands[1] != const0_rtx
636 && operands[1] != constm1_rtx)"
637 [(parallel [(set (match_dup 0) (match_dup 1))
638 (clobber (match_dup 2))])]
641 ;; '*' because it is not used in rtl generation, only in above peephole
642 (define_insn "*reload_inhi"
643 [(set (match_operand:HI 0 "register_operand" "=r")
644 (match_operand:HI 1 "immediate_operand" "i"))
645 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
648 return output_reload_inhi (operands, operands[2], NULL);
650 [(set_attr "length" "4")
651 (set_attr "adjust_len" "reload_in16")
652 (set_attr "cc" "none")])
654 (define_insn "*movhi"
655 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m ,d,*r,q,r")
656 (match_operand:HI 1 "nox_general_operand" "r,L,m,rL,i,i ,r,q"))]
657 "register_operand (operands[0], HImode)
658 || register_operand (operands[1], HImode)
659 || const0_rtx == operands[1]"
661 return output_movhi (insn, operands, NULL);
663 [(set_attr "length" "2,2,6,7,2,6,5,2")
664 (set_attr "adjust_len" "mov16")
665 (set_attr "cc" "none,none,clobber,clobber,none,clobber,none,none")])
667 (define_peephole2 ; movw
668 [(set (match_operand:QI 0 "even_register_operand" "")
669 (match_operand:QI 1 "even_register_operand" ""))
670 (set (match_operand:QI 2 "odd_register_operand" "")
671 (match_operand:QI 3 "odd_register_operand" ""))]
673 && REGNO (operands[0]) == REGNO (operands[2]) - 1
674 && REGNO (operands[1]) == REGNO (operands[3]) - 1)"
675 [(set (match_dup 4) (match_dup 5))]
677 operands[4] = gen_rtx_REG (HImode, REGNO (operands[0]));
678 operands[5] = gen_rtx_REG (HImode, REGNO (operands[1]));
681 (define_peephole2 ; movw_r
682 [(set (match_operand:QI 0 "odd_register_operand" "")
683 (match_operand:QI 1 "odd_register_operand" ""))
684 (set (match_operand:QI 2 "even_register_operand" "")
685 (match_operand:QI 3 "even_register_operand" ""))]
687 && REGNO (operands[2]) == REGNO (operands[0]) - 1
688 && REGNO (operands[3]) == REGNO (operands[1]) - 1)"
689 [(set (match_dup 4) (match_dup 5))]
691 operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));
692 operands[5] = gen_rtx_REG (HImode, REGNO (operands[3]));
695 ;; For LPM loads from AS1 we split
699 ;; Z = Z - sizeof (R)
701 ;; so that the second instruction can be optimized out.
703 (define_split ; "split-lpmx"
704 [(set (match_operand:HISI 0 "register_operand" "")
705 (match_operand:HISI 1 "memory_operand" ""))]
711 (plus:HI (match_dup 3)
714 rtx addr = XEXP (operands[1], 0);
716 if (!avr_mem_flash_p (operands[1])
718 || reg_overlap_mentioned_p (addr, operands[0]))
723 operands[2] = replace_equiv_address (operands[1],
724 gen_rtx_POST_INC (Pmode, addr));
726 operands[4] = gen_int_mode (-GET_MODE_SIZE (<MODE>mode), HImode);
729 ;;==========================================================================
730 ;; xpointer move (24 bit)
732 (define_peephole2 ; *reload_inpsi
733 [(match_scratch:QI 2 "d")
734 (set (match_operand:PSI 0 "l_register_operand" "")
735 (match_operand:PSI 1 "immediate_operand" ""))
737 "operands[1] != const0_rtx
738 && operands[1] != constm1_rtx"
739 [(parallel [(set (match_dup 0)
741 (clobber (match_dup 2))])]
744 ;; '*' because it is not used in rtl generation.
745 (define_insn "*reload_inpsi"
746 [(set (match_operand:PSI 0 "register_operand" "=r")
747 (match_operand:PSI 1 "immediate_operand" "i"))
748 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
751 return avr_out_reload_inpsi (operands, operands[2], NULL);
753 [(set_attr "length" "6")
754 (set_attr "adjust_len" "reload_in24")
755 (set_attr "cc" "clobber")])
757 (define_insn "*movpsi"
758 [(set (match_operand:PSI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
759 (match_operand:PSI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
760 "register_operand (operands[0], PSImode)
761 || register_operand (operands[1], PSImode)
762 || const0_rtx == operands[1]"
764 return avr_out_movpsi (insn, operands, NULL);
766 [(set_attr "length" "3,3,8,9,4,10")
767 (set_attr "adjust_len" "mov24")
768 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
770 ;;==========================================================================
771 ;; move double word (32 bit)
773 (define_peephole2 ; *reload_insi
774 [(match_scratch:QI 2 "d")
775 (set (match_operand:SI 0 "l_register_operand" "")
776 (match_operand:SI 1 "const_int_operand" ""))
778 "(operands[1] != const0_rtx
779 && operands[1] != constm1_rtx)"
780 [(parallel [(set (match_dup 0) (match_dup 1))
781 (clobber (match_dup 2))])]
784 ;; '*' because it is not used in rtl generation.
785 (define_insn "*reload_insi"
786 [(set (match_operand:SI 0 "register_operand" "=r")
787 (match_operand:SI 1 "const_int_operand" "n"))
788 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
791 return output_reload_insisf (operands, operands[2], NULL);
793 [(set_attr "length" "8")
794 (set_attr "adjust_len" "reload_in32")
795 (set_attr "cc" "clobber")])
798 (define_insn "*movsi"
799 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
800 (match_operand:SI 1 "nox_general_operand" "r,L,Qm,rL,i ,i"))]
801 "register_operand (operands[0], SImode)
802 || register_operand (operands[1], SImode)
803 || const0_rtx == operands[1]"
805 return output_movsisf (insn, operands, NULL);
807 [(set_attr "length" "4,4,8,9,4,10")
808 (set_attr "adjust_len" "mov32")
809 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
811 ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
812 ;; move floating point numbers (32 bit)
814 (define_insn "*movsf"
815 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r ,Qm,!d,r")
816 (match_operand:SF 1 "nox_general_operand" "r,G,Qm,rG,F ,F"))]
817 "register_operand (operands[0], SFmode)
818 || register_operand (operands[1], SFmode)
819 || operands[1] == CONST0_RTX (SFmode)"
821 return output_movsisf (insn, operands, NULL);
823 [(set_attr "length" "4,4,8,9,4,10")
824 (set_attr "adjust_len" "mov32")
825 (set_attr "cc" "none,none,clobber,clobber,none,clobber")])
827 (define_peephole2 ; *reload_insf
828 [(match_scratch:QI 2 "d")
829 (set (match_operand:SF 0 "l_register_operand" "")
830 (match_operand:SF 1 "const_double_operand" ""))
832 "operands[1] != CONST0_RTX (SFmode)"
833 [(parallel [(set (match_dup 0)
835 (clobber (match_dup 2))])]
838 ;; '*' because it is not used in rtl generation.
839 (define_insn "*reload_insf"
840 [(set (match_operand:SF 0 "register_operand" "=r")
841 (match_operand:SF 1 "const_double_operand" "F"))
842 (clobber (match_operand:QI 2 "register_operand" "=&d"))]
845 return output_reload_insisf (operands, operands[2], NULL);
847 [(set_attr "length" "8")
848 (set_attr "adjust_len" "reload_in32")
849 (set_attr "cc" "clobber")])
851 ;;=========================================================================
852 ;; move string (like memcpy)
854 (define_expand "movmemhi"
855 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
856 (match_operand:BLK 1 "memory_operand" ""))
857 (use (match_operand:HI 2 "const_int_operand" ""))
858 (use (match_operand:HI 3 "const_int_operand" ""))])]
861 if (avr_emit_movmemhi (operands))
867 (define_mode_attr MOVMEM_r_d [(QI "r")
870 ;; $0 : Address Space
871 ;; $1, $2 : Loop register
872 ;; R30 : source address
873 ;; R26 : destination address
877 (define_insn "movmem_<mode>"
878 [(set (mem:BLK (reg:HI REG_X))
879 (mem:BLK (reg:HI REG_Z)))
880 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
882 (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
883 (clobber (reg:HI REG_X))
884 (clobber (reg:HI REG_Z))
885 (clobber (reg:QI LPM_REGNO))
886 (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
889 return avr_out_movmem (insn, operands, NULL);
891 [(set_attr "adjust_len" "movmem")
892 (set_attr "cc" "clobber")])
895 ;; $0 : Address Space
896 ;; $1 : RAMPZ RAM address
897 ;; R24 : #bytes and loop register
898 ;; R23:Z : 24-bit source address
899 ;; R26 : 16-bit destination address
903 (define_insn "movmemx_<mode>"
904 [(set (mem:BLK (reg:HI REG_X))
905 (mem:BLK (lo_sum:PSI (reg:QI 23)
907 (unspec [(match_operand:QI 0 "const_int_operand" "n")]
910 (clobber (reg:HI REG_X))
911 (clobber (reg:HI REG_Z))
912 (clobber (reg:QI LPM_REGNO))
913 (clobber (reg:HI 24))
914 (clobber (reg:QI 23))
915 (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
917 "%~call __movmemx_<mode>"
918 [(set_attr "type" "xcall")
919 (set_attr "cc" "clobber")])
922 ;; =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2 =%2
923 ;; memset (%0, %2, %1)
925 (define_expand "setmemhi"
926 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
927 (match_operand 2 "const_int_operand" ""))
928 (use (match_operand:HI 1 "const_int_operand" ""))
929 (use (match_operand:HI 3 "const_int_operand" ""))
930 (clobber (match_scratch:HI 4 ""))
931 (clobber (match_dup 5))])]
935 enum machine_mode mode;
937 /* If value to set is not zero, use the library routine. */
938 if (operands[2] != const0_rtx)
941 if (!CONST_INT_P (operands[1]))
944 mode = u8_operand (operands[1], VOIDmode) ? QImode : HImode;
945 operands[5] = gen_rtx_SCRATCH (mode);
946 operands[1] = copy_to_mode_reg (mode,
947 gen_int_mode (INTVAL (operands[1]), mode));
948 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
949 operands[0] = gen_rtx_MEM (BLKmode, addr0);
953 (define_insn "*clrmemqi"
954 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e"))
956 (use (match_operand:QI 1 "register_operand" "r"))
957 (use (match_operand:QI 2 "const_int_operand" "n"))
958 (clobber (match_scratch:HI 3 "=0"))
959 (clobber (match_scratch:QI 4 "=&1"))]
961 "0:\;st %a0+,__zero_reg__\;dec %1\;brne 0b"
962 [(set_attr "length" "3")
963 (set_attr "cc" "clobber")])
966 (define_insn "*clrmemhi"
967 [(set (mem:BLK (match_operand:HI 0 "register_operand" "e,e"))
969 (use (match_operand:HI 1 "register_operand" "!w,d"))
970 (use (match_operand:HI 2 "const_int_operand" "n,n"))
971 (clobber (match_scratch:HI 3 "=0,0"))
972 (clobber (match_scratch:HI 4 "=&1,&1"))]
975 0:\;st %a0+,__zero_reg__\;sbiw %A1,1\;brne 0b
976 0:\;st %a0+,__zero_reg__\;subi %A1,1\;sbci %B1,0\;brne 0b"
977 [(set_attr "length" "3,4")
978 (set_attr "cc" "clobber,clobber")])
980 (define_expand "strlenhi"
982 (unspec:HI [(match_operand:BLK 1 "memory_operand" "")
983 (match_operand:QI 2 "const_int_operand" "")
984 (match_operand:HI 3 "immediate_operand" "")]
987 (plus:HI (match_dup 4)
989 (set (match_operand:HI 0 "register_operand" "")
990 (minus:HI (match_dup 4)
995 if (operands[2] != const0_rtx)
997 addr = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
998 operands[1] = gen_rtx_MEM (BLKmode, addr);
1000 operands[4] = gen_reg_rtx (HImode);
1003 (define_insn "*strlenhi"
1004 [(set (match_operand:HI 0 "register_operand" "=e")
1005 (unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "0"))
1007 (match_operand:HI 2 "immediate_operand" "i")]
1010 "0:\;ld __tmp_reg__,%a0+\;tst __tmp_reg__\;brne 0b"
1011 [(set_attr "length" "3")
1012 (set_attr "cc" "clobber")])
1014 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1017 (define_insn "addqi3"
1018 [(set (match_operand:QI 0 "register_operand" "=r,d,r,r,r,r")
1019 (plus:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0,0")
1020 (match_operand:QI 2 "nonmemory_operand" "r,i,P,N,K,Cm2")))]
1029 [(set_attr "length" "1,1,1,1,2,2")
1030 (set_attr "cc" "set_czn,set_czn,set_zn,set_zn,set_zn,set_zn")])
1033 (define_expand "addhi3"
1034 [(set (match_operand:HI 0 "register_operand" "")
1035 (plus:HI (match_operand:HI 1 "register_operand" "")
1036 (match_operand:HI 2 "nonmemory_operand" "")))]
1039 if (CONST_INT_P (operands[2]))
1041 operands[2] = gen_int_mode (INTVAL (operands[2]), HImode);
1043 if (can_create_pseudo_p()
1044 && !stack_register_operand (operands[0], HImode)
1045 && !stack_register_operand (operands[1], HImode)
1046 && !d_register_operand (operands[0], HImode)
1047 && !d_register_operand (operands[1], HImode))
1049 emit_insn (gen_addhi3_clobber (operands[0], operands[1], operands[2]));
1056 (define_insn "*addhi3_zero_extend"
1057 [(set (match_operand:HI 0 "register_operand" "=r")
1058 (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1059 (match_operand:HI 2 "register_operand" "0")))]
1061 "add %A0,%1\;adc %B0,__zero_reg__"
1062 [(set_attr "length" "2")
1063 (set_attr "cc" "set_n")])
1065 (define_insn "*addhi3_zero_extend1"
1066 [(set (match_operand:HI 0 "register_operand" "=r")
1067 (plus:HI (match_operand:HI 1 "register_operand" "0")
1068 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1070 "add %A0,%2\;adc %B0,__zero_reg__"
1071 [(set_attr "length" "2")
1072 (set_attr "cc" "set_n")])
1074 (define_insn "*addhi3.sign_extend1"
1075 [(set (match_operand:HI 0 "register_operand" "=r")
1076 (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r"))
1077 (match_operand:HI 2 "register_operand" "0")))]
1080 return reg_overlap_mentioned_p (operands[0], operands[1])
1081 ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0"
1082 : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0";
1084 [(set_attr "length" "5")
1085 (set_attr "cc" "clobber")])
1087 (define_insn "*addhi3_sp"
1088 [(set (match_operand:HI 1 "stack_register_operand" "=q")
1089 (plus:HI (match_operand:HI 2 "stack_register_operand" "q")
1090 (match_operand:HI 0 "avr_sp_immediate_operand" "Csp")))]
1093 return avr_out_addto_sp (operands, NULL);
1095 [(set_attr "length" "6")
1096 (set_attr "adjust_len" "addto_sp")])
1098 (define_insn "*addhi3"
1099 [(set (match_operand:HI 0 "register_operand" "=r,d,d")
1100 (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
1101 (match_operand:HI 2 "nonmemory_operand" "r,s,n")))]
1104 static const char * const asm_code[] =
1106 "add %A0,%A2\;adc %B0,%B2",
1107 "subi %A0,lo8(-(%2))\;sbci %B0,hi8(-(%2))",
1111 if (*asm_code[which_alternative])
1112 return asm_code[which_alternative];
1114 return avr_out_plus_noclobber (operands, NULL, NULL);
1116 [(set_attr "length" "2,2,2")
1117 (set_attr "adjust_len" "*,*,out_plus_noclobber")
1118 (set_attr "cc" "set_n,set_czn,out_plus_noclobber")])
1120 ;; Adding a constant to NO_LD_REGS might have lead to a reload of
1121 ;; that constant to LD_REGS. We don't add a scratch to *addhi3
1122 ;; itself because that insn is special to reload.
1124 (define_peephole2 ; addhi3_clobber
1125 [(set (match_operand:HI 0 "d_register_operand" "")
1126 (match_operand:HI 1 "const_int_operand" ""))
1127 (set (match_operand:HI 2 "l_register_operand" "")
1128 (plus:HI (match_dup 2)
1130 "peep2_reg_dead_p (2, operands[0])"
1131 [(parallel [(set (match_dup 2)
1132 (plus:HI (match_dup 2)
1134 (clobber (match_dup 3))])]
1136 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
1139 ;; Same, but with reload to NO_LD_REGS
1140 ;; Combine *reload_inhi with *addhi3
1142 (define_peephole2 ; addhi3_clobber
1143 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
1144 (match_operand:HI 1 "const_int_operand" ""))
1145 (clobber (match_operand:QI 2 "d_register_operand" ""))])
1146 (set (match_operand:HI 3 "l_register_operand" "")
1147 (plus:HI (match_dup 3)
1149 "peep2_reg_dead_p (2, operands[0])"
1150 [(parallel [(set (match_dup 3)
1151 (plus:HI (match_dup 3)
1153 (clobber (match_dup 2))])])
1155 (define_insn "addhi3_clobber"
1156 [(set (match_operand:HI 0 "register_operand" "=d,l")
1157 (plus:HI (match_operand:HI 1 "register_operand" "%0,0")
1158 (match_operand:HI 2 "const_int_operand" "n,n")))
1159 (clobber (match_scratch:QI 3 "=X,&d"))]
1162 gcc_assert (REGNO (operands[0]) == REGNO (operands[1]));
1164 return avr_out_plus (operands, NULL, NULL);
1166 [(set_attr "length" "4")
1167 (set_attr "adjust_len" "out_plus")
1168 (set_attr "cc" "out_plus")])
1171 (define_insn "addsi3"
1172 [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r")
1173 (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0")
1174 (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n")))
1175 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1178 static const char * const asm_code[] =
1180 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2",
1181 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))",
1186 if (*asm_code[which_alternative])
1187 return asm_code[which_alternative];
1189 return avr_out_plus (operands, NULL, NULL);
1191 [(set_attr "length" "4,4,4,8")
1192 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1193 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1195 (define_insn "*addpsi3_zero_extend.qi"
1196 [(set (match_operand:PSI 0 "register_operand" "=r")
1197 (plus:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
1198 (match_operand:PSI 2 "register_operand" "0")))]
1200 "add %A0,%A1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1201 [(set_attr "length" "3")
1202 (set_attr "cc" "set_n")])
1204 (define_insn "*addpsi3_zero_extend.hi"
1205 [(set (match_operand:PSI 0 "register_operand" "=r")
1206 (plus:PSI (zero_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1207 (match_operand:PSI 2 "register_operand" "0")))]
1209 "add %A0,%A1\;adc %B0,%B1\;adc %C0,__zero_reg__"
1210 [(set_attr "length" "3")
1211 (set_attr "cc" "set_n")])
1213 (define_insn "*addpsi3_sign_extend.hi"
1214 [(set (match_operand:PSI 0 "register_operand" "=r")
1215 (plus:PSI (sign_extend:PSI (match_operand:HI 1 "register_operand" "r"))
1216 (match_operand:PSI 2 "register_operand" "0")))]
1218 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;sbrc %B1,7\;dec %C0"
1219 [(set_attr "length" "5")
1220 (set_attr "cc" "set_n")])
1222 (define_insn "*addsi3_zero_extend"
1223 [(set (match_operand:SI 0 "register_operand" "=r")
1224 (plus:SI (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
1225 (match_operand:SI 2 "register_operand" "0")))]
1227 "add %A0,%1\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1228 [(set_attr "length" "4")
1229 (set_attr "cc" "set_n")])
1231 (define_insn "*addsi3_zero_extend.hi"
1232 [(set (match_operand:SI 0 "register_operand" "=r")
1233 (plus:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))
1234 (match_operand:SI 2 "register_operand" "0")))]
1236 "add %A0,%1\;adc %B0,%B1\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1237 [(set_attr "length" "4")
1238 (set_attr "cc" "set_n")])
1240 (define_insn "addpsi3"
1241 [(set (match_operand:PSI 0 "register_operand" "=r,d ,d,r")
1242 (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
1243 (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
1244 (clobber (match_scratch:QI 3 "=X,X ,X,&d"))]
1247 static const char * const asm_code[] =
1249 "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2",
1250 "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))",
1255 if (*asm_code[which_alternative])
1256 return asm_code[which_alternative];
1258 return avr_out_plus (operands, NULL, NULL);
1260 [(set_attr "length" "3,3,3,6")
1261 (set_attr "adjust_len" "*,*,out_plus,out_plus")
1262 (set_attr "cc" "set_n,set_czn,out_plus,out_plus")])
1264 (define_insn "subpsi3"
1265 [(set (match_operand:PSI 0 "register_operand" "=r")
1266 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1267 (match_operand:PSI 2 "register_operand" "r")))]
1269 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2"
1270 [(set_attr "length" "3")
1271 (set_attr "cc" "set_czn")])
1273 (define_insn "*subpsi3_zero_extend.qi"
1274 [(set (match_operand:PSI 0 "register_operand" "=r")
1275 (minus:PSI (match_operand:SI 1 "register_operand" "0")
1276 (zero_extend:PSI (match_operand:QI 2 "register_operand" "r"))))]
1278 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__"
1279 [(set_attr "length" "3")
1280 (set_attr "cc" "set_czn")])
1282 (define_insn "*subpsi3_zero_extend.hi"
1283 [(set (match_operand:PSI 0 "register_operand" "=r")
1284 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1285 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1287 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__"
1288 [(set_attr "length" "3")
1289 (set_attr "cc" "set_czn")])
1291 (define_insn "*subpsi3_sign_extend.hi"
1292 [(set (match_operand:PSI 0 "register_operand" "=r")
1293 (minus:PSI (match_operand:PSI 1 "register_operand" "0")
1294 (sign_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
1296 "sub %A0,%A2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbrc %B2,7\;inc %C0"
1297 [(set_attr "length" "5")
1298 (set_attr "cc" "set_czn")])
1300 ;-----------------------------------------------------------------------------
1302 (define_insn "subqi3"
1303 [(set (match_operand:QI 0 "register_operand" "=r,d")
1304 (minus:QI (match_operand:QI 1 "register_operand" "0,0")
1305 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
1310 [(set_attr "length" "1,1")
1311 (set_attr "cc" "set_czn,set_czn")])
1313 (define_insn "subhi3"
1314 [(set (match_operand:HI 0 "register_operand" "=r,d")
1315 (minus:HI (match_operand:HI 1 "register_operand" "0,0")
1316 (match_operand:HI 2 "nonmemory_operand" "r,i")))]
1319 sub %A0,%A2\;sbc %B0,%B2
1320 subi %A0,lo8(%2)\;sbci %B0,hi8(%2)"
1321 [(set_attr "length" "2,2")
1322 (set_attr "cc" "set_czn,set_czn")])
1324 (define_insn "*subhi3_zero_extend1"
1325 [(set (match_operand:HI 0 "register_operand" "=r")
1326 (minus:HI (match_operand:HI 1 "register_operand" "0")
1327 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1329 "sub %A0,%2\;sbc %B0,__zero_reg__"
1330 [(set_attr "length" "2")
1331 (set_attr "cc" "set_czn")])
1333 (define_insn "*subhi3.sign_extend2"
1334 [(set (match_operand:HI 0 "register_operand" "=r")
1335 (minus:HI (match_operand:HI 1 "register_operand" "0")
1336 (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1339 return reg_overlap_mentioned_p (operands[0], operands[2])
1340 ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0"
1341 : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0";
1343 [(set_attr "length" "5")
1344 (set_attr "cc" "clobber")])
1346 (define_insn "subsi3"
1347 [(set (match_operand:SI 0 "register_operand" "=r")
1348 (minus:SI (match_operand:SI 1 "register_operand" "0")
1349 (match_operand:SI 2 "register_operand" "r")))]
1351 "sub %0,%2\;sbc %B0,%B2\;sbc %C0,%C2\;sbc %D0,%D2"
1352 [(set_attr "length" "4")
1353 (set_attr "cc" "set_czn")])
1355 (define_insn "*subsi3_zero_extend"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (minus:SI (match_operand:SI 1 "register_operand" "0")
1358 (zero_extend:SI (match_operand:QI 2 "register_operand" "r"))))]
1360 "sub %A0,%2\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1361 [(set_attr "length" "4")
1362 (set_attr "cc" "set_czn")])
1364 (define_insn "*subsi3_zero_extend.hi"
1365 [(set (match_operand:SI 0 "register_operand" "=r")
1366 (minus:SI (match_operand:SI 1 "register_operand" "0")
1367 (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1369 "sub %A0,%2\;sbc %B0,%B2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__"
1370 [(set_attr "length" "4")
1371 (set_attr "cc" "set_czn")])
1373 ;******************************************************************************
1376 (define_expand "mulqi3"
1377 [(set (match_operand:QI 0 "register_operand" "")
1378 (mult:QI (match_operand:QI 1 "register_operand" "")
1379 (match_operand:QI 2 "register_operand" "")))]
1384 emit_insn (gen_mulqi3_call (operands[0], operands[1], operands[2]));
1389 (define_insn "*mulqi3_enh"
1390 [(set (match_operand:QI 0 "register_operand" "=r")
1391 (mult:QI (match_operand:QI 1 "register_operand" "r")
1392 (match_operand:QI 2 "register_operand" "r")))]
1397 [(set_attr "length" "3")
1398 (set_attr "cc" "clobber")])
1400 (define_expand "mulqi3_call"
1401 [(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
1402 (set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
1403 (parallel [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1404 (clobber (reg:QI 22))])
1405 (set (match_operand:QI 0 "register_operand" "") (reg:QI 24))]
1409 (define_insn "*mulqi3_call"
1410 [(set (reg:QI 24) (mult:QI (reg:QI 24) (reg:QI 22)))
1411 (clobber (reg:QI 22))]
1414 [(set_attr "type" "xcall")
1415 (set_attr "cc" "clobber")])
1417 ;; "umulqi3_highpart"
1418 ;; "smulqi3_highpart"
1419 (define_insn "<extend_su>mulqi3_highpart"
1420 [(set (match_operand:QI 0 "register_operand" "=r")
1422 (lshiftrt:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1423 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1426 "mul<extend_s> %1,%2
1429 [(set_attr "length" "3")
1430 (set_attr "cc" "clobber")])
1433 ;; Used when expanding div or mod inline for some special values
1434 (define_insn "*subqi3.ashiftrt7"
1435 [(set (match_operand:QI 0 "register_operand" "=r")
1436 (minus:QI (match_operand:QI 1 "register_operand" "0")
1437 (ashiftrt:QI (match_operand:QI 2 "register_operand" "r")
1441 [(set_attr "length" "2")
1442 (set_attr "cc" "clobber")])
1444 (define_insn "*addqi3.lt0"
1445 [(set (match_operand:QI 0 "register_operand" "=r")
1446 (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r")
1448 (match_operand:QI 2 "register_operand" "0")))]
1451 [(set_attr "length" "2")
1452 (set_attr "cc" "clobber")])
1454 (define_insn "*addhi3.lt0"
1455 [(set (match_operand:HI 0 "register_operand" "=w,r")
1456 (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r")
1458 (match_operand:HI 2 "register_operand" "0,0")))
1459 (clobber (match_scratch:QI 3 "=X,&1"))]
1462 sbrc %1,7\;adiw %0,1
1463 lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__"
1464 [(set_attr "length" "2,3")
1465 (set_attr "cc" "clobber")])
1467 (define_insn "*addpsi3.lt0"
1468 [(set (match_operand:PSI 0 "register_operand" "=r")
1469 (plus:PSI (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "r")
1471 (match_operand:PSI 2 "register_operand" "0")))]
1473 "mov __tmp_reg__,%C1\;lsl __tmp_reg__
1474 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__"
1475 [(set_attr "length" "5")
1476 (set_attr "cc" "clobber")])
1478 (define_insn "*addsi3.lt0"
1479 [(set (match_operand:SI 0 "register_operand" "=r")
1480 (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
1482 (match_operand:SI 2 "register_operand" "0")))]
1484 "mov __tmp_reg__,%D1\;lsl __tmp_reg__
1485 adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__"
1486 [(set_attr "length" "6")
1487 (set_attr "cc" "clobber")])
1492 (define_insn "<extend_u>mulqihi3"
1493 [(set (match_operand:HI 0 "register_operand" "=r")
1494 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1495 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>"))))]
1497 "mul<extend_s> %1,%2
1500 [(set_attr "length" "3")
1501 (set_attr "cc" "clobber")])
1503 (define_insn "usmulqihi3"
1504 [(set (match_operand:HI 0 "register_operand" "=r")
1505 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1506 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1511 [(set_attr "length" "3")
1512 (set_attr "cc" "clobber")])
1514 ;; Above insn is not canonicalized by insn combine, so here is a version with
1515 ;; operands swapped.
1517 (define_insn "*sumulqihi3"
1518 [(set (match_operand:HI 0 "register_operand" "=r")
1519 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1520 (zero_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1525 [(set_attr "length" "3")
1526 (set_attr "cc" "clobber")])
1528 ;; One-extend operand 1
1530 (define_insn "*osmulqihi3"
1531 [(set (match_operand:HI 0 "register_operand" "=&r")
1532 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "a"))))
1533 (sign_extend:HI (match_operand:QI 2 "register_operand" "a"))))]
1539 [(set_attr "length" "4")
1540 (set_attr "cc" "clobber")])
1542 (define_insn "*oumulqihi3"
1543 [(set (match_operand:HI 0 "register_operand" "=&r")
1544 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
1545 (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
1551 [(set_attr "length" "4")
1552 (set_attr "cc" "clobber")])
1554 ;******************************************************************************
1555 ; multiply-add/sub QI: $0 = $3 +/- $1*$2
1556 ;******************************************************************************
1558 (define_insn "*maddqi4"
1559 [(set (match_operand:QI 0 "register_operand" "=r")
1560 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1561 (match_operand:QI 2 "register_operand" "r"))
1562 (match_operand:QI 3 "register_operand" "0")))]
1568 [(set_attr "length" "4")
1569 (set_attr "cc" "clobber")])
1571 (define_insn "*msubqi4"
1572 [(set (match_operand:QI 0 "register_operand" "=r")
1573 (minus:QI (match_operand:QI 3 "register_operand" "0")
1574 (mult:QI (match_operand:QI 1 "register_operand" "r")
1575 (match_operand:QI 2 "register_operand" "r"))))]
1580 [(set_attr "length" "4")
1581 (set_attr "cc" "clobber")])
1583 (define_insn_and_split "*maddqi4.const"
1584 [(set (match_operand:QI 0 "register_operand" "=r")
1585 (plus:QI (mult:QI (match_operand:QI 1 "register_operand" "r")
1586 (match_operand:QI 2 "const_int_operand" "n"))
1587 (match_operand:QI 3 "register_operand" "0")))
1588 (clobber (match_scratch:QI 4 "=&d"))]
1591 "&& reload_completed"
1596 (plus:QI (mult:QI (match_dup 1)
1601 (define_insn_and_split "*msubqi4.const"
1602 [(set (match_operand:QI 0 "register_operand" "=r")
1603 (minus:QI (match_operand:QI 3 "register_operand" "0")
1604 (mult:QI (match_operand:QI 1 "register_operand" "r")
1605 (match_operand:QI 2 "const_int_operand" "n"))))
1606 (clobber (match_scratch:QI 4 "=&d"))]
1609 "&& reload_completed"
1614 (minus:QI (match_dup 3)
1615 (mult:QI (match_dup 1)
1620 ;******************************************************************************
1621 ; multiply-add/sub HI: $0 = $3 +/- $1*$2 with 8-bit values $1, $2
1622 ;******************************************************************************
1624 ;; We don't use standard insns/expanders as they lead to cumbersome code for,
1627 ;; int foo (unsigned char z)
1629 ;; extern int aInt[];
1630 ;; return aInt[3*z+2];
1633 ;; because the constant +4 then is added explicitely instead of consuming it
1634 ;; with the aInt symbol. Therefore, we rely on insn combine which takes costs
1635 ;; into account more accurately and doesn't do burte-force multiply-add/sub.
1636 ;; The implementational effort is the same so we are fine with that approach.
1641 (define_insn "*<extend_u>maddqihi4"
1642 [(set (match_operand:HI 0 "register_operand" "=r")
1643 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1644 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))
1645 (match_operand:HI 3 "register_operand" "0")))]
1648 "mul<extend_s> %1,%2
1652 [(set_attr "length" "4")
1653 (set_attr "cc" "clobber")])
1657 (define_insn "*<extend_u>msubqihi4"
1658 [(set (match_operand:HI 0 "register_operand" "=r")
1659 (minus:HI (match_operand:HI 3 "register_operand" "0")
1660 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1661 (any_extend:HI (match_operand:QI 2 "register_operand" "<mul_r_d>")))))]
1663 "mul<extend_s> %1,%2
1667 [(set_attr "length" "4")
1668 (set_attr "cc" "clobber")])
1672 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1673 [(set (match_operand:HI 0 "register_operand" "=r")
1674 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1675 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))
1676 (match_operand:HI 3 "register_operand" "0")))]
1679 && <any_extend:CODE> != <any_extend2:CODE>"
1681 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1682 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1684 return "add %A0,r0\;adc %B0,r1\;clr __zero_reg__";
1686 [(set_attr "length" "4")
1687 (set_attr "cc" "clobber")])
1691 (define_insn "*<any_extend:extend_su><any_extend2:extend_su>msubqihi4"
1692 [(set (match_operand:HI 0 "register_operand" "=r")
1693 (minus:HI (match_operand:HI 3 "register_operand" "0")
1694 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "a"))
1695 (any_extend2:HI (match_operand:QI 2 "register_operand" "a")))))]
1698 && <any_extend:CODE> != <any_extend2:CODE>"
1700 output_asm_insn (<any_extend:CODE> == SIGN_EXTEND
1701 ? "mulsu %1,%2" : "mulsu %2,%1", operands);
1703 return "sub %A0,r0\;sbc %B0,r1\;clr __zero_reg__";
1705 [(set_attr "length" "4")
1706 (set_attr "cc" "clobber")])
1708 ;; Handle small constants
1710 ;; Special case of a += 2*b as frequently seen with accesses to int arrays.
1711 ;; This is shorter, faster than MUL and has lower register pressure.
1713 (define_insn_and_split "*umaddqihi4.2"
1714 [(set (match_operand:HI 0 "register_operand" "=r")
1715 (plus:HI (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1717 (match_operand:HI 2 "register_operand" "r")))]
1719 && !reg_overlap_mentioned_p (operands[0], operands[1])"
1720 { gcc_unreachable(); }
1724 ; *addhi3_zero_extend
1726 (plus:HI (zero_extend:HI (match_dup 1))
1728 ; *addhi3_zero_extend
1730 (plus:HI (zero_extend:HI (match_dup 1))
1733 ;; "umaddqihi4.uconst"
1734 ;; "maddqihi4.sconst"
1735 (define_insn_and_split "*<extend_u>maddqihi4.<extend_su>const"
1736 [(set (match_operand:HI 0 "register_operand" "=r")
1737 (plus:HI (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1738 (match_operand:HI 2 "<extend_su>8_operand" "n"))
1739 (match_operand:HI 3 "register_operand" "0")))
1740 (clobber (match_scratch:QI 4 "=&d"))]
1743 "&& reload_completed"
1746 ; *umaddqihi4 resp. *maddqihi4
1748 (plus:HI (mult:HI (any_extend:HI (match_dup 1))
1749 (any_extend:HI (match_dup 4)))
1752 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1755 ;; "*umsubqihi4.uconst"
1756 ;; "*msubqihi4.sconst"
1757 (define_insn_and_split "*<extend_u>msubqihi4.<extend_su>const"
1758 [(set (match_operand:HI 0 "register_operand" "=r")
1759 (minus:HI (match_operand:HI 3 "register_operand" "0")
1760 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1761 (match_operand:HI 2 "<extend_su>8_operand" "n"))))
1762 (clobber (match_scratch:QI 4 "=&d"))]
1765 "&& reload_completed"
1768 ; *umsubqihi4 resp. *msubqihi4
1770 (minus:HI (match_dup 3)
1771 (mult:HI (any_extend:HI (match_dup 1))
1772 (any_extend:HI (match_dup 4)))))]
1774 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1777 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1778 ;; for MULT with power of 2 and skips trying MULT insn above.
1780 (define_insn_and_split "*umsubqihi4.uconst.ashift"
1781 [(set (match_operand:HI 0 "register_operand" "=r")
1782 (minus:HI (match_operand:HI 3 "register_operand" "0")
1783 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
1784 (match_operand:HI 2 "const_2_to_7_operand" "n"))))
1785 (clobber (match_scratch:QI 4 "=&d"))]
1788 "&& reload_completed"
1793 (minus:HI (match_dup 3)
1794 (mult:HI (zero_extend:HI (match_dup 1))
1795 (zero_extend:HI (match_dup 4)))))]
1797 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1800 ;; Same as the insn above, but combiner tries versions canonicalized to ASHIFT
1801 ;; for MULT with power of 2 and skips trying MULT insn above. We omit 128
1802 ;; because this would require an extra pattern for just one value.
1804 (define_insn_and_split "*msubqihi4.sconst.ashift"
1805 [(set (match_operand:HI 0 "register_operand" "=r")
1806 (minus:HI (match_operand:HI 3 "register_operand" "0")
1807 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1808 (match_operand:HI 2 "const_1_to_6_operand" "M"))))
1809 (clobber (match_scratch:QI 4 "=&d"))]
1812 "&& reload_completed"
1817 (minus:HI (match_dup 3)
1818 (mult:HI (sign_extend:HI (match_dup 1))
1819 (sign_extend:HI (match_dup 4)))))]
1821 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
1824 ;; For signed/unsigned combinations that require narrow constraint "a"
1825 ;; just provide a pattern if signed/unsigned combination is actually needed.
1827 (define_insn_and_split "*sumaddqihi4.uconst"
1828 [(set (match_operand:HI 0 "register_operand" "=r")
1829 (plus:HI (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1830 (match_operand:HI 2 "u8_operand" "M"))
1831 (match_operand:HI 3 "register_operand" "0")))
1832 (clobber (match_scratch:QI 4 "=&a"))]
1834 && !s8_operand (operands[2], VOIDmode)"
1836 "&& reload_completed"
1841 (plus:HI (mult:HI (sign_extend:HI (match_dup 1))
1842 (zero_extend:HI (match_dup 4)))
1845 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1848 (define_insn_and_split "*sumsubqihi4.uconst"
1849 [(set (match_operand:HI 0 "register_operand" "=r")
1850 (minus:HI (match_operand:HI 3 "register_operand" "0")
1851 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1852 (match_operand:HI 2 "u8_operand" "M"))))
1853 (clobber (match_scratch:QI 4 "=&a"))]
1855 && !s8_operand (operands[2], VOIDmode)"
1857 "&& reload_completed"
1862 (minus:HI (match_dup 3)
1863 (mult:HI (sign_extend:HI (match_dup 1))
1864 (zero_extend:HI (match_dup 4)))))]
1866 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1869 ;******************************************************************************
1870 ; mul HI: $1 = sign/zero-extend, $2 = small constant
1871 ;******************************************************************************
1873 ;; "*muluqihi3.uconst"
1874 ;; "*mulsqihi3.sconst"
1875 (define_insn_and_split "*mul<extend_su>qihi3.<extend_su>const"
1876 [(set (match_operand:HI 0 "register_operand" "=r")
1877 (mult:HI (any_extend:HI (match_operand:QI 1 "register_operand" "<mul_r_d>"))
1878 (match_operand:HI 2 "<extend_su>8_operand" "n")))
1879 (clobber (match_scratch:QI 3 "=&d"))]
1882 "&& reload_completed"
1885 ; umulqihi3 resp. mulqihi3
1887 (mult:HI (any_extend:HI (match_dup 1))
1888 (any_extend:HI (match_dup 3))))]
1890 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1893 (define_insn_and_split "*muluqihi3.sconst"
1894 [(set (match_operand:HI 0 "register_operand" "=r")
1895 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "a"))
1896 (match_operand:HI 2 "s8_operand" "n")))
1897 (clobber (match_scratch:QI 3 "=&a"))]
1900 "&& reload_completed"
1905 (mult:HI (zero_extend:HI (match_dup 1))
1906 (sign_extend:HI (match_dup 3))))]
1908 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1911 (define_insn_and_split "*mulsqihi3.uconst"
1912 [(set (match_operand:HI 0 "register_operand" "=r")
1913 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1914 (match_operand:HI 2 "u8_operand" "M")))
1915 (clobber (match_scratch:QI 3 "=&a"))]
1918 "&& reload_completed"
1923 (mult:HI (zero_extend:HI (match_dup 3))
1924 (sign_extend:HI (match_dup 1))))]
1926 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1929 (define_insn_and_split "*mulsqihi3.oconst"
1930 [(set (match_operand:HI 0 "register_operand" "=&r")
1931 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1932 (match_operand:HI 2 "o8_operand" "n")))
1933 (clobber (match_scratch:QI 3 "=&a"))]
1936 "&& reload_completed"
1941 (mult:HI (not:HI (zero_extend:HI (not:QI (match_dup 3))))
1942 (sign_extend:HI (match_dup 1))))]
1944 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
1947 ;; The EXTEND of $1 only appears in combine, we don't see it in expand so that
1948 ;; expand decides to use ASHIFT instead of MUL because ASHIFT costs are cheaper
1949 ;; at that time. Fix that.
1951 (define_insn "*ashiftqihi2.signx.1"
1952 [(set (match_operand:HI 0 "register_operand" "=r,*r")
1953 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0,r"))
1957 lsl %A0\;sbc %B0,%B0
1958 mov %A0,%1\;lsl %A0\;sbc %B0,%B0"
1959 [(set_attr "length" "2,3")
1960 (set_attr "cc" "clobber")])
1962 (define_insn_and_split "*ashifthi3.signx.const"
1963 [(set (match_operand:HI 0 "register_operand" "=r")
1964 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "d"))
1965 (match_operand:HI 2 "const_2_to_6_operand" "I")))
1966 (clobber (match_scratch:QI 3 "=&d"))]
1969 "&& reload_completed"
1974 (mult:HI (sign_extend:HI (match_dup 1))
1975 (sign_extend:HI (match_dup 3))))]
1977 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
1980 (define_insn_and_split "*ashifthi3.signx.const7"
1981 [(set (match_operand:HI 0 "register_operand" "=r")
1982 (ashift:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
1984 (clobber (match_scratch:QI 2 "=&a"))]
1987 "&& reload_completed"
1992 (mult:HI (zero_extend:HI (match_dup 2))
1993 (sign_extend:HI (match_dup 1))))]
1995 operands[3] = gen_int_mode (1 << 7, QImode);
1998 (define_insn_and_split "*ashifthi3.zerox.const"
1999 [(set (match_operand:HI 0 "register_operand" "=r")
2000 (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2001 (match_operand:HI 2 "const_2_to_7_operand" "I")))
2002 (clobber (match_scratch:QI 3 "=&d"))]
2005 "&& reload_completed"
2010 (mult:HI (zero_extend:HI (match_dup 1))
2011 (zero_extend:HI (match_dup 3))))]
2013 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), QImode);
2016 ;******************************************************************************
2017 ; mul HI: $1 = sign-/zero-/one-extend, $2 = reg
2018 ;******************************************************************************
2020 (define_insn "mulsqihi3"
2021 [(set (match_operand:HI 0 "register_operand" "=&r")
2022 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
2023 (match_operand:HI 2 "register_operand" "a")))]
2030 [(set_attr "length" "5")
2031 (set_attr "cc" "clobber")])
2033 (define_insn "muluqihi3"
2034 [(set (match_operand:HI 0 "register_operand" "=&r")
2035 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r"))
2036 (match_operand:HI 2 "register_operand" "r")))]
2043 [(set_attr "length" "5")
2044 (set_attr "cc" "clobber")])
2046 ;; one-extend operand 1
2048 (define_insn "muloqihi3"
2049 [(set (match_operand:HI 0 "register_operand" "=&r")
2050 (mult:HI (not:HI (zero_extend:HI (not:QI (match_operand:QI 1 "register_operand" "r"))))
2051 (match_operand:HI 2 "register_operand" "r")))]
2059 [(set_attr "length" "6")
2060 (set_attr "cc" "clobber")])
2062 ;******************************************************************************
2064 (define_expand "mulhi3"
2065 [(set (match_operand:HI 0 "register_operand" "")
2066 (mult:HI (match_operand:HI 1 "register_operand" "")
2067 (match_operand:HI 2 "register_or_s9_operand" "")))]
2072 if (!register_operand (operands[2], HImode))
2073 operands[2] = force_reg (HImode, operands[2]);
2075 emit_insn (gen_mulhi3_call (operands[0], operands[1], operands[2]));
2079 /* For small constants we can do better by extending them on the fly.
2080 The constant can be loaded in one instruction and the widening
2081 multiplication is shorter. First try the unsigned variant because it
2082 allows constraint "d" instead of "a" for the signed version. */
2084 if (s9_operand (operands[2], HImode))
2086 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2088 if (u8_operand (operands[2], HImode))
2090 emit_insn (gen_muluqihi3 (operands[0], reg, operands[1]));
2092 else if (s8_operand (operands[2], HImode))
2094 emit_insn (gen_mulsqihi3 (operands[0], reg, operands[1]));
2098 emit_insn (gen_muloqihi3 (operands[0], reg, operands[1]));
2104 if (!register_operand (operands[2], HImode))
2105 operands[2] = force_reg (HImode, operands[2]);
2108 (define_insn "*mulhi3_enh"
2109 [(set (match_operand:HI 0 "register_operand" "=&r")
2110 (mult:HI (match_operand:HI 1 "register_operand" "r")
2111 (match_operand:HI 2 "register_operand" "r")))]
2114 return REGNO (operands[1]) == REGNO (operands[2])
2115 ? "mul %A1,%A1\;movw %0,r0\;mul %A1,%B1\;add %B0,r0\;add %B0,r0\;clr r1"
2116 : "mul %A1,%A2\;movw %0,r0\;mul %A1,%B2\;add %B0,r0\;mul %B1,%A2\;add %B0,r0\;clr r1";
2118 [(set_attr "length" "7")
2119 (set_attr "cc" "clobber")])
2121 (define_expand "mulhi3_call"
2122 [(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
2123 (set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
2124 (parallel [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2125 (clobber (reg:HI 22))
2126 (clobber (reg:QI 21))])
2127 (set (match_operand:HI 0 "register_operand" "") (reg:HI 24))]
2131 (define_insn "*mulhi3_call"
2132 [(set (reg:HI 24) (mult:HI (reg:HI 24) (reg:HI 22)))
2133 (clobber (reg:HI 22))
2134 (clobber (reg:QI 21))]
2137 [(set_attr "type" "xcall")
2138 (set_attr "cc" "clobber")])
2140 ;; To support widening multiplication with constant we postpone
2141 ;; expanding to the implicit library call until post combine and
2142 ;; prior to register allocation. Clobber all hard registers that
2143 ;; might be used by the (widening) multiply until it is split and
2144 ;; it's final register footprint is worked out.
2146 (define_expand "mulsi3"
2147 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2148 (mult:SI (match_operand:SI 1 "register_operand" "")
2149 (match_operand:SI 2 "nonmemory_operand" "")))
2150 (clobber (reg:HI 26))
2151 (clobber (reg:DI 18))])]
2154 if (u16_operand (operands[2], SImode))
2156 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2157 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2161 if (o16_operand (operands[2], SImode))
2163 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2164 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2169 (define_insn_and_split "*mulsi3"
2170 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2171 (mult:SI (match_operand:SI 1 "pseudo_register_operand" "r")
2172 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2173 (clobber (reg:HI 26))
2174 (clobber (reg:DI 18))]
2175 "AVR_HAVE_MUL && !reload_completed"
2176 { gcc_unreachable(); }
2182 (parallel [(set (reg:SI 22)
2183 (mult:SI (reg:SI 22)
2185 (clobber (reg:HI 26))])
2189 if (u16_operand (operands[2], SImode))
2191 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2192 emit_insn (gen_muluhisi3 (operands[0], operands[2], operands[1]));
2196 if (o16_operand (operands[2], SImode))
2198 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2199 emit_insn (gen_mulohisi3 (operands[0], operands[2], operands[1]));
2206 (define_insn_and_split "mulu<mode>si3"
2207 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2208 (mult:SI (zero_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2209 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2210 (clobber (reg:HI 26))
2211 (clobber (reg:DI 18))]
2212 "AVR_HAVE_MUL && !reload_completed"
2213 { gcc_unreachable(); }
2220 (mult:SI (zero_extend:SI (reg:HI 26))
2225 /* Do the QI -> HI extension explicitely before the multiplication. */
2226 /* Do the HI -> SI extension implicitely and after the multiplication. */
2228 if (QImode == <MODE>mode)
2229 operands[1] = gen_rtx_ZERO_EXTEND (HImode, operands[1]);
2231 if (u16_operand (operands[2], SImode))
2233 operands[1] = force_reg (HImode, operands[1]);
2234 operands[2] = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2235 emit_insn (gen_umulhisi3 (operands[0], operands[1], operands[2]));
2242 (define_insn_and_split "muls<mode>si3"
2243 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2244 (mult:SI (sign_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2245 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2246 (clobber (reg:HI 26))
2247 (clobber (reg:DI 18))]
2248 "AVR_HAVE_MUL && !reload_completed"
2249 { gcc_unreachable(); }
2256 (mult:SI (sign_extend:SI (reg:HI 26))
2261 /* Do the QI -> HI extension explicitely before the multiplication. */
2262 /* Do the HI -> SI extension implicitely and after the multiplication. */
2264 if (QImode == <MODE>mode)
2265 operands[1] = gen_rtx_SIGN_EXTEND (HImode, operands[1]);
2267 if (u16_operand (operands[2], SImode)
2268 || s16_operand (operands[2], SImode))
2270 rtx xop2 = force_reg (HImode, gen_int_mode (INTVAL (operands[2]), HImode));
2272 operands[1] = force_reg (HImode, operands[1]);
2274 if (u16_operand (operands[2], SImode))
2275 emit_insn (gen_usmulhisi3 (operands[0], xop2, operands[1]));
2277 emit_insn (gen_mulhisi3 (operands[0], operands[1], xop2));
2283 ;; One-extend operand 1
2285 (define_insn_and_split "mulohisi3"
2286 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2287 (mult:SI (not:SI (zero_extend:SI
2288 (not:HI (match_operand:HI 1 "pseudo_register_operand" "r"))))
2289 (match_operand:SI 2 "pseudo_register_or_const_int_operand" "rn")))
2290 (clobber (reg:HI 26))
2291 (clobber (reg:DI 18))]
2292 "AVR_HAVE_MUL && !reload_completed"
2293 { gcc_unreachable(); }
2300 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2308 (define_expand "<extend_u>mulhisi3"
2309 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2310 (mult:SI (any_extend:SI (match_operand:HI 1 "register_operand" ""))
2311 (any_extend:SI (match_operand:HI 2 "register_operand" ""))))
2312 (clobber (reg:HI 26))
2313 (clobber (reg:DI 18))])]
2317 (define_expand "usmulhisi3"
2318 [(parallel [(set (match_operand:SI 0 "register_operand" "")
2319 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" ""))
2320 (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
2321 (clobber (reg:HI 26))
2322 (clobber (reg:DI 18))])]
2326 ;; "*uumulqihisi3" "*uumulhiqisi3" "*uumulhihisi3" "*uumulqiqisi3"
2327 ;; "*usmulqihisi3" "*usmulhiqisi3" "*usmulhihisi3" "*usmulqiqisi3"
2328 ;; "*sumulqihisi3" "*sumulhiqisi3" "*sumulhihisi3" "*sumulqiqisi3"
2329 ;; "*ssmulqihisi3" "*ssmulhiqisi3" "*ssmulhihisi3" "*ssmulqiqisi3"
2330 (define_insn_and_split
2331 "*<any_extend:extend_su><any_extend2:extend_su>mul<QIHI:mode><QIHI2:mode>si3"
2332 [(set (match_operand:SI 0 "pseudo_register_operand" "=r")
2333 (mult:SI (any_extend:SI (match_operand:QIHI 1 "pseudo_register_operand" "r"))
2334 (any_extend2:SI (match_operand:QIHI2 2 "pseudo_register_operand" "r"))))
2335 (clobber (reg:HI 26))
2336 (clobber (reg:DI 18))]
2337 "AVR_HAVE_MUL && !reload_completed"
2338 { gcc_unreachable(); }
2345 (mult:SI (match_dup 3)
2350 rtx xop1 = operands[1];
2351 rtx xop2 = operands[2];
2353 /* Do the QI -> HI extension explicitely before the multiplication. */
2354 /* Do the HI -> SI extension implicitely and after the multiplication. */
2356 if (QImode == <QIHI:MODE>mode)
2357 xop1 = gen_rtx_fmt_e (<any_extend:CODE>, HImode, xop1);
2359 if (QImode == <QIHI2:MODE>mode)
2360 xop2 = gen_rtx_fmt_e (<any_extend2:CODE>, HImode, xop2);
2362 if (<any_extend:CODE> == <any_extend2:CODE>
2363 || <any_extend:CODE> == ZERO_EXTEND)
2367 operands[3] = gen_rtx_fmt_e (<any_extend:CODE>, SImode, gen_rtx_REG (HImode, 18));
2368 operands[4] = gen_rtx_fmt_e (<any_extend2:CODE>, SImode, gen_rtx_REG (HImode, 26));
2372 /* <any_extend:CODE> = SIGN_EXTEND */
2373 /* <any_extend2:CODE> = ZERO_EXTEND */
2377 operands[3] = gen_rtx_ZERO_EXTEND (SImode, gen_rtx_REG (HImode, 18));
2378 operands[4] = gen_rtx_SIGN_EXTEND (SImode, gen_rtx_REG (HImode, 26));
2382 ;; "smulhi3_highpart"
2383 ;; "umulhi3_highpart"
2384 (define_expand "<extend_su>mulhi3_highpart"
2386 (match_operand:HI 1 "nonmemory_operand" ""))
2388 (match_operand:HI 2 "nonmemory_operand" ""))
2389 (parallel [(set (reg:HI 24)
2390 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2391 (any_extend:SI (reg:HI 26)))
2393 (clobber (reg:HI 22))])
2394 (set (match_operand:HI 0 "register_operand" "")
2400 (define_insn "*mulsi3_call"
2402 (mult:SI (reg:SI 22)
2404 (clobber (reg:HI 26))]
2407 [(set_attr "type" "xcall")
2408 (set_attr "cc" "clobber")])
2411 ;; "*umulhisi3_call"
2412 (define_insn "*<extend_u>mulhisi3_call"
2414 (mult:SI (any_extend:SI (reg:HI 18))
2415 (any_extend:SI (reg:HI 26))))]
2417 "%~call __<extend_u>mulhisi3"
2418 [(set_attr "type" "xcall")
2419 (set_attr "cc" "clobber")])
2421 ;; "*umulhi3_highpart_call"
2422 ;; "*smulhi3_highpart_call"
2423 (define_insn "*<extend_su>mulhi3_highpart_call"
2425 (truncate:HI (lshiftrt:SI (mult:SI (any_extend:SI (reg:HI 18))
2426 (any_extend:SI (reg:HI 26)))
2428 (clobber (reg:HI 22))]
2430 "%~call __<extend_u>mulhisi3"
2431 [(set_attr "type" "xcall")
2432 (set_attr "cc" "clobber")])
2434 (define_insn "*usmulhisi3_call"
2436 (mult:SI (zero_extend:SI (reg:HI 18))
2437 (sign_extend:SI (reg:HI 26))))]
2439 "%~call __usmulhisi3"
2440 [(set_attr "type" "xcall")
2441 (set_attr "cc" "clobber")])
2443 (define_insn "*mul<extend_su>hisi3_call"
2445 (mult:SI (any_extend:SI (reg:HI 26))
2448 "%~call __mul<extend_su>hisi3"
2449 [(set_attr "type" "xcall")
2450 (set_attr "cc" "clobber")])
2452 (define_insn "*mulohisi3_call"
2454 (mult:SI (not:SI (zero_extend:SI (not:HI (reg:HI 26))))
2457 "%~call __mulohisi3"
2458 [(set_attr "type" "xcall")
2459 (set_attr "cc" "clobber")])
2461 ; / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / % / %
2464 ;; Generate lib1funcs.S calls ourselves, because:
2465 ;; - we know exactly which registers are clobbered (for QI and HI
2466 ;; modes, some of the call-used registers are preserved)
2467 ;; - we get both the quotient and the remainder at no extra cost
2468 ;; - we split the patterns only after the first CSE passes because
2469 ;; CSE has problems to operate on hard regs.
2471 (define_insn_and_split "divmodqi4"
2472 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2473 (div:QI (match_operand:QI 1 "pseudo_register_operand" "")
2474 (match_operand:QI 2 "pseudo_register_operand" "")))
2475 (set (match_operand:QI 3 "pseudo_register_operand" "")
2476 (mod:QI (match_dup 1) (match_dup 2)))
2477 (clobber (reg:QI 22))
2478 (clobber (reg:QI 23))
2479 (clobber (reg:QI 24))
2480 (clobber (reg:QI 25))])]
2482 "this divmodqi4 pattern should have been splitted;"
2484 [(set (reg:QI 24) (match_dup 1))
2485 (set (reg:QI 22) (match_dup 2))
2486 (parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2487 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2488 (clobber (reg:QI 22))
2489 (clobber (reg:QI 23))])
2490 (set (match_dup 0) (reg:QI 24))
2491 (set (match_dup 3) (reg:QI 25))]
2494 (define_insn "*divmodqi4_call"
2495 [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
2496 (set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
2497 (clobber (reg:QI 22))
2498 (clobber (reg:QI 23))]
2500 "%~call __divmodqi4"
2501 [(set_attr "type" "xcall")
2502 (set_attr "cc" "clobber")])
2504 (define_insn_and_split "udivmodqi4"
2505 [(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
2506 (udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
2507 (match_operand:QI 2 "pseudo_register_operand" "")))
2508 (set (match_operand:QI 3 "pseudo_register_operand" "")
2509 (umod:QI (match_dup 1) (match_dup 2)))
2510 (clobber (reg:QI 22))
2511 (clobber (reg:QI 23))
2512 (clobber (reg:QI 24))
2513 (clobber (reg:QI 25))])]
2515 "this udivmodqi4 pattern should have been splitted;"
2517 [(set (reg:QI 24) (match_dup 1))
2518 (set (reg:QI 22) (match_dup 2))
2519 (parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2520 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2521 (clobber (reg:QI 23))])
2522 (set (match_dup 0) (reg:QI 24))
2523 (set (match_dup 3) (reg:QI 25))]
2526 (define_insn "*udivmodqi4_call"
2527 [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
2528 (set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
2529 (clobber (reg:QI 23))]
2531 "%~call __udivmodqi4"
2532 [(set_attr "type" "xcall")
2533 (set_attr "cc" "clobber")])
2535 (define_insn_and_split "divmodhi4"
2536 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2537 (div:HI (match_operand:HI 1 "pseudo_register_operand" "")
2538 (match_operand:HI 2 "pseudo_register_operand" "")))
2539 (set (match_operand:HI 3 "pseudo_register_operand" "")
2540 (mod:HI (match_dup 1) (match_dup 2)))
2541 (clobber (reg:QI 21))
2542 (clobber (reg:HI 22))
2543 (clobber (reg:HI 24))
2544 (clobber (reg:HI 26))])]
2546 "this should have been splitted;"
2548 [(set (reg:HI 24) (match_dup 1))
2549 (set (reg:HI 22) (match_dup 2))
2550 (parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2551 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2552 (clobber (reg:HI 26))
2553 (clobber (reg:QI 21))])
2554 (set (match_dup 0) (reg:HI 22))
2555 (set (match_dup 3) (reg:HI 24))]
2558 (define_insn "*divmodhi4_call"
2559 [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
2560 (set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
2561 (clobber (reg:HI 26))
2562 (clobber (reg:QI 21))]
2564 "%~call __divmodhi4"
2565 [(set_attr "type" "xcall")
2566 (set_attr "cc" "clobber")])
2568 (define_insn_and_split "udivmodhi4"
2569 [(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
2570 (udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
2571 (match_operand:HI 2 "pseudo_register_operand" "")))
2572 (set (match_operand:HI 3 "pseudo_register_operand" "")
2573 (umod:HI (match_dup 1) (match_dup 2)))
2574 (clobber (reg:QI 21))
2575 (clobber (reg:HI 22))
2576 (clobber (reg:HI 24))
2577 (clobber (reg:HI 26))])]
2579 "this udivmodhi4 pattern should have been splitted.;"
2581 [(set (reg:HI 24) (match_dup 1))
2582 (set (reg:HI 22) (match_dup 2))
2583 (parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2584 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2585 (clobber (reg:HI 26))
2586 (clobber (reg:QI 21))])
2587 (set (match_dup 0) (reg:HI 22))
2588 (set (match_dup 3) (reg:HI 24))]
2591 (define_insn "*udivmodhi4_call"
2592 [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
2593 (set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
2594 (clobber (reg:HI 26))
2595 (clobber (reg:QI 21))]
2597 "%~call __udivmodhi4"
2598 [(set_attr "type" "xcall")
2599 (set_attr "cc" "clobber")])
2601 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2604 ;; To support widening multiplication with constant we postpone
2605 ;; expanding to the implicit library call until post combine and
2606 ;; prior to register allocation. Clobber all hard registers that
2607 ;; might be used by the (widening) multiply until it is split and
2608 ;; it's final register footprint is worked out.
2610 (define_expand "mulpsi3"
2611 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
2612 (mult:PSI (match_operand:PSI 1 "register_operand" "")
2613 (match_operand:PSI 2 "nonmemory_operand" "")))
2614 (clobber (reg:HI 26))
2615 (clobber (reg:DI 18))])]
2618 if (s8_operand (operands[2], PSImode))
2620 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2621 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2626 (define_insn "*umulqihipsi3"
2627 [(set (match_operand:PSI 0 "register_operand" "=&r")
2628 (mult:PSI (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))
2629 (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))))]
2638 [(set_attr "length" "7")
2639 (set_attr "cc" "clobber")])
2641 (define_insn "*umulhiqipsi3"
2642 [(set (match_operand:PSI 0 "register_operand" "=&r")
2643 (mult:PSI (zero_extend:PSI (match_operand:HI 2 "register_operand" "r"))
2644 (zero_extend:PSI (match_operand:QI 1 "register_operand" "r"))))]
2652 adc %C0,__zero_reg__"
2653 [(set_attr "length" "7")
2654 (set_attr "cc" "clobber")])
2656 (define_insn_and_split "mulsqipsi3"
2657 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2658 (mult:PSI (sign_extend:PSI (match_operand:QI 1 "pseudo_register_operand" "r"))
2659 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2660 (clobber (reg:HI 26))
2661 (clobber (reg:DI 18))]
2662 "AVR_HAVE_MUL && !reload_completed"
2663 { gcc_unreachable(); }
2670 (mult:PSI (sign_extend:PSI (reg:QI 25))
2675 (define_insn_and_split "*mulpsi3"
2676 [(set (match_operand:PSI 0 "pseudo_register_operand" "=r")
2677 (mult:PSI (match_operand:PSI 1 "pseudo_register_operand" "r")
2678 (match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
2679 (clobber (reg:HI 26))
2680 (clobber (reg:DI 18))]
2681 "AVR_HAVE_MUL && !reload_completed"
2682 { gcc_unreachable(); }
2688 (parallel [(set (reg:PSI 22)
2689 (mult:PSI (reg:PSI 22)
2691 (clobber (reg:QI 21))
2692 (clobber (reg:QI 25))
2693 (clobber (reg:HI 26))])
2697 if (s8_operand (operands[2], PSImode))
2699 rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
2700 emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
2705 (define_insn "*mulsqipsi3.libgcc"
2707 (mult:PSI (sign_extend:PSI (reg:QI 25))
2710 "%~call __mulsqipsi3"
2711 [(set_attr "type" "xcall")
2712 (set_attr "cc" "clobber")])
2714 (define_insn "*mulpsi3.libgcc"
2716 (mult:PSI (reg:PSI 22)
2718 (clobber (reg:QI 21))
2719 (clobber (reg:QI 25))
2720 (clobber (reg:HI 26))]
2723 [(set_attr "type" "xcall")
2724 (set_attr "cc" "clobber")])
2727 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2728 ;; 24-bit signed/unsigned division and modulo.
2729 ;; Notice that the libgcc implementation return the quotient in R22
2730 ;; and the remainder in R18 whereas the 32-bit [u]divmodsi4
2731 ;; implementation works the other way round.
2733 (define_insn_and_split "divmodpsi4"
2734 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2735 (div:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2736 (match_operand:PSI 2 "pseudo_register_operand" "")))
2737 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2738 (mod:PSI (match_dup 1)
2740 (clobber (reg:DI 18))
2741 (clobber (reg:QI 26))])]
2743 { gcc_unreachable(); }
2745 [(set (reg:PSI 22) (match_dup 1))
2746 (set (reg:PSI 18) (match_dup 2))
2747 (parallel [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2748 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2749 (clobber (reg:QI 21))
2750 (clobber (reg:QI 25))
2751 (clobber (reg:QI 26))])
2752 (set (match_dup 0) (reg:PSI 22))
2753 (set (match_dup 3) (reg:PSI 18))])
2755 (define_insn "*divmodpsi4_call"
2756 [(set (reg:PSI 22) (div:PSI (reg:PSI 22) (reg:PSI 18)))
2757 (set (reg:PSI 18) (mod:PSI (reg:PSI 22) (reg:PSI 18)))
2758 (clobber (reg:QI 21))
2759 (clobber (reg:QI 25))
2760 (clobber (reg:QI 26))]
2762 "%~call __divmodpsi4"
2763 [(set_attr "type" "xcall")
2764 (set_attr "cc" "clobber")])
2766 (define_insn_and_split "udivmodpsi4"
2767 [(parallel [(set (match_operand:PSI 0 "pseudo_register_operand" "")
2768 (udiv:PSI (match_operand:PSI 1 "pseudo_register_operand" "")
2769 (match_operand:PSI 2 "pseudo_register_operand" "")))
2770 (set (match_operand:PSI 3 "pseudo_register_operand" "")
2771 (umod:PSI (match_dup 1)
2773 (clobber (reg:DI 18))
2774 (clobber (reg:QI 26))])]
2776 { gcc_unreachable(); }
2778 [(set (reg:PSI 22) (match_dup 1))
2779 (set (reg:PSI 18) (match_dup 2))
2780 (parallel [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2781 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2782 (clobber (reg:QI 21))
2783 (clobber (reg:QI 25))
2784 (clobber (reg:QI 26))])
2785 (set (match_dup 0) (reg:PSI 22))
2786 (set (match_dup 3) (reg:PSI 18))])
2788 (define_insn "*udivmodpsi4_call"
2789 [(set (reg:PSI 22) (udiv:PSI (reg:PSI 22) (reg:PSI 18)))
2790 (set (reg:PSI 18) (umod:PSI (reg:PSI 22) (reg:PSI 18)))
2791 (clobber (reg:QI 21))
2792 (clobber (reg:QI 25))
2793 (clobber (reg:QI 26))]
2795 "%~call __udivmodpsi4"
2796 [(set_attr "type" "xcall")
2797 (set_attr "cc" "clobber")])
2799 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2801 (define_insn_and_split "divmodsi4"
2802 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2803 (div:SI (match_operand:SI 1 "pseudo_register_operand" "")
2804 (match_operand:SI 2 "pseudo_register_operand" "")))
2805 (set (match_operand:SI 3 "pseudo_register_operand" "")
2806 (mod:SI (match_dup 1) (match_dup 2)))
2807 (clobber (reg:SI 18))
2808 (clobber (reg:SI 22))
2809 (clobber (reg:HI 26))
2810 (clobber (reg:HI 30))])]
2812 "this divmodsi4 pattern should have been splitted;"
2814 [(set (reg:SI 22) (match_dup 1))
2815 (set (reg:SI 18) (match_dup 2))
2816 (parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2817 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2818 (clobber (reg:HI 26))
2819 (clobber (reg:HI 30))])
2820 (set (match_dup 0) (reg:SI 18))
2821 (set (match_dup 3) (reg:SI 22))]
2824 (define_insn "*divmodsi4_call"
2825 [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
2826 (set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
2827 (clobber (reg:HI 26))
2828 (clobber (reg:HI 30))]
2830 "%~call __divmodsi4"
2831 [(set_attr "type" "xcall")
2832 (set_attr "cc" "clobber")])
2834 (define_insn_and_split "udivmodsi4"
2835 [(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
2836 (udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
2837 (match_operand:SI 2 "pseudo_register_operand" "")))
2838 (set (match_operand:SI 3 "pseudo_register_operand" "")
2839 (umod:SI (match_dup 1) (match_dup 2)))
2840 (clobber (reg:SI 18))
2841 (clobber (reg:SI 22))
2842 (clobber (reg:HI 26))
2843 (clobber (reg:HI 30))])]
2845 "this udivmodsi4 pattern should have been splitted;"
2847 [(set (reg:SI 22) (match_dup 1))
2848 (set (reg:SI 18) (match_dup 2))
2849 (parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2850 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2851 (clobber (reg:HI 26))
2852 (clobber (reg:HI 30))])
2853 (set (match_dup 0) (reg:SI 18))
2854 (set (match_dup 3) (reg:SI 22))]
2857 (define_insn "*udivmodsi4_call"
2858 [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
2859 (set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
2860 (clobber (reg:HI 26))
2861 (clobber (reg:HI 30))]
2863 "%~call __udivmodsi4"
2864 [(set_attr "type" "xcall")
2865 (set_attr "cc" "clobber")])
2867 ;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
2870 (define_insn "andqi3"
2871 [(set (match_operand:QI 0 "register_operand" "=r,d")
2872 (and:QI (match_operand:QI 1 "register_operand" "%0,0")
2873 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2878 [(set_attr "length" "1,1")
2879 (set_attr "cc" "set_zn,set_zn")])
2881 (define_insn "andhi3"
2882 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2883 (and:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2884 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Ca2,n")))
2885 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2888 if (which_alternative == 0)
2889 return "and %A0,%A2\;and %B0,%B2";
2890 else if (which_alternative == 1)
2891 return "andi %A0,lo8(%2)\;andi %B0,hi8(%2)";
2893 return avr_out_bitop (insn, operands, NULL);
2895 [(set_attr "length" "2,2,2,4,4")
2896 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2897 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2899 (define_insn "andpsi3"
2900 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2901 (and:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2902 (match_operand:PSI 2 "nonmemory_operand" "r,n,Ca3,n")))
2903 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2906 if (which_alternative == 0)
2907 return "and %A0,%A2" CR_TAB
2908 "and %B0,%B2" CR_TAB
2911 return avr_out_bitop (insn, operands, NULL);
2913 [(set_attr "length" "3,3,6,6")
2914 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2915 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2917 (define_insn "andsi3"
2918 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
2919 (and:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
2920 (match_operand:SI 2 "nonmemory_operand" "r,n,Ca4,n")))
2921 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2924 if (which_alternative == 0)
2925 return "and %0,%2" CR_TAB
2926 "and %B0,%B2" CR_TAB
2927 "and %C0,%C2" CR_TAB
2930 return avr_out_bitop (insn, operands, NULL);
2932 [(set_attr "length" "4,4,8,8")
2933 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2934 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2936 (define_peephole2 ; andi
2937 [(set (match_operand:QI 0 "d_register_operand" "")
2938 (and:QI (match_dup 0)
2939 (match_operand:QI 1 "const_int_operand" "")))
2941 (and:QI (match_dup 0)
2942 (match_operand:QI 2 "const_int_operand" "")))]
2944 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
2946 operands[1] = GEN_INT (INTVAL (operands[1]) & INTVAL (operands[2]));
2949 ;;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2952 (define_insn "iorqi3"
2953 [(set (match_operand:QI 0 "register_operand" "=r,d")
2954 (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
2955 (match_operand:QI 2 "nonmemory_operand" "r,i")))]
2960 [(set_attr "length" "1,1")
2961 (set_attr "cc" "set_zn,set_zn")])
2963 (define_insn "iorhi3"
2964 [(set (match_operand:HI 0 "register_operand" "=r,d,d,r ,r")
2965 (ior:HI (match_operand:HI 1 "register_operand" "%0,0,0,0 ,0")
2966 (match_operand:HI 2 "nonmemory_operand" "r,s,n,Co2,n")))
2967 (clobber (match_scratch:QI 3 "=X,X,X,X ,&d"))]
2970 if (which_alternative == 0)
2971 return "or %A0,%A2\;or %B0,%B2";
2972 else if (which_alternative == 1)
2973 return "ori %A0,lo8(%2)\;ori %B0,hi8(%2)";
2975 return avr_out_bitop (insn, operands, NULL);
2977 [(set_attr "length" "2,2,2,4,4")
2978 (set_attr "adjust_len" "*,*,out_bitop,out_bitop,out_bitop")
2979 (set_attr "cc" "set_n,set_n,clobber,clobber,clobber")])
2981 (define_insn "iorpsi3"
2982 [(set (match_operand:PSI 0 "register_operand" "=r,d,r ,r")
2983 (ior:PSI (match_operand:PSI 1 "register_operand" "%0,0,0 ,0")
2984 (match_operand:PSI 2 "nonmemory_operand" "r,n,Co3,n")))
2985 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
2988 if (which_alternative == 0)
2989 return "or %A0,%A2" CR_TAB
2993 return avr_out_bitop (insn, operands, NULL);
2995 [(set_attr "length" "3,3,6,6")
2996 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
2997 (set_attr "cc" "set_n,clobber,clobber,clobber")])
2999 (define_insn "iorsi3"
3000 [(set (match_operand:SI 0 "register_operand" "=r,d,r ,r")
3001 (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0 ,0")
3002 (match_operand:SI 2 "nonmemory_operand" "r,n,Co4,n")))
3003 (clobber (match_scratch:QI 3 "=X,X,X ,&d"))]
3006 if (which_alternative == 0)
3007 return "or %0,%2" CR_TAB
3012 return avr_out_bitop (insn, operands, NULL);
3014 [(set_attr "length" "4,4,8,8")
3015 (set_attr "adjust_len" "*,out_bitop,out_bitop,out_bitop")
3016 (set_attr "cc" "set_n,clobber,clobber,clobber")])
3018 ;;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3021 (define_insn "xorqi3"
3022 [(set (match_operand:QI 0 "register_operand" "=r")
3023 (xor:QI (match_operand:QI 1 "register_operand" "%0")
3024 (match_operand:QI 2 "register_operand" "r")))]
3027 [(set_attr "length" "1")
3028 (set_attr "cc" "set_zn")])
3030 (define_insn "xorhi3"
3031 [(set (match_operand:HI 0 "register_operand" "=r,r ,r")
3032 (xor:HI (match_operand:HI 1 "register_operand" "%0,0 ,0")
3033 (match_operand:HI 2 "nonmemory_operand" "r,Cx2,n")))
3034 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3037 if (which_alternative == 0)
3038 return "eor %A0,%A2\;eor %B0,%B2";
3040 return avr_out_bitop (insn, operands, NULL);
3042 [(set_attr "length" "2,2,4")
3043 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3044 (set_attr "cc" "set_n,clobber,clobber")])
3046 (define_insn "xorpsi3"
3047 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3048 (xor:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0")
3049 (match_operand:PSI 2 "nonmemory_operand" "r,Cx3,n")))
3050 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3053 if (which_alternative == 0)
3054 return "eor %A0,%A2" CR_TAB
3055 "eor %B0,%B2" CR_TAB
3058 return avr_out_bitop (insn, operands, NULL);
3060 [(set_attr "length" "3,6,6")
3061 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3062 (set_attr "cc" "set_n,clobber,clobber")])
3064 (define_insn "xorsi3"
3065 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3066 (xor:SI (match_operand:SI 1 "register_operand" "%0,0 ,0")
3067 (match_operand:SI 2 "nonmemory_operand" "r,Cx4,n")))
3068 (clobber (match_scratch:QI 3 "=X,X ,&d"))]
3071 if (which_alternative == 0)
3072 return "eor %0,%2" CR_TAB
3073 "eor %B0,%B2" CR_TAB
3074 "eor %C0,%C2" CR_TAB
3077 return avr_out_bitop (insn, operands, NULL);
3079 [(set_attr "length" "4,8,8")
3080 (set_attr "adjust_len" "*,out_bitop,out_bitop")
3081 (set_attr "cc" "set_n,clobber,clobber")])
3083 ;; swap swap swap swap swap swap swap swap swap swap swap swap swap swap swap
3086 (define_expand "rotlqi3"
3087 [(set (match_operand:QI 0 "register_operand" "")
3088 (rotate:QI (match_operand:QI 1 "register_operand" "")
3089 (match_operand:QI 2 "const_0_to_7_operand" "")))]
3092 if (!CONST_INT_P (operands[2]))
3095 operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
3098 ;; Expander used by __builtin_avr_swap
3099 (define_expand "rotlqi3_4"
3100 [(set (match_operand:QI 0 "register_operand" "")
3101 (rotate:QI (match_operand:QI 1 "register_operand" "")
3104 (define_insn "*rotlqi3"
3105 [(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
3106 (rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
3107 (match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
3110 lsl %0\;adc %0,__zero_reg__
3111 lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3112 swap %0\;bst %0,0\;ror %0\;bld %0,7
3114 swap %0\;lsl %0\;adc %0,__zero_reg__
3115 swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
3116 bst %0,0\;ror %0\;bld %0,7
3118 [(set_attr "length" "2,4,4,1,3,5,3,0")
3119 (set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
3121 ;; Split all rotates of HI,SI and PSImode registers where rotation is by
3122 ;; a whole number of bytes. The split creates the appropriate moves and
3123 ;; considers all overlap situations.
3125 ;; HImode does not need scratch. Use attribute for this constraint.
3127 (define_mode_attr rotx [(SI "&r,&r,X") (PSI "&r,&r,X") (HI "X,X,X")])
3128 (define_mode_attr rotsmode [(SI "HI") (PSI "QI") (HI "QI")])
3133 (define_expand "rotl<mode>3"
3134 [(parallel [(set (match_operand:HISI 0 "register_operand" "")
3135 (rotate:HISI (match_operand:HISI 1 "register_operand" "")
3136 (match_operand:VOID 2 "const_int_operand" "")))
3137 (clobber (match_dup 3))])]
3142 if (!CONST_INT_P (operands[2]))
3145 offset = INTVAL (operands[2]);
3147 if (0 == offset % 8)
3149 if (AVR_HAVE_MOVW && 0 == offset % 16)
3150 operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
3152 operands[3] = gen_rtx_SCRATCH (QImode);
3154 else if (offset == 1
3155 || offset == GET_MODE_BITSIZE (<MODE>mode) -1)
3157 /*; Support rotate left/right by 1 */
3159 emit_move_insn (operands[0],
3160 gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
3167 (define_insn "*rotlhi2.1"
3168 [(set (match_operand:HI 0 "register_operand" "=r")
3169 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3172 "lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
3173 [(set_attr "length" "3")
3174 (set_attr "cc" "clobber")])
3176 (define_insn "*rotlhi2.15"
3177 [(set (match_operand:HI 0 "register_operand" "=r")
3178 (rotate:HI (match_operand:HI 1 "register_operand" "0")
3181 "bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
3182 [(set_attr "length" "4")
3183 (set_attr "cc" "clobber")])
3185 (define_insn "*rotlpsi2.1"
3186 [(set (match_operand:PSI 0 "register_operand" "=r")
3187 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3190 "lsl %A0\;rol %B0\;rol %C0\;adc %A0,__zero_reg__"
3191 [(set_attr "length" "4")
3192 (set_attr "cc" "clobber")])
3194 (define_insn "*rotlpsi2.23"
3195 [(set (match_operand:PSI 0 "register_operand" "=r")
3196 (rotate:PSI (match_operand:PSI 1 "register_operand" "0")
3199 "bst %A0,0\;ror %C0\;ror %B0\;ror %A0\;bld %C0,7"
3200 [(set_attr "length" "5")
3201 (set_attr "cc" "clobber")])
3203 (define_insn "*rotlsi2.1"
3204 [(set (match_operand:SI 0 "register_operand" "=r")
3205 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3208 "lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
3209 [(set_attr "length" "5")
3210 (set_attr "cc" "clobber")])
3212 (define_insn "*rotlsi2.31"
3213 [(set (match_operand:SI 0 "register_operand" "=r")
3214 (rotate:SI (match_operand:SI 1 "register_operand" "0")
3217 "bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
3218 [(set_attr "length" "6")
3219 (set_attr "cc" "clobber")])
3221 ;; Overlapping non-HImode registers often (but not always) need a scratch.
3222 ;; The best we can do is use early clobber alternative "#&r" so that
3223 ;; completely non-overlapping operands dont get a scratch but # so register
3224 ;; allocation does not prefer non-overlapping.
3227 ;; Split word aligned rotates using scratch that is mode dependent.
3231 (define_insn_and_split "*rotw<mode>"
3232 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3233 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3234 (match_operand 2 "const_int_operand" "n,n,n")))
3235 (clobber (match_scratch:<rotsmode> 3 "=<rotx>"))]
3237 && CONST_INT_P (operands[2])
3238 && GET_MODE_SIZE (<MODE>mode) % 2 == 0
3239 && 0 == INTVAL (operands[2]) % 16"
3241 "&& reload_completed"
3244 avr_rotate_bytes (operands);
3249 ;; Split byte aligned rotates using scratch that is always QI mode.
3254 (define_insn_and_split "*rotb<mode>"
3255 [(set (match_operand:HISI 0 "register_operand" "=r,r,#&r")
3256 (rotate:HISI (match_operand:HISI 1 "register_operand" "0,r,r")
3257 (match_operand 2 "const_int_operand" "n,n,n")))
3258 (clobber (match_scratch:QI 3 "=<rotx>"))]
3259 "CONST_INT_P (operands[2])
3260 && (8 == INTVAL (operands[2]) % 16
3262 || GET_MODE_SIZE (<MODE>mode) % 2 != 0)
3263 && 0 == INTVAL (operands[2]) % 16))"
3265 "&& reload_completed"
3268 avr_rotate_bytes (operands);
3273 ;;<< << << << << << << << << << << << << << << << << << << << << << << << << <<
3274 ;; arithmetic shift left
3276 (define_expand "ashlqi3"
3277 [(set (match_operand:QI 0 "register_operand" "")
3278 (ashift:QI (match_operand:QI 1 "register_operand" "")
3279 (match_operand:QI 2 "nop_general_operand" "")))])
3281 (define_split ; ashlqi3_const4
3282 [(set (match_operand:QI 0 "d_register_operand" "")
3283 (ashift:QI (match_dup 0)
3286 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3287 (set (match_dup 0) (and:QI (match_dup 0) (const_int -16)))]
3290 (define_split ; ashlqi3_const5
3291 [(set (match_operand:QI 0 "d_register_operand" "")
3292 (ashift:QI (match_dup 0)
3295 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3296 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3297 (set (match_dup 0) (and:QI (match_dup 0) (const_int -32)))]
3300 (define_split ; ashlqi3_const6
3301 [(set (match_operand:QI 0 "d_register_operand" "")
3302 (ashift:QI (match_dup 0)
3305 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3306 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3307 (set (match_dup 0) (and:QI (match_dup 0) (const_int -64)))]
3310 (define_insn "*ashlqi3"
3311 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3312 (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3313 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3316 return ashlqi3_out (insn, operands, NULL);
3318 [(set_attr "length" "5,0,1,2,4,6,9")
3319 (set_attr "adjust_len" "ashlqi")
3320 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3322 (define_insn "ashlhi3"
3323 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3324 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3325 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3328 return ashlhi3_out (insn, operands, NULL);
3330 [(set_attr "length" "6,0,2,2,4,10,10")
3331 (set_attr "adjust_len" "ashlhi")
3332 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3335 ;; Insns like the following are generated when (implicitly) extending 8-bit shifts
3336 ;; like char1 = char2 << char3. Only the low-byte is needed in that situation.
3340 (define_insn_and_split "*ashl<extend_su>qihiqi3"
3341 [(set (match_operand:QI 0 "register_operand" "=r")
3342 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
3343 (match_operand:QI 2 "register_operand" "r"))
3349 (ashift:QI (match_dup 1)
3353 ;; ??? Combiner does not recognize that it could split the following insn;
3354 ;; presumably because he has no register handy?
3356 ;; "*ashluqihiqi3.mem"
3357 ;; "*ashlsqihiqi3.mem"
3358 (define_insn_and_split "*ashl<extend_su>qihiqi3.mem"
3359 [(set (match_operand:QI 0 "memory_operand" "=m")
3360 (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
3361 (match_operand:QI 2 "register_operand" "r"))
3364 { gcc_unreachable(); }
3367 (ashift:QI (match_dup 1)
3372 operands[3] = gen_reg_rtx (QImode);
3377 (define_insn_and_split "*ashlhiqi3"
3378 [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
3379 (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
3380 (match_operand:QI 2 "register_operand" "r")) 0))]
3382 { gcc_unreachable(); }
3385 (ashift:QI (match_dup 3)
3390 operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
3391 operands[4] = gen_reg_rtx (QImode);
3394 ;; High part of 16-bit shift is unused after the instruction:
3395 ;; No need to compute it, map to 8-bit shift.
3398 [(set (match_operand:HI 0 "register_operand" "")
3399 (ashift:HI (match_dup 0)
3400 (match_operand:QI 1 "register_operand" "")))]
3403 (ashift:QI (match_dup 2)
3405 (clobber (match_dup 3))]
3407 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
3409 if (!peep2_reg_dead_p (1, operands[3]))
3412 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
3416 (define_insn "ashlsi3"
3417 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3418 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3419 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3422 return ashlsi3_out (insn, operands, NULL);
3424 [(set_attr "length" "8,0,4,4,8,10,12")
3425 (set_attr "adjust_len" "ashlsi")
3426 (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
3428 ;; Optimize if a scratch register from LD_REGS happens to be available.
3430 (define_peephole2 ; ashlqi3_l_const4
3431 [(set (match_operand:QI 0 "l_register_operand" "")
3432 (ashift:QI (match_dup 0)
3434 (match_scratch:QI 1 "d")]
3436 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3437 (set (match_dup 1) (const_int -16))
3438 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3441 (define_peephole2 ; ashlqi3_l_const5
3442 [(set (match_operand:QI 0 "l_register_operand" "")
3443 (ashift:QI (match_dup 0)
3445 (match_scratch:QI 1 "d")]
3447 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3448 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 1)))
3449 (set (match_dup 1) (const_int -32))
3450 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3453 (define_peephole2 ; ashlqi3_l_const6
3454 [(set (match_operand:QI 0 "l_register_operand" "")
3455 (ashift:QI (match_dup 0)
3457 (match_scratch:QI 1 "d")]
3459 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3460 (set (match_dup 0) (ashift:QI (match_dup 0) (const_int 2)))
3461 (set (match_dup 1) (const_int -64))
3462 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3466 [(match_scratch:QI 3 "d")
3467 (set (match_operand:HI 0 "register_operand" "")
3468 (ashift:HI (match_operand:HI 1 "register_operand" "")
3469 (match_operand:QI 2 "const_int_operand" "")))]
3471 [(parallel [(set (match_dup 0) (ashift:HI (match_dup 1) (match_dup 2)))
3472 (clobber (match_dup 3))])]
3475 (define_insn "*ashlhi3_const"
3476 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3477 (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3478 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3479 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3482 return ashlhi3_out (insn, operands, NULL);
3484 [(set_attr "length" "0,2,2,4,10")
3485 (set_attr "adjust_len" "ashlhi")
3486 (set_attr "cc" "none,set_n,clobber,set_n,clobber")])
3489 [(match_scratch:QI 3 "d")
3490 (set (match_operand:SI 0 "register_operand" "")
3491 (ashift:SI (match_operand:SI 1 "register_operand" "")
3492 (match_operand:QI 2 "const_int_operand" "")))]
3494 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
3495 (clobber (match_dup 3))])]
3498 (define_insn "*ashlsi3_const"
3499 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3500 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3501 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3502 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3505 return ashlsi3_out (insn, operands, NULL);
3507 [(set_attr "length" "0,4,4,10")
3508 (set_attr "adjust_len" "ashlsi")
3509 (set_attr "cc" "none,set_n,clobber,clobber")])
3511 (define_expand "ashlpsi3"
3512 [(parallel [(set (match_operand:PSI 0 "register_operand" "")
3513 (ashift:PSI (match_operand:PSI 1 "register_operand" "")
3514 (match_operand:QI 2 "nonmemory_operand" "")))
3515 (clobber (scratch:QI))])]
3519 && CONST_INT_P (operands[2]))
3521 if (IN_RANGE (INTVAL (operands[2]), 3, 6))
3523 rtx xoffset = force_reg (QImode, gen_int_mode (1 << INTVAL (operands[2]), QImode));
3524 emit_insn (gen_mulsqipsi3 (operands[0], xoffset, operands[1]));
3527 else if (optimize_insn_for_speed_p ()
3528 && INTVAL (operands[2]) != 16
3529 && IN_RANGE (INTVAL (operands[2]), 9, 22))
3531 rtx xoffset = force_reg (PSImode, gen_int_mode (1 << INTVAL (operands[2]), PSImode));
3532 emit_insn (gen_mulpsi3 (operands[0], operands[1], xoffset));
3538 (define_insn "*ashlpsi3"
3539 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r")
3540 (ashift:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0")
3541 (match_operand:QI 2 "nonmemory_operand" "r,P,O,n")))
3542 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3545 return avr_out_ashlpsi3 (insn, operands, NULL);
3547 [(set_attr "adjust_len" "ashlpsi")
3548 (set_attr "cc" "clobber")])
3550 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3551 ;; arithmetic shift right
3553 (define_insn "ashrqi3"
3554 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r ,r ,r")
3555 (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0 ,0")
3556 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,C03 C04 C05,C06 C07,Qm")))]
3559 return ashrqi3_out (insn, operands, NULL);
3561 [(set_attr "length" "5,0,1,2,5,4,9")
3562 (set_attr "adjust_len" "ashrqi")
3563 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,clobber,clobber")])
3565 (define_insn "ashrhi3"
3566 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3567 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3568 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3571 return ashrhi3_out (insn, operands, NULL);
3573 [(set_attr "length" "6,0,2,4,4,10,10")
3574 (set_attr "adjust_len" "ashrhi")
3575 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3577 (define_insn "ashrpsi3"
3578 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3579 (ashiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,0,r,0")
3580 (match_operand:QI 2 "nonmemory_operand" "r,P,K,O,n")))
3581 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3584 return avr_out_ashrpsi3 (insn, operands, NULL);
3586 [(set_attr "adjust_len" "ashrpsi")
3587 (set_attr "cc" "clobber")])
3589 (define_insn "ashrsi3"
3590 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3591 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3592 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3595 return ashrsi3_out (insn, operands, NULL);
3597 [(set_attr "length" "8,0,4,6,8,10,12")
3598 (set_attr "adjust_len" "ashrsi")
3599 (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")])
3601 ;; Optimize if a scratch register from LD_REGS happens to be available.
3604 [(match_scratch:QI 3 "d")
3605 (set (match_operand:HI 0 "register_operand" "")
3606 (ashiftrt:HI (match_operand:HI 1 "register_operand" "")
3607 (match_operand:QI 2 "const_int_operand" "")))]
3609 [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 1) (match_dup 2)))
3610 (clobber (match_dup 3))])]
3613 (define_insn "*ashrhi3_const"
3614 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3615 (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3616 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3617 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3620 return ashrhi3_out (insn, operands, NULL);
3622 [(set_attr "length" "0,2,4,4,10")
3623 (set_attr "adjust_len" "ashrhi")
3624 (set_attr "cc" "none,clobber,set_n,clobber,clobber")])
3627 [(match_scratch:QI 3 "d")
3628 (set (match_operand:SI 0 "register_operand" "")
3629 (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
3630 (match_operand:QI 2 "const_int_operand" "")))]
3632 [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (match_dup 2)))
3633 (clobber (match_dup 3))])]
3636 (define_insn "*ashrsi3_const"
3637 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3638 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3639 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3640 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3643 return ashrsi3_out (insn, operands, NULL);
3645 [(set_attr "length" "0,4,4,10")
3646 (set_attr "adjust_len" "ashrsi")
3647 (set_attr "cc" "none,clobber,set_n,clobber")])
3649 ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
3650 ;; logical shift right
3652 (define_expand "lshrqi3"
3653 [(set (match_operand:QI 0 "register_operand" "")
3654 (lshiftrt:QI (match_operand:QI 1 "register_operand" "")
3655 (match_operand:QI 2 "nop_general_operand" "")))])
3657 (define_split ; lshrqi3_const4
3658 [(set (match_operand:QI 0 "d_register_operand" "")
3659 (lshiftrt:QI (match_dup 0)
3662 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3663 (set (match_dup 0) (and:QI (match_dup 0) (const_int 15)))]
3666 (define_split ; lshrqi3_const5
3667 [(set (match_operand:QI 0 "d_register_operand" "")
3668 (lshiftrt:QI (match_dup 0)
3671 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3672 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3673 (set (match_dup 0) (and:QI (match_dup 0) (const_int 7)))]
3676 (define_split ; lshrqi3_const6
3677 [(set (match_operand:QI 0 "d_register_operand" "")
3678 (lshiftrt:QI (match_dup 0)
3681 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3682 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3683 (set (match_dup 0) (and:QI (match_dup 0) (const_int 3)))]
3686 (define_insn "*lshrqi3"
3687 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r")
3688 (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0 ,0,0")
3689 (match_operand:QI 2 "nop_general_operand" "r,L,P,K,n ,n,Qm")))]
3692 return lshrqi3_out (insn, operands, NULL);
3694 [(set_attr "length" "5,0,1,2,4,6,9")
3695 (set_attr "adjust_len" "lshrqi")
3696 (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")])
3698 (define_insn "lshrhi3"
3699 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r")
3700 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0")
3701 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3704 return lshrhi3_out (insn, operands, NULL);
3706 [(set_attr "length" "6,0,2,2,4,10,10")
3707 (set_attr "adjust_len" "lshrhi")
3708 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3710 (define_insn "lshrpsi3"
3711 [(set (match_operand:PSI 0 "register_operand" "=r,r,r,r,r")
3712 (lshiftrt:PSI (match_operand:PSI 1 "register_operand" "0,0,r,0,0")
3713 (match_operand:QI 2 "nonmemory_operand" "r,P,O,K,n")))
3714 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3717 return avr_out_lshrpsi3 (insn, operands, NULL);
3719 [(set_attr "adjust_len" "lshrpsi")
3720 (set_attr "cc" "clobber")])
3722 (define_insn "lshrsi3"
3723 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r")
3724 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")
3725 (match_operand:QI 2 "nop_general_operand" "r,L,P,O,K,n,Qm")))]
3728 return lshrsi3_out (insn, operands, NULL);
3730 [(set_attr "length" "8,0,4,4,8,10,12")
3731 (set_attr "adjust_len" "lshrsi")
3732 (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")])
3734 ;; Optimize if a scratch register from LD_REGS happens to be available.
3736 (define_peephole2 ; lshrqi3_l_const4
3737 [(set (match_operand:QI 0 "l_register_operand" "")
3738 (lshiftrt:QI (match_dup 0)
3740 (match_scratch:QI 1 "d")]
3742 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3743 (set (match_dup 1) (const_int 15))
3744 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3747 (define_peephole2 ; lshrqi3_l_const5
3748 [(set (match_operand:QI 0 "l_register_operand" "")
3749 (lshiftrt:QI (match_dup 0)
3751 (match_scratch:QI 1 "d")]
3753 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3754 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 1)))
3755 (set (match_dup 1) (const_int 7))
3756 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3759 (define_peephole2 ; lshrqi3_l_const6
3760 [(set (match_operand:QI 0 "l_register_operand" "")
3761 (lshiftrt:QI (match_dup 0)
3763 (match_scratch:QI 1 "d")]
3765 [(set (match_dup 0) (rotate:QI (match_dup 0) (const_int 4)))
3766 (set (match_dup 0) (lshiftrt:QI (match_dup 0) (const_int 2)))
3767 (set (match_dup 1) (const_int 3))
3768 (set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
3772 [(match_scratch:QI 3 "d")
3773 (set (match_operand:HI 0 "register_operand" "")
3774 (lshiftrt:HI (match_operand:HI 1 "register_operand" "")
3775 (match_operand:QI 2 "const_int_operand" "")))]
3777 [(parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 1) (match_dup 2)))
3778 (clobber (match_dup 3))])]
3781 (define_insn "*lshrhi3_const"
3782 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
3783 (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0")
3784 (match_operand:QI 2 "const_int_operand" "L,P,O,K,n")))
3785 (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))]
3788 return lshrhi3_out (insn, operands, NULL);
3790 [(set_attr "length" "0,2,2,4,10")
3791 (set_attr "adjust_len" "lshrhi")
3792 (set_attr "cc" "none,clobber,clobber,clobber,clobber")])
3795 [(match_scratch:QI 3 "d")
3796 (set (match_operand:SI 0 "register_operand" "")
3797 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
3798 (match_operand:QI 2 "const_int_operand" "")))]
3800 [(parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (match_dup 2)))
3801 (clobber (match_dup 3))])]
3804 (define_insn "*lshrsi3_const"
3805 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3806 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0")
3807 (match_operand:QI 2 "const_int_operand" "L,P,O,n")))
3808 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
3811 return lshrsi3_out (insn, operands, NULL);
3813 [(set_attr "length" "0,4,4,10")
3814 (set_attr "adjust_len" "lshrsi")
3815 (set_attr "cc" "none,clobber,clobber,clobber")])
3817 ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x)
3820 (define_insn "absqi2"
3821 [(set (match_operand:QI 0 "register_operand" "=r")
3822 (abs:QI (match_operand:QI 1 "register_operand" "0")))]
3826 [(set_attr "length" "2")
3827 (set_attr "cc" "clobber")])
3830 (define_insn "abssf2"
3831 [(set (match_operand:SF 0 "register_operand" "=d,r")
3832 (abs:SF (match_operand:SF 1 "register_operand" "0,0")))]
3837 [(set_attr "length" "1,2")
3838 (set_attr "cc" "set_n,clobber")])
3840 ;; 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x 0 - x
3843 (define_insn "negqi2"
3844 [(set (match_operand:QI 0 "register_operand" "=r")
3845 (neg:QI (match_operand:QI 1 "register_operand" "0")))]
3848 [(set_attr "length" "1")
3849 (set_attr "cc" "set_zn")])
3851 (define_insn "*negqihi2"
3852 [(set (match_operand:HI 0 "register_operand" "=r")
3853 (neg:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "0"))))]
3855 "clr %B0\;neg %A0\;brge .+2\;com %B0"
3856 [(set_attr "length" "4")
3857 (set_attr "cc" "set_n")])
3859 (define_insn "neghi2"
3860 [(set (match_operand:HI 0 "register_operand" "=r,&r")
3861 (neg:HI (match_operand:HI 1 "register_operand" "0,r")))]
3864 neg %B0\;neg %A0\;sbc %B0,__zero_reg__
3865 clr %A0\;clr %B0\;sub %A0,%A1\;sbc %B0,%B1"
3866 [(set_attr "length" "3,4")
3867 (set_attr "cc" "set_czn")])
3869 (define_insn "negpsi2"
3870 [(set (match_operand:PSI 0 "register_operand" "=!d,r,&r")
3871 (neg:PSI (match_operand:PSI 1 "register_operand" "0,0,r")))]
3874 com %C0\;com %B0\;neg %A0\;sbci %B0,-1\;sbci %C0,-1
3875 com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__
3876 clr %A0\;clr %B0\;clr %C0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1"
3877 [(set_attr "length" "5,6,6")
3878 (set_attr "cc" "set_czn,set_n,set_czn")])
3880 (define_insn "negsi2"
3881 [(set (match_operand:SI 0 "register_operand" "=!d,r,&r,&r")
3882 (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
3885 com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
3886 com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
3887 clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
3888 clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
3889 [(set_attr "length" "7,8,8,7")
3890 (set_attr "isa" "*,*,mov,movw")
3891 (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
3893 (define_insn "negsf2"
3894 [(set (match_operand:SF 0 "register_operand" "=d,r")
3895 (neg:SF (match_operand:SF 1 "register_operand" "0,0")))]
3899 bst %D0,7\;com %D0\;bld %D0,7\;com %D0"
3900 [(set_attr "length" "1,4")
3901 (set_attr "cc" "set_n,set_n")])
3903 ;; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3906 (define_insn "one_cmplqi2"
3907 [(set (match_operand:QI 0 "register_operand" "=r")
3908 (not:QI (match_operand:QI 1 "register_operand" "0")))]
3911 [(set_attr "length" "1")
3912 (set_attr "cc" "set_czn")])
3914 (define_insn "one_cmplhi2"
3915 [(set (match_operand:HI 0 "register_operand" "=r")
3916 (not:HI (match_operand:HI 1 "register_operand" "0")))]
3920 [(set_attr "length" "2")
3921 (set_attr "cc" "set_n")])
3923 (define_insn "one_cmplpsi2"
3924 [(set (match_operand:PSI 0 "register_operand" "=r")
3925 (not:PSI (match_operand:PSI 1 "register_operand" "0")))]
3927 "com %0\;com %B0\;com %C0"
3928 [(set_attr "length" "3")
3929 (set_attr "cc" "set_n")])
3931 (define_insn "one_cmplsi2"
3932 [(set (match_operand:SI 0 "register_operand" "=r")
3933 (not:SI (match_operand:SI 1 "register_operand" "0")))]
3939 [(set_attr "length" "4")
3940 (set_attr "cc" "set_n")])
3942 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
3945 ;; We keep combiner from inserting hard registers into the input of sign- and
3946 ;; zero-extends. A hard register in the input operand is not wanted because
3947 ;; 32-bit multiply patterns clobber some hard registers and extends with a
3948 ;; hard register that overlaps these clobbers won't be combined to a widening
3949 ;; multiplication. There is no need for combine to propagate hard registers,
3950 ;; register allocation can do it just as well.
3952 (define_insn "extendqihi2"
3953 [(set (match_operand:HI 0 "register_operand" "=r,r")
3954 (sign_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3957 clr %B0\;sbrc %0,7\;com %B0
3958 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0"
3959 [(set_attr "length" "3,4")
3960 (set_attr "cc" "set_n,set_n")])
3962 (define_insn "extendqipsi2"
3963 [(set (match_operand:PSI 0 "register_operand" "=r,r")
3964 (sign_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3967 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0
3968 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0"
3969 [(set_attr "length" "4,5")
3970 (set_attr "cc" "set_n,set_n")])
3972 (define_insn "extendqisi2"
3973 [(set (match_operand:SI 0 "register_operand" "=r,r")
3974 (sign_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]
3977 clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0
3978 mov %A0,%A1\;clr %B0\;sbrc %A0,7\;com %B0\;mov %C0,%B0\;mov %D0,%B0"
3979 [(set_attr "length" "5,6")
3980 (set_attr "cc" "set_n,set_n")])
3982 (define_insn "extendhipsi2"
3983 [(set (match_operand:PSI 0 "register_operand" "=r,r ,r")
3984 (sign_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3987 clr %C0\;sbrc %B0,7\;com %C0
3988 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0
3989 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0"
3990 [(set_attr "length" "3,5,4")
3991 (set_attr "isa" "*,mov,movw")
3992 (set_attr "cc" "set_n")])
3994 (define_insn "extendhisi2"
3995 [(set (match_operand:SI 0 "register_operand" "=r,r ,r")
3996 (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
3999 clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4000 mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
4001 movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
4002 [(set_attr "length" "4,6,5")
4003 (set_attr "isa" "*,mov,movw")
4004 (set_attr "cc" "set_n")])
4006 (define_insn "extendpsisi2"
4007 [(set (match_operand:SI 0 "register_operand" "=r")
4008 (sign_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "0")))]
4010 "clr %D0\;sbrc %C0,7\;com %D0"
4011 [(set_attr "length" "3")
4012 (set_attr "cc" "set_n")])
4014 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
4017 (define_insn_and_split "zero_extendqihi2"
4018 [(set (match_operand:HI 0 "register_operand" "=r")
4019 (zero_extend:HI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4023 [(set (match_dup 2) (match_dup 1))
4024 (set (match_dup 3) (const_int 0))]
4026 unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
4027 unsigned int high_off = subreg_highpart_offset (QImode, HImode);
4029 operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
4030 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
4033 (define_insn_and_split "zero_extendqipsi2"
4034 [(set (match_operand:PSI 0 "register_operand" "=r")
4035 (zero_extend:PSI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4039 [(set (match_dup 2) (match_dup 1))
4040 (set (match_dup 3) (const_int 0))
4041 (set (match_dup 4) (const_int 0))]
4043 operands[2] = simplify_gen_subreg (QImode, operands[0], PSImode, 0);
4044 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 1);
4045 operands[4] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4048 (define_insn_and_split "zero_extendqisi2"
4049 [(set (match_operand:SI 0 "register_operand" "=r")
4050 (zero_extend:SI (match_operand:QI 1 "combine_pseudo_register_operand" "r")))]
4054 [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
4055 (set (match_dup 3) (const_int 0))]
4057 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4058 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4060 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4061 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4064 (define_insn_and_split "zero_extendhipsi2"
4065 [(set (match_operand:PSI 0 "register_operand" "=r")
4066 (zero_extend:PSI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4070 [(set (match_dup 2) (match_dup 1))
4071 (set (match_dup 3) (const_int 0))]
4073 operands[2] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4074 operands[3] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4077 (define_insn_and_split "n_extendhipsi2"
4078 [(set (match_operand:PSI 0 "register_operand" "=r,r,d,r")
4079 (lo_sum:PSI (match_operand:QI 1 "const_int_operand" "L,P,n,n")
4080 (match_operand:HI 2 "register_operand" "r,r,r,r")))
4081 (clobber (match_scratch:QI 3 "=X,X,X,&d"))]
4085 [(set (match_dup 4) (match_dup 2))
4086 (set (match_dup 3) (match_dup 6))
4087 ; no-op move in the case where no scratch is needed
4088 (set (match_dup 5) (match_dup 3))]
4090 operands[4] = simplify_gen_subreg (HImode, operands[0], PSImode, 0);
4091 operands[5] = simplify_gen_subreg (QImode, operands[0], PSImode, 2);
4092 operands[6] = operands[1];
4094 if (GET_CODE (operands[3]) == SCRATCH)
4095 operands[3] = operands[5];
4098 (define_insn_and_split "zero_extendhisi2"
4099 [(set (match_operand:SI 0 "register_operand" "=r")
4100 (zero_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "r")))]
4104 [(set (match_dup 2) (match_dup 1))
4105 (set (match_dup 3) (const_int 0))]
4107 unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
4108 unsigned int high_off = subreg_highpart_offset (HImode, SImode);
4110 operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
4111 operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
4114 (define_insn_and_split "zero_extendpsisi2"
4115 [(set (match_operand:SI 0 "register_operand" "=r")
4116 (zero_extend:SI (match_operand:PSI 1 "combine_pseudo_register_operand" "r")))]
4120 [(set (match_dup 2) (match_dup 1))
4121 (set (match_dup 3) (const_int 0))]
4123 operands[2] = simplify_gen_subreg (PSImode, operands[0], SImode, 0);
4124 operands[3] = simplify_gen_subreg (QImode, operands[0], SImode, 3);
4127 (define_insn_and_split "zero_extendqidi2"
4128 [(set (match_operand:DI 0 "register_operand" "=r")
4129 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
4133 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4134 (set (match_dup 3) (const_int 0))]
4136 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4137 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4139 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4140 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4143 (define_insn_and_split "zero_extendhidi2"
4144 [(set (match_operand:DI 0 "register_operand" "=r")
4145 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
4149 [(set (match_dup 2) (zero_extend:SI (match_dup 1)))
4150 (set (match_dup 3) (const_int 0))]
4152 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4153 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4155 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4156 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4159 (define_insn_and_split "zero_extendsidi2"
4160 [(set (match_operand:DI 0 "register_operand" "=r")
4161 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4165 [(set (match_dup 2) (match_dup 1))
4166 (set (match_dup 3) (const_int 0))]
4168 unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
4169 unsigned int high_off = subreg_highpart_offset (SImode, DImode);
4171 operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
4172 operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
4175 ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
4178 ; Optimize negated tests into reverse compare if overflow is undefined.
4179 (define_insn "*negated_tstqi"
4181 (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
4183 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4184 "cp __zero_reg__,%0"
4185 [(set_attr "cc" "compare")
4186 (set_attr "length" "1")])
4188 (define_insn "*reversed_tstqi"
4190 (compare (const_int 0)
4191 (match_operand:QI 0 "register_operand" "r")))]
4193 "cp __zero_reg__,%0"
4194 [(set_attr "cc" "compare")
4195 (set_attr "length" "2")])
4197 (define_insn "*negated_tsthi"
4199 (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
4201 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4202 "cp __zero_reg__,%A0
4203 cpc __zero_reg__,%B0"
4204 [(set_attr "cc" "compare")
4205 (set_attr "length" "2")])
4207 ;; Leave here the clobber used by the cmphi pattern for simplicity, even
4208 ;; though it is unused, because this pattern is synthesized by avr_reorg.
4209 (define_insn "*reversed_tsthi"
4211 (compare (const_int 0)
4212 (match_operand:HI 0 "register_operand" "r")))
4213 (clobber (match_scratch:QI 1 "=X"))]
4215 "cp __zero_reg__,%A0
4216 cpc __zero_reg__,%B0"
4217 [(set_attr "cc" "compare")
4218 (set_attr "length" "2")])
4220 (define_insn "*negated_tstpsi"
4222 (compare (neg:PSI (match_operand:PSI 0 "register_operand" "r"))
4224 "!flag_wrapv && !flag_trapv && flag_strict_overflow"
4225 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4226 [(set_attr "cc" "compare")
4227 (set_attr "length" "3")])
4229 (define_insn "*reversed_tstpsi"
4231 (compare (const_int 0)
4232 (match_operand:PSI 0 "register_operand" "r")))
4233 (clobber (match_scratch:QI 1 "=X"))]
4235 "cp __zero_reg__,%A0\;cpc __zero_reg__,%B0\;cpc __zero_reg__,%C0"
4236 [(set_attr "cc" "compare")
4237 (set_attr "length" "3")])
4239 (define_insn "*negated_tstsi"
4241 (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
4243 "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
4244 "cp __zero_reg__,%A0
4245 cpc __zero_reg__,%B0
4246 cpc __zero_reg__,%C0
4247 cpc __zero_reg__,%D0"
4248 [(set_attr "cc" "compare")
4249 (set_attr "length" "4")])
4251 (define_insn "*reversed_tstsi"
4253 (compare (const_int 0)
4254 (match_operand:SI 0 "register_operand" "r")))
4255 (clobber (match_scratch:QI 1 "=X"))]
4257 "cp __zero_reg__,%A0
4258 cpc __zero_reg__,%B0
4259 cpc __zero_reg__,%C0
4260 cpc __zero_reg__,%D0"
4261 [(set_attr "cc" "compare")
4262 (set_attr "length" "4")])
4265 (define_insn "*cmpqi"
4267 (compare (match_operand:QI 0 "register_operand" "r,r,d")
4268 (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
4274 [(set_attr "cc" "compare,compare,compare")
4275 (set_attr "length" "1,1,1")])
4277 (define_insn "*cmpqi_sign_extend"
4279 (compare (sign_extend:HI (match_operand:QI 0 "register_operand" "d"))
4280 (match_operand:HI 1 "s8_operand" "n")))]
4283 [(set_attr "cc" "compare")
4284 (set_attr "length" "1")])
4286 (define_insn "*cmphi"
4288 (compare (match_operand:HI 0 "register_operand" "!w,r,r,d ,r ,d,r")
4289 (match_operand:HI 1 "nonmemory_operand" "L ,L,r,s ,s ,M,n")))
4290 (clobber (match_scratch:QI 2 "=X ,X,X,&d,&d ,X,&d"))]
4293 switch (which_alternative)
4297 return avr_out_tsthi (insn, operands, NULL);
4300 return "cp %A0,%A1\;cpc %B0,%B1";
4303 return reg_unused_after (insn, operands[0])
4304 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)"
4305 : "ldi %2,hi8(%1)\;cpi %A0,lo8(%1)\;cpc %B0,%2";
4308 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2";
4311 return avr_out_compare (insn, operands, NULL);
4313 [(set_attr "cc" "compare")
4314 (set_attr "length" "1,2,2,3,4,2,4")
4315 (set_attr "adjust_len" "tsthi,tsthi,*,*,*,compare,compare")])
4317 (define_insn "*cmppsi"
4319 (compare (match_operand:PSI 0 "register_operand" "r,r,d ,r ,d,r")
4320 (match_operand:PSI 1 "nonmemory_operand" "L,r,s ,s ,M,n")))
4321 (clobber (match_scratch:QI 2 "=X,X,&d,&d ,X,&d"))]
4324 switch (which_alternative)
4327 return avr_out_tstpsi (insn, operands, NULL);
4330 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1";
4333 return reg_unused_after (insn, operands[0])
4334 ? "subi %A0,lo8(%1)\;sbci %B0,hi8(%1)\;sbci %C0,hh8(%1)"
4335 : "cpi %A0,lo8(%1)\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4338 return "ldi %2,lo8(%1)\;cp %A0,%2\;ldi %2,hi8(%1)\;cpc %B0,%2\;ldi %2,hh8(%1)\;cpc %C0,%2";
4341 return avr_out_compare (insn, operands, NULL);
4343 [(set_attr "cc" "compare")
4344 (set_attr "length" "3,3,5,6,3,7")
4345 (set_attr "adjust_len" "tstpsi,*,*,*,compare,compare")])
4347 (define_insn "*cmpsi"
4349 (compare (match_operand:SI 0 "register_operand" "r,r ,d,r ,r")
4350 (match_operand:SI 1 "nonmemory_operand" "L,r ,M,M ,n")))
4351 (clobber (match_scratch:QI 2 "=X,X ,X,&d,&d"))]
4354 if (0 == which_alternative)
4355 return avr_out_tstsi (insn, operands, NULL);
4356 else if (1 == which_alternative)
4357 return "cp %A0,%A1\;cpc %B0,%B1\;cpc %C0,%C1\;cpc %D0,%D1";
4359 return avr_out_compare (insn, operands, NULL);
4361 [(set_attr "cc" "compare")
4362 (set_attr "length" "4,4,4,5,8")
4363 (set_attr "adjust_len" "tstsi,*,compare,compare,compare")])
4366 ;; ----------------------------------------------------------------------
4367 ;; JUMP INSTRUCTIONS
4368 ;; ----------------------------------------------------------------------
4369 ;; Conditional jump instructions
4371 (define_expand "cbranchsi4"
4372 [(parallel [(set (cc0)
4373 (compare (match_operand:SI 1 "register_operand" "")
4374 (match_operand:SI 2 "nonmemory_operand" "")))
4375 (clobber (match_scratch:QI 4 ""))])
4378 (match_operator 0 "ordered_comparison_operator" [(cc0)
4380 (label_ref (match_operand 3 "" ""))
4384 (define_expand "cbranchpsi4"
4385 [(parallel [(set (cc0)
4386 (compare (match_operand:PSI 1 "register_operand" "")
4387 (match_operand:PSI 2 "nonmemory_operand" "")))
4388 (clobber (match_scratch:QI 4 ""))])
4390 (if_then_else (match_operator 0 "ordered_comparison_operator" [(cc0)
4392 (label_ref (match_operand 3 "" ""))
4396 (define_expand "cbranchhi4"
4397 [(parallel [(set (cc0)
4398 (compare (match_operand:HI 1 "register_operand" "")
4399 (match_operand:HI 2 "nonmemory_operand" "")))
4400 (clobber (match_scratch:QI 4 ""))])
4403 (match_operator 0 "ordered_comparison_operator" [(cc0)
4405 (label_ref (match_operand 3 "" ""))
4409 (define_expand "cbranchqi4"
4411 (compare (match_operand:QI 1 "register_operand" "")
4412 (match_operand:QI 2 "nonmemory_operand" "")))
4415 (match_operator 0 "ordered_comparison_operator" [(cc0)
4417 (label_ref (match_operand 3 "" ""))
4422 ;; Test a single bit in a QI/HI/SImode register.
4423 ;; Combine will create zero extract patterns for single bit tests.
4424 ;; permit any mode in source pattern by using VOIDmode.
4426 (define_insn "*sbrx_branch<mode>"
4429 (match_operator 0 "eqne_operator"
4431 (match_operand:VOID 1 "register_operand" "r")
4433 (match_operand 2 "const_int_operand" "n"))
4435 (label_ref (match_operand 3 "" ""))
4439 return avr_out_sbxx_branch (insn, operands);
4441 [(set (attr "length")
4442 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4443 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4445 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4448 (set_attr "cc" "clobber")])
4450 ;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
4451 ;; or for old peepholes.
4452 ;; Fixme - bitwise Mask will not work for DImode
4454 (define_insn "*sbrx_and_branch<mode>"
4457 (match_operator 0 "eqne_operator"
4459 (match_operand:QISI 1 "register_operand" "r")
4460 (match_operand:QISI 2 "single_one_operand" "n"))
4462 (label_ref (match_operand 3 "" ""))
4466 HOST_WIDE_INT bitnumber;
4467 bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
4468 operands[2] = GEN_INT (bitnumber);
4469 return avr_out_sbxx_branch (insn, operands);
4471 [(set (attr "length")
4472 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4473 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4475 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4478 (set_attr "cc" "clobber")])
4480 ;; Convert sign tests to bit 7/15/31 tests that match the above insns.
4482 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4484 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4485 (label_ref (match_operand 1 "" ""))
4488 [(set (pc) (if_then_else (eq (zero_extract:HI (match_dup 0)
4492 (label_ref (match_dup 1))
4497 [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
4499 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4500 (label_ref (match_operand 1 "" ""))
4503 [(set (pc) (if_then_else (ne (zero_extract:HI (match_dup 0)
4507 (label_ref (match_dup 1))
4512 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4514 (clobber (match_operand:HI 2 ""))])
4515 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4516 (label_ref (match_operand 1 "" ""))
4519 [(set (pc) (if_then_else (eq (and:HI (match_dup 0) (const_int -32768))
4521 (label_ref (match_dup 1))
4526 [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
4528 (clobber (match_operand:HI 2 ""))])
4529 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4530 (label_ref (match_operand 1 "" ""))
4533 [(set (pc) (if_then_else (ne (and:HI (match_dup 0) (const_int -32768))
4535 (label_ref (match_dup 1))
4540 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4542 (clobber (match_operand:SI 2 ""))])
4543 (set (pc) (if_then_else (ge (cc0) (const_int 0))
4544 (label_ref (match_operand 1 "" ""))
4547 [(set (pc) (if_then_else (eq (and:SI (match_dup 0) (match_dup 2))
4549 (label_ref (match_dup 1))
4551 "operands[2] = GEN_INT (-2147483647 - 1);")
4554 [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
4556 (clobber (match_operand:SI 2 ""))])
4557 (set (pc) (if_then_else (lt (cc0) (const_int 0))
4558 (label_ref (match_operand 1 "" ""))
4561 [(set (pc) (if_then_else (ne (and:SI (match_dup 0) (match_dup 2))
4563 (label_ref (match_dup 1))
4565 "operands[2] = GEN_INT (-2147483647 - 1);")
4567 ;; ************************************************************************
4568 ;; Implementation of conditional jumps here.
4569 ;; Compare with 0 (test) jumps
4570 ;; ************************************************************************
4572 (define_insn "branch"
4574 (if_then_else (match_operator 1 "simple_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" "branch")
4584 (set_attr "cc" "clobber")])
4587 ;; Same as above but wrap SET_SRC so that this branch won't be transformed
4588 ;; or optimized in the remainder.
4590 (define_insn "branch_unspec"
4592 (unspec [(if_then_else (match_operator 1 "simple_comparison_operator"
4595 (label_ref (match_operand 0 "" ""))
4597 ] UNSPEC_IDENTITY))]
4600 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4602 [(set_attr "type" "branch")
4603 (set_attr "cc" "none")])
4605 ;; ****************************************************************
4606 ;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
4607 ;; Convert them all to proper jumps.
4608 ;; ****************************************************************/
4610 (define_insn "difficult_branch"
4612 (if_then_else (match_operator 1 "difficult_comparison_operator"
4615 (label_ref (match_operand 0 "" ""))
4619 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 0);
4621 [(set_attr "type" "branch1")
4622 (set_attr "cc" "clobber")])
4626 (define_insn "rvbranch"
4628 (if_then_else (match_operator 1 "simple_comparison_operator"
4632 (label_ref (match_operand 0 "" ""))))]
4635 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4637 [(set_attr "type" "branch1")
4638 (set_attr "cc" "clobber")])
4640 (define_insn "difficult_rvbranch"
4642 (if_then_else (match_operator 1 "difficult_comparison_operator"
4646 (label_ref (match_operand 0 "" ""))))]
4649 return ret_cond_branch (operands[1], avr_jump_mode (operands[0], insn), 1);
4651 [(set_attr "type" "branch")
4652 (set_attr "cc" "clobber")])
4654 ;; **************************************************************************
4655 ;; Unconditional and other jump instructions.
4659 (label_ref (match_operand 0 "" "")))]
4662 return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
4666 [(set (attr "length")
4667 (if_then_else (match_operand 0 "symbol_ref_operand" "")
4668 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4671 (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
4672 (le (minus (pc) (match_dup 0)) (const_int 2047)))
4675 (set_attr "cc" "none")])
4679 (define_expand "call"
4680 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4681 (match_operand:HI 1 "general_operand" ""))
4682 (use (const_int 0))])]
4683 ;; Operand 1 not used on the AVR.
4684 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4688 (define_expand "sibcall"
4689 [(parallel[(call (match_operand:HI 0 "call_insn_operand" "")
4690 (match_operand:HI 1 "general_operand" ""))
4691 (use (const_int 1))])]
4692 ;; Operand 1 not used on the AVR.
4693 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4699 (define_expand "call_value"
4700 [(parallel[(set (match_operand 0 "register_operand" "")
4701 (call (match_operand:HI 1 "call_insn_operand" "")
4702 (match_operand:HI 2 "general_operand" "")))
4703 (use (const_int 0))])]
4704 ;; Operand 2 not used on the AVR.
4705 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4709 (define_expand "sibcall_value"
4710 [(parallel[(set (match_operand 0 "register_operand" "")
4711 (call (match_operand:HI 1 "call_insn_operand" "")
4712 (match_operand:HI 2 "general_operand" "")))
4713 (use (const_int 1))])]
4714 ;; Operand 2 not used on the AVR.
4715 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4719 (define_insn "call_insn"
4720 [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s"))
4721 (match_operand:HI 1 "general_operand" "X,X,X,X"))
4722 (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])]
4723 ;; Operand 1 not used on the AVR.
4724 ;; Operand 2 is 1 for tail-call, 0 otherwise.
4731 [(set_attr "cc" "clobber")
4732 (set_attr "length" "1,*,1,*")
4733 (set_attr "adjust_len" "*,call,*,call")])
4735 (define_insn "call_value_insn"
4736 [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r")
4737 (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s"))
4738 (match_operand:HI 2 "general_operand" "X,X,X,X")))
4739 (use (match_operand:HI 3 "const_int_operand" "L,L,P,P"))])]
4740 ;; Operand 2 not used on the AVR.
4741 ;; Operand 3 is 1 for tail-call, 0 otherwise.
4748 [(set_attr "cc" "clobber")
4749 (set_attr "length" "1,*,1,*")
4750 (set_attr "adjust_len" "*,call,*,call")])
4756 [(set_attr "cc" "none")
4757 (set_attr "length" "1")])
4761 (define_expand "indirect_jump"
4763 (match_operand:HI 0 "nonmemory_operand" ""))]
4766 if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
4768 operands[0] = copy_to_mode_reg (HImode, operands[0]);
4773 (define_insn "*indirect_jump"
4775 (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
4781 push %A0\;push %B0\;ret
4783 [(set_attr "length" "1,2,1,3,1")
4784 (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
4785 (set_attr "cc" "none")])
4788 ;; For entries in jump table see avr_output_addr_vec_elt.
4791 ;; "rjmp .L<n>" instructions for <= 8K devices
4792 ;; ".word gs(.L<n>)" addresses for > 8K devices
4793 (define_insn "*tablejump"
4795 (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
4797 (use (label_ref (match_operand 1 "" "")))
4798 (clobber (match_dup 0))]
4802 push %A0\;push %B0\;ret
4804 [(set_attr "length" "1,3,2")
4805 (set_attr "isa" "rjmp,rjmp,jmp")
4806 (set_attr "cc" "none,none,clobber")])
4809 (define_expand "casesi"
4811 (minus:HI (subreg:HI (match_operand:SI 0 "register_operand" "") 0)
4812 (match_operand:HI 1 "register_operand" "")))
4813 (parallel [(set (cc0)
4814 (compare (match_dup 6)
4815 (match_operand:HI 2 "register_operand" "")))
4816 (clobber (match_scratch:QI 9 ""))])
4819 (if_then_else (gtu (cc0)
4821 (label_ref (match_operand 4 "" ""))
4825 (plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
4827 (parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
4828 (use (label_ref (match_dup 3)))
4829 (clobber (match_dup 6))])]
4832 operands[6] = gen_reg_rtx (HImode);
4836 ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4837 ;; This instruction sets Z flag
4840 [(set (cc0) (const_int 0))]
4843 [(set_attr "length" "1")
4844 (set_attr "cc" "compare")])
4846 ;; Clear/set/test a single bit in I/O address space.
4849 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4850 (and:QI (mem:QI (match_dup 0))
4851 (match_operand:QI 1 "single_zero_operand" "n")))]
4854 operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
4855 return "cbi %i0,%2";
4857 [(set_attr "length" "1")
4858 (set_attr "cc" "none")])
4861 [(set (mem:QI (match_operand 0 "low_io_address_operand" "n"))
4862 (ior:QI (mem:QI (match_dup 0))
4863 (match_operand:QI 1 "single_one_operand" "n")))]
4866 operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
4867 return "sbi %i0,%2";
4869 [(set_attr "length" "1")
4870 (set_attr "cc" "none")])
4872 ;; Lower half of the I/O space - use sbic/sbis directly.
4873 (define_insn "*sbix_branch"
4876 (match_operator 0 "eqne_operator"
4878 (mem:QI (match_operand 1 "low_io_address_operand" "n"))
4880 (match_operand 2 "const_int_operand" "n"))
4882 (label_ref (match_operand 3 "" ""))
4886 return avr_out_sbxx_branch (insn, operands);
4888 [(set (attr "length")
4889 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4890 (le (minus (pc) (match_dup 3)) (const_int 2046)))
4892 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4895 (set_attr "cc" "clobber")])
4897 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
4898 (define_insn "*sbix_branch_bit7"
4901 (match_operator 0 "gelt_operator"
4902 [(mem:QI (match_operand 1 "low_io_address_operand" "n"))
4904 (label_ref (match_operand 2 "" ""))
4908 operands[3] = operands[2];
4909 operands[2] = GEN_INT (7);
4910 return avr_out_sbxx_branch (insn, operands);
4912 [(set (attr "length")
4913 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4914 (le (minus (pc) (match_dup 2)) (const_int 2046)))
4916 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4919 (set_attr "cc" "clobber")])
4921 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
4922 (define_insn "*sbix_branch_tmp"
4925 (match_operator 0 "eqne_operator"
4927 (mem:QI (match_operand 1 "high_io_address_operand" "n"))
4929 (match_operand 2 "const_int_operand" "n"))
4931 (label_ref (match_operand 3 "" ""))
4935 return avr_out_sbxx_branch (insn, operands);
4937 [(set (attr "length")
4938 (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
4939 (le (minus (pc) (match_dup 3)) (const_int 2045)))
4941 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4944 (set_attr "cc" "clobber")])
4946 (define_insn "*sbix_branch_tmp_bit7"
4949 (match_operator 0 "gelt_operator"
4950 [(mem:QI (match_operand 1 "high_io_address_operand" "n"))
4952 (label_ref (match_operand 2 "" ""))
4956 operands[3] = operands[2];
4957 operands[2] = GEN_INT (7);
4958 return avr_out_sbxx_branch (insn, operands);
4960 [(set (attr "length")
4961 (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
4962 (le (minus (pc) (match_dup 2)) (const_int 2045)))
4964 (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
4967 (set_attr "cc" "clobber")])
4969 ;; ************************* Peepholes ********************************
4971 (define_peephole ; "*dec-and-branchsi!=-1.d.clobber"
4972 [(parallel [(set (match_operand:SI 0 "d_register_operand" "")
4973 (plus:SI (match_dup 0)
4975 (clobber (scratch:QI))])
4976 (parallel [(set (cc0)
4977 (compare (match_dup 0)
4979 (clobber (match_operand:QI 1 "d_register_operand" ""))])
4981 (if_then_else (eqne (cc0)
4983 (label_ref (match_operand 2 "" ""))
4990 if (test_hard_reg_class (ADDW_REGS, operands[0]))
4991 output_asm_insn ("sbiw %0,1" CR_TAB
4992 "sbc %C0,__zero_reg__" CR_TAB
4993 "sbc %D0,__zero_reg__", operands);
4995 output_asm_insn ("subi %A0,1" CR_TAB
4996 "sbc %B0,__zero_reg__" CR_TAB
4997 "sbc %C0,__zero_reg__" CR_TAB
4998 "sbc %D0,__zero_reg__", operands);
5000 jump_mode = avr_jump_mode (operands[2], insn);
5001 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5002 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5006 case 1: return "%1 %2";
5007 case 2: return "%1 .+2\;rjmp %2";
5008 case 3: return "%1 .+4\;jmp %2";
5015 (define_peephole ; "*dec-and-branchhi!=-1"
5016 [(set (match_operand:HI 0 "d_register_operand" "")
5017 (plus:HI (match_dup 0)
5019 (parallel [(set (cc0)
5020 (compare (match_dup 0)
5022 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5024 (if_then_else (eqne (cc0)
5026 (label_ref (match_operand 2 "" ""))
5033 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5034 output_asm_insn ("sbiw %0,1", operands);
5036 output_asm_insn ("subi %A0,1" CR_TAB
5037 "sbc %B0,__zero_reg__", operands);
5039 jump_mode = avr_jump_mode (operands[2], insn);
5040 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5041 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5045 case 1: return "%1 %2";
5046 case 2: return "%1 .+2\;rjmp %2";
5047 case 3: return "%1 .+4\;jmp %2";
5054 ;; Same as above but with clobber flavour of addhi3
5055 (define_peephole ; "*dec-and-branchhi!=-1.d.clobber"
5056 [(parallel [(set (match_operand:HI 0 "d_register_operand" "")
5057 (plus:HI (match_dup 0)
5059 (clobber (scratch:QI))])
5060 (parallel [(set (cc0)
5061 (compare (match_dup 0)
5063 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5065 (if_then_else (eqne (cc0)
5067 (label_ref (match_operand 2 "" ""))
5074 if (test_hard_reg_class (ADDW_REGS, operands[0]))
5075 output_asm_insn ("sbiw %0,1", operands);
5077 output_asm_insn ("subi %A0,1" CR_TAB
5078 "sbc %B0,__zero_reg__", operands);
5080 jump_mode = avr_jump_mode (operands[2], insn);
5081 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5082 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5086 case 1: return "%1 %2";
5087 case 2: return "%1 .+2\;rjmp %2";
5088 case 3: return "%1 .+4\;jmp %2";
5095 ;; Same as above but with clobber flavour of addhi3
5096 (define_peephole ; "*dec-and-branchhi!=-1.l.clobber"
5097 [(parallel [(set (match_operand:HI 0 "l_register_operand" "")
5098 (plus:HI (match_dup 0)
5100 (clobber (match_operand:QI 3 "d_register_operand" ""))])
5101 (parallel [(set (cc0)
5102 (compare (match_dup 0)
5104 (clobber (match_operand:QI 1 "d_register_operand" ""))])
5106 (if_then_else (eqne (cc0)
5108 (label_ref (match_operand 2 "" ""))
5115 output_asm_insn ("ldi %3,1" CR_TAB
5117 "sbc %B0,__zero_reg__", operands);
5119 jump_mode = avr_jump_mode (operands[2], insn);
5120 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5121 operands[1] = gen_rtx_CONST_STRING (VOIDmode, op);
5125 case 1: return "%1 %2";
5126 case 2: return "%1 .+2\;rjmp %2";
5127 case 3: return "%1 .+4\;jmp %2";
5134 (define_peephole ; "*dec-and-branchqi!=-1"
5135 [(set (match_operand:QI 0 "d_register_operand" "")
5136 (plus:QI (match_dup 0)
5139 (compare (match_dup 0)
5142 (if_then_else (eqne (cc0)
5144 (label_ref (match_operand 1 "" ""))
5151 cc_status.value1 = operands[0];
5152 cc_status.flags |= CC_OVERFLOW_UNUSABLE;
5154 output_asm_insn ("subi %A0,1", operands);
5156 jump_mode = avr_jump_mode (operands[1], insn);
5157 op = ((EQ == <CODE>) ^ (jump_mode == 1)) ? "brcc" : "brcs";
5158 operands[0] = gen_rtx_CONST_STRING (VOIDmode, op);
5162 case 1: return "%0 %1";
5163 case 2: return "%0 .+2\;rjmp %1";
5164 case 3: return "%0 .+4\;jmp %1";
5172 (define_peephole ; "*cpse.eq"
5174 (compare (match_operand:QI 1 "register_operand" "r,r")
5175 (match_operand:QI 2 "reg_or_0_operand" "r,L")))
5177 (if_then_else (eq (cc0)
5179 (label_ref (match_operand 0 "" ""))
5181 "jump_over_one_insn_p (insn, operands[0])"
5184 cpse %1,__zero_reg__")
5186 ;; This peephole avoids code like
5189 ;; BREQ .+2 ; branch
5192 ;; Notice that the peephole is always shorter than cmpqi + branch.
5193 ;; The reason to write it as peephole is that sequences like
5198 ;; shall not be superseeded. With a respective combine pattern
5199 ;; the latter sequence would be
5202 ;; CPSE Rm, __zero_reg__
5205 ;; and thus longer and slower and not easy to be rolled back.
5207 (define_peephole ; "*cpse.ne"
5209 (compare (match_operand:QI 1 "register_operand" "")
5210 (match_operand:QI 2 "reg_or_0_operand" "")))
5212 (if_then_else (ne (cc0)
5214 (label_ref (match_operand 0 "" ""))
5217 || !avr_current_device->errata_skip"
5219 if (operands[2] == const0_rtx)
5220 operands[2] = zero_reg_rtx;
5222 return 3 == avr_jump_mode (operands[0], insn)
5223 ? "cpse %1,%2\;jmp %0"
5224 : "cpse %1,%2\;rjmp %0";
5227 ;;pppppppppppppppppppppppppppppppppppppppppppppppppppp
5228 ;;prologue/epilogue support instructions
5230 (define_insn "popqi"
5231 [(set (match_operand:QI 0 "register_operand" "=r")
5232 (mem:QI (pre_inc:HI (reg:HI REG_SP))))]
5235 [(set_attr "cc" "none")
5236 (set_attr "length" "1")])
5238 ;; Enable Interrupts
5239 (define_insn "enable_interrupt"
5240 [(unspec_volatile [(const_int 1)] UNSPECV_ENABLE_IRQS)]
5243 [(set_attr "length" "1")
5244 (set_attr "cc" "none")])
5246 ;; Disable Interrupts
5247 (define_insn "disable_interrupt"
5248 [(unspec_volatile [(const_int 0)] UNSPECV_ENABLE_IRQS)]
5251 [(set_attr "length" "1")
5252 (set_attr "cc" "none")])
5254 ;; Library prologue saves
5255 (define_insn "call_prologue_saves"
5256 [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
5257 (match_operand:HI 0 "immediate_operand" "i,i")
5258 (set (reg:HI REG_SP)
5259 (minus:HI (reg:HI REG_SP)
5260 (match_operand:HI 1 "immediate_operand" "i,i")))
5261 (use (reg:HI REG_X))
5262 (clobber (reg:HI REG_Z))]
5264 "ldi r30,lo8(gs(1f))
5266 %~jmp __prologue_saves__+((18 - %0) * 2)
5268 [(set_attr "length" "5,6")
5269 (set_attr "cc" "clobber")
5270 (set_attr "isa" "rjmp,jmp")])
5272 ; epilogue restores using library
5273 (define_insn "epilogue_restores"
5274 [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
5276 (plus:HI (reg:HI REG_Y)
5277 (match_operand:HI 0 "immediate_operand" "i,i")))
5278 (set (reg:HI REG_SP)
5279 (plus:HI (reg:HI REG_Y)
5281 (clobber (reg:QI REG_Z))]
5284 %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
5285 [(set_attr "length" "2,3")
5286 (set_attr "cc" "clobber")
5287 (set_attr "isa" "rjmp,jmp")])
5290 (define_insn "return"
5292 "reload_completed && avr_simple_epilogue ()"
5294 [(set_attr "cc" "none")
5295 (set_attr "length" "1")])
5297 (define_insn "return_from_epilogue"
5301 && !(cfun->machine->is_interrupt || cfun->machine->is_signal)
5302 && !cfun->machine->is_naked)"
5304 [(set_attr "cc" "none")
5305 (set_attr "length" "1")])
5307 (define_insn "return_from_interrupt_epilogue"
5311 && (cfun->machine->is_interrupt || cfun->machine->is_signal)
5312 && !cfun->machine->is_naked)"
5314 [(set_attr "cc" "none")
5315 (set_attr "length" "1")])
5317 (define_insn "return_from_naked_epilogue"
5321 && cfun->machine->is_naked)"
5323 [(set_attr "cc" "none")
5324 (set_attr "length" "0")])
5326 (define_expand "prologue"
5334 (define_expand "epilogue"
5338 expand_epilogue (false /* sibcall_p */);
5342 (define_expand "sibcall_epilogue"
5346 expand_epilogue (true /* sibcall_p */);
5350 ;; Some instructions resp. instruction sequences available
5353 (define_insn "delay_cycles_1"
5354 [(unspec_volatile [(match_operand:QI 0 "const_int_operand" "n")
5356 UNSPECV_DELAY_CYCLES)
5357 (clobber (match_scratch:QI 1 "=&d"))]
5362 [(set_attr "length" "3")
5363 (set_attr "cc" "clobber")])
5365 (define_insn "delay_cycles_2"
5366 [(unspec_volatile [(match_operand:HI 0 "const_int_operand" "n")
5368 UNSPECV_DELAY_CYCLES)
5369 (clobber (match_scratch:HI 1 "=&w"))]
5375 [(set_attr "length" "4")
5376 (set_attr "cc" "clobber")])
5378 (define_insn "delay_cycles_3"
5379 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5381 UNSPECV_DELAY_CYCLES)
5382 (clobber (match_scratch:QI 1 "=&d"))
5383 (clobber (match_scratch:QI 2 "=&d"))
5384 (clobber (match_scratch:QI 3 "=&d"))]
5393 [(set_attr "length" "7")
5394 (set_attr "cc" "clobber")])
5396 (define_insn "delay_cycles_4"
5397 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
5399 UNSPECV_DELAY_CYCLES)
5400 (clobber (match_scratch:QI 1 "=&d"))
5401 (clobber (match_scratch:QI 2 "=&d"))
5402 (clobber (match_scratch:QI 3 "=&d"))
5403 (clobber (match_scratch:QI 4 "=&d"))]
5414 [(set_attr "length" "9")
5415 (set_attr "cc" "clobber")])
5418 ;; __builtin_avr_insert_bits
5420 (define_insn "insert_bits"
5421 [(set (match_operand:QI 0 "register_operand" "=r ,d ,r")
5422 (unspec:QI [(match_operand:SI 1 "const_int_operand" "C0f,Cxf,C0f")
5423 (match_operand:QI 2 "register_operand" "r ,r ,r")
5424 (match_operand:QI 3 "nonmemory_operand" "n ,0 ,0")]
5425 UNSPEC_INSERT_BITS))]
5428 return avr_out_insert_bits (operands, NULL);
5430 [(set_attr "adjust_len" "insert_bits")
5431 (set_attr "cc" "clobber")])
5434 ;; __builtin_avr_flash_segment
5436 ;; Just a helper for the next "official" expander.
5438 (define_expand "flash_segment1"
5439 [(set (match_operand:QI 0 "register_operand" "")
5440 (subreg:QI (match_operand:PSI 1 "register_operand" "")
5443 (compare (match_dup 0)
5446 (if_then_else (ge (cc0)
5448 (label_ref (match_operand 2 "" ""))
5453 (define_expand "flash_segment"
5454 [(parallel [(match_operand:QI 0 "register_operand" "")
5455 (match_operand:PSI 1 "register_operand" "")])]
5458 rtx label = gen_label_rtx ();
5459 emit (gen_flash_segment1 (operands[0], operands[1], label));
5464 ;; Actually, it's too late now to work out address spaces known at compiletime.
5465 ;; Best place would be to fold ADDR_SPACE_CONVERT_EXPR in avr_fold_builtin.
5466 ;; However, avr_addr_space_convert can add some built-in knowledge for PSTR
5467 ;; so that ADDR_SPACE_CONVERT_EXPR in the built-in must not be resolved.
5469 (define_insn_and_split "*split.flash_segment"
5470 [(set (match_operand:QI 0 "register_operand" "=d")
5471 (subreg:QI (lo_sum:PSI (match_operand:QI 1 "nonmemory_operand" "ri")
5472 (match_operand:HI 2 "register_operand" "r"))
5475 { gcc_unreachable(); }
5483 ;; Postpone expansion of 16-bit parity to libgcc call until after combine for
5484 ;; better 8-bit parity recognition.
5486 (define_expand "parityhi2"
5487 [(parallel [(set (match_operand:HI 0 "register_operand" "")
5488 (parity:HI (match_operand:HI 1 "register_operand" "")))
5489 (clobber (reg:HI 24))])])
5491 (define_insn_and_split "*parityhi2"
5492 [(set (match_operand:HI 0 "register_operand" "=r")
5493 (parity:HI (match_operand:HI 1 "register_operand" "r")))
5494 (clobber (reg:HI 24))]
5496 { gcc_unreachable(); }
5501 (parity:HI (reg:HI 24)))
5505 (define_insn_and_split "*parityqihi2"
5506 [(set (match_operand:HI 0 "register_operand" "=r")
5507 (parity:HI (match_operand:QI 1 "register_operand" "r")))
5508 (clobber (reg:HI 24))]
5510 { gcc_unreachable(); }
5515 (zero_extend:HI (parity:QI (reg:QI 24))))
5519 (define_expand "paritysi2"
5521 (match_operand:SI 1 "register_operand" ""))
5523 (truncate:HI (parity:SI (reg:SI 22))))
5526 (set (match_operand:SI 0 "register_operand" "")
5527 (zero_extend:SI (match_dup 2)))]
5530 operands[2] = gen_reg_rtx (HImode);
5533 (define_insn "*parityhi2.libgcc"
5535 (parity:HI (reg:HI 24)))]
5537 "%~call __parityhi2"
5538 [(set_attr "type" "xcall")
5539 (set_attr "cc" "clobber")])
5541 (define_insn "*parityqihi2.libgcc"
5543 (zero_extend:HI (parity:QI (reg:QI 24))))]
5545 "%~call __parityqi2"
5546 [(set_attr "type" "xcall")
5547 (set_attr "cc" "clobber")])
5549 (define_insn "*paritysihi2.libgcc"
5551 (truncate:HI (parity:SI (reg:SI 22))))]
5553 "%~call __paritysi2"
5554 [(set_attr "type" "xcall")
5555 (set_attr "cc" "clobber")])
5560 (define_expand "popcounthi2"
5562 (match_operand:HI 1 "register_operand" ""))
5564 (popcount:HI (reg:HI 24)))
5565 (set (match_operand:HI 0 "register_operand" "")
5570 (define_expand "popcountsi2"
5572 (match_operand:SI 1 "register_operand" ""))
5574 (truncate:HI (popcount:SI (reg:SI 22))))
5577 (set (match_operand:SI 0 "register_operand" "")
5578 (zero_extend:SI (match_dup 2)))]
5581 operands[2] = gen_reg_rtx (HImode);
5584 (define_insn "*popcounthi2.libgcc"
5586 (popcount:HI (reg:HI 24)))]
5588 "%~call __popcounthi2"
5589 [(set_attr "type" "xcall")
5590 (set_attr "cc" "clobber")])
5592 (define_insn "*popcountsi2.libgcc"
5594 (truncate:HI (popcount:SI (reg:SI 22))))]
5596 "%~call __popcountsi2"
5597 [(set_attr "type" "xcall")
5598 (set_attr "cc" "clobber")])
5600 (define_insn "*popcountqi2.libgcc"
5602 (popcount:QI (reg:QI 24)))]
5604 "%~call __popcountqi2"
5605 [(set_attr "type" "xcall")
5606 (set_attr "cc" "clobber")])
5608 (define_insn_and_split "*popcountqihi2.libgcc"
5610 (zero_extend:HI (popcount:QI (reg:QI 24))))]
5615 (popcount:QI (reg:QI 24)))
5620 ;; Count Leading Zeros
5622 (define_expand "clzhi2"
5624 (match_operand:HI 1 "register_operand" ""))
5625 (parallel [(set (reg:HI 24)
5626 (clz:HI (reg:HI 24)))
5627 (clobber (reg:QI 26))])
5628 (set (match_operand:HI 0 "register_operand" "")
5633 (define_expand "clzsi2"
5635 (match_operand:SI 1 "register_operand" ""))
5636 (parallel [(set (reg:HI 24)
5637 (truncate:HI (clz:SI (reg:SI 22))))
5638 (clobber (reg:QI 26))])
5641 (set (match_operand:SI 0 "register_operand" "")
5642 (zero_extend:SI (match_dup 2)))]
5645 operands[2] = gen_reg_rtx (HImode);
5648 (define_insn "*clzhi2.libgcc"
5650 (clz:HI (reg:HI 24)))
5651 (clobber (reg:QI 26))]
5654 [(set_attr "type" "xcall")
5655 (set_attr "cc" "clobber")])
5657 (define_insn "*clzsihi2.libgcc"
5659 (truncate:HI (clz:SI (reg:SI 22))))
5660 (clobber (reg:QI 26))]
5663 [(set_attr "type" "xcall")
5664 (set_attr "cc" "clobber")])
5666 ;; Count Trailing Zeros
5668 (define_expand "ctzhi2"
5670 (match_operand:HI 1 "register_operand" ""))
5671 (parallel [(set (reg:HI 24)
5672 (ctz:HI (reg:HI 24)))
5673 (clobber (reg:QI 26))])
5674 (set (match_operand:HI 0 "register_operand" "")
5679 (define_expand "ctzsi2"
5681 (match_operand:SI 1 "register_operand" ""))
5682 (parallel [(set (reg:HI 24)
5683 (truncate:HI (ctz:SI (reg:SI 22))))
5684 (clobber (reg:QI 22))
5685 (clobber (reg:QI 26))])
5688 (set (match_operand:SI 0 "register_operand" "")
5689 (zero_extend:SI (match_dup 2)))]
5692 operands[2] = gen_reg_rtx (HImode);
5695 (define_insn "*ctzhi2.libgcc"
5697 (ctz:HI (reg:HI 24)))
5698 (clobber (reg:QI 26))]
5701 [(set_attr "type" "xcall")
5702 (set_attr "cc" "clobber")])
5704 (define_insn "*ctzsihi2.libgcc"
5706 (truncate:HI (ctz:SI (reg:SI 22))))
5707 (clobber (reg:QI 22))
5708 (clobber (reg:QI 26))]
5711 [(set_attr "type" "xcall")
5712 (set_attr "cc" "clobber")])
5716 (define_expand "ffshi2"
5718 (match_operand:HI 1 "register_operand" ""))
5719 (parallel [(set (reg:HI 24)
5720 (ffs:HI (reg:HI 24)))
5721 (clobber (reg:QI 26))])
5722 (set (match_operand:HI 0 "register_operand" "")
5727 (define_expand "ffssi2"
5729 (match_operand:SI 1 "register_operand" ""))
5730 (parallel [(set (reg:HI 24)
5731 (truncate:HI (ffs:SI (reg:SI 22))))
5732 (clobber (reg:QI 22))
5733 (clobber (reg:QI 26))])
5736 (set (match_operand:SI 0 "register_operand" "")
5737 (zero_extend:SI (match_dup 2)))]
5740 operands[2] = gen_reg_rtx (HImode);
5743 (define_insn "*ffshi2.libgcc"
5745 (ffs:HI (reg:HI 24)))
5746 (clobber (reg:QI 26))]
5749 [(set_attr "type" "xcall")
5750 (set_attr "cc" "clobber")])
5752 (define_insn "*ffssihi2.libgcc"
5754 (truncate:HI (ffs:SI (reg:SI 22))))
5755 (clobber (reg:QI 22))
5756 (clobber (reg:QI 26))]
5759 [(set_attr "type" "xcall")
5760 (set_attr "cc" "clobber")])
5764 (define_insn "copysignsf3"
5765 [(set (match_operand:SF 0 "register_operand" "=r")
5766 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
5767 (match_operand:SF 2 "register_operand" "r")]
5770 "bst %D2,7\;bld %D0,7"
5771 [(set_attr "length" "2")
5772 (set_attr "cc" "none")])
5774 ;; Swap Bytes (change byte-endianess)
5776 (define_expand "bswapsi2"
5778 (match_operand:SI 1 "register_operand" ""))
5780 (bswap:SI (reg:SI 22)))
5781 (set (match_operand:SI 0 "register_operand" "")
5786 (define_insn "*bswapsi2.libgcc"
5788 (bswap:SI (reg:SI 22)))]
5791 [(set_attr "type" "xcall")
5792 (set_attr "cc" "clobber")])
5797 ;; NOP taking 1 or 2 Ticks
5799 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "P,K")]
5805 [(set_attr "length" "1")
5806 (set_attr "cc" "none")])
5809 (define_insn "sleep"
5810 [(unspec_volatile [(const_int 0)] UNSPECV_SLEEP)]
5813 [(set_attr "length" "1")
5814 (set_attr "cc" "none")])
5818 [(unspec_volatile [(const_int 0)] UNSPECV_WDR)]
5821 [(set_attr "length" "1")
5822 (set_attr "cc" "none")])
5825 (define_expand "fmul"
5827 (match_operand:QI 1 "register_operand" ""))
5829 (match_operand:QI 2 "register_operand" ""))
5830 (parallel [(set (reg:HI 22)
5831 (unspec:HI [(reg:QI 24)
5832 (reg:QI 25)] UNSPEC_FMUL))
5833 (clobber (reg:HI 24))])
5834 (set (match_operand:HI 0 "register_operand" "")
5840 emit_insn (gen_fmul_insn (operand0, operand1, operand2));
5845 (define_insn "fmul_insn"
5846 [(set (match_operand:HI 0 "register_operand" "=r")
5847 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5848 (match_operand:QI 2 "register_operand" "a")]
5854 [(set_attr "length" "3")
5855 (set_attr "cc" "clobber")])
5857 (define_insn "*fmul.call"
5859 (unspec:HI [(reg:QI 24)
5860 (reg:QI 25)] UNSPEC_FMUL))
5861 (clobber (reg:HI 24))]
5864 [(set_attr "type" "xcall")
5865 (set_attr "cc" "clobber")])
5868 (define_expand "fmuls"
5870 (match_operand:QI 1 "register_operand" ""))
5872 (match_operand:QI 2 "register_operand" ""))
5873 (parallel [(set (reg:HI 22)
5874 (unspec:HI [(reg:QI 24)
5875 (reg:QI 25)] UNSPEC_FMULS))
5876 (clobber (reg:HI 24))])
5877 (set (match_operand:HI 0 "register_operand" "")
5883 emit_insn (gen_fmuls_insn (operand0, operand1, operand2));
5888 (define_insn "fmuls_insn"
5889 [(set (match_operand:HI 0 "register_operand" "=r")
5890 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5891 (match_operand:QI 2 "register_operand" "a")]
5897 [(set_attr "length" "3")
5898 (set_attr "cc" "clobber")])
5900 (define_insn "*fmuls.call"
5902 (unspec:HI [(reg:QI 24)
5903 (reg:QI 25)] UNSPEC_FMULS))
5904 (clobber (reg:HI 24))]
5907 [(set_attr "type" "xcall")
5908 (set_attr "cc" "clobber")])
5911 (define_expand "fmulsu"
5913 (match_operand:QI 1 "register_operand" ""))
5915 (match_operand:QI 2 "register_operand" ""))
5916 (parallel [(set (reg:HI 22)
5917 (unspec:HI [(reg:QI 24)
5918 (reg:QI 25)] UNSPEC_FMULSU))
5919 (clobber (reg:HI 24))])
5920 (set (match_operand:HI 0 "register_operand" "")
5926 emit_insn (gen_fmulsu_insn (operand0, operand1, operand2));
5931 (define_insn "fmulsu_insn"
5932 [(set (match_operand:HI 0 "register_operand" "=r")
5933 (unspec:HI [(match_operand:QI 1 "register_operand" "a")
5934 (match_operand:QI 2 "register_operand" "a")]
5940 [(set_attr "length" "3")
5941 (set_attr "cc" "clobber")])
5943 (define_insn "*fmulsu.call"
5945 (unspec:HI [(reg:QI 24)
5946 (reg:QI 25)] UNSPEC_FMULSU))
5947 (clobber (reg:HI 24))]
5950 [(set_attr "type" "xcall")
5951 (set_attr "cc" "clobber")])
5954 ;; Some combiner patterns dealing with bits.
5957 ;; Move bit $3.0 into bit $0.$4
5958 (define_insn "*movbitqi.1-6.a"
5959 [(set (match_operand:QI 0 "register_operand" "=r")
5960 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5961 (match_operand:QI 2 "single_zero_operand" "n"))
5962 (and:QI (ashift:QI (match_operand:QI 3 "register_operand" "r")
5963 (match_operand:QI 4 "const_0_to_7_operand" "n"))
5964 (match_operand:QI 5 "single_one_operand" "n"))))]
5965 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))
5966 && INTVAL(operands[4]) == exact_log2 (INTVAL(operands[5]) & GET_MODE_MASK (QImode))"
5967 "bst %3,0\;bld %0,%4"
5968 [(set_attr "length" "2")
5969 (set_attr "cc" "none")])
5971 ;; Move bit $3.0 into bit $0.$4
5972 ;; Variation of above. Unfortunately, there is no canonicalized representation
5973 ;; of moving around bits. So what we see here depends on how user writes down
5974 ;; bit manipulations.
5975 (define_insn "*movbitqi.1-6.b"
5976 [(set (match_operand:QI 0 "register_operand" "=r")
5977 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5978 (match_operand:QI 2 "single_zero_operand" "n"))
5979 (ashift:QI (and:QI (match_operand:QI 3 "register_operand" "r")
5981 (match_operand:QI 4 "const_0_to_7_operand" "n"))))]
5982 "INTVAL(operands[4]) == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5983 "bst %3,0\;bld %0,%4"
5984 [(set_attr "length" "2")
5985 (set_attr "cc" "none")])
5987 ;; Move bit $3.0 into bit $0.0.
5988 ;; For bit 0, combiner generates slightly different pattern.
5989 (define_insn "*movbitqi.0"
5990 [(set (match_operand:QI 0 "register_operand" "=r")
5991 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
5992 (match_operand:QI 2 "single_zero_operand" "n"))
5993 (and:QI (match_operand:QI 3 "register_operand" "r")
5995 "0 == exact_log2 (~INTVAL(operands[2]) & GET_MODE_MASK (QImode))"
5996 "bst %3,0\;bld %0,0"
5997 [(set_attr "length" "2")
5998 (set_attr "cc" "none")])
6000 ;; Move bit $2.0 into bit $0.7.
6001 ;; For bit 7, combiner generates slightly different pattern
6002 (define_insn "*movbitqi.7"
6003 [(set (match_operand:QI 0 "register_operand" "=r")
6004 (ior:QI (and:QI (match_operand:QI 1 "register_operand" "0")
6006 (ashift:QI (match_operand:QI 2 "register_operand" "r")
6009 "bst %2,0\;bld %0,7"
6010 [(set_attr "length" "2")
6011 (set_attr "cc" "none")])
6013 ;; Combiner transforms above four pattern into ZERO_EXTRACT if it sees MEM
6014 ;; and input/output match. We provide a special pattern for this, because
6015 ;; in contrast to a IN/BST/BLD/OUT sequence we need less registers and the
6016 ;; operation on I/O is atomic.
6017 (define_insn "*insv.io"
6018 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n,n,n"))
6020 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n"))
6021 (match_operand:QI 2 "nonmemory_operand" "L,P,r"))]
6026 sbrc %2,0\;sbi %i0,%1\;sbrs %2,0\;cbi %i0,%1"
6027 [(set_attr "length" "1,1,4")
6028 (set_attr "cc" "none")])
6030 (define_insn "*insv.not.io"
6031 [(set (zero_extract:QI (mem:QI (match_operand 0 "low_io_address_operand" "n"))
6033 (match_operand:QI 1 "const_0_to_7_operand" "n"))
6034 (not:QI (match_operand:QI 2 "register_operand" "r")))]
6036 "sbrs %2,0\;sbi %i0,%1\;sbrc %2,0\;cbi %i0,%1"
6037 [(set_attr "length" "4")
6038 (set_attr "cc" "none")])
6040 ;; The insv expander.
6041 ;; We only support 1-bit inserts
6042 (define_expand "insv"
6043 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "")
6044 (match_operand:QI 1 "const1_operand" "") ; width
6045 (match_operand:QI 2 "const_0_to_7_operand" "")) ; pos
6046 (match_operand:QI 3 "nonmemory_operand" ""))]
6050 ;; Insert bit $2.0 into $0.$1
6051 (define_insn "*insv.reg"
6052 [(set (zero_extract:QI (match_operand:QI 0 "register_operand" "+r,d,d,l,l")
6054 (match_operand:QI 1 "const_0_to_7_operand" "n,n,n,n,n"))
6055 (match_operand:QI 2 "nonmemory_operand" "r,L,P,L,P"))]
6059 andi %0,lo8(~(1<<%1))
6063 [(set_attr "length" "2,1,1,2,2")
6064 (set_attr "cc" "none,set_zn,set_zn,none,none")])
6067 ;; Some combine patterns that try to fix bad code when a value is composed
6068 ;; from byte parts like in PR27663.
6069 ;; The patterns give some release but the code still is not optimal,
6070 ;; in particular when subreg lowering (-fsplit-wide-types) is turned on.
6071 ;; That switch obfuscates things here and in many other places.
6073 ;; "*iorhiqi.byte0" "*iorpsiqi.byte0" "*iorsiqi.byte0"
6074 ;; "*xorhiqi.byte0" "*xorpsiqi.byte0" "*xorsiqi.byte0"
6075 (define_insn_and_split "*<code_stdname><mode>qi.byte0"
6076 [(set (match_operand:HISI 0 "register_operand" "=r")
6078 (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6079 (match_operand:HISI 2 "register_operand" "0")))]
6084 (xior:QI (match_dup 3)
6087 operands[3] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, 0);
6090 ;; "*iorhiqi.byte1-3" "*iorpsiqi.byte1-3" "*iorsiqi.byte1-3"
6091 ;; "*xorhiqi.byte1-3" "*xorpsiqi.byte1-3" "*xorsiqi.byte1-3"
6092 (define_insn_and_split "*<code_stdname><mode>qi.byte1-3"
6093 [(set (match_operand:HISI 0 "register_operand" "=r")
6095 (ashift:HISI (zero_extend:HISI (match_operand:QI 1 "register_operand" "r"))
6096 (match_operand:QI 2 "const_8_16_24_operand" "n"))
6097 (match_operand:HISI 3 "register_operand" "0")))]
6098 "INTVAL(operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
6100 "&& reload_completed"
6102 (xior:QI (match_dup 4)
6105 int byteno = INTVAL(operands[2]) / BITS_PER_UNIT;
6106 operands[4] = simplify_gen_subreg (QImode, operands[0], <MODE>mode, byteno);
6109 (define_expand "extzv"
6110 [(set (match_operand:QI 0 "register_operand" "")
6111 (zero_extract:QI (match_operand:QI 1 "register_operand" "")
6112 (match_operand:QI 2 "const1_operand" "")
6113 (match_operand:QI 3 "const_0_to_7_operand" "")))]
6117 (define_insn "*extzv"
6118 [(set (match_operand:QI 0 "register_operand" "=*d,*d,*d,*d,r")
6119 (zero_extract:QI (match_operand:QI 1 "register_operand" "0,r,0,0,r")
6121 (match_operand:QI 2 "const_0_to_7_operand" "L,L,P,C04,n")))]
6125 mov %0,%1\;andi %0,1
6128 bst %1,%2\;clr %0\;bld %0,0"
6129 [(set_attr "length" "1,2,2,2,3")
6130 (set_attr "cc" "set_zn,set_zn,set_zn,set_zn,clobber")])
6132 (define_insn_and_split "*extzv.qihi1"
6133 [(set (match_operand:HI 0 "register_operand" "=r")
6134 (zero_extract:HI (match_operand:QI 1 "register_operand" "r")
6136 (match_operand:QI 2 "const_0_to_7_operand" "n")))]
6141 (zero_extract:QI (match_dup 1)
6147 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6148 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6151 (define_insn_and_split "*extzv.qihi2"
6152 [(set (match_operand:HI 0 "register_operand" "=r")
6154 (zero_extract:QI (match_operand:QI 1 "register_operand" "r")
6156 (match_operand:QI 2 "const_0_to_7_operand" "n"))))]
6161 (zero_extract:QI (match_dup 1)
6167 operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
6168 operands[4] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
6172 (include "avr-dimode.md")